152 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			152 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/**
 | 
						|
 * $Id$
 | 
						|
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or
 | 
						|
 * modify it under the terms of the GNU General Public License
 | 
						|
 * as published by the Free Software Foundation; either version 2
 | 
						|
 * of the License, or (at your option) any later version.
 | 
						|
 *
 | 
						|
 * This program is distributed in the hope that it will be useful,
 | 
						|
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
 * GNU General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU General Public License
 | 
						|
 * along with this program; if not, write to the Free Software Foundation,
 | 
						|
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
						|
 *
 | 
						|
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 | 
						|
 * All rights reserved.
 | 
						|
 *
 | 
						|
 * The Original Code is: all of this file.
 | 
						|
 *
 | 
						|
 * Contributor(s): none yet.
 | 
						|
 *
 | 
						|
 * ***** END GPL LICENSE BLOCK *****
 | 
						|
 */
 | 
						|
 | 
						|
#include <iostream>
 | 
						|
 
 | 
						|
#include "KX_SG_BoneParentNodeRelationship.h"
 | 
						|
 | 
						|
#include "MT_Matrix4x4.h"
 | 
						|
#include "BL_ArmatureObject.h"
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * Implementation of classes defined in KX_SG_BoneParentNodeRelationship.h
 | 
						|
 */
 | 
						|
 | 
						|
/** 
 | 
						|
 * first of all KX_SG_BoneParentRelation
 | 
						|
 */
 | 
						|
 | 
						|
	KX_BoneParentRelation *
 | 
						|
KX_BoneParentRelation::
 | 
						|
New(Bone* bone
 | 
						|
) {
 | 
						|
	return new KX_BoneParentRelation(bone);
 | 
						|
}		
 | 
						|
 | 
						|
	bool
 | 
						|
KX_BoneParentRelation::
 | 
						|
UpdateChildCoordinates(
 | 
						|
	SG_Spatial * child,
 | 
						|
	const SG_Spatial * parent,
 | 
						|
	bool& parentUpdated	
 | 
						|
){
 | 
						|
	MT_assert(child != NULL);
 | 
						|
	
 | 
						|
	// This way of accessing child coordinates is a bit cumbersome
 | 
						|
	// be nice to have non constant reference access to these values.
 | 
						|
 | 
						|
	const MT_Vector3 & child_scale = child->GetLocalScale();
 | 
						|
	const MT_Point3 & child_pos = child->GetLocalPosition();
 | 
						|
	const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
 | 
						|
	// we don't know if the armature has been updated or not, assume yes
 | 
						|
	parentUpdated = true;
 | 
						|
 | 
						|
	// the childs world locations which we will update.	
 | 
						|
	
 | 
						|
	MT_Vector3 child_w_scale;
 | 
						|
	MT_Point3 child_w_pos;
 | 
						|
	MT_Matrix3x3 child_w_rotation;
 | 
						|
	
 | 
						|
	bool valid_parent_transform = false;
 | 
						|
	
 | 
						|
	if (parent)
 | 
						|
	{
 | 
						|
		BL_ArmatureObject *armature = (BL_ArmatureObject*)(parent->GetSGClientObject());
 | 
						|
		if (armature)
 | 
						|
		{
 | 
						|
			MT_Matrix4x4 parent_matrix;
 | 
						|
			if (armature->GetBoneMatrix(m_bone, parent_matrix))
 | 
						|
			{
 | 
						|
				// Get the child's transform, and the bone matrix.
 | 
						|
				MT_Matrix4x4 child_transform ( 
 | 
						|
					MT_Transform(child_pos + MT_Vector3(0.0, armature->GetBoneLength(m_bone), 0.0), 
 | 
						|
						child_rotation.scaled(
 | 
						|
							child_scale[0], 
 | 
						|
							child_scale[1], 
 | 
						|
							child_scale[2])));
 | 
						|
				
 | 
						|
				// The child's world transform is parent * child
 | 
						|
				parent_matrix = parent->GetWorldTransform() * parent_matrix;
 | 
						|
				child_transform = parent_matrix * child_transform;
 | 
						|
				
 | 
						|
				// Recompute the child transform components from the transform.
 | 
						|
				child_w_scale.setValue( 
 | 
						|
					MT_Vector3(child_transform[0][0], child_transform[0][1], child_transform[0][2]).length(),
 | 
						|
					MT_Vector3(child_transform[1][0], child_transform[1][1], child_transform[1][2]).length(),
 | 
						|
					MT_Vector3(child_transform[2][0], child_transform[2][1], child_transform[2][2]).length());
 | 
						|
				child_w_rotation.setValue(child_transform[0][0], child_transform[0][1], child_transform[0][2], 
 | 
						|
					child_transform[1][0], child_transform[1][1], child_transform[1][2], 
 | 
						|
					child_transform[2][0], child_transform[2][1], child_transform[2][2]);
 | 
						|
				child_w_rotation.scale(1.0/child_w_scale[0], 1.0/child_w_scale[1], 1.0/child_w_scale[2]);
 | 
						|
					
 | 
						|
				child_w_pos = MT_Point3(child_transform[0][3], child_transform[1][3], child_transform[2][3]);
 | 
						|
					
 | 
						|
				valid_parent_transform = true;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	} 
 | 
						|
	
 | 
						|
	if (valid_parent_transform)
 | 
						|
	{
 | 
						|
		child->SetWorldScale(child_w_scale);
 | 
						|
		child->SetWorldPosition(child_w_pos);
 | 
						|
		child->SetWorldOrientation(child_w_rotation);
 | 
						|
	}
 | 
						|
	else {
 | 
						|
		child->SetWorldFromLocalTransform();
 | 
						|
	}
 | 
						|
	child->ClearModified();
 | 
						|
	// this node must always be updated, so reschedule it for next time
 | 
						|
	child->ActivateRecheduleUpdateCallback();
 | 
						|
	return valid_parent_transform;
 | 
						|
}
 | 
						|
 | 
						|
	SG_ParentRelation *
 | 
						|
KX_BoneParentRelation::
 | 
						|
NewCopy(
 | 
						|
){
 | 
						|
	KX_BoneParentRelation* bone_parent = new KX_BoneParentRelation(m_bone);
 | 
						|
	return bone_parent;
 | 
						|
}
 | 
						|
 | 
						|
KX_BoneParentRelation::
 | 
						|
~KX_BoneParentRelation(
 | 
						|
){
 | 
						|
	//nothing to do
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
KX_BoneParentRelation::
 | 
						|
KX_BoneParentRelation(Bone* bone
 | 
						|
)
 | 
						|
: m_bone(bone)
 | 
						|
{
 | 
						|
	// nothing to do
 | 
						|
}
 |