void XFileUtils::LoadChild( GLoadCallback& call, ID3DXFileEnumObject* pObject ) { { 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); } } while (!m_LoadStack.empty()) { ID3DXFileData* pLoadFileData = m_LoadStack.back(); m_LoadStack.pop_back(); int ss = m_LoadStack.size(); GUID gGuid = { 0 }; pLoadFileData->GetType(&gGuid); call.Excute(gGuid, pLoadFileData); 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); } } }
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; }
bool XFileUtils::LoadFrameHierarchy( ID3DXFileEnumObject* pFileData, IDirect3DDevice9* pDevice, GFrameContainer** pNewFrameContainer) { GFrameContainer* pFrameContainer = new GFrameContainer(); SIZE_T numChild = 0; pFileData->GetChildren(&numChild); struct FrameFD { GFrame* pFrame; ID3DXFileData* pFileData; }; //读取用栈 std::vector<FrameFD> FrameStack; //框架GUID const GUID& frameGuid = _XTemplate("Frame"); //创建根框架 GFrame* pRootFrame = new GFrame(); pRootFrame->Name = GROOTFRAME; pFrameContainer->m_pRootFrames = pRootFrame; pFrameContainer->InsertFrame(pRootFrame); //得到第一层 框架 //********************************* { GFrame* pPreSiblingFrame = nullptr; for (size_t i = 0; i < numChild; ++i) { ID3DXFileData* pTopFileData = nullptr; GFrame* pTopChild = nullptr; pFileData->GetChild(i, &pTopFileData); GUID cguid; pTopFileData->GetType(&cguid); if (cguid == frameGuid) { if (!LoadFrame(pTopFileData, pDevice, &pTopChild)) return false; if (pRootFrame->pFrameFirstChild == nullptr) { pRootFrame->pFrameFirstChild = pTopChild; pFrameContainer->InsertFrame(pTopChild); pPreSiblingFrame = pTopChild; } else { pPreSiblingFrame->pFrameSibling = pTopChild; pPreSiblingFrame = pTopChild; } FrameFD fd; fd.pFileData = pTopFileData; fd.pFrame = pTopChild; FrameStack.push_back(fd); } } } //********************************* //得到第一层 框架 while (!FrameStack.empty()) { //上一个兄弟节点 GFrame* pPreSiblingFrame = nullptr; //栈弹出 FrameFD fd = FrameStack.back(); FrameStack.pop_back(); GFrame* pParentFrame = fd.pFrame; ID3DXFileData* pParentFileData = fd.pFileData; //得到孩子个数 SIZE_T numChild = 0; pParentFileData->GetChildren(&numChild); //开始解析该节点的孩子 for (size_t i = 0; i < numChild; ++i) { //读取孩子 ID3DXFileData* pChildFileData = nullptr; pParentFileData->GetChild(i, &pChildFileData); GFrame* pChildFrame = nullptr; //解析该 孩子框架,失败进入条件返回 false GUID cguid; pChildFileData->GetType(&cguid); if (cguid != frameGuid) continue; if (!LoadFrame(pChildFileData, pDevice, &pChildFrame)) { char DebugText[512] = { 0 }; sprintf_s(DebugText, "LoadFrame Error: %s \n", pParentFrame->Name.c_str()); OutputDebugStringA(DebugText); continue; } if (pPreSiblingFrame == nullptr) { //如果是第一个孩子节点,则将pFirstChild指向该节点, //并将preSiblingFrame指针指向它, 并压入解析用栈 pParentFrame->pFrameFirstChild = pChildFrame; pPreSiblingFrame = pChildFrame; } else { //上一个兄弟节点指针连接, preSiblingFrame指针往下移 pPreSiblingFrame->pFrameSibling = pChildFrame; pPreSiblingFrame = pChildFrame; } FrameFD tmp_fd; tmp_fd.pFrame = pChildFrame; tmp_fd.pFileData = pChildFileData; FrameStack.push_back(tmp_fd); pFrameContainer->InsertFrame(pChildFrame); } } *pNewFrameContainer = pFrameContainer; return true; }
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); } } }