But i saw that there are a lot of memory leaks...
After some hours spent on your code, i find the definitive (i think) solution to the memory problems.
I rewrote some of your function in order to delete memory leaks.
Remember to call the destructor (or remove function) before exiting the program!
CPhysics.h
Code: Select all
#ifndef _CPHYSICS_H
#define _CPHYSICS_H
#include <btBulletCollisionCommon.h>
#include <btBulletDynamicsCommon.h>
#include <BulletCollision\CollisionDispatch\btGhostObject.h>
#include <irrlicht.h>
#include <iostream>
using namespace std;
using namespace irr;
using namespace core;
using namespace scene;
using namespace io;
using namespace gui;
using namespace video;
class CPhysics
{
public:
CPhysics(ISceneManager* smgr, IVideoDriver* driver, ITimer* Timer, const vector3df & Gravity, IMeshSceneNode* Map);
~CPhysics();
btTriangleMesh* ConvertIrrMeshToBulletTriangleMesh(IMesh* pMesh,const vector3df& scaling);
void QuaternionToEuler(const btQuaternion &TQuat, btVector3 &TEuler);
void getConvexHull(IMesh *collMesh, btConvexHullShape *hullShape, IAnimatedMeshSceneNode* node);
list<btRigidBody *> getObjectList();
void remove();
/*Create a new box to the specified position*/
btRigidBody* CreateBox(const vector3df &TPosition, const vector3df &TScale, btScalar TMass);
btRigidBody* loadConvex(std::string filename, const btVector3 &TPosition, const vector3df &TScale, btScalar TMass);
/*Get Bullet World Pointer*/
btDiscreteDynamicsWorld* getWorld();
/*Converts irrlicht's vector3df type into Bullet Vector3 format*/
btVector3 ConvertIrrVectorToBulletVector(const vector3df & toConvert);
/*Get gravity Vector*/
vector3df getGravity();
/*Main function of the wrapper. You need to call this function in the rendering loop*/
void Update();
bool UpdateRender(btRigidBody* TObject);
private:
btDefaultCollisionConfiguration* CollisionConfiguration;
btBroadphaseInterface* BroadPhase;
btCollisionDispatcher* Dispatcher;
btSequentialImpulseConstraintSolver* Solver;
btDiscreteDynamicsWorld* World;
btBvhTriangleMeshShape* trimeshShape;
btTriangleMesh* indexVertexArrays;
btGhostPairCallback * ghostPair;
ISceneManager* smgr;
IVideoDriver* driver;
ITimer* Timer;
list<btRigidBody *> Objects;
/*Array only for memory clean purpose*/
array<btDefaultMotionState * > m_motionStates;
array<btCollisionShape * > m_collisionShapes;
array<btRigidBody *> m_bodyPtrs;
array<btTriangleMesh *> m_triangleMeshes;
btVector3 Gravity;
u32 TimeStamp;
u32 DeltaTime;
bool initialized;
};
#endif
Code: Select all
#include "CPhysics.h"
CPhysics::~CPhysics()
{
if(initialized)
this->remove();
}
void CPhysics::remove()
{
for(list<btRigidBody *>::Iterator Iterator = CPhysics::Objects.begin(); Iterator != CPhysics::Objects.end();)
{
CPhysics::World->removeRigidBody((*Iterator));
/*Deletes all irrlicht nodes*/
if((*Iterator)->getUserPointer()!=NULL)
static_cast<ISceneNode *>((*Iterator)->getUserPointer())->remove();
Iterator = CPhysics::Objects.erase(Iterator);
}
delete CPhysics::World;
for(irr::u32 i =0; i<this->m_bodyPtrs.size();i++)
delete this->m_bodyPtrs[i];
for(irr::u32 i =0; i<this->m_collisionShapes.size();i++)
delete this->m_collisionShapes[i];
for(irr::u32 i =0; i<this->m_motionStates.size();i++)
delete this->m_motionStates[i];
for(irr::u32 i =0; i<this->m_triangleMeshes.size();i++)
delete this->m_triangleMeshes[i];
delete CollisionConfiguration;
delete BroadPhase;
delete Dispatcher;
delete Solver;
delete trimeshShape;
delete ghostPair;
initialized = false;
/* if(DEBUG_CONSOLE)
cout<<"Cleaned Physics World"<<endl;*/
}
btVector3 CPhysics::ConvertIrrVectorToBulletVector(const vector3df & toConvert)
{
return btVector3(toConvert.X,toConvert.Y,toConvert.Z);
}
CPhysics::CPhysics(ISceneManager* smgr, IVideoDriver* driver, ITimer* Timer, const vector3df & Gravity, IMeshSceneNode* Map)
{
CollisionConfiguration = new btDefaultCollisionConfiguration();
BroadPhase = new btAxisSweep3(btVector3(-100000, -100000, -100000), btVector3(100000, 100000, 100000));
ghostPair = new btGhostPairCallback();
BroadPhase->getOverlappingPairCache()->setInternalGhostPairCallback(ghostPair);
Dispatcher = new btCollisionDispatcher(CollisionConfiguration);
Solver = new btSequentialImpulseConstraintSolver();
CPhysics::World = new btDiscreteDynamicsWorld(Dispatcher, BroadPhase, Solver, CollisionConfiguration);
this->Gravity = ConvertIrrVectorToBulletVector(Gravity);
CPhysics::World->setGravity(this->Gravity);
CPhysics::smgr = smgr;
CPhysics::driver = driver;
CPhysics::Timer = Timer;
CPhysics::TimeStamp = Timer->getTime();
CPhysics::DeltaTime = 0;
indexVertexArrays = CPhysics::ConvertIrrMeshToBulletTriangleMesh(Map->getMesh(),Map->getScale());
trimeshShape = new btBvhTriangleMeshShape(indexVertexArrays, true);
btQuaternion quat;
quat.setEulerZYX(0,0,0);
btTransform Transform2;
Transform2.setIdentity();
Transform2.setOrigin(ConvertIrrVectorToBulletVector(Map->getPosition()));
Transform2.setRotation(quat);
btDefaultMotionState *MotionState2 = new btDefaultMotionState(Transform2);
this->m_motionStates.push_back(MotionState2);
btRigidBody *RigidBody = new btRigidBody(0, MotionState2, trimeshShape);
this->m_bodyPtrs.push_back(RigidBody);
RigidBody->setUserPointer(Map);
CPhysics::World->addRigidBody(RigidBody);
CPhysics::Objects.push_back(RigidBody);
RigidBody->setCollisionFlags(btCollisionObject::CF_STATIC_OBJECT);
initialized = true;
}
void CPhysics::Update()
{
CPhysics::DeltaTime = CPhysics::Timer->getTime() - CPhysics::TimeStamp;
CPhysics::TimeStamp = CPhysics::Timer->getTime();
CPhysics::World->stepSimulation(CPhysics::DeltaTime * 0.001f, 2);
for(list<btRigidBody *>::Iterator Iterator = CPhysics::Objects.begin(); Iterator != CPhysics::Objects.end();)
if(!CPhysics::UpdateRender(*Iterator))
{
Iterator = CPhysics::Objects.erase(Iterator);
}
else
{
Iterator++;
}
}
bool CPhysics::UpdateRender(btRigidBody* TObject)
{
ISceneNode* Node = static_cast<ISceneNode *>(TObject->getUserPointer());
if(Node == NULL)
{
return false;
}
const btVector3& Point = TObject->getCenterOfMassPosition();
Node->setPosition(vector3df((f32)Point[0], (f32)Point[1], (f32)Point[2]));
btVector3 EulerRotation;
CPhysics::QuaternionToEuler(TObject->getOrientation(), EulerRotation);
Node->setRotation(vector3df(EulerRotation[0], EulerRotation[1], EulerRotation[2]));
return true;
}
btRigidBody* CPhysics::CreateBox(const vector3df &TPosition, const vector3df &TScale, btScalar TMass)
{
ISceneNode* Node = CPhysics::smgr->addCubeSceneNode(1.0f);
Node->setScale(TScale);
Node->setMaterialFlag(EMF_LIGHTING, true);
Node->setMaterialFlag(EMF_NORMALIZE_NORMALS, true);
//Node->setMaterialTexture(0, driver->getTexture("rust0.jpg"));
btTransform Transform;
Transform.setIdentity();
Transform.setOrigin(ConvertIrrVectorToBulletVector(TPosition));
btDefaultMotionState *MotionState = new btDefaultMotionState(Transform);
m_motionStates.push_back(MotionState);
btVector3 HalfExtents(TScale.X * 0.5f, TScale.Y * 0.5f, TScale.Z * 0.5f);
btCollisionShape *Shape = new btBoxShape(HalfExtents);
m_collisionShapes.push_back(Shape);
btVector3 LocalInertia;
Shape->calculateLocalInertia(TMass, LocalInertia);
btRigidBody *RigidBody = new btRigidBody(TMass, MotionState, Shape, LocalInertia);
m_bodyPtrs.push_back(RigidBody);
RigidBody->setUserPointer((void *)(Node));
RigidBody->setActivationState(DISABLE_DEACTIVATION);
CPhysics::World->addRigidBody(RigidBody);
CPhysics::Objects.push_back(RigidBody);
return RigidBody;
}
btTriangleMesh* CPhysics::ConvertIrrMeshToBulletTriangleMesh(IMesh* pMesh,const vector3df& scaling)
{
btVector3 vertices[3];
u32 i,j,k,index,numVertices,numIndices;
u16* mb_indices;
btTriangleMesh *pTriMesh = new btTriangleMesh();
this->m_triangleMeshes.push_back(pTriMesh);
for (i=0; i<pMesh->getMeshBufferCount(); i++)
{
IMeshBuffer* mb=pMesh->getMeshBuffer(i);
if(mb->getVertexType()==EVT_STANDARD)
{
S3DVertex* mb_vertices=(S3DVertex*)mb->getVertices();
mb_indices = mb->getIndices();
numVertices = mb->getVertexCount();
numIndices = mb->getIndexCount();
for(j=0;j<numIndices;j+=3)
{
for (k=0;k<3;k++)
{
index = mb_indices[j+k];
vertices[k] = btVector3(mb_vertices[index].Pos.X*scaling.X, mb_vertices[index].Pos.Y*scaling.Y, mb_vertices[index].Pos.Z*scaling.Z);
}
pTriMesh->addTriangle(vertices[0], vertices[1], vertices[2]);
}
}
else if(mb->getVertexType()==EVT_2TCOORDS)
{
S3DVertex2TCoords* mb_vertices=(S3DVertex2TCoords*)mb->getVertices();
mb_indices = mb->getIndices();
numVertices = mb->getVertexCount();
numIndices = mb->getIndexCount();
for(j=0;j<numIndices;j+=3)
{
for (k=0;k<3;k++)
{
index = mb_indices[j+k];
vertices[k] = btVector3(mb_vertices[index].Pos.X*scaling.X, mb_vertices[index].Pos.Y*scaling.Y, mb_vertices[index].Pos.Z*scaling.Z);
}
pTriMesh->addTriangle(vertices[0], vertices[1], vertices[2]);
}
}
}
return pTriMesh;
};
void CPhysics::QuaternionToEuler(const btQuaternion &TQuat, btVector3 &TEuler)
{
btScalar W = TQuat.getW();
btScalar X = TQuat.getX();
btScalar Y = TQuat.getY();
btScalar Z = TQuat.getZ();
float WSquared = W * W;
float XSquared = X * X;
float YSquared = Y * Y;
float ZSquared = Z * Z;
TEuler.setX(atan2f(2.0f * (Y * Z + X * W), -XSquared - YSquared + ZSquared + WSquared));
TEuler.setY(asinf(-2.0f * (X * Z - Y * W)));
TEuler.setZ(atan2f(2.0f * (X * Y + Z * W), XSquared - YSquared - ZSquared + WSquared));
TEuler *= RADTODEG;
};
btRigidBody* CPhysics::loadConvex(std::string filename, const btVector3 &TPosition, const vector3df &TScale, btScalar TMass)
{
IAnimatedMeshSceneNode* Node = CPhysics::smgr->addAnimatedMeshSceneNode((IAnimatedMesh*)CPhysics::smgr->getMesh(filename.c_str()));
btTriangleMesh* trimesh = CPhysics::ConvertIrrMeshToBulletTriangleMesh(Node->getMesh(), Node->getScale());
btConvexShape* hull = new btConvexTriangleMeshShape(trimesh);
hull->setUserPointer(hull);
btVector3 localInertia(0,0,0);
hull->calculateLocalInertia(TMass, localInertia);
btQuaternion quat;
quat.setEulerZYX(Node->getRotation().X,Node->getRotation().Y,Node->getRotation().Z);
btTransform Transform2;
Transform2.setIdentity();
Transform2.setOrigin(TPosition);
Transform2.setRotation(quat);
btDefaultMotionState *MotionState2 = new btDefaultMotionState(Transform2);
this->m_motionStates.push_back(MotionState2);
btRigidBody* RigidBody = new btRigidBody(TMass, MotionState2, hull, localInertia);
this->m_bodyPtrs.push_back(RigidBody);
RigidBody->setUserPointer((void *)(Node));
RigidBody->setActivationState(DISABLE_DEACTIVATION);
CPhysics::World->addRigidBody(RigidBody);
CPhysics::Objects.push_back(RigidBody);
return RigidBody;
}
list<btRigidBody *> CPhysics::getObjectList()
{
return CPhysics::Objects;
}
btDiscreteDynamicsWorld* CPhysics::getWorld()
{
return CPhysics::World;
}
Thank you again...