实现
现在我们已经准备好去实现我们的skin mesh了.实现代码的最为重要的部分就是设计.下面这个图展示了我们的编码的设计:
这个图没有显示出所有的类成员.它只显示出那些重要的成员.正如图表里所示的,类CMeshNode和CFrameNode都派生自CObject.
CObject的目的在于提供一个树的机制;任一个派生自CObject的对象都有链成一棵树的能力.CFrameNode是场景层次的构造元素而CMeshNode本身则拥有mesh.CMeshNode被包含在CFrameNode里面,而CFrameNode又被包含在CSkinMesh里面.整个场景由CSkinMesh开始,因为它拥有根帧(root frame).所有与skin mesh相关的操作都将在CSkinMesh里面初始化.相应地CSkinMesh将按我们的需要把控制交给场景层次,因此,主程序将只是与CSkinMesh打交道;CFrameNode和CMeshNode将由CSkinMesh间接操作.
下面算法说明了场景是怎样从X文件基础上建立的:
CSKinMesh::CReate()
Begin
Initialize X file API
Register D3DRM templates
Open the X file
For every top level template in the X file
Begin
Retrieve the X file data object
Pass the data object to RootFrame.Load
End
Link the bones to the skin mesh(es)
End
CFrameNode::Load()
Begin
Check the type of the data object
If the type is Mesh
Begin
Create new CMeshNode object
Attach the new object to the frame
Pass the data object to CMeshNode::Create of the new mesh
End
Else if type is FrameTransformMatrix
Load the transform matrix
Else if type is Frame
Begin
Create the new CFrameNode object
Attach the new object to this frame
Set the name of the child frame to the name of the template
For every child template of the current
Begin
Retrieve the X file data object
Pass it to newframe.load
End
End
End
CMeshNode::Create()
Begin
Set the name of the object to the name of the template
Load the skin mesh
Generate blended mesh from this skin mesh object
Load materials
End
建立skin mesh之后,我们就可以开始渲染了.渲染操作由两个阶段构成.在第一个阶段里,我们计算骨骼的世界矩阵(通过矩阵相乘),并把它存储在CMeshNode对象里.在第二个阶段里面,skin mesh将被渲染.下面这个算法显示了这个渲染过程:
CSkinMesh::Render()
Begin
Calculate the world matrix of all the frames
Call CMeshNode::Render of all mesh nodes in the hierarchy
End
CMeshNode::Render
Begin
Enable vertex blending
For every subset in the skin mesh
Begin
Set the bones’ transformation matrices to the device
Set the material
Render
End
Set vertex blending back disabled
End