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-08-08 08:28:30 +0400
committerMitchell Stokes <mogurijin@gmail.com>2011-08-08 08:28:30 +0400
commit8883702f8a3b57d0316811e9412bd46ce0dd9c0d (patch)
tree0aff4a8eaee6ad9e9d1fbd6e60c85fa6a81149df /source/gameengine
parenta8096ef0acb780d5a6d93aef422ce3d82877a60c (diff)
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.
Diffstat (limited to 'source/gameengine')
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.cpp18
-rw-r--r--source/gameengine/Ketsji/BL_Action.cpp43
-rw-r--r--source/gameengine/Ketsji/BL_Action.h4
-rw-r--r--source/gameengine/Ketsji/BL_ActionManager.cpp12
-rw-r--r--source/gameengine/Ketsji/BL_ActionManager.h10
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp10
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h10
7 files changed, 86 insertions, 21 deletions
diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp
index 0932493ccb8..8efcdd8c551 100644
--- a/source/gameengine/Converter/BL_ActionActuator.cpp
+++ b/source/gameengine/Converter/BL_ActionActuator.cpp
@@ -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;
diff --git a/source/gameengine/Ketsji/BL_Action.cpp b/source/gameengine/Ketsji/BL_Action.cpp
index caffd3cd8ca..4cf6f982006 100644
--- a/source/gameengine/Ketsji/BL_Action.cpp
+++ b/source/gameengine/Ketsji/BL_Action.cpp
@@ -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.
-
- dt = frame-m_startframe;
+ m_localtime = frame;
+ m_calc_localtime = false;
+}
- if (m_endframe < m_startframe)
- dt = -dt;
+void BL_Action::SetPlayMode(short play_mode)
+{
+ m_playmode = play_mode;
+}
- 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))
diff --git a/source/gameengine/Ketsji/BL_Action.h b/source/gameengine/Ketsji/BL_Action.h
index 14312e158c0..75bda56419a 100644
--- a/source/gameengine/Ketsji/BL_Action.h
+++ b/source/gameengine/Ketsji/BL_Action.h
@@ -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
{
diff --git a/source/gameengine/Ketsji/BL_ActionManager.cpp b/source/gameengine/Ketsji/BL_ActionManager.cpp
index 2ee0b58574a..af0d4bff8f0 100644
--- a/source/gameengine/Ketsji/BL_ActionManager.cpp
+++ b/source/gameengine/Ketsji/BL_ActionManager.cpp
@@ -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,
diff --git a/source/gameengine/Ketsji/BL_ActionManager.h b/source/gameengine/Ketsji/BL_ActionManager.h
index 3818f643b1c..c310e231ed7 100644
--- a/source/gameengine/Ketsji/BL_ActionManager.h
+++ b/source/gameengine/Ketsji/BL_ActionManager.h
@@ -71,6 +71,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
*/
void StopAction(short layer);
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 91e62442646..4f8860f4767 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -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();
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 40bd86fed1b..6e79914172b 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -239,6 +239,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
*/
void StopAction(short layer);