diff options
author | Mitchell Stokes <mogurijin@gmail.com> | 2011-05-28 11:15:27 +0400 |
---|---|---|
committer | Mitchell Stokes <mogurijin@gmail.com> | 2011-05-28 11:15:27 +0400 |
commit | 07dca944766e702453730fe1a55605dab9380c6e (patch) | |
tree | c0ac8ab439ef1cd06154353f0d7fa3aa71862ecb /source/gameengine/Ketsji | |
parent | bd5f78d1a0bf4e04800395952e9a26ba868cc31a (diff) |
BGE Animation:
* Adding IPOs to BL_Action
* Adding a "speed" option to adjust the playback speed by some factor
Diffstat (limited to 'source/gameengine/Ketsji')
-rw-r--r-- | source/gameengine/Ketsji/BL_Action.cpp | 48 | ||||
-rw-r--r-- | source/gameengine/Ketsji/BL_Action.h | 7 | ||||
-rw-r--r-- | source/gameengine/Ketsji/BL_ActionManager.cpp | 5 | ||||
-rw-r--r-- | source/gameengine/Ketsji/BL_ActionManager.h | 3 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_GameObject.cpp | 12 |
5 files changed, 61 insertions, 14 deletions
diff --git a/source/gameengine/Ketsji/BL_Action.cpp b/source/gameengine/Ketsji/BL_Action.cpp index dcd0c1402e1..6cce2a3486d 100644 --- a/source/gameengine/Ketsji/BL_Action.cpp +++ b/source/gameengine/Ketsji/BL_Action.cpp @@ -29,6 +29,7 @@ #include "BL_Action.h" #include "BL_ArmatureObject.h" +#include "KX_IpoConvert.h" #include "KX_GameObject.h" // These three are for getting the action from the logic manager @@ -49,7 +50,8 @@ BL_Action::BL_Action(class KX_GameObject* gameobj, float end, float blendin, short play_mode, - short blend_mode) + short blend_mode, + float playback_speed) : m_obj(gameobj), m_startframe(start), @@ -60,14 +62,26 @@ BL_Action::BL_Action(class KX_GameObject* gameobj, m_localtime(start), m_blendframe(0.f), m_blendstart(0.f), + m_speed(playback_speed), m_pose(NULL), m_blendpose(NULL), + m_sg_contr(NULL), m_done(false) { 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(); + } + } BL_Action::~BL_Action() @@ -76,11 +90,25 @@ BL_Action::~BL_Action() game_free_pose(m_pose); if (m_blendpose) game_free_pose(m_blendpose); + if (m_sg_contr) + { + m_obj->GetSGNode()->RemoveSGController(m_sg_contr); + delete m_sg_contr; + } +} + +void BL_Action::InitIPO() +{ + // Initialize the IPO + m_sg_contr->SetOption(SG_Controller::SG_CONTR_IPO_RESET, true); + m_sg_contr->SetOption(SG_Controller::SG_CONTR_IPO_IPO_AS_FORCE, false); + m_sg_contr->SetOption(SG_Controller::SG_CONTR_IPO_IPO_ADD, false); + m_sg_contr->SetOption(SG_Controller::SG_CONTR_IPO_LOCAL, false); } void BL_Action::SetLocalTime(float curtime) { - float dt = (curtime-m_starttime)*KX_KetsjiEngine::GetAnimFrameRate(); + float dt = (curtime-m_starttime)*KX_KetsjiEngine::GetAnimFrameRate()*m_speed; if (m_endframe < m_startframe) dt = -dt; @@ -90,12 +118,18 @@ void BL_Action::SetLocalTime(float curtime) void BL_Action::Update(float curtime) { + // Don't bother if we're done with the animation + if (m_done) + return; + curtime -= KX_KetsjiEngine::GetSuspendedDelta(); SetLocalTime(curtime); // Handle wrap around - if (m_localtime < m_startframe || m_localtime > m_endframe) + bool bforward = m_startframe < m_endframe; + if (bforward && (m_localtime < m_startframe || m_localtime > m_endframe) || + !bforward && (m_localtime > m_startframe || m_localtime < m_endframe)) { switch(m_playmode) { @@ -119,6 +153,9 @@ void BL_Action::Update(float curtime) break; } + + if (!m_done) + InitIPO(); } if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) @@ -193,6 +230,9 @@ void BL_Action::Update(float curtime) } else { - printf("Only armature actions are currently supported\n"); + InitIPO(); + m_sg_contr->SetSimulatedTime(m_localtime); + m_obj->GetSGNode()->UpdateWorldData(m_localtime); + m_obj->UpdateTransform(); } } diff --git a/source/gameengine/Ketsji/BL_Action.h b/source/gameengine/Ketsji/BL_Action.h index 3d977f3984a..203714a3b2f 100644 --- a/source/gameengine/Ketsji/BL_Action.h +++ b/source/gameengine/Ketsji/BL_Action.h @@ -41,6 +41,7 @@ private: struct bPose* m_pose; struct bPose* m_blendpose; struct PointerRNA *m_ptrrna; + class SG_Controller *m_sg_contr; class KX_GameObject* m_obj; float m_startframe; @@ -53,11 +54,14 @@ private: float m_blendframe; float m_blendstart; + float m_speed; + short m_playmode; short m_blendmode; bool m_done; + void InitIPO(); void SetLocalTime(float curtime); public: BL_Action(class KX_GameObject* gameobj, @@ -66,7 +70,8 @@ public: float end, float blendin, short play_mode, - short blend_mode); + short blend_mode, + float playback_speed); ~BL_Action(); bool IsDone() {return m_done;} diff --git a/source/gameengine/Ketsji/BL_ActionManager.cpp b/source/gameengine/Ketsji/BL_ActionManager.cpp index 359a7389b51..a4c8a7fe93f 100644 --- a/source/gameengine/Ketsji/BL_ActionManager.cpp +++ b/source/gameengine/Ketsji/BL_ActionManager.cpp @@ -49,14 +49,15 @@ void BL_ActionManager::PlayAction(class KX_GameObject* gameobj, short layer, float blendin, short play_mode, - short blend_mode) + short blend_mode, + float playback_speed) { // Remove a currently running action on this layer if there is one if (m_layers[layer]) StopAction(layer); // Create a new action - m_layers[layer] = new BL_Action(gameobj, name, start, end, blendin, play_mode, blend_mode); + m_layers[layer] = new BL_Action(gameobj, name, start, end, blendin, play_mode, blend_mode, playback_speed); } void BL_ActionManager::StopAction(short layer) diff --git a/source/gameengine/Ketsji/BL_ActionManager.h b/source/gameengine/Ketsji/BL_ActionManager.h index 409d6c24e30..a57e0e1ce87 100644 --- a/source/gameengine/Ketsji/BL_ActionManager.h +++ b/source/gameengine/Ketsji/BL_ActionManager.h @@ -49,7 +49,8 @@ public: short layer=0, float blendin=0.f, short play_mode=0, - short blend_mode=0); + short blend_mode=0, + float playback_speed=1.f); void StopAction(short layer); void Update(float); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 868dc4591e4..804a3d394ec 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -2992,18 +2992,18 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_GameObject, sendMessage, } KX_PYMETHODDEF_DOC(KX_GameObject, playAction, - "playAction(name, start_frame, end_frame, layer=0, blendin=0, play_mode=ACT_MODE_PLAY, blend_mode=ACT_BLEND_NONE)\n" + "playAction(name, start_frame, end_frame, layer=0, blendin=0, play_mode=ACT_MODE_PLAY, blend_mode=ACT_BLEND_NONE, speed=1.0)\n" "plays an action\n") { const char* name; - float start, end, blendin=0.f; + float start, end, blendin=0.f, speed=1.f; short layer=0; short play_mode=0, blend_mode=0; - static const char *kwlist[] = {"name", "start_frame", "end_frame", "layer", "blendin", "play_mode", "blend_mode", NULL}; + static const char *kwlist[] = {"name", "start_frame", "end_frame", "layer", "blendin", "play_mode", "blend_mode", "speed", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "sff|hfhh", const_cast<char**>(kwlist), - &name, &start, &end, &layer, &blendin, &play_mode, &blend_mode)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "sff|hfhhf", const_cast<char**>(kwlist), + &name, &start, &end, &layer, &blendin, &play_mode, &blend_mode, &speed)) return NULL; if (layer < 0 || layer > MAX_ACTION_LAYERS) @@ -3024,7 +3024,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, playAction, blend_mode = BL_Action::ACT_BLEND_NONE; } - m_actionManager->PlayAction(this, name, start, end, layer, blendin, play_mode, blend_mode); + m_actionManager->PlayAction(this, name, start, end, layer, blendin, play_mode, blend_mode, speed); Py_RETURN_NONE; } |