-added basic support for GameActuator 'load game', relative paths were broken, just...
authorErwin Coumans <blender@erwincoumans.com>
Mon, 22 May 2006 21:03:43 +0000 (21:03 +0000)
committerErwin Coumans <blender@erwincoumans.com>
Mon, 22 May 2006 21:03:43 +0000 (21:03 +0000)
-near sensor support
- python binding for PhysicsConstraints.setNumTimeSubSteps (dividing the physics timestep to tradeoff quality for performance)

20 files changed:
extern/bullet/Bullet/CollisionDispatch/ConvexConvexAlgorithm.cpp
extern/bullet/BulletDynamics/ConstraintSolver/SimpleConstraintSolver.cpp
extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp
extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h
extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.cpp
extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.h
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/Converter/KX_ConvertSensors.cpp
source/gameengine/GameLogic/SCA_IScene.h
source/gameengine/Ketsji/KX_NearSensor.cpp
source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_Scene.h
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.h
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
source/gameengine/SceneGraph/SG_Node.cpp

index c3ca2ef6be92d4b5a5ba8b23997f1d14d9511545..9c20f28d1ec9c492dc82b4e522d609e2449db9bb 100644 (file)
@@ -307,26 +307,14 @@ void ConvexConvexAlgorithm ::ProcessCollision (BroadphaseProxy* ,BroadphaseProxy
        
        GjkPairDetector::ClosestPointInput input;
 
-       SphereShape     sphere(0.2f);
-       MinkowskiSumShape       expanded0(min0,&sphere);
-       MinkowskiSumShape       expanded1(min1,&sphere);
 
-       if (dispatchInfo.m_useContinuous)
-       {
-               m_gjkPairDetector.SetMinkowskiA(&expanded0);
-               m_gjkPairDetector.SetMinkowskiB(&expanded1);
-               input.m_maximumDistanceSquared = expanded0.GetMargin()+expanded1.GetMargin();
-               input.m_maximumDistanceSquared *= input.m_maximumDistanceSquared;
-       }
-       else
-       {
-               m_gjkPairDetector.SetMinkowskiA(min0);
-               m_gjkPairDetector.SetMinkowskiB(min1);
-               input.m_maximumDistanceSquared = min0->GetMargin() + min1->GetMargin() + m_manifoldPtr->GetContactBreakingTreshold();
-               input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
-       }
-
-       input.m_maximumDistanceSquared = 1e30f;//
+       //TODO: if (dispatchInfo.m_useContinuous)
+       m_gjkPairDetector.SetMinkowskiA(min0);
+       m_gjkPairDetector.SetMinkowskiB(min1);
+       input.m_maximumDistanceSquared = min0->GetMargin() + min1->GetMargin() + m_manifoldPtr->GetContactBreakingTreshold();
+       input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
+       
+       //input.m_maximumDistanceSquared = 1e30f;//
        
        input.m_transformA = col0->m_worldTransform;
        input.m_transformB = col1->m_worldTransform;
index 9f7d360f7eb7b34842348de92505c8f2b9280b38..fe59a40683a44a104241fdd4df326042c91e6b16 100644 (file)
@@ -112,6 +112,7 @@ SimdScalar restitutionCurve(SimdScalar rel_vel, SimdScalar restitution)
 
 
 
+
 float SimpleConstraintSolver::Solve(PersistentManifold* manifoldPtr, const ContactSolverInfo& info,int iter,IDebugDraw* debugDrawer)
 {
 
@@ -125,7 +126,7 @@ float SimpleConstraintSolver::Solve(PersistentManifold* manifoldPtr, const Conta
        {
                manifoldPtr->RefreshContactPoints(body0->getCenterOfMassTransform(),body1->getCenterOfMassTransform());
                
-               const int numpoints = manifoldPtr->GetNumContacts();
+               int numpoints = manifoldPtr->GetNumContacts();
 
                SimdVector3 color(0,1,0);
                for (int i=0;i<numpoints ;i++)
index 043d5be802e9d02193dad0bc398167a41a35bd3f..cddc780aff4f82e2811431f2c572933ab1e339bc 100644 (file)
@@ -23,6 +23,9 @@ subject to the following restrictions:
 #include "CcdPhysicsEnvironment.h"
 #include "SimdTransformUtil.h"
 
+#include "CollisionShapes/SphereShape.h"
+#include "CollisionShapes/ConeShape.h"
+
 class BP_Proxy;
 
 ///todo: fill all the empty CcdPhysicsController methods, hook them up to the RigidBody class
@@ -31,7 +34,7 @@ class BP_Proxy;
 float  gDeactivationTime = 2.f;
 bool   gDisableDeactivation = false;
 
-float gLinearSleepingTreshold = 0.8f;
+float gLinearSleepingTreshold = 0.4f;
 float gAngularSleepingTreshold = 1.0f;
 
 #include "Dynamics/MassProps.h"
@@ -486,3 +489,96 @@ bool CcdPhysicsController::wantsSleeping()
        return false;
 }
 
+PHY_IPhysicsController*        CcdPhysicsController::GetReplica()
+{
+       //very experimental, shape sharing is not implemented yet.
+       //just support SphereShape/ConeShape for now
+
+       CcdConstructionInfo cinfo = m_cci;
+       if (cinfo.m_collisionShape)
+       {
+               switch (cinfo.m_collisionShape->GetShapeType())
+               {
+               case SPHERE_SHAPE_PROXYTYPE:
+                       {
+                               SphereShape* orgShape = (SphereShape*)cinfo.m_collisionShape;
+                               cinfo.m_collisionShape = new SphereShape(*orgShape);
+                               break;
+                       }
+
+                       case CONE_SHAPE_PROXYTYPE:
+                       {
+                               ConeShape* orgShape = (ConeShape*)cinfo.m_collisionShape;
+                               cinfo.m_collisionShape = new ConeShape(*orgShape);
+                               break;
+                       }
+
+
+               default:
+                       {
+                               return 0;
+                       }
+               }
+       }
+
+       cinfo.m_MotionState = new DefaultMotionState();
+
+       CcdPhysicsController* replica = new CcdPhysicsController(cinfo);
+       return replica;
+}
+
+///////////////////////////////////////////////////////////
+///A small utility class, DefaultMotionState
+///
+///////////////////////////////////////////////////////////
+
+DefaultMotionState::DefaultMotionState()
+{
+       m_worldTransform.setIdentity();
+}
+
+
+DefaultMotionState::~DefaultMotionState()
+{
+
+}
+
+void   DefaultMotionState::getWorldPosition(float& posX,float& posY,float& posZ)
+{
+       posX = m_worldTransform.getOrigin().x();
+       posY = m_worldTransform.getOrigin().y();
+       posZ = m_worldTransform.getOrigin().z();
+}
+
+void   DefaultMotionState::getWorldScaling(float& scaleX,float& scaleY,float& scaleZ)
+{
+       scaleX = 1.;
+       scaleY = 1.;
+       scaleZ = 1.;
+}
+
+void   DefaultMotionState::getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal)
+{
+       quatIma0 = m_worldTransform.getRotation().x();
+       quatIma1 = m_worldTransform.getRotation().y();
+       quatIma2 = m_worldTransform.getRotation().z();
+       quatReal = m_worldTransform.getRotation()[3];
+}
+               
+void   DefaultMotionState::setWorldPosition(float posX,float posY,float posZ)
+{
+       SimdPoint3 pos(posX,posY,posZ);
+       m_worldTransform.setOrigin( pos );
+}
+
+void   DefaultMotionState::setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal)
+{
+       SimdQuaternion orn(quatIma0,quatIma1,quatIma2,quatReal);
+       m_worldTransform.setRotation( orn );
+}
+               
+void   DefaultMotionState::calculateWorldTransformations()
+{
+
+}
+
index 646b21f285e176ee746c94b6902c82418d276239..056feba652c47d1e738c2a3a71bf6a76ed906841 100644 (file)
@@ -27,6 +27,7 @@ subject to the following restrictions:
 #include "SimdTransform.h"
 #include "Dynamics/RigidBody.h"
 
+#include "PHY_IMotionState.h"
 
 #include "BroadphaseCollision/BroadphaseProxy.h" //for CollisionShape access
 class CollisionShape;
@@ -155,7 +156,8 @@ class CcdPhysicsController : public PHY_IPhysicsController
                // clientinfo for raycasts for example
                virtual void*                           getNewClientInfo();
                virtual void                            setNewClientInfo(void* clientinfo);
-               virtual PHY_IPhysicsController* GetReplica() {return 0;}
+               virtual PHY_IPhysicsController* GetReplica();
+               
 
                virtual void    calcXform() {} ;
                virtual void SetMargin(float margin) {};
@@ -184,4 +186,30 @@ class CcdPhysicsController : public PHY_IPhysicsController
 
 };
 
+
+
+
+///DefaultMotionState implements standard motionstate, using SimdTransform
+class  DefaultMotionState : public PHY_IMotionState
+
+{
+       public:
+               DefaultMotionState();
+
+               virtual ~DefaultMotionState();
+
+               virtual void    getWorldPosition(float& posX,float& posY,float& posZ);
+               virtual void    getWorldScaling(float& scaleX,float& scaleY,float& scaleZ);
+               virtual void    getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal);
+               
+               virtual void    setWorldPosition(float posX,float posY,float posZ);
+               virtual void    setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal);
+               
+               virtual void    calculateWorldTransformations();
+               
+               SimdTransform   m_worldTransform;
+
+};
+
+
 #endif //BULLET2_PHYSICSCONTROLLER_H
index cb4adc77d7642ea60a730d5f9e465c2dc0164754..4b4d3f15dae9095ebccaaa929e03179489120c04 100644 (file)
@@ -29,6 +29,10 @@ subject to the following restrictions:
 #include "CollisionDispatch/CollisionWorld.h"
 
 #include "CollisionShapes/ConvexShape.h"
+#include "CollisionShapes/ConeShape.h"
+
+
+
 #include "BroadphaseCollision/Dispatcher.h"
 #include "NarrowPhaseCollision/PersistentManifold.h"
 #include "CollisionShapes/TriangleMeshShape.h"
@@ -321,6 +325,7 @@ static void DrawAabb(IDebugDraw* debugDrawer,const SimdVector3& from,const SimdV
 CcdPhysicsEnvironment::CcdPhysicsEnvironment(CollisionDispatcher* dispatcher,BroadphaseInterface* broadphase)
 :m_scalingPropagated(false),
 m_numIterations(10),
+m_numTimeSubSteps(1),
 m_ccdMode(0),
 m_solverType(-1),
 m_profileTimings(0),
@@ -342,9 +347,9 @@ m_enableSatCollisionDetection(false)
                SimdVector3 worldMin(-10000,-10000,-10000);
                SimdVector3 worldMax(10000,10000,10000);
 
-               //broadphase = new AxisSweep3(worldMin,worldMax);
+               broadphase = new AxisSweep3(worldMin,worldMax);
 
-               broadphase = new SimpleBroadphase();
+               //broadphase = new SimpleBroadphase();
        }
 
 
@@ -498,6 +503,8 @@ void        CcdPhysicsEnvironment::beginFrame()
 
 bool   CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
 {
+       //printf("proceedDeltaTime\n");
+       
 
 #ifdef USE_QUICKPROF
        //toggle Profiler
@@ -528,16 +535,38 @@ bool      CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
 
        if (!SimdFuzzyZero(timeStep))
        {
+               
+               {
+                       //do the kinematic calculation here, over the full timestep
+                       std::vector<CcdPhysicsController*>::iterator i;
+                       for (i=m_controllers.begin();
+                                               !(i==m_controllers.end()); i++)
+                       {
 
-               // define this in blender, the stepsize is 30 hertz, 60 hertz works much better 
-//#define SPLIT_TIMESTEP 1
+                                               CcdPhysicsController* ctrl = *i;
 
-#ifdef SPLIT_TIMESTEP
-               proceedDeltaTimeOneStep(0.5f*timeStep);
-               proceedDeltaTimeOneStep(0.5f*timeStep);
-#else          
-               proceedDeltaTimeOneStep(timeStep);
-#endif
+                                               SimdTransform predictedTrans;
+                                               RigidBody* body = ctrl->GetRigidBody();
+                                               if (body->GetActivationState() != ISLAND_SLEEPING)
+                                               {
+
+                                                       if (body->IsStatic())
+                                                       {
+                                                               //to calculate velocities next frame
+                                                               body->saveKinematicState(timeStep);
+                                                       }
+                                               }
+                       }
+               }
+
+
+               int i;
+               float subTimeStep = timeStep / float(m_numTimeSubSteps);
+
+               for (i=0;i<this->m_numTimeSubSteps;i++)
+               {
+                       proceedDeltaTimeOneStep(subTimeStep);
+               }
        } else
        {
                //todo: interpolate
@@ -563,7 +592,7 @@ bool        CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
 {
 
 
-       //      printf("CcdPhysicsEnvironment::proceedDeltaTime\n");
+       //printf("CcdPhysicsEnvironment::proceedDeltaTime\n");
 
        if (SimdFuzzyZero(timeStep))
                return true;
@@ -811,11 +840,7 @@ bool       CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
                                        if (body->GetActivationState() != ISLAND_SLEEPING)
                                        {
 
-                                               if (body->IsStatic())
-                                               {
-                                                       //to calculate velocities next frame
-                                                       body->saveKinematicState(timeStep);
-                                               } else
+                                               if (!body->IsStatic())
                                                {
                                                        body->predictIntegratedTransform(timeStep*      toi, predictedTrans);
                                                        body->proceedToTransform( predictedTrans);
@@ -1392,10 +1417,34 @@ TypedConstraint*        CcdPhysicsEnvironment::getConstraintById(int constraintId)
 
 void CcdPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl)
 {
+
+       CcdPhysicsController* ctrl1 = (CcdPhysicsController* )ctrl;
+       std::vector<CcdPhysicsController*>::iterator i =
+               std::find(m_controllers.begin(), m_controllers.end(), ctrl);
+       if ((i == m_controllers.end()))
+       {
+               addCcdPhysicsController(ctrl1);
+       }
+
+       requestCollisionCallback(ctrl);
        //printf("addSensor\n");
 }
+
+void CcdPhysicsEnvironment::removeCollisionCallback(PHY_IPhysicsController* ctrl)
+{
+       std::vector<CcdPhysicsController*>::iterator i =
+               std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl);
+       if (!(i == m_triggerControllers.end()))
+       {
+               std::swap(*i, m_triggerControllers.back());
+               m_triggerControllers.pop_back();
+       }
+}
+
+
 void CcdPhysicsEnvironment::removeSensor(PHY_IPhysicsController* ctrl)
 {
+       removeCollisionCallback(ctrl);
        //printf("removeSensor\n");
 }
 void CcdPhysicsEnvironment::addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)
@@ -1584,3 +1633,41 @@ void     CcdPhysicsEnvironment::UpdateAabbs(float        timeStep)
                                }
                        }
 }
+
+PHY_IPhysicsController*        CcdPhysicsEnvironment::CreateSphereController(float radius,const PHY__Vector3& position)
+{
+       
+       CcdConstructionInfo     cinfo;
+       cinfo.m_collisionShape = new SphereShape(radius);
+       cinfo.m_MotionState = 0;
+       cinfo.m_physicsEnv = this;
+       cinfo.m_collisionFlags |= CollisionObject::noContactResponse;
+       DefaultMotionState* motionState = new DefaultMotionState();
+       cinfo.m_MotionState = motionState;
+       motionState->m_worldTransform.setIdentity();
+       motionState->m_worldTransform.setOrigin(SimdVector3(position[0],position[1],position[2]));
+
+       CcdPhysicsController* sphereController = new CcdPhysicsController(cinfo);
+       
+
+       return sphereController;
+}
+
+
+PHY_IPhysicsController* CcdPhysicsEnvironment::CreateConeController(float coneradius,float coneheight)
+{
+       CcdConstructionInfo     cinfo;
+       cinfo.m_collisionShape = new ConeShape(coneradius,coneheight);
+       cinfo.m_MotionState = 0;
+       cinfo.m_physicsEnv = this;
+       DefaultMotionState* motionState = new DefaultMotionState();
+       cinfo.m_MotionState = motionState;
+       motionState->m_worldTransform.setIdentity();
+//     motionState->m_worldTransform.setOrigin(SimdVector3(position[0],position[1],position[2]));
+
+       CcdPhysicsController* sphereController = new CcdPhysicsController(cinfo);
+
+
+       return sphereController;
+}
+       
index 08dff62e236e5e90a87a0e97d359f6179a9206a4..9de7053d271679d91402e976256dc0a6024394c7 100644 (file)
@@ -48,7 +48,11 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
        SimdVector3 m_gravity;
        
        IDebugDraw*     m_debugDrawer;
+       //solver iterations
        int     m_numIterations;
+       
+       //timestep subdivisions
+       int     m_numTimeSubSteps;
        int     m_ccdMode;
        int     m_solverType;
        int     m_profileTimings;
@@ -74,6 +78,10 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
                }
 
                virtual void            setNumIterations(int numIter);
+               virtual void            setNumTimeSubSteps(int numTimeSubSteps)
+               {
+                       m_numTimeSubSteps = numTimeSubSteps;
+               }
                virtual void            setDeactivationTime(float dTime);
                virtual void            setDeactivationLinearTreshold(float linTresh) ;
                virtual void            setDeactivationAngularTreshold(float angTresh) ;
@@ -131,8 +139,10 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
                virtual void removeSensor(PHY_IPhysicsController* ctrl);
                virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user);
                virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl);
-               virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) {return 0;};
-               virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight){ return 0;};
+               virtual void removeCollisionCallback(PHY_IPhysicsController* ctrl);
+
+               virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position);
+               virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight);
        
 
                virtual int     getNumContactPoints();
index 9fcbabba5460f1b32ab07ec0a88ce4823a741960..a270b73c80de74b045644b4a230969c760d10110 100644 (file)
 
 static BlendFileData *load_game_data(char *filename) {
        BlendReadError error;
-       BlendFileData *bfd= BLO_read_from_file(filename, &error);
-       
+       //this doesn't work anymore for relative paths, so use BLO_read_from_memory instead
+       //BlendFileData *bfd= BLO_read_from_file(filename, &error);
+       FILE* file = fopen(filename,"rb");
+       BlendFileData *bfd  = 0;
+       if (file)
+       {
+               fseek(file, 0L, SEEK_END);
+               int len= ftell(file);
+               fseek(file, 0L, SEEK_SET);      
+               char* filebuffer= new char[len];//MEM_mallocN(len, "text_buffer");
+               int sizeread = fread(filebuffer,len,1,file);
+               if (sizeread==1)
+               {
+                       bfd = BLO_read_from_memory(filebuffer, len, &error);
+               }
+               fclose(file);
+       }
+
        if (!bfd) {
                printf("Loading %s failed: %s\n", filename, BLO_bre_as_string(error));
        }
@@ -96,17 +112,17 @@ static BlendFileData *load_game_data(char *filename) {
 
 extern "C" void StartKetsjiShell(struct ScrArea *area,
                                                                 char* scenename,
-                                                                struct Main* maggie,
+                                                                struct Main* maggie1,
                                                                 struct SpaceIpo *sipo,
                                                                 int always_use_expand_framing)
 {
        int exitrequested = KX_EXIT_REQUEST_NO_REQUEST;
        
-       Main* blenderdata = maggie;
+       Main* blenderdata = maggie1;
 
        char* startscenename = scenename;
        char pathname[160];
-       strcpy (pathname, maggie->name);
+       strcpy (pathname, blenderdata->name);
        STR_String exitstring = "";
        BlendFileData *bfd= NULL;
 
@@ -257,8 +273,8 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
                Scene *blscene = NULL;
                if (!bfd)
                {
-                       blscene = (Scene*) maggie->scene.first;
-                       for (Scene *sce= (Scene*) maggie->scene.first; sce; sce= (Scene*) sce->id.next)
+                       blscene = (Scene*) blenderdata->scene.first;
+                       for (Scene *sce= (Scene*) blenderdata->scene.first; sce; sce= (Scene*) sce->id.next)
                        {
                                if (startscenename == (sce->id.name+2))
                                {
@@ -292,7 +308,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
                        }
                        
                        // create a scene converter, create and convert the startingscene
-                       KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(maggie,sipo, ketsjiengine);
+                       KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata,sipo, ketsjiengine);
                        ketsjiengine->SetSceneConverter(sceneconverter);
                        
                        if (always_use_expand_framing)
index eb91427f2d3657266186967c662e1b1579b65c62..40c15302553b96374116a12adf4d27ab03afebde 100644 (file)
@@ -386,6 +386,11 @@ void BL_ConvertSensors(struct Object* blenderobject,
                                        bool bFindMaterial = false;
                                        PHY_IPhysicsController* physCtrl = kxscene->GetPhysicsEnvironment()->CreateSphereController(radius,pos);
 
+                                       if (isInActiveLayer)
+                                               kxscene->GetPhysicsEnvironment()->addSensor(physCtrl);
+
+                                               
+
                                        gamesensor = new KX_NearSensor(eventmgr,gameobj,
                                                blendernearsensor->dist,
                                                blendernearsensor->resetdist,
index d77c1dd648341220aa16367907c4b2ed96683e63..3c62ec91515975d58e0d0a71ca57670cb9205106 100644 (file)
@@ -53,6 +53,8 @@ public:
                                                                                                int lifespan=0)=0;
        virtual void    RemoveObject(class CValue* gameobj)=0;
        virtual void    DelayedRemoveObject(class CValue* gameobj)=0;
+       virtual void    DelayedReleaseObject(class CValue* gameobj)=0;
+       
        virtual void    ReplaceMesh(class CValue* gameobj,
                                                                void* meshobj)=0;
        std::vector<SCA_DebugProp*>& GetDebugProperties();
index 5c6f038e23d3064b24a0b8865f8b1ce293dc0fe1..fac2302b85e84bc9a9ab99a3cf91859bdddcc072 100644 (file)
@@ -80,7 +80,10 @@ KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr,
 
 void KX_NearSensor::RegisterSumo(KX_TouchEventManager *touchman)
 {
-       touchman->GetPhysicsEnvironment()->addSensor(m_physCtrl);
+       if (m_physCtrl)
+       {
+               touchman->GetPhysicsEnvironment()->addSensor(m_physCtrl);
+       }
 }
 
 CValue* KX_NearSensor::GetReplica()
@@ -96,7 +99,18 @@ CValue* KX_NearSensor::GetReplica()
        
        replica->m_client_info = new KX_ClientObjectInfo(m_client_info->m_gameobject, KX_ClientObjectInfo::NEAR);
        
-       replica->m_physCtrl = replica->m_physCtrl->GetReplica();
+       if (replica->m_physCtrl)
+       {
+               replica->m_physCtrl = replica->m_physCtrl->GetReplica();
+               if (replica->m_physCtrl)
+               {
+                       //static_cast<KX_TouchEventManager*>(m_eventmgr)->GetPhysicsEnvironment()->addSensor(replica->m_physCtrl);
+                       replica->m_physCtrl->SetMargin(m_Margin);
+                       replica->m_physCtrl->setNewClientInfo(replica->m_client_info);
+               }
+               
+       }
+       //static_cast<KX_TouchEventManager*>(m_eventmgr)->RegisterSensor(this);
        //todo: make sure replication works fine
        //>m_sumoObj = new SM_Object(DT_NewSphere(0.0),NULL,NULL,NULL);
        //replica->m_sumoObj->setMargin(m_Margin);
@@ -111,11 +125,21 @@ CValue* KX_NearSensor::GetReplica()
 
 void KX_NearSensor::ReParent(SCA_IObject* parent)
 {
+
        SCA_ISensor::ReParent(parent);
        
        m_client_info->m_gameobject = static_cast<KX_GameObject*>(parent); 
        m_client_info->m_sensors.push_back(this);
        
+
+/*     KX_ClientObjectInfo *client_info = gameobj->getClientInfo();
+       client_info->m_gameobject = gameobj;
+       client_info->m_auxilary_info = NULL;
+       
+       client_info->m_sensors.push_back(this);
+       SCA_ISensor::ReParent(parent);
+*/
+
        SynchronizeTransform();
 }
 
@@ -127,10 +151,11 @@ KX_NearSensor::~KX_NearSensor()
        // for touchsensor, it's the parent
        if (m_physCtrl)
        {
-               static_cast<KX_TouchEventManager*>(m_eventmgr)->GetPhysicsEnvironment()->removeSensor(m_physCtrl);
+               //static_cast<KX_TouchEventManager*>(m_eventmgr)->GetPhysicsEnvironment()->removeSensor(m_physCtrl);
                delete m_physCtrl;
                m_physCtrl = NULL;
        }
+       
                
        if (m_client_info)
                delete m_client_info;
index e9c71fe02c96684e62c467a5f375778e23d58cbe..28138195a5ea962c230ffd3317b6fac518ecb77c 100644 (file)
@@ -53,6 +53,9 @@ static char gPySetGravity__doc__[] = "setGravity(float x,float y,float z)";
 static char gPySetDebugMode__doc__[] = "setDebugMode(int mode)";
 
 static char gPySetNumIterations__doc__[] = "setNumIterations(int numiter) This sets the number of iterations for an iterative constraint solver";
+static char gPySetNumTimeSubSteps__doc__[] = "setNumTimeSubSteps(int numsubstep) This sets the number of substeps for each physics proceed. Tradeoff quality for performance.";
+
+
 static char gPySetDeactivationTime__doc__[] = "setDeactivationTime(float time) This sets the time after which a resting rigidbody gets deactived";
 static char gPySetDeactivationLinearTreshold__doc__[] = "setDeactivationLinearTreshold(float linearTreshold)";
 static char gPySetDeactivationAngularTreshold__doc__[] = "setDeactivationAngularTreshold(float angularTreshold)";
@@ -106,6 +109,24 @@ static PyObject* gPySetDebugMode(PyObject* self,
        Py_INCREF(Py_None); return Py_None;
 }
 
+
+
+static PyObject* gPySetNumTimeSubSteps(PyObject* self,
+                                                                                PyObject* args, 
+                                                                                PyObject* kwds)
+{
+       int substep;
+       if (PyArg_ParseTuple(args,"i",&substep))
+       {
+               if (PHY_GetActiveEnvironment())
+               {
+                       PHY_GetActiveEnvironment()->setNumTimeSubSteps(substep);
+               }
+       }
+       Py_INCREF(Py_None); return Py_None;
+}
+
+
 static PyObject* gPySetNumIterations(PyObject* self,
                                                                                 PyObject* args, 
                                                                                 PyObject* kwds)
@@ -411,6 +432,9 @@ static struct PyMethodDef physicsconstraints_methods[] = {
   {"setNumIterations",(PyCFunction) gPySetNumIterations,
    METH_VARARGS, gPySetNumIterations__doc__},
 
+   {"setNumTimeSubSteps",(PyCFunction) gPySetNumTimeSubSteps,
+   METH_VARARGS, gPySetNumTimeSubSteps__doc__},
+
   {"setDeactivationTime",(PyCFunction) gPySetDeactivationTime,
    METH_VARARGS, gPySetDeactivationTime__doc__},
 
index 322f41e11a36afdf9a935da28d770a0b13fe13fc..45b2db10b33a73b91fc474459d38f40dbf9e1642 100644 (file)
@@ -318,7 +318,11 @@ void       KX_SCA_AddObjectActuator::InstantAddObject()
 
                // keep a copy of the last object, to allow python scripters to change it
                if (m_lastCreatedObject)
+               {
+                       //careful with destruction, it might still have outstanding collision callbacks
+                       m_scene->DelayedReleaseObject(m_lastCreatedObject);
                        m_lastCreatedObject->Release();
+               }
                
                m_lastCreatedObject = replica;
                m_lastCreatedObject->AddRef();
index 1706937f8df50124e9b1ac478668ddeb4cbf36bd..a5bbfa41e3e82e20ae249f593830ec5da6ae65d5 100644 (file)
@@ -125,6 +125,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
        m_parentlist = new CListValue();
        m_lightlist= new CListValue();
        m_euthanasyobjects = new CListValue();
+       m_delayReleaseObjects = new CListValue();
 
        m_logicmgr = new SCA_LogicManager();
        
@@ -193,6 +194,8 @@ KX_Scene::~KX_Scene()
 
        if (m_euthanasyobjects)
                m_euthanasyobjects->Release();
+       if (m_delayReleaseObjects)
+               m_delayReleaseObjects->Release();
 
        if (m_logicmgr)
                delete m_logicmgr;
@@ -654,8 +657,13 @@ void KX_Scene::RemoveObject(class CValue* gameobj)
                // recursively destruct
                node->Destruct();
        }
+       newobj->SetSGNode(0);
 }
 
+void KX_Scene::DelayedReleaseObject(CValue* gameobj)
+{
+       m_delayReleaseObjects->Add(gameobj->AddRef());
+}
 
 
 void KX_Scene::DelayedRemoveObject(class CValue* gameobj)
@@ -1087,12 +1095,22 @@ void KX_Scene::LogicEndFrame()
 {
        m_logicmgr->EndFrame();
        int numobj = m_euthanasyobjects->GetCount();
-
-       for (int i = numobj - 1; i >= 0; i--)
+       int i;
+       for (i = numobj - 1; i >= 0; i--)
        {
                KX_GameObject* gameobj = (KX_GameObject*)m_euthanasyobjects->GetValue(i);
                this->RemoveObject(gameobj);
        }
+
+       numobj= m_delayReleaseObjects->GetCount();
+       for (i = numobj-1;i>=0;i--)
+       {
+               KX_GameObject* gameobj = (KX_GameObject*)m_delayReleaseObjects->GetValue(i);
+               m_delayReleaseObjects->RemoveValue(gameobj);    
+               
+       }
+       
+
 }
 
 
index 4bcfb3ee194c58153f5d758a9bd51481d14fb61f..ba479c5e5437167b284f18ab6a9628d347f9cbaa 100644 (file)
@@ -101,6 +101,11 @@ protected:
         * LogicEndFrame() via a call to RemoveObject().
         */
        CListValue*     m_euthanasyobjects;
+       /**
+       * The list of objects that couldn't be released during logic update.
+       * for example, AddObject actuator sometimes releases an object that was cached from previous frame
+       */
+       CListValue*     m_delayReleaseObjects;
 
        CListValue*                     m_objectlist;
        CListValue*                     m_parentlist; // all 'root' parents
@@ -288,6 +293,9 @@ public:
                                                                  CValue* gameobj);
        void RemoveObject(CValue* gameobj);
        void DelayedRemoveObject(CValue* gameobj);
+       
+       void DelayedReleaseObject(CValue* gameobj);
+
        void NewRemoveObject(CValue* gameobj);
        void ReplaceMesh(CValue* gameobj,
                                         void* meshobj);
index b8ce09729c2387883e56a6d5fa33be4304de0304..cddc780aff4f82e2811431f2c572933ab1e339bc 100644 (file)
@@ -23,6 +23,9 @@ subject to the following restrictions:
 #include "CcdPhysicsEnvironment.h"
 #include "SimdTransformUtil.h"
 
+#include "CollisionShapes/SphereShape.h"
+#include "CollisionShapes/ConeShape.h"
+
 class BP_Proxy;
 
 ///todo: fill all the empty CcdPhysicsController methods, hook them up to the RigidBody class
@@ -486,3 +489,96 @@ bool CcdPhysicsController::wantsSleeping()
        return false;
 }
 
+PHY_IPhysicsController*        CcdPhysicsController::GetReplica()
+{
+       //very experimental, shape sharing is not implemented yet.
+       //just support SphereShape/ConeShape for now
+
+       CcdConstructionInfo cinfo = m_cci;
+       if (cinfo.m_collisionShape)
+       {
+               switch (cinfo.m_collisionShape->GetShapeType())
+               {
+               case SPHERE_SHAPE_PROXYTYPE:
+                       {
+                               SphereShape* orgShape = (SphereShape*)cinfo.m_collisionShape;
+                               cinfo.m_collisionShape = new SphereShape(*orgShape);
+                               break;
+                       }
+
+                       case CONE_SHAPE_PROXYTYPE:
+                       {
+                               ConeShape* orgShape = (ConeShape*)cinfo.m_collisionShape;
+                               cinfo.m_collisionShape = new ConeShape(*orgShape);
+                               break;
+                       }
+
+
+               default:
+                       {
+                               return 0;
+                       }
+               }
+       }
+
+       cinfo.m_MotionState = new DefaultMotionState();
+
+       CcdPhysicsController* replica = new CcdPhysicsController(cinfo);
+       return replica;
+}
+
+///////////////////////////////////////////////////////////
+///A small utility class, DefaultMotionState
+///
+///////////////////////////////////////////////////////////
+
+DefaultMotionState::DefaultMotionState()
+{
+       m_worldTransform.setIdentity();
+}
+
+
+DefaultMotionState::~DefaultMotionState()
+{
+
+}
+
+void   DefaultMotionState::getWorldPosition(float& posX,float& posY,float& posZ)
+{
+       posX = m_worldTransform.getOrigin().x();
+       posY = m_worldTransform.getOrigin().y();
+       posZ = m_worldTransform.getOrigin().z();
+}
+
+void   DefaultMotionState::getWorldScaling(float& scaleX,float& scaleY,float& scaleZ)
+{
+       scaleX = 1.;
+       scaleY = 1.;
+       scaleZ = 1.;
+}
+
+void   DefaultMotionState::getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal)
+{
+       quatIma0 = m_worldTransform.getRotation().x();
+       quatIma1 = m_worldTransform.getRotation().y();
+       quatIma2 = m_worldTransform.getRotation().z();
+       quatReal = m_worldTransform.getRotation()[3];
+}
+               
+void   DefaultMotionState::setWorldPosition(float posX,float posY,float posZ)
+{
+       SimdPoint3 pos(posX,posY,posZ);
+       m_worldTransform.setOrigin( pos );
+}
+
+void   DefaultMotionState::setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal)
+{
+       SimdQuaternion orn(quatIma0,quatIma1,quatIma2,quatReal);
+       m_worldTransform.setRotation( orn );
+}
+               
+void   DefaultMotionState::calculateWorldTransformations()
+{
+
+}
+
index 646b21f285e176ee746c94b6902c82418d276239..056feba652c47d1e738c2a3a71bf6a76ed906841 100644 (file)
@@ -27,6 +27,7 @@ subject to the following restrictions:
 #include "SimdTransform.h"
 #include "Dynamics/RigidBody.h"
 
+#include "PHY_IMotionState.h"
 
 #include "BroadphaseCollision/BroadphaseProxy.h" //for CollisionShape access
 class CollisionShape;
@@ -155,7 +156,8 @@ class CcdPhysicsController : public PHY_IPhysicsController
                // clientinfo for raycasts for example
                virtual void*                           getNewClientInfo();
                virtual void                            setNewClientInfo(void* clientinfo);
-               virtual PHY_IPhysicsController* GetReplica() {return 0;}
+               virtual PHY_IPhysicsController* GetReplica();
+               
 
                virtual void    calcXform() {} ;
                virtual void SetMargin(float margin) {};
@@ -184,4 +186,30 @@ class CcdPhysicsController : public PHY_IPhysicsController
 
 };
 
+
+
+
+///DefaultMotionState implements standard motionstate, using SimdTransform
+class  DefaultMotionState : public PHY_IMotionState
+
+{
+       public:
+               DefaultMotionState();
+
+               virtual ~DefaultMotionState();
+
+               virtual void    getWorldPosition(float& posX,float& posY,float& posZ);
+               virtual void    getWorldScaling(float& scaleX,float& scaleY,float& scaleZ);
+               virtual void    getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal);
+               
+               virtual void    setWorldPosition(float posX,float posY,float posZ);
+               virtual void    setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal);
+               
+               virtual void    calculateWorldTransformations();
+               
+               SimdTransform   m_worldTransform;
+
+};
+
+
 #endif //BULLET2_PHYSICSCONTROLLER_H
index e24bc1653afeed3be538ddfd767ad89e6f1a0aba..4b4d3f15dae9095ebccaaa929e03179489120c04 100644 (file)
@@ -29,6 +29,10 @@ subject to the following restrictions:
 #include "CollisionDispatch/CollisionWorld.h"
 
 #include "CollisionShapes/ConvexShape.h"
+#include "CollisionShapes/ConeShape.h"
+
+
+
 #include "BroadphaseCollision/Dispatcher.h"
 #include "NarrowPhaseCollision/PersistentManifold.h"
 #include "CollisionShapes/TriangleMeshShape.h"
@@ -321,6 +325,7 @@ static void DrawAabb(IDebugDraw* debugDrawer,const SimdVector3& from,const SimdV
 CcdPhysicsEnvironment::CcdPhysicsEnvironment(CollisionDispatcher* dispatcher,BroadphaseInterface* broadphase)
 :m_scalingPropagated(false),
 m_numIterations(10),
+m_numTimeSubSteps(1),
 m_ccdMode(0),
 m_solverType(-1),
 m_profileTimings(0),
@@ -342,9 +347,9 @@ m_enableSatCollisionDetection(false)
                SimdVector3 worldMin(-10000,-10000,-10000);
                SimdVector3 worldMax(10000,10000,10000);
 
-               //broadphase = new AxisSweep3(worldMin,worldMax);
+               broadphase = new AxisSweep3(worldMin,worldMax);
 
-               broadphase = new SimpleBroadphase();
+               //broadphase = new SimpleBroadphase();
        }
 
 
@@ -498,6 +503,8 @@ void        CcdPhysicsEnvironment::beginFrame()
 
 bool   CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
 {
+       //printf("proceedDeltaTime\n");
+       
 
 #ifdef USE_QUICKPROF
        //toggle Profiler
@@ -529,16 +536,37 @@ bool      CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
        if (!SimdFuzzyZero(timeStep))
        {
                
+               {
+                       //do the kinematic calculation here, over the full timestep
+                       std::vector<CcdPhysicsController*>::iterator i;
+                       for (i=m_controllers.begin();
+                                               !(i==m_controllers.end()); i++)
+                       {
 
-               // define this in blender, the stepsize is 30 hertz, 60 hertz works much better 
-//#define SPLIT_TIMESTEP 1
+                                               CcdPhysicsController* ctrl = *i;
 
-#ifdef SPLIT_TIMESTEP
-               proceedDeltaTimeOneStep(0.5f*timeStep);
-               proceedDeltaTimeOneStep(0.5f*timeStep);
-#else          
-               proceedDeltaTimeOneStep(timeStep);
-#endif
+                                               SimdTransform predictedTrans;
+                                               RigidBody* body = ctrl->GetRigidBody();
+                                               if (body->GetActivationState() != ISLAND_SLEEPING)
+                                               {
+
+                                                       if (body->IsStatic())
+                                                       {
+                                                               //to calculate velocities next frame
+                                                               body->saveKinematicState(timeStep);
+                                                       }
+                                               }
+                       }
+               }
+
+
+               int i;
+               float subTimeStep = timeStep / float(m_numTimeSubSteps);
+
+               for (i=0;i<this->m_numTimeSubSteps;i++)
+               {
+                       proceedDeltaTimeOneStep(subTimeStep);
+               }
        } else
        {
                //todo: interpolate
@@ -564,7 +592,7 @@ bool        CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
 {
 
 
-       //      printf("CcdPhysicsEnvironment::proceedDeltaTime\n");
+       //printf("CcdPhysicsEnvironment::proceedDeltaTime\n");
 
        if (SimdFuzzyZero(timeStep))
                return true;
@@ -812,11 +840,7 @@ bool       CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep)
                                        if (body->GetActivationState() != ISLAND_SLEEPING)
                                        {
 
-                                               if (body->IsStatic())
-                                               {
-                                                       //to calculate velocities next frame
-                                                       body->saveKinematicState(timeStep);
-                                               } else
+                                               if (!body->IsStatic())
                                                {
                                                        body->predictIntegratedTransform(timeStep*      toi, predictedTrans);
                                                        body->proceedToTransform( predictedTrans);
@@ -1393,10 +1417,34 @@ TypedConstraint*        CcdPhysicsEnvironment::getConstraintById(int constraintId)
 
 void CcdPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl)
 {
+
+       CcdPhysicsController* ctrl1 = (CcdPhysicsController* )ctrl;
+       std::vector<CcdPhysicsController*>::iterator i =
+               std::find(m_controllers.begin(), m_controllers.end(), ctrl);
+       if ((i == m_controllers.end()))
+       {
+               addCcdPhysicsController(ctrl1);
+       }
+
+       requestCollisionCallback(ctrl);
        //printf("addSensor\n");
 }
+
+void CcdPhysicsEnvironment::removeCollisionCallback(PHY_IPhysicsController* ctrl)
+{
+       std::vector<CcdPhysicsController*>::iterator i =
+               std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl);
+       if (!(i == m_triggerControllers.end()))
+       {
+               std::swap(*i, m_triggerControllers.back());
+               m_triggerControllers.pop_back();
+       }
+}
+
+
 void CcdPhysicsEnvironment::removeSensor(PHY_IPhysicsController* ctrl)
 {
+       removeCollisionCallback(ctrl);
        //printf("removeSensor\n");
 }
 void CcdPhysicsEnvironment::addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)
@@ -1585,3 +1633,41 @@ void     CcdPhysicsEnvironment::UpdateAabbs(float        timeStep)
                                }
                        }
 }
+
+PHY_IPhysicsController*        CcdPhysicsEnvironment::CreateSphereController(float radius,const PHY__Vector3& position)
+{
+       
+       CcdConstructionInfo     cinfo;
+       cinfo.m_collisionShape = new SphereShape(radius);
+       cinfo.m_MotionState = 0;
+       cinfo.m_physicsEnv = this;
+       cinfo.m_collisionFlags |= CollisionObject::noContactResponse;
+       DefaultMotionState* motionState = new DefaultMotionState();
+       cinfo.m_MotionState = motionState;
+       motionState->m_worldTransform.setIdentity();
+       motionState->m_worldTransform.setOrigin(SimdVector3(position[0],position[1],position[2]));
+
+       CcdPhysicsController* sphereController = new CcdPhysicsController(cinfo);
+       
+
+       return sphereController;
+}
+
+
+PHY_IPhysicsController* CcdPhysicsEnvironment::CreateConeController(float coneradius,float coneheight)
+{
+       CcdConstructionInfo     cinfo;
+       cinfo.m_collisionShape = new ConeShape(coneradius,coneheight);
+       cinfo.m_MotionState = 0;
+       cinfo.m_physicsEnv = this;
+       DefaultMotionState* motionState = new DefaultMotionState();
+       cinfo.m_MotionState = motionState;
+       motionState->m_worldTransform.setIdentity();
+//     motionState->m_worldTransform.setOrigin(SimdVector3(position[0],position[1],position[2]));
+
+       CcdPhysicsController* sphereController = new CcdPhysicsController(cinfo);
+
+
+       return sphereController;
+}
+       
index 08dff62e236e5e90a87a0e97d359f6179a9206a4..9de7053d271679d91402e976256dc0a6024394c7 100644 (file)
@@ -48,7 +48,11 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
        SimdVector3 m_gravity;
        
        IDebugDraw*     m_debugDrawer;
+       //solver iterations
        int     m_numIterations;
+       
+       //timestep subdivisions
+       int     m_numTimeSubSteps;
        int     m_ccdMode;
        int     m_solverType;
        int     m_profileTimings;
@@ -74,6 +78,10 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
                }
 
                virtual void            setNumIterations(int numIter);
+               virtual void            setNumTimeSubSteps(int numTimeSubSteps)
+               {
+                       m_numTimeSubSteps = numTimeSubSteps;
+               }
                virtual void            setDeactivationTime(float dTime);
                virtual void            setDeactivationLinearTreshold(float linTresh) ;
                virtual void            setDeactivationAngularTreshold(float angTresh) ;
@@ -131,8 +139,10 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
                virtual void removeSensor(PHY_IPhysicsController* ctrl);
                virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user);
                virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl);
-               virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) {return 0;};
-               virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight){ return 0;};
+               virtual void removeCollisionCallback(PHY_IPhysicsController* ctrl);
+
+               virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position);
+               virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight);
        
 
                virtual int     getNumContactPoints();
index 6b40b51eba70de1b33d54c6491f6519e23771951..cdd67257de269c7124ca2fce11bb6142b9cf5d93 100644 (file)
@@ -57,6 +57,8 @@ class PHY_IPhysicsEnvironment
                virtual void            setDebugMode(int debugMode) {}
                ///setNumIterations set the number of iterations for iterative solvers
                virtual void            setNumIterations(int numIter) {}
+               ///setNumTimeSubSteps set the number of divisions of the timestep. Tradeoff quality versus performance.
+               virtual void            setNumTimeSubSteps(int numTimeSubSteps){}
                ///setDeactivationTime sets the minimum time that an objects has to stay within the velocity tresholds until it gets fully deactivated
                virtual void            setDeactivationTime(float dTime) {}
                ///setDeactivationLinearTreshold sets the linear velocity treshold, see setDeactivationTime
index c2a662c1fa223b088e28a7bfff47eb3361eaafdc..aaacd43646b2a0db8d2dc4a4abeb83e5d3a343b2 100644 (file)
@@ -186,6 +186,9 @@ void SG_Node::RemoveChild(SG_Node* child)
 
 void SG_Node::UpdateWorldData(double time)
 {
+       //if (!GetSGParent())
+       //      return;
+
        if (UpdateSpatialData(GetSGParent(),time))
                ActivateUpdateTransformCallback();