Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Stokes <mogurijin@gmail.com>2011-05-28 11:15:27 +0400
committerMitchell Stokes <mogurijin@gmail.com>2011-05-28 11:15:27 +0400
commit07dca944766e702453730fe1a55605dab9380c6e (patch)
treec0ac8ab439ef1cd06154353f0d7fa3aa71862ecb /source/gameengine/Ketsji
parentbd5f78d1a0bf4e04800395952e9a26ba868cc31a (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.cpp48
-rw-r--r--source/gameengine/Ketsji/BL_Action.h7
-rw-r--r--source/gameengine/Ketsji/BL_ActionManager.cpp5
-rw-r--r--source/gameengine/Ketsji/BL_ActionManager.h3
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp12
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;
}