BGE showstopper bug fix:
authorBenoit Bolsee <benoit.bolsee@online.be>
Thu, 16 Oct 2008 23:33:40 +0000 (23:33 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Thu, 16 Oct 2008 23:33:40 +0000 (23:33 +0000)
- Reset hit object pointer at end of frame of touch sensor to avoid returning invalid pointer to getHitObject().
- Clear all references in KX_TouchSensor::m_colliders when the sensor is disabled to avoid loose references.
- Test GetSGNode() systematically for all KX_GameObject functions that can be called from python in case a python controller keeps a reference in GameLogic (bad practice anyway).

source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_TouchSensor.cpp
source/gameengine/Ketsji/KX_TouchSensor.h
source/gameengine/Ketsji/KX_VehicleWrapper.cpp

index 1b57b9acc1d9e5b8022ce6d6e6a80702f69ad9ff..8b2feca53a3471be422371efac70dc3239f7800b 100644 (file)
@@ -214,7 +214,8 @@ KX_GameObject* KX_GameObject::GetParent()
 
 void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
 {
-       if (obj && GetSGNode()->GetSGParent() != obj->GetSGNode())
+       // check on valid node in case a python controller holds a reference to a deleted object
+       if (obj && GetSGNode() && obj->GetSGNode() && GetSGNode()->GetSGParent() != obj->GetSGNode())
        {
                // Make sure the objects have some scale
                MT_Vector3 scale1 = NodeGetWorldScaling();
@@ -256,7 +257,8 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
 
 void KX_GameObject::RemoveParent(KX_Scene *scene)
 {
-       if (GetSGNode()->GetSGParent())
+       // check on valid node in case a python controller holds a reference to a deleted object
+       if (GetSGNode() && GetSGNode()->GetSGParent())
        {
                // Set us to the right spot 
                GetSGNode()->SetLocalScale(GetSGNode()->GetWorldScaling());
@@ -642,6 +644,10 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac)
        MT_Vector3 vect,ori,z,x,y;
        MT_Scalar len;
 
+       // check on valid node in case a python controller holds a reference to a deleted object
+       if (!GetSGNode())
+               return;
+
        vect = dir;
        len = vect.length();
        if (MT_fuzzyZero(len))
@@ -785,7 +791,11 @@ MT_Vector3 KX_GameObject::GetVelocity(const MT_Point3& point)
 
 void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans)
 {
-       if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent()))
+       // check on valid node in case a python controller holds a reference to a deleted object
+       if (!GetSGNode())
+               return;
+
+       if (m_pPhysicsController1 && !GetSGNode()->GetSGParent())
        {
                // don't update physic controller if the object is a child:
                // 1) the transformation will not be right
@@ -794,35 +804,39 @@ void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans)
                m_pPhysicsController1->setPosition(trans);
        }
 
-       if (GetSGNode())
-               GetSGNode()->SetLocalPosition(trans);
+       GetSGNode()->SetLocalPosition(trans);
 }
 
 
 
 void KX_GameObject::NodeSetLocalOrientation(const MT_Matrix3x3& rot)
 {
-       if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent()))
+       // check on valid node in case a python controller holds a reference to a deleted object
+       if (!GetSGNode())
+               return;
+
+       if (m_pPhysicsController1 && !GetSGNode()->GetSGParent())
        {
                // see note above
                m_pPhysicsController1->setOrientation(rot);
        }
-       if (GetSGNode())
-               GetSGNode()->SetLocalOrientation(rot);
+       GetSGNode()->SetLocalOrientation(rot);
 }
 
 
 
 void KX_GameObject::NodeSetLocalScale(const MT_Vector3& scale)
 {
-       if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent()))
+       // check on valid node in case a python controller holds a reference to a deleted object
+       if (!GetSGNode())
+               return;
+
+       if (m_pPhysicsController1 && !GetSGNode()->GetSGParent())
        {
                // see note above
                m_pPhysicsController1->setScaling(scale);
        }
-       
-       if (GetSGNode())
-               GetSGNode()->SetLocalScale(scale);
+       GetSGNode()->SetLocalScale(scale);
 }
 
 
@@ -880,6 +894,13 @@ void KX_GameObject::NodeUpdateGS(double time,bool bInitiator)
 
 const MT_Matrix3x3& KX_GameObject::NodeGetWorldOrientation() const
 {
+       static MT_Matrix3x3 defaultOrientation = MT_Matrix3x3(  1.0, 0.0, 0.0,
+                                                                                                                       0.0, 1.0, 0.0,
+                                                                                                                       0.0, 0.0, 1.0);
+
+       // check on valid node in case a python controller holds a reference to a deleted object
+       if (!GetSGNode())
+               return defaultOrientation;
        return GetSGNode()->GetWorldOrientation();
 }
 
@@ -887,6 +908,12 @@ const MT_Matrix3x3& KX_GameObject::NodeGetWorldOrientation() const
 
 const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const
 {
+       static MT_Vector3 defaultScaling = MT_Vector3(1.0, 1.0, 1.0);
+
+       // check on valid node in case a python controller holds a reference to a deleted object
+       if (!GetSGNode())
+               return defaultScaling;
+
        return GetSGNode()->GetWorldScaling();
 }
 
@@ -894,6 +921,12 @@ const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const
 
 const MT_Point3& KX_GameObject::NodeGetWorldPosition() const
 {
+       static MT_Point3 defaultPosition = MT_Point3(0.0, 0.0, 0.0);
+
+       // check on valid node in case a python controller holds a reference to a deleted object
+       if (!GetSGNode())
+               return defaultPosition;
+
        return GetSGNode()->GetWorldPosition();
 }
 
index f5d6d7e8e0aeddc132af146e6799c737e95d62ad..caa71441b1dc95a0346e0eba3fcbdfd075d88167 100644 (file)
@@ -614,7 +614,8 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
        GroupObject *go;
        vector<KX_GameObject*> duplilist;
 
-       if (!groupobj->IsDupliGroup() ||
+       if (!groupobj->GetSGNode() ||
+               !groupobj->IsDupliGroup() ||
                level>MAX_DUPLI_RECUR)
                return;
 
@@ -1232,7 +1233,7 @@ void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool vi
 void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Camera*  cam,int layer)
 {
        // User (Python/Actuator) has forced object invisible...
-       if (!gameobj->GetVisible())
+       if (!gameobj->GetSGNode() || !gameobj->GetVisible())
                return;
        
        // Shadow lamp layers
index 41757a23f7ab0dca4f6b54cd4c9a14d5e0328534..2802da2723da50ae538679ef754b2e6a5a55267f 100644 (file)
@@ -55,9 +55,17 @@ void KX_TouchSensor::SynchronizeTransform()
 
 void KX_TouchSensor::EndFrame() {
        m_colliders->ReleaseAndRemoveAll();
+       m_hitObject = NULL;
        m_bTriggered = false;
 }
 
+void KX_TouchSensor::UnregisterToManager()
+{
+       // before unregistering the sensor, make sure we release all references
+       EndFrame();
+       m_eventmgr->RemoveSensor(this);
+}
+
 bool KX_TouchSensor::Evaluate(CValue* event)
 {
        bool result = false;
index b611d296939fc29d0e68aa81b98d990d8a076c91..8fbb1c676ba943ea02477dca6654c54799238ca4 100644 (file)
@@ -77,6 +77,7 @@ public:
        
        virtual void RegisterSumo(KX_TouchEventManager* touchman);
        virtual void UnregisterSumo(KX_TouchEventManager* touchman);
+       virtual void UnregisterToManager();
 
 //     virtual DT_Bool HandleCollision(void* obj1,void* obj2,
 //                                              const DT_CollData * coll_data); 
index 342e71c5093b1968e05ab08af16f59c378f10796..028f96f6c5b26d0feb3328b9168b067064aa5d94 100644 (file)
@@ -49,26 +49,29 @@ PyObject* KX_VehicleWrapper::PyAddWheel(PyObject* self,
        if (PyArg_ParseTuple(args,"OOOOffi",&wheelGameObject,&pylistPos,&pylistDir,&pylistAxleDir,&suspensionRestLength,&wheelRadius,&hasSteering))
        {
                KX_GameObject* gameOb = (KX_GameObject*) wheelGameObject;
-               
-               PHY_IMotionState* motionState = new KX_MotionState(gameOb->GetSGNode());
-
-               MT_Vector3 attachPos,attachDir,attachAxle;
-               PyVecTo(pylistPos,attachPos);
-               PyVecTo(pylistDir,attachDir);
-               PyVecTo(pylistAxleDir,attachAxle);
-               PHY__Vector3 aPos,aDir,aAxle;
-               aPos[0] = attachPos[0];
-               aPos[1] = attachPos[1];
-               aPos[2] = attachPos[2];
-               aDir[0] = attachDir[0];
-               aDir[1] = attachDir[1];
-               aDir[2] = attachDir[2];
-               aAxle[0] = -attachAxle[0];//someone reverse some conventions inside Bullet (axle winding)
-               aAxle[1] = -attachAxle[1];
-               aAxle[2] = -attachAxle[2];
-               
-               printf("attempt for addWheel: suspensionRestLength%f wheelRadius %f, hasSteering:%d\n",suspensionRestLength,wheelRadius,hasSteering);
-               m_vehicle->AddWheel(motionState,aPos,aDir,aAxle,suspensionRestLength,wheelRadius,hasSteering);
+
+               if (gameOb->GetSGNode())
+               {
+                       PHY_IMotionState* motionState = new KX_MotionState(gameOb->GetSGNode());
+
+                       MT_Vector3 attachPos,attachDir,attachAxle;
+                       PyVecTo(pylistPos,attachPos);
+                       PyVecTo(pylistDir,attachDir);
+                       PyVecTo(pylistAxleDir,attachAxle);
+                       PHY__Vector3 aPos,aDir,aAxle;
+                       aPos[0] = attachPos[0];
+                       aPos[1] = attachPos[1];
+                       aPos[2] = attachPos[2];
+                       aDir[0] = attachDir[0];
+                       aDir[1] = attachDir[1];
+                       aDir[2] = attachDir[2];
+                       aAxle[0] = -attachAxle[0];//someone reverse some conventions inside Bullet (axle winding)
+                       aAxle[1] = -attachAxle[1];
+                       aAxle[2] = -attachAxle[2];
+                       
+                       printf("attempt for addWheel: suspensionRestLength%f wheelRadius %f, hasSteering:%d\n",suspensionRestLength,wheelRadius,hasSteering);
+                       m_vehicle->AddWheel(motionState,aPos,aDir,aAxle,suspensionRestLength,wheelRadius,hasSteering);
+               }
                
        } else {
                return NULL;