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

📄 trsnode.cpp

📁 小型的3D游戏引擎
💻 CPP
字号:
 #include "../global.h"
#include "trsnode.h"


GcTRSNode::GcTRSNode( const std::string & NodeName, GcTRSNode * parent ) : GcUpdateEntity(), GcRenderEntity()
{
	m_name = NodeName;
	m_parent = 0;

	m_worldUpdate = true;
	SetTranslation( GcVector3(0.0f, 0.0f, 0.0f) );

	if( parent )
		parent->AttachNode(this);

	TRSReset();
}

GcTRSNode::~GcTRSNode()
{
	DetachFromParent();

	// Delete all children (they detach from us)
	while( m_children.size() )
		delete m_children[0];
}

bool GcTRSNode::AttachNode( GcTRSNode * node )
{
	// Make sure node is contains an address and that we aren't attaching ourselves to ourselves (what!? hehe :)
	if( !node || ( node->GetParent() == this ) )
		return false;

	// Add the child
	m_children.push_back(node);

	// Detach the child from it's parent
	node->DetachFromParent();
	
	// Tell the child who's in charge
	node->m_parent = this;

	return true;
}

bool GcTRSNode::DetachNode( GcTRSNode * node )
{
	for( std::vector<GcTRSNode *>::iterator itnode = m_children.begin(); itnode != m_children.end(); ++itnode )
	{
		// Check if current node matches the one we passed
		if( (*itnode) == node )
		{
			// Delete it from our child list
			m_children.erase( itnode );

			// Orphan the child
			node->m_parent = 0;

			return false;
		}
	}

	return true;
}

void GcTRSNode::DetachFromParent()
{
	if( m_parent )
	{
		//SetTranslation( GetWorldTranslation() );
		//SetRotation( GetWorldRotation() );
		SetMatrix( GetWorldMatrix() );
		SetScaling( GetWorldScaling() );
	
		m_parent->DetachNode( this );
		m_parent = 0;
	}
}

void GcTRSNode::Update( float deltaTime )
{
	for( unsigned int i = 0; i < m_children.size(); i++ )
		m_children[i]->Update( deltaTime ); 
}

void GcTRSNode::NotifyUpdate( bool recurse )
{
	m_worldUpdate = true;
	UpdateWorld();
	
	if( !recurse )
		return;
	
	for( unsigned int i = 0; i < m_children.size(); ++i )
		m_children[i]->NotifyUpdate(true);
} 

bool GcTRSNode::UpdateWorld()
{
	if( m_worldUpdate )
	{
		// Do we have a parent ?
		if( m_parent )
		{
			// Yes! Set up relative to the parent
			
			m_worldMatrix = m_parent->GetWorldMatrix() * m_matrix;
			m_worldMatrix.SetTranslation( m_parent->GetWorldTranslation() + ( m_parent->GetWorldMatrix() * GetTranslation() ) );
			
			//m_worldTranslation = m_parent->GetWorldTranslation() + ( m_parent->GetWorldRotation() * m_translation );
			//m_worldTranslation = m_parent->GetWorldTranslation() + m_translation;
			
			//m_worldScaling     = m_parent->GetWorldScaling() * m_scaling;

			m_worldScaling.x = m_parent->GetWorldScaling().x * m_scaling.x;
			m_worldScaling.y = m_parent->GetWorldScaling().y * m_scaling.y;
			m_worldScaling.z = m_parent->GetWorldScaling().z * m_scaling.z;
		}
		else
		{
			// Nope! Just set the variables
			
			m_worldMatrix = m_matrix;
			//m_worldTranslation = m_translation;
			//m_worldRotation    = m_rotation;
			m_worldScaling     = m_scaling;
		}

		m_worldUpdate = false;

		return true;
	}

	return false;
}


void GcTRSNode::TRSReset()
{
//	m_translation = GcVector3(0, 0, 0);
	//m_rotation = GcVector3(0, 0, 0);
//	m_scaling = GcVector3(1, 1, 1);
	m_matrix.SetIdentity();
	
	m_worldMatrix.SetIdentity();

	//m_worldTranslation = GcVector3(0, 0, 0);
	//m_worldRotation = GcVector3(0, 0, 0);
	//m_worldScaling = GcVector3(1, 1, 1);
}


void GcTRSNode::Rotate( const GcVector3 & angles, bool notifyUpdate )
{
	NormalizeAngle(angles.x);
	NormalizeAngle(angles.y);
	NormalizeAngle(angles.z);
	
	GcVector3 pos = GetTranslation();
	GcVector3 tmp;
	
	m_matrix.ConvertToEuler(tmp);
	tmp += angles;
	
	m_matrix.BuildFromEuler( tmp );
	m_matrix.SetTranslation( pos );

//

//	GcMatrix4 rot, tmp;

	//if( !m_gimbalLock )
	//{
	//	m_matrix.BuildFromEuler(m_rotation);
	//	m_matrix.SetTranslation(pos);
//	}

	/*rot.BuildFromEuler(m_newRotation);
	m_matrix *= rot;

	tmp.SetIdentity();
	tmp.SetTranslation(m_newPosition);
    
	m_matrix *= tmp;*/

	/*if( m_matrix.ConvertToEuler(m_rotation) != 0 )
		m_gimbalLock = true;
	else
		m_gimbalLock = false;*7

	/*GetPosition(m_position);

	m_newPosition = LVector4(0, 0, 0, 1);

	m_newRotation = LVector4(0, 0, 0, 1);*/


	//m_matrix.BuildFromEuler( angles );
	
	if( notifyUpdate )
		NotifyUpdate( notifyUpdate );
}

void GcTRSNode::Rotate( float x, float y, float z, bool notifyUpdate )
{
	NormalizeAngle(x);
	NormalizeAngle(y);
	NormalizeAngle(z);
	
	//m_matrix.BuildFromEuler( GcVector3(x, y, z) );

	GcVector3 pos = GetTranslation();
	GcVector3 tmp;
	
	m_matrix.ConvertToEuler(tmp);
	tmp += GcVector3(x, y, z);
	
	m_matrix.BuildFromEuler( tmp );
	m_matrix.SetTranslation( pos );
	
	if( notifyUpdate )
		NotifyUpdate( notifyUpdate );
}


void GcTRSNode::SetRotation( const GcVector3 & angles, bool notifyUpdate )
{
	GcVector3 pos = GetTranslation();
	m_matrix.BuildFromEuler( angles );
	m_matrix.SetTranslation( pos );


	if( notifyUpdate )
		NotifyUpdate( notifyUpdate );
}
/*
void GcTRSNode::SetRotation( const GcMatrix4 & rotation, bool notifyUpdate )
{
	m_matrix = rotation;

	if( notifyUpdate )
		NotifyUpdate( notifyUpdate );
}
*/


/*
void GcTRSNode::WorldRotate( const GcVector3 & angles )
{

}

void GcTRSNode::WorldRotate( float x, float y, float z )
{
	NormalizeAngle(x);
	NormalizeAngle(y);
	NormalizeAngle(z);
	
	m_worldRotation.x += x;
	m_worldRotation.y += y;
	m_worldRotation.z += z;
}

void GcTRSNode::SetWorldRotation( const GcVector3 & angles )
{


}
*/

⌨️ 快捷键说明

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