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:
Diffstat (limited to 'source/gameengine/Ketsji/BL_Action.cpp')
-rw-r--r--source/gameengine/Ketsji/BL_Action.cpp58
1 files changed, 34 insertions, 24 deletions
diff --git a/source/gameengine/Ketsji/BL_Action.cpp b/source/gameengine/Ketsji/BL_Action.cpp
index 12a1caee221..5889f5ed412 100644
--- a/source/gameengine/Ketsji/BL_Action.cpp
+++ b/source/gameengine/Ketsji/BL_Action.cpp
@@ -56,6 +56,15 @@ extern "C" {
#include "BKE_library.h"
#include "BKE_global.h"
+#include "BLI_threads.h" // for lock
+
+/* Lock to solve animation thread issues.
+ * A spin lock is better than a mutex in case of short wait
+ * because spin lock stop the thread by a loop contrary to mutex
+ * which switch all memory, process.
+ */
+static SpinLock BL_ActionLock;
+
BL_Action::BL_Action(class KX_GameObject* gameobj)
:
m_action(NULL),
@@ -65,8 +74,7 @@ BL_Action::BL_Action(class KX_GameObject* gameobj)
m_obj(gameobj),
m_startframe(0.f),
m_endframe(0.f),
- m_endtime(0.f),
- m_localtime(0.f),
+ m_localframe(0.f),
m_blendin(0.f),
m_blendframe(0.f),
m_blendstart(0.f),
@@ -252,12 +260,11 @@ bool BL_Action::Play(const char* name,
// Now that we have an action, we have something we can play
m_starttime = -1.f; // We get the start time on our first update
- m_startframe = m_localtime = start;
+ m_startframe = m_localframe = start;
m_endframe = end;
m_blendin = blendin;
m_playmode = play_mode;
m_blendmode = blend_mode;
- m_endtime = 0.f;
m_blendframe = 0.f;
m_blendstart = 0.f;
m_speed = playback_speed;
@@ -268,11 +275,6 @@ bool BL_Action::Play(const char* name,
return true;
}
-void BL_Action::Stop()
-{
- m_done = true;
-}
-
bool BL_Action::IsDone()
{
return m_done;
@@ -298,7 +300,7 @@ bAction *BL_Action::GetAction()
float BL_Action::GetFrame()
{
- return m_localtime;
+ return m_localframe;
}
const char *BL_Action::GetName()
@@ -321,7 +323,7 @@ void BL_Action::SetFrame(float frame)
else if (frame > max(m_startframe, m_endframe))
frame = max(m_startframe, m_endframe);
- m_localtime = frame;
+ m_localframe = frame;
m_calc_localtime = false;
}
@@ -343,12 +345,12 @@ void BL_Action::SetLocalTime(float curtime)
if (m_endframe < m_startframe)
dt = -dt;
- m_localtime = m_startframe + dt;
+ m_localframe = m_startframe + dt;
}
void BL_Action::ResetStartTime(float curtime)
{
- float dt = (m_localtime > m_startframe) ? m_localtime - m_startframe : m_startframe - m_localtime;
+ float dt = (m_localframe > m_startframe) ? m_localframe - m_startframe : m_startframe - m_localframe;
m_starttime = curtime - dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed);
SetLocalTime(curtime);
@@ -396,7 +398,7 @@ void BL_Action::Update(float curtime)
curtime -= KX_KetsjiEngine::GetSuspendedDelta();
- // Grab the start time here so we don't end up with a negative m_localtime when
+ // Grab the start time here so we don't end up with a negative m_localframe when
// suspending and resuming scenes.
if (m_starttime < 0)
m_starttime = curtime;
@@ -410,16 +412,16 @@ void BL_Action::Update(float curtime)
}
// Handle wrap around
- if (m_localtime < min(m_startframe, m_endframe) || m_localtime > max(m_startframe, m_endframe)) {
+ if (m_localframe < min(m_startframe, m_endframe) || m_localframe > max(m_startframe, m_endframe)) {
switch (m_playmode) {
case ACT_MODE_PLAY:
// Clamp
- m_localtime = m_endframe;
+ m_localframe = m_endframe;
m_done = true;
break;
case ACT_MODE_LOOP:
// Put the time back to the beginning
- m_localtime = m_startframe;
+ m_localframe = m_startframe;
m_starttime = curtime;
break;
case ACT_MODE_PING_PONG:
@@ -442,7 +444,7 @@ void BL_Action::Update(float curtime)
obj->GetPose(&m_blendpose);
// Extract the pose from the action
- obj->SetPoseByAction(m_tmpaction, m_localtime);
+ obj->SetPoseByAction(m_tmpaction, m_localframe);
// Handle blending between armature actions
if (m_blendin && m_blendframe<m_blendin)
@@ -476,7 +478,7 @@ void BL_Action::Update(float curtime)
PointerRNA ptrrna;
RNA_id_pointer_create(&key->id, &ptrrna);
- animsys_evaluate_action(&ptrrna, m_tmpaction, NULL, m_localtime);
+ animsys_evaluate_action(&ptrrna, m_tmpaction, NULL, m_localframe);
// Handle blending between shape actions
if (m_blendin && m_blendframe < m_blendin)
@@ -506,15 +508,23 @@ void BL_Action::Update(float curtime)
}
}
- // This isn't thread-safe, so we move it into it's own function for now
- //m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
+ BLI_spin_lock(&BL_ActionLock);
+ /* This function is not thread safe because of recursive scene graph transform
+ * updates on children. e.g: If an object and one of its children is animated,
+ * the both can write transform at the same time. A thread lock avoid problems. */
+ m_obj->UpdateIPO(m_localframe, m_ipo_flags & ACT_IPOFLAG_CHILD);
+ BLI_spin_unlock(&BL_ActionLock);
if (m_done)
ClearControllerList();
}
-void BL_Action::UpdateIPOs()
+void BL_Action::InitLock()
+{
+ BLI_spin_init(&BL_ActionLock);
+}
+
+void BL_Action::EndLock()
{
- if (!m_done)
- m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
+ BLI_spin_end(&BL_ActionLock);
}