diff options
author | Mitchell Stokes <mogurijin@gmail.com> | 2011-08-08 08:28:30 +0400 |
---|---|---|
committer | Mitchell Stokes <mogurijin@gmail.com> | 2011-08-08 08:28:30 +0400 |
commit | 8883702f8a3b57d0316811e9412bd46ce0dd9c0d (patch) | |
tree | 0aff4a8eaee6ad9e9d1fbd6e60c85fa6a81149df /source/gameengine | |
parent | a8096ef0acb780d5a6d93aef422ce3d82877a60c (diff) |
BGE Animations: Various compatibility fixes:
* Blendin for Loop End works even after a negative pulse. Flipper could still use some work in this area.
* Continuous works a lot better.
* BL_Action::SetFrame() should work a little smoother.
Diffstat (limited to 'source/gameengine')
-rw-r--r-- | source/gameengine/Converter/BL_ActionActuator.cpp | 18 | ||||
-rw-r--r-- | source/gameengine/Ketsji/BL_Action.cpp | 43 | ||||
-rw-r--r-- | source/gameengine/Ketsji/BL_Action.h | 4 | ||||
-rw-r--r-- | source/gameengine/Ketsji/BL_ActionManager.cpp | 12 | ||||
-rw-r--r-- | source/gameengine/Ketsji/BL_ActionManager.h | 10 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_GameObject.cpp | 10 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_GameObject.h | 10 |
7 files changed, 86 insertions, 21 deletions
diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index 0932493ccb8..8efcdd8c551 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -139,6 +139,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame) { bool bNegativeEvent = false; bool bPositiveEvent = false; + bool use_continue = false; KX_GameObject *obj = (KX_GameObject*)GetParent(); short play_mode = BL_Action::ACT_MODE_PLAY; float start = m_startframe, end = m_endframe; @@ -172,6 +173,10 @@ bool BL_ActionActuator::Update(double curtime, bool frame) play_mode = BL_Action::ACT_MODE_PLAY; start = end = prop->GetNumber(); } + + // Continue only really makes sense for play stop. All other modes go until they are complete. + if (m_flag & ACT_FLAG_CONTINUE && m_playtype == ACT_ACTION_LOOP_STOP) + use_continue = true; // Handle events @@ -184,14 +189,10 @@ bool BL_ActionActuator::Update(double curtime, bool frame) if (bPositiveEvent) { - - if (m_playtype != ACT_ACTION_PINGPONG && m_flag & ACT_FLAG_ACTIVE && m_flag & ACT_FLAG_CONTINUE) - start = m_localtime = obj->GetActionFrame(m_layer); - if (obj->PlayAction(m_action->id.name+2, start, end, m_layer, m_priority, m_blendin, play_mode, m_layer_weight, m_ipo_flags)) { m_flag |= ACT_FLAG_ACTIVE; - if (m_playtype != ACT_ACTION_PINGPONG && m_flag & ACT_FLAG_CONTINUE) + if (use_continue) obj->SetActionFrame(m_layer, m_localtime); if (m_playtype == ACT_ACTION_PLAY) @@ -217,6 +218,8 @@ bool BL_ActionActuator::Update(double curtime, bool frame) if (m_playtype == ACT_ACTION_LOOP_STOP) { m_localtime = obj->GetActionFrame(m_layer); + if (m_localtime < min(m_startframe, m_endframe) || m_localtime > max(m_startframe, m_endframe)) + m_localtime = m_startframe; obj->StopAction(m_layer); // Stop the action after getting the frame // We're done @@ -226,9 +229,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame) else if (m_playtype == ACT_ACTION_LOOP_END || m_playtype == ACT_ACTION_PINGPONG) { // Convert into a play and let it finish - start = obj->GetActionFrame(m_layer); - obj->StopAction(m_layer); - obj->PlayAction(m_action->id.name+2, start, end, m_layer, m_priority, 0, BL_Action::ACT_MODE_PLAY, m_layer_weight, m_ipo_flags); + obj->SetPlayMode(m_layer, BL_Action::ACT_MODE_PLAY); m_flag |= ACT_FLAG_PLAY_END; @@ -240,7 +241,6 @@ bool BL_ActionActuator::Update(double curtime, bool frame) // Convert into a play action and play back to the beginning end = start; start = obj->GetActionFrame(m_layer); - obj->StopAction(m_layer); obj->PlayAction(m_action->id.name+2, start, end, m_layer, m_priority, 0, BL_Action::ACT_MODE_PLAY, m_layer_weight, m_ipo_flags); m_flag |= ACT_FLAG_PLAY_END; diff --git a/source/gameengine/Ketsji/BL_Action.cpp b/source/gameengine/Ketsji/BL_Action.cpp index caffd3cd8ca..4cf6f982006 100644 --- a/source/gameengine/Ketsji/BL_Action.cpp +++ b/source/gameengine/Ketsji/BL_Action.cpp @@ -67,7 +67,8 @@ BL_Action::BL_Action(class KX_GameObject* gameobj) m_priority(0), m_playmode(0), m_ipo_flags(0), - m_done(true) + m_done(true), + m_calc_localtime(true) { if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) { @@ -215,24 +216,25 @@ float BL_Action::GetFrame() void BL_Action::SetFrame(float frame) { - float dt; - // Clamp the frame to the start and end frame if (frame < min(m_startframe, m_endframe)) frame = min(m_startframe, m_endframe); else if (frame > max(m_startframe, m_endframe)) frame = max(m_startframe, m_endframe); - // We don't set m_localtime directly since it's recalculated - // in the next update. So, we modify the value (m_starttime) - // used to calculate m_localtime the next time SetLocalTime() is called. - - dt = frame-m_startframe; + m_localtime = frame; + m_calc_localtime = false; +} - if (m_endframe < m_startframe) - dt = -dt; +void BL_Action::SetPlayMode(short play_mode) +{ + m_playmode = play_mode; +} - m_starttime -= dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed); +void BL_Action::SetTimes(float start, float end) +{ + m_startframe = start; + m_endframe = end; } void BL_Action::SetLocalTime(float curtime) @@ -245,6 +247,16 @@ void BL_Action::SetLocalTime(float curtime) m_localtime = m_startframe + dt; } +void BL_Action::ResetStartTime(float curtime) +{ + float dt = m_localtime - m_startframe; + + m_starttime = curtime - dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed); + printf("Before: %f, ", m_localtime); + SetLocalTime(curtime); + printf("After: %f\n", m_localtime); +} + void BL_Action::IncrementBlending(float curtime) { // Setup m_blendstart if we need to @@ -285,7 +297,14 @@ void BL_Action::Update(float curtime) return; curtime -= KX_KetsjiEngine::GetSuspendedDelta(); - SetLocalTime(curtime); + + if (m_calc_localtime) + SetLocalTime(curtime); + else + { + ResetStartTime(curtime); + m_calc_localtime = true; + } // Handle wrap around if (m_localtime < min(m_startframe, m_endframe) || m_localtime > max(m_startframe, m_endframe)) diff --git a/source/gameengine/Ketsji/BL_Action.h b/source/gameengine/Ketsji/BL_Action.h index 14312e158c0..75bda56419a 100644 --- a/source/gameengine/Ketsji/BL_Action.h +++ b/source/gameengine/Ketsji/BL_Action.h @@ -71,9 +71,11 @@ private: short m_ipo_flags; bool m_done; + bool m_calc_localtime; void InitIPO(); void SetLocalTime(float curtime); + void ResetStartTime(float curtime); void IncrementBlending(float curtime); void BlendShape(struct Key* key, float srcweight, std::vector<float>& blendshape); public: @@ -111,6 +113,8 @@ public: // Mutators void SetFrame(float frame); + void SetPlayMode(short play_mode); + void SetTimes(float start, float end); enum { diff --git a/source/gameengine/Ketsji/BL_ActionManager.cpp b/source/gameengine/Ketsji/BL_ActionManager.cpp index 2ee0b58574a..af0d4bff8f0 100644 --- a/source/gameengine/Ketsji/BL_ActionManager.cpp +++ b/source/gameengine/Ketsji/BL_ActionManager.cpp @@ -63,6 +63,18 @@ struct bAction *BL_ActionManager::GetCurrentAction(short layer) return 0; } +void BL_ActionManager::SetPlayMode(short layer, short mode) +{ + if (m_layers[layer]) + m_layers[layer]->SetPlayMode(mode); +} + +void BL_ActionManager::SetTimes(short layer, float start, float end) +{ + if (m_layers[layer]) + m_layers[layer]->SetTimes(start, end); +} + bool BL_ActionManager::PlayAction(const char* name, float start, float end, diff --git a/source/gameengine/Ketsji/BL_ActionManager.h b/source/gameengine/Ketsji/BL_ActionManager.h index 3818f643b1c..c310e231ed7 100644 --- a/source/gameengine/Ketsji/BL_ActionManager.h +++ b/source/gameengine/Ketsji/BL_ActionManager.h @@ -71,6 +71,16 @@ public: struct bAction *GetCurrentAction(short layer); /** + * Sets play mode of the action on the given layer + */ + void SetPlayMode(short layer, short mode); + + /** + * Sets the start and end times of the action on the given layer + */ + void SetTimes(short layer, float start, float end); + + /** * Stop playing the action on the given layer */ void StopAction(short layer); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 91e62442646..4f8860f4767 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -404,6 +404,16 @@ bAction *KX_GameObject::GetCurrentAction(short layer) return GetActionManager()->GetCurrentAction(layer); } +void KX_GameObject::SetPlayMode(short layer, short mode) +{ + GetActionManager()->SetPlayMode(layer, mode); +} + +void KX_GameObject::SetTimes(short layer, float start, float end) +{ + GetActionManager()->SetTimes(layer, start, end); +} + void KX_GameObject::ProcessReplica() { SCA_IObject::ProcessReplica(); diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 40bd86fed1b..6e79914172b 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -239,6 +239,16 @@ public: bAction *GetCurrentAction(short layer); /** + * Sets play mode of the action on the given layer + */ + void SetPlayMode(short layer, short mode); + + /** + * Sets the start and end times of the action on the given layer + */ + void SetTimes(short layer, float start, float end); + + /** * Stop playing the action on the given layer */ void StopAction(short layer); |