diff --git a/CHANGELOG.md b/CHANGELOG.md index 87f0a74b..b63b6457 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,16 @@ - The CollisionWorld::testOverlap() methods do not have the 'categoryMaskBits' parameter anymore. - Many methods in the EventListener class have changed. Check the user manual for more information. - The way to retrieve contacts from a CollisionCallbackInfo object has changed. Check the user manual for more information. + - Now, the collision shapes need be be created with the PhysicsWorld::createXXXShape() methods instead of using the constructor of the shape as before. For instance, you need to use the PhysicsWorld::createBoxShape() method to create a BoxShape. + - There is now a single MemoryManager (with memory allocators) per PhysicsWorld. The memory allocators are no longer shared between worlds. + - An instance of the BoxShape class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createBoxShape() method. + - An instance of the SphereShape class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createSphereShape() method. + - An instance of the CapsuleShape class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createCapsuleShape() method. + - An instance of the ConvexMeshShape class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createConvexMeshShape() method. + - An instance of the HeightFieldShape class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createHeightFieldShape() method. + - An instance of the ConcaveMeshShape class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createConcaveMeshShape() method. + - An instance of the PolyhedronMesh class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createPolyhedronMesh() method. + - An instance of the TriangleMesh class cannot be instanciated directly anymore. You need to use the PhysicsCommon::createTriangleMesh() method. ### Removed @@ -24,7 +34,7 @@ - Make possible for the user to get vertices, normals and triangle indices of a ConcaveMeshShape - Make possible for the user to get vertices and height values of the HeightFieldShape - - Make possible for the user to use a custom single frame and pool memory allocator + - Add PhysicsCommon class that needs to be instanciated at the beginning and is used as a factory for other objects of the library ### Fixed diff --git a/CMakeLists.txt b/CMakeLists.txt index 24464719..7ec405f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -128,6 +128,7 @@ SET (REACTPHYSICS3D_HEADERS "src/engine/Entity.h" "src/engine/EntityManager.h" "src/engine/CollisionWorld.h" + "src/engine/PhysicsCommon.h" "src/systems/ConstraintSolverSystem.h" "src/systems/ContactSolverSystem.h" "src/systems/DynamicsSystem.h" @@ -228,6 +229,7 @@ SET (REACTPHYSICS3D_SOURCES "src/constraint/Joint.cpp" "src/constraint/SliderJoint.cpp" "src/engine/CollisionWorld.cpp" + "src/engine/PhysicsCommon.cpp" "src/systems/ConstraintSolverSystem.cpp" "src/systems/ContactSolverSystem.cpp" "src/systems/DynamicsSystem.cpp" diff --git a/src/collision/PolyhedronMesh.cpp b/src/collision/PolyhedronMesh.cpp index 2a386e16..3245ff19 100644 --- a/src/collision/PolyhedronMesh.cpp +++ b/src/collision/PolyhedronMesh.cpp @@ -36,10 +36,8 @@ using namespace reactphysics3d; * Create a polyhedron mesh given an array of polygons. * @param polygonVertexArray Pointer to the array of polygons and their vertices */ -PolyhedronMesh::PolyhedronMesh(PolygonVertexArray* polygonVertexArray) - : mHalfEdgeStructure(MemoryManager::getBaseAllocator(), - polygonVertexArray->getNbFaces(), - polygonVertexArray->getNbVertices(), +PolyhedronMesh::PolyhedronMesh(PolygonVertexArray* polygonVertexArray, MemoryAllocator &allocator) + : mMemoryAllocator(allocator), mHalfEdgeStructure(allocator, polygonVertexArray->getNbFaces(), polygonVertexArray->getNbVertices(), (polygonVertexArray->getNbFaces() + polygonVertexArray->getNbVertices() - 2) * 2) { mPolygonVertexArray = polygonVertexArray; @@ -76,7 +74,7 @@ void PolyhedronMesh::createHalfEdgeStructure() { // Get the polygon face PolygonVertexArray::PolygonFace* face = mPolygonVertexArray->getPolygonFace(f); - List faceVertices(MemoryManager::getBaseAllocator(), face->nbVertices); + List faceVertices(mMemoryAllocator, face->nbVertices); // For each vertex of the face for (uint v=0; v < face->nbVertices; v++) { diff --git a/src/collision/PolyhedronMesh.h b/src/collision/PolyhedronMesh.h index 0a32614e..a5ae6114 100644 --- a/src/collision/PolyhedronMesh.h +++ b/src/collision/PolyhedronMesh.h @@ -47,6 +47,9 @@ class PolyhedronMesh { // -------------------- Attributes -------------------- // + /// Reference to the memory allocator + MemoryAllocator& mMemoryAllocator; + /// Pointer the the polygon vertex array with vertices and faces /// of the mesh PolygonVertexArray* mPolygonVertexArray; @@ -62,6 +65,9 @@ class PolyhedronMesh { // -------------------- Methods -------------------- // + /// Constructor + PolyhedronMesh(PolygonVertexArray* polygonVertexArray, MemoryAllocator& allocator); + /// Create the half-edge structure of the mesh void createHalfEdgeStructure(); @@ -75,9 +81,6 @@ class PolyhedronMesh { // -------------------- Methods -------------------- // - /// Constructor - PolyhedronMesh(PolygonVertexArray* polygonVertexArray); - /// Destructor ~PolyhedronMesh(); @@ -98,6 +101,10 @@ class PolyhedronMesh { /// Return the centroid of the polyhedron Vector3 getCentroid() const; + + // ---------- Friendship ---------- // + + friend class PhysicsCommon; }; // Return the number of vertices diff --git a/src/collision/TriangleMesh.cpp b/src/collision/TriangleMesh.cpp index 59bf2d1e..3596ba24 100644 --- a/src/collision/TriangleMesh.cpp +++ b/src/collision/TriangleMesh.cpp @@ -25,12 +25,15 @@ // Libraries #include "TriangleMesh.h" -#include "memory/MemoryManager.h" using namespace reactphysics3d; // Constructor -TriangleMesh::TriangleMesh() - : mTriangleArrays(MemoryManager::getBaseAllocator()) { +TriangleMesh::TriangleMesh(MemoryAllocator& allocator) : mTriangleArrays(allocator) { + +} + +// Destructor +TriangleMesh::~TriangleMesh() { } diff --git a/src/collision/TriangleMesh.h b/src/collision/TriangleMesh.h index d5708249..f70a7aae 100644 --- a/src/collision/TriangleMesh.h +++ b/src/collision/TriangleMesh.h @@ -29,12 +29,12 @@ // Libraries #include #include "containers/List.h" +#include "memory/MemoryAllocator.h" namespace reactphysics3d { // Declarations class TriangleVertexArray; -class MemoryManager; // Class TriangleMesh /** @@ -51,13 +51,13 @@ class TriangleMesh { /// All the triangle arrays of the mesh (one triangle array per part) List mTriangleArrays; + /// Constructor + TriangleMesh(reactphysics3d::MemoryAllocator& allocator); + public: - /// Constructor - TriangleMesh(); - /// Destructor - ~TriangleMesh() = default; + ~TriangleMesh(); /// Add a subpart of the mesh void addSubpart(TriangleVertexArray* triangleVertexArray); @@ -67,6 +67,11 @@ class TriangleMesh { /// Return the number of subparts of the mesh uint getNbSubparts() const; + + + // ---------- Friendship ---------- // + + friend class PhysicsCommon; }; // Add a subpart of the mesh diff --git a/src/collision/shapes/BoxShape.cpp b/src/collision/shapes/BoxShape.cpp index 32fe47ef..6abab88e 100644 --- a/src/collision/shapes/BoxShape.cpp +++ b/src/collision/shapes/BoxShape.cpp @@ -37,9 +37,9 @@ using namespace reactphysics3d; /** * @param extent The vector with the three extents of the box (in meters) */ -BoxShape::BoxShape(const Vector3& extent) +BoxShape::BoxShape(const Vector3& extent, MemoryAllocator& allocator) : ConvexPolyhedronShape(CollisionShapeName::BOX), mExtent(extent), - mHalfEdgeStructure(MemoryManager::getBaseAllocator(), 6, 8, 24) { + mHalfEdgeStructure(allocator, 6, 8, 24) { assert(extent.x > decimal(0.0)); assert(extent.y > decimal(0.0)); @@ -55,8 +55,6 @@ BoxShape::BoxShape(const Vector3& extent) mHalfEdgeStructure.addVertex(6); mHalfEdgeStructure.addVertex(7); - MemoryAllocator& allocator = MemoryManager::getBaseAllocator(); - // Faces List face0(allocator, 4); face0.add(0); face0.add(1); face0.add(2); face0.add(3); diff --git a/src/collision/shapes/BoxShape.h b/src/collision/shapes/BoxShape.h index d0a5a151..3900f764 100644 --- a/src/collision/shapes/BoxShape.h +++ b/src/collision/shapes/BoxShape.h @@ -58,6 +58,9 @@ class BoxShape : public ConvexPolyhedronShape { // -------------------- Methods -------------------- // + /// Constructor + BoxShape(const Vector3& extent, MemoryAllocator& allocator); + /// Return a local support point in a given direction without the object margin virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const override; @@ -70,16 +73,13 @@ class BoxShape : public ConvexPolyhedronShape { /// Return the number of bytes used by the collision shape virtual size_t getSizeInBytes() const override; + /// Destructor + virtual ~BoxShape() override = default; + public : // -------------------- Methods -------------------- // - /// Constructor - BoxShape(const Vector3& extent); - - /// Destructor - virtual ~BoxShape() override = default; - /// Deleted copy-constructor BoxShape(const BoxShape& shape) = delete; @@ -124,6 +124,10 @@ class BoxShape : public ConvexPolyhedronShape { /// Return the string representation of the shape virtual std::string to_string() const override; + + // ----- Friendship ----- // + + friend class PhysicsCommon; }; // Return the extents of the box diff --git a/src/collision/shapes/CapsuleShape.h b/src/collision/shapes/CapsuleShape.h index fed74a70..6eaded49 100644 --- a/src/collision/shapes/CapsuleShape.h +++ b/src/collision/shapes/CapsuleShape.h @@ -57,6 +57,9 @@ class CapsuleShape : public ConvexShape { // -------------------- Methods -------------------- // + /// Constructor + CapsuleShape(decimal radius, decimal height); + /// Return a local support point in a given direction without the object margin virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const override; @@ -74,16 +77,13 @@ class CapsuleShape : public ConvexShape { /// Return the number of bytes used by the collision shape virtual size_t getSizeInBytes() const override; + /// Destructor + virtual ~CapsuleShape() override = default; + public : // -------------------- Methods -------------------- // - /// Constructor - CapsuleShape(decimal radius, decimal height); - - /// Destructor - virtual ~CapsuleShape() override = default; - /// Deleted copy-constructor CapsuleShape(const CapsuleShape& shape) = delete; @@ -107,6 +107,10 @@ class CapsuleShape : public ConvexShape { /// Return the string representation of the shape virtual std::string to_string() const override; + + // ----- Friendship ----- // + + friend class PhysicsCommon; }; // Get the radius of the capsule diff --git a/src/collision/shapes/ConcaveMeshShape.cpp b/src/collision/shapes/ConcaveMeshShape.cpp index 47c00b94..dd664b04 100644 --- a/src/collision/shapes/ConcaveMeshShape.cpp +++ b/src/collision/shapes/ConcaveMeshShape.cpp @@ -34,9 +34,9 @@ using namespace reactphysics3d; // Constructor -ConcaveMeshShape::ConcaveMeshShape(TriangleMesh* triangleMesh, const Vector3& scaling) +ConcaveMeshShape::ConcaveMeshShape(TriangleMesh* triangleMesh, MemoryAllocator& allocator, const Vector3& scaling) // TODO : Do not use the default base allocator here - : ConcaveShape(CollisionShapeName::TRIANGLE_MESH), mDynamicAABBTree(MemoryManager::getBaseAllocator()), + : ConcaveShape(CollisionShapeName::TRIANGLE_MESH), mDynamicAABBTree(allocator), mScaling(scaling) { mTriangleMesh = triangleMesh; mRaycastTestType = TriangleRaycastSide::FRONT; diff --git a/src/collision/shapes/ConcaveMeshShape.h b/src/collision/shapes/ConcaveMeshShape.h index e898f5c7..3b6ac86d 100644 --- a/src/collision/shapes/ConcaveMeshShape.h +++ b/src/collision/shapes/ConcaveMeshShape.h @@ -146,6 +146,9 @@ class ConcaveMeshShape : public ConcaveShape { // -------------------- Methods -------------------- // + /// Constructor + ConcaveMeshShape(TriangleMesh* triangleMesh, MemoryAllocator& allocator, const Vector3& scaling = Vector3(1, 1, 1)); + /// Raycast method with feedback information virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const override; @@ -169,14 +172,11 @@ class ConcaveMeshShape : public ConcaveShape { List &triangleVerticesNormals, List& shapeIds, MemoryAllocator& allocator) const override; - public: - - /// Constructor - ConcaveMeshShape(TriangleMesh* triangleMesh, const Vector3& scaling = Vector3(1, 1, 1)); - /// Destructor virtual ~ConcaveMeshShape() override = default; + public: + /// Deleted copy-constructor ConcaveMeshShape(const ConcaveMeshShape& shape) = delete; @@ -215,6 +215,7 @@ class ConcaveMeshShape : public ConcaveShape { friend class ConvexTriangleAABBOverlapCallback; friend class ConcaveMeshRaycastCallback; + friend class PhysicsCommon; }; // Return the number of bytes used by the collision shape diff --git a/src/collision/shapes/ConvexMeshShape.h b/src/collision/shapes/ConvexMeshShape.h index 51106eac..9cf931fb 100644 --- a/src/collision/shapes/ConvexMeshShape.h +++ b/src/collision/shapes/ConvexMeshShape.h @@ -66,6 +66,9 @@ class ConvexMeshShape : public ConvexPolyhedronShape { // -------------------- Methods -------------------- // + /// Constructor + ConvexMeshShape(PolyhedronMesh* polyhedronMesh, const Vector3& scaling = Vector3(1,1,1)); + /// Recompute the bounds of the mesh void recalculateBounds(); @@ -81,16 +84,13 @@ class ConvexMeshShape : public ConvexPolyhedronShape { /// Return the number of bytes used by the collision shape virtual size_t getSizeInBytes() const override; + /// Destructor + virtual ~ConvexMeshShape() override = default; + public : // -------------------- Methods -------------------- // - /// Constructor - ConvexMeshShape(PolyhedronMesh* polyhedronMesh, const Vector3& scaling = Vector3(1,1,1)); - - /// Destructor - virtual ~ConvexMeshShape() override = default; - /// Deleted copy-constructor ConvexMeshShape(const ConvexMeshShape& shape) = delete; @@ -135,6 +135,10 @@ class ConvexMeshShape : public ConvexPolyhedronShape { /// Return the string representation of the shape virtual std::string to_string() const override; + + // ----- Friendship ----- // + + friend class PhysicsCommon; }; // Return the number of bytes used by the collision shape diff --git a/src/collision/shapes/HeightFieldShape.h b/src/collision/shapes/HeightFieldShape.h index 6de59031..ef0b18d5 100644 --- a/src/collision/shapes/HeightFieldShape.h +++ b/src/collision/shapes/HeightFieldShape.h @@ -96,6 +96,12 @@ class HeightFieldShape : public ConcaveShape { // -------------------- Methods -------------------- // + /// Constructor + HeightFieldShape(int nbGridColumns, int nbGridRows, decimal minHeight, decimal maxHeight, + const void* heightFieldData, HeightDataType dataType, + int upAxis = 1, decimal integerHeightScale = 1.0f, + const Vector3& scaling = Vector3(1,1,1)); + /// Raycast method with feedback information virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const override; @@ -119,17 +125,11 @@ class HeightFieldShape : public ConcaveShape { /// Compute the shape Id for a given triangle uint computeTriangleShapeId(uint iIndex, uint jIndex, uint secondTriangleIncrement) const; - public: - - /// Constructor - HeightFieldShape(int nbGridColumns, int nbGridRows, decimal minHeight, decimal maxHeight, - const void* heightFieldData, HeightDataType dataType, - int upAxis = 1, decimal integerHeightScale = 1.0f, - const Vector3& scaling = Vector3(1,1,1)); - /// Destructor virtual ~HeightFieldShape() override = default; + public: + /// Deleted copy-constructor HeightFieldShape(const HeightFieldShape& shape) = delete; @@ -172,6 +172,7 @@ class HeightFieldShape : public ConcaveShape { friend class ConvexTriangleAABBOverlapCallback; friend class ConcaveMeshRaycastCallback; + friend class PhysicsCommon; }; // Return the scaling factor diff --git a/src/collision/shapes/SphereShape.h b/src/collision/shapes/SphereShape.h index 4faa9cc0..676780f3 100644 --- a/src/collision/shapes/SphereShape.h +++ b/src/collision/shapes/SphereShape.h @@ -50,6 +50,9 @@ class SphereShape : public ConvexShape { // -------------------- Methods -------------------- // + /// Constructor + SphereShape(decimal radius); + /// Return a local support point in a given direction without the object margin virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const override; @@ -62,16 +65,13 @@ class SphereShape : public ConvexShape { /// Return the number of bytes used by the collision shape virtual size_t getSizeInBytes() const override; + /// Destructor + virtual ~SphereShape() override = default; + public : // -------------------- Methods -------------------- // - /// Constructor - SphereShape(decimal radius); - - /// Destructor - virtual ~SphereShape() override = default; - /// Deleted copy-constructor SphereShape(const SphereShape& shape) = delete; @@ -95,6 +95,10 @@ class SphereShape : public ConvexShape { /// Return the string representation of the shape virtual std::string to_string() const override; + + // ----- Friendship ----- // + + friend class PhysicsCommon; }; // Get the radius of the sphere diff --git a/src/collision/shapes/TriangleShape.h b/src/collision/shapes/TriangleShape.h index 4de8ea8c..504848b9 100644 --- a/src/collision/shapes/TriangleShape.h +++ b/src/collision/shapes/TriangleShape.h @@ -107,10 +107,6 @@ class TriangleShape : public ConvexPolyhedronShape { const Transform& worldToOtherShapeTransform, decimal penetrationDepth, bool isTriangleShape1, Vector3& outNewLocalContactPointOtherShape, Vector3& outSmoothWorldContactTriangleNormal) const; - public: - - // -------------------- Methods -------------------- // - /// Constructor TriangleShape(const Vector3* vertices, const Vector3* verticesNormals, uint shapeId, MemoryAllocator& allocator); @@ -118,6 +114,10 @@ class TriangleShape : public ConvexPolyhedronShape { /// Destructor virtual ~TriangleShape() override = default; + public: + + // -------------------- Methods -------------------- // + /// Deleted copy-constructor TriangleShape(const TriangleShape& shape) = delete; @@ -181,6 +181,7 @@ class TriangleShape : public ConvexPolyhedronShape { friend class TriangleOverlapCallback; friend class MiddlePhaseTriangleCallback; friend class HeightFieldShape; + friend class CollisionDetectionSystem; }; // Return the number of bytes used by the collision shape diff --git a/src/engine/CollisionWorld.cpp b/src/engine/CollisionWorld.cpp index 2169239d..7ba4151a 100644 --- a/src/engine/CollisionWorld.cpp +++ b/src/engine/CollisionWorld.cpp @@ -36,8 +36,8 @@ using namespace std; uint CollisionWorld::mNbWorlds = 0; // Constructor -CollisionWorld::CollisionWorld(const WorldSettings& worldSettings, Logger* logger, Profiler* profiler) - : mConfig(worldSettings), mEntityManager(mMemoryManager.getPoolAllocator()), +CollisionWorld::CollisionWorld(const WorldSettings& worldSettings, Logger* logger, Profiler* profiler, MemoryAllocator* baseMemoryAllocator) + : mMemoryManager(baseMemoryAllocator), mConfig(worldSettings), mEntityManager(mMemoryManager.getPoolAllocator()), mCollisionBodyComponents(mMemoryManager.getBaseAllocator()), mRigidBodyComponents(mMemoryManager.getBaseAllocator()), mTransformComponents(mMemoryManager.getBaseAllocator()), mProxyShapesComponents(mMemoryManager.getBaseAllocator()), mJointsComponents(mMemoryManager.getBaseAllocator()), mBallAndSocketJointsComponents(mMemoryManager.getBaseAllocator()), diff --git a/src/engine/CollisionWorld.h b/src/engine/CollisionWorld.h index 8bec62ec..8739f9cf 100644 --- a/src/engine/CollisionWorld.h +++ b/src/engine/CollisionWorld.h @@ -143,23 +143,23 @@ class CollisionWorld { // -------------------- Methods -------------------- // + /// Constructor + CollisionWorld(const WorldSettings& worldSettings = WorldSettings(), Logger* logger = nullptr, + Profiler* profiler = nullptr, MemoryAllocator* baseMemoryAllocator = nullptr); + /// Notify the world if a body is disabled (slepping or inactive) or not void setBodyDisabled(Entity entity, bool isDisabled); /// Notify the world whether a joint is disabled or not void setJointDisabled(Entity jointEntity, bool isDisabled); + /// Destructor + virtual ~CollisionWorld(); + public : // -------------------- Methods -------------------- // - /// Constructor - CollisionWorld(const WorldSettings& worldSettings = WorldSettings(), Logger* logger = nullptr, - Profiler* profiler = nullptr); - - /// Destructor - virtual ~CollisionWorld(); - /// Deleted copy-constructor CollisionWorld(const CollisionWorld& world) = delete; @@ -221,6 +221,7 @@ class CollisionWorld { // -------------------- Friendship -------------------- // + friend class PhysicsCommon; friend class CollisionDetectionSystem; friend class CollisionBody; friend class RigidBody; diff --git a/src/engine/DynamicsWorld.cpp b/src/engine/DynamicsWorld.cpp index 12052b91..8b050e6e 100644 --- a/src/engine/DynamicsWorld.cpp +++ b/src/engine/DynamicsWorld.cpp @@ -520,7 +520,7 @@ void DynamicsWorld::createIslands() { uint nbTotalManifolds = 0; - // For each dynamic component + // For each rigid body component for (uint b=0; b < mRigidBodyComponents.getNbEnabledComponents(); b++) { // If the body has already been added to an island, we go to the next body diff --git a/src/engine/DynamicsWorld.h b/src/engine/DynamicsWorld.h index 4671a55a..549d5573 100644 --- a/src/engine/DynamicsWorld.h +++ b/src/engine/DynamicsWorld.h @@ -100,6 +100,10 @@ class DynamicsWorld : public CollisionWorld { // -------------------- Methods -------------------- // + /// Constructor + DynamicsWorld(const Vector3& mGravity, const WorldSettings& worldSettings = WorldSettings(), + Logger* logger = nullptr, Profiler* profiler = nullptr); + /// Solve the contacts and constraints void solveContactsAndConstraints(decimal timeStep); @@ -118,17 +122,13 @@ class DynamicsWorld : public CollisionWorld { /// Add the joint to the list of joints of the two bodies involved in the joint void addJointToBodies(Entity body1, Entity body2, Entity joint); + /// Destructor + virtual ~DynamicsWorld() override; + public : // -------------------- Methods -------------------- // - /// Constructor - DynamicsWorld(const Vector3& mGravity, const WorldSettings& worldSettings = WorldSettings(), - Logger* logger = nullptr, Profiler* profiler = nullptr); - - /// Destructor - virtual ~DynamicsWorld() override; - /// Deleted copy-constructor DynamicsWorld(const DynamicsWorld& world) = delete; @@ -212,6 +212,7 @@ class DynamicsWorld : public CollisionWorld { // -------------------- Friendship -------------------- // + friend class PhysicsCommon; friend class RigidBody; friend class Joint; friend class BallAndSocketJoint; diff --git a/src/engine/PhysicsCommon.cpp b/src/engine/PhysicsCommon.cpp new file mode 100644 index 00000000..8f72814b --- /dev/null +++ b/src/engine/PhysicsCommon.cpp @@ -0,0 +1,340 @@ +/******************************************************************************** +* 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) + // TODO : Use Heap allocator for internal Sets<> here instead of Pool allocator + : mMemoryManager(baseMemoryAllocator), mCollisionWorlds(mMemoryManager.getPoolAllocator()), + mDynamicsWorlds(mMemoryManager.getPoolAllocator()), mSphereShapes(mMemoryManager.getPoolAllocator()), + mBoxShapes(mMemoryManager.getPoolAllocator()), mCapsuleShapes(mMemoryManager.getPoolAllocator()), + mConvexMeshShapes(mMemoryManager.getPoolAllocator()), mConcaveMeshShapes(mMemoryManager.getPoolAllocator()), + mHeightFieldShapes(mMemoryManager.getPoolAllocator()), mPolyhedronMeshes(mMemoryManager.getPoolAllocator()), + mTriangleMeshes(mMemoryManager.getPoolAllocator()) { + +} + +// Destructor +PhysicsCommon::~PhysicsCommon() { + + // Release the allocated memory + release(); +} + +// Destroy and release everything that has been allocated +void PhysicsCommon::release() { + + // Destroy the collision worlds + for (auto it = mCollisionWorlds.begin(); it != mCollisionWorlds.end(); ++it) { + destroyCollisionWorld(*it); + } + + // Destroy the dynamics worlds + for (auto it = mDynamicsWorlds.begin(); it != mDynamicsWorlds.end(); ++it) { + destroyDynamicsWorld(*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); + } +} + +// Create and return an instance of CollisionWorld +CollisionWorld* PhysicsCommon::createCollisionWorld(const WorldSettings& worldSettings, Logger* logger, Profiler* profiler) { + + // TODO : Allocate in heap allocator here instead of pool + CollisionWorld* world = new(mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(CollisionWorld))) CollisionWorld(worldSettings, logger, profiler); + mCollisionWorlds.add(world); + + return world; +} + +// Destroy an instance of CollisionWorld +void PhysicsCommon::destroyCollisionWorld(CollisionWorld* world) { + + // Call the destructor of the world + world->~CollisionWorld(); + + // Release allocated memory + // TODO : Use Heap allocator for internal Sets<> here instead of Pool allocator + mMemoryManager.release(MemoryManager::AllocationType::Pool, world, sizeof(CollisionWorld)); + + mCollisionWorlds.remove(world); +} + +// Create and return an instance of DynamicsWorld +DynamicsWorld* PhysicsCommon::createDynamicsWorld(const Vector3& gravity, const WorldSettings& worldSettings, + Logger* logger, Profiler* profiler) { + + // TODO : Allocate in heap allocator here instead of pool + DynamicsWorld* world = new(mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(DynamicsWorld))) DynamicsWorld(gravity, worldSettings, logger, profiler); + + mDynamicsWorlds.add(world); + + return world; +} + +// Destroy an instance of DynamicsWorld +DynamicsWorld* PhysicsCommon::destroyDynamicsWorld(DynamicsWorld* world) { + + // Call the destructor of the world + world->~DynamicsWorld(); + + // Release allocated memory + // TODO : Use Heap allocator for internal Sets<> here instead of Pool allocator + mMemoryManager.release(MemoryManager::AllocationType::Pool, world, sizeof(DynamicsWorld)); + + mDynamicsWorlds.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); + 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 + // TODO : Use Heap allocator for internal Sets<> here instead of Pool allocator + mMemoryManager.release(MemoryManager::AllocationType::Pool, sphereShape, sizeof(SphereShape)); + + mSphereShapes.remove(sphereShape); +} + +// Create and return a box collision shape +BoxShape* PhysicsCommon::createBoxShape(const Vector3& extent) { + + // TODO : Pass heap allocator here in parameter + BoxShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(BoxShape))) BoxShape(extent, mMemoryManager.getPoolAllocator()); + + 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 + // TODO : Use Heap allocator for internal Sets<> here instead of Pool allocator + 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); + + 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 + // TODO : Use Heap allocator for internal Sets<> here instead of Pool allocator + 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, 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 + // TODO : Use Heap allocator for internal Sets<> here instead of Pool allocator + 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, 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 + // TODO : Use Heap allocator for internal Sets<> here instead of Pool allocator + 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) { + + // TODO : Pass heap allocator here in parameter + ConcaveMeshShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(ConcaveMeshShape))) ConcaveMeshShape(triangleMesh, mMemoryManager.getPoolAllocator(), 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 + // TODO : Use Heap allocator for internal Sets<> here instead of Pool allocator + mMemoryManager.release(MemoryManager::AllocationType::Pool, concaveMeshShape, sizeof(ConcaveMeshShape)); + + mConcaveMeshShapes.remove(concaveMeshShape); +} + +// Create a polyhedron mesh +PolyhedronMesh* PhysicsCommon::createPolyhedronMesh(PolygonVertexArray* polygonVertexArray) { + + // TODO : Pass heap allocator here in parameter + PolyhedronMesh* mesh = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(PolyhedronMesh))) PolyhedronMesh(polygonVertexArray, mMemoryManager.getPoolAllocator()); + + 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 + // TODO : Use Heap allocator for internal Sets<> here instead of Pool allocator + mMemoryManager.release(MemoryManager::AllocationType::Pool, polyhedronMesh, sizeof(PolyhedronMesh)); + + mPolyhedronMeshes.remove(polyhedronMesh); +} + +// Create a triangle mesh +TriangleMesh* PhysicsCommon::createTriangleMesh() { + + // TODO : Pass heap allocator here in parameter + TriangleMesh* mesh = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(TriangleMesh))) TriangleMesh(mMemoryManager.getPoolAllocator()); + + 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 + // TODO : Use Heap allocator for internal Sets<> here instead of Pool allocator + mMemoryManager.release(MemoryManager::AllocationType::Pool, triangleMesh, sizeof(TriangleMesh)); + + mTriangleMeshes.remove(triangleMesh); +} diff --git a/src/engine/PhysicsCommon.h b/src/engine/PhysicsCommon.h new file mode 100644 index 00000000..e64b37d0 --- /dev/null +++ b/src/engine/PhysicsCommon.h @@ -0,0 +1,175 @@ +/******************************************************************************** +* 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. * +* * +********************************************************************************/ + +#ifndef REACTPHYSICS3D_PHYSICS_COMMON_H +#define REACTPHYSICS3D_PHYSICS_COMMON_H + +// Libraries +#include "memory/MemoryManager.h" +#include "engine/CollisionWorld.h" +#include "engine/DynamicsWorld.h" +#include "collision/shapes/SphereShape.h" +#include "collision/shapes/BoxShape.h" +#include "collision/shapes/CapsuleShape.h" +#include "collision/shapes/HeightFieldShape.h" +#include "collision/shapes/ConvexMeshShape.h" +#include "collision/shapes/ConcaveMeshShape.h" +#include "collision/TriangleMesh.h" + +/// ReactPhysics3D namespace +namespace reactphysics3d { + +// Class PhysicsCommon +/** + * This class is a singleton that needs to be instanciated once at the beginning. + * Then this class is used by the user as a factory to create the physics world and + * other objects. + */ +class PhysicsCommon { + + private : + + // -------------------- Attributes -------------------- // + + /// Memory manager + MemoryManager mMemoryManager; + + /// Set of collision worlds + Set mCollisionWorlds; + + /// Set of dynamics worlds + Set mDynamicsWorlds; + + /// Set of sphere shapes + Set mSphereShapes; + + /// Set of box shapes + Set mBoxShapes; + + /// Set of capsule shapes + Set mCapsuleShapes; + + /// Set of convex mesh shapes + Set mConvexMeshShapes; + + /// Set of concave mesh shapes + Set mConcaveMeshShapes; + + /// Set of height field shapes + Set mHeightFieldShapes; + + /// Set of polyhedron meshes + Set mPolyhedronMeshes; + + /// Set of triangle meshes + Set mTriangleMeshes; + + // -------------------- Methods -------------------- // + + /// Destroy and release everything that has been allocated + void release(); + + public : + + // -------------------- Methods -------------------- // + + /// Constructor + /** + * @param baseMemoryAllocator Pointer to a user custom memory allocator + */ + PhysicsCommon(MemoryAllocator* baseMemoryAllocator = nullptr); + + /// Destructor + ~PhysicsCommon(); + + /// Create and return an instance of CollisionWorld + CollisionWorld* createCollisionWorld(const WorldSettings& worldSettings = WorldSettings(), Logger* logger = nullptr, + Profiler* profiler = nullptr); + + /// Destroy an instance of CollisionWorld + void destroyCollisionWorld(CollisionWorld* world); + + /// Create and return an instance of DynamicsWorld + DynamicsWorld* createDynamicsWorld(const Vector3& gravity, const WorldSettings& worldSettings = WorldSettings(), + Logger* logger = nullptr, Profiler* profiler = nullptr); + + /// Destroy an instance of DynamicsWorld + DynamicsWorld* destroyDynamicsWorld(DynamicsWorld* world); + + /// Create and return a sphere collision shape + SphereShape* createSphereShape(const decimal radius); + + /// Destroy a sphere collision shape + void destroySphereShape(SphereShape* sphereShape); + + /// Create and return a box collision shape + BoxShape* createBoxShape(const Vector3& extent); + + /// Destroy a box collision shape + void destroyBoxShape(BoxShape* boxShape); + + /// Create and return a capsule shape + CapsuleShape* createCapsuleShape(decimal radius, decimal height); + + /// Destroy a capsule collision shape + void destroyCapsuleShape(CapsuleShape* capsuleShape); + + /// Create and return a convex mesh shape + ConvexMeshShape* createConvexMeshShape(PolyhedronMesh* polyhedronMesh, const Vector3& scaling = Vector3(1,1,1)); + + /// Destroy a convex mesh shape + void destroyConvexMeshShape(ConvexMeshShape* convexMeshShape); + + /// Create and return a height-field shape + HeightFieldShape* createHeightFieldShape(int nbGridColumns, int nbGridRows, decimal minHeight, decimal maxHeight, + const void* heightFieldData, HeightFieldShape::HeightDataType dataType, + int upAxis = 1, decimal integerHeightScale = 1.0f, + const Vector3& scaling = Vector3(1,1,1)); + + /// Destroy a height-field shape + void destroyHeightFieldShape(HeightFieldShape* heightFieldShape); + + /// Create and return a concave mesh shape + ConcaveMeshShape* createConcaveMeshShape(TriangleMesh* triangleMesh, const Vector3& scaling = Vector3(1, 1, 1)); + + /// Destroy a concave mesh shape + void destroyConcaveMeshShape(ConcaveMeshShape* concaveMeshShape); + + /// Create a polyhedron mesh + PolyhedronMesh* createPolyhedronMesh(PolygonVertexArray* polygonVertexArray); + + /// Destroy a polyhedron mesh + void destroyPolyhedronMesh(PolyhedronMesh* polyhedronMesh); + + /// Create a triangle mesh + TriangleMesh* createTriangleMesh(); + + /// Destroy a triangle mesh + void destroyTriangleMesh(TriangleMesh* triangleMesh); +}; + +} + +#endif diff --git a/src/memory/MemoryManager.cpp b/src/memory/MemoryManager.cpp index 7dc80543..bc197ac6 100644 --- a/src/memory/MemoryManager.cpp +++ b/src/memory/MemoryManager.cpp @@ -24,11 +24,14 @@ ********************************************************************************/ // Libraries -#include "MemoryManager.h" +#include "memory/MemoryManager.h" using namespace reactphysics3d; -// Static variables -DefaultAllocator MemoryManager::mDefaultAllocator; -MemoryAllocator* MemoryManager::mBaseAllocator = &mDefaultAllocator; +// Constructor +MemoryManager::MemoryManager(MemoryAllocator* baseAllocator) : + mBaseAllocator(baseAllocator == nullptr ? &mDefaultAllocator : baseAllocator), + mPoolAllocator(baseAllocator == nullptr ? mDefaultAllocator : *baseAllocator), + mSingleFrameAllocator(baseAllocator == nullptr ? mDefaultAllocator : *baseAllocator) { +} diff --git a/src/memory/MemoryManager.h b/src/memory/MemoryManager.h index 65797218..ae8d4f3e 100644 --- a/src/memory/MemoryManager.h +++ b/src/memory/MemoryManager.h @@ -47,10 +47,10 @@ class MemoryManager { private: /// Default malloc/free memory allocator - static DefaultAllocator mDefaultAllocator; + DefaultAllocator mDefaultAllocator; /// Pointer to the base memory allocator to use - static MemoryAllocator* mBaseAllocator; + MemoryAllocator* mBaseAllocator; /// Memory pool allocator PoolAllocator mPoolAllocator; @@ -68,7 +68,7 @@ class MemoryManager { }; /// Constructor - MemoryManager() = default; + MemoryManager(MemoryAllocator* baseAllocator); /// Destructor ~MemoryManager() = default; @@ -86,10 +86,10 @@ class MemoryManager { SingleFrameAllocator& getSingleFrameAllocator(); /// Return the base memory allocator - static MemoryAllocator& getBaseAllocator(); + MemoryAllocator& getBaseAllocator(); /// Set the base memory allocator - static void setBaseAllocator(MemoryAllocator* memoryAllocator); + void setBaseAllocator(MemoryAllocator* memoryAllocator); /// Reset the single frame allocator void resetFrameAllocator(); diff --git a/src/memory/PoolAllocator.cpp b/src/memory/PoolAllocator.cpp index 3126ff9e..6ae8aecc 100644 --- a/src/memory/PoolAllocator.cpp +++ b/src/memory/PoolAllocator.cpp @@ -37,13 +37,13 @@ size_t PoolAllocator::mUnitSizes[NB_HEAPS]; int PoolAllocator::mMapSizeToHeapIndex[MAX_UNIT_SIZE + 1]; // Constructor -PoolAllocator::PoolAllocator() { +PoolAllocator::PoolAllocator(MemoryAllocator& baseAllocator) : mBaseAllocator(baseAllocator) { // Allocate some memory to manage the blocks mNbAllocatedMemoryBlocks = 64; mNbCurrentMemoryBlocks = 0; const size_t sizeToAllocate = mNbAllocatedMemoryBlocks * sizeof(MemoryBlock); - mMemoryBlocks = static_cast(MemoryManager::getBaseAllocator().allocate(sizeToAllocate)); + mMemoryBlocks = static_cast(baseAllocator.allocate(sizeToAllocate)); memset(mMemoryBlocks, 0, sizeToAllocate); memset(mFreeMemoryUnits, 0, sizeof(mFreeMemoryUnits)); @@ -83,10 +83,10 @@ PoolAllocator::~PoolAllocator() { // Release the memory allocated for each block for (uint i=0; i MAX_UNIT_SIZE) { // Allocate memory using default allocation - return MemoryManager::getBaseAllocator().allocate(size); + return mBaseAllocator.allocate(size); } // Get the index of the heap that will take care of the allocation request @@ -136,16 +136,16 @@ void* PoolAllocator::allocate(size_t size) { // Allocate more memory to contain the blocks MemoryBlock* currentMemoryBlocks = mMemoryBlocks; mNbAllocatedMemoryBlocks += 64; - mMemoryBlocks = static_cast(MemoryManager::getBaseAllocator().allocate(mNbAllocatedMemoryBlocks * sizeof(MemoryBlock))); + mMemoryBlocks = static_cast(mBaseAllocator.allocate(mNbAllocatedMemoryBlocks * sizeof(MemoryBlock))); memcpy(mMemoryBlocks, currentMemoryBlocks, mNbCurrentMemoryBlocks * sizeof(MemoryBlock)); memset(mMemoryBlocks + mNbCurrentMemoryBlocks, 0, 64 * sizeof(MemoryBlock)); - MemoryManager::getBaseAllocator().release(currentMemoryBlocks, mNbCurrentMemoryBlocks * sizeof(MemoryBlock)); + mBaseAllocator.release(currentMemoryBlocks, mNbCurrentMemoryBlocks * sizeof(MemoryBlock)); } // Allocate a new memory blocks for the corresponding heap and divide it in many // memory units MemoryBlock* newBlock = mMemoryBlocks + mNbCurrentMemoryBlocks; - newBlock->memoryUnits = static_cast(MemoryManager::getBaseAllocator().allocate(BLOCK_SIZE)); + newBlock->memoryUnits = static_cast(mBaseAllocator.allocate(BLOCK_SIZE)); assert(newBlock->memoryUnits != nullptr); size_t unitSize = mUnitSizes[indexHeap]; uint nbUnits = BLOCK_SIZE / unitSize; @@ -188,7 +188,7 @@ void PoolAllocator::release(void* pointer, size_t size) { if (size > MAX_UNIT_SIZE) { // Release the memory using the default deallocation - MemoryManager::getBaseAllocator().release(pointer, size); + mBaseAllocator.release(pointer, size); return; } diff --git a/src/memory/PoolAllocator.h b/src/memory/PoolAllocator.h index 27c4586d..cfeb2726 100644 --- a/src/memory/PoolAllocator.h +++ b/src/memory/PoolAllocator.h @@ -101,6 +101,9 @@ class PoolAllocator : public MemoryAllocator { /// True if the mMapSizeToHeapIndex array has already been initialized static bool isMapSizeToHeadIndexInitialized; + /// Base memory allocator + MemoryAllocator& mBaseAllocator; + /// Pointers to the first free memory unit for each heap MemoryUnit* mFreeMemoryUnits[NB_HEAPS]; @@ -126,7 +129,7 @@ class PoolAllocator : public MemoryAllocator { // -------------------- Methods -------------------- // /// Constructor - PoolAllocator(); + PoolAllocator(MemoryAllocator& baseAllocator); /// Destructor virtual ~PoolAllocator() override; diff --git a/src/memory/SingleFrameAllocator.cpp b/src/memory/SingleFrameAllocator.cpp index 6ffe924b..94b6aa0c 100644 --- a/src/memory/SingleFrameAllocator.cpp +++ b/src/memory/SingleFrameAllocator.cpp @@ -32,12 +32,12 @@ using namespace reactphysics3d; // Constructor -SingleFrameAllocator::SingleFrameAllocator() - : mTotalSizeBytes(INIT_SINGLE_FRAME_ALLOCATOR_NB_BYTES), - mCurrentOffset(0), mNbFramesTooMuchAllocated(0), mNeedToAllocatedMore(false) { +SingleFrameAllocator::SingleFrameAllocator(MemoryAllocator& baseAllocator) : mBaseAllocator(baseAllocator), + mTotalSizeBytes(INIT_SINGLE_FRAME_ALLOCATOR_NB_BYTES), + mCurrentOffset(0), mNbFramesTooMuchAllocated(0), mNeedToAllocatedMore(false) { // Allocate a whole block of memory at the beginning - mMemoryBufferStart = static_cast(MemoryManager::getBaseAllocator().allocate(mTotalSizeBytes)); + mMemoryBufferStart = static_cast(mBaseAllocator.allocate(mTotalSizeBytes)); assert(mMemoryBufferStart != nullptr); } @@ -45,7 +45,7 @@ SingleFrameAllocator::SingleFrameAllocator() SingleFrameAllocator::~SingleFrameAllocator() { // Release the memory allocated at the beginning - MemoryManager::getBaseAllocator().release(mMemoryBufferStart, mTotalSizeBytes); + mBaseAllocator.release(mMemoryBufferStart, mTotalSizeBytes); } @@ -60,7 +60,7 @@ void* SingleFrameAllocator::allocate(size_t size) { mNeedToAllocatedMore = true; // Return default memory allocation - return MemoryManager::getBaseAllocator().allocate(size); + return mBaseAllocator.allocate(size); } // Next available memory location @@ -81,7 +81,7 @@ void SingleFrameAllocator::release(void* pointer, size_t size) { if (p < mMemoryBufferStart || p > mMemoryBufferStart + mTotalSizeBytes) { // Use default deallocation - MemoryManager::getBaseAllocator().release(pointer, size); + mBaseAllocator.release(pointer, size); } } @@ -96,14 +96,14 @@ void SingleFrameAllocator::reset() { if (mNbFramesTooMuchAllocated > NB_FRAMES_UNTIL_SHRINK) { // Release the memory allocated at the beginning - MemoryManager::getBaseAllocator().release(mMemoryBufferStart, mTotalSizeBytes); + mBaseAllocator.release(mMemoryBufferStart, mTotalSizeBytes); // Divide the total memory to allocate by two mTotalSizeBytes /= 2; if (mTotalSizeBytes == 0) mTotalSizeBytes = 1; // Allocate a whole block of memory at the beginning - mMemoryBufferStart = static_cast(MemoryManager::getBaseAllocator().allocate(mTotalSizeBytes)); + mMemoryBufferStart = static_cast(mBaseAllocator.allocate(mTotalSizeBytes)); assert(mMemoryBufferStart != nullptr); mNbFramesTooMuchAllocated = 0; @@ -117,13 +117,13 @@ void SingleFrameAllocator::reset() { if (mNeedToAllocatedMore) { // Release the memory allocated at the beginning - MemoryManager::getBaseAllocator().release(mMemoryBufferStart, mTotalSizeBytes); + mBaseAllocator.release(mMemoryBufferStart, mTotalSizeBytes); // Multiply the total memory to allocate by two mTotalSizeBytes *= 2; // Allocate a whole block of memory at the beginning - mMemoryBufferStart = static_cast(MemoryManager::getBaseAllocator().allocate(mTotalSizeBytes)); + mMemoryBufferStart = static_cast(mBaseAllocator.allocate(mTotalSizeBytes)); assert(mMemoryBufferStart != nullptr); mNeedToAllocatedMore = false; diff --git a/src/memory/SingleFrameAllocator.h b/src/memory/SingleFrameAllocator.h index 599c0b65..7db915a2 100644 --- a/src/memory/SingleFrameAllocator.h +++ b/src/memory/SingleFrameAllocator.h @@ -53,6 +53,9 @@ class SingleFrameAllocator : public MemoryAllocator { // -------------------- Attributes -------------------- // + /// Reference to the base memory allocator + MemoryAllocator& mBaseAllocator; + /// Total size (in bytes) of memory of the allocator size_t mTotalSizeBytes; @@ -74,7 +77,7 @@ class SingleFrameAllocator : public MemoryAllocator { // -------------------- Methods -------------------- // /// Constructor - SingleFrameAllocator(); + SingleFrameAllocator(MemoryAllocator& baseAllocator); /// Destructor virtual ~SingleFrameAllocator() override; diff --git a/src/reactphysics3d.h b/src/reactphysics3d.h index 24c95965..a18cff7b 100644 --- a/src/reactphysics3d.h +++ b/src/reactphysics3d.h @@ -39,6 +39,7 @@ #include "mathematics/mathematics.h" #include "body/CollisionBody.h" #include "body/RigidBody.h" +#include "engine/PhysicsCommon.h" #include "engine/DynamicsWorld.h" #include "engine/CollisionWorld.h" #include "engine/Material.h" diff --git a/src/utils/Profiler.cpp b/src/utils/Profiler.cpp index 0bae856e..879d12d5 100644 --- a/src/utils/Profiler.cpp +++ b/src/utils/Profiler.cpp @@ -155,11 +155,15 @@ void ProfileNodeIterator::enterParent() { } // Constructor -Profiler::Profiler() :mRootNode("Root", nullptr), mDestinations(MemoryManager::getBaseAllocator()) { +Profiler::Profiler() :mRootNode("Root", nullptr) { mCurrentNode = &mRootNode; + mNbDestinations = 0; + mNbAllocatedDestinations = 0; mProfilingStartTime = Timer::getCurrentSystemTime() * 1000.0L; mFrameCounter = 0; + + allocatedDestinations(1); } // Destructor @@ -174,11 +178,11 @@ Profiler::~Profiler() { void Profiler::removeAllDestinations() { // Delete all the destinations - for (uint i=0; igetOutputStream()); + printRecursiveNodeReport(iterator, 0, mDestinations[i]->getOutputStream()); // Destroy the iterator destroyIterator(iterator); @@ -232,15 +236,39 @@ void Profiler::printReport() { // Add a file destination to the profiler void Profiler::addFileDestination(const std::string& filePath, Format format) { + if (mNbAllocatedDestinations == mNbDestinations) { + allocatedDestinations(mNbAllocatedDestinations * 2); + } + FileDestination* destination = new FileDestination(filePath, format); - mDestinations.add(destination); + mDestinations[mNbDestinations] = destination; + + mNbDestinations++; +} + +// Allocate memory for the destinations +void Profiler::allocatedDestinations(uint nbDestinationsToAllocate) { + + if (mNbAllocatedDestinations >= nbDestinationsToAllocate) return; + + Destination** newArray = static_cast(std::malloc(nbDestinationsToAllocate * sizeof(Destination*))); + std::memcpy(newArray, mDestinations, mNbAllocatedDestinations * sizeof(Destination*)); + + mDestinations = newArray; + mNbAllocatedDestinations = nbDestinationsToAllocate; } // Add a stream destination to the profiler void Profiler::addStreamDestination(std::ostream& outputStream, Format format) { + if (mNbAllocatedDestinations == mNbDestinations) { + allocatedDestinations(mNbAllocatedDestinations * 2); + } + StreamDestination* destination = new StreamDestination(outputStream, format); - mDestinations.add(destination); + mDestinations[mNbDestinations] = destination; + + mNbDestinations++; } // Recursively print the report of a given node of the profiler tree diff --git a/src/utils/Profiler.h b/src/utils/Profiler.h index 5cb22309..b1f583f7 100644 --- a/src/utils/Profiler.h +++ b/src/utils/Profiler.h @@ -291,8 +291,14 @@ class Profiler { /// Starting profiling time long double mProfilingStartTime; - /// All the output destinations - List mDestinations; + /// Number of allocated destinations + uint mNbAllocatedDestinations; + + /// Number of destinations + uint mNbDestinations; + + /// Array with all the output destinations + Destination** mDestinations; /// Recursively print the report of a given node of the profiler tree void printRecursiveNodeReport(ProfileNodeIterator* iterator, int spacing, @@ -336,6 +342,9 @@ class Profiler { /// Return an iterator over the profiler tree starting at the root ProfileNodeIterator* getIterator(); + // Allocate memory for the destinations + void allocatedDestinations(uint nbDestinationsToAllocate); + // Add a file destination to the profiler void addFileDestination(const std::string& filePath, Format format); diff --git a/test/tests/collision/TestCollisionWorld.h b/test/tests/collision/TestCollisionWorld.h index 3a218d1c..63cf0280 100644 --- a/test/tests/collision/TestCollisionWorld.h +++ b/test/tests/collision/TestCollisionWorld.h @@ -265,6 +265,8 @@ class TestCollisionWorld : public Test { // ---------- Atributes ---------- // + PhysicsCommon mPhysicsCommon; + // Physics world CollisionWorld* mWorld; @@ -330,37 +332,37 @@ class TestCollisionWorld : public Test { TestCollisionWorld(const std::string& name) : Test(name) { // Create the collision world - mWorld = new CollisionWorld(); + mWorld = mPhysicsCommon.createCollisionWorld(); // ---------- Boxes ---------- // Transform boxTransform1(Vector3(-20, 20, 0), Quaternion::identity()); mBoxBody1 = mWorld->createCollisionBody(boxTransform1); - mBoxShape1 = new BoxShape(Vector3(3, 3, 3)); + mBoxShape1 = mPhysicsCommon.createBoxShape(Vector3(3, 3, 3)); mBoxProxyShape1 = mBoxBody1->addCollisionShape(mBoxShape1, Transform::identity()); Transform boxTransform2(Vector3(-10, 20, 0), Quaternion::identity()); mBoxBody2 = mWorld->createCollisionBody(boxTransform2); - mBoxShape2 = new BoxShape(Vector3(4, 2, 8)); + mBoxShape2 = mPhysicsCommon.createBoxShape(Vector3(4, 2, 8)); mBoxProxyShape2 = mBoxBody2->addCollisionShape(mBoxShape2, Transform::identity()); // ---------- Spheres ---------- // - mSphereShape1 = new SphereShape(3.0); + mSphereShape1 = mPhysicsCommon.createSphereShape(3.0); Transform sphereTransform1(Vector3(10, 20, 0), Quaternion::identity()); mSphereBody1 = mWorld->createCollisionBody(sphereTransform1); mSphereProxyShape1 = mSphereBody1->addCollisionShape(mSphereShape1, Transform::identity()); - mSphereShape2 = new SphereShape(5.0); + mSphereShape2 = mPhysicsCommon.createSphereShape(5.0); Transform sphereTransform2(Vector3(20, 20, 0), Quaternion::identity()); mSphereBody2 = mWorld->createCollisionBody(sphereTransform2); mSphereProxyShape2 = mSphereBody2->addCollisionShape(mSphereShape2, Transform::identity()); // ---------- Capsules ---------- // - mCapsuleShape1 = new CapsuleShape(2, 6); + mCapsuleShape1 = mPhysicsCommon.createCapsuleShape(2, 6); Transform capsuleTransform1(Vector3(-10, 0, 0), Quaternion::identity()); mCapsuleBody1 = mWorld->createCollisionBody(capsuleTransform1); mCapsuleProxyShape1 = mCapsuleBody1->addCollisionShape(mCapsuleShape1, Transform::identity()); - mCapsuleShape2 = new CapsuleShape(3, 4); + mCapsuleShape2 = mPhysicsCommon.createCapsuleShape(3, 4); Transform capsuleTransform2(Vector3(-20, 0, 0), Quaternion::identity()); mCapsuleBody2 = mWorld->createCollisionBody(capsuleTransform2); mCapsuleProxyShape2 = mCapsuleBody2->addCollisionShape(mCapsuleShape2, Transform::identity()); @@ -393,8 +395,8 @@ class TestCollisionWorld : public Test { &(mConvexMeshCubeIndices[0]), sizeof(int), 6, mConvexMeshPolygonFaces, rp3d::PolygonVertexArray::VertexDataType::VERTEX_FLOAT_TYPE, rp3d::PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE); - mConvexMesh1PolyhedronMesh = new rp3d::PolyhedronMesh(mConvexMesh1PolygonVertexArray); - mConvexMeshShape1 = new rp3d::ConvexMeshShape(mConvexMesh1PolyhedronMesh); + mConvexMesh1PolyhedronMesh = mPhysicsCommon.createPolyhedronMesh(mConvexMesh1PolygonVertexArray); + mConvexMeshShape1 = mPhysicsCommon.createConvexMeshShape(mConvexMesh1PolyhedronMesh); Transform convexMeshTransform1(Vector3(10, 0, 0), Quaternion::identity()); mConvexMeshBody1 = mWorld->createCollisionBody(convexMeshTransform1); mConvexMeshProxyShape1 = mConvexMeshBody1->addCollisionShape(mConvexMeshShape1, Transform::identity()); @@ -412,8 +414,8 @@ class TestCollisionWorld : public Test { &(mConvexMeshCubeIndices[0]), sizeof(int), 6, mConvexMeshPolygonFaces, rp3d::PolygonVertexArray::VertexDataType::VERTEX_FLOAT_TYPE, rp3d::PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE); - mConvexMesh2PolyhedronMesh = new rp3d::PolyhedronMesh(mConvexMesh2PolygonVertexArray); - mConvexMeshShape2 = new rp3d::ConvexMeshShape(mConvexMesh2PolyhedronMesh); + mConvexMesh2PolyhedronMesh = mPhysicsCommon.createPolyhedronMesh(mConvexMesh2PolygonVertexArray); + mConvexMeshShape2 = mPhysicsCommon.createConvexMeshShape(mConvexMesh2PolyhedronMesh); Transform convexMeshTransform2(Vector3(20, 0, 0), Quaternion::identity()); mConvexMeshBody2 = mWorld->createCollisionBody(convexMeshTransform2); mConvexMeshProxyShape2 = mConvexMeshBody2->addCollisionShape(mConvexMeshShape2, Transform::identity()); @@ -449,9 +451,9 @@ class TestCollisionWorld : public Test { // Add the triangle vertex array of the subpart to the triangle mesh Transform concaveMeshTransform(Vector3(0, -20, 0), Quaternion::identity()); - mConcaveTriangleMesh = new TriangleMesh(); + mConcaveTriangleMesh = mPhysicsCommon.createTriangleMesh(); mConcaveTriangleMesh->addSubpart(mConcaveMeshTriangleVertexArray); - mConcaveMeshShape = new rp3d::ConcaveMeshShape(mConcaveTriangleMesh); + mConcaveMeshShape = mPhysicsCommon.createConcaveMeshShape(mConcaveTriangleMesh); mConcaveMeshBody = mWorld->createCollisionBody(concaveMeshTransform); mConcaveMeshProxyShape = mConcaveMeshBody->addCollisionShape(mConcaveMeshShape, rp3d::Transform::identity()); } @@ -459,28 +461,32 @@ class TestCollisionWorld : public Test { /// Destructor virtual ~TestCollisionWorld() { - delete mBoxShape1; - delete mBoxShape2; + mPhysicsCommon.destroyBoxShape(mBoxShape1); + mPhysicsCommon.destroyBoxShape(mBoxShape2); - delete mSphereShape1; - delete mSphereShape2; + mPhysicsCommon.destroySphereShape(mSphereShape1); + mPhysicsCommon.destroySphereShape(mSphereShape2); - delete mCapsuleShape1; - delete mCapsuleShape2; + mPhysicsCommon.destroyCapsuleShape(mCapsuleShape1); + mPhysicsCommon.destroyCapsuleShape(mCapsuleShape2); + + mPhysicsCommon.destroyConvexMeshShape(mConvexMeshShape1); + mPhysicsCommon.destroyConvexMeshShape(mConvexMeshShape2); + + mPhysicsCommon.destroyPolyhedronMesh(mConvexMesh1PolyhedronMesh); + mPhysicsCommon.destroyPolyhedronMesh(mConvexMesh2PolyhedronMesh); - delete mConvexMeshShape1; - delete mConvexMeshShape2; - delete mConvexMesh1PolyhedronMesh; - delete mConvexMesh2PolyhedronMesh; delete mConvexMesh1PolygonVertexArray; delete mConvexMesh2PolygonVertexArray; delete[] mConvexMeshPolygonFaces; - delete mConcaveMeshShape; - delete mConcaveTriangleMesh; + mPhysicsCommon.destroyConcaveMeshShape(mConcaveMeshShape); + + mPhysicsCommon.destroyTriangleMesh(mConcaveTriangleMesh); + delete mConcaveMeshTriangleVertexArray; - delete mWorld; + mPhysicsCommon.destroyCollisionWorld(mWorld); } /// Run the tests diff --git a/test/tests/collision/TestDynamicAABBTree.h b/test/tests/collision/TestDynamicAABBTree.h index 5e5033b7..5c39fb99 100755 --- a/test/tests/collision/TestDynamicAABBTree.h +++ b/test/tests/collision/TestDynamicAABBTree.h @@ -30,6 +30,7 @@ #include "Test.h" #include "collision/broadphase/DynamicAABBTree.h" #include "memory/MemoryManager.h" +#include "engine/PhysicsCommon.h" #include "utils/Profiler.h" #include @@ -57,6 +58,28 @@ class DynamicTreeRaycastCallback : public DynamicAABBTreeRaycastCallback { } }; +class DefaultTestTreeAllocator : public MemoryAllocator { + + public: + + /// Destructor + virtual ~DefaultTestTreeAllocator() override = default; + + /// Assignment operator + DefaultTestTreeAllocator& operator=(DefaultTestTreeAllocator& allocator) = default; + + /// Allocate memory of a given size (in bytes) and return a pointer to the + /// allocated memory. + virtual void* allocate(size_t size) override { + + return malloc(size); + } + + /// Release previously allocated memory. + virtual void release(void* pointer, size_t size) override { + free(pointer); + } +}; // Class TestDynamicAABBTree /** @@ -68,8 +91,9 @@ class TestDynamicAABBTree : public Test { // ---------- Atributes ---------- // + DefaultTestTreeAllocator mAllocator; + DynamicTreeRaycastCallback mRaycastCallback; - PoolAllocator mAllocator; public : @@ -99,7 +123,7 @@ class TestDynamicAABBTree : public Test { // ------------ Create tree ---------- // // Dynamic AABB Tree - DynamicAABBTree tree(MemoryManager::getBaseAllocator()); + DynamicAABBTree tree(mAllocator); #ifdef IS_PROFILING_ACTIVE /// Pointer to the profiler @@ -155,7 +179,7 @@ class TestDynamicAABBTree : public Test { // ------------- Create tree ----------- // // Dynamic AABB Tree - DynamicAABBTree tree(MemoryManager::getBaseAllocator()); + DynamicAABBTree tree(mAllocator); #ifdef IS_PROFILING_ACTIVE /// Pointer to the profiler @@ -356,7 +380,7 @@ class TestDynamicAABBTree : public Test { // ------------- Create tree ----------- // // Dynamic AABB Tree - DynamicAABBTree tree(MemoryManager::getBaseAllocator()); + DynamicAABBTree tree(mAllocator); #ifdef IS_PROFILING_ACTIVE /// Pointer to the profiler diff --git a/test/tests/collision/TestPointInside.h b/test/tests/collision/TestPointInside.h index f0b0cd1e..ba545181 100644 --- a/test/tests/collision/TestPointInside.h +++ b/test/tests/collision/TestPointInside.h @@ -33,6 +33,7 @@ #include "collision/shapes/CapsuleShape.h" #include "collision/shapes/ConvexMeshShape.h" #include "engine/CollisionWorld.h" +#include "engine/PhysicsCommon.h" #include "collision/PolygonVertexArray.h" /// Reactphysics3D namespace @@ -48,6 +49,9 @@ class TestPointInside : public Test { // ---------- Atributes ---------- // + // Physics common + PhysicsCommon mPhysicsCommon; + // Physics world CollisionWorld* mWorld; @@ -93,7 +97,7 @@ class TestPointInside : public Test { TestPointInside(const std::string& name) : Test(name) { // Create the world - mWorld = new CollisionWorld(); + mWorld = mPhysicsCommon.createCollisionWorld(); // Body transform Vector3 position(-3, 2, 7); @@ -120,13 +124,13 @@ class TestPointInside : public Test { mLocalShapeToWorld = mBodyTransform * mShapeTransform; // Create collision shapes - mBoxShape = new BoxShape(Vector3(2, 3, 4)); + mBoxShape = mPhysicsCommon.createBoxShape(Vector3(2, 3, 4)); mBoxProxyShape = mBoxBody->addCollisionShape(mBoxShape, mShapeTransform); - mSphereShape = new SphereShape(3); + mSphereShape = mPhysicsCommon.createSphereShape(3); mSphereProxyShape = mSphereBody->addCollisionShape(mSphereShape, mShapeTransform); - mCapsuleShape = new CapsuleShape(3, 10); + mCapsuleShape = mPhysicsCommon.createCapsuleShape(3, 10); mCapsuleProxyShape = mCapsuleBody->addCollisionShape(mCapsuleShape, mShapeTransform); mConvexMeshCubeVertices[0] = Vector3(-2, -3, 4); @@ -156,8 +160,8 @@ class TestPointInside : public Test { &(mConvexMeshCubeIndices[0]), sizeof(int), 6, mConvexMeshPolygonFaces, PolygonVertexArray::VertexDataType::VERTEX_FLOAT_TYPE, PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE); - mConvexMeshPolyhedronMesh = new PolyhedronMesh(mConvexMeshPolygonVertexArray); - mConvexMeshShape = new ConvexMeshShape(mConvexMeshPolyhedronMesh); + mConvexMeshPolyhedronMesh = mPhysicsCommon.createPolyhedronMesh(mConvexMeshPolygonVertexArray); + mConvexMeshShape = mPhysicsCommon.createConvexMeshShape(mConvexMeshPolyhedronMesh); Transform convexMeshTransform(Vector3(10, 0, 0), Quaternion::identity()); mConvexMeshProxyShape = mConvexMeshBody->addCollisionShape(mConvexMeshShape, mShapeTransform); @@ -172,11 +176,11 @@ class TestPointInside : public Test { /// Destructor virtual ~TestPointInside() { - delete mWorld; - delete mBoxShape; - delete mSphereShape; - delete mCapsuleShape; - delete mConvexMeshShape; + mPhysicsCommon.destroyBoxShape(mBoxShape); + mPhysicsCommon.destroySphereShape(mSphereShape); + mPhysicsCommon.destroyCapsuleShape(mCapsuleShape); + mPhysicsCommon.destroyConvexMeshShape(mConvexMeshShape); + mPhysicsCommon.destroyCollisionWorld(mWorld); delete[] mConvexMeshPolygonFaces; delete mConvexMeshPolygonVertexArray; delete mConvexMeshPolyhedronMesh; diff --git a/test/tests/collision/TestRaycast.h b/test/tests/collision/TestRaycast.h index 995108f2..09e3aba8 100644 --- a/test/tests/collision/TestRaycast.h +++ b/test/tests/collision/TestRaycast.h @@ -28,6 +28,7 @@ // Libraries #include "Test.h" +#include "engine/PhysicsCommon.h" #include "engine/CollisionWorld.h" #include "body/CollisionBody.h" #include "collision/shapes/BoxShape.h" @@ -40,6 +41,8 @@ #include "collision/TriangleMesh.h" #include "collision/TriangleVertexArray.h" #include "collision/RaycastInfo.h" +#include "collision/PolygonVertexArray.h" +#include /// Reactphysics3D namespace namespace reactphysics3d { @@ -99,6 +102,8 @@ class TestRaycast : public Test { // ---------- Atributes ---------- // + PhysicsCommon mPhysicsCommon; + // Raycast callback class WorldRaycastCallback mCallback; @@ -117,7 +122,6 @@ class TestRaycast : public Test { CollisionBody* mConvexMeshBody; CollisionBody* mCylinderBody; CollisionBody* mCompoundBody; - CollisionBody* mTriangleBody; CollisionBody* mConcaveMeshBody; CollisionBody* mHeightFieldBody; @@ -132,8 +136,7 @@ class TestRaycast : public Test { SphereShape* mSphereShape; CapsuleShape* mCapsuleShape; ConvexMeshShape* mConvexMeshShape; - TriangleShape* mTriangleShape; - ConcaveShape* mConcaveMeshShape; + ConcaveMeshShape* mConcaveMeshShape; HeightFieldShape* mHeightFieldShape; // Proxy Shapes @@ -143,12 +146,11 @@ class TestRaycast : public Test { ProxyShape* mConvexMeshProxyShape; ProxyShape* mCompoundSphereProxyShape; ProxyShape* mCompoundCapsuleProxyShape; - ProxyShape* mTriangleProxyShape; ProxyShape* mConcaveMeshProxyShape; ProxyShape* mHeightFieldProxyShape; // Triangle meshes - TriangleMesh mConcaveTriangleMesh; + TriangleMesh* mConcaveTriangleMesh; std::vector mConcaveMeshVertices; std::vector mConcaveMeshIndices; @@ -170,7 +172,7 @@ class TestRaycast : public Test { epsilon = decimal(0.0001); // Create the world - mWorld = new CollisionWorld(); + mWorld = mPhysicsCommon.createCollisionWorld(); // Body transform Vector3 position(-3, 2, 7); @@ -184,7 +186,6 @@ class TestRaycast : public Test { mConvexMeshBody = mWorld->createCollisionBody(mBodyTransform); mCylinderBody = mWorld->createCollisionBody(mBodyTransform); mCompoundBody = mWorld->createCollisionBody(mBodyTransform); - mTriangleBody = mWorld->createCollisionBody(mBodyTransform); mConcaveMeshBody = mWorld->createCollisionBody(mBodyTransform); mHeightFieldBody = mWorld->createCollisionBody(mBodyTransform); @@ -197,21 +198,13 @@ class TestRaycast : public Test { mLocalShapeToWorld = mBodyTransform * mShapeTransform; // Create collision shapes - mBoxShape = new BoxShape(Vector3(2, 3, 4)); + mBoxShape = mPhysicsCommon.createBoxShape(Vector3(2, 3, 4)); mBoxProxyShape = mBoxBody->addCollisionShape(mBoxShape, mShapeTransform); - mSphereShape = new SphereShape(3); + mSphereShape = mPhysicsCommon.createSphereShape(3); mSphereProxyShape = mSphereBody->addCollisionShape(mSphereShape, mShapeTransform); - Vector3 triangleVertices[3]; - triangleVertices[0] = Vector3(100, 100, 0); - triangleVertices[1] = Vector3(105, 100, 0); - triangleVertices[2] = Vector3(100, 103, 0); - Vector3 triangleVerticesNormals[3] = {Vector3(0, 0, 1), Vector3(0, 0, 1), Vector3(0, 0, 1)}; - mTriangleShape = new TriangleShape(triangleVertices, triangleVerticesNormals, 0, mAllocator); - mTriangleProxyShape = mTriangleBody->addCollisionShape(mTriangleShape, mShapeTransform); - - mCapsuleShape = new CapsuleShape(2, 5); + mCapsuleShape = mPhysicsCommon.createCapsuleShape(2, 5); mCapsuleProxyShape = mCapsuleBody->addCollisionShape(mCapsuleShape, mShapeTransform); mPolyhedronVertices[0] = Vector3(-2, -3, 4); @@ -244,8 +237,8 @@ class TestRaycast : public Test { PolygonVertexArray::VertexDataType::VERTEX_FLOAT_TYPE, PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE); - mPolyhedronMesh = new PolyhedronMesh(mPolygonVertexArray); - mConvexMeshShape = new ConvexMeshShape(mPolyhedronMesh); + mPolyhedronMesh = mPhysicsCommon.createPolyhedronMesh(mPolygonVertexArray); + mConvexMeshShape = mPhysicsCommon.createConvexMeshShape(mPolyhedronMesh); mConvexMeshProxyShape = mConvexMeshBody->addCollisionShape(mConvexMeshShape, mShapeTransform); // Compound shape is a cylinder and a sphere @@ -285,16 +278,15 @@ class TestRaycast : public Test { 12, &(mConcaveMeshIndices[0]), 3 * sizeof(uint), vertexType, TriangleVertexArray::IndexDataType::INDEX_INTEGER_TYPE); - // Add the triangle vertex array of the subpart to the triangle mesh - mConcaveTriangleMesh.addSubpart(mConcaveMeshVertexArray); - mConcaveMeshShape = new ConcaveMeshShape(&mConcaveTriangleMesh); + mConcaveTriangleMesh->addSubpart(mConcaveMeshVertexArray); + mConcaveMeshShape = mPhysicsCommon.createConcaveMeshShape(mConcaveTriangleMesh); mConcaveMeshProxyShape = mConcaveMeshBody->addCollisionShape(mConcaveMeshShape, mShapeTransform); // Heightfield shape (plane height field at height=4) for (int i=0; i<100; i++) mHeightFieldData[i] = 4; - mHeightFieldShape = new HeightFieldShape(10, 10, 0, 4, mHeightFieldData, HeightFieldShape::HeightDataType::HEIGHT_FLOAT_TYPE); + mHeightFieldShape = mPhysicsCommon.createHeightFieldShape(10, 10, 0, 4, mHeightFieldData, HeightFieldShape::HeightDataType::HEIGHT_FLOAT_TYPE); mHeightFieldProxyShape = mHeightFieldBody->addCollisionShape(mHeightFieldShape, mShapeTransform); // Assign proxy shapes to the different categories @@ -304,22 +296,21 @@ class TestRaycast : public Test { mConvexMeshProxyShape->setCollisionCategoryBits(CATEGORY2); mCompoundSphereProxyShape->setCollisionCategoryBits(CATEGORY2); mCompoundCapsuleProxyShape->setCollisionCategoryBits(CATEGORY2); - mTriangleProxyShape->setCollisionCategoryBits(CATEGORY1); mConcaveMeshProxyShape->setCollisionCategoryBits(CATEGORY2); mHeightFieldProxyShape->setCollisionCategoryBits(CATEGORY2); } /// Destructor virtual ~TestRaycast() { - delete mWorld; - delete mBoxShape; - delete mSphereShape; - delete mCapsuleShape; - delete mConvexMeshShape; - delete mTriangleShape; - delete mConcaveMeshShape; - delete mHeightFieldShape; + mPhysicsCommon.destroyBoxShape(mBoxShape); + mPhysicsCommon.destroySphereShape(mSphereShape); + mPhysicsCommon.destroyCapsuleShape(mCapsuleShape); + mPhysicsCommon.destroyConvexMeshShape(mConvexMeshShape); + mPhysicsCommon.destroyConcaveMeshShape(mConcaveMeshShape); + mPhysicsCommon.destroyHeightFieldShape(mHeightFieldShape); + + mPhysicsCommon.destroyCollisionWorld(mWorld); delete mConcaveMeshVertexArray; delete mPolygonVertexArray; @@ -333,7 +324,6 @@ class TestRaycast : public Test { testCapsule(); testConvexMesh(); testCompound(); - testTriangle(); testConcaveMesh(); testHeightField(); } @@ -1000,304 +990,6 @@ class TestRaycast : public Test { rp3d_test(mCallback.isHit); } - /// Test the ProxySphereShape::raycast(), CollisionBody::raycast() and - /// CollisionWorld::raycast() methods. - void testTriangle() { - - // ----- Test feedback data ----- // - Vector3 point1 = mLocalShapeToWorld * Vector3(101, 101, 400); - Vector3 point2 = mLocalShapeToWorld * Vector3(101, 101, -200); - Ray ray(point1, point2); - Ray rayBackward(point2, point1); - - Vector3 hitPoint = mLocalShapeToWorld * Vector3(101, 101, 0); - Vector3 hitNormal = mLocalShapeToWorld.getOrientation() * Vector3(0, 0, 1); - hitNormal.normalize(); - mCallback.shapeToTest = mTriangleProxyShape; - - // CollisionWorld::raycast() - mCallback.reset(); - mTriangleShape->setRaycastTestType(TriangleRaycastSide::FRONT); - mWorld->raycast(ray, &mCallback); - rp3d_test(mCallback.isHit); - rp3d_test(mCallback.raycastInfo.body == mTriangleBody); - rp3d_test(mCallback.raycastInfo.proxyShape == mTriangleProxyShape); - rp3d_test(approxEqual(mCallback.raycastInfo.hitFraction, 0.6666, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldPoint.x, hitPoint.x, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldPoint.y, hitPoint.y, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldPoint.z, hitPoint.z, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldNormal.x, hitNormal.x, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldNormal.y, hitNormal.y, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldNormal.z, hitNormal.z, epsilon)); - - mCallback.reset(); - mTriangleShape->setRaycastTestType(TriangleRaycastSide::BACK); - mWorld->raycast(rayBackward, &mCallback); - rp3d_test(mCallback.isHit); - rp3d_test(mCallback.raycastInfo.body == mTriangleBody); - rp3d_test(mCallback.raycastInfo.proxyShape == mTriangleProxyShape); - rp3d_test(approxEqual(mCallback.raycastInfo.hitFraction, 0.3333, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldPoint.x, hitPoint.x, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldPoint.y, hitPoint.y, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldPoint.z, hitPoint.z, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldNormal.x, -hitNormal.x, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldNormal.y, -hitNormal.y, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldNormal.z, -hitNormal.z, epsilon)); - - mCallback.reset(); - mTriangleShape->setRaycastTestType(TriangleRaycastSide::FRONT_AND_BACK); - mWorld->raycast(ray, &mCallback); - rp3d_test(mCallback.isHit); - rp3d_test(mCallback.raycastInfo.body == mTriangleBody); - rp3d_test(mCallback.raycastInfo.proxyShape == mTriangleProxyShape); - rp3d_test(approxEqual(mCallback.raycastInfo.hitFraction, 0.6666, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldPoint.x, hitPoint.x, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldPoint.y, hitPoint.y, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldPoint.z, hitPoint.z, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldNormal.x, hitNormal.x, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldNormal.y, hitNormal.y, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldNormal.z, hitNormal.z, epsilon)); - - mCallback.reset(); - mTriangleShape->setRaycastTestType(TriangleRaycastSide::FRONT_AND_BACK); - mWorld->raycast(rayBackward, &mCallback); - rp3d_test(mCallback.isHit); - rp3d_test(mCallback.raycastInfo.body == mTriangleBody); - rp3d_test(mCallback.raycastInfo.proxyShape == mTriangleProxyShape); - rp3d_test(approxEqual(mCallback.raycastInfo.hitFraction, 0.3333, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldPoint.x, hitPoint.x, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldPoint.y, hitPoint.y, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldPoint.z, hitPoint.z, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldNormal.x, -hitNormal.x, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldNormal.y, -hitNormal.y, epsilon)); - rp3d_test(approxEqual(mCallback.raycastInfo.worldNormal.z, -hitNormal.z, epsilon)); - - mTriangleShape->setRaycastTestType(TriangleRaycastSide::FRONT); - - // Correct category filter mask - mCallback.reset(); - mWorld->raycast(ray, &mCallback, CATEGORY1); - rp3d_test(mCallback.isHit); - - // Wrong category filter mask - mCallback.reset(); - mWorld->raycast(ray, &mCallback, CATEGORY2); - rp3d_test(!mCallback.isHit); - - // CollisionBody::raycast() - RaycastInfo raycastInfo2; - rp3d_test(mTriangleBody->raycast(ray, raycastInfo2)); - rp3d_test(raycastInfo2.body == mTriangleBody); - rp3d_test(raycastInfo2.proxyShape == mTriangleProxyShape); - rp3d_test(approxEqual(raycastInfo2.hitFraction, 0.6666, epsilon)); - rp3d_test(approxEqual(raycastInfo2.worldPoint.x, hitPoint.x, epsilon)); - rp3d_test(approxEqual(raycastInfo2.worldPoint.y, hitPoint.y, epsilon)); - rp3d_test(approxEqual(raycastInfo2.worldPoint.z, hitPoint.z, epsilon)); - - // ProxyCollisionShape::raycast() - RaycastInfo raycastInfo3; - rp3d_test(mTriangleProxyShape->raycast(ray, raycastInfo3)); - rp3d_test(raycastInfo3.body == mTriangleBody); - rp3d_test(raycastInfo3.proxyShape == mTriangleProxyShape); - rp3d_test(approxEqual(raycastInfo3.hitFraction, 0.6666, epsilon)); - rp3d_test(approxEqual(raycastInfo3.worldPoint.x, hitPoint.x, epsilon)); - rp3d_test(approxEqual(raycastInfo3.worldPoint.y, hitPoint.y, epsilon)); - rp3d_test(approxEqual(raycastInfo3.worldPoint.z, hitPoint.z, epsilon)); - - Ray ray1(mLocalShapeToWorld * Vector3(-10, 10, 4), mLocalShapeToWorld * Vector3(15, 6, -4)); - Ray ray2(mLocalShapeToWorld * Vector3(102, 107, 5), mLocalShapeToWorld * Vector3(102, 107, -5)); - Ray ray3(mLocalShapeToWorld * Vector3(106, 102, 6), mLocalShapeToWorld * Vector3(106, 102, -8)); - - Ray ray4(mLocalShapeToWorld * Vector3(100.2, 101, 5), mLocalShapeToWorld * Vector3(100.2, 101, -5)); - Ray ray5(mLocalShapeToWorld * Vector3(100.5, 101.5, 4), mLocalShapeToWorld * Vector3(100.5, 101.5, -54)); - Ray ray6(mLocalShapeToWorld * Vector3(102, 101, 1), mLocalShapeToWorld * Vector3(102, 102, -1)); - - Ray ray4Back(mLocalShapeToWorld * Vector3(100.2, 101, -5), mLocalShapeToWorld * Vector3(100.2, 101, 5)); - Ray ray5Back(mLocalShapeToWorld * Vector3(100.5, 101.5, -54), mLocalShapeToWorld * Vector3(100.5, 101.5, 4)); - Ray ray6Back(mLocalShapeToWorld * Vector3(102, 102, -1), mLocalShapeToWorld * Vector3(102, 101, 1)); - - // ----- Test raycast miss ----- // - rp3d_test(!mTriangleBody->raycast(ray1, raycastInfo3)); - rp3d_test(!mTriangleProxyShape->raycast(ray1, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray1, &mCallback); - rp3d_test(!mCallback.isHit); - mCallback.reset(); - mWorld->raycast(Ray(ray1.point1, ray1.point2, decimal(0.01)), &mCallback); - rp3d_test(!mCallback.isHit); - mCallback.reset(); - mWorld->raycast(Ray(ray1.point1, ray1.point2, decimal(100.0)), &mCallback); - rp3d_test(!mCallback.isHit); - - rp3d_test(!mTriangleBody->raycast(ray2, raycastInfo3)); - rp3d_test(!mTriangleProxyShape->raycast(ray2, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray2, &mCallback); - rp3d_test(!mCallback.isHit); - - rp3d_test(!mTriangleBody->raycast(ray3, raycastInfo3)); - rp3d_test(!mTriangleProxyShape->raycast(ray3, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray3, &mCallback); - rp3d_test(!mCallback.isHit); - - // Test backward ray against front triangles (not hit should occur) - mTriangleShape->setRaycastTestType(TriangleRaycastSide::FRONT); - - rp3d_test(!mTriangleBody->raycast(ray4Back, raycastInfo3)); - rp3d_test(!mTriangleProxyShape->raycast(ray4Back, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray4Back, &mCallback); - rp3d_test(!mCallback.isHit); - - rp3d_test(!mTriangleBody->raycast(ray5Back, raycastInfo3)); - rp3d_test(!mTriangleProxyShape->raycast(ray5Back, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray5Back, &mCallback); - rp3d_test(!mCallback.isHit); - - rp3d_test(!mTriangleBody->raycast(ray6Back, raycastInfo3)); - rp3d_test(!mTriangleProxyShape->raycast(ray6Back, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray6Back, &mCallback); - rp3d_test(!mCallback.isHit); - - // Test front ray against back triangles (not hit should occur) - mTriangleShape->setRaycastTestType(TriangleRaycastSide::BACK); - - rp3d_test(!mTriangleBody->raycast(ray4, raycastInfo3)); - rp3d_test(!mTriangleProxyShape->raycast(ray4, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray4, &mCallback); - rp3d_test(!mCallback.isHit); - - rp3d_test(!mTriangleBody->raycast(ray5, raycastInfo3)); - rp3d_test(!mTriangleProxyShape->raycast(ray5, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray5, &mCallback); - rp3d_test(!mCallback.isHit); - - rp3d_test(!mTriangleBody->raycast(ray6, raycastInfo3)); - rp3d_test(!mTriangleProxyShape->raycast(ray6, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray6, &mCallback); - rp3d_test(!mCallback.isHit); - - // ----- Test raycast hits ----- // - - // Test front ray against front triangles - mTriangleShape->setRaycastTestType(TriangleRaycastSide::FRONT); - - rp3d_test(mTriangleBody->raycast(ray4, raycastInfo3)); - rp3d_test(mTriangleProxyShape->raycast(ray4, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray4, &mCallback); - rp3d_test(mCallback.isHit); - mCallback.reset(); - mWorld->raycast(Ray(ray4.point1, ray4.point2, decimal(0.8)), &mCallback); - rp3d_test(mCallback.isHit); - - rp3d_test(mTriangleBody->raycast(ray5, raycastInfo3)); - rp3d_test(mTriangleProxyShape->raycast(ray5, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray5, &mCallback); - rp3d_test(mCallback.isHit); - mCallback.reset(); - mWorld->raycast(Ray(ray5.point1, ray5.point2, decimal(0.8)), &mCallback); - rp3d_test(mCallback.isHit); - - rp3d_test(mTriangleBody->raycast(ray6, raycastInfo3)); - rp3d_test(mTriangleProxyShape->raycast(ray6, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray6, &mCallback); - mCallback.reset(); - mWorld->raycast(Ray(ray6.point1, ray6.point2, decimal(0.8)), &mCallback); - - // Test back ray against back triangles - mTriangleShape->setRaycastTestType(TriangleRaycastSide::BACK); - - rp3d_test(mTriangleBody->raycast(ray4Back, raycastInfo3)); - rp3d_test(mTriangleProxyShape->raycast(ray4Back, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray4Back, &mCallback); - rp3d_test(mCallback.isHit); - mCallback.reset(); - mWorld->raycast(Ray(ray4Back.point1, ray4Back.point2, decimal(0.8)), &mCallback); - rp3d_test(mCallback.isHit); - - rp3d_test(mTriangleBody->raycast(ray5Back, raycastInfo3)); - rp3d_test(mTriangleProxyShape->raycast(ray5Back, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray5Back, &mCallback); - rp3d_test(mCallback.isHit); - mCallback.reset(); - mWorld->raycast(Ray(ray5Back.point1, ray5Back.point2, decimal(1.0)), &mCallback); - rp3d_test(mCallback.isHit); - - rp3d_test(mTriangleBody->raycast(ray6Back, raycastInfo3)); - rp3d_test(mTriangleProxyShape->raycast(ray6Back, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray6Back, &mCallback); - mCallback.reset(); - mWorld->raycast(Ray(ray6Back.point1, ray6Back.point2, decimal(0.8)), &mCallback); - - // Test front ray against front-back triangles - mTriangleShape->setRaycastTestType(TriangleRaycastSide::FRONT_AND_BACK); - - rp3d_test(mTriangleBody->raycast(ray4, raycastInfo3)); - rp3d_test(mTriangleProxyShape->raycast(ray4, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray4, &mCallback); - rp3d_test(mCallback.isHit); - mCallback.reset(); - mWorld->raycast(Ray(ray4.point1, ray4.point2, decimal(0.8)), &mCallback); - rp3d_test(mCallback.isHit); - - rp3d_test(mTriangleBody->raycast(ray5, raycastInfo3)); - rp3d_test(mTriangleProxyShape->raycast(ray5, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray5, &mCallback); - rp3d_test(mCallback.isHit); - mCallback.reset(); - mWorld->raycast(Ray(ray5.point1, ray5.point2, decimal(0.8)), &mCallback); - rp3d_test(mCallback.isHit); - - rp3d_test(mTriangleBody->raycast(ray6, raycastInfo3)); - rp3d_test(mTriangleProxyShape->raycast(ray6, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray6, &mCallback); - mCallback.reset(); - mWorld->raycast(Ray(ray6.point1, ray6.point2, decimal(0.8)), &mCallback); - - // Test back ray against front-back triangles - mTriangleShape->setRaycastTestType(TriangleRaycastSide::FRONT_AND_BACK); - - rp3d_test(mTriangleBody->raycast(ray4Back, raycastInfo3)); - rp3d_test(mTriangleProxyShape->raycast(ray4Back, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray4Back, &mCallback); - rp3d_test(mCallback.isHit); - mCallback.reset(); - mWorld->raycast(Ray(ray4Back.point1, ray4Back.point2, decimal(0.8)), &mCallback); - rp3d_test(mCallback.isHit); - - rp3d_test(mTriangleBody->raycast(ray5Back, raycastInfo3)); - rp3d_test(mTriangleProxyShape->raycast(ray5Back, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray5Back, &mCallback); - rp3d_test(mCallback.isHit); - mCallback.reset(); - mWorld->raycast(Ray(ray5Back.point1, ray5Back.point2, decimal(1.0)), &mCallback); - rp3d_test(mCallback.isHit); - - rp3d_test(mTriangleBody->raycast(ray6Back, raycastInfo3)); - rp3d_test(mTriangleProxyShape->raycast(ray6Back, raycastInfo3)); - mCallback.reset(); - mWorld->raycast(ray6Back, &mCallback); - mCallback.reset(); - mWorld->raycast(Ray(ray6Back.point1, ray6Back.point2, decimal(0.8)), &mCallback); - } - /// Test the ProxyConvexMeshShape::raycast(), CollisionBody::raycast() and /// CollisionWorld::raycast() methods. void testConvexMesh() { diff --git a/testbed/CMakeLists.txt b/testbed/CMakeLists.txt index 7799ca0b..038ff1e4 100755 --- a/testbed/CMakeLists.txt +++ b/testbed/CMakeLists.txt @@ -116,6 +116,8 @@ SET(SCENES_SOURCES scenes/heightfield/HeightFieldScene.cpp scenes/cubestack/CubeStackScene.h scenes/cubestack/CubeStackScene.cpp + scenes/pile/PileScene.h + scenes/pile/PileScene.cpp ) # Add .user file to set debug path in Visual Studio diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index 8d55eed9..16a6c1a1 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -38,9 +38,9 @@ openglframework::VertexArrayObject Box::mVAO; int Box::totalNbBoxes = 0; // Constructor -Box::Box(const openglframework::Vector3& size, reactphysics3d::CollisionWorld* world, +Box::Box(const openglframework::Vector3& size, reactphysics3d::PhysicsCommon& physicsCommon, reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath) - : PhysicsObject(meshFolderPath + "cube.obj") { + : PhysicsObject(physicsCommon, meshFolderPath + "cube.obj") { // Initialize the size of the box mSize[0] = size.x * 0.5f; @@ -56,7 +56,7 @@ Box::Box(const openglframework::Vector3& size, reactphysics3d::CollisionWorld* w // Create the collision shape for the rigid body (box shape) // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - mBoxShape = new rp3d::BoxShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); + mBoxShape = mPhysicsCommon.createBoxShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); //mBoxShape->setLocalScaling(rp3d::Vector3(2, 2, 2)); mPreviousTransform = rp3d::Transform::identity(); @@ -80,9 +80,9 @@ Box::Box(const openglframework::Vector3& size, reactphysics3d::CollisionWorld* w } // Constructor -Box::Box(const openglframework::Vector3& size, float mass, reactphysics3d::DynamicsWorld* world, +Box::Box(const openglframework::Vector3& size, float mass, reactphysics3d::PhysicsCommon &physicsCommon, reactphysics3d::DynamicsWorld* world, const std::string& meshFolderPath) - : PhysicsObject(meshFolderPath + "cube.obj") { + : PhysicsObject(physicsCommon, meshFolderPath + "cube.obj") { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshFolderPath + "cube.obj", *this); @@ -104,7 +104,7 @@ Box::Box(const openglframework::Vector3& size, float mass, reactphysics3d::Dynam // Create the collision shape for the rigid body (box shape) // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - mBoxShape = new rp3d::BoxShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); + mBoxShape = mPhysicsCommon.createBoxShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2])); mPreviousTransform = rp3d::Transform::identity(); @@ -138,7 +138,7 @@ Box::~Box() { mVBONormals.destroy(); mVAO.destroy(); } - delete mBoxShape; + mPhysicsCommon.destroyBoxShape(mBoxShape); totalNbBoxes--; } diff --git a/testbed/common/Box.h b/testbed/common/Box.h index 21fe0ed1..66dc6430 100644 --- a/testbed/common/Box.h +++ b/testbed/common/Box.h @@ -75,10 +75,11 @@ class Box : public PhysicsObject { // -------------------- Methods -------------------- // /// Constructor - Box(const openglframework::Vector3& size, reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath); + Box(const openglframework::Vector3& size, reactphysics3d::PhysicsCommon& physicsCommon, + reactphysics3d::CollisionWorld* world, const std::string& meshFolderPath); /// Constructor - Box(const openglframework::Vector3& size, float mass, reactphysics3d::DynamicsWorld *world, const std::string& meshFolderPath); + Box(const openglframework::Vector3& size, float mass, reactphysics3d::PhysicsCommon& physicsCommon, reactphysics3d::DynamicsWorld *world, const std::string& meshFolderPath); /// Destructor ~Box(); diff --git a/testbed/common/Capsule.cpp b/testbed/common/Capsule.cpp index f2ee3e52..3140d40e 100644 --- a/testbed/common/Capsule.cpp +++ b/testbed/common/Capsule.cpp @@ -34,8 +34,8 @@ openglframework::VertexArrayObject Capsule::mVAO; int Capsule::totalNbCapsules = 0; // Constructor -Capsule::Capsule(float radius, float height, rp3d::CollisionWorld* world, const std::string& meshFolderPath) - : PhysicsObject(meshFolderPath + "capsule.obj"), mRadius(radius), mHeight(height) { +Capsule::Capsule(float radius, float height, rp3d::PhysicsCommon& physicsCommon, rp3d::CollisionWorld* world, const std::string& meshFolderPath) + : PhysicsObject(physicsCommon, meshFolderPath + "capsule.obj"), mRadius(radius), mHeight(height) { // Compute the scaling matrix mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, @@ -46,7 +46,7 @@ Capsule::Capsule(float radius, float height, rp3d::CollisionWorld* world, const // Create the collision shape for the rigid body (sphere shape) // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - mCapsuleShape = new rp3d::CapsuleShape(mRadius, mHeight); + mCapsuleShape = mPhysicsCommon.createCapsuleShape(mRadius, mHeight); //mCapsuleShape->setLocalScaling(rp3d::Vector3(2, 2, 2)); mPreviousTransform = rp3d::Transform::identity(); @@ -68,9 +68,9 @@ Capsule::Capsule(float radius, float height, rp3d::CollisionWorld* world, const } // Constructor -Capsule::Capsule(float radius, float height, float mass, rp3d::DynamicsWorld* dynamicsWorld, +Capsule::Capsule(float radius, float height, float mass, reactphysics3d::PhysicsCommon &physicsCommon, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath) - : PhysicsObject(meshFolderPath + "capsule.obj"), mRadius(radius), mHeight(height) { + : PhysicsObject(physicsCommon, meshFolderPath + "capsule.obj"), mRadius(radius), mHeight(height) { // Compute the scaling matrix mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, @@ -83,7 +83,7 @@ Capsule::Capsule(float radius, float height, float mass, rp3d::DynamicsWorld* dy // Create the collision shape for the rigid body (sphere shape) // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - mCapsuleShape = new rp3d::CapsuleShape(mRadius, mHeight); + mCapsuleShape = mPhysicsCommon.createCapsuleShape(mRadius, mHeight); // Create a rigid body corresponding in the dynamics world rp3d::RigidBody* body = dynamicsWorld->createRigidBody(mPreviousTransform); @@ -118,7 +118,7 @@ Capsule::~Capsule() { mVBOTextureCoords.destroy(); mVAO.destroy(); } - delete mCapsuleShape; + mPhysicsCommon.destroyCapsuleShape(mCapsuleShape); totalNbCapsules--; } diff --git a/testbed/common/Capsule.h b/testbed/common/Capsule.h index 1591f247..f53a0073 100644 --- a/testbed/common/Capsule.h +++ b/testbed/common/Capsule.h @@ -82,10 +82,10 @@ class Capsule : public PhysicsObject { // -------------------- Methods -------------------- // /// Constructor - Capsule(float radius, float height, rp3d::CollisionWorld* world, const std::string& meshFolderPath); + Capsule(float radius, float height, reactphysics3d::PhysicsCommon &physicsCommon, rp3d::CollisionWorld* world, const std::string& meshFolderPath); /// Constructor - Capsule(float radius, float height, float mass, rp3d::DynamicsWorld* dynamicsWorld, + Capsule(float radius, float height, float mass, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); /// Destructor diff --git a/testbed/common/ConcaveMesh.cpp b/testbed/common/ConcaveMesh.cpp index 487312b0..f4a452f2 100644 --- a/testbed/common/ConcaveMesh.cpp +++ b/testbed/common/ConcaveMesh.cpp @@ -27,14 +27,18 @@ #include "ConcaveMesh.h" // Constructor -ConcaveMesh::ConcaveMesh(rp3d::CollisionWorld* world, const std::string& meshPath) - : PhysicsObject(meshPath), mVBOVertices(GL_ARRAY_BUFFER), +ConcaveMesh::ConcaveMesh(rp3d::PhysicsCommon& physicsCommon, rp3d::CollisionWorld* world, const std::string& meshPath) + : PhysicsObject(physicsCommon, meshPath), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { + mPhysicsTriangleMesh = mPhysicsCommon.createTriangleMesh(); + // Compute the scaling matrix mScalingMatrix = openglframework::Matrix4::identity(); + mPhysicsTriangleMesh = mPhysicsCommon.createTriangleMesh(); + // For each subpart of the mesh for (unsigned int i=0; iaddSubpart(vertexArray); } // Create the collision shape for the rigid body (convex mesh shape) and // do not forget to delete it at the end - mConcaveShape = new rp3d::ConcaveMeshShape(&mPhysicsTriangleMesh); + mConcaveShape = mPhysicsCommon.createConcaveMeshShape(mPhysicsTriangleMesh); mPreviousTransform = rp3d::Transform::identity(); @@ -68,14 +72,16 @@ ConcaveMesh::ConcaveMesh(rp3d::CollisionWorld* world, const std::string& meshPat } // Constructor -ConcaveMesh::ConcaveMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath) - : PhysicsObject(meshPath), mVBOVertices(GL_ARRAY_BUFFER), +ConcaveMesh::ConcaveMesh(float mass, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath) + : PhysicsObject(physicsCommon, meshPath), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { // Compute the scaling matrix mScalingMatrix = openglframework::Matrix4::identity(); + mPhysicsTriangleMesh = mPhysicsCommon.createTriangleMesh(); + // For each subpart of the mesh for (unsigned int i=0; iaddSubpart(vertexArray); } // Create the collision shape for the rigid body (convex mesh shape) and // do not forget to delete it at the end - mConcaveShape = new rp3d::ConcaveMeshShape(&mPhysicsTriangleMesh); + mConcaveShape = mPhysicsCommon.createConcaveMeshShape(mPhysicsTriangleMesh); mPreviousTransform = rp3d::Transform::identity(); @@ -114,8 +120,8 @@ ConcaveMesh::ConcaveMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const s ConcaveMesh::~ConcaveMesh() { // Destroy the triangle mesh data for the physics engine - for (unsigned int i=0; igetNbSubparts(); i++) { + delete mPhysicsTriangleMesh->getSubpart(i); } // Destroy the mesh @@ -128,7 +134,7 @@ ConcaveMesh::~ConcaveMesh() { mVBOTextureCoords.destroy(); mVAO.destroy(); - delete mConcaveShape; + mPhysicsCommon.destroyConcaveMeshShape(mConcaveShape); } // Render the sphere at the correct position and with the correct orientation diff --git a/testbed/common/ConcaveMesh.h b/testbed/common/ConcaveMesh.h index 21d40082..0befd75c 100644 --- a/testbed/common/ConcaveMesh.h +++ b/testbed/common/ConcaveMesh.h @@ -64,7 +64,7 @@ class ConcaveMesh : public PhysicsObject { openglframework::VertexArrayObject mVAO; /// Structure with pointer to the shared mesh data (vertices, indices, ...) - rp3d::TriangleMesh mPhysicsTriangleMesh; + rp3d::TriangleMesh* mPhysicsTriangleMesh; // -------------------- Methods -------------------- // @@ -76,10 +76,10 @@ class ConcaveMesh : public PhysicsObject { // -------------------- Methods -------------------- // /// Constructor - ConcaveMesh(rp3d::CollisionWorld* world, const std::string& meshPath); + ConcaveMesh(reactphysics3d::PhysicsCommon& physicsCommon, rp3d::CollisionWorld* world, const std::string& meshPath); /// Constructor - ConcaveMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath); + ConcaveMesh(float mass, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath); /// Destructor ~ConcaveMesh(); diff --git a/testbed/common/ConvexMesh.cpp b/testbed/common/ConvexMesh.cpp index c676d165..d29ce40b 100644 --- a/testbed/common/ConvexMesh.cpp +++ b/testbed/common/ConvexMesh.cpp @@ -27,8 +27,8 @@ #include "ConvexMesh.h" // Constructor -ConvexMesh::ConvexMesh(rp3d::CollisionWorld* world, const std::string& meshPath) - : PhysicsObject(meshPath), mVBOVertices(GL_ARRAY_BUFFER), +ConvexMesh::ConvexMesh(rp3d::PhysicsCommon& physicsCommon, rp3d::CollisionWorld* world, const std::string& meshPath) + : PhysicsObject(physicsCommon, meshPath), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { @@ -53,11 +53,11 @@ ConvexMesh::ConvexMesh(rp3d::CollisionWorld* world, const std::string& meshPath) rp3d::PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE); // Create the polyhedron mesh - mPolyhedronMesh = new rp3d::PolyhedronMesh(mPolygonVertexArray); + mPolyhedronMesh = mPhysicsCommon.createPolyhedronMesh(mPolygonVertexArray); // Create the collision shape for the rigid body (convex mesh shape) and // do not forget to delete it at the end - mConvexShape = new rp3d::ConvexMeshShape(mPolyhedronMesh); + mConvexShape = mPhysicsCommon.createConvexMeshShape(mPolyhedronMesh); mPreviousTransform = rp3d::Transform::identity(); @@ -74,8 +74,8 @@ ConvexMesh::ConvexMesh(rp3d::CollisionWorld* world, const std::string& meshPath) } // Constructor -ConvexMesh::ConvexMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath) - : PhysicsObject(meshPath), mVBOVertices(GL_ARRAY_BUFFER), +ConvexMesh::ConvexMesh(float mass, rp3d::PhysicsCommon& physicsCommon, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath) + : PhysicsObject(physicsCommon, meshPath), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { @@ -100,11 +100,11 @@ ConvexMesh::ConvexMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std rp3d::PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE); // Create the polyhedron mesh - mPolyhedronMesh = new rp3d::PolyhedronMesh(mPolygonVertexArray); + mPolyhedronMesh = mPhysicsCommon.createPolyhedronMesh(mPolygonVertexArray); // Create the collision shape for the rigid body (convex mesh shape) and do // not forget to delete it at the end - mConvexShape = new rp3d::ConvexMeshShape(mPolyhedronMesh); + mConvexShape = mPhysicsCommon.createConvexMeshShape(mPolyhedronMesh); mPreviousTransform = rp3d::Transform::identity(); @@ -135,10 +135,10 @@ ConvexMesh::~ConvexMesh() { mVBOTextureCoords.destroy(); mVAO.destroy(); - delete mPolyhedronMesh; + mPhysicsCommon.destroyConvexMeshShape(mConvexShape); + mPhysicsCommon.destroyPolyhedronMesh(mPolyhedronMesh); delete mPolygonVertexArray; delete[] mPolygonFaces; - delete mConvexShape; } // Render the sphere at the correct position and with the correct orientation diff --git a/testbed/common/ConvexMesh.h b/testbed/common/ConvexMesh.h index cc8c1599..56019d0f 100644 --- a/testbed/common/ConvexMesh.h +++ b/testbed/common/ConvexMesh.h @@ -79,10 +79,10 @@ class ConvexMesh : public PhysicsObject { // -------------------- Methods -------------------- // /// Constructor - ConvexMesh(rp3d::CollisionWorld* world, const std::string& meshPath); + ConvexMesh(rp3d::PhysicsCommon& physicsCommon, rp3d::CollisionWorld* world, const std::string& meshPath); /// Constructor - ConvexMesh(float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath); + ConvexMesh(float mass, rp3d::PhysicsCommon& physicsCommon, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshPath); /// Destructor ~ConvexMesh(); diff --git a/testbed/common/Dumbbell.cpp b/testbed/common/Dumbbell.cpp index 111f63e2..65484c65 100644 --- a/testbed/common/Dumbbell.cpp +++ b/testbed/common/Dumbbell.cpp @@ -34,8 +34,8 @@ openglframework::VertexArrayObject Dumbbell::mVAO; int Dumbbell::totalNbDumbbells = 0; // Constructor -Dumbbell::Dumbbell(rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath) - : PhysicsObject(meshFolderPath + "dumbbell.obj") { +Dumbbell::Dumbbell(rp3d::PhysicsCommon& physicsCommon, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath) + : PhysicsObject(physicsCommon, meshFolderPath + "dumbbell.obj") { // Identity scaling matrix mScalingMatrix.setToIdentity(); @@ -47,7 +47,7 @@ Dumbbell::Dumbbell(rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFo // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() const rp3d::decimal radiusSphere = rp3d::decimal(1.5); const rp3d::decimal massSphere = rp3d::decimal(2.0); - mSphereShape = new rp3d::SphereShape(radiusSphere); + mSphereShape = mPhysicsCommon.createSphereShape(radiusSphere); // Create a capsule collision shape for the middle of the dumbbell // ReactPhysics3D will clone this object to create an internal one. Therefore, @@ -55,7 +55,7 @@ Dumbbell::Dumbbell(rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFo const rp3d::decimal radiusCapsule = rp3d::decimal(0.5); const rp3d::decimal heightCapsule = rp3d::decimal(7.0); const rp3d::decimal massCylinder = rp3d::decimal(1.0); - mCapsuleShape = new rp3d::CapsuleShape(radiusCapsule, heightCapsule); + mCapsuleShape = mPhysicsCommon.createCapsuleShape(radiusCapsule, heightCapsule); mPreviousTransform = rp3d::Transform::identity(); @@ -89,8 +89,8 @@ Dumbbell::Dumbbell(rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFo } // Constructor -Dumbbell::Dumbbell(rp3d::CollisionWorld* world, const std::string& meshFolderPath) - : PhysicsObject(meshFolderPath + "dumbbell.obj"){ +Dumbbell::Dumbbell(reactphysics3d::PhysicsCommon &physicsCommon, rp3d::CollisionWorld* world, const std::string& meshFolderPath) + : PhysicsObject(physicsCommon, meshFolderPath + "dumbbell.obj"){ // Identity scaling matrix mScalingMatrix.setToIdentity(); @@ -101,14 +101,14 @@ Dumbbell::Dumbbell(rp3d::CollisionWorld* world, const std::string& meshFolderPat // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() const rp3d::decimal radiusSphere = rp3d::decimal(1.5); - mSphereShape = new rp3d::SphereShape(radiusSphere); + mSphereShape = mPhysicsCommon.createSphereShape(radiusSphere); // Create a cylinder collision shape for the middle of the dumbbell // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() const rp3d::decimal radiusCapsule = rp3d::decimal(0.5); const rp3d::decimal heightCapsule = rp3d::decimal(7.0); - mCapsuleShape = new rp3d::CapsuleShape(radiusCapsule, heightCapsule); + mCapsuleShape = mPhysicsCommon.createCapsuleShape(radiusCapsule, heightCapsule); // Initial transform of the first sphere collision shape of the dumbbell (in local-space) rp3d::Transform transformSphereShape1(rp3d::Vector3(0, mDistanceBetweenSphere / 2.0f, 0), rp3d::Quaternion::identity()); @@ -154,8 +154,8 @@ Dumbbell::~Dumbbell() { mVBOTextureCoords.destroy(); mVAO.destroy(); } - delete mSphereShape; - delete mCapsuleShape; + mPhysicsCommon.destroySphereShape(mSphereShape); + mPhysicsCommon.destroyCapsuleShape(mCapsuleShape); totalNbDumbbells--; } diff --git a/testbed/common/Dumbbell.h b/testbed/common/Dumbbell.h index 8044e434..949d0f63 100644 --- a/testbed/common/Dumbbell.h +++ b/testbed/common/Dumbbell.h @@ -82,10 +82,10 @@ class Dumbbell : public PhysicsObject { // -------------------- Methods -------------------- // /// Constructor - Dumbbell(rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); + Dumbbell(reactphysics3d::PhysicsCommon& physicsCommon, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); /// Constructor - Dumbbell(rp3d::CollisionWorld* world, const std::string& meshFolderPath); + Dumbbell(reactphysics3d::PhysicsCommon& physicsCommon, rp3d::CollisionWorld* world, const std::string& meshFolderPath); /// Destructor ~Dumbbell(); diff --git a/testbed/common/HeightField.cpp b/testbed/common/HeightField.cpp index e9aee55a..6966c018 100644 --- a/testbed/common/HeightField.cpp +++ b/testbed/common/HeightField.cpp @@ -28,8 +28,8 @@ #include "PerlinNoise.h" // Constructor -HeightField::HeightField(rp3d::CollisionWorld* world) - : mVBOVertices(GL_ARRAY_BUFFER), +HeightField::HeightField(rp3d::PhysicsCommon& physicsCommon, rp3d::CollisionWorld* world) + : PhysicsObject(physicsCommon), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { @@ -44,7 +44,7 @@ HeightField::HeightField(rp3d::CollisionWorld* world) // Create the collision shape for the rigid body (convex mesh shape) and // do not forget to delete it at the end - mHeightFieldShape = new rp3d::HeightFieldShape(NB_POINTS_WIDTH, NB_POINTS_LENGTH, mMinHeight, mMaxHeight, + mHeightFieldShape = mPhysicsCommon.createHeightFieldShape(NB_POINTS_WIDTH, NB_POINTS_LENGTH, mMinHeight, mMaxHeight, mHeightData, rp3d::HeightFieldShape::HeightDataType::HEIGHT_FLOAT_TYPE); mPreviousTransform = rp3d::Transform::identity(); @@ -62,8 +62,8 @@ HeightField::HeightField(rp3d::CollisionWorld* world) } // Constructor -HeightField::HeightField(float mass, rp3d::DynamicsWorld* dynamicsWorld) - : mVBOVertices(GL_ARRAY_BUFFER), +HeightField::HeightField(float mass, reactphysics3d::PhysicsCommon& physicsCommon, rp3d::DynamicsWorld* dynamicsWorld) + : PhysicsObject(physicsCommon), mVBOVertices(GL_ARRAY_BUFFER), mVBONormals(GL_ARRAY_BUFFER), mVBOTextureCoords(GL_ARRAY_BUFFER), mVBOIndices(GL_ELEMENT_ARRAY_BUFFER) { @@ -78,7 +78,7 @@ HeightField::HeightField(float mass, rp3d::DynamicsWorld* dynamicsWorld) // Create the collision shape for the rigid body (convex mesh shape) and // do not forget to delete it at the end - mHeightFieldShape = new rp3d::HeightFieldShape(NB_POINTS_WIDTH, NB_POINTS_LENGTH, mMinHeight, mMaxHeight, + mHeightFieldShape = mPhysicsCommon.createHeightFieldShape(NB_POINTS_WIDTH, NB_POINTS_LENGTH, mMinHeight, mMaxHeight, mHeightData, rp3d::HeightFieldShape::HeightDataType::HEIGHT_FLOAT_TYPE); mPreviousTransform = rp3d::Transform::identity(); @@ -110,7 +110,7 @@ HeightField::~HeightField() { mVBOTextureCoords.destroy(); mVAO.destroy(); - delete mHeightFieldShape; + mPhysicsCommon.destroyHeightFieldShape(mHeightFieldShape); } // Render the sphere at the correct position and with the correct orientation diff --git a/testbed/common/HeightField.h b/testbed/common/HeightField.h index e68c8388..16994d62 100644 --- a/testbed/common/HeightField.h +++ b/testbed/common/HeightField.h @@ -89,10 +89,10 @@ class HeightField : public PhysicsObject { // -------------------- Methods -------------------- // /// Constructor - HeightField(rp3d::CollisionWorld* world); + HeightField(reactphysics3d::PhysicsCommon& physicsCommon, rp3d::CollisionWorld* world); /// Constructor - HeightField(float mass, rp3d::DynamicsWorld* dynamicsWorld); + HeightField(float mass, rp3d::PhysicsCommon& physicsCommon, rp3d::DynamicsWorld* dynamicsWorld); /// Destructor ~HeightField(); diff --git a/testbed/common/PhysicsObject.cpp b/testbed/common/PhysicsObject.cpp index 7f5a8ba2..d511beb9 100644 --- a/testbed/common/PhysicsObject.cpp +++ b/testbed/common/PhysicsObject.cpp @@ -27,7 +27,8 @@ #include "PhysicsObject.h" /// Constructor -PhysicsObject::PhysicsObject() : openglframework::Mesh() { +PhysicsObject::PhysicsObject(rp3d::PhysicsCommon& physicsCommon) + : openglframework::Mesh(), mPhysicsCommon(physicsCommon) { mBody = nullptr; mColor = openglframework::Color(1, 1, 1, 1); @@ -35,7 +36,7 @@ PhysicsObject::PhysicsObject() : openglframework::Mesh() { } /// Constructor -PhysicsObject::PhysicsObject(const std::string& meshPath) : PhysicsObject() { +PhysicsObject::PhysicsObject(rp3d::PhysicsCommon& physicsCommon, const std::string& meshPath) : PhysicsObject(physicsCommon) { // Load the mesh from a file openglframework::MeshReaderWriter::loadMeshFromFile(meshPath, *this); diff --git a/testbed/common/PhysicsObject.h b/testbed/common/PhysicsObject.h index 31e01c4f..444e9962 100644 --- a/testbed/common/PhysicsObject.h +++ b/testbed/common/PhysicsObject.h @@ -35,6 +35,9 @@ class PhysicsObject : public openglframework::Mesh { protected: + /// Reference to the physics common object + rp3d::PhysicsCommon& mPhysicsCommon; + /// Body used to simulate the dynamics of the box rp3d::CollisionBody* mBody; @@ -54,10 +57,10 @@ class PhysicsObject : public openglframework::Mesh { public: /// Constructor - PhysicsObject(); + PhysicsObject(rp3d::PhysicsCommon& physicsCommon); /// Constructor - PhysicsObject(const std::string& meshPath); + PhysicsObject(rp3d::PhysicsCommon& physicsCommon, const std::string& meshPath); /// Update the transform matrix of the object virtual void updateTransform(float interpolationFactor)=0; diff --git a/testbed/common/Sphere.cpp b/testbed/common/Sphere.cpp index ce8509e8..a758ef40 100644 --- a/testbed/common/Sphere.cpp +++ b/testbed/common/Sphere.cpp @@ -34,9 +34,9 @@ openglframework::VertexArrayObject Sphere::mVAO; int Sphere::totalNbSpheres = 0; // Constructor -Sphere::Sphere(float radius, rp3d::CollisionWorld* world, +Sphere::Sphere(float radius, rp3d::PhysicsCommon& physicsCommon, rp3d::CollisionWorld* world, const std::string& meshFolderPath) - : PhysicsObject(meshFolderPath + "sphere.obj"), mRadius(radius) { + : PhysicsObject(physicsCommon, meshFolderPath + "sphere.obj"), mRadius(radius) { // Compute the scaling matrix mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, @@ -47,7 +47,7 @@ Sphere::Sphere(float radius, rp3d::CollisionWorld* world, // Create the collision shape for the rigid body (sphere shape) // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - mCollisionShape = new rp3d::SphereShape(mRadius); + mCollisionShape = mPhysicsCommon.createSphereShape(mRadius); //mCollisionShape->setLocalScaling(rp3d::Vector3(2, 2, 2)); mPreviousTransform = rp3d::Transform::identity(); @@ -69,9 +69,9 @@ Sphere::Sphere(float radius, rp3d::CollisionWorld* world, } // Constructor -Sphere::Sphere(float radius, float mass, reactphysics3d::DynamicsWorld* world, +Sphere::Sphere(float radius, float mass, rp3d::PhysicsCommon& physicsCommon,reactphysics3d::DynamicsWorld* world, const std::string& meshFolderPath) - : PhysicsObject(meshFolderPath + "sphere.obj"), mRadius(radius) { + : PhysicsObject(physicsCommon, meshFolderPath + "sphere.obj"), mRadius(radius) { // Compute the scaling matrix mScalingMatrix = openglframework::Matrix4(mRadius, 0, 0, 0, @@ -82,7 +82,7 @@ Sphere::Sphere(float radius, float mass, reactphysics3d::DynamicsWorld* world, // Create the collision shape for the rigid body (sphere shape) // ReactPhysics3D will clone this object to create an internal one. Therefore, // it is OK if this object is destroyed right after calling RigidBody::addCollisionShape() - mCollisionShape = new rp3d::SphereShape(mRadius); + mCollisionShape = mPhysicsCommon.createSphereShape(mRadius); mPreviousTransform = rp3d::Transform::identity(); @@ -118,7 +118,7 @@ Sphere::~Sphere() { mVBOTextureCoords.destroy(); mVAO.destroy(); } - delete mCollisionShape; + mPhysicsCommon.destroySphereShape(mCollisionShape); totalNbSpheres--; } diff --git a/testbed/common/Sphere.h b/testbed/common/Sphere.h index e1ba6ed6..e23cddea 100644 --- a/testbed/common/Sphere.h +++ b/testbed/common/Sphere.h @@ -79,10 +79,10 @@ class Sphere : public PhysicsObject { // -------------------- Methods -------------------- // /// Constructor - Sphere(float radius, rp3d::CollisionWorld* world, const std::string& meshFolderPath); + Sphere(float radius, rp3d::PhysicsCommon& physicsCommon, rp3d::CollisionWorld* world, const std::string& meshFolderPath); /// Constructor - Sphere(float radius, float mass, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); + Sphere(float radius, float mass, reactphysics3d::PhysicsCommon &physicsCommon, rp3d::DynamicsWorld* dynamicsWorld, const std::string& meshFolderPath); /// Destructor ~Sphere(); diff --git a/testbed/meshes/sandbox.obj b/testbed/meshes/sandbox.obj new file mode 100644 index 00000000..38dbc99d --- /dev/null +++ b/testbed/meshes/sandbox.obj @@ -0,0 +1,116 @@ +# Blender v2.79 (sub 0) OBJ File: '' +# www.blender.org +v -31.880749 -0.589469 22.622011 +v -25.786182 -0.589469 22.622011 +v -19.691614 -0.589469 22.622011 +v -13.597046 -0.589469 22.622011 +v -7.502479 -0.589469 22.622011 +v -1.407912 -0.589469 22.622011 +v 4.686658 -0.589469 22.622011 +v 10.781222 -0.589469 22.622011 +v -31.880749 -0.589469 16.527445 +v -25.786182 -0.589469 16.527445 +v -19.691614 -0.589469 16.527445 +v -13.597046 -0.589469 16.527445 +v -7.502479 -0.589469 16.527445 +v -1.407912 -0.589469 16.527445 +v 4.686658 -0.589469 16.527445 +v 10.781222 -0.589469 16.527445 +v -31.880749 -0.589469 10.432877 +v -25.786182 -0.589469 10.432877 +v -19.691614 -13.260081 10.432877 +v -13.597046 -13.260081 10.432877 +v -7.502479 -13.260081 10.432877 +v -1.407912 -13.260081 10.432877 +v 4.686658 -13.260081 10.432877 +v 10.781222 -0.589469 10.432877 +v -31.880749 -0.589469 4.338308 +v -25.786182 -0.589469 4.338308 +v -19.691614 -13.260081 4.338308 +v -13.597046 -13.260081 4.338308 +v -7.502479 -13.260081 4.338308 +v -1.407912 -13.260081 4.338308 +v 4.686658 -13.260081 4.338308 +v 10.781222 -0.589469 4.338308 +v -31.880749 -0.589469 -1.756259 +v -25.786182 -0.589469 -1.756259 +v -19.691614 -13.260081 -1.756259 +v -13.597046 -13.260081 -1.756259 +v -7.502479 -13.260081 -1.756259 +v -1.407912 -13.260081 -1.756259 +v 4.686658 -13.260081 -1.756259 +v 10.781222 -0.589469 -1.756259 +v -31.880749 -0.589469 -7.850826 +v -25.786182 -0.589469 -7.850826 +v -19.691614 -13.260081 -7.850826 +v -13.597046 -13.260081 -7.850826 +v -7.502479 -13.260081 -7.850826 +v -1.407912 -13.260081 -7.850826 +v 4.686658 -13.260081 -7.850826 +v 10.781222 -0.589469 -7.850826 +v -31.880749 -0.589469 -13.945395 +v -25.786182 -0.589469 -13.945395 +v -19.691614 -0.589469 -13.945395 +v -13.597046 -0.589469 -13.945395 +v -7.502479 -0.589469 -13.945395 +v -1.407912 -0.589469 -13.945395 +v 4.686658 -0.589469 -13.945395 +v 10.781222 -0.589469 -13.945395 +v -31.880749 -0.589469 -20.039961 +v -25.786182 -0.589469 -20.039961 +v -19.691614 -0.589469 -20.039961 +v -13.597046 -0.589469 -20.039961 +v -7.502479 -0.589469 -20.039961 +v -1.407912 -0.589469 -20.039961 +v 4.686658 -0.589469 -20.039961 +v 10.781222 -0.589469 -20.039961 +s off +f 1 2 10 9 +f 2 3 11 10 +f 3 4 12 11 +f 4 5 13 12 +f 5 6 14 13 +f 6 7 15 14 +f 7 8 16 15 +f 9 10 18 17 +f 10 11 19 18 +f 11 12 20 19 +f 12 13 21 20 +f 13 14 22 21 +f 14 15 23 22 +f 15 16 24 23 +f 17 18 26 25 +f 18 19 27 26 +f 19 20 28 27 +f 20 21 29 28 +f 21 22 30 29 +f 22 23 31 30 +f 23 24 32 31 +f 25 26 34 33 +f 26 27 35 34 +f 27 28 36 35 +f 28 29 37 36 +f 29 30 38 37 +f 30 31 39 38 +f 31 32 40 39 +f 33 34 42 41 +f 34 35 43 42 +f 35 36 44 43 +f 36 37 45 44 +f 37 38 46 45 +f 38 39 47 46 +f 39 40 48 47 +f 41 42 50 49 +f 42 43 51 50 +f 43 44 52 51 +f 44 45 53 52 +f 45 46 54 53 +f 46 47 55 54 +f 47 48 56 55 +f 49 50 58 57 +f 50 51 59 58 +f 51 52 60 59 +f 52 53 61 60 +f 53 54 62 61 +f 54 55 63 62 +f 55 56 64 63 diff --git a/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp b/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp index ecff6b94..1eb39b53 100755 --- a/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp +++ b/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp @@ -52,12 +52,12 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine worldSettings.worldName = name; // Create the dynamics world for the physics simulation - mPhysicsWorld = new rp3d::CollisionWorld(worldSettings); + mPhysicsWorld = mPhysicsCommon.createCollisionWorld(worldSettings); // ---------- Sphere 1 ---------- // // Create a sphere and a corresponding collision body in the dynamics world - mSphere1 = new Sphere(4, mPhysicsWorld, mMeshFolderPath); + mSphere1 = new Sphere(4, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mAllShapes.push_back(mSphere1); // Set the color @@ -69,7 +69,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine // ---------- Sphere 2 ---------- // // Create a sphere and a corresponding collision body in the dynamics world - mSphere2 = new Sphere(2, mPhysicsWorld, mMeshFolderPath); + mSphere2 = new Sphere(2, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mAllShapes.push_back(mSphere2); // Set the color @@ -81,7 +81,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine // ---------- Capsule 1 ---------- // // Create a cylinder and a corresponding collision body in the dynamics world - mCapsule1 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsWorld, mMeshFolderPath); + mCapsule1 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mAllShapes.push_back(mCapsule1); // Set the color @@ -92,7 +92,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine // ---------- Capsule 2 ---------- // // Create a cylinder and a corresponding collision body in the dynamics world - mCapsule2 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsWorld, mMeshFolderPath); + mCapsule2 = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mAllShapes.push_back(mCapsule2); // Set the color @@ -103,7 +103,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine // ---------- Concave Mesh ---------- // // Create a convex mesh and a corresponding collision body in the dynamics world - mConcaveMesh = new ConcaveMesh(mPhysicsWorld, mMeshFolderPath + "city.obj"); + mConcaveMesh = new ConcaveMesh(mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "city.obj"); mAllShapes.push_back(mConcaveMesh); // Set the color @@ -114,7 +114,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine // ---------- Box 1 ---------- // // Create a cylinder and a corresponding collision body in the dynamics world - mBox1 = new Box(BOX_SIZE, mPhysicsWorld, mMeshFolderPath); + mBox1 = new Box(BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mAllShapes.push_back(mBox1); // Set the color @@ -125,7 +125,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine // ---------- Box 2 ---------- // // Create a cylinder and a corresponding collision body in the dynamics world - mBox2 = new Box(openglframework::Vector3(3, 2, 5), mPhysicsWorld, mMeshFolderPath); + mBox2 = new Box(openglframework::Vector3(3, 2, 5), mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mAllShapes.push_back(mBox2); // Set the color @@ -136,7 +136,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine // ---------- Convex Mesh ---------- // // Create a convex mesh and a corresponding collision body in the dynamics world - mConvexMesh = new ConvexMesh(mPhysicsWorld, mMeshFolderPath + "convexmesh.obj"); + mConvexMesh = new ConvexMesh(mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj"); mAllShapes.push_back(mConvexMesh); // Set the color @@ -147,7 +147,7 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine // ---------- Heightfield ---------- // // Create a convex mesh and a corresponding collision body in the dynamics world - mHeightField = new HeightField(mPhysicsWorld); + mHeightField = new HeightField(mPhysicsCommon, mPhysicsWorld); // Set the color mHeightField->setColor(mGreyColorDemo); @@ -212,7 +212,7 @@ CollisionDetectionScene::~CollisionDetectionScene() { VisualContactPoint::destroyStaticData(); // Destroy the collision world - delete mPhysicsWorld; + mPhysicsCommon.destroyCollisionWorld(mPhysicsWorld); } // Take a step for the simulation diff --git a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp index 12021ca7..7d2c4a4e 100644 --- a/testbed/scenes/collisionshapes/CollisionShapesScene.cpp +++ b/testbed/scenes/collisionshapes/CollisionShapesScene.cpp @@ -49,14 +49,14 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin worldSettings.worldName = name; // Create the dynamics world for the physics simulation - rp3d::DynamicsWorld* dynamicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings); + rp3d::DynamicsWorld* dynamicsWorld = mPhysicsCommon.createDynamicsWorld(gravity, worldSettings); dynamicsWorld->setEventListener(this); mPhysicsWorld = dynamicsWorld; for (int i=0; isetColor(mDemoColors[i % mNbDemoColors]); @@ -75,7 +75,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin for (int i=0; isetColor(mDemoColors[i % mNbDemoColors]); @@ -94,7 +94,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin for (int i=0; igetRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08)); @@ -117,7 +117,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin // Create a cylinder and a corresponding rigid in the dynamics world Capsule* capsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, CAPSULE_MASS, - getDynamicsWorld(), meshFolderPath); + mPhysicsCommon, getDynamicsWorld(), meshFolderPath); capsule->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08f)); @@ -138,7 +138,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin for (int i=0; isetColor(mDemoColors[i % mNbDemoColors]); @@ -155,7 +155,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin // ---------- Create the floor --------- - mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath); + mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath); mPhysicsObjects.push_back(mFloor); // Set the box color @@ -195,7 +195,7 @@ CollisionShapesScene::~CollisionShapesScene() { } // Destroy the dynamics world - delete mPhysicsWorld; + mPhysicsCommon.destroyDynamicsWorld(static_cast(mPhysicsWorld)); } /// Reset the scene diff --git a/testbed/scenes/concavemesh/ConcaveMeshScene.cpp b/testbed/scenes/concavemesh/ConcaveMeshScene.cpp index 7b73dec4..45d5327f 100644 --- a/testbed/scenes/concavemesh/ConcaveMeshScene.cpp +++ b/testbed/scenes/concavemesh/ConcaveMeshScene.cpp @@ -49,7 +49,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett worldSettings.worldName = name; // Create the dynamics world for the physics simulation - rp3d::DynamicsWorld* dynamicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings); + rp3d::DynamicsWorld* dynamicsWorld = mPhysicsCommon.createDynamicsWorld(gravity, worldSettings); dynamicsWorld->setEventListener(this); mPhysicsWorld = dynamicsWorld; @@ -57,7 +57,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett for (int i = 0; isetColor(mDemoColors[i % mNbDemoColors]); @@ -76,7 +76,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett for (int i = 0; isetColor(mDemoColors[i % mNbDemoColors]); @@ -95,7 +95,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett for (int i = 0; igetRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08)); @@ -118,7 +118,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett // Create a cylinder and a corresponding rigid in the dynamics world Capsule* capsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, CAPSULE_MASS, - getDynamicsWorld(), meshFolderPath); + mPhysicsCommon, getDynamicsWorld(), meshFolderPath); capsule->getRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08)); @@ -139,7 +139,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett for (int i = 0; isetColor(mDemoColors[i % mNbDemoColors]); @@ -160,7 +160,7 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett rp3d::decimal mass = 1.0; // Create a convex mesh and a corresponding rigid in the dynamics world - mConcaveMesh = new ConcaveMesh(mass, getDynamicsWorld(), meshFolderPath + "city.obj"); + mConcaveMesh = new ConcaveMesh(mass, mPhysicsCommon, getDynamicsWorld(), meshFolderPath + "city.obj"); // Set the mesh as beeing static mConcaveMesh->getRigidBody()->setType(rp3d::BodyType::STATIC); @@ -202,7 +202,7 @@ ConcaveMeshScene::~ConcaveMeshScene() { } // Destroy the dynamics world - delete getDynamicsWorld(); + mPhysicsCommon.destroyDynamicsWorld(getDynamicsWorld()); } // Reset the scene diff --git a/testbed/scenes/cubes/CubesScene.cpp b/testbed/scenes/cubes/CubesScene.cpp index 66a59215..24da0261 100644 --- a/testbed/scenes/cubes/CubesScene.cpp +++ b/testbed/scenes/cubes/CubesScene.cpp @@ -47,7 +47,7 @@ CubesScene::CubesScene(const std::string& name, EngineSettings& settings) worldSettings.worldName = name; // Create the dynamics world for the physics simulation - rp3d::DynamicsWorld* dynamicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings); + rp3d::DynamicsWorld* dynamicsWorld = mPhysicsCommon.createDynamicsWorld(gravity, worldSettings); dynamicsWorld->setEventListener(this); mPhysicsWorld = dynamicsWorld; @@ -55,7 +55,7 @@ CubesScene::CubesScene(const std::string& name, EngineSettings& settings) for (int i=0; isetColor(mDemoColors[i % mNbDemoColors]); @@ -73,7 +73,7 @@ CubesScene::CubesScene(const std::string& name, EngineSettings& settings) // ------------------------- FLOOR ----------------------- // // Create the floor - mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath); + mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath); mFloor->setColor(mGreyColorDemo); mFloor->setSleepingColor(mGreyColorDemo); @@ -113,7 +113,7 @@ CubesScene::~CubesScene() { delete mFloor; // Destroy the dynamics world - delete getDynamicsWorld(); + mPhysicsCommon.destroyDynamicsWorld(getDynamicsWorld()); } // Reset the scene diff --git a/testbed/scenes/cubestack/CubeStackScene.cpp b/testbed/scenes/cubestack/CubeStackScene.cpp index 56fb3c35..ab45a5df 100644 --- a/testbed/scenes/cubestack/CubeStackScene.cpp +++ b/testbed/scenes/cubestack/CubeStackScene.cpp @@ -47,7 +47,7 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings worldSettings.worldName = name; // Create the dynamics world for the physics simulation - rp3d::DynamicsWorld* dynamicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings); + rp3d::DynamicsWorld* dynamicsWorld = mPhysicsCommon.createDynamicsWorld(gravity, worldSettings); dynamicsWorld->setEventListener(this); mPhysicsWorld = dynamicsWorld; @@ -57,7 +57,7 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings for (int j=0; jsetColor(mDemoColors[i % mNbDemoColors]); @@ -76,7 +76,7 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings // ------------------------- FLOOR ----------------------- // // Create the floor - mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath); + mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath); mFloor->setColor(mGreyColorDemo); mFloor->setSleepingColor(mGreyColorDemo); @@ -116,7 +116,7 @@ CubeStackScene::~CubeStackScene() { delete mFloor; // Destroy the dynamics world - delete getDynamicsWorld(); + mPhysicsCommon.destroyDynamicsWorld(getDynamicsWorld()); } // Reset the scene diff --git a/testbed/scenes/heightfield/HeightFieldScene.cpp b/testbed/scenes/heightfield/HeightFieldScene.cpp index d2734bbc..b0fad108 100644 --- a/testbed/scenes/heightfield/HeightFieldScene.cpp +++ b/testbed/scenes/heightfield/HeightFieldScene.cpp @@ -49,14 +49,14 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett worldSettings.worldName = name; // Create the dynamics world for the physics simulation - rp3d::DynamicsWorld* dynamicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings); + rp3d::DynamicsWorld* dynamicsWorld = mPhysicsCommon.createDynamicsWorld(gravity, worldSettings); dynamicsWorld->setEventListener(this); mPhysicsWorld = dynamicsWorld; for (int i = 0; isetColor(mDemoColors[i % mNbDemoColors]); @@ -75,7 +75,7 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett for (int i = 0; isetColor(mDemoColors[i % mNbDemoColors]); @@ -94,7 +94,7 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett for (int i = 0; igetRigidBody()->getMaterial().setRollingResistance(0.08f); @@ -117,7 +117,7 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett // Create a cylinder and a corresponding rigid in the dynamics world Capsule* capsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, CAPSULE_MASS, - getDynamicsWorld(), meshFolderPath); + mPhysicsCommon, getDynamicsWorld(), meshFolderPath); capsule->getRigidBody()->getMaterial().setRollingResistance(0.08f); @@ -138,7 +138,7 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett for (int i = 0; isetColor(mDemoColors[i % mNbDemoColors]); @@ -159,7 +159,7 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett rp3d::decimal mass = 1.0; // Create a convex mesh and a corresponding rigid in the dynamics world - mHeightField = new HeightField(mass, getDynamicsWorld()); + mHeightField = new HeightField(mass, mPhysicsCommon, getDynamicsWorld()); // Set the mesh as beeing static mHeightField->getRigidBody()->setType(rp3d::BodyType::STATIC); @@ -201,7 +201,7 @@ HeightFieldScene::~HeightFieldScene() { } // Destroy the dynamics world - delete getDynamicsWorld(); + mPhysicsCommon.destroyDynamicsWorld(getDynamicsWorld()); } // Reset the scene diff --git a/testbed/scenes/joints/JointsScene.cpp b/testbed/scenes/joints/JointsScene.cpp index 6c6a2bfc..8188eddc 100644 --- a/testbed/scenes/joints/JointsScene.cpp +++ b/testbed/scenes/joints/JointsScene.cpp @@ -48,7 +48,7 @@ JointsScene::JointsScene(const std::string& name, EngineSettings& settings) worldSettings.worldName = name; // Create the dynamics world for the physics simulation - rp3d::DynamicsWorld* dynamicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings); + rp3d::DynamicsWorld* dynamicsWorld = mPhysicsCommon.createDynamicsWorld(gravity, worldSettings); dynamicsWorld->setEventListener(this); mPhysicsWorld = dynamicsWorld; @@ -115,7 +115,7 @@ JointsScene::~JointsScene() { delete mFloor; // Destroy the dynamics world - delete getDynamicsWorld(); + mPhysicsCommon.destroyDynamicsWorld(getDynamicsWorld()); } // Update the physics world (take a simulation step) @@ -214,7 +214,7 @@ void JointsScene::createBallAndSocketJoints() { // Create a box and a corresponding rigid in the dynamics world mBallAndSocketJointChainBoxes[i] = new Box(boxDimension, boxMass, - getDynamicsWorld(), mMeshFolderPath); + mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath); mBallAndSocketJointChainBoxes[i]->setTransform(rp3d::Transform(positionBox, rp3d::Quaternion::identity())); // Set the box color @@ -266,7 +266,7 @@ void JointsScene::createSliderJoint() { // Create a box and a corresponding rigid in the dynamics world openglframework::Vector3 box1Dimension(2, 4, 2); - mSliderJointBottomBox = new Box(box1Dimension , BOX_MASS, getDynamicsWorld(), mMeshFolderPath); + mSliderJointBottomBox = new Box(box1Dimension , BOX_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath); mSliderJointBottomBox->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity())); // Set the box color @@ -288,7 +288,7 @@ void JointsScene::createSliderJoint() { // Create a box and a corresponding rigid in the dynamics world openglframework::Vector3 box2Dimension(1.5f, 4, 1.5f); - mSliderJointTopBox = new Box(box2Dimension, BOX_MASS, getDynamicsWorld(), mMeshFolderPath); + mSliderJointTopBox = new Box(box2Dimension, BOX_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath); mSliderJointTopBox->setTransform(rp3d::Transform(positionBox2, rp3d::Quaternion::identity())); // Set the box color @@ -330,7 +330,7 @@ void JointsScene::createPropellerHingeJoint() { // Create a box and a corresponding rigid in the dynamics world openglframework::Vector3 boxDimension(10, 1, 1); - mPropellerBox = new Box(boxDimension, BOX_MASS, getDynamicsWorld(), mMeshFolderPath); + mPropellerBox = new Box(boxDimension, BOX_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath); mPropellerBox->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity())); // Set the box color @@ -371,7 +371,7 @@ void JointsScene::createFixedJoints() { // Create a box and a corresponding rigid in the dynamics world openglframework::Vector3 boxDimension(1.5, 1.5, 1.5); - mFixedJointBox1 = new Box(boxDimension, BOX_MASS, getDynamicsWorld(), mMeshFolderPath); + mFixedJointBox1 = new Box(boxDimension, BOX_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath); mFixedJointBox1->setTransform(rp3d::Transform(positionBox1, rp3d::Quaternion::identity())); // Set the box color @@ -389,7 +389,7 @@ void JointsScene::createFixedJoints() { rp3d::Vector3 positionBox2(-5, 7, 0); // Create a box and a corresponding rigid in the dynamics world - mFixedJointBox2 = new Box(boxDimension, BOX_MASS, getDynamicsWorld(), mMeshFolderPath); + mFixedJointBox2 = new Box(boxDimension, BOX_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath); mFixedJointBox2->setTransform(rp3d::Transform(positionBox2, rp3d::Quaternion::identity())); // Set the box color @@ -430,7 +430,7 @@ void JointsScene::createFloor() { // Create the floor rp3d::Vector3 floorPosition(0, 0, 0); - mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, getDynamicsWorld(), mMeshFolderPath); + mFloor = new Box(FLOOR_SIZE, FLOOR_MASS, mPhysicsCommon, getDynamicsWorld(), mMeshFolderPath); // Set the box color mFloor->setColor(mGreyColorDemo); diff --git a/testbed/scenes/pile/PileScene.cpp b/testbed/scenes/pile/PileScene.cpp new file mode 100644 index 00000000..c6fbd255 --- /dev/null +++ b/testbed/scenes/pile/PileScene.cpp @@ -0,0 +1,272 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2016 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 "PileScene.h" + +// Namespaces +using namespace openglframework; +using namespace pilescene; + +// Constructor +PileScene::PileScene(const std::string& name, EngineSettings& settings) + : SceneDemo(name, settings, SCENE_RADIUS) { + + std::string meshFolderPath("meshes/"); + + // Compute the radius and the center of the scene + openglframework::Vector3 center(0, 5, 0); + + // Set the center of the scene + setScenePosition(center, SCENE_RADIUS); + + // Gravity vector in the dynamics world + rp3d::Vector3 gravity(0, -9.81f, 0); + + rp3d::WorldSettings worldSettings; + worldSettings.worldName = name; + + // Create the dynamics world for the physics simulation + mPhysicsWorld = mPhysicsCommon.createDynamicsWorld(gravity, worldSettings); + + for (int i=0; isetColor(mDemoColors[i % mNbDemoColors]); + dumbbell->setSleepingColor(mRedColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material = dumbbell->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // Add the mesh the list of dumbbells in the scene + mDumbbells.push_back(dumbbell); + mPhysicsObjects.push_back(dumbbell); + } + + // Create all the boxes of the scene + for (int i=0; isetColor(mDemoColors[i % mNbDemoColors]); + box->setSleepingColor(mRedColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material = box->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // Add the sphere the list of sphere in the scene + mBoxes.push_back(box); + mPhysicsObjects.push_back(box); + } + + // Create all the spheres of the scene + for (int i=0; igetRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08)); + + // Set the box color + sphere->setColor(mDemoColors[i % mNbDemoColors]); + sphere->setSleepingColor(mRedColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material = sphere->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // Add the sphere the list of sphere in the scene + mSpheres.push_back(sphere); + mPhysicsObjects.push_back(sphere); + } + + // Create all the capsules of the scene + for (int i=0; igetRigidBody()->getMaterial().setRollingResistance(rp3d::decimal(0.08f)); + + // Set the box color + capsule->setColor(mDemoColors[i % mNbDemoColors]); + capsule->setSleepingColor(mRedColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material = capsule->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // Add the cylinder the list of sphere in the scene + mCapsules.push_back(capsule); + mPhysicsObjects.push_back(capsule); + } + + // Create all the convex meshes of the scene + for (int i=0; isetColor(mDemoColors[i % mNbDemoColors]); + mesh->setSleepingColor(mRedColorDemo); + + // Change the material properties of the rigid body + rp3d::Material& material = mesh->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + + // Add the mesh the list of sphere in the scene + mConvexMeshes.push_back(mesh); + mPhysicsObjects.push_back(mesh); + } + + // ---------- Create the triangular mesh ---------- // + + // Position + rp3d::decimal mass = 1.0; + + // Create a convex mesh and a corresponding rigid in the dynamics world + mSandbox = new ConcaveMesh(mass, mPhysicsCommon, getDynamicsWorld(), meshFolderPath + "sandbox.obj"); + + // Set the mesh as beeing static + mSandbox->getRigidBody()->setType(rp3d::BodyType::STATIC); + + // Set the box color + mSandbox->setColor(mGreyColorDemo); + mSandbox->setSleepingColor(mGreyColorDemo); + + mPhysicsObjects.push_back(mSandbox); + + // Change the material properties of the rigid body + rp3d::Material& material = mSandbox->getRigidBody()->getMaterial(); + material.setBounciness(rp3d::decimal(0.2)); + material.setFrictionCoefficient(rp3d::decimal(0.1)); + + // Get the physics engine parameters + mEngineSettings.isGravityEnabled = getDynamicsWorld()->isGravityEnabled(); + rp3d::Vector3 gravityVector = getDynamicsWorld()->getGravity(); + mEngineSettings.gravity = openglframework::Vector3(gravityVector.x, gravityVector.y, gravityVector.z); + mEngineSettings.isSleepingEnabled = getDynamicsWorld()->isSleepingEnabled(); + mEngineSettings.sleepLinearVelocity = getDynamicsWorld()->getSleepLinearVelocity(); + mEngineSettings.sleepAngularVelocity = getDynamicsWorld()->getSleepAngularVelocity(); + mEngineSettings.nbPositionSolverIterations = getDynamicsWorld()->getNbIterationsPositionSolver(); + mEngineSettings.nbVelocitySolverIterations = getDynamicsWorld()->getNbIterationsVelocitySolver(); + mEngineSettings.timeBeforeSleep = getDynamicsWorld()->getTimeBeforeSleep(); +} + +// Destructor +PileScene::~PileScene() { + + // Destroy all the physics objects of the scene + for (std::vector::iterator it = mPhysicsObjects.begin(); it != mPhysicsObjects.end(); ++it) { + + // Destroy the corresponding rigid body from the dynamics world + getDynamicsWorld()->destroyRigidBody((*it)->getRigidBody()); + + // Destroy the object + delete (*it); + } + + // Destroy the dynamics world + mPhysicsCommon.destroyDynamicsWorld(getDynamicsWorld()); +} + +/// Reset the scene +void PileScene::reset() { + + const float radius = 3.0f; + + for (uint i = 0; isetTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); + } + + // Create all the boxes of the scene + for (uint i = 0; isetTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); + } + + // Create all the spheres of the scene + for (uint i = 0; isetTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); + } + + // Create all the capsules of the scene + for (uint i = 0; isetTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); + } + + // Create all the convex meshes of the scene + for (uint i = 0; isetTransform(rp3d::Transform(position, rp3d::Quaternion::identity())); + } + + // ---------- Create the triangular mesh ---------- // + + mSandbox->setTransform(rp3d::Transform::identity()); +} diff --git a/testbed/scenes/pile/PileScene.h b/testbed/scenes/pile/PileScene.h new file mode 100644 index 00000000..d199f663 --- /dev/null +++ b/testbed/scenes/pile/PileScene.h @@ -0,0 +1,106 @@ +/******************************************************************************** +* ReactPhysics3D physics library, http://www.reactphysics3d.com * +* Copyright (c) 2010-2016 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. * +* * +********************************************************************************/ + +#ifndef PILE_SCENE_H +#define PILE_SCENE_H + +// Libraries +#include "openglframework.h" +#include "reactphysics3d.h" +#include "SceneDemo.h" +#include "Sphere.h" +#include "Box.h" +#include "Capsule.h" +#include "ConvexMesh.h" +#include "ConcaveMesh.h" +#include "Dumbbell.h" +#include "VisualContactPoint.h" + +namespace pilescene { + +// Constants +const float SCENE_RADIUS = 30.0f; +const int NB_BOXES = 150; +const int NB_SPHERES = 80; +const int NB_CAPSULES = 5; +const int NB_MESHES = 0; +const int NB_COMPOUND_SHAPES = 0; +const openglframework::Vector3 BOX_SIZE(2, 2, 2); +const float SPHERE_RADIUS = 1.5f; +const float CONE_RADIUS = 2.0f; +const float CONE_HEIGHT = 3.0f; +const float CYLINDER_RADIUS = 1.0f; +const float CYLINDER_HEIGHT = 5.0f; +const float CAPSULE_RADIUS = 1.0f; +const float CAPSULE_HEIGHT = 1.0f; +const float DUMBBELL_HEIGHT = 1.0f; +const openglframework::Vector3 FLOOR_SIZE(50, 0.5f, 50); // Floor dimensions in meters +const float BOX_MASS = 1.0f; +const float CONE_MASS = 1.0f; +const float CYLINDER_MASS = 1.0f; +const float CAPSULE_MASS = 1.0f; +const float MESH_MASS = 1.0f; +const float FLOOR_MASS = 100.0f; // Floor mass in kilograms + +// Class PileScene +class PileScene : public SceneDemo { + + private : + + // -------------------- Attributes -------------------- // + + /// All the boxes of the scene + std::vector mBoxes; + + std::vector mSpheres; + + std::vector mCapsules; + + /// All the convex meshes of the scene + std::vector mConvexMeshes; + + /// All the dumbbell of the scene + std::vector mDumbbells; + + /// Sandbox for the floor + ConcaveMesh* mSandbox; + + public: + + // -------------------- Methods -------------------- // + + /// Constructor + PileScene(const std::string& name, EngineSettings& settings); + + /// Destructor + virtual ~PileScene() override; + + /// Reset the scene + virtual void reset() override; +}; + +} + +#endif diff --git a/testbed/scenes/raycast/RaycastScene.cpp b/testbed/scenes/raycast/RaycastScene.cpp index 1c5bb9c0..dd12e116 100644 --- a/testbed/scenes/raycast/RaycastScene.cpp +++ b/testbed/scenes/raycast/RaycastScene.cpp @@ -48,12 +48,12 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings) worldSettings.worldName = name; // Create the dynamics world for the physics simulation - mPhysicsWorld = new rp3d::CollisionWorld(worldSettings); + mPhysicsWorld = mPhysicsCommon.createCollisionWorld(worldSettings); // ---------- Dumbbell ---------- // // Create a convex mesh and a corresponding collision body in the dynamics world - mDumbbell = new Dumbbell(mPhysicsWorld, mMeshFolderPath); + mDumbbell = new Dumbbell(mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); // Set the box color mDumbbell->setColor(mGreyColorDemo); @@ -63,7 +63,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings) // ---------- Box ---------- // // Create a box and a corresponding collision body in the dynamics world - mBox = new Box(BOX_SIZE, mPhysicsWorld, mMeshFolderPath); + mBox = new Box(BOX_SIZE, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); mBox->getCollisionBody()->setIsActive(false); // Set the box color @@ -74,7 +74,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings) // ---------- Sphere ---------- // // Create a sphere and a corresponding collision body in the dynamics world - mSphere = new Sphere(SPHERE_RADIUS, mPhysicsWorld, mMeshFolderPath); + mSphere = new Sphere(SPHERE_RADIUS, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); // Set the color mSphere->setColor(mGreyColorDemo); @@ -85,7 +85,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings) openglframework::Vector3 position6(0, 0, 0); // Create a cylinder and a corresponding collision body in the dynamics world - mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsWorld, mMeshFolderPath); + mCapsule = new Capsule(CAPSULE_RADIUS, CAPSULE_HEIGHT, mPhysicsCommon, mPhysicsWorld, mMeshFolderPath); // Set the color mCapsule->setColor(mGreyColorDemo); @@ -95,7 +95,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings) // ---------- Convex Mesh ---------- // // Create a convex mesh and a corresponding collision body in the dynamics world - mConvexMesh = new ConvexMesh(mPhysicsWorld, mMeshFolderPath + "convexmesh.obj"); + mConvexMesh = new ConvexMesh(mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "convexmesh.obj"); // Set the color mConvexMesh->setColor(mGreyColorDemo); @@ -105,7 +105,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings) // ---------- Concave Mesh ---------- // // Create a convex mesh and a corresponding collision body in the dynamics world - mConcaveMesh = new ConcaveMesh(mPhysicsWorld, mMeshFolderPath + "city.obj"); + mConcaveMesh = new ConcaveMesh(mPhysicsCommon, mPhysicsWorld, mMeshFolderPath + "city.obj"); // Set the color mConcaveMesh->setColor(mGreyColorDemo); @@ -115,7 +115,7 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings) // ---------- Heightfield ---------- // // Create a convex mesh and a corresponding collision body in the dynamics world - mHeightField = new HeightField(mPhysicsWorld); + mHeightField = new HeightField(mPhysicsCommon, mPhysicsWorld); // Set the color mHeightField->setColor(mGreyColorDemo); @@ -251,7 +251,7 @@ RaycastScene::~RaycastScene() { VisualContactPoint::destroyStaticData(); // Destroy the collision world - delete mPhysicsWorld; + mPhysicsCommon.destroyCollisionWorld(mPhysicsWorld); // Destroy the lines for (std::vector::iterator it = mLines.begin(); it != mLines.end(); diff --git a/testbed/src/Gui.cpp b/testbed/src/Gui.cpp index 69b89852..d6ab6fe0 100644 --- a/testbed/src/Gui.cpp +++ b/testbed/src/Gui.cpp @@ -36,12 +36,14 @@ double Gui::mScrollY = 0.0; double Gui::mTimeSinceLastProfilingDisplay = 0; double Gui::mCachedFPS = 0; double Gui::mCachedUpdateTime = 0; -double Gui::mCachedPhysicsUpdateTime = 0; +double Gui::mCachedTotalPhysicsUpdateTime = 0; +double Gui::mCachedPhysicsStepTime = 0; // Constructor Gui::Gui(TestbedApplication* app) : mApp(app), mSimulationPanel(nullptr), mSettingsPanel(nullptr), mPhysicsPanel(nullptr), - mRenderingPanel(nullptr), mFPSLabel(nullptr), mFrameTimeLabel(nullptr), mPhysicsTimeLabel(nullptr) + mRenderingPanel(nullptr), mFPSLabel(nullptr), mFrameTimeLabel(nullptr), mTotalPhysicsTimeLabel(nullptr), + mPhysicsStepTimeLabel(nullptr) { } @@ -78,7 +80,8 @@ void Gui::update() { mTimeSinceLastProfilingDisplay = mApp->mCurrentTime; mCachedFPS = mApp->mFPS; mCachedUpdateTime = mApp->mFrameTime; - mCachedPhysicsUpdateTime = mApp->mPhysicsTime; + mCachedTotalPhysicsUpdateTime = mApp->mTotalPhysicsTime; + mCachedPhysicsStepTime = mApp->mPhysicsStepTime; } // Framerate (FPS) @@ -87,8 +90,11 @@ void Gui::update() { // Frame time mFrameTimeLabel->setCaption(std::string("Frame time : ") + floatToString(mCachedUpdateTime * 1000.0, 1) + std::string(" ms")); - // Physics time - mPhysicsTimeLabel->setCaption(std::string("Physics time : ") + floatToString(mCachedPhysicsUpdateTime * 1000.0, 1) + std::string(" ms")); + // Total Physics time + mTotalPhysicsTimeLabel->setCaption(std::string("Total physics time : ") + floatToString(mCachedTotalPhysicsUpdateTime * 1000.0, 1) + std::string(" ms")); + + // Physics step time + mPhysicsStepTimeLabel->setCaption(std::string("Physics step time : ") + floatToString(mCachedPhysicsStepTime * 1000.0, 1) + std::string(" ms")); } void Gui::createSimulationPanel() { @@ -447,8 +453,11 @@ void Gui::createProfilingPanel() { // Update time mFrameTimeLabel = new Label(profilingPanel, std::string("Frame time : ") + floatToString(mCachedUpdateTime * 1000.0, 1) + std::string(" ms"),"sans-bold"); - // Update time - mPhysicsTimeLabel = new Label(profilingPanel, std::string("Physics time : ") + floatToString(mCachedPhysicsUpdateTime * 1000.0, 1) + std::string(" ms"),"sans-bold"); + // Total physics time + mTotalPhysicsTimeLabel = new Label(profilingPanel, std::string("Total physics time : ") + floatToString(mCachedTotalPhysicsUpdateTime * 1000.0, 1) + std::string(" ms"),"sans-bold"); + + // Physics step time + mPhysicsStepTimeLabel = new Label(profilingPanel, std::string("Physics step time : ") + floatToString(mCachedPhysicsStepTime * 1000.0, 1) + std::string(" ms"),"sans-bold"); profilingPanel->setVisible(true); } diff --git a/testbed/src/Gui.h b/testbed/src/Gui.h index 2cdace7a..46427b51 100644 --- a/testbed/src/Gui.h +++ b/testbed/src/Gui.h @@ -69,7 +69,8 @@ class Gui { // Profiling panel Label* mFPSLabel; Label* mFrameTimeLabel; - Label* mPhysicsTimeLabel; + Label* mTotalPhysicsTimeLabel; + Label* mPhysicsStepTimeLabel; std::vector mCheckboxesScenes; @@ -86,8 +87,11 @@ class Gui { /// Cached update time static double mCachedUpdateTime; - // Cached update physics time - static double mCachedPhysicsUpdateTime; + // Cached total update physics time + static double mCachedTotalPhysicsUpdateTime; + + // Cached update single physics step time + static double mCachedPhysicsStepTime; // -------------------- Methods -------------------- // diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index 31b832c0..2f427b47 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -96,6 +96,8 @@ class SceneDemo : public Scene { std::string mMeshFolderPath; + rp3d::PhysicsCommon mPhysicsCommon; + std::vector mPhysicsObjects; rp3d::CollisionWorld* mPhysicsWorld; diff --git a/testbed/src/TestbedApplication.cpp b/testbed/src/TestbedApplication.cpp index 4a0963f2..b0fbd01c 100644 --- a/testbed/src/TestbedApplication.cpp +++ b/testbed/src/TestbedApplication.cpp @@ -37,6 +37,7 @@ #include "raycast/RaycastScene.h" #include "concavemesh/ConcaveMeshScene.h" #include "cubestack/CubeStackScene.h" +#include "pile/PileScene.h" using namespace openglframework; using namespace jointsscene; @@ -47,6 +48,7 @@ using namespace trianglemeshscene; using namespace heightfieldscene; using namespace collisiondetectionscene; using namespace cubestackscene; +using namespace pilescene; // Initialization of static variables const float TestbedApplication::SCROLL_SENSITIVITY = 0.08f; @@ -57,7 +59,7 @@ TestbedApplication::TestbedApplication(bool isFullscreen) mIsInitialized(false), mGui(this), mCurrentScene(nullptr), mEngineSettings(EngineSettings::defaultSettings()), mFPS(0), mNbFrames(0), mPreviousTime(0), - mLastTimeComputedFPS(0), mFrameTime(0), mPhysicsTime(0), + mLastTimeComputedFPS(0), mFrameTime(0), mTotalPhysicsTime(0), mPhysicsStepTime(0), mWidth(1280), mHeight(720), mSinglePhysicsStepEnabled(false), mSinglePhysicsStepDone(false), mWindowToFramebufferRatio(Vector2(1, 1)), mIsShadowMappingEnabled(true), @@ -125,6 +127,10 @@ void TestbedApplication::createScenes() { ConcaveMeshScene* concaveMeshScene = new ConcaveMeshScene("Concave Mesh", mEngineSettings); mScenes.push_back(concaveMeshScene); + // Pile scene + PileScene* pileScene = new PileScene("Pile", mEngineSettings); + mScenes.push_back(pileScene); + assert(mScenes.size() > 0); const int firstSceneIndex = 0; @@ -139,7 +145,7 @@ void TestbedApplication::destroyScenes() { delete mScenes[i]; } - mCurrentScene = NULL; + mCurrentScene = nullptr; } void TestbedApplication::updateSinglePhysicsStep() { @@ -163,9 +169,13 @@ void TestbedApplication::updatePhysics() { // While the time accumulator is not empty while(mTimer.isPossibleToTakeStep(mEngineSettings.timeStep)) { + double currentTime = glfwGetTime(); + // Take a physics simulation step mCurrentScene->updatePhysics(); + mPhysicsStepTime = glfwGetTime() - currentTime; + // Update the timer mTimer.nextStep(mEngineSettings.timeStep); } @@ -186,7 +196,7 @@ void TestbedApplication::update() { } // Compute the physics update time - mPhysicsTime = glfwGetTime() - currentTime; + mTotalPhysicsTime = glfwGetTime() - currentTime; // Compute the interpolation factor float factor = mTimer.computeInterpolationFactor(mEngineSettings.timeStep); diff --git a/testbed/src/TestbedApplication.h b/testbed/src/TestbedApplication.h index c9ca44ee..fc3d53e0 100644 --- a/testbed/src/TestbedApplication.h +++ b/testbed/src/TestbedApplication.h @@ -83,8 +83,11 @@ class TestbedApplication : public Screen { /// Update time (in seconds) double mFrameTime; - /// Physics update time (in seconds) - double mPhysicsTime; + /// Total physics update time (in seconds) + double mTotalPhysicsTime; + + /// Time of a single physics step (in seconds) + double mPhysicsStepTime; /// Width and height of the window int mWidth, mHeight;