CAnimatedMeshScenenNode
几个重要的接口:
1:OnAnimate
在前面说过该接口负责时间驱动,因此在这里的该接口中先根据过去的时间计算出现在的Frame,然后在根据Frame得到当前的Mesh。
buildFrameNr(timeMs-LastTimeMs); // Compute current frame
...
scene::IMesh * mesh = getMeshForCurrentFrame(); // Get current frame mesh
对于getMeshForCurrentFrame中如果是SkinnedMesh的话
// animate the mesh , update the local matrix(Local Motion)
skinnedMesh->animateMesh(getFrameNr(), 1.0f);
// Update the skinned mesh for the current joint transforms.
// Update the global matrix according to the Local Matrices. And transform the mesh buffer.
skinnedMesh->skinMesh();
2: render
渲染该SkinnedMesh.注意的是Irrlicht对于SkinnedMesh是在CPU中进行Skin的,所以这里对于MeshBuffer的变换只有该AnimationMeshSceneNode的矩阵,并且MeshBuffer的Transformation总是为Identity Matrix。
- // only render transparent buffer if this is the transparent render pass
- // and solid only in solid pass
- if (transparent == isTransparentPass)
- {
- scene::IMeshBuffer* mb = m->getMeshBuffer(i);
- const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
- if (RenderFromIdentity)
- driver->setTransform(video::ETS_WORLD, core::IdentityMatrix );
- else if (Mesh->getMeshType() == EAMT_SKINNED)
- // ((SSkinMeshBuffer*)mb)->Transformation always be Identity matrix.
- driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((SSkinMeshBuffer*)mb)->Transformation);
- driver->setMaterial(material);
- driver->drawMeshBuffer(mb);
- }
对于SkinnedMesh的实现:
animateMesh:
// Get the blended position, scale and rotation.
// 这里主要是根据frame(注意frame不一定是整数值)来插值关键帧。从而得到该Joint(Bone)的Translation, Rotation, Scaling。
getFrameData(frame, joint, position, joint->positionHint, scale, joint->scaleHint, rotation, joint->rotationHint);
用getFrameData得到这个Joint的三个参数过后,就可以根据这些信息来更新Local Matrix。
buildAll_LocalAnimatedMatrices();
该接口就是根据局每一个Joint的三个参数信息,更新LocalAnimatedMatrix。
skinMesh:
// Construct all the global animated matrix
// 这里主要是迭代每一个Joint,根据LocalAnimatedMatrix和Parent-Child关系来更新GlobalAnimatedMatrix。
buildAll_GlobalAnimatedMatrices();
// 注意这一段代码是为Software实现的,但是对于//rigid animation Part应该是在HardwareSkinning中使用。
- if (!HardwareSkinning)
- {
- //Software skin....
- u32 i;
- // Note
- //rigid animation
- for (i=0; i<AllJoints.size(); ++i)
- {
- for (u32 j=0; j<AllJoints[i]->AttachedMeshes.size(); ++j)
- {
- SSkinMeshBuffer* Buffer=(*SkinningBuffers)[ AllJoints[i]->AttachedMeshes[j] ];
- Buffer->Transformation=AllJoints[i]->GlobalAnimatedMatrix; // Never called.
- }
- }
- //clear skinning helper array
- for (i=0; i<Vertices_Moved.size(); ++i)
- for (u32 j=0; j<Vertices_Moved[i].size(); ++j)
- Vertices_Moved[i][j]=false;
- //skin starting with the root joints
- // Skin the model
- // 这里根据已有的GlobalAnimatedMatrix来Transform所有的顶点。这里面实现了Vertex Blend 技术
- for (i=0; i<RootJoints.size(); ++i)
- SkinJoint(RootJoints[i], 0);
- for (i=0; i<SkinningBuffers->size(); ++i)
- (*SkinningBuffers)[i]->setDirty(EBT_VERTEX);
- }
经过skinMesh过后,这个SkinnedMesh就完成了Skinning过程。
对于CSkinnedMesh中的几个说明:
//! Unnecessary for loaders, will be overwritten on finalize
core::matrix4 GlobalMatrix; //!< The Combined matrix.
core::matrix4 GlobalAnimatedMatrix; //!< The current blended global matrix, LocalAnimatedMatrix*Parent::GlobalAnimatedMatrix, Combined Matrix
core::matrix4 LocalAnimatedMatrix; //!< The current blended local matrix, generated by below three factors, Local Matrix
core::vector3df Animatedposition; //!< The current blended position
core::vector3df Animatedscale; //!< The current blended scaling
core::quaternion Animatedrotation; //!< The current blended rotation
注意这个矩阵:
core::matrix4 GlobalInversedMatrix; //the x format pre-calculates this, In x format, it's offset matrix. Transform the bone to Local bone space. Offet Matrix
这个矩阵在X File中实际上是Offset Matrix.
但是:
在CalculateGlobalMatrices中(在finalize()中被调用,而finalize在该模型被加载好过后才调用)。
if (joint->GlobalInversedMatrix.isIdentity())//might be pre calculated
{
joint->GlobalInversedMatrix = joint->GlobalMatrix;
joint->GlobalInversedMatrix.makeInverse(); // slow
}
在X File的Skinned Mesh是没有用处的,而且是错的。他在这里添加这个代码仅仅是为了支持某一种Skinned Animation的模型格式。
GlobalInversedMatrix在skinJoint中被使用,作为Offset Matrix。
阅读(1791) | 评论(0) | 转发(0) |