Added bone parent relationship.
authorKester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>
Sat, 23 Apr 2005 11:36:44 +0000 (11:36 +0000)
committerKester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>
Sat, 23 Apr 2005 11:36:44 +0000 (11:36 +0000)
source/gameengine/Converter/BL_ArmatureObject.cpp
source/gameengine/Converter/BL_ArmatureObject.h
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp [new file with mode: 0644]
source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h [new file with mode: 0644]
source/gameengine/Ketsji/KX_SG_NodeRelationships.h
source/gameengine/Ketsji/SConscript

index 0c0dda52d2c49556a6bc47f5812611cdad268178..82f97fe9c1828ad7a85eab0366fc5d55e3b29e44 100644 (file)
 #include "GEN_HashedPtr.h"
 #include "MEM_guardedalloc.h"
 #include "DNA_action_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_object_types.h"
+
+#include "MT_Matrix4x4.h"
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -72,7 +76,7 @@ BL_ArmatureObject::~BL_ArmatureObject()
 void BL_ArmatureObject::ApplyPose()
 {
        if (m_pose){
-               apply_pose_armature(m_armature, m_pose, 1);
+               apply_pose_armature(GetArmature(), m_pose, 1);
                if (!m_mrdPose)
                        copy_pose (&m_mrdPose, m_pose, 0);
                else
@@ -151,3 +155,21 @@ double BL_ArmatureObject::GetLastFrame()
 {
        return m_lastframe;
 }
+
+bool BL_ArmatureObject::GetBoneMatrix(Bone* bone, MT_Matrix4x4& matrix) const
+{
+       MT_assert(verify_boneptr((bArmature*) GetArmature(), bone) && "Bone is not part of this armature.");
+       
+       matrix.setValue(&bone->posemat[0][0]);
+       
+       return true;
+}
+
+float BL_ArmatureObject::GetBoneLength(Bone* bone) const
+{
+       MT_assert(verify_boneptr((bArmature*) GetArmature(), bone) && "Bone is not part of this armature.");
+       
+       return (MT_Point3(bone->head) - MT_Point3(bone->tail)).length();
+}
+
+
index b81a6f0eddd175a4f457e7a8ddedbeb286b98213..7244d08da761c7d6d1df9eb6c48af55c283fb52c 100644 (file)
 
 #include "SG_IObject.h"
 
+struct bArmature;
+struct Bone;
+
 class BL_ActionActuator;
+class MT_Matrix4x4;
 
 class BL_ArmatureObject : public KX_GameObject  
 {
@@ -47,10 +51,10 @@ public:
        virtual void ProcessReplica(BL_ArmatureObject *replica);
        class BL_ActionActuator * GetActiveAction();
        BL_ArmatureObject(void* sgReplicationInfo, SG_Callbacks callbacks,
-               struct bArmature *arm,
+               bArmature *armature,
                struct bPose *pose) :
        KX_GameObject(sgReplicationInfo,callbacks),
-               m_armature(arm),
+               m_armature(armature),
                m_pose(pose),
                m_mrdPose(NULL),
                m_lastframe(0.),
@@ -65,7 +69,17 @@ public:
        void SetPose (struct bPose *pose);
        void ApplyPose();
        bool SetActiveAction(class BL_ActionActuator *act, short priority, double curtime);
-       struct bArmature * GetArmature(){return m_armature;};
+       
+       struct bArmature * GetArmature() { return m_armature; }
+       
+       const struct bArmature * GetArmature() const { return m_armature; }
+       
+       /// Retrieve the pose matrix for the specified bone.
+       /// Returns true on success.
+       bool GetBoneMatrix(Bone* bone, MT_Matrix4x4& matrix) const;
+       
+       /// Returns the bone length.  The end of the bone is in the local y direction.
+       float GetBoneLength(Bone* bone) const;
 
 protected:
        struct bArmature        *m_armature;
index 8295600b6cfb0a9f8cb8e2bfa0326894c81e4c97..bc0ac8eff5aa10c0234fe56cfc626adcc536a6aa 100644 (file)
 #include "DNA_world_types.h"
 #include "DNA_sound_types.h"
 #include "DNA_key_types.h"
-
+#include "DNA_armature_types.h"
 
 #include "MEM_guardedalloc.h"
 #include "BKE_utildefines.h"
 // in the game engine.
 
 #include "KX_SG_NodeRelationships.h"
+#include "KX_SG_BoneParentNodeRelationship.h"
 
 #include "BL_ArmatureObject.h"
 #include "BL_DeformableGameObject.h"
@@ -974,7 +975,7 @@ static KX_GameObject *gameobject_from_blenderobject(
        case OB_ARMATURE:
        {
                gameobj = new BL_ArmatureObject (kxscene, KX_Scene::m_callbacks,
-                       (bArmature*)ob->data,
+                       get_armature(ob),
                        ob->pose);
        
                /* Get the current pose from the armature object and apply it as the rest pose */
@@ -1160,11 +1161,12 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
                                pclink.m_blenderchild = blenderobject;
                                pclink.m_gamechildnode = parentinversenode;
                                vec_parent_child.push_back(pclink);
-       
+
                                float* fl = (float*) blenderobject->parentinv;
                                MT_Transform parinvtrans(fl);
                                parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
                                parentinversenode->SetLocalOrientation(parinvtrans.getBasis());
+                               
                                parentinversenode->AddChild(gameobj->GetSGNode());
                        }
                        
@@ -1229,18 +1231,42 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
        {
        
                struct Object* blenderchild = pcit->m_blenderchild;
-               if (blenderchild->partype == PARVERT1)
-               {
-                       // creat a new vertex parent relationship for this node.
-                       KX_VertexParentRelation * vertex_parent_relation = KX_VertexParentRelation::New();
-                       pcit->m_gamechildnode->SetParentRelation(vertex_parent_relation);
-               } else 
-               if (blenderchild->partype == PARSLOW) 
+               switch (blenderchild->partype)
                {
-                       // creat a new slow parent relationship for this node.
-                       KX_SlowParentRelation * slow_parent_relation = KX_SlowParentRelation::New(blenderchild->sf);
-                       pcit->m_gamechildnode->SetParentRelation(slow_parent_relation);
-               }       
+                       case PARVERT1:
+                       {
+                               // creat a new vertex parent relationship for this node.
+                               KX_VertexParentRelation * vertex_parent_relation = KX_VertexParentRelation::New();
+                               pcit->m_gamechildnode->SetParentRelation(vertex_parent_relation);
+                               break;
+                       }
+                       case PARSLOW:
+                       {
+                               // creat a new slow parent relationship for this node.
+                               KX_SlowParentRelation * slow_parent_relation = KX_SlowParentRelation::New(blenderchild->sf);
+                               pcit->m_gamechildnode->SetParentRelation(slow_parent_relation);
+                               break;
+                       }       
+                       case PARBONE:
+                       {
+                               // parent this to a bone
+                               Bone *parent_bone = get_named_bone(get_armature(blenderchild->parent), blenderchild->parsubstr);
+                               KX_BoneParentRelation *bone_parent_relation = KX_BoneParentRelation::New(parent_bone);
+                               pcit->m_gamechildnode->SetParentRelation(bone_parent_relation);
+                       
+                               break;
+                       }
+                       case PARSKEL: // skinned - ignore
+                               break;
+                       case PAROBJECT:
+                       case PARCURVE:
+                       case PARKEY:
+                       case PARLIMB:
+                       case PARVERT3:
+                       default:
+                               // unhandled
+                               break;
+               }
        
                struct Object* blenderparent = blenderchild->parent;
                KX_GameObject* parentobj = converter->FindGameObject(blenderparent);
diff --git a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp
new file mode 100644 (file)
index 0000000..632cb75
--- /dev/null
@@ -0,0 +1,154 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <iostream>
+#include "KX_SG_BoneParentNodeRelationship.h"
+
+#include "MT_Matrix4x4.h"
+#include "BL_ArmatureObject.h"
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/**
+ * 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
+){
+       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();
+
+       // 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)
+       {
+               const BL_ArmatureObject *armature = (const 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 =  MT_Vector3( 
+                                       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 = MT_Matrix3x3(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_w_scale = child_scale;
+               child_w_pos = child_pos;
+               child_w_rotation = child_rotation;
+       }
+
+       child->SetWorldScale(child_w_scale);
+       child->SetWorldPosition(child_w_pos);
+       child->SetWorldOrientation(child_w_rotation);
+       
+       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
+}
diff --git a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h
new file mode 100644 (file)
index 0000000..1f81672
--- /dev/null
@@ -0,0 +1,109 @@
+/**
+ * @mainpage KX_SG_NodeRelationships   
+
+ * @section 
+ *
+ * This file provides common concrete implementations of 
+ * SG_ParentRelation used by the game engine. These are
+ * KX_SlowParentRelation a slow parent relationship.
+ * KX_NormalParentRelation a normal parent relationship where 
+ * orientation and position are inherited from the parent by
+ * the child.
+ * KX_VertexParentRelation only location information is 
+ * inherited by the child. 
+ *
+ * @see SG_ParentRelation for more information about this 
+ * interface     
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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/BL DUAL LICENSE BLOCK *****
+ * 
+ */
+
+#ifndef __KX_SG_BONEPARENTRELATION_H__
+#define __KX_SG_BONEPARENTRELATION_H__
+#include "SG_Spatial.h"
+#include "SG_ParentRelation.h"
+
+struct Bone;
+
+/**
+ *  Bone parent relationship parents a child SG_Spatial frame to a 
+ *  bone in an armature object.
+ */
+class KX_BoneParentRelation : public SG_ParentRelation
+{
+
+public :
+
+       /**
+        * Allocate and construct a new KX_SG_BoneParentRelation
+        * on the heap.
+        *
+        * bone is the bone id to use.  Currently it is a pointer
+        * to a Blender struct Bone - this should be fixed if
+        */
+
+       static 
+               KX_BoneParentRelation *
+       New(Bone* bone
+       );              
+
+       /**
+        *  Updates the childs world coordinates relative to the parent's
+        *  world coordinates.
+        *
+        *  Parent should be a BL_ArmatureObject.
+        */
+               bool
+       UpdateChildCoordinates(
+               SG_Spatial * child,
+               const SG_Spatial * parent
+       );
+
+       /**
+        *  Create a copy of this relationship
+        */
+               SG_ParentRelation *
+       NewCopy(
+       );
+
+       ~KX_BoneParentRelation(
+       );
+
+private :
+       Bone* m_bone;
+       KX_BoneParentRelation(Bone* bone
+       );
+
+};
+
+#endif
index 8eda5d7b7345903479d9a387851e3c3fe8e16833..f434cb5b6489a55aa275b3bd26a27c489c165377 100644 (file)
@@ -46,6 +46,9 @@
  * ***** END GPL/BL DUAL LICENSE BLOCK *****
  * 
  */
+#ifndef __KX_SG_NODERELATIONS_H__
+#define __KX_SG_NODERELATIONS_H__
 
 #include "SG_Spatial.h"
 #include "SG_ParentRelation.h"
@@ -198,3 +201,4 @@ private :
 
 };
 
+#endif
index 0407232a9ac35cd9a9696be0882f216f29221a8c..1b22231f3f9085bfd741dba5da3c7b5d1c0be058 100644 (file)
@@ -17,6 +17,7 @@ source_files = ['KX_WorldIpoController.cpp',
                 'KX_TimeCategoryLogger.cpp',
                 'KX_SoundActuator.cpp',
                 'KX_SG_NodeRelationships.cpp',
+               'KX_SG_BoneParentNodeRelationship.cpp',
                 'KX_SceneActuator.cpp',
                 'KX_Scene.cpp',
                 'KX_ScalingInterpolator.cpp',