📄 gnode.cpp
字号:
//--------------------------------------------------
// Desc: Game Object Node
// Author: artsylee/2007.3.12
//--------------------------------------------------
#include <assert.h>
#include "GMath.h"
#include "GNode.h"
#include "Common.h"
#include "NodeManager.h"
#include "MS3DLoader.h"
extern CNodeManager g_NodeManager;
char* szNodeTypeName[] =
{
"Default",
"MS3D Model",
"X Model",
"X Skin Model",
"Water",
"Camera"
};
GNode::GNode():
m_bCachedOutOfDate(true),
m_vRotate(0.0f, 0.0f, 0.0f),
m_vPos(0.0f, 0.0f, 0.0f),
m_vScale(1.0f, 1.0f, 1.0f),
m_vDerivedScale(1.0f, 1.0f, 1.0f),
m_vDerivedPos(0.0f, 0.0f, 0.0f),
m_pParent(NULL),
m_bUpdateFromParent(true),
m_bRotateFromParent(true),
m_bScaleFromParent(true),
m_bIsUseParentMatrix(false)
{
D3DXMatrixIdentity(&m_ParentMatrix);
D3DXMatrixIdentity(&m_Orientation);
D3DXMatrixIdentity(&m_DerivedOrientation);
m_Children.clear();
m_NodeType = NT_DEFAULT;
strcpy(m_szName, "NoName");
g_NodeManager.AddNode(this);
}
GNode::~GNode()
{
//----------------------------
// 释放所有子节点占用的内存
//----------------------------
m_Children.clear();
g_NodeManager.RemoveNode(this);
}
void GNode::SetName(const char *pName)
{
strcpy(m_szName, pName);
}
void GNode::GetName(char *pName)
{
strcpy(pName, m_szName);
}
void GNode::SetNodeType(int type)
{
m_NodeType = type;
}
int GNode::GetNodeType(void)
{
return m_NodeType;
}
char* GNode::GetNodeTypeString(void)
{
if(m_NodeType>=0 && m_NodeType<=5)
return szNodeTypeName[m_NodeType];
else
return szNodeTypeName[0];
}
void GNode::GetWorldTransform(D3DXMATRIX *pMatWorld)
{
if(m_bCachedOutOfDate)
{
// Scaling, Rotate, Translate
D3DXMATRIX matScale, matTranslate;
D3DXMatrixScaling(&matScale, m_vDerivedScale.x, m_vDerivedScale.y, m_vDerivedScale.z);
D3DXMatrixTranslation(&matTranslate, m_vDerivedPos.x, m_vDerivedPos.y, m_vDerivedPos.z);
m_CachedWorldTrans = matScale * m_DerivedOrientation * matTranslate;
if(m_bIsUseParentMatrix)
{
m_CachedWorldTrans = m_CachedWorldTrans * m_ParentMatrix;
}
m_bCachedOutOfDate = false;
}
*pMatWorld = m_CachedWorldTrans;
}
void GNode::SetPosition(const D3DXVECTOR3 &pos)
{
m_vPos = pos;
NeedUpdate();
}
void GNode::GetPosition(D3DXVECTOR3 *pos)
{
*pos = m_vPos;
}
void GNode::SetScale(const D3DXVECTOR3 &scale)
{
m_vScale = scale;
NeedUpdate();
}
void GNode::GetScale(D3DXVECTOR3 *scale)
{
*scale = m_vScale;
}
void GNode::SetRotate(const D3DXVECTOR3 &rotate)
{
m_vRotate = rotate;
while(m_vRotate.x>=AS_PI*2.0f) { m_vRotate.x -= AS_PI*2.0f; }
while(m_vRotate.x<0.0f) { m_vRotate.x += AS_PI*2.0f; }
while(m_vRotate.y>=AS_PI*2.0f) { m_vRotate.y -= AS_PI*2.0f; }
while(m_vRotate.y<0.0f) { m_vRotate.y += AS_PI*2.0f; }
while(m_vRotate.z>=AS_PI*2.0f) { m_vRotate.z -= AS_PI*2.0f; }
while(m_vRotate.z<0.0f) { m_vRotate.z += AS_PI*2.0f; }
D3DXMatrixIdentity(&m_Orientation);
D3DXMATRIX matRot;
D3DXMatrixRotationX(&matRot, m_vRotate.x);
m_Orientation *= matRot;
D3DXMatrixRotationY(&matRot, m_vRotate.y);
m_Orientation *= matRot;
D3DXMatrixRotationZ(&matRot, m_vRotate.z);
m_Orientation *= matRot;
NeedUpdate();
}
void GNode::GetRotate(D3DXVECTOR3 *rotate)
{
*rotate = m_vRotate;
}
void GNode::SetRotateX(float value)
{
m_vRotate.x = value;
while(m_vRotate.x>=AS_PI*2.0f) { m_vRotate.x -= AS_PI*2.0f; }
while(m_vRotate.x<0.0f) { m_vRotate.x += AS_PI*2.0f; }
D3DXMatrixIdentity(&m_Orientation);
D3DXMATRIX matRot;
D3DXMatrixRotationX(&matRot, m_vRotate.x);
m_Orientation *= matRot;
D3DXMatrixRotationY(&matRot, m_vRotate.y);
m_Orientation *= matRot;
D3DXMatrixRotationZ(&matRot, m_vRotate.z);
m_Orientation *= matRot;
NeedUpdate();
}
float GNode::GetRotateX(void)
{
return m_vRotate.x;
}
void GNode::SetRotateY(float value)
{
m_vRotate.y = value;
while(m_vRotate.y>=AS_PI*2.0f) { m_vRotate.y -= AS_PI*2.0f; }
while(m_vRotate.y<0.0f) { m_vRotate.y += AS_PI*2.0f; }
D3DXMatrixIdentity(&m_Orientation);
D3DXMATRIX matRot;
D3DXMatrixRotationX(&matRot, m_vRotate.x);
m_Orientation *= matRot;
D3DXMatrixRotationY(&matRot, m_vRotate.y);
m_Orientation *= matRot;
D3DXMatrixRotationZ(&matRot, m_vRotate.z);
m_Orientation *= matRot;
NeedUpdate();
}
float GNode::GetRotateY(void)
{
return m_vRotate.y;
}
void GNode::SetRotateZ(float value)
{
m_vRotate.z = value;
while(m_vRotate.z>=AS_PI*2.0f) { m_vRotate.z -= AS_PI*2.0f; }
while(m_vRotate.z<0.0f) { m_vRotate.z += AS_PI*2.0f; }
D3DXMatrixIdentity(&m_Orientation);
D3DXMATRIX matRot;
D3DXMatrixRotationX(&matRot, m_vRotate.x);
m_Orientation *= matRot;
D3DXMatrixRotationY(&matRot, m_vRotate.y);
m_Orientation *= matRot;
D3DXMatrixRotationZ(&matRot, m_vRotate.z);
m_Orientation *= matRot;
NeedUpdate();
}
float GNode::GetRotateZ(void)
{
return m_vRotate.z;
}
D3DXVECTOR3 GNode::GetDerivedPos(void)
{
if(m_bUpdateFromParent)
{
UpdateFromParent();
m_bUpdateFromParent = false;
}
return m_vDerivedPos;
}
D3DXMATRIX GNode::GetDerivedOrientation(void)
{
if(m_bUpdateFromParent)
{
UpdateFromParent();
m_bUpdateFromParent = false;
}
return m_DerivedOrientation;
}
D3DXVECTOR3 GNode::GetDerivedScale(void)
{
if(m_bUpdateFromParent)
{
UpdateFromParent();
m_bUpdateFromParent = false;
}
return m_vDerivedScale;
}
void GNode::Translate(const D3DXVECTOR3 &d, TransformSpace relativeTo /* = TS_PARENT */)
{
// local: rot * d + p
// parent: p + d
// world: ( parentRot.inverse * d )/parentScale + p
switch(relativeTo)
{
case TS_LOCAL:
//m_vPos += m_Orientation * d;
break;
case TS_PARENT:
m_vPos += d;
break;
case TS_WORLD:
break;
}
NeedUpdate();
}
/*
void GNode::Rotate(const D3DXVECTOR3 &axis, float angle, TransformSpace relativeTo)
{
D3DXMATRIX matRot;
D3DXMatrixRotationAxis(&matRot, &axis, angle);
switch(relativeTo)
{
case TS_LOCAL:
m_Orientation = m_Orientation * matRot;
break;
case TS_PARENT:
m_Orientation = matRot * m_Orientation;
break;
case TS_WORLD:
break;
}
NeedUpdate();
}
*/
void GNode::UpdateFromParent()
{
if(m_pParent)
{
D3DXMATRIX parentOrientation;
D3DXMatrixIdentity(&parentOrientation);
D3DXVECTOR3 parentScale(1.0f, 1.0f, 1.0f);
// orientation
if(m_bRotateFromParent)
{
parentOrientation = m_pParent->GetDerivedOrientation();
m_DerivedOrientation = m_Orientation * parentOrientation;
}
else
{
m_DerivedOrientation = m_Orientation;
}
// scale
if(m_bScaleFromParent)
{
parentScale = m_pParent->GetDerivedScale();
m_vDerivedScale = Vec3Mutiply(parentScale, m_vScale);
}
else
{
m_vDerivedScale = m_vScale;
}
// position
if(m_bRotateFromParent || m_bScaleFromParent)
{
D3DXVec3TransformCoord(&m_vDerivedPos, &Vec3Mutiply(parentScale, m_vPos), &parentOrientation);
}
else
{
m_vDerivedPos = m_vPos;
}
m_vDerivedPos += m_pParent->GetDerivedPos();
if(m_pParent->IsUseParentMatrix())
{
m_pParent->GetWorldTransform(&m_ParentMatrix);
SetParentMatrix(m_ParentMatrix);
}
}
else
{
m_vDerivedPos = m_vPos;
m_DerivedOrientation = m_Orientation;
m_vDerivedScale = m_vScale;
}
m_bCachedOutOfDate = true;
}
void GNode::Update()
{
UpdateFromParent();
std::vector<GNode*>::iterator itor;
for(itor=m_Children.begin(); itor!=m_Children.end(); itor++)
{
(*itor)->Update();
}
}
void GNode::NeedUpdate()
{
m_bCachedOutOfDate = true;
m_bUpdateFromParent = true;
}
void GNode::AddChildNode(GNode *pChild)
{
assert(pChild);
pChild->m_pParent = this;
m_Children.push_back(pChild);
}
void GNode::RemoveChildNode(GNode *pChild)
{
assert(pChild);
std::vector<GNode*>::iterator itor;
for(itor=m_Children.begin(); itor!=m_Children.end(); itor++)
{
if((*itor) == pChild)
{
m_Children.erase(itor);
//----------------------------
// 释放该节点占用的内存或返回该节点地址
//----------------------------
break;
}
}
}
void GNode::SetParentMatrix(const D3DXMATRIX &mat)
{
m_ParentMatrix = mat;
m_bIsUseParentMatrix = true;
NeedUpdate();
}
D3DXMATRIX GNode::GetParentMaxtrix(void)
{
return m_ParentMatrix;
}
void GNode::UseParentMatrix(bool bIsUse)
{
m_bIsUseParentMatrix = bIsUse;
}
bool GNode::IsUseParentMatrix(void)
{
return m_bIsUseParentMatrix;
}
void GNode::SetRotateFromParent(bool bRotateFromParent)
{
m_bRotateFromParent = bRotateFromParent;
}
void GNode::SetScaleFromParent(bool bScaleFromParent)
{
m_bScaleFromParent = bScaleFromParent;
}
void GNode::DrawCoordinates(void)
{
CollisionBox pV[6];
pV[0] = CollisionBox(0.0f, 0.0f, 0.0f, 0xff0000ff);
pV[1] = CollisionBox(5.0f, 0.0f, 0.0f, 0xff0000ff);
pV[2] = CollisionBox(0.0f, 0.0f, 0.0f, 0xff00ff00);
pV[3] = CollisionBox(0.0f, 5.0f, 0.0f, 0xff00ff00);
pV[4] = CollisionBox(0.0f, 0.0f, 0.0f, 0xffff0000);
pV[5] = CollisionBox(0.0f, 0.0f, 5.0f, 0xffff0000);
D3DXMATRIX matWorld;
GetWorldTransform(&matWorld);
g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);
g_pD3DDevice->SetFVF(CollisionBox::COLLISIONFVF);
g_pD3DDevice->SetTexture(0, NULL);
g_pD3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 3, pV, sizeof(CollisionBox));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -