Many small optimizations

This commit is contained in:
Daniel Chappuis 2017-12-04 22:14:52 +01:00
parent 4cc024b85e
commit 4f76553c59
30 changed files with 235 additions and 204 deletions

View File

@ -273,7 +273,7 @@ void CollisionDetection::computeNarrowPhase() {
// Use the narrow-phase collision detection algorithm to check // Use the narrow-phase collision detection algorithm to check
// if there really is a collision. If a collision occurs, the // if there really is a collision. If a collision occurs, the
// notifyContact() callback method will be called. // notifyContact() callback method will be called.
if (narrowPhaseAlgorithm->testCollision(currentNarrowPhaseInfo, true)) { if (narrowPhaseAlgorithm->testCollision(currentNarrowPhaseInfo, true, mSingleFrameAllocator)) {
// Add the contact points as a potential contact manifold into the pair // Add the contact points as a potential contact manifold into the pair
currentNarrowPhaseInfo->addContactPointsAsPotentialContactManifold(); currentNarrowPhaseInfo->addContactPointsAsPotentialContactManifold();
@ -593,7 +593,7 @@ bool CollisionDetection::testOverlap(CollisionBody* body1, CollisionBody* body2)
// Use the narrow-phase collision detection algorithm to check // Use the narrow-phase collision detection algorithm to check
// if there really is a collision. If a collision occurs, the // if there really is a collision. If a collision occurs, the
// notifyContact() callback method will be called. // notifyContact() callback method will be called.
isColliding |= narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, false); isColliding |= narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, false, mPoolAllocator);
} }
} }
@ -688,7 +688,7 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
// Use the narrow-phase collision detection algorithm to check // Use the narrow-phase collision detection algorithm to check
// if there really is a collision. If a collision occurs, the // if there really is a collision. If a collision occurs, the
// notifyContact() callback method will be called. // notifyContact() callback method will be called.
isColliding |= narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, false); isColliding |= narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, false, mPoolAllocator);
} }
} }
@ -767,7 +767,7 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body
// Use the narrow-phase collision detection algorithm to check // Use the narrow-phase collision detection algorithm to check
// if there really is a collision. If a collision occurs, the // if there really is a collision. If a collision occurs, the
// notifyContact() callback method will be called. // notifyContact() callback method will be called.
if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true)) { if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true, mPoolAllocator)) {
// Add the contact points as a potential contact manifold into the pair // Add the contact points as a potential contact manifold into the pair
narrowPhaseInfo->addContactPointsAsPotentialContactManifold(); narrowPhaseInfo->addContactPointsAsPotentialContactManifold();
@ -859,7 +859,7 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
// Use the narrow-phase collision detection algorithm to check // Use the narrow-phase collision detection algorithm to check
// if there really is a collision. If a collision occurs, the // if there really is a collision. If a collision occurs, the
// notifyContact() callback method will be called. // notifyContact() callback method will be called.
if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true)) { if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true, mPoolAllocator)) {
// Add the contact points as a potential contact manifold into the pair // Add the contact points as a potential contact manifold into the pair
narrowPhaseInfo->addContactPointsAsPotentialContactManifold(); narrowPhaseInfo->addContactPointsAsPotentialContactManifold();
@ -943,7 +943,7 @@ void CollisionDetection::testCollision(CollisionCallback* callback) {
// Use the narrow-phase collision detection algorithm to check // Use the narrow-phase collision detection algorithm to check
// if there really is a collision. If a collision occurs, the // if there really is a collision. If a collision occurs, the
// notifyContact() callback method will be called. // notifyContact() callback method will be called.
if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true)) { if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true, mPoolAllocator)) {
// Add the contact points as a potential contact manifold into the pair // Add the contact points as a potential contact manifold into the pair
narrowPhaseInfo->addContactPointsAsPotentialContactManifold(); narrowPhaseInfo->addContactPointsAsPotentialContactManifold();

View File

@ -150,7 +150,6 @@ class CollisionDetection {
/// Process the potential contacts where one collion is a concave shape /// Process the potential contacts where one collion is a concave shape
void processSmoothMeshContacts(OverlappingPair* pair); void processSmoothMeshContacts(OverlappingPair* pair);
public : public :

View File

@ -106,13 +106,13 @@ class HalfEdgeStructure {
uint getNbVertices() const; uint getNbVertices() const;
/// Return a given face /// Return a given face
Face getFace(uint index) const; const Face& getFace(uint index) const;
/// Return a given edge /// Return a given edge
Edge getHalfEdge(uint index) const; const Edge& getHalfEdge(uint index) const;
/// Return a given vertex /// Return a given vertex
Vertex getVertex(uint index) const; const Vertex& getVertex(uint index) const;
}; };
@ -133,33 +133,33 @@ inline void HalfEdgeStructure::addFace(std::vector<uint> faceVertices) {
// Return the number of faces // Return the number of faces
inline uint HalfEdgeStructure::getNbFaces() const { inline uint HalfEdgeStructure::getNbFaces() const {
return mFaces.size(); return static_cast<uint>(mFaces.size());
} }
// Return the number of edges // Return the number of edges
inline uint HalfEdgeStructure::getNbHalfEdges() const { inline uint HalfEdgeStructure::getNbHalfEdges() const {
return mEdges.size(); return static_cast<uint>(mEdges.size());
} }
// Return the number of vertices // Return the number of vertices
inline uint HalfEdgeStructure::getNbVertices() const { inline uint HalfEdgeStructure::getNbVertices() const {
return mVertices.size(); return static_cast<uint>(mVertices.size());
} }
// Return a given face // Return a given face
inline HalfEdgeStructure::Face HalfEdgeStructure::getFace(uint index) const { inline const HalfEdgeStructure::Face& HalfEdgeStructure::getFace(uint index) const {
assert(index < mFaces.size()); assert(index < mFaces.size());
return mFaces[index]; return mFaces[index];
} }
// Return a given edge // Return a given edge
inline HalfEdgeStructure::Edge HalfEdgeStructure::getHalfEdge(uint index) const { inline const HalfEdgeStructure::Edge& HalfEdgeStructure::getHalfEdge(uint index) const {
assert(index < mEdges.size()); assert(index < mEdges.size());
return mEdges[index]; return mEdges[index];
} }
// Return a given vertex // Return a given vertex
inline HalfEdgeStructure::Vertex HalfEdgeStructure::getVertex(uint index) const { inline const HalfEdgeStructure::Vertex& HalfEdgeStructure::getVertex(uint index) const {
assert(index < mVertices.size()); assert(index < mVertices.size());
return mVertices[index]; return mVertices[index];
} }

View File

@ -123,7 +123,7 @@ void PolyhedronMesh::computeFacesNormals() {
// For each face // For each face
for (uint f=0; f < mHalfEdgeStructure.getNbFaces(); f++) { for (uint f=0; f < mHalfEdgeStructure.getNbFaces(); f++) {
HalfEdgeStructure::Face face = mHalfEdgeStructure.getFace(f); const HalfEdgeStructure::Face& face = mHalfEdgeStructure.getFace(f);
assert(face.faceVertices.size() >= 3); assert(face.faceVertices.size() >= 3);

View File

@ -33,7 +33,8 @@ using namespace reactphysics3d;
// Compute the narrow-phase collision detection between two capsules // Compute the narrow-phase collision detection between two capsules
// This technique is based on the "Robust Contact Creation for Physics Simulations" presentation // This technique is based on the "Robust Contact Creation for Physics Simulations" presentation
// by Dirk Gregorius. // by Dirk Gregorius.
bool CapsuleVsCapsuleAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) { bool CapsuleVsCapsuleAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
Allocator& memoryAllocator) {
assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::CAPSULE); assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::CAPSULE);
assert(narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::CAPSULE); assert(narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::CAPSULE);

View File

@ -61,7 +61,7 @@ class CapsuleVsCapsuleAlgorithm : public NarrowPhaseAlgorithm {
CapsuleVsCapsuleAlgorithm& operator=(const CapsuleVsCapsuleAlgorithm& algorithm) = delete; CapsuleVsCapsuleAlgorithm& operator=(const CapsuleVsCapsuleAlgorithm& algorithm) = delete;
/// Compute the narrow-phase collision detection between two capsules /// Compute the narrow-phase collision detection between two capsules
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) override; virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, Allocator& memoryAllocator) override;
}; };
} }

View File

@ -37,11 +37,12 @@ using namespace reactphysics3d;
// Compute the narrow-phase collision detection between a capsule and a polyhedron // Compute the narrow-phase collision detection between a capsule and a polyhedron
// This technique is based on the "Robust Contact Creation for Physics Simulations" presentation // This technique is based on the "Robust Contact Creation for Physics Simulations" presentation
// by Dirk Gregorius. // by Dirk Gregorius.
bool CapsuleVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) { bool CapsuleVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
Allocator& memoryAllocator) {
// First, we run the GJK algorithm // First, we run the GJK algorithm
GJKAlgorithm gjkAlgorithm; GJKAlgorithm gjkAlgorithm;
SATAlgorithm satAlgorithm; SATAlgorithm satAlgorithm(memoryAllocator);
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
@ -85,9 +86,6 @@ bool CapsuleVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPh
// For each face of the polyhedron // For each face of the polyhedron
for (uint f = 0; f < polyhedron->getNbFaces(); f++) { for (uint f = 0; f < polyhedron->getNbFaces(); f++) {
// Get the face
HalfEdgeStructure::Face face = polyhedron->getFace(f);
const Transform polyhedronToWorld = isCapsuleShape1 ? narrowPhaseInfo->shape2ToWorldTransform : narrowPhaseInfo->shape1ToWorldTransform; const Transform polyhedronToWorld = isCapsuleShape1 ? narrowPhaseInfo->shape2ToWorldTransform : narrowPhaseInfo->shape1ToWorldTransform;
const Transform capsuleToWorld = isCapsuleShape1 ? narrowPhaseInfo->shape1ToWorldTransform : narrowPhaseInfo->shape2ToWorldTransform; const Transform capsuleToWorld = isCapsuleShape1 ? narrowPhaseInfo->shape1ToWorldTransform : narrowPhaseInfo->shape2ToWorldTransform;

View File

@ -61,7 +61,7 @@ class CapsuleVsConvexPolyhedronAlgorithm : public NarrowPhaseAlgorithm {
CapsuleVsConvexPolyhedronAlgorithm& operator=(const CapsuleVsConvexPolyhedronAlgorithm& algorithm) = delete; CapsuleVsConvexPolyhedronAlgorithm& operator=(const CapsuleVsConvexPolyhedronAlgorithm& algorithm) = delete;
/// Compute the narrow-phase collision detection between a capsule and a polyhedron /// Compute the narrow-phase collision detection between a capsule and a polyhedron
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) override; virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, Allocator& memoryAllocator) override;
}; };
} }

View File

@ -34,10 +34,11 @@ using namespace reactphysics3d;
// Compute the narrow-phase collision detection between two convex polyhedra // Compute the narrow-phase collision detection between two convex polyhedra
// This technique is based on the "Robust Contact Creation for Physics Simulations" presentation // This technique is based on the "Robust Contact Creation for Physics Simulations" presentation
// by Dirk Gregorius. // by Dirk Gregorius.
bool ConvexPolyhedronVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) { bool ConvexPolyhedronVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
Allocator& memoryAllocator) {
// Run the SAT algorithm to find the separating axis and compute contact point // Run the SAT algorithm to find the separating axis and compute contact point
SATAlgorithm satAlgorithm; SATAlgorithm satAlgorithm(memoryAllocator);
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE

View File

@ -61,7 +61,7 @@ class ConvexPolyhedronVsConvexPolyhedronAlgorithm : public NarrowPhaseAlgorithm
ConvexPolyhedronVsConvexPolyhedronAlgorithm& operator=(const ConvexPolyhedronVsConvexPolyhedronAlgorithm& algorithm) = delete; ConvexPolyhedronVsConvexPolyhedronAlgorithm& operator=(const ConvexPolyhedronVsConvexPolyhedronAlgorithm& algorithm) = delete;
/// Compute the narrow-phase collision detection between two convex polyhedra /// Compute the narrow-phase collision detection between two convex polyhedra
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) override; virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, Allocator& memoryAllocator) override;
}; };
} }

View File

@ -90,8 +90,9 @@ class NarrowPhaseAlgorithm {
/// Deleted assignment operator /// Deleted assignment operator
NarrowPhaseAlgorithm& operator=(const NarrowPhaseAlgorithm& algorithm) = delete; NarrowPhaseAlgorithm& operator=(const NarrowPhaseAlgorithm& algorithm) = delete;
/// Compute a contact info if the two bounding volume collide /// Compute a contact info if the two bounding volumes collide
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts)=0; virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
Allocator& memoryAllocator)=0;
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE

View File

@ -44,6 +44,11 @@ using namespace reactphysics3d;
// Static variables initialization // Static variables initialization
const decimal SATAlgorithm::SAME_SEPARATING_AXIS_BIAS = decimal(0.001); const decimal SATAlgorithm::SAME_SEPARATING_AXIS_BIAS = decimal(0.001);
// Constructor
SATAlgorithm::SATAlgorithm(Allocator& memoryAllocator) : mMemoryAllocator(memoryAllocator) {
}
// Test collision between a sphere and a convex mesh // Test collision between a sphere and a convex mesh
bool SATAlgorithm::testCollisionSphereVsConvexPolyhedron(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) const { bool SATAlgorithm::testCollisionSphereVsConvexPolyhedron(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) const {
@ -125,7 +130,7 @@ decimal SATAlgorithm::computePolyhedronFaceVsSpherePenetrationDepth(uint faceInd
PROFILE("SATAlgorithm::computePolyhedronFaceVsSpherePenetrationDepth)", mProfiler); PROFILE("SATAlgorithm::computePolyhedronFaceVsSpherePenetrationDepth)", mProfiler);
// Get the face // Get the face
HalfEdgeStructure::Face face = polyhedron->getFace(faceIndex); const HalfEdgeStructure::Face& face = polyhedron->getFace(faceIndex);
// Get the face normal // Get the face normal
const Vector3 faceNormal = polyhedron->getFaceNormal(faceIndex); const Vector3 faceNormal = polyhedron->getFaceNormal(faceIndex);
@ -200,12 +205,12 @@ bool SATAlgorithm::testCollisionCapsuleVsConvexPolyhedron(NarrowPhaseInfo* narro
for (uint e = 0; e < polyhedron->getNbHalfEdges(); e += 2) { for (uint e = 0; e < polyhedron->getNbHalfEdges(); e += 2) {
// Get an edge from the polyhedron (convert it into the capsule local-space) // Get an edge from the polyhedron (convert it into the capsule local-space)
HalfEdgeStructure::Edge edge = polyhedron->getHalfEdge(e); const HalfEdgeStructure::Edge& edge = polyhedron->getHalfEdge(e);
const Vector3 edgeVertex1 = polyhedron->getVertexPosition(edge.vertexIndex); const Vector3 edgeVertex1 = polyhedron->getVertexPosition(edge.vertexIndex);
const Vector3 edgeVertex2 = polyhedron->getVertexPosition(polyhedron->getHalfEdge(edge.nextEdgeIndex).vertexIndex); const Vector3 edgeVertex2 = polyhedron->getVertexPosition(polyhedron->getHalfEdge(edge.nextEdgeIndex).vertexIndex);
const Vector3 edgeDirectionCapsuleSpace = polyhedronToCapsuleTransform.getOrientation() * (edgeVertex2 - edgeVertex1); const Vector3 edgeDirectionCapsuleSpace = polyhedronToCapsuleTransform.getOrientation() * (edgeVertex2 - edgeVertex1);
HalfEdgeStructure::Edge twinEdge = polyhedron->getHalfEdge(edge.twinEdgeIndex); const HalfEdgeStructure::Edge& twinEdge = polyhedron->getHalfEdge(edge.twinEdgeIndex);
const Vector3 adjacentFace1Normal = polyhedronToCapsuleTransform.getOrientation() * polyhedron->getFaceNormal(edge.faceIndex); const Vector3 adjacentFace1Normal = polyhedronToCapsuleTransform.getOrientation() * polyhedron->getFaceNormal(edge.faceIndex);
const Vector3 adjacentFace2Normal = polyhedronToCapsuleTransform.getOrientation() * polyhedron->getFaceNormal(twinEdge.faceIndex); const Vector3 adjacentFace2Normal = polyhedronToCapsuleTransform.getOrientation() * polyhedron->getFaceNormal(twinEdge.faceIndex);
@ -336,7 +341,7 @@ decimal SATAlgorithm::computePolyhedronFaceVsCapsulePenetrationDepth(uint polyhe
PROFILE("SATAlgorithm::computePolyhedronFaceVsCapsulePenetrationDepth", mProfiler); PROFILE("SATAlgorithm::computePolyhedronFaceVsCapsulePenetrationDepth", mProfiler);
// Get the face // Get the face
HalfEdgeStructure::Face face = polyhedron->getFace(polyhedronFaceIndex); const HalfEdgeStructure::Face& face = polyhedron->getFace(polyhedronFaceIndex);
// Get the face normal // Get the face normal
const Vector3 faceNormal = polyhedron->getFaceNormal(polyhedronFaceIndex); const Vector3 faceNormal = polyhedron->getFaceNormal(polyhedronFaceIndex);
@ -361,7 +366,7 @@ bool SATAlgorithm::computeCapsulePolyhedronFaceContactPoints(uint referenceFaceI
PROFILE("SATAlgorithm::computeCapsulePolyhedronFaceContactPoints", mProfiler); PROFILE("SATAlgorithm::computeCapsulePolyhedronFaceContactPoints", mProfiler);
HalfEdgeStructure::Face face = polyhedron->getFace(referenceFaceIndex); const HalfEdgeStructure::Face& face = polyhedron->getFace(referenceFaceIndex);
// Get the face normal // Get the face normal
Vector3 faceNormal = polyhedron->getFaceNormal(referenceFaceIndex); Vector3 faceNormal = polyhedron->getFaceNormal(referenceFaceIndex);
@ -375,8 +380,8 @@ bool SATAlgorithm::computeCapsulePolyhedronFaceContactPoints(uint referenceFaceI
// For each adjacent edge of the separating face of the polyhedron // For each adjacent edge of the separating face of the polyhedron
do { do {
HalfEdgeStructure::Edge edge = polyhedron->getHalfEdge(edgeIndex); const HalfEdgeStructure::Edge& edge = polyhedron->getHalfEdge(edgeIndex);
HalfEdgeStructure::Edge twinEdge = polyhedron->getHalfEdge(edge.twinEdgeIndex); const HalfEdgeStructure::Edge& twinEdge = polyhedron->getHalfEdge(edge.twinEdgeIndex);
// Compute the edge vertices and edge direction // Compute the edge vertices and edge direction
Vector3 edgeV1 = polyhedron->getVertexPosition(edge.vertexIndex); Vector3 edgeV1 = polyhedron->getVertexPosition(edge.vertexIndex);
@ -575,8 +580,8 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn
} }
else { // If the previous separating axis (or axis with minimum penetration depth) was the cross product of two edges else { // If the previous separating axis (or axis with minimum penetration depth) was the cross product of two edges
HalfEdgeStructure::Edge edge1 = polyhedron1->getHalfEdge(lastFrameCollisionInfo->satMinEdge1Index); const HalfEdgeStructure::Edge& edge1 = polyhedron1->getHalfEdge(lastFrameCollisionInfo->satMinEdge1Index);
HalfEdgeStructure::Edge edge2 = polyhedron2->getHalfEdge(lastFrameCollisionInfo->satMinEdge2Index); const HalfEdgeStructure::Edge& edge2 = polyhedron2->getHalfEdge(lastFrameCollisionInfo->satMinEdge2Index);
Vector3 separatingAxisPolyhedron2Space; Vector3 separatingAxisPolyhedron2Space;
@ -669,7 +674,7 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn
for (uint i=0; i < polyhedron1->getNbHalfEdges(); i += 2) { for (uint i=0; i < polyhedron1->getNbHalfEdges(); i += 2) {
// Get an edge of polyhedron 1 // Get an edge of polyhedron 1
HalfEdgeStructure::Edge edge1 = polyhedron1->getHalfEdge(i); const HalfEdgeStructure::Edge& edge1 = polyhedron1->getHalfEdge(i);
const Vector3 edge1A = polyhedron1ToPolyhedron2 * polyhedron1->getVertexPosition(edge1.vertexIndex); const Vector3 edge1A = polyhedron1ToPolyhedron2 * polyhedron1->getVertexPosition(edge1.vertexIndex);
const Vector3 edge1B = polyhedron1ToPolyhedron2 * polyhedron1->getVertexPosition(polyhedron1->getHalfEdge(edge1.nextEdgeIndex).vertexIndex); const Vector3 edge1B = polyhedron1ToPolyhedron2 * polyhedron1->getVertexPosition(polyhedron1->getHalfEdge(edge1.nextEdgeIndex).vertexIndex);
@ -678,7 +683,7 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn
for (uint j=0; j < polyhedron2->getNbHalfEdges(); j += 2) { for (uint j=0; j < polyhedron2->getNbHalfEdges(); j += 2) {
// Get an edge of polyhedron 2 // Get an edge of polyhedron 2
HalfEdgeStructure::Edge edge2 = polyhedron2->getHalfEdge(j); const HalfEdgeStructure::Edge& edge2 = polyhedron2->getHalfEdge(j);
const Vector3 edge2A = polyhedron2->getVertexPosition(edge2.vertexIndex); const Vector3 edge2A = polyhedron2->getVertexPosition(edge2.vertexIndex);
const Vector3 edge2B = polyhedron2->getVertexPosition(polyhedron2->getHalfEdge(edge2.nextEdgeIndex).vertexIndex); const Vector3 edge2B = polyhedron2->getVertexPosition(polyhedron2->getHalfEdge(edge2.nextEdgeIndex).vertexIndex);
@ -816,23 +821,24 @@ bool SATAlgorithm::computePolyhedronVsPolyhedronFaceContactPoints(bool isMinPene
-(narrowPhaseInfo->shape2ToWorldTransform.getOrientation() * axisReferenceSpace); -(narrowPhaseInfo->shape2ToWorldTransform.getOrientation() * axisReferenceSpace);
// Get the reference face // Get the reference face
HalfEdgeStructure::Face referenceFace = referencePolyhedron->getFace(minFaceIndex); const HalfEdgeStructure::Face& referenceFace = referencePolyhedron->getFace(minFaceIndex);
// Find the incident face on the other polyhedron (most anti-parallel face) // Find the incident face on the other polyhedron (most anti-parallel face)
uint incidentFaceIndex = findMostAntiParallelFaceOnPolyhedron(incidentPolyhedron, axisIncidentSpace); uint incidentFaceIndex = findMostAntiParallelFaceOnPolyhedron(incidentPolyhedron, axisIncidentSpace);
// Get the incident face // Get the incident face
HalfEdgeStructure::Face incidentFace = incidentPolyhedron->getFace(incidentFaceIndex); const HalfEdgeStructure::Face& incidentFace = incidentPolyhedron->getFace(incidentFaceIndex);
std::vector<Vector3> polygonVertices; // Vertices to clip of the incident face uint nbIncidentFaceVertices = static_cast<uint>(incidentFace.faceVertices.size());
std::vector<Vector3> planesNormals; // Normals of the clipping planes List<Vector3> polygonVertices(mMemoryAllocator, nbIncidentFaceVertices); // Vertices to clip of the incident face
std::vector<Vector3> planesPoints; // Points on the clipping planes List<Vector3> planesNormals(mMemoryAllocator, nbIncidentFaceVertices); // Normals of the clipping planes
List<Vector3> planesPoints(mMemoryAllocator, nbIncidentFaceVertices); // Points on the clipping planes
// Get all the vertices of the incident face (in the reference local-space) // Get all the vertices of the incident face (in the reference local-space)
std::vector<uint>::const_iterator it; std::vector<uint>::const_iterator it;
for (it = incidentFace.faceVertices.begin(); it != incidentFace.faceVertices.end(); ++it) { for (it = incidentFace.faceVertices.begin(); it != incidentFace.faceVertices.end(); ++it) {
const Vector3 faceVertexIncidentSpace = incidentPolyhedron->getVertexPosition(*it); const Vector3 faceVertexIncidentSpace = incidentPolyhedron->getVertexPosition(*it);
polygonVertices.push_back(incidentToReferenceTransform * faceVertexIncidentSpace); polygonVertices.add(incidentToReferenceTransform * faceVertexIncidentSpace);
} }
// Get the reference face clipping planes // Get the reference face clipping planes
@ -841,10 +847,10 @@ bool SATAlgorithm::computePolyhedronVsPolyhedronFaceContactPoints(bool isMinPene
do { do {
// Get the adjacent edge // Get the adjacent edge
HalfEdgeStructure::Edge edge = referencePolyhedron->getHalfEdge(currentEdgeIndex); const HalfEdgeStructure::Edge& edge = referencePolyhedron->getHalfEdge(currentEdgeIndex);
// Get the twin edge // Get the twin edge
HalfEdgeStructure::Edge twinEdge = referencePolyhedron->getHalfEdge(edge.twinEdgeIndex); const HalfEdgeStructure::Edge& twinEdge = referencePolyhedron->getHalfEdge(edge.twinEdgeIndex);
// Compute the edge vertices and edge direction // Compute the edge vertices and edge direction
Vector3 edgeV1 = referencePolyhedron->getVertexPosition(edge.vertexIndex); Vector3 edgeV1 = referencePolyhedron->getVertexPosition(edge.vertexIndex);
@ -855,8 +861,8 @@ bool SATAlgorithm::computePolyhedronVsPolyhedronFaceContactPoints(bool isMinPene
// The clipping plane is perpendicular to the edge direction and the reference face normal // The clipping plane is perpendicular to the edge direction and the reference face normal
Vector3 clipPlaneNormal = axisReferenceSpace.cross(edgeDirection); Vector3 clipPlaneNormal = axisReferenceSpace.cross(edgeDirection);
planesNormals.push_back(clipPlaneNormal); planesNormals.add(clipPlaneNormal);
planesPoints.push_back(edgeV1); planesPoints.add(edgeV1);
// Go to the next adjacent edge of the reference face // Go to the next adjacent edge of the reference face
currentEdgeIndex = edge.nextEdgeIndex; currentEdgeIndex = edge.nextEdgeIndex;
@ -867,17 +873,16 @@ bool SATAlgorithm::computePolyhedronVsPolyhedronFaceContactPoints(bool isMinPene
assert(planesNormals.size() == planesPoints.size()); assert(planesNormals.size() == planesPoints.size());
// Clip the reference faces with the adjacent planes of the reference face // Clip the reference faces with the adjacent planes of the reference face
std::vector<Vector3> clipPolygonVertices = clipPolygonWithPlanes(polygonVertices, planesPoints, planesNormals); List<Vector3> clipPolygonVertices = clipPolygonWithPlanes(polygonVertices, planesPoints, planesNormals, mMemoryAllocator);
// We only keep the clipped points that are below the reference face // We only keep the clipped points that are below the reference face
const Vector3 referenceFaceVertex = referencePolyhedron->getVertexPosition(referencePolyhedron->getHalfEdge(firstEdgeIndex).vertexIndex); const Vector3 referenceFaceVertex = referencePolyhedron->getVertexPosition(referencePolyhedron->getHalfEdge(firstEdgeIndex).vertexIndex);
std::vector<Vector3>::const_iterator itPoints;
bool contactPointsFound = false; bool contactPointsFound = false;
for (itPoints = clipPolygonVertices.begin(); itPoints != clipPolygonVertices.end(); ++itPoints) { for (uint i=0; i<clipPolygonVertices.size(); i++) {
// Compute the penetration depth of this contact point (can be different from the minPenetration depth which is // Compute the penetration depth of this contact point (can be different from the minPenetration depth which is
// the maximal penetration depth of any contact point for this separating axis // the maximal penetration depth of any contact point for this separating axis
decimal penetrationDepth = (referenceFaceVertex - (*itPoints)).dot(axisReferenceSpace); decimal penetrationDepth = (referenceFaceVertex - clipPolygonVertices[i]).dot(axisReferenceSpace);
// If the clip point is bellow the reference face // If the clip point is bellow the reference face
if (penetrationDepth > decimal(0.0)) { if (penetrationDepth > decimal(0.0)) {
@ -887,10 +892,10 @@ bool SATAlgorithm::computePolyhedronVsPolyhedronFaceContactPoints(bool isMinPene
Vector3 outWorldNormal = normalWorld; Vector3 outWorldNormal = normalWorld;
// Convert the clip incident polyhedron vertex into the incident polyhedron local-space // Convert the clip incident polyhedron vertex into the incident polyhedron local-space
Vector3 contactPointIncidentPolyhedron = referenceToIncidentTransform * (*itPoints); Vector3 contactPointIncidentPolyhedron = referenceToIncidentTransform * clipPolygonVertices[i];
// Project the contact point onto the reference face // Project the contact point onto the reference face
Vector3 contactPointReferencePolyhedron = projectPointOntoPlane(*itPoints, axisReferenceSpace, referenceFaceVertex); Vector3 contactPointReferencePolyhedron = projectPointOntoPlane(clipPolygonVertices[i], axisReferenceSpace, referenceFaceVertex);
// Compute smooth triangle mesh contact if one of the two collision shapes is a triangle // Compute smooth triangle mesh contact if one of the two collision shapes is a triangle
TriangleShape::computeSmoothTriangleMeshContact(narrowPhaseInfo->collisionShape1, narrowPhaseInfo->collisionShape2, TriangleShape::computeSmoothTriangleMeshContact(narrowPhaseInfo->collisionShape1, narrowPhaseInfo->collisionShape2,
@ -968,7 +973,7 @@ decimal SATAlgorithm::testSingleFaceDirectionPolyhedronVsPolyhedron(const Convex
PROFILE("SATAlgorithm::testSingleFaceDirectionPolyhedronVsPolyhedron", mProfiler); PROFILE("SATAlgorithm::testSingleFaceDirectionPolyhedronVsPolyhedron", mProfiler);
HalfEdgeStructure::Face face = polyhedron1->getFace(faceIndex); const HalfEdgeStructure::Face& face = polyhedron1->getFace(faceIndex);
// Get the face normal // Get the face normal
const Vector3 faceNormal = polyhedron1->getFaceNormal(faceIndex); const Vector3 faceNormal = polyhedron1->getFaceNormal(faceIndex);

View File

@ -50,6 +50,9 @@ class SATAlgorithm {
/// make sure the contact manifold does not change too much between frames. /// make sure the contact manifold does not change too much between frames.
static const decimal SAME_SEPARATING_AXIS_BIAS; static const decimal SAME_SEPARATING_AXIS_BIAS;
/// Memory allocator
Allocator& mMemoryAllocator;
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
/// Pointer to the profiler /// Pointer to the profiler
@ -115,7 +118,7 @@ class SATAlgorithm {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
SATAlgorithm() = default; SATAlgorithm(Allocator& memoryAllocator);
/// Destructor /// Destructor
~SATAlgorithm() = default; ~SATAlgorithm() = default;

View File

@ -34,7 +34,8 @@ using namespace reactphysics3d;
// Compute the narrow-phase collision detection between a sphere and a capsule // Compute the narrow-phase collision detection between a sphere and a capsule
// This technique is based on the "Robust Contact Creation for Physics Simulations" presentation // This technique is based on the "Robust Contact Creation for Physics Simulations" presentation
// by Dirk Gregorius. // by Dirk Gregorius.
bool SphereVsCapsuleAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) { bool SphereVsCapsuleAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
Allocator& memoryAllocator) {
bool isSphereShape1 = narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::SPHERE; bool isSphereShape1 = narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::SPHERE;

View File

@ -61,7 +61,7 @@ class SphereVsCapsuleAlgorithm : public NarrowPhaseAlgorithm {
SphereVsCapsuleAlgorithm& operator=(const SphereVsCapsuleAlgorithm& algorithm) = delete; SphereVsCapsuleAlgorithm& operator=(const SphereVsCapsuleAlgorithm& algorithm) = delete;
/// Compute the narrow-phase collision detection between a sphere and a capsule /// Compute the narrow-phase collision detection between a sphere and a capsule
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) override; virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, Allocator& memoryAllocator) override;
}; };
} }

View File

@ -34,7 +34,8 @@ using namespace reactphysics3d;
// Compute the narrow-phase collision detection between a sphere and a convex polyhedron // Compute the narrow-phase collision detection between a sphere and a convex polyhedron
// This technique is based on the "Robust Contact Creation for Physics Simulations" presentation // This technique is based on the "Robust Contact Creation for Physics Simulations" presentation
// by Dirk Gregorius. // by Dirk Gregorius.
bool SphereVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) { bool SphereVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
Allocator& memoryAllocator) {
assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::CONVEX_POLYHEDRON || assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::CONVEX_POLYHEDRON ||
narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::CONVEX_POLYHEDRON); narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::CONVEX_POLYHEDRON);
@ -69,7 +70,7 @@ bool SphereVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPha
if (result == GJKAlgorithm::GJKResult::INTERPENETRATE) { if (result == GJKAlgorithm::GJKResult::INTERPENETRATE) {
// Run the SAT algorithm to find the separating axis and compute contact point // Run the SAT algorithm to find the separating axis and compute contact point
SATAlgorithm satAlgorithm; SATAlgorithm satAlgorithm(memoryAllocator);
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE

View File

@ -61,7 +61,7 @@ class SphereVsConvexPolyhedronAlgorithm : public NarrowPhaseAlgorithm {
SphereVsConvexPolyhedronAlgorithm& operator=(const SphereVsConvexPolyhedronAlgorithm& algorithm) = delete; SphereVsConvexPolyhedronAlgorithm& operator=(const SphereVsConvexPolyhedronAlgorithm& algorithm) = delete;
/// Compute the narrow-phase collision detection between a sphere and a convex polyhedron /// Compute the narrow-phase collision detection between a sphere and a convex polyhedron
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) override; virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, Allocator& memoryAllocator) override;
}; };
} }

View File

@ -30,7 +30,8 @@
// We want to use the ReactPhysics3D namespace // We want to use the ReactPhysics3D namespace
using namespace reactphysics3d; using namespace reactphysics3d;
bool SphereVsSphereAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) { bool SphereVsSphereAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
Allocator& memoryAllocator) {
assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::SPHERE); assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::SPHERE);
assert(narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::SPHERE); assert(narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::SPHERE);

View File

@ -61,7 +61,7 @@ class SphereVsSphereAlgorithm : public NarrowPhaseAlgorithm {
SphereVsSphereAlgorithm& operator=(const SphereVsSphereAlgorithm& algorithm) = delete; SphereVsSphereAlgorithm& operator=(const SphereVsSphereAlgorithm& algorithm) = delete;
/// Compute a contact info if the two bounding volume collide /// Compute a contact info if the two bounding volume collide
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) override; virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, Allocator& memoryAllocator) override;
}; };
} }

View File

@ -84,10 +84,9 @@ BoxShape::BoxShape(const Vector3& extent)
*/ */
void BoxShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const { void BoxShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const {
decimal factor = (decimal(1.0) / decimal(3.0)) * mass; decimal factor = (decimal(1.0) / decimal(3.0)) * mass;
Vector3 realExtent = mExtent + Vector3(mMargin, mMargin, mMargin); decimal xSquare = mExtent.x * mExtent.x;
decimal xSquare = realExtent.x * realExtent.x; decimal ySquare = mExtent.y * mExtent.y;
decimal ySquare = realExtent.y * realExtent.y; decimal zSquare = mExtent.z * mExtent.z;
decimal zSquare = realExtent.z * realExtent.z;
tensor.setAllValues(factor * (ySquare + zSquare), 0.0, 0.0, tensor.setAllValues(factor * (ySquare + zSquare), 0.0, 0.0,
0.0, factor * (xSquare + zSquare), 0.0, 0.0, factor * (xSquare + zSquare), 0.0,
0.0, 0.0, factor * (xSquare + ySquare)); 0.0, 0.0, factor * (xSquare + ySquare));

View File

@ -101,7 +101,7 @@ class BoxShape : public ConvexPolyhedronShape {
virtual uint getNbFaces() const override; virtual uint getNbFaces() const override;
/// Return a given face of the polyhedron /// Return a given face of the polyhedron
virtual HalfEdgeStructure::Face getFace(uint faceIndex) const override; virtual const HalfEdgeStructure::Face& getFace(uint faceIndex) const override;
/// Return the number of vertices of the polyhedron /// Return the number of vertices of the polyhedron
virtual uint getNbVertices() const override; virtual uint getNbVertices() const override;
@ -113,7 +113,7 @@ class BoxShape : public ConvexPolyhedronShape {
virtual uint getNbHalfEdges() const override; virtual uint getNbHalfEdges() const override;
/// Return a given half-edge of the polyhedron /// Return a given half-edge of the polyhedron
virtual HalfEdgeStructure::Edge getHalfEdge(uint edgeIndex) const override; virtual const HalfEdgeStructure::Edge& getHalfEdge(uint edgeIndex) const override;
/// Return the position of a given vertex /// Return the position of a given vertex
virtual Vector3 getVertexPosition(uint vertexIndex) const override; virtual Vector3 getVertexPosition(uint vertexIndex) const override;
@ -130,7 +130,7 @@ class BoxShape : public ConvexPolyhedronShape {
* @return The vector with the three extents of the box shape (in meters) * @return The vector with the three extents of the box shape (in meters)
*/ */
inline Vector3 BoxShape::getExtent() const { inline Vector3 BoxShape::getExtent() const {
return mExtent + Vector3(mMargin, mMargin, mMargin); return mExtent;
} }
// Set the scaling vector of the collision shape // Set the scaling vector of the collision shape
@ -150,7 +150,7 @@ inline void BoxShape::setLocalScaling(const Vector3& scaling) {
inline void BoxShape::getLocalBounds(Vector3& min, Vector3& max) const { inline void BoxShape::getLocalBounds(Vector3& min, Vector3& max) const {
// Maximum bounds // Maximum bounds
max = mExtent + Vector3(mMargin, mMargin, mMargin); max = mExtent;
// Minimum bounds // Minimum bounds
min = -max; min = -max;
@ -161,7 +161,7 @@ inline size_t BoxShape::getSizeInBytes() const {
return sizeof(BoxShape); return sizeof(BoxShape);
} }
// Return a local support point in a given direction without the objec margin // Return a local support point in a given direction without the object margin
inline Vector3 BoxShape::getLocalSupportPointWithoutMargin(const Vector3& direction) const { inline Vector3 BoxShape::getLocalSupportPointWithoutMargin(const Vector3& direction) const {
return Vector3(direction.x < decimal(0.0) ? -mExtent.x : mExtent.x, return Vector3(direction.x < decimal(0.0) ? -mExtent.x : mExtent.x,
@ -182,7 +182,7 @@ inline uint BoxShape::getNbFaces() const {
} }
// Return a given face of the polyhedron // Return a given face of the polyhedron
inline HalfEdgeStructure::Face BoxShape::getFace(uint faceIndex) const { inline const HalfEdgeStructure::Face& BoxShape::getFace(uint faceIndex) const {
assert(faceIndex < mHalfEdgeStructure.getNbFaces()); assert(faceIndex < mHalfEdgeStructure.getNbFaces());
return mHalfEdgeStructure.getFace(faceIndex); return mHalfEdgeStructure.getFace(faceIndex);
} }
@ -243,7 +243,7 @@ inline uint BoxShape::getNbHalfEdges() const {
} }
// Return a given half-edge of the polyhedron // Return a given half-edge of the polyhedron
inline HalfEdgeStructure::Edge BoxShape::getHalfEdge(uint edgeIndex) const { inline const HalfEdgeStructure::Edge& BoxShape::getHalfEdge(uint edgeIndex) const {
assert(edgeIndex < getNbHalfEdges()); assert(edgeIndex < getNbHalfEdges());
return mHalfEdgeStructure.getHalfEdge(edgeIndex); return mHalfEdgeStructure.getHalfEdge(edgeIndex);
} }

View File

@ -111,7 +111,7 @@ class ConvexMeshShape : public ConvexPolyhedronShape {
virtual uint getNbFaces() const override; virtual uint getNbFaces() const override;
/// Return a given face of the polyhedron /// Return a given face of the polyhedron
virtual HalfEdgeStructure::Face getFace(uint faceIndex) const override; virtual const HalfEdgeStructure::Face& getFace(uint faceIndex) const override;
/// Return the number of vertices of the polyhedron /// Return the number of vertices of the polyhedron
virtual uint getNbVertices() const override; virtual uint getNbVertices() const override;
@ -123,7 +123,7 @@ class ConvexMeshShape : public ConvexPolyhedronShape {
virtual uint getNbHalfEdges() const override; virtual uint getNbHalfEdges() const override;
/// Return a given half-edge of the polyhedron /// Return a given half-edge of the polyhedron
virtual HalfEdgeStructure::Edge getHalfEdge(uint edgeIndex) const override; virtual const HalfEdgeStructure::Edge& getHalfEdge(uint edgeIndex) const override;
/// Return the position of a given vertex /// Return the position of a given vertex
virtual Vector3 getVertexPosition(uint vertexIndex) const override; virtual Vector3 getVertexPosition(uint vertexIndex) const override;
@ -191,7 +191,7 @@ inline uint ConvexMeshShape::getNbFaces() const {
} }
// Return a given face of the polyhedron // Return a given face of the polyhedron
inline HalfEdgeStructure::Face ConvexMeshShape::getFace(uint faceIndex) const { inline const HalfEdgeStructure::Face& ConvexMeshShape::getFace(uint faceIndex) const {
assert(faceIndex < getNbFaces()); assert(faceIndex < getNbFaces());
return mPolyhedronMesh->getHalfEdgeStructure().getFace(faceIndex); return mPolyhedronMesh->getHalfEdgeStructure().getFace(faceIndex);
} }
@ -213,7 +213,7 @@ inline uint ConvexMeshShape::getNbHalfEdges() const {
} }
// Return a given half-edge of the polyhedron // Return a given half-edge of the polyhedron
inline HalfEdgeStructure::Edge ConvexMeshShape::getHalfEdge(uint edgeIndex) const { inline const HalfEdgeStructure::Edge& ConvexMeshShape::getHalfEdge(uint edgeIndex) const {
assert(edgeIndex < getNbHalfEdges()); assert(edgeIndex < getNbHalfEdges());
return mPolyhedronMesh->getHalfEdgeStructure().getHalfEdge(edgeIndex); return mPolyhedronMesh->getHalfEdgeStructure().getHalfEdge(edgeIndex);
} }

View File

@ -62,7 +62,7 @@ class ConvexPolyhedronShape : public ConvexShape {
virtual uint getNbFaces() const=0; virtual uint getNbFaces() const=0;
/// Return a given face of the polyhedron /// Return a given face of the polyhedron
virtual HalfEdgeStructure::Face getFace(uint faceIndex) const=0; virtual const HalfEdgeStructure::Face& getFace(uint faceIndex) const=0;
/// Return the number of vertices of the polyhedron /// Return the number of vertices of the polyhedron
virtual uint getNbVertices() const=0; virtual uint getNbVertices() const=0;
@ -80,7 +80,7 @@ class ConvexPolyhedronShape : public ConvexShape {
virtual uint getNbHalfEdges() const=0; virtual uint getNbHalfEdges() const=0;
/// Return a given half-edge of the polyhedron /// Return a given half-edge of the polyhedron
virtual HalfEdgeStructure::Edge getHalfEdge(uint edgeIndex) const=0; virtual const HalfEdgeStructure::Edge& getHalfEdge(uint edgeIndex) const=0;
/// Return true if the collision shape is a polyhedron /// Return true if the collision shape is a polyhedron
virtual bool isPolyhedron() const override; virtual bool isPolyhedron() const override;

View File

@ -58,6 +58,57 @@ TriangleShape::TriangleShape(const Vector3* vertices, const Vector3* verticesNor
mVerticesNormals[1] = verticesNormals[1]; mVerticesNormals[1] = verticesNormals[1];
mVerticesNormals[2] = verticesNormals[2]; mVerticesNormals[2] = verticesNormals[2];
// Faces
for (uint i=0; i<2; i++) {
mFaces[i].faceVertices.push_back(0);
mFaces[i].faceVertices.push_back(1);
mFaces[i].faceVertices.push_back(2);
mFaces[i].edgeIndex = i;
}
// 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; mRaycastTestType = TriangleRaycastSide::FRONT;
mId = shapeId; mId = shapeId;
@ -227,51 +278,3 @@ bool TriangleShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape
return true; return true;
} }
// Return a given half-edge of the polyhedron
HalfEdgeStructure::Edge TriangleShape::getHalfEdge(uint edgeIndex) const {
assert(edgeIndex < getNbHalfEdges());
HalfEdgeStructure::Edge edge;
switch(edgeIndex) {
case 0:
edge.vertexIndex = 0;
edge.twinEdgeIndex = 1;
edge.faceIndex = 0;
edge.nextEdgeIndex = 2;
break;
case 1:
edge.vertexIndex = 1;
edge.twinEdgeIndex = 0;
edge.faceIndex = 1;
edge.nextEdgeIndex = 5;
break;
case 2:
edge.vertexIndex = 1;
edge.twinEdgeIndex = 3;
edge.faceIndex = 0;
edge.nextEdgeIndex = 4;
break;
case 3:
edge.vertexIndex = 2;
edge.twinEdgeIndex = 2;
edge.faceIndex = 1;
edge.nextEdgeIndex = 1;
break;
case 4:
edge.vertexIndex = 2;
edge.twinEdgeIndex = 5;
edge.faceIndex = 0;
edge.nextEdgeIndex = 0;
break;
case 5:
edge.vertexIndex = 0;
edge.twinEdgeIndex = 4;
edge.faceIndex = 1;
edge.nextEdgeIndex = 3;
break;
}
return edge;
}

View File

@ -72,6 +72,12 @@ class TriangleShape : public ConvexPolyhedronShape {
/// Raycast test type for the triangle (front, back, front-back) /// Raycast test type for the triangle (front, back, front-back)
TriangleRaycastSide mRaycastTestType; 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];
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Return a local support point in a given direction without the object margin /// Return a local support point in a given direction without the object margin
@ -137,7 +143,7 @@ class TriangleShape : public ConvexPolyhedronShape {
virtual uint getNbFaces() const override; virtual uint getNbFaces() const override;
/// Return a given face of the polyhedron /// Return a given face of the polyhedron
virtual HalfEdgeStructure::Face getFace(uint faceIndex) const override; virtual const HalfEdgeStructure::Face& getFace(uint faceIndex) const override;
/// Return the number of vertices of the polyhedron /// Return the number of vertices of the polyhedron
virtual uint getNbVertices() const override; virtual uint getNbVertices() const override;
@ -155,7 +161,7 @@ class TriangleShape : public ConvexPolyhedronShape {
virtual uint getNbHalfEdges() const override; virtual uint getNbHalfEdges() const override;
/// Return a given half-edge of the polyhedron /// Return a given half-edge of the polyhedron
virtual HalfEdgeStructure::Edge getHalfEdge(uint edgeIndex) const override; virtual const HalfEdgeStructure::Edge& getHalfEdge(uint edgeIndex) const override;
/// Return the centroid of the polyhedron /// Return the centroid of the polyhedron
virtual Vector3 getCentroid() const override; virtual Vector3 getCentroid() const override;
@ -252,26 +258,9 @@ inline uint TriangleShape::getNbFaces() const {
} }
// Return a given face of the polyhedron // Return a given face of the polyhedron
inline HalfEdgeStructure::Face TriangleShape::getFace(uint faceIndex) const { inline const HalfEdgeStructure::Face& TriangleShape::getFace(uint faceIndex) const {
assert(faceIndex < 2); assert(faceIndex < 2);
return mFaces[faceIndex];
HalfEdgeStructure::Face face;
if (faceIndex == 0) {
face.faceVertices.push_back(0);
face.faceVertices.push_back(1);
face.faceVertices.push_back(2);
face.edgeIndex = 0;
}
else {
face.faceVertices.push_back(0);
face.faceVertices.push_back(2);
face.faceVertices.push_back(1);
face.edgeIndex = 1;
}
return face;
} }
// Return the number of vertices of the polyhedron // Return the number of vertices of the polyhedron
@ -292,6 +281,12 @@ inline HalfEdgeStructure::Vertex TriangleShape::getVertex(uint vertexIndex) cons
return vertex; return vertex;
} }
// Return a given half-edge of the polyhedron
inline const HalfEdgeStructure::Edge& TriangleShape::getHalfEdge(uint edgeIndex) const {
assert(edgeIndex < getNbHalfEdges());
return mEdges[edgeIndex];
}
// Return the position of a given vertex // Return the position of a given vertex
inline Vector3 TriangleShape::getVertexPosition(uint vertexIndex) const { inline Vector3 TriangleShape::getVertexPosition(uint vertexIndex) const {
assert(vertexIndex < 3); assert(vertexIndex < 3);

View File

@ -306,16 +306,35 @@ inline Quaternion Quaternion::operator*(decimal nb) const {
// Overloaded operator for the multiplication of two quaternions // Overloaded operator for the multiplication of two quaternions
inline Quaternion Quaternion::operator*(const Quaternion& quaternion) const { inline Quaternion Quaternion::operator*(const Quaternion& quaternion) const {
/* The followin code is equivalent to this
return Quaternion(w * quaternion.w - getVectorV().dot(quaternion.getVectorV()), return Quaternion(w * quaternion.w - getVectorV().dot(quaternion.getVectorV()),
w * quaternion.getVectorV() + quaternion.w * getVectorV() + w * quaternion.getVectorV() + quaternion.w * getVectorV() +
getVectorV().cross(quaternion.getVectorV())); getVectorV().cross(quaternion.getVectorV()));
*/
return Quaternion(w * quaternion.x + quaternion.w * x + y * quaternion.z - z * quaternion.y,
w * quaternion.y + quaternion.w * y + z * quaternion.x - x * quaternion.z,
w * quaternion.z + quaternion.w * z + x * quaternion.y - y * quaternion.x,
w * quaternion.w - x * quaternion.x - y * quaternion.y - z * quaternion.z);
} }
// Overloaded operator for the multiplication with a vector. // Overloaded operator for the multiplication with a vector.
/// This methods rotates a point given the rotation of a quaternion. /// This methods rotates a point given the rotation of a quaternion.
inline Vector3 Quaternion::operator*(const Vector3& point) const { inline Vector3 Quaternion::operator*(const Vector3& point) const {
Quaternion p(point.x, point.y, point.z, 0.0);
return (((*this) * p) * getConjugate()).getVectorV(); /* The following code is equivalent to this
* Quaternion p(point.x, point.y, point.z, 0.0);
* return (((*this) * p) * getConjugate()).getVectorV();
*/
const decimal prodX = w * point.x + y * point.z - z * point.y;
const decimal prodY = w * point.y + z * point.x - x * point.z;
const decimal prodZ = w * point.z + x * point.y - y * point.x;
const decimal prodW = -x * point.x - y * point.y - z * point.z;
return Vector3(w * prodX - prodY * z + prodZ * y - prodW * x,
w * prodY - prodZ * x + prodX * z - prodW * y,
w * prodZ - prodX * y + prodY * x - prodW * z);
} }
// Overloaded operator for the assignment // Overloaded operator for the assignment

View File

@ -194,7 +194,7 @@ inline Transform Transform::identity() {
// Return the transformed vector // Return the transformed vector
inline Vector3 Transform::operator*(const Vector3& vector) const { inline Vector3 Transform::operator*(const Vector3& vector) const {
return (mOrientation.getMatrix() * vector) + mPosition; return (mOrientation * vector) + mPosition;
} }
// Operator of multiplication of a transform with another one // Operator of multiplication of a transform with another one

View File

@ -198,10 +198,7 @@ decimal reactphysics3d::computePlaneSegmentIntersection(const Vector3& segA, con
const decimal parallelEpsilon = decimal(0.0001); const decimal parallelEpsilon = decimal(0.0001);
decimal t = decimal(-1); decimal t = decimal(-1);
// Segment AB decimal nDotAB = planeNormal.dot(segB - segA);
const Vector3 ab = segB - segA;
decimal nDotAB = planeNormal.dot(ab);
// If the segment is not parallel to the plane // If the segment is not parallel to the plane
if (std::abs(nDotAB) > parallelEpsilon) { if (std::abs(nDotAB) > parallelEpsilon) {
@ -297,23 +294,27 @@ std::vector<Vector3> reactphysics3d::clipSegmentWithPlanes(const Vector3& segA,
// Clip a polygon against multiple planes and return the clipped polygon vertices // Clip a polygon against multiple planes and return the clipped polygon vertices
// This method implements the SutherlandHodgman clipping algorithm // This method implements the SutherlandHodgman clipping algorithm
std::vector<Vector3> reactphysics3d::clipPolygonWithPlanes(const std::vector<Vector3>& polygonVertices, const std::vector<Vector3>& planesPoints, List<Vector3> reactphysics3d::clipPolygonWithPlanes(const List<Vector3>& polygonVertices, const List<Vector3>& planesPoints,
const std::vector<Vector3>& planesNormals) { const List<Vector3>& planesNormals, Allocator& allocator) {
assert(planesPoints.size() == planesNormals.size()); assert(planesPoints.size() == planesNormals.size());
std::vector<Vector3> inputVertices(polygonVertices); uint nbMaxElements = polygonVertices.size() + planesPoints.size();
std::vector<Vector3> outputVertices; List<Vector3> inputVertices(allocator, nbMaxElements);
List<Vector3> outputVertices(allocator, nbMaxElements);
inputVertices.addRange(polygonVertices);
// For each clipping plane // For each clipping plane
for (uint p=0; p<planesPoints.size(); p++) { for (uint p=0; p<planesPoints.size(); p++) {
outputVertices.clear(); outputVertices.clear();
uint vStart = inputVertices.size() - 1; uint nbInputVertices = inputVertices.size();
uint vStart = nbInputVertices - 1;
// For each edge of the polygon // For each edge of the polygon
for (uint vEnd = 0; vEnd<inputVertices.size(); vEnd++) { for (uint vEnd = 0; vEnd<nbInputVertices; vEnd++) {
Vector3& v1 = inputVertices[vStart]; Vector3& v1 = inputVertices[vStart];
Vector3& v2 = inputVertices[vEnd]; Vector3& v2 = inputVertices[vEnd];
@ -331,15 +332,15 @@ std::vector<Vector3> reactphysics3d::clipPolygonWithPlanes(const std::vector<Vec
decimal t = computePlaneSegmentIntersection(v1, v2, planesNormals[p].dot(planesPoints[p]), planesNormals[p]); decimal t = computePlaneSegmentIntersection(v1, v2, planesNormals[p].dot(planesPoints[p]), planesNormals[p]);
if (t >= decimal(0) && t <= decimal(1.0)) { if (t >= decimal(0) && t <= decimal(1.0)) {
outputVertices.push_back(v1 + t * (v2 - v1)); outputVertices.add(v1 + t * (v2 - v1));
} }
else { else {
outputVertices.push_back(v2); outputVertices.add(v2);
} }
} }
// Add the second vertex // Add the second vertex
outputVertices.push_back(v2); outputVertices.add(v2);
} }
else { // If the second vertex is behind the clipping plane else { // If the second vertex is behind the clipping plane
@ -350,10 +351,10 @@ std::vector<Vector3> reactphysics3d::clipPolygonWithPlanes(const std::vector<Vec
decimal t = computePlaneSegmentIntersection(v1, v2, -planesNormals[p].dot(planesPoints[p]), -planesNormals[p]); decimal t = computePlaneSegmentIntersection(v1, v2, -planesNormals[p].dot(planesPoints[p]), -planesNormals[p]);
if (t >= decimal(0.0) && t <= decimal(1.0)) { if (t >= decimal(0.0) && t <= decimal(1.0)) {
outputVertices.push_back(v1 + t * (v2 - v1)); outputVertices.add(v1 + t * (v2 - v1));
} }
else { else {
outputVertices.push_back(v1); outputVertices.add(v1);
} }
} }
} }

View File

@ -33,6 +33,7 @@
#include <cassert> #include <cassert>
#include <cmath> #include <cmath>
#include <vector> #include <vector>
#include "containers/List.h"
/// ReactPhysics3D namespace /// ReactPhysics3D namespace
namespace reactphysics3d { namespace reactphysics3d {
@ -116,8 +117,8 @@ std::vector<Vector3> clipSegmentWithPlanes(const Vector3& segA, const Vector3& s
const std::vector<Vector3>& planesNormals); const std::vector<Vector3>& planesNormals);
/// Clip a polygon against multiple planes and return the clipped polygon vertices /// Clip a polygon against multiple planes and return the clipped polygon vertices
std::vector<Vector3> clipPolygonWithPlanes(const std::vector<Vector3>& polygonVertices, const std::vector<Vector3>& planesPoints, List<Vector3> clipPolygonWithPlanes(const List<Vector3>& polygonVertices, const List<Vector3>& planesPoints,
const std::vector<Vector3>& planesNormals); const List<Vector3>& planesNormals, Allocator& allocator);
/// Project a point onto a plane that is given by a point and its unit length normal /// Project a point onto a plane that is given by a point and its unit length normal
Vector3 projectPointOntoPlane(const Vector3& point, const Vector3& planeNormal, const Vector3& planePoint); Vector3 projectPointOntoPlane(const Vector3& point, const Vector3& planeNormal, const Vector3& planePoint);

View File

@ -27,6 +27,8 @@
#define TEST_MATHEMATICS_FUNCTIONS_H #define TEST_MATHEMATICS_FUNCTIONS_H
// Libraries // Libraries
#include "containers/List.h"
#include "memory/DefaultAllocator.h"
/// Reactphysics3D namespace /// Reactphysics3D namespace
namespace reactphysics3d { namespace reactphysics3d {
@ -41,7 +43,7 @@ class TestMathematicsFunctions : public Test {
// ---------- Atributes ---------- // // ---------- Atributes ---------- //
DefaultAllocator mAllocator;
public : public :
@ -223,37 +225,37 @@ class TestMathematicsFunctions : public Test {
test(clipSegmentVertices.size() == 0); test(clipSegmentVertices.size() == 0);
// Test clipPolygonWithPlanes() // Test clipPolygonWithPlanes()
std::vector<Vector3> polygonVertices; List<Vector3> polygonVertices(mAllocator);
polygonVertices.push_back(Vector3(-4, 2, 0)); polygonVertices.add(Vector3(-4, 2, 0));
polygonVertices.push_back(Vector3(7, 2, 0)); polygonVertices.add(Vector3(7, 2, 0));
polygonVertices.push_back(Vector3(7, 4, 0)); polygonVertices.add(Vector3(7, 4, 0));
polygonVertices.push_back(Vector3(-4, 4, 0)); polygonVertices.add(Vector3(-4, 4, 0));
planesNormals.clear(); List<Vector3> polygonPlanesNormals(mAllocator);
planesPoints.clear(); List<Vector3> polygonPlanesPoints(mAllocator);
planesNormals.push_back(Vector3(1, 0, 0)); polygonPlanesNormals.add(Vector3(1, 0, 0));
planesPoints.push_back(Vector3(0, 0, 0)); polygonPlanesPoints.add(Vector3(0, 0, 0));
planesNormals.push_back(Vector3(0, 1, 0)); polygonPlanesNormals.add(Vector3(0, 1, 0));
planesPoints.push_back(Vector3(0, 0, 0)); polygonPlanesPoints.add(Vector3(0, 0, 0));
planesNormals.push_back(Vector3(-1, 0, 0)); polygonPlanesNormals.add(Vector3(-1, 0, 0));
planesPoints.push_back(Vector3(10, 0, 0)); polygonPlanesPoints.add(Vector3(10, 0, 0));
planesNormals.push_back(Vector3(0, -1, 0)); polygonPlanesNormals.add(Vector3(0, -1, 0));
planesPoints.push_back(Vector3(10, 5, 0)); polygonPlanesPoints.add(Vector3(10, 5, 0));
clipSegmentVertices = clipPolygonWithPlanes(polygonVertices, planesPoints, planesNormals); List<Vector3> clipPolygonVertices = clipPolygonWithPlanes(polygonVertices, polygonPlanesPoints, polygonPlanesNormals, mAllocator);
test(clipSegmentVertices.size() == 4); test(clipPolygonVertices.size() == 4);
test(approxEqual(clipSegmentVertices[0].x, 0, 0.000001)); test(approxEqual(clipPolygonVertices[0].x, 0, 0.000001));
test(approxEqual(clipSegmentVertices[0].y, 2, 0.000001)); test(approxEqual(clipPolygonVertices[0].y, 2, 0.000001));
test(approxEqual(clipSegmentVertices[0].z, 0, 0.000001)); test(approxEqual(clipPolygonVertices[0].z, 0, 0.000001));
test(approxEqual(clipSegmentVertices[1].x, 7, 0.000001)); test(approxEqual(clipPolygonVertices[1].x, 7, 0.000001));
test(approxEqual(clipSegmentVertices[1].y, 2, 0.000001)); test(approxEqual(clipPolygonVertices[1].y, 2, 0.000001));
test(approxEqual(clipSegmentVertices[1].z, 0, 0.000001)); test(approxEqual(clipPolygonVertices[1].z, 0, 0.000001));
test(approxEqual(clipSegmentVertices[2].x, 7, 0.000001)); test(approxEqual(clipPolygonVertices[2].x, 7, 0.000001));
test(approxEqual(clipSegmentVertices[2].y, 4, 0.000001)); test(approxEqual(clipPolygonVertices[2].y, 4, 0.000001));
test(approxEqual(clipSegmentVertices[2].z, 0, 0.000001)); test(approxEqual(clipPolygonVertices[2].z, 0, 0.000001));
test(approxEqual(clipSegmentVertices[3].x, 0, 0.000001)); test(approxEqual(clipPolygonVertices[3].x, 0, 0.000001));
test(approxEqual(clipSegmentVertices[3].y, 4, 0.000001)); test(approxEqual(clipPolygonVertices[3].y, 4, 0.000001));
test(approxEqual(clipSegmentVertices[3].z, 0, 0.000001)); test(approxEqual(clipPolygonVertices[3].z, 0, 0.000001));
} }