forked from bartvdbraak/blender
Added bone parent relationship.
This commit is contained in:
parent
c333ba8dfa
commit
2ac1ef13e2
@ -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 <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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
switch (blenderchild->partype)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
// 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);
|
||||
|
154
source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp
Normal file
154
source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp
Normal file
@ -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
|
||||
}
|
109
source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h
Normal file
109
source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h
Normal file
@ -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
|
@ -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
|
||||
|
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user