2015-08-27 20:31:05 +00:00
/********************************************************************************
* ReactPhysics3D physics library , http : //www.reactphysics3d.com *
2016-04-11 18:15:20 +00:00
* Copyright ( c ) 2010 - 2016 Daniel Chappuis *
2015-08-27 20:31:05 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* This software is provided ' as - is ' , without any express or implied warranty . *
* In no event will the authors be held liable for any damages arising from the *
* use of this software . *
* *
* Permission is granted to anyone to use this software for any purpose , *
* including commercial applications , and to alter it and redistribute it *
* freely , subject to the following restrictions : *
* *
* 1. The origin of this software must not be misrepresented ; you must not claim *
* that you wrote the original software . If you use this software in a *
* product , an acknowledgment in the product documentation would be *
* appreciated but is not required . *
* *
* 2. Altered source versions must be plainly marked as such , and must not be *
* misrepresented as being the original software . *
* *
* 3. This notice may not be removed or altered from any source distribution . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifndef REACTPHYSICS3D_TRIANGLE_SHAPE_H
# define REACTPHYSICS3D_TRIANGLE_SHAPE_H
// Libraries
# include "mathematics/mathematics.h"
2017-06-06 19:12:26 +00:00
# include "ConvexPolyhedronShape.h"
2015-08-27 20:31:05 +00:00
/// ReactPhysics3D namespace
namespace reactphysics3d {
2015-12-05 16:51:07 +00:00
/// Raycast test side for the triangle
2016-07-08 05:25:37 +00:00
enum class TriangleRaycastSide {
2015-12-05 16:51:07 +00:00
/// Raycast against front triangle
FRONT ,
/// Raycast against back triangle
BACK ,
/// Raycast against front and back triangle
FRONT_AND_BACK
} ;
2015-08-27 20:31:05 +00:00
// Class TriangleShape
/**
* This class represents a triangle collision shape that is centered
2017-08-21 05:35:08 +00:00
* at the origin and defined three points . A user cannot instanciate
* an object of this class . This class is for internal use only . Instances
* of this class are created when the user creates an HeightFieldShape and
* a ConcaveMeshShape
2015-08-27 20:31:05 +00:00
*/
2017-06-06 19:12:26 +00:00
class TriangleShape : public ConvexPolyhedronShape {
2015-08-27 20:31:05 +00:00
protected :
// -------------------- Attribute -------------------- //
/// Three points of the triangle
Vector3 mPoints [ 3 ] ;
2017-06-06 19:12:26 +00:00
/// Normal of the triangle
Vector3 mNormal ;
2017-08-21 05:35:08 +00:00
/// Three vertices normals for smooth collision with triangle mesh
Vector3 mVerticesNormals [ 3 ] ;
2015-12-05 16:51:07 +00:00
/// Raycast test type for the triangle (front, back, front-back)
TriangleRaycastSide mRaycastTestType ;
2017-12-04 21:14:52 +00:00
/// 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 ] ;
2015-08-27 20:31:05 +00:00
// -------------------- Methods -------------------- //
/// Return a local support point in a given direction without the object margin
2017-09-03 16:05:23 +00:00
virtual Vector3 getLocalSupportPointWithoutMargin ( const Vector3 & direction ) const override ;
2015-08-27 20:31:05 +00:00
2017-08-21 05:35:08 +00:00
/// Get a smooth contact normal for collision for a triangle of the mesh
Vector3 computeSmoothLocalContactNormalForTriangle ( const Vector3 & localContactPoint ) const ;
2015-08-27 20:31:05 +00:00
/// Return true if a point is inside the collision shape
2016-07-11 06:33:24 +00:00
virtual bool testPointInside ( const Vector3 & localPoint , ProxyShape * proxyShape ) const override ;
2015-08-27 20:31:05 +00:00
/// Raycast method with feedback information
2016-07-11 06:33:24 +00:00
virtual bool raycast ( const Ray & ray , RaycastInfo & raycastInfo , ProxyShape * proxyShape ) const override ;
2015-08-27 20:31:05 +00:00
/// Return the number of bytes used by the collision shape
2016-07-11 06:33:24 +00:00
virtual size_t getSizeInBytes ( ) const override ;
2015-08-27 20:31:05 +00:00
2017-11-22 21:43:27 +00:00
/// Generate the id of the shape (used for temporal coherence)
void generateId ( ) ;
2017-08-21 05:35:08 +00:00
// -------------------- Methods -------------------- //
/// This method implements the technique described in Game Physics Pearl book
void computeSmoothMeshContact ( Vector3 localContactPointTriangle , const Transform & triangleShapeToWorldTransform ,
2017-09-21 20:44:42 +00:00
const Transform & worldToOtherShapeTransform , decimal penetrationDepth , bool isTriangleShape1 ,
2017-08-21 05:35:08 +00:00
Vector3 & outNewLocalContactPointOtherShape , Vector3 & outSmoothWorldContactTriangleNormal ) const ;
2015-08-27 20:31:05 +00:00
public :
// -------------------- Methods -------------------- //
/// Constructor
2017-11-22 21:43:27 +00:00
TriangleShape ( const Vector3 * vertices , const Vector3 * verticesNormals , uint shapeId ) ;
2015-08-27 20:31:05 +00:00
/// Destructor
2016-07-19 04:52:18 +00:00
virtual ~ TriangleShape ( ) override = default ;
2015-08-27 20:31:05 +00:00
2016-07-08 05:25:37 +00:00
/// Deleted copy-constructor
TriangleShape ( const TriangleShape & shape ) = delete ;
/// Deleted assignment operator
TriangleShape & operator = ( const TriangleShape & shape ) = delete ;
2015-08-27 20:31:05 +00:00
/// Return the local bounds of the shape in x, y and z directions.
2016-07-11 06:33:24 +00:00
virtual void getLocalBounds ( Vector3 & min , Vector3 & max ) const override ;
2015-08-27 20:31:05 +00:00
2015-11-19 06:20:43 +00:00
/// Set the local scaling vector of the collision shape
2016-07-11 06:33:24 +00:00
virtual void setLocalScaling ( const Vector3 & scaling ) override ;
2015-11-19 06:20:43 +00:00
2015-08-27 20:31:05 +00:00
/// Return the local inertia tensor of the collision shape
2016-07-11 06:33:24 +00:00
virtual void computeLocalInertiaTensor ( Matrix3x3 & tensor , decimal mass ) const override ;
2015-08-27 20:31:05 +00:00
/// Update the AABB of a body using its collision shape
2016-07-11 06:33:24 +00:00
virtual void computeAABB ( AABB & aabb , const Transform & transform ) const override ;
2015-12-02 21:25:52 +00:00
2015-12-05 16:51:07 +00:00
/// Return the raycast test type (front, back, front-back)
TriangleRaycastSide getRaycastTestType ( ) const ;
// Set the raycast test type (front, back, front-back)
void setRaycastTestType ( TriangleRaycastSide testType ) ;
2017-06-06 19:12:26 +00:00
/// Return the number of faces of the polyhedron
virtual uint getNbFaces ( ) const override ;
/// Return a given face of the polyhedron
2017-12-04 21:14:52 +00:00
virtual const HalfEdgeStructure : : Face & getFace ( uint faceIndex ) const override ;
2017-06-06 19:12:26 +00:00
/// Return the number of vertices of the polyhedron
virtual uint getNbVertices ( ) const override ;
/// Return a given vertex of the polyhedron
virtual HalfEdgeStructure : : Vertex getVertex ( uint vertexIndex ) const override ;
/// Return the position of a given vertex
virtual Vector3 getVertexPosition ( uint vertexIndex ) const override ;
2016-01-05 17:39:22 +00:00
2017-06-06 19:12:26 +00:00
/// Return the normal vector of a given face of the polyhedron
virtual Vector3 getFaceNormal ( uint faceIndex ) const override ;
/// Return the number of half-edges of the polyhedron
virtual uint getNbHalfEdges ( ) const override ;
/// Return a given half-edge of the polyhedron
2017-12-04 21:14:52 +00:00
virtual const HalfEdgeStructure : : Edge & getHalfEdge ( uint edgeIndex ) const override ;
2017-06-06 19:12:26 +00:00
/// Return the centroid of the polyhedron
virtual Vector3 getCentroid ( ) const override ;
2016-07-05 19:34:44 +00:00
2017-08-21 05:35:08 +00:00
/// This method compute the smooth mesh contact with a triangle in case one of the two collision shapes is a triangle. The idea in this case is to use a smooth vertex normal of the triangle mesh
static void computeSmoothTriangleMeshContact ( const CollisionShape * shape1 , const CollisionShape * shape2 ,
2017-08-31 21:11:00 +00:00
Vector3 & localContactPointShape1 , Vector3 & localContactPointShape2 ,
2017-08-21 05:35:08 +00:00
const Transform & shape1ToWorld , const Transform & shape2ToWorld ,
decimal penetrationDepth , Vector3 & outSmoothVertexNormal ) ;
2015-12-02 21:25:52 +00:00
// ---------- Friendship ---------- //
friend class ConcaveMeshRaycastCallback ;
2016-02-08 21:24:57 +00:00
friend class TriangleOverlapCallback ;
2017-08-21 05:35:08 +00:00
friend class MiddlePhaseTriangleCallback ;
2015-08-27 20:31:05 +00:00
} ;
// Return the number of bytes used by the collision shape
inline size_t TriangleShape : : getSizeInBytes ( ) const {
return sizeof ( TriangleShape ) ;
}
// Return a local support point in a given direction without the object margin
2017-09-03 16:05:23 +00:00
inline Vector3 TriangleShape : : getLocalSupportPointWithoutMargin ( const Vector3 & direction ) const {
2015-08-31 15:33:34 +00:00
Vector3 dotProducts ( direction . dot ( mPoints [ 0 ] ) , direction . dot ( mPoints [ 1 ] ) , direction . dot ( mPoints [ 2 ] ) ) ;
2015-08-27 20:31:05 +00:00
return mPoints [ dotProducts . getMaxAxis ( ) ] ;
}
// Return the local bounds of the shape in x, y and z directions.
// This method is used to compute the AABB of the box
/**
* @ param min The minimum bounds of the shape in local - space coordinates
* @ param max The maximum bounds of the shape in local - space coordinates
*/
inline void TriangleShape : : getLocalBounds ( Vector3 & min , Vector3 & max ) const {
2015-09-04 17:56:27 +00:00
const Vector3 xAxis ( mPoints [ 0 ] . x , mPoints [ 1 ] . x , mPoints [ 2 ] . x ) ;
const Vector3 yAxis ( mPoints [ 0 ] . y , mPoints [ 1 ] . y , mPoints [ 2 ] . y ) ;
const Vector3 zAxis ( mPoints [ 0 ] . z , mPoints [ 1 ] . z , mPoints [ 2 ] . z ) ;
2015-08-31 15:33:34 +00:00
min . setAllValues ( xAxis . getMinValue ( ) , yAxis . getMinValue ( ) , zAxis . getMinValue ( ) ) ;
max . setAllValues ( xAxis . getMaxValue ( ) , yAxis . getMaxValue ( ) , zAxis . getMaxValue ( ) ) ;
2016-01-14 20:24:21 +00:00
min - = Vector3 ( mMargin , mMargin , mMargin ) ;
max + = Vector3 ( mMargin , mMargin , mMargin ) ;
2015-08-27 20:31:05 +00:00
}
2015-11-19 06:20:43 +00:00
// Set the local scaling vector of the collision shape
inline void TriangleShape : : setLocalScaling ( const Vector3 & scaling ) {
mPoints [ 0 ] = ( mPoints [ 0 ] / mScaling ) * scaling ;
mPoints [ 1 ] = ( mPoints [ 1 ] / mScaling ) * scaling ;
mPoints [ 2 ] = ( mPoints [ 2 ] / mScaling ) * scaling ;
CollisionShape : : setLocalScaling ( scaling ) ;
}
2015-08-27 20:31:05 +00:00
// Return the local inertia tensor of the triangle shape
/**
* @ param [ out ] tensor The 3 x3 inertia tensor matrix of the shape in local - space
* coordinates
* @ param mass Mass to use to compute the inertia tensor of the collision shape
*/
inline void TriangleShape : : computeLocalInertiaTensor ( Matrix3x3 & tensor , decimal mass ) const {
tensor . setToZero ( ) ;
}
// Update the AABB of a body using its collision shape
/**
* @ param [ out ] aabb The axis - aligned bounding box ( AABB ) of the collision shape
* computed in world - space coordinates
* @ param transform Transform used to compute the AABB of the collision shape
*/
2015-12-02 21:25:52 +00:00
inline void TriangleShape : : computeAABB ( AABB & aabb , const Transform & transform ) const {
2015-08-27 20:31:05 +00:00
const Vector3 worldPoint1 = transform * mPoints [ 0 ] ;
const Vector3 worldPoint2 = transform * mPoints [ 1 ] ;
const Vector3 worldPoint3 = transform * mPoints [ 2 ] ;
2015-09-04 17:56:27 +00:00
const Vector3 xAxis ( worldPoint1 . x , worldPoint2 . x , worldPoint3 . x ) ;
const Vector3 yAxis ( worldPoint1 . y , worldPoint2 . y , worldPoint3 . y ) ;
const Vector3 zAxis ( worldPoint1 . z , worldPoint2 . z , worldPoint3 . z ) ;
2015-08-31 15:33:34 +00:00
aabb . setMin ( Vector3 ( xAxis . getMinValue ( ) , yAxis . getMinValue ( ) , zAxis . getMinValue ( ) ) ) ;
aabb . setMax ( Vector3 ( xAxis . getMaxValue ( ) , yAxis . getMaxValue ( ) , zAxis . getMaxValue ( ) ) ) ;
2015-08-27 20:31:05 +00:00
}
// Return true if a point is inside the collision shape
inline bool TriangleShape : : testPointInside ( const Vector3 & localPoint , ProxyShape * proxyShape ) const {
return false ;
}
2017-06-06 19:12:26 +00:00
// Return the number of faces of the polyhedron
inline uint TriangleShape : : getNbFaces ( ) const {
return 2 ;
}
// Return a given face of the polyhedron
2017-12-04 21:14:52 +00:00
inline const HalfEdgeStructure : : Face & TriangleShape : : getFace ( uint faceIndex ) const {
2017-06-06 19:12:26 +00:00
assert ( faceIndex < 2 ) ;
2017-12-04 21:14:52 +00:00
return mFaces [ faceIndex ] ;
2017-06-06 19:12:26 +00:00
}
// Return the number of vertices of the polyhedron
inline uint TriangleShape : : getNbVertices ( ) const {
return 3 ;
}
// Return a given vertex of the polyhedron
inline HalfEdgeStructure : : Vertex TriangleShape : : getVertex ( uint vertexIndex ) const {
assert ( vertexIndex < 3 ) ;
HalfEdgeStructure : : Vertex vertex ( vertexIndex ) ;
switch ( vertexIndex ) {
case 0 : vertex . edgeIndex = 0 ; break ;
case 1 : vertex . edgeIndex = 2 ; break ;
case 2 : vertex . edgeIndex = 4 ; break ;
}
return vertex ;
}
2017-12-04 21:14:52 +00:00
// Return a given half-edge of the polyhedron
inline const HalfEdgeStructure : : Edge & TriangleShape : : getHalfEdge ( uint edgeIndex ) const {
assert ( edgeIndex < getNbHalfEdges ( ) ) ;
return mEdges [ edgeIndex ] ;
}
2017-06-06 19:12:26 +00:00
// Return the position of a given vertex
inline Vector3 TriangleShape : : getVertexPosition ( uint vertexIndex ) const {
assert ( vertexIndex < 3 ) ;
return mPoints [ vertexIndex ] ;
}
// Return the normal vector of a given face of the polyhedron
inline Vector3 TriangleShape : : getFaceNormal ( uint faceIndex ) const {
assert ( faceIndex < 2 ) ;
return faceIndex = = 0 ? mNormal : - mNormal ;
}
// Return the centroid of the box
inline Vector3 TriangleShape : : getCentroid ( ) const {
return ( mPoints [ 0 ] + mPoints [ 1 ] + mPoints [ 2 ] ) / decimal ( 3.0 ) ;
}
// Return the number of half-edges of the polyhedron
inline uint TriangleShape : : getNbHalfEdges ( ) const {
return 6 ;
}
2015-12-05 16:51:07 +00:00
// Return the raycast test type (front, back, front-back)
inline TriangleRaycastSide TriangleShape : : getRaycastTestType ( ) const {
return mRaycastTestType ;
}
// Set the raycast test type (front, back, front-back)
/**
* @ param testType Raycast test type for the triangle ( front , back , front - back )
*/
inline void TriangleShape : : setRaycastTestType ( TriangleRaycastSide testType ) {
mRaycastTestType = testType ;
}
2015-08-27 20:31:05 +00:00
}
# endif