|
Blender
V2.59
|
00001 /* 00002 * $Id: KX_SG_BoneParentNodeRelationship.cpp 35171 2011-02-25 13:35:59Z jesterking $ 00003 * ***** BEGIN GPL LICENSE BLOCK ***** 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software Foundation, 00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 * 00019 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00020 * All rights reserved. 00021 * 00022 * The Original Code is: all of this file. 00023 * 00024 * Contributor(s): none yet. 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include <iostream> 00035 00036 #include "KX_SG_BoneParentNodeRelationship.h" 00037 00038 #include "MT_Matrix4x4.h" 00039 #include "BL_ArmatureObject.h" 00040 00041 00050 KX_BoneParentRelation * 00051 KX_BoneParentRelation:: 00052 New(Bone* bone 00053 ) { 00054 return new KX_BoneParentRelation(bone); 00055 } 00056 00057 bool 00058 KX_BoneParentRelation:: 00059 UpdateChildCoordinates( 00060 SG_Spatial * child, 00061 const SG_Spatial * parent, 00062 bool& parentUpdated 00063 ){ 00064 MT_assert(child != NULL); 00065 00066 // This way of accessing child coordinates is a bit cumbersome 00067 // be nice to have non constant reference access to these values. 00068 00069 const MT_Vector3 & child_scale = child->GetLocalScale(); 00070 const MT_Point3 & child_pos = child->GetLocalPosition(); 00071 const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation(); 00072 // we don't know if the armature has been updated or not, assume yes 00073 parentUpdated = true; 00074 00075 // the childs world locations which we will update. 00076 00077 MT_Vector3 child_w_scale; 00078 MT_Point3 child_w_pos; 00079 MT_Matrix3x3 child_w_rotation; 00080 00081 bool valid_parent_transform = false; 00082 00083 if (parent) 00084 { 00085 BL_ArmatureObject *armature = (BL_ArmatureObject*)(parent->GetSGClientObject()); 00086 if (armature) 00087 { 00088 MT_Matrix4x4 parent_matrix; 00089 if (armature->GetBoneMatrix(m_bone, parent_matrix)) 00090 { 00091 // Get the child's transform, and the bone matrix. 00092 MT_Matrix4x4 child_transform ( 00093 MT_Transform(child_pos + MT_Vector3(0.0, armature->GetBoneLength(m_bone), 0.0), 00094 child_rotation.scaled( 00095 child_scale[0], 00096 child_scale[1], 00097 child_scale[2]))); 00098 00099 // The child's world transform is parent * child 00100 parent_matrix = parent->GetWorldTransform() * parent_matrix; 00101 child_transform = parent_matrix * child_transform; 00102 00103 // Recompute the child transform components from the transform. 00104 child_w_scale.setValue( 00105 MT_Vector3(child_transform[0][0], child_transform[0][1], child_transform[0][2]).length(), 00106 MT_Vector3(child_transform[1][0], child_transform[1][1], child_transform[1][2]).length(), 00107 MT_Vector3(child_transform[2][0], child_transform[2][1], child_transform[2][2]).length()); 00108 child_w_rotation.setValue(child_transform[0][0], child_transform[0][1], child_transform[0][2], 00109 child_transform[1][0], child_transform[1][1], child_transform[1][2], 00110 child_transform[2][0], child_transform[2][1], child_transform[2][2]); 00111 child_w_rotation.scale(1.0/child_w_scale[0], 1.0/child_w_scale[1], 1.0/child_w_scale[2]); 00112 00113 child_w_pos = MT_Point3(child_transform[0][3], child_transform[1][3], child_transform[2][3]); 00114 00115 valid_parent_transform = true; 00116 } 00117 } 00118 } 00119 00120 if (valid_parent_transform) 00121 { 00122 child->SetWorldScale(child_w_scale); 00123 child->SetWorldPosition(child_w_pos); 00124 child->SetWorldOrientation(child_w_rotation); 00125 } 00126 else { 00127 child->SetWorldFromLocalTransform(); 00128 } 00129 child->ClearModified(); 00130 // this node must always be updated, so reschedule it for next time 00131 child->ActivateRecheduleUpdateCallback(); 00132 return valid_parent_transform; 00133 } 00134 00135 SG_ParentRelation * 00136 KX_BoneParentRelation:: 00137 NewCopy( 00138 ){ 00139 KX_BoneParentRelation* bone_parent = new KX_BoneParentRelation(m_bone); 00140 return bone_parent; 00141 } 00142 00143 KX_BoneParentRelation:: 00144 ~KX_BoneParentRelation( 00145 ){ 00146 //nothing to do 00147 } 00148 00149 00150 KX_BoneParentRelation:: 00151 KX_BoneParentRelation(Bone* bone 00152 ) 00153 : m_bone(bone) 00154 { 00155 // nothing to do 00156 }