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

📄 gnode.cpp

📁 3D游戏展示程序
💻 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 + -