From c431863312bd839a4b97d7939434a1f8bc8eb9fc Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sat, 11 Jun 2011 00:14:47 +0000 Subject: [PATCH] BGE Animations: * Adding BL_Action::Play() and BL_Action::Stop() * Making BL_ActonManger reuse BL_Actions instead of recreating them all the time * Making the Property play type work for the Action actuator. --- .../Converter/BL_ActionActuator.cpp | 17 +++- source/gameengine/Ketsji/BL_Action.cpp | 84 ++++++++++++------- source/gameengine/Ketsji/BL_Action.h | 9 +- source/gameengine/Ketsji/BL_ActionManager.cpp | 21 ++--- source/gameengine/Ketsji/BL_ActionManager.h | 5 +- source/gameengine/Ketsji/KX_GameObject.cpp | 6 +- 6 files changed, 88 insertions(+), 54 deletions(-) diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index 97bedb4d6c7..a6ef7155522 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -150,6 +150,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame) bool bPositiveEvent = false; KX_GameObject *obj = (KX_GameObject*)GetParent(); short play_mode = BL_Action::ACT_MODE_PLAY; + float start = m_startframe, end = m_endframe; // Don't do anything if we're not "active" if (!frame) @@ -162,7 +163,14 @@ bool BL_ActionActuator::Update(double curtime, bool frame) play_mode = BL_Action::ACT_MODE_LOOP; else if (m_playtype == ACT_ACTION_PINGPONG) play_mode = BL_Action::ACT_MODE_PING_PONG; + else if (m_playtype == ACT_ACTION_FROM_PROP) + { + CValue* prop = GetParent()->GetProperty(m_propname); + play_mode = BL_Action::ACT_MODE_PLAY; + start = end = prop->GetNumber(); + m_is_going = false; + } // Handle events bNegativeEvent = m_negevent; @@ -172,7 +180,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame) if (!m_is_going && bPositiveEvent) { m_is_going = true; - obj->PlayAction(m_action->id.name+2, m_startframe, m_endframe, 0, m_blendin, play_mode); + obj->PlayAction(m_action->id.name+2, start, end, 0, m_blendin, play_mode); if (m_end_reset) obj->SetActionFrame(0, m_localtime); } @@ -202,9 +210,12 @@ bool BL_ActionActuator::Update(double curtime, bool frame) newval->Release(); } - + if (m_playtype == ACT_ACTION_FROM_PROP) + { + return true; + } // Handle a finished animation - if (m_is_going && obj->IsActionDone(0)) + else if (m_is_going && obj->IsActionDone(0)) { return false; } diff --git a/source/gameengine/Ketsji/BL_Action.cpp b/source/gameengine/Ketsji/BL_Action.cpp index 512aa962b05..bd65c7d45d8 100644 --- a/source/gameengine/Ketsji/BL_Action.cpp +++ b/source/gameengine/Ketsji/BL_Action.cpp @@ -46,43 +46,23 @@ extern "C" { #include "RNA_define.h" } -BL_Action::BL_Action(class KX_GameObject* gameobj, - const char* name, - float start, - float end, - float blendin, - short play_mode, - short blend_mode, - float playback_speed) +BL_Action::BL_Action(class KX_GameObject* gameobj) : m_obj(gameobj), - m_startframe(start), - m_endframe(end), - m_blendin(blendin), - m_playmode(play_mode), + m_startframe(0.f), + m_endframe(0.f), + m_blendin(0.f), + m_playmode(0), m_endtime(0.f), - m_localtime(start), + m_localtime(0.f), m_blendframe(0.f), m_blendstart(0.f), - m_speed(playback_speed), + m_speed(0.f), m_pose(NULL), m_blendpose(NULL), m_sg_contr(NULL), - m_done(false) + m_done(true) { - m_starttime = KX_GetActiveEngine()->GetFrameTime(); - m_action = (bAction*)KX_GetActiveScene()->GetLogicManager()->GetActionByName(name); - - if (!m_action) printf("Failed to load action: %s\n", name); - - if (m_obj->GetGameObjectType() != SCA_IObject::OBJ_ARMATURE) - { - // Create an SG_Controller - m_sg_contr = BL_CreateIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter()); - m_obj->GetSGNode()->AddSGController(m_sg_contr); - m_sg_contr->SetObject(m_obj->GetSGNode()); - InitIPO(); - } } @@ -99,6 +79,54 @@ BL_Action::~BL_Action() } } +void BL_Action::Play(const char* name, + float start, + float end, + float blendin, + short play_mode, + short blend_mode, + float playback_speed) +{ + bAction* prev_action = m_action; + + // First try to load the action + m_action = (bAction*)KX_GetActiveScene()->GetLogicManager()->GetActionByName(name); + if (!m_action) + { + printf("Failed to load action: %s\n", name); + m_done = true; + return; + } + + //if (m_obj->GetGameObjectType() != SCA_IObject::OBJ_ARMATURE) + if (prev_action != m_action) + { + // Create an SG_Controller + m_sg_contr = BL_CreateIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter()); + m_obj->GetSGNode()->AddSGController(m_sg_contr); + m_sg_contr->SetObject(m_obj->GetSGNode()); + InitIPO(); + } + + // Now that we have an action, we have something we can play + m_starttime = KX_GetActiveEngine()->GetFrameTime(); + m_startframe = m_localtime = start; + m_endframe = end; + m_blendin = blendin; + m_playmode = play_mode; + m_endtime = 0.f; + m_blendframe = 0.f; + m_blendstart = 0.f; + m_speed = playback_speed; + + m_done = false; +} + +void BL_Action::Stop() +{ + m_done = true; +} + void BL_Action::InitIPO() { // Initialize the IPO diff --git a/source/gameengine/Ketsji/BL_Action.h b/source/gameengine/Ketsji/BL_Action.h index f7d0feb20af..1eb4483eb37 100644 --- a/source/gameengine/Ketsji/BL_Action.h +++ b/source/gameengine/Ketsji/BL_Action.h @@ -64,16 +64,17 @@ private: void InitIPO(); void SetLocalTime(float curtime); public: - BL_Action(class KX_GameObject* gameobj, - const char* name, + BL_Action(class KX_GameObject* gameobj); + ~BL_Action(); + + void Play(const char* name, float start, float end, float blendin, short play_mode, short blend_mode, float playback_speed); - ~BL_Action(); - + void Stop(); bool IsDone() {return m_done;} void Update(float curtime); diff --git a/source/gameengine/Ketsji/BL_ActionManager.cpp b/source/gameengine/Ketsji/BL_ActionManager.cpp index 2570cc1f140..0a99a5a43a9 100644 --- a/source/gameengine/Ketsji/BL_ActionManager.cpp +++ b/source/gameengine/Ketsji/BL_ActionManager.cpp @@ -29,17 +29,17 @@ #include "BL_ActionManager.h" -BL_ActionManager::BL_ActionManager() +BL_ActionManager::BL_ActionManager(class KX_GameObject *obj) { for (int i=0; iSetFrame(frame); } -void BL_ActionManager::PlayAction(class KX_GameObject* gameobj, - const char* name, +void BL_ActionManager::PlayAction(const char* name, float start, float end, short layer, @@ -71,13 +70,12 @@ void BL_ActionManager::PlayAction(class KX_GameObject* gameobj, StopAction(layer); // Create a new action - m_layers[layer] = new BL_Action(gameobj, name, start, end, blendin, play_mode, blend_mode, playback_speed); + m_layers[layer]->Play(name, start, end, blendin, play_mode, blend_mode, playback_speed); } void BL_ActionManager::StopAction(short layer) { - delete m_layers[layer]; - m_layers[layer] = 0; + m_layers[layer]->Stop(); } bool BL_ActionManager::IsActionDone(short layer) @@ -92,12 +90,9 @@ void BL_ActionManager::Update(float curtime) { for (int i=0; iIsDone()) { - if (m_layers[i]->IsDone()) - StopAction(i); - else - m_layers[i]->Update(curtime); + m_layers[i]->Update(curtime); } } } diff --git a/source/gameengine/Ketsji/BL_ActionManager.h b/source/gameengine/Ketsji/BL_ActionManager.h index 32e6ce82a76..b769db02bf9 100644 --- a/source/gameengine/Ketsji/BL_ActionManager.h +++ b/source/gameengine/Ketsji/BL_ActionManager.h @@ -39,11 +39,10 @@ private: BL_Action* m_layers[MAX_ACTION_LAYERS]; public: - BL_ActionManager(); + BL_ActionManager(class KX_GameObject* obj); ~BL_ActionManager(); - void PlayAction(class KX_GameObject* gameobj, - const char* name, + void PlayAction(const char* name, float start, float end, short layer=0, diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 0ea775e3fbc..ca7ed670f14 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -124,7 +124,7 @@ KX_GameObject::KX_GameObject( KX_NormalParentRelation::New(); m_pSGNode->SetParentRelation(parent_relation); - m_actionManager = new BL_ActionManager(); + m_actionManager = new BL_ActionManager(this); }; @@ -361,7 +361,7 @@ void KX_GameObject::PlayAction(const char* name, short blend_mode, float playback_speed) { - m_actionManager->PlayAction(this, name, start, end, layer, blendin, play_mode, blend_mode, playback_speed); + m_actionManager->PlayAction(name, start, end, layer, blendin, play_mode, blend_mode, playback_speed); } void KX_GameObject::StopAction(short layer) @@ -398,7 +398,7 @@ void KX_GameObject::ProcessReplica() m_pSGNode = NULL; m_pClient_info = new KX_ClientObjectInfo(*m_pClient_info); m_pClient_info->m_gameobject = this; - m_actionManager = new BL_ActionManager(); + m_actionManager = new BL_ActionManager(this); m_state = 0; #ifdef WITH_PYTHON