2017-08-01 14:30:58 +02:00
/*
Bullet Continuous Collision Detection and Physics Library
Copyright ( c ) 2010 Erwin Coumans http : //bulletphysics.org
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 _BT_TRIANGLE_INFO_MAP_H
# define _BT_TRIANGLE_INFO_MAP_H
# include "LinearMath/btHashMap.h"
# include "LinearMath/btSerializer.h"
///for btTriangleInfo m_flags
# define TRI_INFO_V0V1_CONVEX 1
# define TRI_INFO_V1V2_CONVEX 2
# define TRI_INFO_V2V0_CONVEX 4
# define TRI_INFO_V0V1_SWAP_NORMALB 8
# define TRI_INFO_V1V2_SWAP_NORMALB 16
# define TRI_INFO_V2V0_SWAP_NORMALB 32
///The btTriangleInfo structure stores information to adjust collision normals to avoid collisions against internal edges
2019-01-03 14:26:51 +01:00
///it can be generated using
struct btTriangleInfo
2017-08-01 14:30:58 +02:00
{
btTriangleInfo ( )
{
m_edgeV0V1Angle = SIMD_2_PI ;
m_edgeV1V2Angle = SIMD_2_PI ;
m_edgeV2V0Angle = SIMD_2_PI ;
2019-01-03 14:26:51 +01:00
m_flags = 0 ;
2017-08-01 14:30:58 +02:00
}
2019-01-03 14:26:51 +01:00
int m_flags ;
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
btScalar m_edgeV0V1Angle ;
btScalar m_edgeV1V2Angle ;
btScalar m_edgeV2V0Angle ;
2017-08-01 14:30:58 +02:00
} ;
2019-01-03 14:26:51 +01:00
typedef btHashMap < btHashInt , btTriangleInfo > btInternalTriangleInfoMap ;
2017-08-01 14:30:58 +02:00
///The btTriangleInfoMap stores edge angle information for some triangles. You can compute this information yourself or using btGenerateInternalEdgeInfo.
2019-01-03 14:26:51 +01:00
struct btTriangleInfoMap : public btInternalTriangleInfoMap
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
btScalar m_convexEpsilon ; ///used to determine if an edge or contact normal is convex, using the dot product
btScalar m_planarEpsilon ; ///used to determine if a triangle edge is planar with zero angle
btScalar m_equalVertexThreshold ; ///used to compute connectivity: if the distance between two vertices is smaller than m_equalVertexThreshold, they are considered to be 'shared'
btScalar m_edgeDistanceThreshold ; ///used to determine edge contacts: if the closest distance between a contact point and an edge is smaller than this distance threshold it is considered to "hit the edge"
btScalar m_maxEdgeAngleThreshold ; //ignore edges that connect triangles at an angle larger than this m_maxEdgeAngleThreshold
btScalar m_zeroAreaThreshold ; ///used to determine if a triangle is degenerate (length squared of cross product of 2 triangle edges < threshold)
2017-08-01 14:30:58 +02:00
btTriangleInfoMap ( )
{
m_convexEpsilon = 0.00f ;
m_planarEpsilon = 0.0001f ;
2019-01-03 14:26:51 +01:00
m_equalVertexThreshold = btScalar ( 0.0001 ) * btScalar ( 0.0001 ) ;
2017-08-01 14:30:58 +02:00
m_edgeDistanceThreshold = btScalar ( 0.1 ) ;
2019-01-03 14:26:51 +01:00
m_zeroAreaThreshold = btScalar ( 0.0001 ) * btScalar ( 0.0001 ) ;
2017-08-01 14:30:58 +02:00
m_maxEdgeAngleThreshold = SIMD_2_PI ;
}
virtual ~ btTriangleInfoMap ( ) { }
2019-01-03 14:26:51 +01:00
virtual int calculateSerializeBufferSize ( ) const ;
2017-08-01 14:30:58 +02:00
///fills the dataBuffer and returns the struct name (and 0 on failure)
2019-01-03 14:26:51 +01:00
virtual const char * serialize ( void * dataBuffer , btSerializer * serializer ) const ;
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
void deSerialize ( struct btTriangleInfoMapData & data ) ;
2017-08-01 14:30:58 +02:00
} ;
2019-01-03 14:26:51 +01:00
// clang-format off
2017-08-01 14:30:58 +02:00
///those fields have to be float and not btScalar for the serialization to work properly
struct btTriangleInfoData
{
int m_flags ;
float m_edgeV0V1Angle ;
float m_edgeV1V2Angle ;
float m_edgeV2V0Angle ;
} ;
struct btTriangleInfoMapData
{
int * m_hashTablePtr ;
int * m_nextPtr ;
btTriangleInfoData * m_valueArrayPtr ;
int * m_keyArrayPtr ;
float m_convexEpsilon ;
float m_planarEpsilon ;
float m_equalVertexThreshold ;
float m_edgeDistanceThreshold ;
float m_zeroAreaThreshold ;
int m_nextSize ;
int m_hashTableSize ;
int m_numValues ;
int m_numKeys ;
char m_padding [ 4 ] ;
} ;
2019-01-03 14:26:51 +01:00
// clang-format on
SIMD_FORCE_INLINE int btTriangleInfoMap : : calculateSerializeBufferSize ( ) const
2017-08-01 14:30:58 +02:00
{
return sizeof ( btTriangleInfoMapData ) ;
}
///fills the dataBuffer and returns the struct name (and 0 on failure)
2019-01-03 14:26:51 +01:00
SIMD_FORCE_INLINE const char * btTriangleInfoMap : : serialize ( void * dataBuffer , btSerializer * serializer ) const
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
btTriangleInfoMapData * tmapData = ( btTriangleInfoMapData * ) dataBuffer ;
2017-08-01 14:30:58 +02:00
tmapData - > m_convexEpsilon = ( float ) m_convexEpsilon ;
tmapData - > m_planarEpsilon = ( float ) m_planarEpsilon ;
2019-01-03 14:26:51 +01:00
tmapData - > m_equalVertexThreshold = ( float ) m_equalVertexThreshold ;
2017-08-01 14:30:58 +02:00
tmapData - > m_edgeDistanceThreshold = ( float ) m_edgeDistanceThreshold ;
tmapData - > m_zeroAreaThreshold = ( float ) m_zeroAreaThreshold ;
2019-01-03 14:26:51 +01:00
2017-08-01 14:30:58 +02:00
tmapData - > m_hashTableSize = m_hashTable . size ( ) ;
tmapData - > m_hashTablePtr = tmapData - > m_hashTableSize ? ( int * ) serializer - > getUniquePointer ( ( void * ) & m_hashTable [ 0 ] ) : 0 ;
if ( tmapData - > m_hashTablePtr )
2019-01-03 14:26:51 +01:00
{
2017-08-01 14:30:58 +02:00
//serialize an int buffer
int sz = sizeof ( int ) ;
int numElem = tmapData - > m_hashTableSize ;
2019-01-03 14:26:51 +01:00
btChunk * chunk = serializer - > allocate ( sz , numElem ) ;
2017-08-01 14:30:58 +02:00
int * memPtr = ( int * ) chunk - > m_oldPtr ;
2019-01-03 14:26:51 +01:00
for ( int i = 0 ; i < numElem ; i + + , memPtr + + )
2017-08-01 14:30:58 +02:00
{
* memPtr = m_hashTable [ i ] ;
}
2019-01-03 14:26:51 +01:00
serializer - > finalizeChunk ( chunk , " int " , BT_ARRAY_CODE , ( void * ) & m_hashTable [ 0 ] ) ;
2017-08-01 14:30:58 +02:00
}
tmapData - > m_nextSize = m_next . size ( ) ;
2019-01-03 14:26:51 +01:00
tmapData - > m_nextPtr = tmapData - > m_nextSize ? ( int * ) serializer - > getUniquePointer ( ( void * ) & m_next [ 0 ] ) : 0 ;
2017-08-01 14:30:58 +02:00
if ( tmapData - > m_nextPtr )
{
int sz = sizeof ( int ) ;
int numElem = tmapData - > m_nextSize ;
2019-01-03 14:26:51 +01:00
btChunk * chunk = serializer - > allocate ( sz , numElem ) ;
2017-08-01 14:30:58 +02:00
int * memPtr = ( int * ) chunk - > m_oldPtr ;
2019-01-03 14:26:51 +01:00
for ( int i = 0 ; i < numElem ; i + + , memPtr + + )
2017-08-01 14:30:58 +02:00
{
* memPtr = m_next [ i ] ;
}
2019-01-03 14:26:51 +01:00
serializer - > finalizeChunk ( chunk , " int " , BT_ARRAY_CODE , ( void * ) & m_next [ 0 ] ) ;
2017-08-01 14:30:58 +02:00
}
2019-01-03 14:26:51 +01:00
2017-08-01 14:30:58 +02:00
tmapData - > m_numValues = m_valueArray . size ( ) ;
2019-01-03 14:26:51 +01:00
tmapData - > m_valueArrayPtr = tmapData - > m_numValues ? ( btTriangleInfoData * ) serializer - > getUniquePointer ( ( void * ) & m_valueArray [ 0 ] ) : 0 ;
2017-08-01 14:30:58 +02:00
if ( tmapData - > m_valueArrayPtr )
{
int sz = sizeof ( btTriangleInfoData ) ;
int numElem = tmapData - > m_numValues ;
2019-01-03 14:26:51 +01:00
btChunk * chunk = serializer - > allocate ( sz , numElem ) ;
2017-08-01 14:30:58 +02:00
btTriangleInfoData * memPtr = ( btTriangleInfoData * ) chunk - > m_oldPtr ;
2019-01-03 14:26:51 +01:00
for ( int i = 0 ; i < numElem ; i + + , memPtr + + )
2017-08-01 14:30:58 +02:00
{
memPtr - > m_edgeV0V1Angle = ( float ) m_valueArray [ i ] . m_edgeV0V1Angle ;
memPtr - > m_edgeV1V2Angle = ( float ) m_valueArray [ i ] . m_edgeV1V2Angle ;
memPtr - > m_edgeV2V0Angle = ( float ) m_valueArray [ i ] . m_edgeV2V0Angle ;
memPtr - > m_flags = m_valueArray [ i ] . m_flags ;
}
2019-01-03 14:26:51 +01:00
serializer - > finalizeChunk ( chunk , " btTriangleInfoData " , BT_ARRAY_CODE , ( void * ) & m_valueArray [ 0 ] ) ;
2017-08-01 14:30:58 +02:00
}
2019-01-03 14:26:51 +01:00
2017-08-01 14:30:58 +02:00
tmapData - > m_numKeys = m_keyArray . size ( ) ;
tmapData - > m_keyArrayPtr = tmapData - > m_numKeys ? ( int * ) serializer - > getUniquePointer ( ( void * ) & m_keyArray [ 0 ] ) : 0 ;
if ( tmapData - > m_keyArrayPtr )
{
int sz = sizeof ( int ) ;
int numElem = tmapData - > m_numValues ;
2019-01-03 14:26:51 +01:00
btChunk * chunk = serializer - > allocate ( sz , numElem ) ;
2017-08-01 14:30:58 +02:00
int * memPtr = ( int * ) chunk - > m_oldPtr ;
2019-01-03 14:26:51 +01:00
for ( int i = 0 ; i < numElem ; i + + , memPtr + + )
2017-08-01 14:30:58 +02:00
{
* memPtr = m_keyArray [ i ] . getUid1 ( ) ;
}
2019-01-03 14:26:51 +01:00
serializer - > finalizeChunk ( chunk , " int " , BT_ARRAY_CODE , ( void * ) & m_keyArray [ 0 ] ) ;
2017-08-01 14:30:58 +02:00
}
// Fill padding with zeros to appease msan.
tmapData - > m_padding [ 0 ] = 0 ;
tmapData - > m_padding [ 1 ] = 0 ;
tmapData - > m_padding [ 2 ] = 0 ;
tmapData - > m_padding [ 3 ] = 0 ;
return " btTriangleInfoMapData " ;
}
///fills the dataBuffer and returns the struct name (and 0 on failure)
2019-01-03 14:26:51 +01:00
SIMD_FORCE_INLINE void btTriangleInfoMap : : deSerialize ( btTriangleInfoMapData & tmapData )
2017-08-01 14:30:58 +02:00
{
m_convexEpsilon = tmapData . m_convexEpsilon ;
m_planarEpsilon = tmapData . m_planarEpsilon ;
m_equalVertexThreshold = tmapData . m_equalVertexThreshold ;
m_edgeDistanceThreshold = tmapData . m_edgeDistanceThreshold ;
m_zeroAreaThreshold = tmapData . m_zeroAreaThreshold ;
m_hashTable . resize ( tmapData . m_hashTableSize ) ;
2019-01-03 14:26:51 +01:00
int i = 0 ;
for ( i = 0 ; i < tmapData . m_hashTableSize ; i + + )
2017-08-01 14:30:58 +02:00
{
m_hashTable [ i ] = tmapData . m_hashTablePtr [ i ] ;
}
m_next . resize ( tmapData . m_nextSize ) ;
2019-01-03 14:26:51 +01:00
for ( i = 0 ; i < tmapData . m_nextSize ; i + + )
2017-08-01 14:30:58 +02:00
{
m_next [ i ] = tmapData . m_nextPtr [ i ] ;
}
m_valueArray . resize ( tmapData . m_numValues ) ;
2019-01-03 14:26:51 +01:00
for ( i = 0 ; i < tmapData . m_numValues ; i + + )
2017-08-01 14:30:58 +02:00
{
m_valueArray [ i ] . m_edgeV0V1Angle = tmapData . m_valueArrayPtr [ i ] . m_edgeV0V1Angle ;
m_valueArray [ i ] . m_edgeV1V2Angle = tmapData . m_valueArrayPtr [ i ] . m_edgeV1V2Angle ;
m_valueArray [ i ] . m_edgeV2V0Angle = tmapData . m_valueArrayPtr [ i ] . m_edgeV2V0Angle ;
m_valueArray [ i ] . m_flags = tmapData . m_valueArrayPtr [ i ] . m_flags ;
}
2019-01-03 14:26:51 +01:00
m_keyArray . resize ( tmapData . m_numKeys , btHashInt ( 0 ) ) ;
for ( i = 0 ; i < tmapData . m_numKeys ; i + + )
2017-08-01 14:30:58 +02:00
{
m_keyArray [ i ] . setUid1 ( tmapData . m_keyArrayPtr [ i ] ) ;
}
}
2019-01-03 14:26:51 +01:00
# endif //_BT_TRIANGLE_INFO_MAP_H