www.pudn.com > DirectX source.zip > CFrameNode.cpp
/*!
@file : CFrameNode.cpp
Contains the implementation of class CFrameNode
@author Sarmad Kh. Abdulla
*/
//------------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
// Header files
#include "stdafx.h"
/*!
* Initialize the object
*
* @param void :
*
* @return void :
*/
void CFrameNode::InitObject( void )
{
D3DXMatrixIdentity( &TransformationMatrix );
D3DXMatrixIdentity( &OriginalMatrix );
}
/*!
* Load an object from the x file.
*
* @param pxofobj : Pointer to the x file data object to load from.
* @param pd3ddevice : Pointer to the device
* @param pskinmesh : Pointer to the owner skin mesh object.
*
* @return void :
*/
void CFrameNode::Load( LPDIRECTXFILEDATA pxofobj, LPDIRECT3DDEVICE8 pd3ddevice,
CSkinMesh * pskinmesh )
{
HRESULT result;
DWORD dwsize;
// get the type of the object
const GUID * objecttype;
result = pxofobj->GetType( &objecttype );
if( FAILED(result) )
throw new CDXException( "Couldn't get x file data object's type", result );
// check the type of the object to load
if( *objecttype == TID_D3DRMMesh )
{
// load a child mesh
CMeshNode * pmeshnode = new CMeshNode;
SAFEPOINTER( pmeshnode );
Meshes.AttachChild( *pmeshnode );
pmeshnode->Create( pxofobj, pd3ddevice );
}
else if( *objecttype == TID_D3DRMFrameTransformMatrix )
{
// load the transformation matrix
D3DXMATRIX * pmat;
result = pxofobj->GetData( NULL, &dwsize, (PVOID*)&pmat );
TransformationMatrix = *pmat;
OriginalMatrix = *pmat;
if( FAILED(result) )
throw new CDXException( "Couldn't read frame transformation matrix from an x file", result );
}
else if( *objecttype == TID_D3DRMAnimationSet )
pskinmesh->LoadAnimationSet( pxofobj );
else if( *objecttype == TID_D3DRMAnimation )
pskinmesh->LoadAnimation( pxofobj );
else if( *objecttype == TID_D3DRMFrame )
{
// create a new child frame
CFrameNode * pchildframe = new CFrameNode;
SAFEPOINTER( pchildframe );
AttachChild( *pchildframe );
// get the name of the child frame
DWORD dwnamelength;
result = pxofobj->GetName( NULL, &dwnamelength );
if( FAILED(result) )
throw new CDXException( "Couldn't get the name of the D3DRM frame", result );
if( dwnamelength > 0 )
{
char * pname;
pname = new char[dwnamelength];
SAFEPOINTER( pname );
result = pxofobj->GetName( pname, &dwnamelength );
if( FAILED(result) )
throw new CDXException( "Couldn't get frame name from x file", result );
pchildframe->SetName( pname );
delete[] pname;
}
// Enumerate child objects.
// Child object can be data, data reference or binary.
// Use QueryInterface() to find what objecttype of object a child is.
LPDIRECTXFILEDATA pxofchildobj;
LPDIRECTXFILEOBJECT pxofchild;
while( SUCCEEDED( pxofobj->GetNextObject(&pxofchild) ) )
{
// Query the child for it's FileData
result = pxofchild->QueryInterface( IID_IDirectXFileData,
(LPVOID *)&pxofchildobj );
if( SUCCEEDED( result ) )
{
// load the child's object
pchildframe->Load( pxofchildobj, pd3ddevice, pskinmesh );
pxofchildobj->Release();
}
pxofchild->Release();
}
}
}
/*!
* Destory the frame and its childs
*
* @param void :
*
* @return void :
*/
void CFrameNode::Destroy( void )
{
DeleteChilds();
Meshes.DeleteChilds();
}
/*!
* Compute the world matrix of the frame by combining the transformation
* matrix of this frame with the parent's matrix
*
* @param mat : A pointer to the parent's world matrix
*
* @return void :
*/
void CFrameNode::Update( D3DXMATRIX * pmat )
{
D3DXMatrixMultiply( &CombinedMatrix, &TransformationMatrix, pmat );
// update child frames
CFrameNode * pframe = static_cast(GetFirstChild());
while( pframe )
{
pframe->Update( &CombinedMatrix );
pframe = static_cast(pframe->GetNextSibling());
}
}
/*!
* Render the frame's contents
*
* @param pd3ddevice : The device to render on.
*
* @return void :
*/
void CFrameNode::Render( LPDIRECT3DDEVICE8 pd3ddevice )
{
// if we have child meshes, set the world matrix
if( Meshes.GetFirstChild() )
pd3ddevice->SetTransform( D3DTS_WORLD, &CombinedMatrix );
// render meshes
CMeshNode * pmesh = static_cast(Meshes.GetFirstChild());
while( pmesh )
{
pmesh->Render( pd3ddevice );
pmesh = static_cast(pmesh->GetNextSibling());
}
// render child frames
CFrameNode * pframe = static_cast(GetFirstChild());
while( pframe )
{
pframe->Render( pd3ddevice );
pframe = static_cast(pframe->GetNextSibling());
}
}
/*!
* Find a frame in this frame hierarchy with the specified name.
*
* @param framename : The name of the frame
*
* @return CFrameNode * : Pointer to the found frame.
*/
CFrameNode * CFrameNode::FindFrame( const char * framename )
{
if( Name == framename )
return this;
else
{
// loop through the child objects
CFrameNode * pframe = static_cast(GetFirstChild());
while( pframe )
{
CFrameNode * foundframe = pframe->FindFrame( framename );
if( foundframe )
return foundframe;
pframe = static_cast(pframe->GetNextSibling());
}
return NULL;
}
}
/*!
* Find the bones of the child meshes.
*
* @param prootframe : The root of the frame hierarchy to search in for the bones.
*
* @return void :
*/
void CFrameNode::FindBones( CFrameNode * prootframe )
{
// find the bones of the meshes
CMeshNode * pmesh = static_cast(Meshes.GetFirstChild());
while( pmesh )
{
pmesh->FindBones( prootframe );
pmesh = static_cast(pmesh->GetNextSibling());
}
// find the bones in the child frames
CFrameNode * pframe = static_cast(GetFirstChild());
while( pframe )
{
pframe->FindBones( prootframe );
pframe = static_cast(pframe->GetNextSibling());
}
}