📄 scenereader.cpp
字号:
// SceneReader.cpp: implementation of the CSceneReader class.
//
//////////////////////////////////////////////////////////////////////
#include "SceneReader.h"
#include "modstack.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSceneReader::CSceneReader(IScene *pScene, Interface *itr)
{
m_pScene = pScene;
m_pInterface = itr;
m_pGameScene = GetIGameInterface();
m_pGameScene->InitialiseIGame(false);
m_pGameScene->SetStaticFrame(0);
m_bExportSelected = FALSE;
}
CSceneReader::~CSceneReader()
{
}
// -------------------------------------------------------------------------------
// function FindRootNode
//
// devnote Finds the root node of the scene by aborting a tree walk after the first node
//
// returns S_OK if a node is found, E_FAIL if not
//
HRESULT CSceneReader::FindRootNode (INode **ppNode )
{
CFindRootNode RootNode;
// grab the first node of the scene graph
m_pScene->EnumTree(&RootNode);
*ppNode = RootNode.m_pNodeRoot;
return RootNode.m_pNodeRoot != NULL ? S_OK : E_FAIL;
}
// ================================================== IsExportableMesh()
BOOL CSceneReader::IsExportableMesh(INode* pNode, Object* &pObj)
{
ULONG superClassID;
assert(pNode);
pObj = pNode->EvalWorldState(m_pMesh->m_startTime).obj;
if (pObj == NULL)
{
return FALSE;
}
superClassID = pObj->SuperClassID();
//find out if mesh is renderable
if( !pNode->Renderable() || pNode->IsNodeHidden() || (m_bExportSelected&&pNode->Selected()==0))
{
return FALSE;
}
BOOL bFoundGeomObject = FALSE;
//find out if mesh is renderable (more)
switch(superClassID)
{
case GEN_DERIVOB_CLASS_ID:
do
{
pObj = ((IDerivedObject*)pObj)->GetObjRef();
superClassID = pObj->SuperClassID();
}
while( superClassID == GEN_DERIVOB_CLASS_ID );
switch(superClassID)
{
case GEOMOBJECT_CLASS_ID:
bFoundGeomObject = TRUE;
break;
}
break;
case GEOMOBJECT_CLASS_ID:
bFoundGeomObject = TRUE;
default:
break;
}
return bFoundGeomObject;
}
void CSceneReader::ParseScene(BOOL bExportSelected)
{
if (m_pMesh == NULL || m_pScene == NULL)
return;
m_bExportSelected = bExportSelected;
INode *pRootNode;
Interval intv = m_pInterface->GetAnimRange();
//get animation time data
m_pMesh->m_interval = GetTicksPerFrame();
m_pMesh->m_startTime = intv.Start();
m_pMesh->m_endTime = intv.End();
m_pMesh->m_FameCount = 1+(m_pMesh->m_endTime - m_pMesh->m_startTime)/m_pMesh->m_interval;
m_pMesh->GetBones();
// first find the root node
HRESULT hr = FindRootNode(&pRootNode);
//find every mesh
EnumTreeNode(pRootNode);
m_pMesh->MergeSubmesh();
}
HRESULT CSceneReader::EnumTreeNode(INode *pNode)
{
if (pNode == NULL)
return S_OK;
Object *pObj;
BOOL bNeedDelete;
TriObject *pTriObject = NULL;
Mesh *pMesh;
FindTextureFilename findTextureFilename;
IGameNode *pGameNode;
if (IsExportableMesh(pNode, pObj))
{
pNode->EvalWorldState(m_pMesh->m_startTime);
pTriObject = GetTriObjectFromObjRef(pObj, &bNeedDelete);
//get triobject data
if (pTriObject != NULL)
{
pMesh = &(pTriObject->mesh);
//read tri data and material data to m_pMesh
//m_pMesh->AddMeshData(pMesh, pNode->GetMtl(), pNode);
pGameNode = m_pGameScene->GetIGameNode(pNode);
m_pMesh->AddSubMeshData(pMesh, pNode->GetMtl(), pNode, pGameNode);
if (bNeedDelete)
{
delete pTriObject;
}
}
}
int cChildren = pNode->NumberOfChildren();
for (int iChild = 0; iChild < cChildren; iChild++)
{
// enumerate the child
EnumTreeNode(pNode->GetChildNode(iChild));
}
return S_OK;
}
// ================================================== GetTriObjectFromObjRef
// Return a pointer to a TriObject given an object reference or return NULL
// if the node cannot be converted to a TriObject
TriObject *CSceneReader::GetTriObjectFromObjRef( Object* pObj, BOOL *pbDeleteIt)
{
TriObject *pTri;
*pbDeleteIt = FALSE;
if (pObj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0)))
{
pTri = (TriObject *) pObj->ConvertToType(0, Class_ID(TRIOBJ_CLASS_ID, 0));
// Note that the TriObject should only be deleted
// if the pointer to it is not equal to the object
// pointer that called ConvertToType()
if (pObj != pTri)
*pbDeleteIt = TRUE;
return pTri;
}
else
{
return NULL;
}
}
void CSceneReader::SetMaxMesh(CMaxMesh *pMesh)
{
m_pMesh = pMesh;
pMesh->m_pScene = m_pGameScene;
}
void CSceneReader::ExportSelectedNodePath(const char * filename)
{
if (m_pScene == NULL)
return;
INode *pRootNode;
Interval intv = m_pInterface->GetAnimRange();
char temp[256];
strcpy(temp, filename);
int len = strlen(temp);
temp[len-4] = 't';
temp[len-3] = 'x';
temp[len-2] = 't';
temp[len-1] = 0;
ofstream fout(temp);
//get animation time data
int interval = GetTicksPerFrame();
int startTime = intv.Start();
int endTime = intv.End();
// first find the root node
HRESULT hr = FindRootNode(&pRootNode);
//find every mesh
EnumSelectedNode(fout, pRootNode, interval, startTime, endTime);
}
//# define PI 3.1415926
void CSceneReader::EnumSelectedNode(ofstream &fout, INode *pNode, int intv, int start, int end)
{
if (pNode == NULL)
return;
pNode->EvalWorldState(0);
if (pNode->Selected())
{
Matrix3 matrix;
Point3 pt;
fout<<pNode->GetName()<<endl;
for (int time=start; time<=end; time+=intv)
{
pNode->EvalWorldState(time);
matrix = pNode->GetNodeTM(time);
pt = matrix.GetTrans();
fout<<(int)pt.x<<", "<<(int)pt.y<<", "<<(int)pt.z<<"; ";
matrix.GetYawPitchRoll(&pt.x, &pt.y, &pt.z);
fout.width(10);
fout<<(int)(pt.x*1024/PI)<<", "<<(int)(pt.y*1024/PI)<<", "<<(int)(pt.z*1024/PI)<<";\n";
}
fout<<"\n";
}
int cChildren = pNode->NumberOfChildren();
for (int iChild = 0; iChild < cChildren; iChild++)
{
// enumerate the child
EnumSelectedNode(fout, pNode->GetChildNode(iChild), intv, start, end);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -