From 2ac1ef13e20949374720afec1d8da59cce83a45c Mon Sep 17 00:00:00 2001 From: Kester Maddock Date: Sat, 23 Apr 2005 11:36:44 +0000 Subject: Added bone parent relationship. --- source/gameengine/Converter/BL_ArmatureObject.cpp | 24 +++- source/gameengine/Converter/BL_ArmatureObject.h | 20 ++- .../Converter/BL_BlenderDataConversion.cpp | 54 ++++++-- .../Ketsji/KX_SG_BoneParentNodeRelationship.cpp | 154 +++++++++++++++++++++ .../Ketsji/KX_SG_BoneParentNodeRelationship.h | 109 +++++++++++++++ source/gameengine/Ketsji/KX_SG_NodeRelationships.h | 4 + source/gameengine/Ketsji/SConscript | 1 + 7 files changed, 348 insertions(+), 18 deletions(-) create mode 100644 source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp create mode 100644 source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h (limited to 'source/gameengine') diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index 0c0dda52d2c..82f97fe9c18 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -39,6 +39,10 @@ #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 @@ -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(); +} + + diff --git a/source/gameengine/Converter/BL_ArmatureObject.h b/source/gameengine/Converter/BL_ArmatureObject.h index b81a6f0eddd..7244d08da76 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.h +++ b/source/gameengine/Converter/BL_ArmatureObject.h @@ -37,7 +37,11 @@ #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; diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 8295600b6cf..bc0ac8eff5a 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -124,7 +124,7 @@ #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" @@ -158,6 +158,7 @@ // 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 index 00000000000..632cb753240 --- /dev/null +++ b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp @@ -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 + +#include "KX_SG_BoneParentNodeRelationship.h" + +#include "MT_Matrix4x4.h" +#include "BL_ArmatureObject.h" + + +#ifdef HAVE_CONFIG_H +#include +#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 index 00000000000..1f816726264 --- /dev/null +++ b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h @@ -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 diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.h b/source/gameengine/Ketsji/KX_SG_NodeRelationships.h index 8eda5d7b734..f434cb5b648 100644 --- a/source/gameengine/Ketsji/KX_SG_NodeRelationships.h +++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.h @@ -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 diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index 0407232a9ac..1b22231f3f9 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -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', -- cgit v1.2.3