www.pudn.com > Gimcrack-v0.0051-Source.zip > trsnode.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::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 ) 
{ 
 
 
} 
*/