⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nvworldtree.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*********************************************************************NVMH2****
Copyright (C) 1999, 2000 NVIDIA Corporation
This file is provided without support, instruction, or implied warranty of any
kind.  NVIDIA makes no guarantee of its fitness for a particular purpose and is
not liable under any circumstances for any damages or loss whatsoever arising
from the use or inability to use this file or items derived from it.

Comments:


******************************************************************************/


#include "nvworldtree.h"
#include "rmxfguid.h"
#include "rmxftmpl.h"

using namespace std;

namespace nv_objects
{

NVWorldTree::NVWorldTree()
	: m_vCenter(0.0f, 0.0f, 0.0f),
	m_fRadius(1.0f)
{
	m_pframeRoot = new NVWorldFrame(this, "WorldTreeRoot");
}

NVWorldTree::~NVWorldTree()
{
    SAFE_DELETE(m_pframeRoot);

}


NVWorldFrame* NVWorldTree::FindFrame(const char *szName)
{
	return m_pframeRoot->FindFrame(szName);
}

void NVWorldTree::UpdateFrames(const D3DXMATRIX* pmatCur, NVWorldFrame* pframeCur)
{
	if (pframeCur == NULL)
	{
		pframeCur = m_pframeRoot;
	}
	NVASSERT(pframeCur, "No Root Frame!");

    pframeCur->UpdateFrames(pmatCur);
}

// Walks from the designated world frame down and assigns all bones to meshes
// with bone data
HRESULT NVWorldTree::FindBones(NVWorldFrame* pRootFrame)
{
    HRESULT hr = S_OK;
    
	// Walk all the meshes
	tWorldFrames::const_iterator itrFrames = m_MeshFrames.begin();
	while (itrFrames != m_MeshFrames.end())
	{
		const tMeshes& Meshes = (*itrFrames)->GetMeshes();
		tMeshes::const_iterator itrMeshes = Meshes.begin();
		while (itrMeshes != Meshes.end())
		{
			NVComplexMesh* pMesh = *itrMeshes;

			for (DWORD i = 0; i < pMesh->GetNumBones(); ++i)
			{
				const char* pBoneName = pMesh->GetBoneName(i);
				NVASSERT(pBoneName, "Couldn't find bone " << i); 
				if (pBoneName)
				{
					NVWorldFrame* pFrame = pRootFrame->FindFrame(pBoneName);
					NVASSERT(pFrame, "Couldn't find bone " << pBoneName); 
					if (pFrame)
					{
						pMesh->SetBoneMatrixPtr(i, pFrame->GetCurrentTransform());
					}
				}
			}
    
			itrMeshes++;
		}
		itrFrames++;
	}
	
    return hr;
}


#ifdef _DEBUG
void NVWorldTree::Dump(NVWorldFrame* pframeCur)
{
	if (pframeCur == NULL)
	{
		pframeCur = m_pframeRoot;
	}
	pframeCur->Dump();
}
#endif

void NVWorldTree::SetTime(float fElapsedTime)
{
	m_fCurTime += fElapsedTime;
	
	tWorldFrames::iterator itrAnimationFrames = m_AnimationFrames.begin();
	while(itrAnimationFrames != m_AnimationFrames.end())
	{
		(*itrAnimationFrames)->SetTime(m_fCurTime);
		itrAnimationFrames++;
	}
}

void NVWorldTree::ComputeBounds(NVAABounds* pBounds)
{
	pBounds->m_vecCenter = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
	pBounds->m_fRadius = 0.0f;
	pBounds->m_vecMinExtents = D3DXVECTOR3(FLT_MAX, FLT_MAX, FLT_MAX);
	pBounds->m_vecMaxExtents = D3DXVECTOR3(-FLT_MAX, -FLT_MAX, -FLT_MAX);

	// Walk all the meshes
	tWorldFrames::const_iterator itrFrames = m_MeshFrames.begin();
	while (itrFrames != m_MeshFrames.end())
	{
	
		const tMeshes& Meshes = (*itrFrames)->GetMeshes();
		tMeshes::const_iterator itrMeshes = Meshes.begin();
		while (itrMeshes != Meshes.end())
		{
			NVComplexMesh* pMesh = *itrMeshes;

			NVAABounds ThisBounds;

			// Get the mesh extents
			pMesh->ComputeBounds(&ThisBounds);

			ThisBounds.Transform((*itrFrames)->GetCurrentTransform());

			pBounds->Add(&ThisBounds);

			itrMeshes++;
		}
		itrFrames++;
	}
	
	pBounds->CalculateCenterRadius();
}


HRESULT NVWorldTree::LoadXFile(LPDIRECT3DDEVICE8 pD3DDev, NVWorldFrame* pframeParent, const char* fileName)
{
    HRESULT hr = S_OK;
    LPDIRECTXFILE pxofapi = NULL;
    LPDIRECTXFILEENUMOBJECT pxofenum = NULL;
    LPDIRECTXFILEDATA pxofobjCur = NULL;
    DWORD dwOptions = 0;
    
    if (fileName == NULL)
        return E_INVALIDARG;

	// If there's a path to this file, jump to this directory to ensure correct loading of textures, etc.
	std::string strDirectory = fileName;
	std::string::size_type Pos = strDirectory.find_last_of("\\", strDirectory.size());
	if (Pos != strDirectory.npos)
	{
		strDirectory = strDirectory.substr(0, Pos);
	}										
	else
	{
		strDirectory = ".";
	}
	// Make sure we are in the right directory for any associated resources
	SetCurrentDirectory(strDirectory.c_str());

	// If we don't have a root frame, create it
	if (!m_pframeRoot)
	{
		m_pframeRoot = new NVWorldFrame(this, fileName);
	}

	// If they didn't specify a parent, make the root frame the parent.
	if (!pframeParent)
	{
		pframeParent = m_pframeRoot;
	}

	// Create a DX file API
    hr = DirectXFileCreate(&pxofapi);
    if (FAILED(hr))
        goto e_Exit;
    
    // Register templates for d3drm.
    hr = pxofapi->RegisterTemplates((LPVOID)D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES);
    if (FAILED(hr))
        goto e_Exit;
    
    // Create enum object.
    hr = pxofapi->CreateEnumObject((LPVOID)fileName, DXFILELOAD_FROMFILE, &pxofenum);
    if (FAILED(hr))
        goto e_Exit;
        
    // Enumerate top level objects.
    // Top level objects are always data object.
    while (SUCCEEDED(pxofenum->GetNextDataObject(&pxofobjCur)))
    {
        hr = LoadXFileFrames(pD3DDev, pxofobjCur, dwOptions, m_pframeRoot);
        SAFE_RELEASE(pxofobjCur);
        
        if (FAILED(hr))
            goto e_Exit;
    }
    
    hr = FindBones(pframeParent);
    if (FAILED(hr))
        goto e_Exit;
 
	m_fCurTime = 0.0f;
    m_fMaxTime = 200.0f;
    
	m_pframeRoot->m_matRotOrig = m_pframeRoot->m_matRot;

    
e_Exit:
    SAFE_RELEASE(pxofobjCur);
    SAFE_RELEASE(pxofenum);
    SAFE_RELEASE(pxofapi);
    
    NVASSERT(SUCCEEDED(hr), "Couldn't load .x file!");
    
    return hr;
}

HRESULT NVWorldTree::LoadXFileMesh(LPDIRECT3DDEVICE8 pD3DDevice, LPDIRECTXFILEDATA pxofobjCur, DWORD options, NVWorldFrame* pframeParent)
{
    HRESULT hr = S_OK;
    DWORD cchName;
	NVComplexMesh* pMesh = NULL;
    
    hr = pxofobjCur->GetName(NULL, &cchName);
    if (FAILED(hr))
	{
		NVASSERT(0, "Could not get Mesh name!");
		return hr;
	}

	std::string strMeshName;
	strMeshName.resize(cchName);
    hr = pxofobjCur->GetName(&strMeshName[0], &cchName);
    if (FAILED(hr))
	{
		NVASSERT(0, "Could not get Mesh name!");
		return hr;
	}
	
	pMesh = new NVComplexMesh();
	
	if (pMesh->CreateFromXof(pD3DDevice, pxofobjCur))
	{
	    // add the mesh to the parent frame
		pframeParent->AddMesh(pMesh);
	}
	else
	{
		SAFE_DELETE(pMesh);
	}
   
    return hr;
}


HRESULT NVWorldTree::LoadXFileFrames(LPDIRECT3DDEVICE8 pD3DDevice, LPDIRECTXFILEDATA pxofobjCur, DWORD options, NVWorldFrame* pframeParent)
{
    HRESULT hr = S_OK;
    LPDIRECTXFILEDATA pxofobjChild = NULL;
    LPDIRECTXFILEOBJECT pxofChild = NULL;
    const GUID *type;
    DWORD cbSize;
    D3DXMATRIX *pmatNew;
    NVWorldFrame *pframeCur;
    DWORD cchName;
    
    // Get the type of the object
    hr = pxofobjCur->GetType(&type);
    if (FAILED(hr))
        goto e_Exit;
    
    
    if (*type == TID_D3DRMMesh)
    {
        hr = LoadXFileMesh(pD3DDevice, pxofobjCur, options, pframeParent);
        if (FAILED(hr))
            goto e_Exit;
    }
    else if (*type == TID_D3DRMFrameTransformMatrix)
    {
        hr = pxofobjCur->GetData(NULL, &cbSize, (PVOID*)&pmatNew);
        if (FAILED(hr))
            goto e_Exit;
        
        // update the parents matrix with the new one
	    pframeParent->m_matRot = *pmatNew;
        pframeParent->m_matRotOrig = *pmatNew;
    }
    else if (*type == TID_D3DRMAnimationSet)
    {
	    LoadXFileAnimationSet(pD3DDevice, pxofobjCur, options, pframeParent);
    }
    else if (*type == TID_D3DRMAnimation)
    {
        LoadXFileAnimation(pD3DDevice, pxofobjCur, options, pframeParent);
    }
    else if (*type == TID_D3DRMFrame)
    {
        hr = pxofobjCur->GetName(NULL, &cchName);
        if (FAILED(hr))
            goto e_Exit;

       	std::string strFrameName;
		strFrameName.resize(cchName);
		hr = pxofobjCur->GetName(&strFrameName[0], &cchName);
		if (FAILED(hr))
			goto e_Exit;

		pframeCur = new NVWorldFrame(this, strFrameName.c_str());
        if (pframeCur == NULL)
        {
            hr = E_OUTOFMEMORY;
            goto e_Exit;
        }
   
        pframeParent->AddChildFrame(pframeCur);
        
        // Enumerate child objects.
        // Child object can be data, data reference or binary.
        // Use QueryInterface() to find what type of object a child is.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -