MeshX::MeshX(const char *xFileName) { this->mesh = NULL; HRESULT hr; animCtrl = 0; CreateWindowHandle(); CreateDirect3dDevice(); allocMeshHierarchy.setDevice(pDevice); //try to load skinned mesh hr = D3DXLoadMeshHierarchyFromXA(xFileName, D3DXMESH_SYSTEMMEM, pDevice, &allocMeshHierarchy, 0, /* ignore user data */ (D3DXFRAME**)&root, &animCtrl); if (FAILED(hr)) { throw std::bad_alloc(); } skinInfo = allocMeshHierarchy.GetMeshList().front()->pSkinInfo; BuildSkinnedMesh(); boneMatrices = new D3DXMATRIX[skinInfo->GetNumBones()]; boneMatrices3x4 = HQMatrix3x4::NewArray(skinInfo->GetNumBones()); }
//----------------------------------------------------------------------------- // The mesh class constructor. //----------------------------------------------------------------------------- Mesh::Mesh( char *name, char *path ) : Resource< Mesh >( name, path ) { // Create the list of reference points. m_frames = new LinkedList< Frame >; m_refPoints = new LinkedList< Frame >; // Load the mesh's frame hierarchy. AllocateHierarchy ah; D3DXLoadMeshHierarchyFromXA( GetFilename(), D3DXMESH_MANAGED, g_engine->GetDevice(), &ah, NULL, (D3DXFRAME**)&m_firstFrame, &m_animationController ); // Disable all the animation tracks initially. if( m_animationController != NULL ) for( unsigned long t = 0; t < m_animationController->GetMaxNumTracks(); ++t ) m_animationController->SetTrackEnable( t, false ); // Invalidate the bone transformation matrices array. m_boneMatrices = NULL; m_totalBoneMatrices = 0; // Prepare the frame hierarchy. PrepareFrame( m_firstFrame ); // Allocate memory for the bone matrices. m_boneMatrices = new D3DXMATRIX[m_totalBoneMatrices]; // Create a static (non-animated) version of the mesh. m_staticMesh = new MeshContainer; ZeroMemory( m_staticMesh, sizeof( MeshContainer ) ); // Load the mesh. ID3DXBuffer *materialBuffer, *adjacencyBuffer; D3DXLoadMeshFromXA( GetFilename(), D3DXMESH_MANAGED, g_engine->GetDevice(), &adjacencyBuffer, &materialBuffer, NULL, &m_staticMesh->NumMaterials, &m_staticMesh->originalMesh ); // Optimise the mesh for better rendering performance. m_staticMesh->originalMesh->OptimizeInplace( D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, (DWORD*)adjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ); // Finished with the adjacency buffer, so destroy it. SAFE_RELEASE( adjacencyBuffer ); // Check if the mesh has any materials. if( m_staticMesh->NumMaterials > 0 ) { // Create the array of materials. m_staticMesh->materials = new Material*[m_staticMesh->NumMaterials]; // Get the list of materials from the material buffer. D3DXMATERIAL *materials = (D3DXMATERIAL*)materialBuffer->GetBufferPointer(); // Load each material into the array via the material manager. for( unsigned long m = 0; m < m_staticMesh->NumMaterials; m++ ) { // Ensure the material has a texture. if( materials[m].pTextureFilename ) { // Get the name of the material's script and load it. char *name = new char[strlen( materials[m].pTextureFilename ) + 5]; sprintf( name, "%s.txt", materials[m].pTextureFilename ); m_staticMesh->materials[m] = g_engine->GetMaterialManager()->Add( name, GetPath() ); SAFE_DELETE_ARRAY( name ); } else m_staticMesh->materials[m] = NULL; } } // Create the bounding volume around the mesh. BoundingVolumeFromMesh( m_staticMesh->originalMesh ); // Destroy the material buffer. SAFE_RELEASE( materialBuffer ); // Create a vertex array and an array of indices into the vertex array. m_vertices = new Vertex[m_staticMesh->originalMesh->GetNumVertices()]; m_indices = new unsigned short[m_staticMesh->originalMesh->GetNumFaces() * 3]; // Use the arrays to store a local copy of the static mesh's vertices and // indices so that they can be used by the scene manager on the fly. Vertex* verticesPtr; m_staticMesh->originalMesh->LockVertexBuffer( 0, (void**)&verticesPtr ); unsigned short *indicesPtr; m_staticMesh->originalMesh->LockIndexBuffer( 0, (void**)&indicesPtr ); memcpy( m_vertices, verticesPtr, VERTEX_FVF_SIZE * m_staticMesh->originalMesh->GetNumVertices() ); memcpy( m_indices, indicesPtr, sizeof( unsigned short ) * m_staticMesh->originalMesh->GetNumFaces() * 3 ); m_staticMesh->originalMesh->UnlockVertexBuffer(); m_staticMesh->originalMesh->UnlockIndexBuffer(); }