forked from bartvdbraak/blender
BGE Animations: Various compatibility fixes:
* Blendin for Loop End works even after a negative pulse. Flipper could still use some work in this area. * Continuous works a lot better. * BL_Action::SetFrame() should work a little smoother.
This commit is contained in:
parent
a8096ef0ac
commit
8883702f8a
@ -139,6 +139,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
|
||||
{
|
||||
bool bNegativeEvent = false;
|
||||
bool bPositiveEvent = false;
|
||||
bool use_continue = false;
|
||||
KX_GameObject *obj = (KX_GameObject*)GetParent();
|
||||
short play_mode = BL_Action::ACT_MODE_PLAY;
|
||||
float start = m_startframe, end = m_endframe;
|
||||
@ -172,6 +173,10 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
|
||||
play_mode = BL_Action::ACT_MODE_PLAY;
|
||||
start = end = prop->GetNumber();
|
||||
}
|
||||
|
||||
// Continue only really makes sense for play stop. All other modes go until they are complete.
|
||||
if (m_flag & ACT_FLAG_CONTINUE && m_playtype == ACT_ACTION_LOOP_STOP)
|
||||
use_continue = true;
|
||||
|
||||
|
||||
// Handle events
|
||||
@ -184,14 +189,10 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
|
||||
|
||||
if (bPositiveEvent)
|
||||
{
|
||||
|
||||
if (m_playtype != ACT_ACTION_PINGPONG && m_flag & ACT_FLAG_ACTIVE && m_flag & ACT_FLAG_CONTINUE)
|
||||
start = m_localtime = obj->GetActionFrame(m_layer);
|
||||
|
||||
if (obj->PlayAction(m_action->id.name+2, start, end, m_layer, m_priority, m_blendin, play_mode, m_layer_weight, m_ipo_flags))
|
||||
{
|
||||
m_flag |= ACT_FLAG_ACTIVE;
|
||||
if (m_playtype != ACT_ACTION_PINGPONG && m_flag & ACT_FLAG_CONTINUE)
|
||||
if (use_continue)
|
||||
obj->SetActionFrame(m_layer, m_localtime);
|
||||
|
||||
if (m_playtype == ACT_ACTION_PLAY)
|
||||
@ -217,6 +218,8 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
|
||||
if (m_playtype == ACT_ACTION_LOOP_STOP)
|
||||
{
|
||||
m_localtime = obj->GetActionFrame(m_layer);
|
||||
if (m_localtime < min(m_startframe, m_endframe) || m_localtime > max(m_startframe, m_endframe))
|
||||
m_localtime = m_startframe;
|
||||
obj->StopAction(m_layer); // Stop the action after getting the frame
|
||||
|
||||
// We're done
|
||||
@ -226,9 +229,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
|
||||
else if (m_playtype == ACT_ACTION_LOOP_END || m_playtype == ACT_ACTION_PINGPONG)
|
||||
{
|
||||
// Convert into a play and let it finish
|
||||
start = obj->GetActionFrame(m_layer);
|
||||
obj->StopAction(m_layer);
|
||||
obj->PlayAction(m_action->id.name+2, start, end, m_layer, m_priority, 0, BL_Action::ACT_MODE_PLAY, m_layer_weight, m_ipo_flags);
|
||||
obj->SetPlayMode(m_layer, BL_Action::ACT_MODE_PLAY);
|
||||
|
||||
m_flag |= ACT_FLAG_PLAY_END;
|
||||
|
||||
@ -240,7 +241,6 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
|
||||
// Convert into a play action and play back to the beginning
|
||||
end = start;
|
||||
start = obj->GetActionFrame(m_layer);
|
||||
obj->StopAction(m_layer);
|
||||
obj->PlayAction(m_action->id.name+2, start, end, m_layer, m_priority, 0, BL_Action::ACT_MODE_PLAY, m_layer_weight, m_ipo_flags);
|
||||
|
||||
m_flag |= ACT_FLAG_PLAY_END;
|
||||
|
@ -67,7 +67,8 @@ BL_Action::BL_Action(class KX_GameObject* gameobj)
|
||||
m_priority(0),
|
||||
m_playmode(0),
|
||||
m_ipo_flags(0),
|
||||
m_done(true)
|
||||
m_done(true),
|
||||
m_calc_localtime(true)
|
||||
{
|
||||
if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
|
||||
{
|
||||
@ -215,24 +216,25 @@ float BL_Action::GetFrame()
|
||||
|
||||
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.
|
||||
m_localtime = frame;
|
||||
m_calc_localtime = false;
|
||||
}
|
||||
|
||||
dt = frame-m_startframe;
|
||||
void BL_Action::SetPlayMode(short play_mode)
|
||||
{
|
||||
m_playmode = play_mode;
|
||||
}
|
||||
|
||||
if (m_endframe < m_startframe)
|
||||
dt = -dt;
|
||||
|
||||
m_starttime -= dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed);
|
||||
void BL_Action::SetTimes(float start, float end)
|
||||
{
|
||||
m_startframe = start;
|
||||
m_endframe = end;
|
||||
}
|
||||
|
||||
void BL_Action::SetLocalTime(float curtime)
|
||||
@ -245,6 +247,16 @@ void BL_Action::SetLocalTime(float curtime)
|
||||
m_localtime = m_startframe + dt;
|
||||
}
|
||||
|
||||
void BL_Action::ResetStartTime(float curtime)
|
||||
{
|
||||
float dt = m_localtime - m_startframe;
|
||||
|
||||
m_starttime = curtime - dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed);
|
||||
printf("Before: %f, ", m_localtime);
|
||||
SetLocalTime(curtime);
|
||||
printf("After: %f\n", m_localtime);
|
||||
}
|
||||
|
||||
void BL_Action::IncrementBlending(float curtime)
|
||||
{
|
||||
// Setup m_blendstart if we need to
|
||||
@ -285,7 +297,14 @@ void BL_Action::Update(float curtime)
|
||||
return;
|
||||
|
||||
curtime -= KX_KetsjiEngine::GetSuspendedDelta();
|
||||
SetLocalTime(curtime);
|
||||
|
||||
if (m_calc_localtime)
|
||||
SetLocalTime(curtime);
|
||||
else
|
||||
{
|
||||
ResetStartTime(curtime);
|
||||
m_calc_localtime = true;
|
||||
}
|
||||
|
||||
// Handle wrap around
|
||||
if (m_localtime < min(m_startframe, m_endframe) || m_localtime > max(m_startframe, m_endframe))
|
||||
|
@ -71,9 +71,11 @@ private:
|
||||
short m_ipo_flags;
|
||||
|
||||
bool m_done;
|
||||
bool m_calc_localtime;
|
||||
|
||||
void InitIPO();
|
||||
void SetLocalTime(float curtime);
|
||||
void ResetStartTime(float curtime);
|
||||
void IncrementBlending(float curtime);
|
||||
void BlendShape(struct Key* key, float srcweight, std::vector<float>& blendshape);
|
||||
public:
|
||||
@ -111,6 +113,8 @@ public:
|
||||
|
||||
// Mutators
|
||||
void SetFrame(float frame);
|
||||
void SetPlayMode(short play_mode);
|
||||
void SetTimes(float start, float end);
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -63,6 +63,18 @@ struct bAction *BL_ActionManager::GetCurrentAction(short layer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BL_ActionManager::SetPlayMode(short layer, short mode)
|
||||
{
|
||||
if (m_layers[layer])
|
||||
m_layers[layer]->SetPlayMode(mode);
|
||||
}
|
||||
|
||||
void BL_ActionManager::SetTimes(short layer, float start, float end)
|
||||
{
|
||||
if (m_layers[layer])
|
||||
m_layers[layer]->SetTimes(start, end);
|
||||
}
|
||||
|
||||
bool BL_ActionManager::PlayAction(const char* name,
|
||||
float start,
|
||||
float end,
|
||||
|
@ -70,6 +70,16 @@ public:
|
||||
*/
|
||||
struct bAction *GetCurrentAction(short layer);
|
||||
|
||||
/**
|
||||
* Sets play mode of the action on the given layer
|
||||
*/
|
||||
void SetPlayMode(short layer, short mode);
|
||||
|
||||
/**
|
||||
* Sets the start and end times of the action on the given layer
|
||||
*/
|
||||
void SetTimes(short layer, float start, float end);
|
||||
|
||||
/**
|
||||
* Stop playing the action on the given layer
|
||||
*/
|
||||
|
@ -404,6 +404,16 @@ bAction *KX_GameObject::GetCurrentAction(short layer)
|
||||
return GetActionManager()->GetCurrentAction(layer);
|
||||
}
|
||||
|
||||
void KX_GameObject::SetPlayMode(short layer, short mode)
|
||||
{
|
||||
GetActionManager()->SetPlayMode(layer, mode);
|
||||
}
|
||||
|
||||
void KX_GameObject::SetTimes(short layer, float start, float end)
|
||||
{
|
||||
GetActionManager()->SetTimes(layer, start, end);
|
||||
}
|
||||
|
||||
void KX_GameObject::ProcessReplica()
|
||||
{
|
||||
SCA_IObject::ProcessReplica();
|
||||
|
@ -238,6 +238,16 @@ public:
|
||||
*/
|
||||
bAction *GetCurrentAction(short layer);
|
||||
|
||||
/**
|
||||
* Sets play mode of the action on the given layer
|
||||
*/
|
||||
void SetPlayMode(short layer, short mode);
|
||||
|
||||
/**
|
||||
* Sets the start and end times of the action on the given layer
|
||||
*/
|
||||
void SetTimes(short layer, float start, float end);
|
||||
|
||||
/**
|
||||
* Stop playing the action on the given layer
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user