BGE Animations: Reimplemented the continuous function of the action actuator.

* To do this, I've added Get/SetFrame() functions.
  * I've also cleaned up a little bit of the wrap around logic in BL_Action.cpp.
This commit is contained in:
Mitchell Stokes 2011-06-01 07:42:40 +00:00
parent 6394261e54
commit 39bbf3854a
7 changed files with 93 additions and 5 deletions

@ -173,12 +173,21 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
{
m_is_going = true;
obj->PlayAction(m_action->id.name+2, m_startframe, m_endframe, 0, m_blendin, play_mode);
if (m_end_reset)
obj->SetActionFrame(0, m_localtime);
}
else if (m_is_going && bNegativeEvent)
{
m_is_going = false;
obj->StopAction(0);
return false;
if (!m_end_reset)
{
obj->StopAction(0);
return false;
}
m_localtime = obj->GetActionFrame(0);
obj->StopAction(0); // Stop the action after getting the frame
}
// Handle a finished animation

@ -27,6 +27,8 @@
* ***** END GPL LICENSE BLOCK *****
*/
#include <cstdlib>
#include "BL_Action.h"
#include "BL_ArmatureObject.h"
#include "KX_IpoConvert.h"
@ -106,6 +108,33 @@ void BL_Action::InitIPO()
m_sg_contr->SetOption(SG_Controller::SG_CONTR_IPO_LOCAL, false);
}
float BL_Action::GetFrame()
{
return m_localtime;
}
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;
if (m_endframe < m_startframe)
dt = -dt;
m_starttime -= dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed);
}
void BL_Action::SetLocalTime(float curtime)
{
float dt = (curtime-m_starttime)*KX_KetsjiEngine::GetAnimFrameRate()*m_speed;
@ -127,9 +156,7 @@ void BL_Action::Update(float curtime)
SetLocalTime(curtime);
// Handle wrap around
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))
if (m_localtime < min(m_startframe, m_endframe) || m_localtime > max(m_startframe, m_endframe))
{
switch(m_playmode)
{

@ -77,6 +77,12 @@ public:
bool IsDone() {return m_done;}
void Update(float curtime);
// Accessors
float GetFrame();
// Mutators
void SetFrame(float frame);
enum
{
ACT_MODE_PLAY = 0,

@ -42,6 +42,20 @@ BL_ActionManager::~BL_ActionManager()
StopAction(i);
}
float BL_ActionManager::GetActionFrame(short layer)
{
if (m_layers[layer])
return m_layers[layer]->GetFrame();
return 0.f;
}
void BL_ActionManager::SetActionFrame(short layer, float frame)
{
if (m_layers[layer])
m_layers[layer]->SetFrame(frame);
}
void BL_ActionManager::PlayAction(class KX_GameObject* gameobj,
const char* name,
float start,

@ -51,10 +51,14 @@ public:
short play_mode=0,
short blend_mode=0,
float playback_speed=1.f);
float GetActionFrame(short layer);
void SetActionFrame(short layer, float frame);
void StopAction(short layer);
bool IsActionDone(short layer);
void Update(float);
#ifdef WITH_CXX_GUARDEDALLOC
public:
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_ActionManager"); }

@ -379,6 +379,16 @@ void KX_GameObject::UpdateActionManager(float curtime)
m_actionManager->Update(curtime);
}
float KX_GameObject::GetActionFrame(short layer)
{
return m_actionManager->GetActionFrame(layer);
}
void KX_GameObject::SetActionFrame(short layer, float frame)
{
m_actionManager->SetActionFrame(layer, frame);
}
void KX_GameObject::ProcessReplica()
{
SCA_IObject::ProcessReplica();

@ -202,6 +202,10 @@ public:
*/
void RemoveParent(KX_Scene *scene);
/*********************************
* Animation API
*********************************/
/**
* Adds an action to the object's action manager
*/
@ -214,6 +218,16 @@ public:
short blend_mode=0,
float playback_speed=1.f);
/**
* Gets the current frame of an action
*/
float GetActionFrame(short layer);
/**
* Sets the current frame of an action
*/
void SetActionFrame(short layer, float frame);
/**
* Remove an action from the object's action manager
*/
@ -229,6 +243,10 @@ public:
*/
void UpdateActionManager(float curtime);
/*********************************
* End Animation API
*********************************/
/**
* Construct a game object. This class also inherits the
* default constructors - use those with care!