forked from bartvdbraak/blender
BGE fix: game object to controller links consistancy maintained regardless of order of deletion
AddObject actuator forces last created object to hang in memory even after object is removed from scene => bad link between object and physic controller that causes Blender to crash in case a python script tries to use it (bad programming anyway). This patch avoids the crash by maintaining consistent links at all time.
This commit is contained in:
parent
822e51bd2d
commit
52293831b2
@ -24,7 +24,18 @@ CcdPhysicsController(ci)
|
|||||||
|
|
||||||
KX_BulletPhysicsController::~KX_BulletPhysicsController ()
|
KX_BulletPhysicsController::~KX_BulletPhysicsController ()
|
||||||
{
|
{
|
||||||
|
// The game object has a direct link to
|
||||||
|
if (m_pObject)
|
||||||
|
{
|
||||||
|
// If we cheat in SetObject, we must also cheat here otherwise the
|
||||||
|
// object will still things it has a physical controller
|
||||||
|
// Note that it requires that m_pObject is reset in case the object is deleted
|
||||||
|
// before the controller (usual case, see KX_Scene::RemoveNodeDestructObjec)
|
||||||
|
// The non usual case is when the object is not deleted because its reference is hanging
|
||||||
|
// in a AddObject actuator but the node is deleted. This case is covered here.
|
||||||
|
KX_GameObject* gameobj = (KX_GameObject*) m_pObject->GetSGClientObject();
|
||||||
|
gameobj->SetPhysicsController(NULL,false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KX_BulletPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ)
|
void KX_BulletPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ)
|
||||||
@ -58,6 +69,7 @@ void KX_BulletPhysicsController::SetObject (SG_IObject* object)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void KX_BulletPhysicsController::setMargin (float collisionMargin)
|
void KX_BulletPhysicsController::setMargin (float collisionMargin)
|
||||||
{
|
{
|
||||||
CcdPhysicsController::SetMargin(collisionMargin);
|
CcdPhysicsController::SetMargin(collisionMargin);
|
||||||
|
@ -105,7 +105,19 @@ KX_GameObject::~KX_GameObject()
|
|||||||
delete m_pClient_info;
|
delete m_pClient_info;
|
||||||
//if (m_pSGNode)
|
//if (m_pSGNode)
|
||||||
// delete m_pSGNode;
|
// delete m_pSGNode;
|
||||||
|
if (m_pSGNode)
|
||||||
|
{
|
||||||
|
// must go through controllers and make sure they will not use us anymore
|
||||||
|
// This is important for KX_BulletPhysicsControllers that unregister themselves
|
||||||
|
// from the object when they are deleted.
|
||||||
|
SGControllerList::iterator contit;
|
||||||
|
SGControllerList& controllers = m_pSGNode->GetSGControllerList();
|
||||||
|
for (contit = controllers.begin();contit!=controllers.end();++contit)
|
||||||
|
{
|
||||||
|
(*contit)->ClearObject();
|
||||||
|
}
|
||||||
|
m_pSGNode->SetSGClientObject(NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -410,8 +410,15 @@ void KX_Scene::EnableZBufferClearing(bool isclearingZbuffer)
|
|||||||
void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gameobj)
|
void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gameobj)
|
||||||
{
|
{
|
||||||
KX_GameObject* orgobj = (KX_GameObject*)gameobj;
|
KX_GameObject* orgobj = (KX_GameObject*)gameobj;
|
||||||
NewRemoveObject(orgobj);
|
if (NewRemoveObject(orgobj) != 0)
|
||||||
|
{
|
||||||
|
// object is not yet deleted (this can happen when it hangs in an add object actuator
|
||||||
|
// last object created reference. It's a bad situation, don't know how to fix it exactly
|
||||||
|
// The least I can do, is remove the reference to the node in the object as the node
|
||||||
|
// will in any case be deleted. This ensures that the object will not try to use the node
|
||||||
|
// when it is finally deleted (see KX_GameObject destructor)
|
||||||
|
orgobj->SetSGNode(NULL);
|
||||||
|
}
|
||||||
if (node)
|
if (node)
|
||||||
delete node;
|
delete node;
|
||||||
}
|
}
|
||||||
@ -723,8 +730,9 @@ void KX_Scene::DelayedRemoveObject(class CValue* gameobj)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void KX_Scene::NewRemoveObject(class CValue* gameobj)
|
int KX_Scene::NewRemoveObject(class CValue* gameobj)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
KX_GameObject* newobj = (KX_GameObject*) gameobj;
|
KX_GameObject* newobj = (KX_GameObject*) gameobj;
|
||||||
|
|
||||||
//todo: look at this
|
//todo: look at this
|
||||||
@ -768,16 +776,17 @@ void KX_Scene::NewRemoveObject(class CValue* gameobj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
newobj->RemoveMeshes();
|
newobj->RemoveMeshes();
|
||||||
|
ret = 1;
|
||||||
if (m_objectlist->RemoveValue(newobj))
|
if (m_objectlist->RemoveValue(newobj))
|
||||||
newobj->Release();
|
ret = newobj->Release();
|
||||||
if (m_tempObjectList->RemoveValue(newobj))
|
if (m_tempObjectList->RemoveValue(newobj))
|
||||||
newobj->Release();
|
ret = newobj->Release();
|
||||||
if (m_parentlist->RemoveValue(newobj))
|
if (m_parentlist->RemoveValue(newobj))
|
||||||
newobj->Release();
|
ret = newobj->Release();
|
||||||
if (m_inactivelist->RemoveValue(newobj))
|
if (m_inactivelist->RemoveValue(newobj))
|
||||||
newobj->Release();
|
ret = newobj->Release();
|
||||||
if (m_euthanasyobjects->RemoveValue(newobj))
|
if (m_euthanasyobjects->RemoveValue(newobj))
|
||||||
newobj->Release();
|
ret = newobj->Release();
|
||||||
|
|
||||||
if (newobj == m_active_camera)
|
if (newobj == m_active_camera)
|
||||||
{
|
{
|
||||||
@ -787,6 +796,8 @@ void KX_Scene::NewRemoveObject(class CValue* gameobj)
|
|||||||
}
|
}
|
||||||
if (m_sceneConverter)
|
if (m_sceneConverter)
|
||||||
m_sceneConverter->UnregisterGameObject(newobj);
|
m_sceneConverter->UnregisterGameObject(newobj);
|
||||||
|
// return value will be 0 if the object is actually deleted (all reference gone)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -306,7 +306,7 @@ public:
|
|||||||
|
|
||||||
void DelayedReleaseObject(CValue* gameobj);
|
void DelayedReleaseObject(CValue* gameobj);
|
||||||
|
|
||||||
void NewRemoveObject(CValue* gameobj);
|
int NewRemoveObject(CValue* gameobj);
|
||||||
void ReplaceMesh(CValue* gameobj,
|
void ReplaceMesh(CValue* gameobj,
|
||||||
void* meshobj);
|
void* meshobj);
|
||||||
void AddShape(class btCollisionShape* shape);
|
void AddShape(class btCollisionShape* shape);
|
||||||
|
Loading…
Reference in New Issue
Block a user