reactphysics3d/src/engine/PhysicsCommon.cpp

381 lines
13 KiB
C++

/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2019 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Libraries
#include "PhysicsCommon.h"
using namespace reactphysics3d;
/// Constructor
PhysicsCommon::PhysicsCommon(MemoryAllocator* baseMemoryAllocator)
: mMemoryManager(baseMemoryAllocator),
mPhysicsWorlds(mMemoryManager.getHeapAllocator()), mSphereShapes(mMemoryManager.getHeapAllocator()),
mBoxShapes(mMemoryManager.getHeapAllocator()), mCapsuleShapes(mMemoryManager.getHeapAllocator()),
mConvexMeshShapes(mMemoryManager.getHeapAllocator()), mConcaveMeshShapes(mMemoryManager.getHeapAllocator()),
mHeightFieldShapes(mMemoryManager.getHeapAllocator()), mPolyhedronMeshes(mMemoryManager.getHeapAllocator()),
mTriangleMeshes(mMemoryManager.getHeapAllocator()), mLoggers(mMemoryManager.getHeapAllocator()),
mProfilers(mMemoryManager.getHeapAllocator()) {
}
// Destructor
PhysicsCommon::~PhysicsCommon() {
// Release the allocated memory
release();
}
// Destroy and release everything that has been allocated
void PhysicsCommon::release() {
// Destroy the physics worlds
for (auto it = mPhysicsWorlds.begin(); it != mPhysicsWorlds.end(); ++it) {
destroyPhysicsWorld(*it);
}
// Destroy the sphere shapes
for (auto it = mSphereShapes.begin(); it != mSphereShapes.end(); ++it) {
destroySphereShape(*it);
}
// Destroy the box shapes
for (auto it = mBoxShapes.begin(); it != mBoxShapes.end(); ++it) {
destroyBoxShape(*it);
}
// Destroy the capsule shapes
for (auto it = mCapsuleShapes.begin(); it != mCapsuleShapes.end(); ++it) {
destroyCapsuleShape(*it);
}
// Destroy the convex mesh shapes
for (auto it = mConvexMeshShapes.begin(); it != mConvexMeshShapes.end(); ++it) {
destroyConvexMeshShape(*it);
}
// Destroy the heigh-field shapes
for (auto it = mHeightFieldShapes.begin(); it != mHeightFieldShapes.end(); ++it) {
destroyHeightFieldShape(*it);
}
// Destroy the concave mesh shapes
for (auto it = mConcaveMeshShapes.begin(); it != mConcaveMeshShapes.end(); ++it) {
destroyConcaveMeshShape(*it);
}
// Destroy the polyhedron mesh
for (auto it = mPolyhedronMeshes.begin(); it != mPolyhedronMeshes.end(); ++it) {
destroyPolyhedronMesh(*it);
}
// Destroy the triangle mesh
for (auto it = mTriangleMeshes.begin(); it != mTriangleMeshes.end(); ++it) {
destroyTriangleMesh(*it);
}
// Destroy the loggers
for (auto it = mLoggers.begin(); it != mLoggers.end(); ++it) {
destroyLogger(*it);
}
// Destroy the profilers
for (auto it = mProfilers.begin(); it != mProfilers.end(); ++it) {
destroyProfiler(*it);
}
}
// Create and return an instance of PhysicsWorld
PhysicsWorld* PhysicsCommon::createPhysicsWorld(const PhysicsWorld::WorldSettings& worldSettings, Logger* logger, Profiler* profiler) {
#ifdef IS_PROFILING_ACTIVE
// If the user has not provided its own profiler, we create one
if (profiler == nullptr) {
profiler = createProfiler();
// Add a destination file for the profiling data
profiler->addFileDestination("rp3d_profiling_" + worldSettings.worldName + ".txt", Profiler::Format::Text);
}
#endif
#ifdef IS_LOGGING_ACTIVE
// If the user has not provided its own logger, we create one
if (logger == nullptr) {
logger = createLogger();
// Add a log destination file
uint logLevel = static_cast<uint>(Logger::Level::Information) | static_cast<uint>(Logger::Level::Warning) |
static_cast<uint>(Logger::Level::Error);
logger->addFileDestination("rp3d_log_" + worldSettings.worldName + ".html", logLevel, Logger::Format::HTML);
}
#endif
PhysicsWorld* world = new(mMemoryManager.allocate(MemoryManager::AllocationType::Heap, sizeof(PhysicsWorld))) PhysicsWorld(mMemoryManager, worldSettings, logger, profiler);
mPhysicsWorlds.add(world);
return world;
}
// Destroy an instance of PhysicsWorld
void PhysicsCommon::destroyPhysicsWorld(PhysicsWorld* world) {
// Call the destructor of the world
world->~PhysicsWorld();
// Release allocated memory
mMemoryManager.release(MemoryManager::AllocationType::Heap, world, sizeof(PhysicsWorld));
mPhysicsWorlds.remove(world);
}
// Create and return a sphere collision shape
SphereShape* PhysicsCommon::createSphereShape(const decimal radius) {
SphereShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(SphereShape))) SphereShape(radius, mMemoryManager.getHeapAllocator());
mSphereShapes.add(shape);
return shape;
}
// Destroy a sphere collision shape
void PhysicsCommon::destroySphereShape(SphereShape* sphereShape) {
// Call the destructor of the shape
sphereShape->~SphereShape();
// Release allocated memory
mMemoryManager.release(MemoryManager::AllocationType::Pool, sphereShape, sizeof(SphereShape));
mSphereShapes.remove(sphereShape);
}
// Create and return a box collision shape
BoxShape* PhysicsCommon::createBoxShape(const Vector3& extent) {
BoxShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(BoxShape))) BoxShape(extent, mMemoryManager.getHeapAllocator());
mBoxShapes.add(shape);
return shape;
}
// Destroy a box collision shape
void PhysicsCommon::destroyBoxShape(BoxShape* boxShape) {
// Call the destructor of the shape
boxShape->~BoxShape();
// Release allocated memory
mMemoryManager.release(MemoryManager::AllocationType::Pool, boxShape, sizeof(BoxShape));
mBoxShapes.remove(boxShape);
}
// Create and return a capsule shape
CapsuleShape* PhysicsCommon::createCapsuleShape(decimal radius, decimal height) {
CapsuleShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(CapsuleShape))) CapsuleShape(radius, height, mMemoryManager.getHeapAllocator());
mCapsuleShapes.add(shape);
return shape;
}
// Destroy a capsule collision shape
void PhysicsCommon::destroyCapsuleShape(CapsuleShape* capsuleShape) {
// Call the destructor of the shape
capsuleShape->~CapsuleShape();
// Release allocated memory
mMemoryManager.release(MemoryManager::AllocationType::Pool, capsuleShape, sizeof(CapsuleShape));
mCapsuleShapes.remove(capsuleShape);
}
// Create and return a convex mesh shape
ConvexMeshShape* PhysicsCommon::createConvexMeshShape(PolyhedronMesh* polyhedronMesh, const Vector3& scaling) {
ConvexMeshShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(ConvexMeshShape))) ConvexMeshShape(polyhedronMesh, mMemoryManager.getHeapAllocator(), scaling);
mConvexMeshShapes.add(shape);
return shape;
}
// Destroy a convex mesh shape
void PhysicsCommon::destroyConvexMeshShape(ConvexMeshShape* convexMeshShape) {
// Call the destructor of the shape
convexMeshShape->~ConvexMeshShape();
// Release allocated memory
mMemoryManager.release(MemoryManager::AllocationType::Pool, convexMeshShape, sizeof(ConvexMeshShape));
mConvexMeshShapes.remove(convexMeshShape);
}
// Create and return a height-field shape
HeightFieldShape* PhysicsCommon::createHeightFieldShape(int nbGridColumns, int nbGridRows, decimal minHeight, decimal maxHeight,
const void* heightFieldData, HeightFieldShape::HeightDataType dataType,
int upAxis, decimal integerHeightScale, const Vector3& scaling) {
HeightFieldShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(HeightFieldShape))) HeightFieldShape(nbGridColumns, nbGridRows, minHeight, maxHeight,
heightFieldData, dataType, mMemoryManager.getHeapAllocator(), upAxis, integerHeightScale, scaling);
mHeightFieldShapes.add(shape);
return shape;
}
// Destroy a height-field shape
void PhysicsCommon::destroyHeightFieldShape(HeightFieldShape* heightFieldShape) {
// Call the destructor of the shape
heightFieldShape->~HeightFieldShape();
// Release allocated memory
mMemoryManager.release(MemoryManager::AllocationType::Pool, heightFieldShape, sizeof(HeightFieldShape));
mHeightFieldShapes.remove(heightFieldShape);
}
// Create and return a concave mesh shape
ConcaveMeshShape* PhysicsCommon::createConcaveMeshShape(TriangleMesh* triangleMesh, const Vector3& scaling) {
ConcaveMeshShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(ConcaveMeshShape))) ConcaveMeshShape(triangleMesh, mMemoryManager.getHeapAllocator(), scaling);
mConcaveMeshShapes.add(shape);
return shape;
}
// Destroy a concave mesh shape
void PhysicsCommon::destroyConcaveMeshShape(ConcaveMeshShape* concaveMeshShape) {
// Call the destructor of the shape
concaveMeshShape->~ConcaveMeshShape();
// Release allocated memory
mMemoryManager.release(MemoryManager::AllocationType::Pool, concaveMeshShape, sizeof(ConcaveMeshShape));
mConcaveMeshShapes.remove(concaveMeshShape);
}
// Create a polyhedron mesh
PolyhedronMesh* PhysicsCommon::createPolyhedronMesh(PolygonVertexArray* polygonVertexArray) {
PolyhedronMesh* mesh = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(PolyhedronMesh))) PolyhedronMesh(polygonVertexArray, mMemoryManager.getHeapAllocator());
mPolyhedronMeshes.add(mesh);
return mesh;
}
// Destroy a polyhedron mesh
void PhysicsCommon::destroyPolyhedronMesh(PolyhedronMesh* polyhedronMesh) {
// Call the destructor of the shape
polyhedronMesh->~PolyhedronMesh();
// Release allocated memory
mMemoryManager.release(MemoryManager::AllocationType::Pool, polyhedronMesh, sizeof(PolyhedronMesh));
mPolyhedronMeshes.remove(polyhedronMesh);
}
// Create a triangle mesh
TriangleMesh* PhysicsCommon::createTriangleMesh() {
TriangleMesh* mesh = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(TriangleMesh))) TriangleMesh(mMemoryManager.getHeapAllocator());
mTriangleMeshes.add(mesh);
return mesh;
}
// Destroy a triangle mesh
void PhysicsCommon::destroyTriangleMesh(TriangleMesh* triangleMesh) {
// Call the destructor of the shape
triangleMesh->~TriangleMesh();
// Release allocated memory
mMemoryManager.release(MemoryManager::AllocationType::Pool, triangleMesh, sizeof(TriangleMesh));
mTriangleMeshes.remove(triangleMesh);
}
// Create and return a new logger
Logger* PhysicsCommon::createLogger() {
Logger* logger = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(Logger))) Logger(mMemoryManager.getHeapAllocator());
mLoggers.add(logger);
return logger;
}
// Destroy a logger
void PhysicsCommon::destroyLogger(Logger* logger) {
// Call the destructor of the logger
logger->~Logger();
// Release allocated memory
mMemoryManager.release(MemoryManager::AllocationType::Pool, logger, sizeof(Logger));
mLoggers.remove(logger);
}
// Create and return a new profiler
/// Note that you need to use a different profiler for each PhysicsWorld.
Profiler* PhysicsCommon::createProfiler() {
Profiler* profiler = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(Profiler))) Profiler();
mProfilers.add(profiler);
return profiler;
}
// Destroy a profiler
void PhysicsCommon::destroyProfiler(Profiler* profiler) {
// Call the destructor of the profiler
profiler->~Profiler();
// Release allocated memory
mMemoryManager.release(MemoryManager::AllocationType::Pool, profiler, sizeof(Profiler));
mProfilers.remove(profiler);
}