diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_action.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 55 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_ActionActuator.cpp | 6 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_ArmatureObject.cpp | 47 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_ArmatureObject.h | 3 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_ShapeDeformer.cpp | 4 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_SkinDeformer.cpp | 2 | ||||
-rw-r--r-- | source/gameengine/GamePlayer/ghost/GPG_Application.cpp | 4 |
8 files changed, 89 insertions, 36 deletions
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index 4a13fa31f6c..37ced4cb00b 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -163,6 +163,10 @@ void extract_ipochannels_from_action(ListBase *lb, struct ID *id, struct bAction /* write values returned by extract_ipochannels_from_action, returns the number of value written */ int execute_ipochannels(ListBase *lb); +/* functions used by the game engine */ +void game_copy_pose(struct bPose **dst, struct bPose *src); +void game_free_pose(struct bPose *pose); + #ifdef __cplusplus }; #endif diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 043ede5987a..d65a99f23f0 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -62,6 +62,7 @@ #include "BLI_arithb.h" #include "BLI_blenlib.h" +#include "BLI_ghash.h" #include "nla.h" @@ -340,6 +341,60 @@ void free_pose(bPose *pose) } } +void game_copy_pose(bPose **dst, bPose *src) +{ + bPose *out; + bPoseChannel *pchan, *outpchan; + GHash *ghash; + + /* the game engine copies the current armature pose and then swaps + * the object pose pointer. this makes it possible to change poses + * without affecting the original blender data. */ + + if (!src) { + *dst=NULL; + return; + } + else if (*dst==src) { + printf("copy_pose source and target are the same\n"); + *dst=NULL; + return; + } + + out= MEM_dupallocN(src); + out->agroups.first= out->agroups.last= NULL; + duplicatelist(&out->chanbase, &src->chanbase); + + /* remap pointers */ + ghash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + + pchan= src->chanbase.first; + outpchan= out->chanbase.first; + for (; pchan; pchan=pchan->next, outpchan=outpchan->next) + BLI_ghash_insert(ghash, pchan, outpchan); + + for (pchan=out->chanbase.first; pchan; pchan=pchan->next) { + pchan->parent= BLI_ghash_lookup(ghash, pchan->parent); + pchan->child= BLI_ghash_lookup(ghash, pchan->child); + pchan->path= NULL; + } + + BLI_ghash_free(ghash, NULL, NULL); + + *dst=out; +} + +void game_free_pose(bPose *pose) +{ + if (pose) { + /* we don't free constraints, those are owned by the original pose */ + if(pose->chanbase.first) + BLI_freelistN(&pose->chanbase); + + MEM_freeN(pose); + } +} + static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan) { bConstraint *pcon, *con; diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index b8514e33127..c08427c6d27 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -59,11 +59,11 @@ BL_ActionActuator::~BL_ActionActuator() { if (m_pose) - free_pose(m_pose); + game_free_pose(m_pose); if (m_userpose) - free_pose(m_userpose); + game_free_pose(m_userpose); if (m_blendpose) - free_pose(m_blendpose); + game_free_pose(m_blendpose); } void BL_ActionActuator::ProcessReplica(){ diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index bf774bf7568..d2001212f7d 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -45,7 +45,6 @@ #include <config.h> #endif - BL_ArmatureObject::BL_ArmatureObject( void* sgReplicationInfo, SG_Callbacks callbacks, @@ -65,7 +64,7 @@ BL_ArmatureObject::BL_ArmatureObject( * the original pose before calling into blender functions, to deal with * replica's or other objects using the same blender object */ m_pose = NULL; - copy_pose(&m_pose, m_objArma->pose, 1 /* copy_constraint_channels_hack */); + game_copy_pose(&m_pose, m_objArma->pose); } CValue* BL_ArmatureObject::GetReplica() @@ -84,32 +83,30 @@ void BL_ArmatureObject::ProcessReplica(BL_ArmatureObject *replica) KX_GameObject::ProcessReplica(replica); replica->m_pose = NULL; - copy_pose(&replica->m_pose, m_pose, 1 /* copy_constraint_channels_hack */); + game_copy_pose(&replica->m_pose, m_pose); } BL_ArmatureObject::~BL_ArmatureObject() { if (m_pose) - free_pose(m_pose); + game_free_pose(m_pose); } -bool BL_ArmatureObject::VerifyPose() +void BL_ArmatureObject::ApplyPose() { + m_armpose = m_objArma->pose; + m_objArma->pose = m_pose; + if(m_lastapplyframe != m_lastframe) { - extract_pose_from_pose(m_objArma->pose, m_pose); where_is_pose(m_objArma); m_lastapplyframe = m_lastframe; - extract_pose_from_pose(m_pose, m_objArma->pose); - return false; } - else - return true; } -void BL_ArmatureObject::ApplyPose() +void BL_ArmatureObject::RestorePose() { - if(VerifyPose()) - extract_pose_from_pose(m_objArma->pose, m_pose); + m_objArma->pose = m_armpose; + m_armpose = NULL; } void BL_ArmatureObject::SetPose(bPose *pose) @@ -164,8 +161,7 @@ void BL_ArmatureObject::GetPose(bPose **pose) a crash and memory leakage when &BL_ActionActuator::m_pose is freed */ - int copy_constraint_channels_hack = 1; - copy_pose(pose, m_pose, copy_constraint_channels_hack); + game_copy_pose(pose, m_pose); } else { if (*pose == m_pose) @@ -181,17 +177,10 @@ void BL_ArmatureObject::GetMRDPose(bPose **pose) /* If the caller supplies a null pose, create a new one. */ /* Otherwise, copy the armature's pose channels into the caller-supplied pose */ - if (!*pose) { - // must duplicate the constraints too otherwise we have corruption in free_pose_channels() - // because it will free the blender constraints. - // Ideally, blender should rememeber that the constraints were not copied so that - // free_pose_channels() would not free them. - copy_pose(pose, m_pose, 1); - } - else { + if (!*pose) + game_copy_pose(pose, m_pose); + else extract_pose_from_pose(*pose, m_pose); - } - } short BL_ArmatureObject::GetActivePriority() @@ -210,13 +199,11 @@ bool BL_ArmatureObject::GetBoneMatrix(Bone* bone, MT_Matrix4x4& matrix) ApplyPose(); pchan = get_pose_channel(m_objArma->pose, bone->name); - - if(pchan) { + if(pchan) matrix.setValue(&pchan->pose_mat[0][0]); - return true; - } + RestorePose(); - return false; + return (pchan != NULL); } float BL_ArmatureObject::GetBoneLength(Bone* bone) const diff --git a/source/gameengine/Converter/BL_ArmatureObject.h b/source/gameengine/Converter/BL_ArmatureObject.h index 6f2c0d2f4c9..d68e37d9e37 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.h +++ b/source/gameengine/Converter/BL_ArmatureObject.h @@ -61,7 +61,7 @@ public: void SetPose (struct bPose *pose); void ApplyPose(); - bool VerifyPose(); + void RestorePose(); bool SetActiveAction(class BL_ActionActuator *act, short priority, double curtime); @@ -82,6 +82,7 @@ protected: Object *m_objArma; struct bArmature *m_armature; struct bPose *m_pose; + struct bPose *m_armpose; struct bPose *m_framePose; double m_lastframe; class BL_ActionActuator *m_activeAct; diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp index 236cd1a6667..dfd33e45fef 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.cpp +++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp @@ -109,6 +109,7 @@ bool BL_ShapeDeformer::ExecuteShapeDrivers(void) vector<IpoCurve*>::iterator it; void *poin; int type; + // the shape drivers use the bone matrix as input. Must // update the matrix now m_armobj->ApplyPose(); @@ -121,7 +122,10 @@ bool BL_ShapeDeformer::ExecuteShapeDrivers(void) if (poin) write_ipo_poin(poin, type, icu->curval); } + ForceUpdate(); + m_armobj->RestorePose(); + return true; } return false; diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index d8e7a9cdadf..b7b39ad7fbf 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -197,6 +197,8 @@ bool BL_SkinDeformer::Update(void) /* Update the current frame */ m_lastArmaUpdate=m_armobj->GetLastFrame(); + m_armobj->RestorePose(); + /* indicate that the m_transverts and normals are up to date */ return true; } diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index 752b776beff..4cd5184fee1 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -139,7 +139,7 @@ GPG_Application::GPG_Application(GHOST_ISystem* system) GPG_Application::~GPG_Application(void) { if(m_pyGlobalDictString) { - delete m_pyGlobalDictString; + delete [] m_pyGlobalDictString; m_pyGlobalDictString = 0; m_pyGlobalDictString_Length = 0; } @@ -729,7 +729,7 @@ void GPG_Application::stopEngine() // m_pyGlobalDictString so we can restore after python has stopped // and started between .blend file loads. if(m_pyGlobalDictString) { - delete m_pyGlobalDictString; + delete [] m_pyGlobalDictString; m_pyGlobalDictString = 0; } |