diff --git a/include/reactphysics3d/collision/shapes/BoxShape.h b/include/reactphysics3d/collision/shapes/BoxShape.h index bbf08d0e..a94df5b5 100644 --- a/include/reactphysics3d/collision/shapes/BoxShape.h +++ b/include/reactphysics3d/collision/shapes/BoxShape.h @@ -36,6 +36,7 @@ namespace reactphysics3d { // Declarations class CollisionBody; class DefaultAllocator; +class PhysicsCommon; // Class BoxShape /** @@ -53,13 +54,13 @@ class BoxShape : public ConvexPolyhedronShape { /// Half-extents of the box in the x, y and z direction Vector3 mHalfExtents; - /// Half-edge structure of the polyhedron - HalfEdgeStructure mHalfEdgeStructure; + /// Reference to the physics common object + PhysicsCommon& mPhysicsCommon; // -------------------- Methods -------------------- // /// Constructor - BoxShape(const Vector3& halfExtents, MemoryAllocator& allocator); + BoxShape(const Vector3& halfExtents, MemoryAllocator& allocator, PhysicsCommon& physicsCommon); /// Return a local support point in a given direction without the object margin virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const override; @@ -196,23 +197,11 @@ RP3D_FORCE_INLINE uint BoxShape::getNbFaces() const { return 6; } -// Return a given face of the polyhedron -RP3D_FORCE_INLINE const HalfEdgeStructure::Face& BoxShape::getFace(uint faceIndex) const { - assert(faceIndex < mHalfEdgeStructure.getNbFaces()); - return mHalfEdgeStructure.getFace(faceIndex); -} - // Return the number of vertices of the polyhedron RP3D_FORCE_INLINE uint BoxShape::getNbVertices() const { return 8; } -// Return a given vertex of the polyhedron -RP3D_FORCE_INLINE HalfEdgeStructure::Vertex BoxShape::getVertex(uint vertexIndex) const { - assert(vertexIndex < getNbVertices()); - return mHalfEdgeStructure.getVertex(vertexIndex); -} - // Return the position of a given vertex RP3D_FORCE_INLINE Vector3 BoxShape::getVertexPosition(uint vertexIndex) const { assert(vertexIndex < getNbVertices()); @@ -269,12 +258,6 @@ RP3D_FORCE_INLINE uint BoxShape::getNbHalfEdges() const { return 24; } -// Return a given half-edge of the polyhedron -RP3D_FORCE_INLINE const HalfEdgeStructure::Edge& BoxShape::getHalfEdge(uint edgeIndex) const { - assert(edgeIndex < getNbHalfEdges()); - return mHalfEdgeStructure.getHalfEdge(edgeIndex); -} - } #endif diff --git a/include/reactphysics3d/collision/shapes/ConcaveMeshShape.h b/include/reactphysics3d/collision/shapes/ConcaveMeshShape.h index 106f0844..af2112b3 100644 --- a/include/reactphysics3d/collision/shapes/ConcaveMeshShape.h +++ b/include/reactphysics3d/collision/shapes/ConcaveMeshShape.h @@ -142,10 +142,13 @@ class ConcaveMeshShape : public ConcaveShape { /// if the user did not provide its own vertices normals) Vector3** mComputedVerticesNormals; + /// Reference to the triangle half-edge structure + HalfEdgeStructure& mTriangleHalfEdgeStructure; + // -------------------- Methods -------------------- // /// Constructor - ConcaveMeshShape(TriangleMesh* triangleMesh, MemoryAllocator& allocator, const Vector3& scaling = Vector3(1, 1, 1)); + ConcaveMeshShape(TriangleMesh* triangleMesh, MemoryAllocator& allocator, HalfEdgeStructure& triangleHalfEdgeStructure, const Vector3& scaling = Vector3(1, 1, 1)); /// Raycast method with feedback information virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, Collider* collider, MemoryAllocator& allocator) const override; diff --git a/include/reactphysics3d/collision/shapes/HeightFieldShape.h b/include/reactphysics3d/collision/shapes/HeightFieldShape.h index c991de12..efa2625e 100644 --- a/include/reactphysics3d/collision/shapes/HeightFieldShape.h +++ b/include/reactphysics3d/collision/shapes/HeightFieldShape.h @@ -91,12 +91,15 @@ class HeightFieldShape : public ConcaveShape { /// Local AABB of the height field (without scaling) AABB mAABB; + /// Reference to the half-edge structure + HalfEdgeStructure& mTriangleHalfEdgeStructure; + // -------------------- Methods -------------------- // /// Constructor HeightFieldShape(int nbGridColumns, int nbGridRows, decimal minHeight, decimal maxHeight, const void* heightFieldData, HeightDataType dataType, MemoryAllocator& allocator, - int upAxis = 1, decimal integerHeightScale = 1.0f, + HalfEdgeStructure& triangleHalfEdgeStructure, int upAxis = 1, decimal integerHeightScale = 1.0f, const Vector3& scaling = Vector3(1,1,1)); /// Raycast method with feedback information diff --git a/include/reactphysics3d/collision/shapes/TriangleShape.h b/include/reactphysics3d/collision/shapes/TriangleShape.h index 5224f242..aa9a4003 100644 --- a/include/reactphysics3d/collision/shapes/TriangleShape.h +++ b/include/reactphysics3d/collision/shapes/TriangleShape.h @@ -33,6 +33,9 @@ /// ReactPhysics3D namespace namespace reactphysics3d { +// Forward declarations +class PhysicsCommon; + /// Raycast test side for the triangle enum class TriangleRaycastSide { @@ -73,11 +76,8 @@ class TriangleShape : public ConvexPolyhedronShape { /// Raycast test type for the triangle (front, back, front-back) TriangleRaycastSide mRaycastTestType; - /// Faces information for the two faces of the triangle - HalfEdgeStructure::Face mFaces[2]; - - /// Edges information for the six edges of the triangle - HalfEdgeStructure::Edge mEdges[6]; + /// Reference to triangle half-edge structure + HalfEdgeStructure& mTriangleHalfEdgeStructure; // -------------------- Methods -------------------- // @@ -108,8 +108,8 @@ class TriangleShape : public ConvexPolyhedronShape { Vector3& outNewLocalContactPointOtherShape, Vector3& outSmoothWorldContactTriangleNormal) const; /// Constructor - TriangleShape(const Vector3* vertices, const Vector3* verticesNormals, - uint shapeId, MemoryAllocator& allocator); + TriangleShape(const Vector3* vertices, const Vector3* verticesNormals, uint shapeId, HalfEdgeStructure& triangleHalfEdgeStructure, + MemoryAllocator& allocator); /// Destructor virtual ~TriangleShape() override = default; @@ -236,12 +236,6 @@ RP3D_FORCE_INLINE uint TriangleShape::getNbFaces() const { return 2; } -// Return a given face of the polyhedron -RP3D_FORCE_INLINE const HalfEdgeStructure::Face& TriangleShape::getFace(uint faceIndex) const { - assert(faceIndex < 2); - return mFaces[faceIndex]; -} - // Return the number of vertices of the polyhedron RP3D_FORCE_INLINE uint TriangleShape::getNbVertices() const { return 3; @@ -260,12 +254,6 @@ RP3D_FORCE_INLINE HalfEdgeStructure::Vertex TriangleShape::getVertex(uint vertex return vertex; } -// Return a given half-edge of the polyhedron -RP3D_FORCE_INLINE const HalfEdgeStructure::Edge& TriangleShape::getHalfEdge(uint edgeIndex) const { - assert(edgeIndex < getNbHalfEdges()); - return mEdges[edgeIndex]; -} - // Return the position of a given vertex RP3D_FORCE_INLINE Vector3 TriangleShape::getVertexPosition(uint vertexIndex) const { assert(vertexIndex < 3); @@ -377,6 +365,18 @@ RP3D_FORCE_INLINE void TriangleShape::computeSmoothTriangleMeshContact(const Col } } +// Return a given face of the polyhedron +RP3D_FORCE_INLINE const HalfEdgeStructure::Face& TriangleShape::getFace(uint faceIndex) const { + assert(faceIndex < 2); + return mTriangleHalfEdgeStructure.getFace(faceIndex); +} + +// Return a given half-edge of the polyhedron +RP3D_FORCE_INLINE const HalfEdgeStructure::Edge& TriangleShape::getHalfEdge(uint edgeIndex) const { + assert(edgeIndex < getNbHalfEdges()); + return mTriangleHalfEdgeStructure.getHalfEdge(edgeIndex); +} + } #endif diff --git a/include/reactphysics3d/engine/PhysicsCommon.h b/include/reactphysics3d/engine/PhysicsCommon.h index f2e827c8..7f685458 100644 --- a/include/reactphysics3d/engine/PhysicsCommon.h +++ b/include/reactphysics3d/engine/PhysicsCommon.h @@ -92,8 +92,17 @@ class PhysicsCommon { /// Set of default loggers Set mDefaultLoggers; + /// Half-edge structure of a box polyhedron + HalfEdgeStructure mBoxShapeHalfEdgeStructure; + + /// Half-edge structure of a triangle shape + HalfEdgeStructure mTriangleShapeHalfEdgeStructure; + // -------------------- Methods -------------------- // + /// Initialization + void init(); + /// Destroy and release everything that has been allocated void release(); @@ -127,6 +136,12 @@ class PhysicsCommon { /// Delete a default logger void deleteDefaultLogger(DefaultLogger* logger); + /// Initialize the half-edge structure of a BoxShape + void initBoxShapeHalfEdgeStructure(); + + /// Initialize the static half-edge structure of a TriangleShape + void initTriangleShapeHalfEdgeStructure(); + // If profiling is enabled #ifdef IS_RP3D_PROFILING_ENABLED @@ -219,6 +234,13 @@ class PhysicsCommon { /// Set the logger static void setLogger(Logger* logger); + + + // ---------- Friendship ---------- // + + friend class BoxShape; + friend class TriangleShape; + friend class PhysicsWorld; }; // Return the current logger diff --git a/include/reactphysics3d/engine/PhysicsWorld.h b/include/reactphysics3d/engine/PhysicsWorld.h index bafe96c7..a6f894eb 100644 --- a/include/reactphysics3d/engine/PhysicsWorld.h +++ b/include/reactphysics3d/engine/PhysicsWorld.h @@ -59,6 +59,7 @@ namespace reactphysics3d { // Declarations class Island; class RigidBody; +class PhysicsCommon; struct JointInfo; // Class PhysicsWorld @@ -275,7 +276,7 @@ class PhysicsWorld { // -------------------- Methods -------------------- // /// Constructor - PhysicsWorld(MemoryManager& memoryManager, const WorldSettings& worldSettings = WorldSettings(), Profiler* profiler = nullptr); + PhysicsWorld(MemoryManager& memoryManager, PhysicsCommon& physicsCommon, const WorldSettings& worldSettings = WorldSettings(), Profiler* profiler = nullptr); /// Notify the world if a body is disabled (slepping or inactive) or not void setBodyDisabled(Entity entity, bool isDisabled); diff --git a/include/reactphysics3d/systems/CollisionDetectionSystem.h b/include/reactphysics3d/systems/CollisionDetectionSystem.h index 29b21d73..a978fd3a 100644 --- a/include/reactphysics3d/systems/CollisionDetectionSystem.h +++ b/include/reactphysics3d/systems/CollisionDetectionSystem.h @@ -43,6 +43,7 @@ #include #include #include +#include /// ReactPhysics3D namespace namespace reactphysics3d { @@ -168,6 +169,9 @@ class CollisionDetectionSystem { /// Number of potential contact points in the previous frame uint32 mNbPreviousPotentialContactPoints; + /// Reference to the half-edge structure of the triangle polyhedron + HalfEdgeStructure& mTriangleHalfEdgeStructure; + #ifdef IS_RP3D_PROFILING_ENABLED /// Pointer to the profiler @@ -294,7 +298,7 @@ class CollisionDetectionSystem { /// Constructor CollisionDetectionSystem(PhysicsWorld* world, ColliderComponents& collidersComponents, TransformComponents& transformComponents, CollisionBodyComponents& collisionBodyComponents, RigidBodyComponents& rigidBodyComponents, - MemoryManager& memoryManager); + MemoryManager& memoryManager, HalfEdgeStructure& triangleHalfEdgeStructure); /// Destructor ~CollisionDetectionSystem() = default; diff --git a/src/collision/HalfEdgeStructure.cpp b/src/collision/HalfEdgeStructure.cpp index 5ec064fa..e71e35e1 100644 --- a/src/collision/HalfEdgeStructure.cpp +++ b/src/collision/HalfEdgeStructure.cpp @@ -47,7 +47,7 @@ void HalfEdgeStructure::init() { const uint32 nbFaces = mFaces.size(); for (uint32 f=0; f < nbFaces; f++) { - Face face = mFaces[f]; + Face& face = mFaces[f]; VerticesPair firstEdgeKey(0, 0); diff --git a/src/collision/PolyhedronMesh.cpp b/src/collision/PolyhedronMesh.cpp index b205b1cd..f48f0e46 100644 --- a/src/collision/PolyhedronMesh.cpp +++ b/src/collision/PolyhedronMesh.cpp @@ -177,7 +177,8 @@ Vector3 PolyhedronMesh::getVertex(uint index) const { void PolyhedronMesh::computeFacesNormals() { // For each face - for (uint f=0; f < mHalfEdgeStructure.getNbFaces(); f++) { + const uint32 nbFaces = mHalfEdgeStructure.getNbFaces(); + for (uint f=0; f < nbFaces; f++) { const HalfEdgeStructure::Face& face = mHalfEdgeStructure.getFace(f); assert(face.faceVertices.size() >= 3); diff --git a/src/collision/shapes/BoxShape.cpp b/src/collision/shapes/BoxShape.cpp index 35448295..51335e0a 100644 --- a/src/collision/shapes/BoxShape.cpp +++ b/src/collision/shapes/BoxShape.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -37,46 +38,12 @@ using namespace reactphysics3d; /** * @param halfExtents The vector with the three half-extents of the box */ -BoxShape::BoxShape(const Vector3& halfExtents, MemoryAllocator& allocator) - : ConvexPolyhedronShape(CollisionShapeName::BOX, allocator), mHalfExtents(halfExtents), - mHalfEdgeStructure(allocator, 6, 8, 24) { +BoxShape::BoxShape(const Vector3& halfExtents, MemoryAllocator& allocator, PhysicsCommon& physicsCommon) + : ConvexPolyhedronShape(CollisionShapeName::BOX, allocator), mHalfExtents(halfExtents), mPhysicsCommon(physicsCommon) { assert(halfExtents.x > decimal(0.0)); assert(halfExtents.y > decimal(0.0)); assert(halfExtents.z > decimal(0.0)); - - // Vertices - mHalfEdgeStructure.addVertex(0); - mHalfEdgeStructure.addVertex(1); - mHalfEdgeStructure.addVertex(2); - mHalfEdgeStructure.addVertex(3); - mHalfEdgeStructure.addVertex(4); - mHalfEdgeStructure.addVertex(5); - mHalfEdgeStructure.addVertex(6); - mHalfEdgeStructure.addVertex(7); - - // Faces - Array face0(allocator, 4); - face0.add(0); face0.add(1); face0.add(2); face0.add(3); - Array face1(allocator, 4); - face1.add(1); face1.add(5); face1.add(6); face1.add(2); - Array face2(allocator, 4); - face2.add(4); face2.add(7); face2.add(6); face2.add(5); - Array face3(allocator, 4); - face3.add(4); face3.add(0); face3.add(3); face3.add(7); - Array face4(allocator, 4); - face4.add(4); face4.add(5); face4.add(1); face4.add(0); - Array face5(allocator, 4); - face5.add(2); face5.add(6); face5.add(7); face5.add(3); - - mHalfEdgeStructure.addFace(face0); - mHalfEdgeStructure.addFace(face1); - mHalfEdgeStructure.addFace(face2); - mHalfEdgeStructure.addFace(face3); - mHalfEdgeStructure.addFace(face4); - mHalfEdgeStructure.addFace(face5); - - mHalfEdgeStructure.init(); } // Return the local inertia tensor of the collision shape @@ -155,3 +122,21 @@ bool BoxShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, Collider* colli return true; } + +// Return a given face of the polyhedron +const HalfEdgeStructure::Face& BoxShape::getFace(uint faceIndex) const { + assert(faceIndex < mPhysicsCommon.mBoxShapeHalfEdgeStructure.getNbFaces()); + return mPhysicsCommon.mBoxShapeHalfEdgeStructure.getFace(faceIndex); +} + +// Return a given vertex of the polyhedron +HalfEdgeStructure::Vertex BoxShape::getVertex(uint vertexIndex) const { + assert(vertexIndex < getNbVertices()); + return mPhysicsCommon.mBoxShapeHalfEdgeStructure.getVertex(vertexIndex); +} + +// Return a given half-edge of the polyhedron +const HalfEdgeStructure::Edge& BoxShape::getHalfEdge(uint edgeIndex) const { + assert(edgeIndex < getNbHalfEdges()); + return mPhysicsCommon.mBoxShapeHalfEdgeStructure.getHalfEdge(edgeIndex); +} diff --git a/src/collision/shapes/ConcaveMeshShape.cpp b/src/collision/shapes/ConcaveMeshShape.cpp index cedb55f2..77703c92 100644 --- a/src/collision/shapes/ConcaveMeshShape.cpp +++ b/src/collision/shapes/ConcaveMeshShape.cpp @@ -34,8 +34,8 @@ using namespace reactphysics3d; // Constructor -ConcaveMeshShape::ConcaveMeshShape(TriangleMesh* triangleMesh, MemoryAllocator& allocator, const Vector3& scaling) - : ConcaveShape(CollisionShapeName::TRIANGLE_MESH, allocator, scaling), mDynamicAABBTree(allocator) { +ConcaveMeshShape::ConcaveMeshShape(TriangleMesh* triangleMesh, MemoryAllocator& allocator, HalfEdgeStructure& triangleHalfEdgeStructure, const Vector3& scaling) + : ConcaveShape(CollisionShapeName::TRIANGLE_MESH, allocator, scaling), mDynamicAABBTree(allocator), mTriangleHalfEdgeStructure(triangleHalfEdgeStructure) { mTriangleMesh = triangleMesh; mRaycastTestType = TriangleRaycastSide::FRONT; @@ -247,7 +247,7 @@ void ConcaveMeshRaycastCallback::raycastTriangles() { mConcaveMeshShape.getTriangleVerticesNormals(data[0], data[1], verticesNormals); // Create a triangle collision shape - TriangleShape triangleShape(trianglePoints, verticesNormals, mConcaveMeshShape.computeTriangleShapeId(data[0], data[1]), mAllocator); + TriangleShape triangleShape(trianglePoints, verticesNormals, mConcaveMeshShape.computeTriangleShapeId(data[0], data[1]), mConcaveMeshShape.mTriangleHalfEdgeStructure, mAllocator); triangleShape.setRaycastTestType(mConcaveMeshShape.getRaycastTestType()); #ifdef IS_RP3D_PROFILING_ENABLED diff --git a/src/collision/shapes/HeightFieldShape.cpp b/src/collision/shapes/HeightFieldShape.cpp index 3322d88d..f3693fc1 100644 --- a/src/collision/shapes/HeightFieldShape.cpp +++ b/src/collision/shapes/HeightFieldShape.cpp @@ -42,12 +42,13 @@ using namespace reactphysics3d; * @param integerHeightScale Scaling factor used to scale the height values (only when height values type is integer) */ HeightFieldShape::HeightFieldShape(int nbGridColumns, int nbGridRows, decimal minHeight, decimal maxHeight, - const void* heightFieldData, HeightDataType dataType, MemoryAllocator& allocator, int upAxis, + const void* heightFieldData, HeightDataType dataType, MemoryAllocator& allocator, + HalfEdgeStructure& triangleHalfEdgeStructure, int upAxis, decimal integerHeightScale, const Vector3& scaling) : ConcaveShape(CollisionShapeName::HEIGHTFIELD, allocator, scaling), mNbColumns(nbGridColumns), mNbRows(nbGridRows), mWidth(nbGridColumns - 1), mLength(nbGridRows - 1), mMinHeight(minHeight), mMaxHeight(maxHeight), mUpAxis(upAxis), mIntegerHeightScale(integerHeightScale), - mHeightDataType(dataType) { + mHeightDataType(dataType), mTriangleHalfEdgeStructure(triangleHalfEdgeStructure) { assert(nbGridColumns >= 2); assert(nbGridRows >= 2); @@ -254,7 +255,7 @@ bool HeightFieldShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, Collide for (uint32 i=0; i < nbShapeIds; i++) { // Create a triangle collision shape - TriangleShape triangleShape(&(triangleVertices[i * 3]), &(triangleVerticesNormals[i * 3]), shapeIds[i], allocator); + TriangleShape triangleShape(&(triangleVertices[i * 3]), &(triangleVerticesNormals[i * 3]), shapeIds[i], mTriangleHalfEdgeStructure, allocator); triangleShape.setRaycastTestType(getRaycastTestType()); #ifdef IS_RP3D_PROFILING_ENABLED diff --git a/src/collision/shapes/TriangleShape.cpp b/src/collision/shapes/TriangleShape.cpp index 091d2507..f2150e05 100644 --- a/src/collision/shapes/TriangleShape.cpp +++ b/src/collision/shapes/TriangleShape.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -45,9 +46,8 @@ using namespace reactphysics3d; * @param verticesNormals The three vertices normals for smooth mesh collision * @param margin The collision margin (in meters) around the collision shape */ -TriangleShape::TriangleShape(const Vector3* vertices, const Vector3* verticesNormals, uint shapeId, - MemoryAllocator& allocator) - : ConvexPolyhedronShape(CollisionShapeName::TRIANGLE, allocator), mFaces{HalfEdgeStructure::Face(allocator), HalfEdgeStructure::Face(allocator)} { +TriangleShape::TriangleShape(const Vector3* vertices, const Vector3* verticesNormals, uint shapeId, HalfEdgeStructure& triangleHalfEdgeStructure, MemoryAllocator& allocator) + : ConvexPolyhedronShape(CollisionShapeName::TRIANGLE, allocator), mTriangleHalfEdgeStructure(triangleHalfEdgeStructure) { mPoints[0] = vertices[0]; mPoints[1] = vertices[1]; @@ -61,62 +61,6 @@ TriangleShape::TriangleShape(const Vector3* vertices, const Vector3* verticesNor mVerticesNormals[1] = verticesNormals[1]; mVerticesNormals[2] = verticesNormals[2]; - // Faces - mFaces[0].faceVertices.reserve(3); - mFaces[0].faceVertices.add(0); - mFaces[0].faceVertices.add(1); - mFaces[0].faceVertices.add(2); - mFaces[0].edgeIndex = 0; - - mFaces[1].faceVertices.reserve(3); - mFaces[1].faceVertices.add(0); - mFaces[1].faceVertices.add(2); - mFaces[1].faceVertices.add(1); - mFaces[1].edgeIndex = 1; - - // Edges - for (uint i=0; i<6; i++) { - switch(i) { - case 0: - mEdges[0].vertexIndex = 0; - mEdges[0].twinEdgeIndex = 1; - mEdges[0].faceIndex = 0; - mEdges[0].nextEdgeIndex = 2; - break; - case 1: - mEdges[1].vertexIndex = 1; - mEdges[1].twinEdgeIndex = 0; - mEdges[1].faceIndex = 1; - mEdges[1].nextEdgeIndex = 5; - break; - case 2: - mEdges[2].vertexIndex = 1; - mEdges[2].twinEdgeIndex = 3; - mEdges[2].faceIndex = 0; - mEdges[2].nextEdgeIndex = 4; - break; - case 3: - mEdges[3].vertexIndex = 2; - mEdges[3].twinEdgeIndex = 2; - mEdges[3].faceIndex = 1; - mEdges[3].nextEdgeIndex = 1; - break; - case 4: - mEdges[4].vertexIndex = 2; - mEdges[4].twinEdgeIndex = 5; - mEdges[4].faceIndex = 0; - mEdges[4].nextEdgeIndex = 0; - break; - case 5: - mEdges[5].vertexIndex = 0; - mEdges[5].twinEdgeIndex = 4; - mEdges[5].faceIndex = 1; - mEdges[5].nextEdgeIndex = 3; - break; - } - } - - mRaycastTestType = TriangleRaycastSide::FRONT; mId = shapeId; @@ -249,4 +193,3 @@ bool TriangleShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, Collider* return true; } - diff --git a/src/engine/PhysicsCommon.cpp b/src/engine/PhysicsCommon.cpp index a36e6e26..7d774fa2 100644 --- a/src/engine/PhysicsCommon.cpp +++ b/src/engine/PhysicsCommon.cpp @@ -42,8 +42,11 @@ PhysicsCommon::PhysicsCommon(MemoryAllocator* baseMemoryAllocator) mConvexMeshShapes(mMemoryManager.getHeapAllocator()), mConcaveMeshShapes(mMemoryManager.getHeapAllocator()), mHeightFieldShapes(mMemoryManager.getHeapAllocator()), mPolyhedronMeshes(mMemoryManager.getHeapAllocator()), mTriangleMeshes(mMemoryManager.getHeapAllocator()), - mProfilers(mMemoryManager.getHeapAllocator()), mDefaultLoggers(mMemoryManager.getHeapAllocator()) { + mProfilers(mMemoryManager.getHeapAllocator()), mDefaultLoggers(mMemoryManager.getHeapAllocator()), + mBoxShapeHalfEdgeStructure(mMemoryManager.getHeapAllocator(), 6, 8, 24), + mTriangleShapeHalfEdgeStructure(mMemoryManager.getHeapAllocator(), 2, 3, 6) { + init(); } // Destructor @@ -53,6 +56,77 @@ PhysicsCommon::~PhysicsCommon() { release(); } +/// Initialization +void PhysicsCommon::init() { + + // Initialize the static half-edge structure for the BoxShape collision shape + initBoxShapeHalfEdgeStructure(); + + // Initialize the static half-edge structure for the TriangleShape collision shape + initTriangleShapeHalfEdgeStructure(); +} + +// Initialize the static half-edge structure of a BoxShape +void PhysicsCommon::initBoxShapeHalfEdgeStructure() { + + // Vertices + mBoxShapeHalfEdgeStructure.addVertex(0); + mBoxShapeHalfEdgeStructure.addVertex(1); + mBoxShapeHalfEdgeStructure.addVertex(2); + mBoxShapeHalfEdgeStructure.addVertex(3); + mBoxShapeHalfEdgeStructure.addVertex(4); + mBoxShapeHalfEdgeStructure.addVertex(5); + mBoxShapeHalfEdgeStructure.addVertex(6); + mBoxShapeHalfEdgeStructure.addVertex(7); + + MemoryAllocator& allocator = mMemoryManager.getHeapAllocator(); + + // Faces + Array face0(allocator, 4); + face0.add(0); face0.add(1); face0.add(2); face0.add(3); + Array face1(allocator, 4); + face1.add(1); face1.add(5); face1.add(6); face1.add(2); + Array face2(allocator, 4); + face2.add(4); face2.add(7); face2.add(6); face2.add(5); + Array face3(allocator, 4); + face3.add(4); face3.add(0); face3.add(3); face3.add(7); + Array face4(allocator, 4); + face4.add(4); face4.add(5); face4.add(1); face4.add(0); + Array face5(allocator, 4); + face5.add(2); face5.add(6); face5.add(7); face5.add(3); + + mBoxShapeHalfEdgeStructure.addFace(face0); + mBoxShapeHalfEdgeStructure.addFace(face1); + mBoxShapeHalfEdgeStructure.addFace(face2); + mBoxShapeHalfEdgeStructure.addFace(face3); + mBoxShapeHalfEdgeStructure.addFace(face4); + mBoxShapeHalfEdgeStructure.addFace(face5); + + mBoxShapeHalfEdgeStructure.init(); +} + +// Initialize the static half-edge structure of a TriangleShape +void PhysicsCommon::initTriangleShapeHalfEdgeStructure() { + + // Vertices + mTriangleShapeHalfEdgeStructure.addVertex(0); + mTriangleShapeHalfEdgeStructure.addVertex(1); + mTriangleShapeHalfEdgeStructure.addVertex(2); + + MemoryAllocator& allocator = mMemoryManager.getHeapAllocator(); + + // Faces + Array face0(allocator, 3); + face0.add(0); face0.add(1); face0.add(2); + Array face1(allocator, 3); + face1.add(0); face1.add(2); face1.add(1); + + mTriangleShapeHalfEdgeStructure.addFace(face0); + mTriangleShapeHalfEdgeStructure.addFace(face1); + + mTriangleShapeHalfEdgeStructure.init(); +} + // Destroy and release everything that has been allocated void PhysicsCommon::release() { @@ -149,7 +223,7 @@ PhysicsWorld* PhysicsCommon::createPhysicsWorld(const PhysicsWorld::WorldSetting #endif - PhysicsWorld* world = new(mMemoryManager.allocate(MemoryManager::AllocationType::Heap, sizeof(PhysicsWorld))) PhysicsWorld(mMemoryManager, worldSettings, profiler); + PhysicsWorld* world = new(mMemoryManager.allocate(MemoryManager::AllocationType::Heap, sizeof(PhysicsWorld))) PhysicsWorld(mMemoryManager, *this, worldSettings, profiler); mPhysicsWorlds.add(world); @@ -242,7 +316,7 @@ BoxShape* PhysicsCommon::createBoxShape(const Vector3& halfExtents) { RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::PhysicCommon, "Error when creating a BoxShape: the half extents must be positive values", __FILE__, __LINE__); } - BoxShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(BoxShape))) BoxShape(halfExtents, mMemoryManager.getHeapAllocator()); + BoxShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(BoxShape))) BoxShape(halfExtents, mMemoryManager.getHeapAllocator(), *this); mBoxShapes.add(shape); @@ -401,7 +475,7 @@ HeightFieldShape* PhysicsCommon::createHeightFieldShape(int nbGridColumns, int n int upAxis, decimal integerHeightScale, const Vector3& scaling) { HeightFieldShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(HeightFieldShape))) HeightFieldShape(nbGridColumns, nbGridRows, minHeight, maxHeight, - heightFieldData, dataType, mMemoryManager.getHeapAllocator(), upAxis, integerHeightScale, scaling); + heightFieldData, dataType, mMemoryManager.getHeapAllocator(), mTriangleShapeHalfEdgeStructure, upAxis, integerHeightScale, scaling); mHeightFieldShapes.add(shape); @@ -447,7 +521,8 @@ void PhysicsCommon::deleteHeightFieldShape(HeightFieldShape* heightFieldShape) { */ ConcaveMeshShape* PhysicsCommon::createConcaveMeshShape(TriangleMesh* triangleMesh, const Vector3& scaling) { - ConcaveMeshShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(ConcaveMeshShape))) ConcaveMeshShape(triangleMesh, mMemoryManager.getHeapAllocator(), scaling); + ConcaveMeshShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(ConcaveMeshShape))) ConcaveMeshShape(triangleMesh, + mMemoryManager.getHeapAllocator(), mTriangleShapeHalfEdgeStructure, scaling); mConcaveMeshShapes.add(shape); diff --git a/src/engine/PhysicsWorld.cpp b/src/engine/PhysicsWorld.cpp index 19a4bca3..a6fe538d 100644 --- a/src/engine/PhysicsWorld.cpp +++ b/src/engine/PhysicsWorld.cpp @@ -50,14 +50,14 @@ uint PhysicsWorld::mNbWorlds = 0; * @param worldSettings The settings of the world * @param profiler Pointer to the profiler */ -PhysicsWorld::PhysicsWorld(MemoryManager& memoryManager, const WorldSettings& worldSettings, Profiler* profiler) +PhysicsWorld::PhysicsWorld(MemoryManager& memoryManager, PhysicsCommon& physicsCommon, const WorldSettings& worldSettings, Profiler* profiler) : mMemoryManager(memoryManager), mConfig(worldSettings), mEntityManager(mMemoryManager.getHeapAllocator()), mDebugRenderer(mMemoryManager.getHeapAllocator()), mCollisionBodyComponents(mMemoryManager.getHeapAllocator()), mRigidBodyComponents(mMemoryManager.getHeapAllocator()), mTransformComponents(mMemoryManager.getHeapAllocator()), mCollidersComponents(mMemoryManager.getHeapAllocator()), mJointsComponents(mMemoryManager.getHeapAllocator()), mBallAndSocketJointsComponents(mMemoryManager.getHeapAllocator()), mFixedJointsComponents(mMemoryManager.getHeapAllocator()), mHingeJointsComponents(mMemoryManager.getHeapAllocator()), mSliderJointsComponents(mMemoryManager.getHeapAllocator()), mCollisionDetection(this, mCollidersComponents, mTransformComponents, mCollisionBodyComponents, mRigidBodyComponents, - mMemoryManager), + mMemoryManager, physicsCommon.mTriangleShapeHalfEdgeStructure), mCollisionBodies(mMemoryManager.getHeapAllocator()), mEventListener(nullptr), mName(worldSettings.worldName), mIslands(mMemoryManager.getSingleFrameAllocator()), mProcessContactPairsOrderIslands(mMemoryManager.getSingleFrameAllocator()), mContactSolverSystem(mMemoryManager, *this, mIslands, mCollisionBodyComponents, mRigidBodyComponents, diff --git a/src/systems/CollisionDetectionSystem.cpp b/src/systems/CollisionDetectionSystem.cpp index b09c338a..3cb40a27 100644 --- a/src/systems/CollisionDetectionSystem.cpp +++ b/src/systems/CollisionDetectionSystem.cpp @@ -51,7 +51,7 @@ using namespace std; // Constructor CollisionDetectionSystem::CollisionDetectionSystem(PhysicsWorld* world, ColliderComponents& collidersComponents, TransformComponents& transformComponents, CollisionBodyComponents& collisionBodyComponents, RigidBodyComponents& rigidBodyComponents, - MemoryManager& memoryManager) + MemoryManager& memoryManager, HalfEdgeStructure& triangleHalfEdgeStructure) : mMemoryManager(memoryManager), mCollidersComponents(collidersComponents), mRigidBodyComponents(rigidBodyComponents), mCollisionDispatch(mMemoryManager.getPoolAllocator()), mWorld(world), mNoCollisionPairs(mMemoryManager.getPoolAllocator()), @@ -68,7 +68,7 @@ CollisionDetectionSystem::CollisionDetectionSystem(PhysicsWorld* world, Collider mPreviousContactManifolds(&mContactManifolds1), mCurrentContactManifolds(&mContactManifolds2), mContactPoints1(mMemoryManager.getPoolAllocator()), mContactPoints2(mMemoryManager.getPoolAllocator()), mPreviousContactPoints(&mContactPoints1), mCurrentContactPoints(&mContactPoints2), mCollisionBodyContactPairsIndices(mMemoryManager.getSingleFrameAllocator()), - mNbPreviousPotentialContactManifolds(0), mNbPreviousPotentialContactPoints(0) { + mNbPreviousPotentialContactManifolds(0), mNbPreviousPotentialContactPoints(0), mTriangleHalfEdgeStructure(triangleHalfEdgeStructure) { #ifdef IS_RP3D_PROFILING_ENABLED @@ -486,7 +486,7 @@ void CollisionDetectionSystem::computeConvexVsConcaveMiddlePhase(OverlappingPair // Create a triangle collision shape (the allocated memory for the TriangleShape will be released in the // destructor of the corresponding NarrowPhaseInfo. TriangleShape* triangleShape = new (allocator.allocate(sizeof(TriangleShape))) - TriangleShape(&(triangleVertices[i * 3]), &(triangleVerticesNormals[i * 3]), shapeIds[i], allocator); + TriangleShape(&(triangleVertices[i * 3]), &(triangleVerticesNormals[i * 3]), shapeIds[i], mTriangleHalfEdgeStructure, allocator); #ifdef IS_RP3D_PROFILING_ENABLED