forked from bartvdbraak/blender
Various mem leaks related to CValue reference count fixed
This commit is contained in:
parent
44314581dc
commit
0db0f5734d
@ -1514,7 +1514,8 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
delete shapeprops;
|
||||
delete smmaterial;
|
||||
}
|
||||
|
||||
|
||||
@ -1599,7 +1600,8 @@ static KX_GameObject *gameobject_from_blenderobject(
|
||||
KX_Camera* gamecamera = gamecamera_from_bcamera(static_cast<Camera*>(ob->data), kxscene, converter);
|
||||
gameobj = gamecamera;
|
||||
|
||||
gamecamera->AddRef();
|
||||
//don't add a reference: the camera list in kxscene->m_cameras is not released at the end
|
||||
//gamecamera->AddRef();
|
||||
kxscene->AddCamera(gamecamera);
|
||||
|
||||
break;
|
||||
@ -1845,6 +1847,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
|
||||
vector<parentChildLink> vec_parent_child;
|
||||
|
||||
CListValue* objectlist = kxscene->GetObjectList();
|
||||
CListValue* inactivelist = kxscene->GetInactiveList();
|
||||
CListValue* parentlist = kxscene->GetRootParentList();
|
||||
|
||||
SCA_LogicManager* logicmgr = kxscene->GetLogicManager();
|
||||
@ -1852,7 +1855,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
|
||||
|
||||
CListValue* logicbrick_conversionlist = new CListValue();
|
||||
|
||||
SG_TreeFactory tf;
|
||||
//SG_TreeFactory tf;
|
||||
|
||||
// Convert actions to actionmap
|
||||
bAction *curAct;
|
||||
@ -1990,19 +1993,35 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
|
||||
if (isInActiveLayer)
|
||||
{
|
||||
objectlist->Add(gameobj->AddRef());
|
||||
tf.Add(gameobj->GetSGNode());
|
||||
//tf.Add(gameobj->GetSGNode());
|
||||
|
||||
gameobj->NodeUpdateGS(0,true);
|
||||
gameobj->Bucketize();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//we must store this object otherwise it will be deleted
|
||||
//at the end of this function if it is not a root object
|
||||
inactivelist->Add(gameobj->AddRef());
|
||||
}
|
||||
if (converter->addInitFromFrame){
|
||||
gameobj->NodeSetLocalPosition(posPrev);
|
||||
gameobj->NodeSetLocalOrientation(angor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Note about memory leak issues:
|
||||
When a CValue derived class is created, m_refcount is initialized to 1
|
||||
so the class must be released after being used to make sure that it won't
|
||||
hang in memory. If the object needs to be stored for a long time,
|
||||
use AddRef() so that this Release() does not free the object.
|
||||
Make sure that for any AddRef() there is a Release()!!!!
|
||||
Do the same for any object derived from CValue, CExpression and NG_NetworkMessage
|
||||
*/
|
||||
if (gameobj)
|
||||
gameobj->Release();
|
||||
|
||||
base = base->next;
|
||||
}
|
||||
|
||||
|
@ -934,6 +934,8 @@ void BL_ConvertActuators(char* maggiename,
|
||||
gameobj->AddActuator(baseact);
|
||||
|
||||
converter->RegisterGameActuator(baseact, bact);
|
||||
// done with baseact, release it
|
||||
baseact->Release();
|
||||
}
|
||||
|
||||
bact = bact->next;
|
||||
|
@ -174,6 +174,8 @@ void BL_ConvertControllers(
|
||||
gameobj->AddController(gamecontroller);
|
||||
|
||||
converter->RegisterGameController(gamecontroller, bcontr);
|
||||
//done with gamecontroller
|
||||
gamecontroller->Release();
|
||||
}
|
||||
|
||||
bcontr = bcontr->next;
|
||||
|
@ -105,8 +105,9 @@ void BL_ConvertProperties(Object* object,KX_GameObject* gameobj,SCA_TimeEventMan
|
||||
// set a subproperty called 'timer' so that
|
||||
// we can register the replica of this property
|
||||
// at the time a game object is replicated (AddObjectActuator triggers this)
|
||||
|
||||
timeval->SetProperty("timer",new CBoolValue(true));
|
||||
CValue *bval = new CBoolValue(true);
|
||||
timeval->SetProperty("timer",bval);
|
||||
bval->Release();
|
||||
if (isInActiveLayer)
|
||||
{
|
||||
timemgr->AddTimeProperty(timeval);
|
||||
@ -128,6 +129,8 @@ void BL_ConvertProperties(Object* object,KX_GameObject* gameobj,SCA_TimeEventMan
|
||||
{
|
||||
scene->AddDebugProperty(gameobj,STR_String(prop->name));
|
||||
}
|
||||
// done with propval, release it
|
||||
propval->Release();
|
||||
}
|
||||
|
||||
prop = prop->next;
|
||||
|
@ -733,6 +733,8 @@ void BL_ConvertSensors(struct Object* blenderobject,
|
||||
logicmgr->RegisterToSensor(gamecont,gamesensor);
|
||||
}
|
||||
}
|
||||
// done with gamesensor
|
||||
gamesensor->Release();
|
||||
|
||||
}
|
||||
sens=sens->next;
|
||||
|
@ -22,7 +22,9 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef _DEBUG
|
||||
//int gRefCountExpr;
|
||||
#endif
|
||||
CExpression::CExpression()// : m_cached_calculate(NULL)
|
||||
{
|
||||
m_refcount = 1;
|
||||
|
@ -169,7 +169,28 @@ PyObject* CValue::PyGetName(PyObject* self,PyObject* args,PyObject* kwds)
|
||||
return pyname;
|
||||
}
|
||||
|
||||
/*#define CVALUE_DEBUG*/
|
||||
#ifdef CVALUE_DEBUG
|
||||
int gRefCount;
|
||||
struct SmartCValueRef
|
||||
{
|
||||
CValue *m_ref;
|
||||
int m_count;
|
||||
SmartCValueRef(CValue *ref)
|
||||
{
|
||||
m_ref = ref;
|
||||
m_count = gRefCount++;
|
||||
}
|
||||
};
|
||||
|
||||
#include <vector>
|
||||
|
||||
std::vector<SmartCValueRef> gRefList;
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
//int gRefCountValue;
|
||||
#endif
|
||||
|
||||
CValue::CValue(PyTypeObject *T)
|
||||
: PyObjectPlus(T),
|
||||
@ -186,6 +207,12 @@ effect: constucts a CValue
|
||||
*/
|
||||
{
|
||||
//debug(gRefCountValue++) // debugging
|
||||
#ifdef _DEBUG
|
||||
//gRefCountValue++;
|
||||
#ifdef CVALUE_DEBUG
|
||||
gRefList.push_back(SmartCValueRef(this));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -199,6 +226,18 @@ effect: deletes the object
|
||||
ClearProperties();
|
||||
|
||||
assertd (m_refcount==0);
|
||||
#ifdef CVALUE_DEBUG
|
||||
std::vector<SmartCValueRef>::iterator it;
|
||||
for (it=gRefList.begin(); it!=gRefList.end(); it++)
|
||||
{
|
||||
if (it->m_ref == this)
|
||||
{
|
||||
*it = gRefList.back();
|
||||
gRefList.pop_back();
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -293,7 +332,7 @@ void CValue::SetProperty(const STR_String & name,CValue* ioProperty)
|
||||
}
|
||||
|
||||
// Add property at end of array
|
||||
(*m_pNamedPropertyArray)[name] = ioProperty;//->Add(ioProperty);
|
||||
(*m_pNamedPropertyArray)[name] = ioProperty->AddRef();//->Add(ioProperty);
|
||||
}
|
||||
|
||||
|
||||
@ -356,10 +395,13 @@ bool CValue::RemoveProperty(const STR_String & inName)
|
||||
if (m_pNamedPropertyArray == NULL)
|
||||
return false;
|
||||
|
||||
// Scan all properties, as soon as we find one with <inName> -> Remove it
|
||||
// CValue* val = (*m_pNamedPropertyArray)[inName];
|
||||
if (m_pNamedPropertyArray->erase(inName)) return true;
|
||||
|
||||
CValue* val = GetProperty(inName);
|
||||
if (NULL != val)
|
||||
{
|
||||
val->Release();
|
||||
m_pNamedPropertyArray->erase(inName);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -379,7 +421,7 @@ void CValue::ClearProperties()
|
||||
!(it == m_pNamedPropertyArray->end());it++)
|
||||
{
|
||||
CValue* tmpval = (*it).second;
|
||||
STR_String name = (*it).first;
|
||||
//STR_String name = (*it).first;
|
||||
tmpval->Release();
|
||||
}
|
||||
|
||||
@ -469,8 +511,9 @@ void CValue::CloneProperties(CValue *replica)
|
||||
for ( std::map<STR_String,CValue*>::iterator it = m_pNamedPropertyArray->begin();
|
||||
!(it == m_pNamedPropertyArray->end());it++)
|
||||
{
|
||||
|
||||
replica->SetProperty((*it).first,(*it).second->GetReplica());
|
||||
CValue *val = (*it).second->GetReplica();
|
||||
replica->SetProperty((*it).first,val);
|
||||
val->Release();
|
||||
}
|
||||
}
|
||||
|
||||
@ -489,10 +532,6 @@ double* CValue::GetVector3(bool bGetTransformedVec)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------------------------------------------------
|
||||
Reference Counting
|
||||
---------------------------------------------------------------------------------------------------------------------*/
|
||||
@ -504,6 +543,9 @@ CValue *CValue::AddRef()
|
||||
// Increase global reference count, used to see at the end of the program
|
||||
// if all CValue-derived classes have been dereferenced to 0
|
||||
//debug(gRefCountValue++);
|
||||
#ifdef _DEBUG
|
||||
//gRefCountValue++;
|
||||
#endif
|
||||
m_refcount++;
|
||||
return this;
|
||||
}
|
||||
@ -518,7 +560,9 @@ int CValue::Release()
|
||||
// Decrease global reference count, used to see at the end of the program
|
||||
// if all CValue-derived classes have been dereferenced to 0
|
||||
//debug(gRefCountValue--);
|
||||
|
||||
#ifdef _DEBUG
|
||||
//gRefCountValue--;
|
||||
#endif
|
||||
// Decrease local reference count, if it reaches 0 the object should be freed
|
||||
if (--m_refcount > 0)
|
||||
{
|
||||
@ -546,6 +590,9 @@ void CValue::DisableRefCount()
|
||||
m_refcount--;
|
||||
|
||||
//debug(gRefCountValue--);
|
||||
#ifdef _DEBUG
|
||||
//gRefCountValue--;
|
||||
#endif
|
||||
m_ValFlags.RefCountDisabled=true;
|
||||
}
|
||||
|
||||
@ -590,11 +637,14 @@ CValue* CValue::FindIdentifier(const STR_String& identifiername)
|
||||
} else
|
||||
{
|
||||
result = GetProperty(identifiername);
|
||||
if (result)
|
||||
return result->AddRef();
|
||||
}
|
||||
if (!result)
|
||||
{
|
||||
// warning here !!!
|
||||
result = new CErrorValue(identifiername+" not found");
|
||||
}
|
||||
if (result)
|
||||
return result->AddRef();
|
||||
// warning here !!!
|
||||
result = new CErrorValue(identifiername+" not found");
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -717,7 +767,7 @@ int CValue::_setattr(const STR_String& attr,PyObject* pyobj)
|
||||
oldprop->SetValue(vallie);
|
||||
} else
|
||||
{
|
||||
SetProperty(attr,vallie->AddRef());
|
||||
SetProperty(attr,vallie);
|
||||
}
|
||||
vallie->Release();
|
||||
}
|
||||
|
@ -101,6 +101,7 @@ SCA_ActuatorList& SCA_IObject::GetActuators()
|
||||
|
||||
void SCA_IObject::AddSensor(SCA_ISensor* act)
|
||||
{
|
||||
act->AddRef();
|
||||
m_sensors.push_back(act);
|
||||
}
|
||||
|
||||
@ -108,6 +109,7 @@ void SCA_IObject::AddSensor(SCA_ISensor* act)
|
||||
|
||||
void SCA_IObject::AddController(SCA_IController* act)
|
||||
{
|
||||
act->AddRef();
|
||||
m_controllers.push_back(act);
|
||||
}
|
||||
|
||||
@ -115,6 +117,7 @@ void SCA_IObject::AddController(SCA_IController* act)
|
||||
|
||||
void SCA_IObject::AddActuator(SCA_IActuator* act)
|
||||
{
|
||||
act->AddRef();
|
||||
m_actuators.push_back(act);
|
||||
}
|
||||
|
||||
|
@ -212,6 +212,7 @@ void SCA_KeyboardSensor::AddToTargetProp(int keyIndex)
|
||||
newprop.SetLength(oldlength - 1);
|
||||
CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
|
||||
GetParent()->SetProperty(m_targetprop, newstringprop);
|
||||
newstringprop->Release();
|
||||
}
|
||||
} else {
|
||||
/* append */
|
||||
@ -219,6 +220,7 @@ void SCA_KeyboardSensor::AddToTargetProp(int keyIndex)
|
||||
STR_String newprop = tprop->GetText() + pchar;
|
||||
CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
|
||||
GetParent()->SetProperty(m_targetprop, newstringprop);
|
||||
newstringprop->Release();
|
||||
}
|
||||
} else {
|
||||
if (!IsDelete(keyIndex)) {
|
||||
@ -227,6 +229,7 @@ void SCA_KeyboardSensor::AddToTargetProp(int keyIndex)
|
||||
STR_String newprop = pchar;
|
||||
CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
|
||||
GetParent()->SetProperty(m_targetprop, newstringprop);
|
||||
newstringprop->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,10 @@ SCA_LogicManager::SCA_LogicManager()
|
||||
|
||||
SCA_LogicManager::~SCA_LogicManager()
|
||||
{
|
||||
/* AddRef() is not used when the objects are added to m_mapStringToGameObjects
|
||||
so Release() should not be used either. The memory leak big is fixed
|
||||
in BL_ConvertBlenderObjects()
|
||||
|
||||
int numgameobj = m_mapStringToGameObjects.size();
|
||||
for (int i = 0; i < numgameobj; i++)
|
||||
{
|
||||
@ -58,8 +62,9 @@ SCA_LogicManager::~SCA_LogicManager()
|
||||
assert(gameobjptr);
|
||||
if (gameobjptr)
|
||||
(*gameobjptr)->Release();
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
/*for (int i=0;i<m_sensorcontrollermap.size();i++)
|
||||
{
|
||||
vector<SCA_IController*>* controllerarray = *(m_sensorcontrollermap[i]);
|
||||
@ -72,6 +77,8 @@ SCA_LogicManager::~SCA_LogicManager()
|
||||
}
|
||||
m_eventmanagers.clear();
|
||||
m_sensorcontrollermapje.clear();
|
||||
m_removedActuators.clear();
|
||||
m_activeActuators.clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -90,12 +90,11 @@ bool SCA_PropertyActuator::Update()
|
||||
if (oldprop)
|
||||
{
|
||||
oldprop->SetValue(newval);
|
||||
newval->Release();
|
||||
} else
|
||||
{
|
||||
propowner->SetProperty(m_propname,newval);
|
||||
}
|
||||
|
||||
newval->Release();
|
||||
break;
|
||||
}
|
||||
case KX_ACT_PROP_ADD:
|
||||
@ -123,9 +122,11 @@ bool SCA_PropertyActuator::Update()
|
||||
CValue* copyprop = m_sourceObj->GetProperty(m_exprtxt);
|
||||
if (copyprop)
|
||||
{
|
||||
CValue *val = copyprop->GetReplica();
|
||||
GetParent()->SetProperty(
|
||||
m_propname,
|
||||
copyprop->GetReplica());
|
||||
val);
|
||||
val->Release();
|
||||
|
||||
}
|
||||
}
|
||||
@ -239,11 +240,12 @@ PyObject* SCA_PropertyActuator::PySetProperty(PyObject* self, PyObject* args, Py
|
||||
|
||||
CValue* prop = GetParent()->FindIdentifier(nameArg);
|
||||
|
||||
if (prop) {
|
||||
if (!prop->IsError()) {
|
||||
m_propname = nameArg;
|
||||
} else {
|
||||
; /* not found ... */
|
||||
}
|
||||
prop->Release();
|
||||
|
||||
Py_Return;
|
||||
}
|
||||
|
@ -58,7 +58,9 @@ KX_Camera::KX_Camera(void* sgReplicationInfo,
|
||||
m_name = "cam";
|
||||
m_projection_matrix.setIdentity();
|
||||
m_modelview_matrix.setIdentity();
|
||||
SetProperty("camera",new CIntValue(1));
|
||||
CValue* val = new CIntValue(1);
|
||||
SetProperty("camera",val);
|
||||
val->Release();
|
||||
}
|
||||
|
||||
|
||||
|
@ -858,6 +858,8 @@ static btCollisionShape* CreateBulletShapeFromMesh(RAS_MeshObject* meshobj, bool
|
||||
//concaveShape = new btTriangleMeshShape( collisionMeshData );
|
||||
|
||||
concaveShape->recalcLocalAabb();
|
||||
if (collisionMeshShape)
|
||||
delete collisionMeshShape;
|
||||
collisionMeshShape = concaveShape;
|
||||
|
||||
}
|
||||
@ -866,8 +868,10 @@ static btCollisionShape* CreateBulletShapeFromMesh(RAS_MeshObject* meshobj, bool
|
||||
|
||||
return collisionMeshShape;
|
||||
}
|
||||
|
||||
delete collisionMeshShape;
|
||||
if (collisionMeshShape)
|
||||
delete collisionMeshShape;
|
||||
if (collisionMeshData)
|
||||
delete collisionMeshData;
|
||||
return NULL;
|
||||
|
||||
}
|
||||
@ -1021,7 +1025,10 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
|
||||
// ci.m_localInertiaTensor.setValue(0.1f,0.1f,0.1f);
|
||||
|
||||
if (!bm)
|
||||
{
|
||||
delete motionstate;
|
||||
return;
|
||||
}
|
||||
|
||||
bm->setMargin(0.06);
|
||||
|
||||
@ -1057,6 +1064,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
|
||||
|
||||
|
||||
compoundShape->addChildShape(childTrans,bm);
|
||||
kxscene->AddShape(bm);
|
||||
//do some recalc?
|
||||
//recalc inertia for rigidbody
|
||||
if (!rigidbody->isStaticOrKinematicObject())
|
||||
@ -1076,6 +1084,9 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
|
||||
btTransform identTrans;
|
||||
identTrans.setIdentity();
|
||||
compoundShape->addChildShape(identTrans,bm);
|
||||
//note abount compoundShape: Bullet does not delete the child shapes when
|
||||
//the compound shape is deleted, so insert also the child shapes
|
||||
kxscene->AddShape(bm);
|
||||
bm = compoundShape;
|
||||
}
|
||||
|
||||
@ -1112,9 +1123,6 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
|
||||
|
||||
|
||||
ci.m_collisionShape = bm;
|
||||
|
||||
|
||||
|
||||
ci.m_friction = smmaterial->m_friction;//tweak the friction a bit, so the default 0.5 works nice
|
||||
ci.m_restitution = smmaterial->m_restitution;
|
||||
ci.m_physicsEnv = env;
|
||||
@ -1127,6 +1135,8 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
|
||||
ci.m_collisionFilterMask = (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter);
|
||||
|
||||
KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna);
|
||||
//remember that we created a shape so that we can delete it when the scene is removed (bullet will not delete it)
|
||||
kxscene->AddShape(bm);
|
||||
|
||||
if (objprop->m_in_active_layer)
|
||||
{
|
||||
|
@ -1047,6 +1047,8 @@ void KX_KetsjiEngine::PostProcessScene(KX_Scene* scene)
|
||||
scene->SetActiveCamera(activecam);
|
||||
scene->GetObjectList()->Add(activecam->AddRef());
|
||||
scene->GetRootParentList()->Add(activecam->AddRef());
|
||||
//done with activecam
|
||||
activecam->Release();
|
||||
}
|
||||
|
||||
scene->UpdateParents(0.0);
|
||||
|
@ -326,6 +326,8 @@ void KX_SCA_AddObjectActuator::InstantAddObject()
|
||||
|
||||
m_lastCreatedObject = replica;
|
||||
m_lastCreatedObject->AddRef();
|
||||
// finished using replica? then release it
|
||||
replica->Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#pragma warning (disable : 4786)
|
||||
#endif //WIN32
|
||||
|
||||
|
||||
#include "KX_Scene.h"
|
||||
#include "MT_assert.h"
|
||||
|
||||
@ -78,6 +79,13 @@
|
||||
#include "BL_SkinDeformer.h"
|
||||
#include "BL_DeformableGameObject.h"
|
||||
|
||||
// to get USE_BULLET!
|
||||
#include "KX_ConvertPhysicsObject.h"
|
||||
|
||||
#ifdef USE_BULLET
|
||||
#include "CcdPhysicsEnvironment.h"
|
||||
#include "CcdPhysicsController.h"
|
||||
#endif
|
||||
|
||||
void* KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene)
|
||||
{
|
||||
@ -124,6 +132,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
|
||||
m_objectlist = new CListValue();
|
||||
m_parentlist = new CListValue();
|
||||
m_lightlist= new CListValue();
|
||||
m_inactivelist = new CListValue();
|
||||
m_euthanasyobjects = new CListValue();
|
||||
m_delayReleaseObjects = new CListValue();
|
||||
|
||||
@ -183,6 +192,9 @@ KX_Scene::~KX_Scene()
|
||||
if (m_parentlist)
|
||||
m_parentlist->Release();
|
||||
|
||||
if (m_inactivelist)
|
||||
m_inactivelist->Release();
|
||||
|
||||
if (m_lightlist)
|
||||
m_lightlist->Release();
|
||||
|
||||
@ -210,11 +222,38 @@ KX_Scene::~KX_Scene()
|
||||
{
|
||||
delete m_bucketmanager;
|
||||
}
|
||||
|
||||
#ifdef USE_BULLET
|
||||
// This is a fix for memory leaks in bullet: the collision shapes is not destroyed
|
||||
// when the physical controllers are destroyed. The reason is that shapes are shared
|
||||
// between replicas of an object. There is no reference count in Bullet so the
|
||||
// only workaround that does not involve changes in Bullet is to save in this array
|
||||
// the list of shapes that are created when the scene is created (see KX_ConvertPhysicsObjects.cpp)
|
||||
class btCollisionShape* shape;
|
||||
class btTriangleMeshShape* meshShape;
|
||||
vector<class btCollisionShape*>::iterator it = m_shapes.begin();
|
||||
while (it != m_shapes.end()) {
|
||||
shape = *it;
|
||||
if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
|
||||
{
|
||||
meshShape = static_cast<btTriangleMeshShape*>(shape);
|
||||
// shapes based on meshes use an interface that contains the vertices.
|
||||
// Again the idea is to be able to share the interface between shapes but
|
||||
// this is not used in Blender: each base object will have its own interface
|
||||
btStridingMeshInterface* meshInterface = meshShape->getMeshInterface();
|
||||
if (meshInterface)
|
||||
delete meshInterface;
|
||||
}
|
||||
delete shape;
|
||||
it++;
|
||||
}
|
||||
#endif
|
||||
//Py_DECREF(m_attrlist);
|
||||
}
|
||||
|
||||
|
||||
void KX_Scene::AddShape(class btCollisionShape*shape)
|
||||
{
|
||||
m_shapes.push_back(shape);
|
||||
}
|
||||
|
||||
|
||||
void KX_Scene::SetProjectionMatrix(MT_CmMatrix4x4& pmat)
|
||||
@ -243,6 +282,11 @@ CListValue* KX_Scene::GetRootParentList()
|
||||
return m_parentlist;
|
||||
}
|
||||
|
||||
CListValue* KX_Scene::GetInactiveList()
|
||||
{
|
||||
return m_inactivelist;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CListValue* KX_Scene::GetLightList()
|
||||
@ -415,7 +459,7 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal
|
||||
replicanode->SetSGClientObject(newobj);
|
||||
|
||||
// this is the list of object that are send to the graphics pipeline
|
||||
m_objectlist->Add(newobj);
|
||||
m_objectlist->Add(newobj->AddRef());
|
||||
newobj->Bucketize();
|
||||
|
||||
// logic cannot be replicated, until the whole hierarchy is replicated.
|
||||
@ -571,7 +615,9 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
|
||||
// add a timebomb to this object
|
||||
// for now, convert between so called frames and realtime
|
||||
m_tempObjectList->Add(replica->AddRef());
|
||||
replica->SetProperty("::timebomb",new CFloatValue(lifespan*0.02));
|
||||
CValue *fval = new CFloatValue(lifespan*0.02);
|
||||
replica->SetProperty("::timebomb",fval);
|
||||
fval->Release();
|
||||
}
|
||||
|
||||
// add to 'rootparent' list (this is the list of top hierarchy objects, updated each frame)
|
||||
@ -634,7 +680,7 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
|
||||
replica->GetSGNode()->UpdateWorldData(0);
|
||||
replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox());
|
||||
replica->GetSGNode()->SetRadius(originalobj->GetSGNode()->Radius());
|
||||
|
||||
// don't release replica here because we are returning it, not done with it...
|
||||
return replica;
|
||||
}
|
||||
|
||||
@ -654,7 +700,8 @@ void KX_Scene::RemoveObject(class CValue* gameobj)
|
||||
// recursively destruct
|
||||
node->Destruct();
|
||||
}
|
||||
newobj->SetSGNode(0);
|
||||
//no need to do that: the object is destroyed and memory released
|
||||
//newobj->SetSGNode(0);
|
||||
}
|
||||
|
||||
void KX_Scene::DelayedReleaseObject(CValue* gameobj)
|
||||
@ -704,6 +751,7 @@ void KX_Scene::NewRemoveObject(class CValue* gameobj)
|
||||
{
|
||||
m_logicmgr->RemoveDestroyedActuator(*ita);
|
||||
}
|
||||
// the sensors/controllers/actuators must also be released, this is done in ~SCA_IObject
|
||||
|
||||
// now remove the timer properties from the time manager
|
||||
int numprops = newobj->GetPropertyCount();
|
||||
@ -724,12 +772,15 @@ void KX_Scene::NewRemoveObject(class CValue* gameobj)
|
||||
newobj->Release();
|
||||
if (m_parentlist->RemoveValue(newobj))
|
||||
newobj->Release();
|
||||
if (m_inactivelist->RemoveValue(newobj))
|
||||
newobj->Release();
|
||||
if (m_euthanasyobjects->RemoveValue(newobj))
|
||||
newobj->Release();
|
||||
|
||||
if (newobj == m_active_camera)
|
||||
{
|
||||
m_active_camera->Release();
|
||||
//no AddRef done on m_active_camera so no Release
|
||||
//m_active_camera->Release();
|
||||
m_active_camera = NULL;
|
||||
}
|
||||
}
|
||||
@ -1108,6 +1159,8 @@ void KX_Scene::LogicEndFrame()
|
||||
for (i = numobj - 1; i >= 0; i--)
|
||||
{
|
||||
KX_GameObject* gameobj = (KX_GameObject*)m_euthanasyobjects->GetValue(i);
|
||||
// KX_Scene::RemoveObject will also remove the object from this list
|
||||
// that's why we start from the end
|
||||
this->RemoveObject(gameobj);
|
||||
}
|
||||
|
||||
@ -1115,11 +1168,11 @@ void KX_Scene::LogicEndFrame()
|
||||
for (i = numobj-1;i>=0;i--)
|
||||
{
|
||||
KX_GameObject* gameobj = (KX_GameObject*)m_delayReleaseObjects->GetValue(i);
|
||||
m_delayReleaseObjects->RemoveValue(gameobj);
|
||||
|
||||
// This list is not for object removal, but just object release
|
||||
gameobj->Release();
|
||||
}
|
||||
|
||||
|
||||
// empty the list as we have removed all references
|
||||
m_delayReleaseObjects->Resize(0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -85,6 +85,7 @@ class RAS_IPolyMaterial;
|
||||
class RAS_IRasterizer;
|
||||
class RAS_IRenderTools;
|
||||
class SCA_JoystickManager;
|
||||
class btCollisionShape;
|
||||
/**
|
||||
* The KX_Scene holds all data for an independent scene. It relates
|
||||
* KX_Objects to the specific objects in the modules.
|
||||
@ -111,6 +112,7 @@ protected:
|
||||
CListValue* m_objectlist;
|
||||
CListValue* m_parentlist; // all 'root' parents
|
||||
CListValue* m_lightlist;
|
||||
CListValue* m_inactivelist; // all objects that are not in the active layer
|
||||
|
||||
/**
|
||||
* The tree of objects in the scene.
|
||||
@ -121,7 +123,11 @@ protected:
|
||||
* The set of cameras for this scene
|
||||
*/
|
||||
list<class KX_Camera*> m_cameras;
|
||||
|
||||
/**
|
||||
* The set of bullet shapes that must be deleted at the end of the scene
|
||||
* to avoid memory leak (not deleted by bullet because shape are shared between replicas)
|
||||
*/
|
||||
vector<class btCollisionShape*> m_shapes;
|
||||
/**
|
||||
* Various SCA managers used by the scene
|
||||
*/
|
||||
@ -300,6 +306,7 @@ public:
|
||||
void NewRemoveObject(CValue* gameobj);
|
||||
void ReplaceMesh(CValue* gameobj,
|
||||
void* meshobj);
|
||||
void AddShape(class btCollisionShape* shape);
|
||||
/**
|
||||
* @section Logic stuff
|
||||
* Initiate an update of the logic system.
|
||||
@ -313,6 +320,10 @@ public:
|
||||
|
||||
CListValue*
|
||||
GetObjectList(
|
||||
);
|
||||
|
||||
CListValue*
|
||||
GetInactiveList(
|
||||
);
|
||||
|
||||
CListValue*
|
||||
|
Loading…
Reference in New Issue
Block a user