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.
This commit is contained in:
Mitchell Stokes 2011-06-11 00:14:47 +00:00
parent 9d5f436d75
commit c431863312
6 changed files with 88 additions and 54 deletions

@ -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;
}

@ -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

@ -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);

@ -29,17 +29,17 @@
#include "BL_ActionManager.h"
BL_ActionManager::BL_ActionManager()
BL_ActionManager::BL_ActionManager(class KX_GameObject *obj)
{
for (int i=0; i<MAX_ACTION_LAYERS; ++i)
m_layers[i] = 0;
m_layers[i] = new BL_Action(obj);
}
BL_ActionManager::~BL_ActionManager()
{
for (int i=0; i<MAX_ACTION_LAYERS; ++i)
if (m_layers[i])
StopAction(i);
delete m_layers[i];
}
float BL_ActionManager::GetActionFrame(short layer)
@ -56,8 +56,7 @@ void BL_ActionManager::SetActionFrame(short layer, float frame)
m_layers[layer]->SetFrame(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; i<MAX_ACTION_LAYERS; ++i)
{
if (m_layers[i])
if (!m_layers[i]->IsDone())
{
if (m_layers[i]->IsDone())
StopAction(i);
else
m_layers[i]->Update(curtime);
m_layers[i]->Update(curtime);
}
}
}

@ -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,

@ -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