Exemple #1
0
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);
		}
	}
}