diff options
author | Mitchell Stokes <mogurijin@gmail.com> | 2011-06-29 05:05:12 +0400 |
---|---|---|
committer | Mitchell Stokes <mogurijin@gmail.com> | 2011-06-29 05:05:12 +0400 |
commit | de3c95a09c9eb82b04da4345c98eb53030342af8 (patch) | |
tree | 1bd6d5e617e7dff38bbb1dbc7d8eda54645ec9f8 /source/gameengine/Ketsji/BL_Action.cpp | |
parent | caef67eb923e37accdbb0664f90c99fe928406c2 (diff) |
BGE Animations: Adding blendin for Shape Actions.
Diffstat (limited to 'source/gameengine/Ketsji/BL_Action.cpp')
-rw-r--r-- | source/gameengine/Ketsji/BL_Action.cpp | 96 |
1 files changed, 77 insertions, 19 deletions
diff --git a/source/gameengine/Ketsji/BL_Action.cpp b/source/gameengine/Ketsji/BL_Action.cpp index 90349bcfddd..1741e74a771 100644 --- a/source/gameengine/Ketsji/BL_Action.cpp +++ b/source/gameengine/Ketsji/BL_Action.cpp @@ -142,6 +142,30 @@ void BL_Action::Play(const char* name, m_ipo_flags = ipo_flags; InitIPO(); + // Setup blendin shapes/poses + if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) + { + if (!m_blendpose) + { + BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj; + obj->GetMRDPose(&m_blendpose); + } + } + else + { + BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj; + BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer()); + + obj->GetShape(m_blendshape); + + // Now that we have the previous blend shape saved, we can clear out the key to avoid any + // further interference. + KeyBlock *kb; + for (kb=(KeyBlock*)shape_deformer->GetKey()->block.first; kb; kb=(KeyBlock*)kb->next) + kb->curval = 0.f; + + } + // Now that we have an action, we have something we can play m_starttime = KX_GetActiveEngine()->GetFrameTime(); m_startframe = m_localtime = start; @@ -197,6 +221,39 @@ void BL_Action::SetLocalTime(float curtime) m_localtime = m_startframe + dt; } +void BL_Action::IncrementBlending(float curtime) +{ + // Setup m_blendstart if we need to + if (m_blendstart == 0.f) + m_blendstart = curtime; + + // Bump the blend frame + m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate(); + + // Clamp + if (m_blendframe>m_blendin) + m_blendframe = m_blendin; +} + + +void BL_Action::BlendShape(Key* key, float srcweight) +{ + vector<float>::const_iterator it; + float dstweight; + KeyBlock *kb; + + dstweight = 1.0F - srcweight; + //printf("Dst: %f\tSrc: %f\n", srcweight, dstweight); + for (it=m_blendshape.begin(), kb = (KeyBlock*)key->block.first; + kb && it != m_blendshape.end(); + kb = (KeyBlock*)kb->next, it++) { + //printf("OirgKeys: %f\t%f\n", kb->curval, (*it)); + kb->curval = kb->curval * dstweight + (*it) * srcweight; + //printf("NewKey: %f\n", kb->curval); + } + //printf("\n"); +} + void BL_Action::Update(float curtime) { // Don't bother if we're done with the animation @@ -260,25 +317,16 @@ void BL_Action::Update(float curtime) arm->pose = temp; } - // Handle blending between actions + // Handle blending between armature actions if (m_blendin && m_blendframe<m_blendin) { - if (!m_blendpose) - { - obj->GetMRDPose(&m_blendpose); - m_blendstart = curtime; - } + IncrementBlending(curtime); // Calculate weight float weight = 1.f - (m_blendframe/m_blendin); - game_blend_poses(m_pose, m_blendpose, weight); - // Bump the blend frame - m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate(); - - // Clamp - if (m_blendframe>m_blendin) - m_blendframe = m_blendin; + // Blend the poses + game_blend_poses(m_pose, m_blendpose, weight); } obj->SetPose(m_pose); @@ -295,15 +343,25 @@ void BL_Action::Update(float curtime) { Key *key = shape_deformer->GetKey(); - // We go through and clear out the keyblocks so there isn't any interference - // from other shape actions - KeyBlock *kb; - for (kb=(KeyBlock*)key->block.first; kb; kb=(KeyBlock*)kb->next) - kb->curval = 0.f; animsys_evaluate_action(m_ptrrna, m_action, NULL, m_localtime); - // XXX TODO handle blendin + // Handle blending between shape actions + if (m_blendin && m_blendframe < m_blendin) + { + IncrementBlending(curtime); + + float weight = 1.f - (m_blendframe/m_blendin); + + // We go through and clear out the keyblocks so there isn't any interference + // from other shape actions + KeyBlock *kb; + for (kb=(KeyBlock*)key->block.first; kb; kb=(KeyBlock*)kb->next) + kb->curval = 0.f; + + // Now blend the shape + BlendShape(key, weight); + } obj->SetActiveAction(NULL, 0, m_localtime); } |