www.pudn.com > DirectX source.zip > CSkinMesh.cpp
/*! @file : CSkinMesh.cpp Contains the implementation of class CSkinMesh @author Sarmad Kh. Abdulla */ //------------------------------------------------------------------------------ //////////////////////////////////////////////////////////////////////////////// // Header files #include "stdafx.h" #include/*! * Create the skin mesh from an x file. * * @param filename : The name of the x file * @param pd3ddevice : A pointer to the D3D device object * * @return void : */ void CSkinMesh::Create( const char * filename, LPDIRECT3DDEVICE8 pd3ddevice ) { HRESULT result; // Create an x file LPDIRECTXFILE pxofapi; result = DirectXFileCreate( &pxofapi ); if( FAILED(result) ) throw new CDXException( "Couldn't create IDirectXFile", result ); // Register templates for d3drm. result = pxofapi->RegisterTemplates((LPVOID)D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES); if( FAILED( result ) ) { SAFERELEASE( pxofapi ); throw new CDXException( "Couldn't register D3DRM templates", result ); } // create the enum object LPDIRECTXFILEENUMOBJECT pxofenum; result = pxofapi->CreateEnumObject( (LPVOID)filename, DXFILELOAD_FROMFILE, &pxofenum); if( FAILED( result ) ) { SAFERELEASE( pxofapi ); throw new CDXException( "Couldn't create x file enum object", result ); } // Enumerate top level objects. // Top level objects are always data object. LPDIRECTXFILEDATA pxofobj; while( SUCCEEDED(pxofenum->GetNextDataObject( &pxofobj )) ) { try { RootFrame.Load( pxofobj, pd3ddevice, this ); } catch(...) { SAFERELEASE( pxofapi ); SAFERELEASE( pxofenum ); SAFERELEASE( pxofobj ); throw; } pxofobj->Release(); } // Find the bones of this hierarchy FindBones(); // release SAFERELEASE( pxofapi ); SAFERELEASE( pxofenum ); SAFERELEASE( pxofobj ); } /*! * Destroy the object * * @param void : * * @return void : */ void CSkinMesh::Destroy( void ) { RootFrame.Destroy(); Animations.Destroy(); } /*! * Load an animation from an x file data object * * @param pxofobj : The x file data object to load from * @param pparent : The parent node on which to attach the new created animation node. * Specify NULL to add the animation at the root level (if the animation is not * part of an animation set). * * @return void : */ void CSkinMesh::LoadAnimation( LPDIRECTXFILEDATA pxofobj, CAnimationNode * pparent ) { // if no parent node is specified, take the head of the list if( pparent == NULL ) pparent = &Animations; // create the new object CAnimationNode * panimation = new CAnimationNode; SAFEPOINTER( panimation ); pparent->AttachChild( *panimation ); // load the animation LPDIRECTXFILEOBJECT pxofchildobj; while( SUCCEEDED( pxofobj->GetNextObject( &pxofchildobj ) ) ) { panimation->Load( pxofchildobj ); } } /*! * Load an animation set from an x file data object. * * @param pxofobj : The x file data object to load from. * * @return void : */ void CSkinMesh::LoadAnimationSet( LPDIRECTXFILEDATA pxofobj ) { // create the animation object CAnimationNode * panimationset = new CAnimationNode; SAFEPOINTER( panimationset ); Animations.AttachChild( *panimationset ); // set the name of the animation set char * szname; DWORD dwnamelength; HRESULT result; result = pxofobj->GetName( NULL, &dwnamelength ); if( FAILED( result ) ) throw new CDXException( "Couldn't get animation set name", result ); if( dwnamelength > 0 ) { szname = new char[dwnamelength]; SAFEPOINTER( szname ); result = pxofobj->GetName( szname, &dwnamelength ); if( FAILED( result ) ) { delete[] szname; throw new CDXException( "Couldn't get animation set name", result ); } panimationset->SetName( szname ); } // query through the child objects to load the animations LPDIRECTXFILEOBJECT pxofchildobj; LPDIRECTXFILEDATA pxofchilddataobj; const GUID *type; while( SUCCEEDED( pxofobj->GetNextObject( &pxofchildobj ) ) ) { // Query the child for it's FileData result = pxofchildobj->QueryInterface( IID_IDirectXFileData, (LPVOID *)&pxofchilddataobj); if( SUCCEEDED( result ) ) { result = pxofchilddataobj->GetType( &type ); if( FAILED( result ) ) { pxofchildobj->Release(); pxofchilddataobj->Release(); throw new CDXException( "Couldn't get object type while loading animation set", result ); } if( TID_D3DRMAnimation == *type ) LoadAnimation( pxofchilddataobj, panimationset ); pxofchilddataobj->Release(); } pxofchildobj->Release(); } } /*! * Find the bones for each skin mesh * * @param void : * * @return void : */ void CSkinMesh::FindBones( void ) { RootFrame.FindBones( &RootFrame ); Animations.FindBone( &RootFrame ); } /*! * Render the mesh to the given device * * @param pd3ddevice : The device to render on * @param pd3dxms : The matrix stack to get the world matrix from * * @return void : */ void CSkinMesh::Render( LPDIRECT3DDEVICE8 pd3ddevice, LPD3DXMATRIX pworldmat ) { // calculate world matrix of all bones RootFrame.Update( pworldmat ); // render the meshes RootFrame.Render( pd3ddevice ); }