Fix T39928: Blender crash/freeze when game engine is started with animation played...
authorMitchell Stokes <mogurijin@gmail.com>
Sun, 4 May 2014 22:37:18 +0000 (15:37 -0700)
committerMitchell Stokes <mogurijin@gmail.com>
Sun, 4 May 2014 22:39:15 +0000 (15:39 -0700)
Updating object IPOs is not currently thread-safe since it also updates
children. This leads to problems when parents and children are both
animated. For now, updating object IPOs is done in its own loop to avoid
threading issues.

source/gameengine/Ketsji/BL_Action.cpp
source/gameengine/Ketsji/BL_Action.h
source/gameengine/Ketsji/BL_ActionManager.cpp
source/gameengine/Ketsji/BL_ActionManager.h
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_Scene.cpp

index e4ab2d5ce28b8216293989bd926e1aa4781d51a7..a50c07a486aaab74124d1294b010c8b9cf5bdcc1 100644 (file)
@@ -485,8 +485,15 @@ void BL_Action::Update(float curtime)
                }
        }
 
-       m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
+       // 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);
 
        if (m_done)
                ClearControllerList();
 }
+
+void BL_Action::UpdateIPOs()
+{
+       if (!m_done)
+               m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
+}
index 463d177c8764aaeccd581a0293ce37428ba2fbdd..dd1cd1f69ff8e16eb2e1301540187b1859e6a770 100644 (file)
@@ -105,6 +105,10 @@ public:
         * Update the action's frame, etc.
         */
        void Update(float curtime);
+       /**
+        * Update object IPOs (note: not thread-safe!)
+        */
+       void UpdateIPOs();
 
        // Accessors
        float GetFrame();
index 2e882ceba74552818403605687ddc2e2ef2d9c79..404f276eca8ed4c69453882d1643ead7705180e4 100644 (file)
@@ -102,3 +102,14 @@ void BL_ActionManager::Update(float curtime)
                }
        }
 }
+
+void BL_ActionManager::UpdateIPOs()
+{
+       for (int i=0; i<MAX_ACTION_LAYERS; ++i)
+       {
+               if (!m_layers[i]->IsDone())
+               {
+                       m_layers[i]->UpdateIPOs();
+               }
+       }
+}
index 8c5b8e909dad5e80efed2bc6a510c80a9fb12b28..be9097c3ca31b95a5edc77d9197fe0bbc2eba148 100644 (file)
@@ -98,6 +98,11 @@ public:
         */
        void Update(float);
 
+       /**
+        * Update object IPOs (note: not thread-safe!)
+        */
+       void UpdateIPOs();
+
 #ifdef WITH_CXX_GUARDEDALLOC
        MEM_CXX_CLASS_ALLOC_FUNCS("GE:BL_ActionManager")
 #endif
index 7042e6ed36030435c513ac5f4f1f4e1b0eed09a2..9ea76980c2071eaadc16625a023e1a5fad1503b5 100644 (file)
@@ -462,6 +462,11 @@ void KX_GameObject::UpdateActionManager(float curtime)
        GetActionManager()->Update(curtime);
 }
 
+void KX_GameObject::UpdateActionIPOs()
+{
+       GetActionManager()->UpdateIPOs();
+}
+
 float KX_GameObject::GetActionFrame(short layer)
 {
        return GetActionManager()->GetActionFrame(layer);
index ac0afca91eb6e6b29fb3aaaf2f39a6d44a3f9448..7450be4fdefaba2651e5a0bcae8eeed790819f77 100644 (file)
@@ -300,6 +300,12 @@ public:
         */
        void UpdateActionManager(float curtime);
 
+       /**
+        * Have the action manager update IPOs
+        * note: not thread-safe!
+        */
+       void UpdateActionIPOs();
+
        /*********************************
         * End Animation API
         *********************************/
index 5a33a612d2e0b236a5d23e64f0f61953f8d56a9b..4c9fba8a10b5962f048c04de788fbb4dafbebdac 100644 (file)
@@ -1658,6 +1658,10 @@ void KX_Scene::UpdateAnimations(double curtime)
 
        BLI_task_pool_work_and_wait(pool);
        BLI_task_pool_free(pool);
+
+       for (int i=0; i<m_animatedlist->GetCount(); ++i) {
+               ((KX_GameObject*)m_animatedlist->GetValue(i))->UpdateActionIPOs();
+       }
 }
 
 void KX_Scene::LogicUpdateFrame(double curtime, bool frame)