VOID JCXFile::parseChildren(ID3DXFileData* lpXFileData, BOOL isReference, ID3DXFileData* lpXFileDataParent, VOID* lpDataParent) { if(lpXFileData == NULL) { return; } GUID guid; xVerifyFailedIf(lpXFileData->GetType(&guid)) return; xVerifyFailedEndIf VOID* lpData = parseChild(lpXFileData, isReference || lpXFileData->IsReference(), lpXFileDataParent, lpDataParent, &guid); SIZE_T numChlidren; xVerifyFailedIf(lpXFileData->GetChildren(&numChlidren)) return; xVerifyFailedEndIf for (SIZE_T childIndex = 0; childIndex < numChlidren; ++childIndex) { ID3DXFileData* lpChildXFileData = NULL; xVerifyFailedIf(lpXFileData->GetChild(childIndex, &lpChildXFileData)) return; xVerifyFailedEndIf parseChildren(lpChildXFileData, isReference || lpXFileData->IsReference() || lpChildXFileData->IsReference(), lpXFileData, lpData); jccommon_releaseComM(lpChildXFileData); } }
void cMesh::ParseXFileData(ID3DXFileData *pDataObj, sFrame *ParentFrame, char *TexturePath) { ID3DXFileData *pSubObj = NULL; ID3DXFileData *pSubData = NULL; IDirectXFileDataReference *pDataRef = NULL; GUID Type = GUID_NULL; char *Name = NULL; DWORD Size; sFrame *SubFrame = NULL; char Path[MAX_PATH]; sFrame *Frame = NULL; //D3DXMATRIX *FrameMatrix = NULL; sMesh *Mesh = NULL; ID3DXBuffer *MaterialBuffer = NULL; D3DXMATERIAL *Materials = NULL; ID3DXBuffer *Adjacency = NULL; DWORD *AdjacencyIn = NULL; DWORD *AdjacencyOut = NULL; DWORD i; BYTE **Ptr; // Get the template type if(FAILED(pDataObj->GetType((&Type)))) return; // Get the template name (if any) if(FAILED(pDataObj->GetName(NULL, &Size))) return; if(Size) { if((Name = new char[Size]) != NULL) pDataObj->GetName(Name, &Size); } // Give template a default name if none found if(Name == NULL) { if((Name = new char[9]) == NULL) return; strcpy(Name, "$NoName$"); } // Set sub frame SubFrame = ParentFrame; // Process the templates // Frame if(IsEqualGUID(Type, TID_D3DRMFrame)) { // Create a new frame structure Frame = new sFrame(); // Store the name Frame->m_Name = Name; Name = NULL; // Add to parent frame Frame->m_Parent = ParentFrame; Frame->m_Sibling = ParentFrame->m_Child; ParentFrame->m_Child = Frame; // Increase frame count m_NumFrames++; // Set sub frame parent SubFrame = Frame; } // Frame transformation matrix if(Type == TID_D3DRMFrameTransformMatrix) { BYTE** DataPtr = NULL; if(FAILED(pDataObj->Lock(&Size, (LPCVOID*)&DataPtr))) return; memcpy(&ParentFrame->m_matOriginal, (void*)DataPtr, Size); pDataObj->Unlock(); } // Mesh if(Type == TID_D3DRMMesh) { // See if mesh already loaded if(m_Meshes == NULL || m_Meshes->FindMesh(Name) == NULL) { // Create a new mesh structure Mesh = new sMesh(); // Store the name Mesh->m_Name = Name; Name = NULL; // Load mesh data if(FAILED(D3DXLoadSkinMeshFromXof(pDataObj, 0, m_Graphics->GetDeviceCOM(), &Adjacency, &MaterialBuffer, NULL, &Mesh->m_NumMaterials, &Mesh->m_SkinInfo, &Mesh->m_Mesh))) { delete Mesh; return; } // Calculate the bounding box and sphere if(SUCCEEDED(Mesh->m_Mesh->LockVertexBuffer(D3DLOCK_READONLY, (void**)&Ptr))) { D3DXComputeBoundingBox((D3DXVECTOR3*)Ptr, Mesh->m_Mesh->GetNumVertices(), Mesh->m_Mesh->GetNumBytesPerVertex(), &Mesh->m_Min, &Mesh->m_Max); D3DXComputeBoundingSphere((D3DXVECTOR3*)Ptr, Mesh->m_Mesh->GetNumVertices(), Mesh->m_Mesh->GetNumBytesPerVertex(), &D3DXVECTOR3(0.0f,0.0f,0.0f), &Mesh->m_Radius); Mesh->m_Mesh->UnlockVertexBuffer(); } // Store # of bones (if any) if(Mesh->m_SkinInfo) Mesh->m_NumBones = Mesh->m_SkinInfo->GetNumBones(); // Create a matching skinned mesh if bone exist if(Mesh->m_SkinInfo != NULL && Mesh->m_NumBones != 0) { if(FAILED(Mesh->m_Mesh->CloneMeshFVF(0, Mesh->m_Mesh->GetFVF(), m_Graphics->GetDeviceCOM(), &Mesh->m_SkinMesh))) ReleaseCOM(Mesh->m_SkinInfo); } // Create an array of matrices to store bone transformations if(Mesh->m_SkinInfo != NULL && Mesh->m_NumBones != 0) { // Create the bone matrix array and clear it out Mesh->m_Matrices = new D3DXMATRIX[Mesh->m_NumBones]; for(i=0;i<Mesh->m_NumBones;i++) D3DXMatrixIdentity(&Mesh->m_Matrices[i]); // Create the frame mapping matrix array and clear out Mesh->m_FrameMatrices = new D3DXMATRIX*[Mesh->m_NumBones]; for(i=0;i<Mesh->m_NumBones;i++) Mesh->m_FrameMatrices[i] = NULL; } // Load materials or create a default one if none if(!Mesh->m_NumMaterials) { // Create a default one Mesh->m_Materials = new D3DMATERIAL9[1]; Mesh->m_Textures = new LPDIRECT3DTEXTURE9[1]; ZeroMemory(Mesh->m_Materials, sizeof(D3DMATERIAL9)); Mesh->m_Materials[0].Diffuse.r = 1.0f; Mesh->m_Materials[0].Diffuse.g = 1.0f; Mesh->m_Materials[0].Diffuse.b = 1.0f; Mesh->m_Materials[0].Diffuse.a = 1.0f; Mesh->m_Materials[0].Ambient = Mesh->m_Materials[0].Diffuse; Mesh->m_Materials[0].Specular = Mesh->m_Materials[0].Diffuse; Mesh->m_Textures[0] = NULL; Mesh->m_NumMaterials = 1; } else { // Load the materials Materials = (D3DXMATERIAL*)MaterialBuffer->GetBufferPointer(); Mesh->m_Materials = new D3DMATERIAL9[Mesh->m_NumMaterials]; Mesh->m_Textures = new LPDIRECT3DTEXTURE9[Mesh->m_NumMaterials]; for(i=0;i<Mesh->m_NumMaterials;i++) { Mesh->m_Materials[i] = Materials[i].MatD3D; Mesh->m_Materials[i].Ambient = Mesh->m_Materials[i].Diffuse; // Build a texture path and load it sprintf(Path, "%s%s", TexturePath, Materials[i].pTextureFilename); if(FAILED(D3DXCreateTextureFromFile(m_Graphics->GetDeviceCOM(), Path, &Mesh->m_Textures[i]))) { Mesh->m_Textures[i] = NULL; } } } ReleaseCOM(MaterialBuffer); // link in mesh Mesh->m_Next = m_Meshes; m_Meshes = Mesh; m_NumMeshes++; } else { // Find mesh in list Mesh = m_Meshes->FindMesh(Name); } // Add mesh to frame if(Mesh != NULL) ParentFrame->AddMesh(Mesh); } // Skip animation sets and animations if(Type == TID_D3DRMAnimationSet || Type == TID_D3DRMAnimation || Type == TID_D3DRMAnimationKey) { delete [] Name; return; } // Release name buffer delete [] Name; SIZE_T count; if (FAILED(pDataObj->GetChildren(&count))) return; SIZE_T c = 0; // Scan for embedded templates while(c < count) { if (FAILED(pDataObj->GetChild(c, &pSubObj))) break; c++; // Process embedded references if (pSubObj->IsReference()) { if (SUCCEEDED(pSubObj->GetChild(0, &pSubData))) { ParseXFileData(pSubData, SubFrame, TexturePath); ReleaseCOM(pSubData); } } /*if(SUCCEEDED(pSubObj->QueryInterface(IID_IDirectXFileDataReference, (void**)&pDataRef))) { if(SUCCEEDED(pDataRef->Resolve(&pSubData))) { ParseXFileData(pSubData, SubFrame, TexturePath); ReleaseCOM(pSubData); } ReleaseCOM(pDataRef); }*/ // Process non-referenced embedded templates if(SUCCEEDED(pSubObj->QueryInterface(IID_ID3DXFileData, (void**)&pSubData))) { ParseXFileData(pSubData, SubFrame, TexturePath); ReleaseCOM(pSubData); } ReleaseCOM(pSubObj); } return; }
void XFileUtils::PrintAll( ID3DXFileEnumObject* pObject, std::ostream& os) { std::vector<size_t> stack_depth; //保存节点深度 { SIZE_T numChild = 0; pObject->GetChildren(&numChild); for (SIZE_T i = numChild - 1; i >= 0 && i < numChild; --i) { ID3DXFileData* pFileData = nullptr; pObject->GetChild(i, &pFileData); m_LoadStack.push_back(pFileData); stack_depth.push_back(1); } } while (!m_LoadStack.empty()) { ID3DXFileData* pLoadFileData = m_LoadStack.back(); m_LoadStack.pop_back(); size_t depth = stack_depth.back(); stack_depth.pop_back(); int ss = m_LoadStack.size(); GUID gGuid = { 0 }; char name[128] = { 0 }; SIZE_T nameLen = 128; pLoadFileData->GetType(&gGuid); pLoadFileData->GetName(name, &nameLen); const std::string& typeName = getStringFromGuid(gGuid); { for (size_t i = 0; i < depth - 1; ++i) os.write(" ", 2); if (pLoadFileData->IsReference()) { os.write("[", 1); } os.write(typeName.c_str(), typeName.size()); os.write(" ", 1); os.write(name, strlen(name)); if (pLoadFileData->IsReference()) { os.write("]", 1); os.write("\n", 1); continue; } os.write("\n", 1); } SIZE_T numChild = 0; pLoadFileData->GetChildren(&numChild); for (SIZE_T i = numChild - 1; i >= 0 && i < numChild; --i) { ID3DXFileData* pInsertFileData = nullptr; pLoadFileData->GetChild(i, &pInsertFileData); m_LoadStack.push_back(pInsertFileData); stack_depth.push_back(depth + 1); } } }