149 lines
6.2 KiB
C++
149 lines
6.2 KiB
C++
/** @file
|
|
* Original ReactPhysics3D C++ library by Daniel Chappuis <http://www.reactphysics3d.com/> This code is re-licensed with permission from ReactPhysics3D author.
|
|
* @author Daniel CHAPPUIS
|
|
* @author Edouard DUPIN
|
|
* @copyright 2010-2016, Daniel Chappuis
|
|
* @copyright 2017, Edouard DUPIN
|
|
* @license MPL v2.0 (see license file)
|
|
*/
|
|
#pragma once
|
|
|
|
#include <ephysics/collision/narrowphase/NarrowPhaseAlgorithm.hpp>
|
|
#include <ephysics/collision/shapes/ConvexShape.hpp>
|
|
#include <ephysics/collision/shapes/ConcaveShape.hpp>
|
|
|
|
namespace ephysics {
|
|
|
|
/**
|
|
* @brief This class is used to encapsulate a callback method for
|
|
* collision detection between the triangle of a concave mesh shape
|
|
* and a convex shape.
|
|
*/
|
|
class ConvexVsTriangleCallback : public TriangleCallback {
|
|
protected:
|
|
CollisionDetection* m_collisionDetection; //!< Pointer to the collision detection object
|
|
NarrowPhaseCallback* m_narrowPhaseCallback; //!< Narrow-phase collision callback
|
|
const ConvexShape* m_convexShape; //!< Convex collision shape to test collision with
|
|
const ConcaveShape* m_concaveShape; //!< Concave collision shape
|
|
ProxyShape* m_convexProxyShape; //!< Proxy shape of the convex collision shape
|
|
ProxyShape* m_concaveProxyShape; //!< Proxy shape of the concave collision shape
|
|
OverlappingPair* m_overlappingPair; //!< Broadphase overlapping pair
|
|
static bool contactsDepthCompare(const ContactPointInfo& _contact1,
|
|
const ContactPointInfo& _contact2);
|
|
public:
|
|
/// Set the collision detection pointer
|
|
void setCollisionDetection(CollisionDetection* _collisionDetection) {
|
|
m_collisionDetection = _collisionDetection;
|
|
}
|
|
/// Set the narrow-phase collision callback
|
|
void setNarrowPhaseCallback(NarrowPhaseCallback* _callback) {
|
|
m_narrowPhaseCallback = _callback;
|
|
}
|
|
/// Set the convex collision shape to test collision with
|
|
void setConvexShape(const ConvexShape* _convexShape) {
|
|
m_convexShape = _convexShape;
|
|
}
|
|
/// Set the concave collision shape
|
|
void setConcaveShape(const ConcaveShape* _concaveShape) {
|
|
m_concaveShape = _concaveShape;
|
|
}
|
|
/// Set the broadphase overlapping pair
|
|
void setOverlappingPair(OverlappingPair* _overlappingPair) {
|
|
m_overlappingPair = _overlappingPair;
|
|
}
|
|
/// Set the proxy shapes of the two collision shapes
|
|
void setProxyShapes(ProxyShape* _convexProxyShape, ProxyShape* _concaveProxyShape) {
|
|
m_convexProxyShape = _convexProxyShape;
|
|
m_concaveProxyShape = _concaveProxyShape;
|
|
}
|
|
/// Test collision between a triangle and the convex mesh shape
|
|
virtual void testTriangle(const vec3* _trianglePoints);
|
|
};
|
|
|
|
/**
|
|
* @brief This class is used to store data about a contact with a triangle for the smooth
|
|
* mesh algorithm.
|
|
*/
|
|
class SmoothMeshContactInfo {
|
|
public:
|
|
ContactPointInfo contactInfo;
|
|
bool isFirstShapeTriangle;
|
|
vec3 triangleVertices[3];
|
|
/// Constructor
|
|
SmoothMeshContactInfo(const ContactPointInfo& _contact,
|
|
bool _firstShapeTriangle,
|
|
const vec3& _trianglePoint1,
|
|
const vec3& _trianglePoint2,
|
|
const vec3& _trianglePoint3):
|
|
contactInfo(_contact) {
|
|
isFirstShapeTriangle = _firstShapeTriangle;
|
|
triangleVertices[0] = _trianglePoint1;
|
|
triangleVertices[1] = _trianglePoint2;
|
|
triangleVertices[2] = _trianglePoint3;
|
|
}
|
|
SmoothMeshContactInfo() {
|
|
// TODO: add it for etk::Vector
|
|
}
|
|
};
|
|
|
|
/*
|
|
struct ContactsDepthCompare {
|
|
bool operator()(const SmoothMeshContactInfo& _contact1, const SmoothMeshContactInfo& _contact2) {
|
|
return _contact1.contactInfo.penetrationDepth < _contact2.contactInfo.penetrationDepth;
|
|
}
|
|
};
|
|
*/
|
|
|
|
/**
|
|
* @brief This class is used as a narrow-phase callback to get narrow-phase contacts
|
|
* of the concave triangle mesh to temporary store them in order to be used in
|
|
* the smooth mesh collision algorithm if this one is enabled.
|
|
*/
|
|
class SmoothCollisionNarrowPhaseCallback : public NarrowPhaseCallback {
|
|
private:
|
|
etk::Vector<SmoothMeshContactInfo>& m_contactPoints;
|
|
public:
|
|
// Constructor
|
|
SmoothCollisionNarrowPhaseCallback(etk::Vector<SmoothMeshContactInfo>& _contactPoints):
|
|
m_contactPoints(_contactPoints) {
|
|
|
|
}
|
|
/// Called by a narrow-phase collision algorithm when a new contact has been found
|
|
virtual void notifyContact(OverlappingPair* _overlappingPair, const ContactPointInfo& _contactInfo);
|
|
};
|
|
|
|
/**
|
|
* @brief This class is used to compute the narrow-phase collision detection
|
|
* between a concave collision shape and a convex collision shape. The idea is
|
|
* to use the GJK collision detection algorithm to compute the collision between
|
|
* the convex shape and each of the triangles in the concave shape.
|
|
*/
|
|
class ConcaveVsConvexAlgorithm : public NarrowPhaseAlgorithm {
|
|
protected :
|
|
/// Private copy-constructor
|
|
ConcaveVsConvexAlgorithm(const ConcaveVsConvexAlgorithm& _algorithm);
|
|
/// Private assignment operator
|
|
ConcaveVsConvexAlgorithm& operator=(const ConcaveVsConvexAlgorithm& _algorithm);
|
|
/// Process the concave triangle mesh collision using the smooth mesh collision algorithm
|
|
void processSmoothMeshCollision(OverlappingPair* _overlappingPair,
|
|
etk::Vector<SmoothMeshContactInfo> _contactPoints,
|
|
NarrowPhaseCallback* _narrowPhaseCallback);
|
|
/// Add a triangle vertex int32_to the set of processed triangles
|
|
void addProcessedVertex(etk::Vector<etk::Pair<int32_t, vec3>>& _processTriangleVertices, const vec3& _vertex) {
|
|
_processTriangleVertices.pushBack(etk::makePair(int32_t(_vertex.x() * _vertex.y() * _vertex.z()), _vertex));
|
|
}
|
|
/// Return true if the vertex is in the set of already processed vertices
|
|
bool hasVertexBeenProcessed(const etk::Vector<etk::Pair<int32_t, vec3>>& _processTriangleVertices,
|
|
const vec3& _vertex) const;
|
|
public :
|
|
/// Constructor
|
|
ConcaveVsConvexAlgorithm();
|
|
/// Compute a contact info if the two bounding volume collide
|
|
virtual void testCollision(const CollisionShapeInfo& _shape1Info,
|
|
const CollisionShapeInfo& _shape2Info,
|
|
NarrowPhaseCallback* _narrowPhaseCallback);
|
|
};
|
|
|
|
}
|
|
|