Added an UpdateTransform callback from SceneGraph -> Physics.
authorKester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>
Wed, 26 May 2004 12:06:41 +0000 (12:06 +0000)
committerKester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>
Wed, 26 May 2004 12:06:41 +0000 (12:06 +0000)
Profiling revealed that the SceneGraph updated every physics object, whether it moved or not, even though the physics object was at the right place.  This would cause SOLID to go and update its bounding boxes, overlap tests etc.
This callback handles the special case (parented objects) where the physics scene needs to be informed of changes to the scenegraph.

Added Python attributes (mass, parent, visible, position, orientation, scaling) to the KX_GameObject module.
Make KX_GameObject use the KX_PyMath Python <-> Moto conversion.

13 files changed:
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
source/gameengine/Ketsji/KX_SG_NodeRelationships.h
source/gameengine/Ketsji/KX_SumoPhysicsController.cpp
source/gameengine/Physics/Sumo/SumoPhysicsController.cpp
source/gameengine/SceneGraph/SG_IObject.cpp
source/gameengine/SceneGraph/SG_IObject.h
source/gameengine/SceneGraph/SG_Node.cpp
source/gameengine/SceneGraph/SG_Node.h
source/gameengine/SceneGraph/SG_ParentRelation.h
source/gameengine/SceneGraph/SG_Spatial.cpp
source/gameengine/SceneGraph/SG_Spatial.h

index c20f874fcc959c4fdb9db4d56cdfeed08a3c4396..6a35dfc048492877bddc2297f8558fbff220890a 100644 (file)
@@ -55,6 +55,8 @@
 #include "KX_ClientObjectInfo.h"
 #include "RAS_BucketManager.h"
 
+#include "KX_PyMath.h"
+
 // This file defines relationships between parents and children
 // in the game engine.
 
@@ -77,11 +79,11 @@ KX_GameObject::KX_GameObject(
        m_pSGNode = new SG_Node(this,sgReplicationInfo,callbacks);
        
        // define the relationship between this node and it's parent.
-
+       
        KX_NormalParentRelation * parent_relation = 
                KX_NormalParentRelation::New();
        m_pSGNode->SetParentRelation(parent_relation);
-
+       
 
 };
 
@@ -303,11 +305,13 @@ void KX_GameObject::UpdateNonDynas()
 void KX_GameObject::UpdateTransform()
 {
        if (m_pPhysicsController1)
-       {
                m_pPhysicsController1->SetSumoTransform(false);
-       }
 }
 
+void KX_GameObject::UpdateTransformFunc(SG_IObject* node, void* gameobj, void* scene)
+{
+       ((KX_GameObject*)gameobj)->UpdateTransform();
+}
 
 
 void KX_GameObject::SetDebugColor(unsigned int bgra)
@@ -408,7 +412,7 @@ KX_GameObject::MarkVisible(
         * determined on this level. Maybe change this to mesh level
         * later on? */
        
-       double* fl = GetOpenGLMatrix();
+       double* fl = GetOpenGLMatrixPtr()->getPointer();
        for (size_t i=0;i<m_meshes.size();i++)
        {
                m_meshes[i]->MarkVisible(fl,this,visible,m_bUseObjectColor,m_objectColor);
@@ -422,7 +426,7 @@ KX_GameObject::MarkVisible(
        void
        )
 {
-       double* fl = GetOpenGLMatrix();
+       double* fl = GetOpenGLMatrixPtr()->getPointer();
        for (size_t i=0;i<m_meshes.size();i++)
        {
                m_meshes[i]->MarkVisible(fl,
@@ -603,10 +607,10 @@ PyMethodDef KX_GameObject::Methods[] = {
        {"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS},  
        {"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_VARARGS},
        {"getPosition", (PyCFunction) KX_GameObject::sPyGetPosition, METH_VARARGS},
-       {"getLinearVelocity", (PyCFunction) KX_GameObject::sPyGetLinearVelocity, METH_VARARGS},
-       {"getVelocity", (PyCFunction) KX_GameObject::sPyGetVelocity, METH_VARARGS},
        {"getOrientation", (PyCFunction) KX_GameObject::sPyGetOrientation, METH_VARARGS},
        {"setOrientation", (PyCFunction) KX_GameObject::sPySetOrientation, METH_VARARGS},
+       {"getLinearVelocity", (PyCFunction) KX_GameObject::sPyGetLinearVelocity, METH_VARARGS},
+       {"getVelocity", (PyCFunction) KX_GameObject::sPyGetVelocity, METH_VARARGS},
        {"getMass", (PyCFunction) KX_GameObject::sPyGetMass, METH_VARARGS},
        {"getReactionForce", (PyCFunction) KX_GameObject::sPyGetReactionForce, METH_VARARGS},
        {"applyImpulse", (PyCFunction) KX_GameObject::sPyApplyImpulse, METH_VARARGS},
@@ -654,17 +658,7 @@ PyObject* KX_GameObject::PyGetPosition(PyObject* self,
                                                                           PyObject* args, 
                                                                           PyObject* kwds)
 {
-       MT_Point3 pos = NodeGetWorldPosition();
-       
-       PyObject* resultlist = PyList_New(3);
-       int index;
-       for (index=0;index<3;index++)
-       {
-               PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index]));
-       }
-       
-       return resultlist;
-       
+       return PyObjectFromMT_Point3(NodeGetWorldPosition());
 }
 
 
@@ -702,9 +696,101 @@ PyParentObject KX_GameObject::Parents[] = {
 
 PyObject* KX_GameObject::_getattr(const STR_String& attr)
 {
+       if (m_pPhysicsController1)
+       {
+               if (attr == "mass")
+                       return PyFloat_FromDouble(GetPhysicsController()->GetMass());
+       }
+
+       if (attr == "parent")
+       {       
+               KX_GameObject* parent = GetParent();
+               if (parent)
+                       return parent;
+               Py_Return;
+       }
+       
+       if (attr == "visible")
+               return PyInt_FromLong(m_bVisible);
+       
+       if (attr == "position")
+               return PyObjectFromMT_Point3(NodeGetWorldPosition());
+       
+       if (attr == "orientation")
+               return PyObjectFromMT_Matrix3x3(NodeGetWorldOrientation());
+       
+       if (attr == "scaling")
+               return PyObjectFromMT_Vector3(NodeGetWorldScaling());
+       
        _getattr_up(SCA_IObject);
 }
 
+int KX_GameObject::_setattr(const STR_String& attr, PyObject *value)   // _setattr method
+{
+       if (attr == "mass")
+               return 1;
+       
+       if (attr == "parent")
+               return 1;
+               
+       if (PyInt_Check(value))
+       {
+               int val = PyInt_AsLong(value);
+               if (attr == "visible")
+               {
+                       SetVisible(val != 0);
+                       return 0;
+               }
+       }
+       
+       if (PySequence_Check(value))
+       {
+               if (attr == "orientation")
+               {
+                       MT_Matrix3x3 rot;
+                       if (PyObject_IsMT_Matrix(value, 3))
+                       {
+                               rot = MT_Matrix3x3FromPyObject(value);
+                               NodeSetLocalOrientation(rot);
+                               return 0;
+                       }
+                       
+                       if (PySequence_Size(value) == 4)
+                       {
+                               MT_Quaternion qrot = MT_QuaternionFromPyList(value);
+                               rot.setRotation(qrot);
+                               NodeSetLocalOrientation(rot);
+                               return 0;
+                       }
+                       
+                       if (PySequence_Size(value) == 3)
+                       {
+                               MT_Vector3 erot = MT_Vector3FromPyList(value);
+                               rot.setEuler(erot);
+                               NodeSetLocalOrientation(rot);
+                               return 0;
+                       }
+                       
+                       return 1;
+               }
+               
+               if (attr == "position")
+               {
+                       MT_Point3 pos(MT_Point3FromPyList(value));
+                       NodeSetLocalPosition(pos);
+                       return 0;
+               }
+               
+               if (attr == "scaling")
+               {
+                       MT_Vector3 scale(MT_Vector3FromPyList(value));
+                       NodeSetLocalScale(scale);
+                       return 0;
+               }
+       }
+       
+       return SCA_IObject::_setattr(attr, value);
+}
 
 
 PyObject* KX_GameObject::PyGetLinearVelocity(PyObject* self, 
@@ -712,16 +798,7 @@ PyObject* KX_GameObject::PyGetLinearVelocity(PyObject* self,
                                                                                         PyObject* kwds)
 {
        // only can get the velocity if we have a physics object connected to us...
-       MT_Vector3 velocity = GetLinearVelocity();
-       
-       PyObject* resultlist = PyList_New(3);
-       int index;
-       for (index=0;index<3;index++)
-       {
-               PyList_SetItem(resultlist,index,PyFloat_FromDouble(velocity[index]));
-       }
-
-       return resultlist;
+       return PyObjectFromMT_Vector3( GetLinearVelocity());
 }
 
 
@@ -756,66 +833,19 @@ PyObject* KX_GameObject::PyGetVelocity(PyObject* self,
        MT_Point3 point(0.0,0.0,0.0);
        
        
-       MT_Point3 pos;
-       PyObject* pylist;
-       bool    error = false;
-       
-       int len = PyTuple_Size(args);
-       
-       if ((len > 0) && PyArg_ParseTuple(args,"O",&pylist))
+       PyObject* pypos = NULL;
+       if (PyArg_ParseTuple(args, "|O", &pypos))
        {
-               if (pylist->ob_type == &CListValue::Type)
-               {
-                       CListValue* listval = (CListValue*) pylist;
-                       if (listval->GetCount() == 3)
-                       {
-                               int index;
-                               for (index=0;index<3;index++)
-                               {
-                                       pos[index] = listval->GetValue(index)->GetNumber();
-                               }
-                       }       else
-                       {
-                               error = true;
-                       }
-                       
-               } else
-               {
-                       
-                       // assert the list is long enough...
-                       int numitems = PyList_Size(pylist);
-                       if (numitems == 3)
-                       {
-                               int index;
-                               for (index=0;index<3;index++)
-                               {
-                                       pos[index] = PyFloat_AsDouble(PyList_GetItem(pylist,index));
-                               }
-                       }
-                       else
-                       {
-                               error = true;
-                       }
-               }
-               
-               if (!error)
-                       point = pos;    
+               if (pypos)
+                       point = MT_Point3FromPyList(pypos);
        }
        
-       
        if (m_pPhysicsController1)
        {
                velocity = m_pPhysicsController1->GetVelocity(point);
        }
        
-       PyObject* resultlist = PyList_New(3);
-       int index;
-       for (index=0;index<3;index++)
-       {
-               PyList_SetItem(resultlist,index,PyFloat_FromDouble(velocity[index]));
-       }
-
-       return resultlist;
+       return PyObjectFromMT_Vector3(velocity);
 }
 
 
@@ -842,18 +872,7 @@ PyObject* KX_GameObject::PyGetReactionForce(PyObject* self,
                                                                                        PyObject* kwds)
 {
        // only can get the velocity if we have a physics object connected to us...
-       
-       MT_Vector3 reaction_force = GetPhysicsController()->getReactionForce();
-       
-       PyObject* resultlist = PyList_New(3);
-       int index;
-       for (index=0;index<3;index++)
-       {
-               PyList_SetItem(resultlist,index,
-                       PyFloat_FromDouble(reaction_force[index]));
-       }
-
-       return resultlist;
+       return PyObjectFromMT_Vector3(GetPhysicsController()->getReactionForce());
 }
 
 
@@ -897,12 +916,16 @@ PyObject* KX_GameObject::PyGetMesh(PyObject* self,
                                                                   PyObject* args, 
                                                                   PyObject* kwds)
 {
-       if (m_meshes.size() > 0)
+       int mesh = 0;
+       
+       if (PyArg_ParseTuple(args, "|i", &mesh))
        {
-               KX_MeshProxy* meshproxy = new KX_MeshProxy(m_meshes[0]);
-               return meshproxy;
+               if (mesh < m_meshes.size() && mesh >= 0)
+               {
+                       KX_MeshProxy* meshproxy = new KX_MeshProxy(m_meshes[mesh]);
+                       return meshproxy;
+               }
        }
-       
        Py_Return;
 }
 
@@ -913,16 +936,20 @@ PyObject* KX_GameObject::PyApplyImpulse(PyObject* self,
                                                                                PyObject* kwds)
 {
        
-       MT_Point3  attach(0, 1, 0);
-       MT_Vector3 impulse(1, 0, 0);
        
-       if (ConvertPythonVectorArgs(args,attach,impulse))
+       PyObject* pyattach;
+       PyObject* pyimpulse;
+       
+       if (PyArg_ParseTuple(args, "OO", &pyattach, &pyimpulse))
        {
+               MT_Point3  attach(MT_Point3FromPyList(pyattach));
+               MT_Vector3 impulse(MT_Vector3FromPyList(pyimpulse));
+       
                if (m_pPhysicsController1)
                {
                        m_pPhysicsController1->applyImpulse(attach, impulse);
                }
-               
+
        }
        
        Py_Return;
@@ -975,27 +1002,8 @@ PyObject* KX_GameObject::PyGetOrientation(PyObject* self,
                                                                                  PyObject* args,
                                                                                  PyObject* kwds) //keywords
 {
-       // do the conversion of a C++ matrix to a python list
-       
-       PyObject* resultlist = PyList_New(3);
-       
-       
-       int row,col;
        const MT_Matrix3x3& orient = NodeGetWorldOrientation();
-       
-       for (row=0;row<3;row++)
-       {
-               PyObject* veclist = PyList_New(3);
-               
-               for (col=0;col<3;col++)
-               {
-                       const MT_Scalar fl = orient[row][col];
-                       PyList_SetItem(veclist,col,PyFloat_FromDouble(fl));
-               }
-               PyList_SetItem(resultlist,row,veclist);
-               
-       }
-       return resultlist;
+       return PyObjectFromMT_Matrix3x3(orient);
 }
 
 
@@ -1004,68 +1012,33 @@ PyObject* KX_GameObject::PySetOrientation(PyObject* self,
                                                                                  PyObject* args, 
                                                                                  PyObject* kwds)
 {
-       MT_Matrix3x3 matrix;
-       
        PyObject* pylist;
        bool    error = false;
        int row,col;
        
        PyArg_ParseTuple(args,"O",&pylist);
        
-       if (pylist->ob_type == &CListValue::Type)
-       {
-               CListValue* listval = (CListValue*) pylist;
-               if (listval->GetCount() == 3)
-               {
-                       for (row=0;row<3;row++) // each row has a 3-vector [x,y,z]
-                       {
-                               CListValue* vecval = (CListValue*)listval->GetValue(row);
-                               for (col=0;col<3;col++)
-                               {
-                                       matrix[row][col] = vecval->GetValue(col)->GetNumber();
-                                       
-                               }
-                       }
-               }
-               else
-               {
-                       error = true;
-               }
-       }
-       else
+       MT_Matrix3x3 matrix;
+       if (PyObject_IsMT_Matrix(pylist, 3))
        {
-               // assert the list is long enough...
-               int numitems = PyList_Size(pylist);
-               if (numitems == 3)
-               {
-                       for (row=0;row<3;row++) // each row has a 3-vector [x,y,z]
-                       {
-                               
-                               PyObject* veclist = PyList_GetItem(pylist,row); // here we have a vector3 list
-                               for (col=0;col<3;col++)
-                               {
-                                       matrix[row][col] =  PyFloat_AsDouble(PyList_GetItem(veclist,col));
-                                       
-                               }
-                       }
-               }
-               else
+               matrix = MT_Matrix3x3FromPyObject(pylist);
+                       
+               if (!PyErr_Occurred())
                {
-                       error = true;
+                       NodeSetLocalOrientation(matrix);
                }
+               
+               Py_Return;
        }
        
-       if (!error)
+       MT_Quaternion quat = MT_QuaternionFromPyList(pylist);
+       if (!PyErr_Occurred())
        {
-               if (m_pPhysicsController1)
-               {
-                       m_pPhysicsController1->setOrientation(matrix.getRotation());
-               }
+               matrix.setRotation(quat);
                NodeSetLocalOrientation(matrix);
        }
        
-       Py_INCREF(Py_None);
-       return Py_None;
+       Py_Return;
 }
 
 
@@ -1075,16 +1048,13 @@ PyObject* KX_GameObject::PySetPosition(PyObject* self,
                                                                           PyObject* kwds)
 {
        // make a general function for this, it's needed many times
-       
-       MT_Point3 pos = ConvertPythonVectorArg(args);
-       if (this->m_pPhysicsController1)
+       PyObject *pypos;
+       if (PyArg_ParseTuple(args, "O", &pypos))
        {
-               this->m_pPhysicsController1->setPosition(pos);
+               MT_Point3 pos = MT_Point3FromPyList(pypos);
+               NodeSetLocalPosition(pos);
        }
-       NodeSetLocalPosition(pos);
-       
-       Py_INCREF(Py_None);
-       return Py_None;
+       Py_Return;
 }
 
 PyObject* KX_GameObject::PyGetPhysicsId(PyObject* self,
index 41528bd9dd86cfebdfd3bcd74b5e1004130234aa..2918fb1a3b683258c723a4810e2a7ee42509892b 100644 (file)
@@ -415,10 +415,12 @@ public:
         * Update the physics object transform based upon the current SG_Node
         * position.
         */
-               void                                            
+               void
        UpdateTransform(
        );
 
+       static void UpdateTransformFunc(SG_IObject* node, void* gameobj, void* scene);
+
        /**
         * Only update the transform if it's a non-dynamic object
         */
@@ -572,6 +574,13 @@ public:
        _getattr(
                const STR_String& attr
        );
+       virtual 
+               int 
+       _setattr(
+               const STR_String& attr, 
+               PyObject *value
+       );              // _setattr method
 
                PyObject*                                       
        PySetPosition(
index 437f696d872022b2d0b5dbc80d22d38c0c5d678b..1b4783d0b8bd1a8da4acf60d0033cc7122ead8b6 100644 (file)
@@ -50,7 +50,7 @@ New(
        return new KX_NormalParentRelation();
 }              
 
-       void
+       bool
 KX_NormalParentRelation::
 UpdateChildCoordinates(
        SG_Spatial * child,
@@ -82,6 +82,7 @@ UpdateChildCoordinates(
 
                child_w_pos = p_world_pos + p_world_scale * 
                        (p_world_rotation * child_pos);
+               
        } else {
 
                child_w_scale = child_scale;
@@ -92,6 +93,8 @@ UpdateChildCoordinates(
        child->SetWorldScale(child_w_scale);
        child->SetWorldPosition(child_w_pos);
        child->SetWorldOrientation(child_w_rotation);
+       
+       return parent != NULL;
 }
 
        SG_ParentRelation *
@@ -130,7 +133,7 @@ New(
  * Method inherited from KX_ParentRelation
  */
 
-       void
+       bool
 KX_VertexParentRelation::
 UpdateChildCoordinates(
        SG_Spatial * child,
@@ -161,7 +164,6 @@ UpdateChildCoordinates(
                child_w_scale = child_scale;
                child_w_rotation = child_rotation;
                child_w_pos = p_world_pos + child_pos;
-
        } else {
 
                child_w_scale = child_scale;
@@ -172,6 +174,8 @@ UpdateChildCoordinates(
        child->SetWorldScale(child_w_scale);
        child->SetWorldPosition(child_w_pos);
        child->SetWorldOrientation(child_w_rotation);
+       
+       return parent != NULL;
 }
 
 /** 
@@ -215,7 +219,7 @@ New(
  * Method inherited from KX_ParentRelation
  */
 
-       void
+       bool
 KX_SlowParentRelation::
 UpdateChildCoordinates(
        SG_Spatial * child,
@@ -280,6 +284,8 @@ UpdateChildCoordinates(
                                child_w_rotation[1][i] = (m_relax * child_w_rotation[1][i] + child_n_rotation[1][i]) * weight;
                                child_w_rotation[2][i] = (m_relax * child_w_rotation[2][i] + child_n_rotation[2][i]) * weight;
                        }
+                       
+                       //FIXME: update physics controller.
                } else {
                        child_w_scale = child_n_scale;
                        child_w_pos = child_n_pos;
@@ -297,6 +303,8 @@ UpdateChildCoordinates(
        child->SetWorldScale(child_w_scale);
        child->SetWorldPosition(child_w_pos);
        child->SetWorldOrientation(child_w_rotation);
+       
+       return parent != NULL;
 }
 
 /** 
index e5bd96dd2e3ad48d5f41c3c8ee18a09d60b4f174..8eda5d7b7345903479d9a387851e3c3fe8e16833 100644 (file)
@@ -69,7 +69,7 @@ public :
         * Method inherited from KX_ParentRelation
         */
 
-               void
+               bool
        UpdateChildCoordinates(
                SG_Spatial * child,
                const SG_Spatial * parent
@@ -113,7 +113,7 @@ public :
         * Method inherited from KX_ParentRelation
         */
 
-               void
+               bool
        UpdateChildCoordinates(
                SG_Spatial * child,
                const SG_Spatial * parent
@@ -158,7 +158,7 @@ public :
         * Method inherited from KX_ParentRelation
         */
 
-               void
+               bool
        UpdateChildCoordinates(
                SG_Spatial * child,
                const SG_Spatial * parent
index 33ede321f02806e874eb1247d2d79442eef0233b..a5284b4016581987d4ab0032565d81cf64f76e37 100644 (file)
@@ -84,8 +84,7 @@ void  KX_SumoPhysicsController::ApplyForce(const MT_Vector3& force,bool local)
 
 bool KX_SumoPhysicsController::Update(double time)
 {
-       return SynchronizeMotionStates(time);
-
+       return SynchronizeMotionStates(time); 
 }
 
 void   KX_SumoPhysicsController::SetSimulatedTime(double time)
index 3407f2120e80bec91c574e52b1d67828ce0f5054..8638c0a610af5965401d52abbcf19a80ed66dfaf 100644 (file)
@@ -85,38 +85,12 @@ float SumoPhysicsController::getMass()
 
 bool SumoPhysicsController::SynchronizeMotionStates(float time)
 {
-
        if (m_bFirstTime)
        {
-               setSumoTransform(false);
+               setSumoTransform(!m_bFirstTime);
                m_bFirstTime = false;
        }
-
-       if (!m_bDyna)
-       {
-               if (m_sumoObj)
-               {
-                       MT_Point3 pos;
-                       GetWorldPosition(pos);
-
-                       m_sumoObj->setPosition(pos);
-                       if (m_bDyna)
-                       {
-                               m_sumoObj->setScaling(MT_Vector3(1,1,1));
-                       } else
-                       {
-                               MT_Vector3 scaling;
-                               GetWorldScaling(scaling);
-                               m_sumoObj->setScaling(scaling);
-                       }
-                       MT_Matrix3x3 orn;
-                       GetWorldOrientation(orn);
-                       m_sumoObj->setOrientation(orn.getRotation());
-                       m_sumoObj->calcXform();
-               }
-       }
-       return false; // physics object are not part of
-                                // hierarchy, or ignore it ??
+       return false;
 }
  
 
index 5433b5017eb09b7c38ee2b8f790b4e1bc2355070..232ceb06958f02e3522e9a00824e3a327525cf81 100644 (file)
@@ -130,6 +130,17 @@ ActivateDestructionCallback(
        }
 }
 
+       void
+SG_IObject::
+ActivateUpdateTransformCallback(
+){
+       if (m_callbacks.m_updatefunc)
+       {
+               // Call client provided update func.
+               m_callbacks.m_updatefunc(this, m_SGclientObject, m_SGclientInfo);
+       }
+}
+
        void 
 SG_IObject::
 SetControllerTime(
index f3af9a68d8571ee97bfea4de31b393d88bc279e9..b0c1d64cf69e6f6d8220128cf92f9c7b42a8898a 100644 (file)
@@ -51,6 +51,12 @@ typedef void* (*SG_DestructionNewCallback)(
        void*   clientinfo
 );
 
+typedef void  (*SG_UpdateTransformCallback)(
+       SG_IObject* sgobject,
+       void*   clientobj,
+       void*   clientinfo
+);
+
 
 /**
  * SG_Callbacks hold 2 call backs to the outside world.
@@ -72,21 +78,25 @@ struct      SG_Callbacks
        SG_Callbacks(
        ):
                m_replicafunc(NULL),
-               m_destructionfunc(NULL) 
+               m_destructionfunc(NULL),
+               m_updatefunc(NULL)
        {
        };
                
        SG_Callbacks(
                SG_ReplicationNewCallback repfunc,
-               SG_DestructionNewCallback destructfunc
+               SG_DestructionNewCallback destructfunc,
+               SG_UpdateTransformCallback updatefunc
        ): 
                m_replicafunc(repfunc),
-               m_destructionfunc(destructfunc) 
+               m_destructionfunc(destructfunc),
+               m_updatefunc(updatefunc)
        {
        };
 
        SG_ReplicationNewCallback       m_replicafunc;
        SG_DestructionNewCallback       m_destructionfunc;
+       SG_UpdateTransformCallback      m_updatefunc;
 };
 
 /**
@@ -202,6 +212,10 @@ protected :
 
                void
        ActivateDestructionCallback(
+       );
+       
+               void
+       ActivateUpdateTransformCallback(
        );
 
        SG_IObject(
index b083d79bb70cc4f81865e91fbd4a232130063f09..c2a662c1fa223b088e28a7bfff47eb3361eaafdc 100644 (file)
@@ -186,7 +186,8 @@ void SG_Node::RemoveChild(SG_Node* child)
 
 void SG_Node::UpdateWorldData(double time)
 {
-       UpdateSpatialData(GetSGParent(),time);
+       if (UpdateSpatialData(GetSGParent(),time))
+               ActivateUpdateTransformCallback();
 
        // update children's worlddata
        for (NodeList::iterator it = m_children.begin();it!=m_children.end();++it)
index fe30213614fc39cf52b5915b0d053fed67d1ad05..ef5af717d6001f3bdc6bf48579aaab676138fa5f 100644 (file)
@@ -188,8 +188,6 @@ public:
        Destruct(
        );
        
-
-
 private:
 
                void            
index b26c4758480e39430b02a2dffb95e3daa7b31e26..d4a8e7e8cb3755d80248eb03be009b3aa429f3d4 100644 (file)
@@ -69,7 +69,7 @@ public :
         */ 
        
        virtual
-               void
+               bool
        UpdateChildCoordinates(
                SG_Spatial * child,
                const SG_Spatial * parent
index c65542c98ce71692ffbfb76bbdbe65f5c77d8b0b..a91b462b3ae9b9d386b85d233029197944db5354 100644 (file)
@@ -103,7 +103,7 @@ SetParentRelation(
  */
 
 
-       void 
+       bool 
 SG_Spatial::
 UpdateSpatialData(
        const SG_Spatial *parent,
@@ -128,17 +128,16 @@ UpdateSpatialData(
        // our world coordinates.
 
        if (!bComputesWorldTransform)
-       {
-               ComputeWorldTransforms(parent);
-       }
+               bComputesWorldTransform = ComputeWorldTransforms(parent);
+
+       return bComputesWorldTransform;
 }
 
-void   SG_Spatial::ComputeWorldTransforms(const SG_Spatial *parent)
+bool   SG_Spatial::ComputeWorldTransforms(const SG_Spatial *parent)
 {
-       m_parent_relation->UpdateChildCoordinates(this,parent);
+       return m_parent_relation->UpdateChildCoordinates(this,parent);
 }
 
-
 /**
  * Position and translation methods
  */
index e58e45bb4512d2824455cb88fbcc039599bc2bb4..1f1e97a5b5644d7bbdf85550bc7a9dd116497381 100644 (file)
@@ -177,7 +177,7 @@ public:
 
        MT_Transform GetWorldTransform() const;
 
-       void    ComputeWorldTransforms(         const SG_Spatial *parent);
+       bool    ComputeWorldTransforms(         const SG_Spatial *parent);
 
        /**
         * Bounding box functions.
@@ -217,7 +217,7 @@ protected:
         * any controllers to update this object. 
         */ 
 
-               void 
+               bool 
        UpdateSpatialData(
                const SG_Spatial *parent,
                double time