Exemple #1
0
VOID parseXFile(ID3DXFile* lpXFile)
{
	if(lpXFile == NULL)
	{
		return;
	}

	ID3DXFileEnumObject* lpEnum;
	if(FAILED(lpXFile->CreateEnumObject("Warrior.x", D3DXF_FILELOAD_FROMFILE, &lpEnum)))
	{
		return;
	}

	SIZE_T numChildren;
	if(FAILED(lpEnum->GetChildren(&numChildren)))
	{
		lpEnum->Release();
		return;
	}

	for (SIZE_T i = 0; i < numChildren; ++i)
	{
		ID3DXFileData* lpXFileData;
		if(FAILED(lpEnum->GetChild(i, &lpXFileData)))
		{
			break;
		}
		parseXFileData(lpXFileData, 0);
		lpXFileData->Release();
	}

	lpEnum->Release();
}
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);
		}
	}
}
Exemple #3
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);
	}
}
ID3DXFileData* XFileUtils::SearchChild(
	const GUID& guid, ID3DXFileData* pFileData, size_t offset /*= 0*/ )
{
	SIZE_T numChild = 0;
	pFileData->GetChildren(&numChild);
	for (size_t i = offset; i < numChild; ++i)
	{
		GUID cguid;
		ID3DXFileData* pChild = nullptr;
		pFileData->GetChild(i, &pChild);
		pChild->GetType(&cguid);
		if(guid == cguid)
			return pChild;
	}
	return nullptr;
}
size_t XFileUtils::GetChildCountByGuid( const GUID& guid, ID3DXFileData* pFileData )
{
	size_t sumChild = 0;
	SIZE_T numChild = 0;
	pFileData->GetChildren(&numChild);
	for (size_t i = 0; i < numChild; ++i)
	{
		ID3DXFileData* pChild = nullptr;
		GUID cguid;
		pFileData->GetChild(i, &pChild);
		pChild->GetType(&cguid);

		if(cguid == guid)
			++sumChild;
	}

	return sumChild;
}
Exemple #6
0
VOID parseXFileData(ID3DXFileData* lpXFileData, INT depth)
{
	if(lpXFileData == NULL || lpXFileData->IsReference())
	{
		return;
	}

	SIZE_T nameSize;
	CHAR* lpName;
	if(FAILED(lpXFileData->GetName(NULL, &nameSize)))
	{
		return;
	}
	lpName = new CHAR[nameSize];
	if(FAILED(lpXFileData->GetName(lpName, &nameSize)))
	{
		delete []lpName;
		return;
	}

	CHAR* lpTab = NULL;
	if(depth > 0)
	{
		lpTab = new CHAR[depth + 1];
		for (INT depthIndex = 0; depthIndex < depth; ++depthIndex)
		{
			lpTab[depthIndex] = '	';
		}
		lpTab[depth] = '\0';
	}

	GUID guid;
	if(FAILED(lpXFileData->GetType(&guid)))
	{
		delete []lpName;
		delete []lpTab;
		return;
	}

	char* tmpl = 
		guid == TID_D3DRMFrame ? "Frame" : 
		guid == TID_D3DRMFrameTransformMatrix ? "FrameTransformMatrix" : 
		guid == TID_D3DRMMeshMaterialList ? "MeshMaterialList" : 
		guid == TID_D3DRMMeshTextureCoords ? "MeshTextureCoords" : 
		guid == TID_D3DRMMeshNormals ? "MeshNormal" : 
		guid == TID_D3DRMMesh ? "Mesh" : 
		guid == TID_D3DRMMaterial ? "Material" : 
		guid == TID_D3DRMTextureFilename ? "TextureFilename" : NULL;

	trace2("%s%s", lpTab == NULL ? "" : lpTab,"---------------------------------------------------\n");
	trace3("%sname:%s, tmpl:%s\n", lpTab == NULL ? "" : lpTab, lpName, tmpl == NULL ? "" : tmpl);
	delete []lpName;
	delete []lpTab;

	SIZE_T numChildren;
	if(FAILED(lpXFileData->GetChildren(&numChildren)))
	{
		return;
	}
	for (SIZE_T i = 0; i < numChildren; ++i)
	{
		ID3DXFileData* lpXFileSubData;
		if(FAILED(lpXFileData->GetChild(i, &lpXFileSubData)))
		{
			return;
		}
		parseXFileData(lpXFileSubData, depth + 1);
		lpXFileSubData->Release();
	}
}
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);
		}
	}
}