Blender  V2.59
KX_SG_BoneParentNodeRelationship.cpp
Go to the documentation of this file.
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 }