forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			249 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			249 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /*
 | ||
|  | 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
 | ||
|  | ///it can be generated using 
 | ||
|  | struct	btTriangleInfo | ||
|  | { | ||
|  | 	btTriangleInfo() | ||
|  | 	{ | ||
|  | 		m_edgeV0V1Angle = SIMD_2_PI; | ||
|  | 		m_edgeV1V2Angle = SIMD_2_PI; | ||
|  | 		m_edgeV2V0Angle = SIMD_2_PI; | ||
|  | 		m_flags=0; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	int			m_flags; | ||
|  | 
 | ||
|  | 	btScalar	m_edgeV0V1Angle; | ||
|  | 	btScalar	m_edgeV1V2Angle; | ||
|  | 	btScalar	m_edgeV2V0Angle; | ||
|  | 
 | ||
|  | }; | ||
|  | 
 | ||
|  | typedef btHashMap<btHashInt,btTriangleInfo> btInternalTriangleInfoMap; | ||
|  | 
 | ||
|  | 
 | ||
|  | ///The btTriangleInfoMap stores edge angle information for some triangles. You can compute this information yourself or using btGenerateInternalEdgeInfo.
 | ||
|  | struct	btTriangleInfoMap : public btInternalTriangleInfoMap | ||
|  | { | ||
|  | 	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)
 | ||
|  | 	 | ||
|  | 	 | ||
|  | 	btTriangleInfoMap() | ||
|  | 	{ | ||
|  | 		m_convexEpsilon = 0.00f; | ||
|  | 		m_planarEpsilon = 0.0001f; | ||
|  | 		m_equalVertexThreshold = btScalar(0.0001)*btScalar(0.0001); | ||
|  | 		m_edgeDistanceThreshold = btScalar(0.1); | ||
|  | 		m_zeroAreaThreshold = btScalar(0.0001)*btScalar(0.0001); | ||
|  | 		m_maxEdgeAngleThreshold = SIMD_2_PI; | ||
|  | 	} | ||
|  | 	virtual ~btTriangleInfoMap() {} | ||
|  | 
 | ||
|  | 	virtual	int	calculateSerializeBufferSize() const; | ||
|  | 
 | ||
|  | 	///fills the dataBuffer and returns the struct name (and 0 on failure)
 | ||
|  | 	virtual	const char*	serialize(void* dataBuffer, btSerializer* serializer) const; | ||
|  | 
 | ||
|  | 	void	deSerialize(struct btTriangleInfoMapData& data); | ||
|  | 
 | ||
|  | }; | ||
|  | 
 | ||
|  | ///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]; | ||
|  | }; | ||
|  | 
 | ||
|  | SIMD_FORCE_INLINE	int	btTriangleInfoMap::calculateSerializeBufferSize() const | ||
|  | { | ||
|  | 	return sizeof(btTriangleInfoMapData); | ||
|  | } | ||
|  | 
 | ||
|  | ///fills the dataBuffer and returns the struct name (and 0 on failure)
 | ||
|  | SIMD_FORCE_INLINE	const char*	btTriangleInfoMap::serialize(void* dataBuffer, btSerializer* serializer) const | ||
|  | { | ||
|  | 	btTriangleInfoMapData* tmapData = (btTriangleInfoMapData*) dataBuffer; | ||
|  | 	tmapData->m_convexEpsilon = (float)m_convexEpsilon; | ||
|  | 	tmapData->m_planarEpsilon = (float)m_planarEpsilon; | ||
|  | 	tmapData->m_equalVertexThreshold =(float) m_equalVertexThreshold; | ||
|  | 	tmapData->m_edgeDistanceThreshold = (float)m_edgeDistanceThreshold; | ||
|  | 	tmapData->m_zeroAreaThreshold = (float)m_zeroAreaThreshold; | ||
|  | 	 | ||
|  | 	tmapData->m_hashTableSize = m_hashTable.size(); | ||
|  | 
 | ||
|  | 	tmapData->m_hashTablePtr = tmapData->m_hashTableSize ? (int*)serializer->getUniquePointer((void*)&m_hashTable[0]) : 0; | ||
|  | 	if (tmapData->m_hashTablePtr) | ||
|  | 	{  | ||
|  | 		//serialize an int buffer
 | ||
|  | 		int sz = sizeof(int); | ||
|  | 		int numElem = tmapData->m_hashTableSize; | ||
|  | 		btChunk* chunk = serializer->allocate(sz,numElem); | ||
|  | 		int* memPtr = (int*)chunk->m_oldPtr; | ||
|  | 		for (int i=0;i<numElem;i++,memPtr++) | ||
|  | 		{ | ||
|  | 			*memPtr = m_hashTable[i]; | ||
|  | 		} | ||
|  | 		serializer->finalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*)&m_hashTable[0]); | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	tmapData->m_nextSize = m_next.size(); | ||
|  | 	tmapData->m_nextPtr = tmapData->m_nextSize? (int*)serializer->getUniquePointer((void*)&m_next[0]): 0; | ||
|  | 	if (tmapData->m_nextPtr) | ||
|  | 	{ | ||
|  | 		int sz = sizeof(int); | ||
|  | 		int numElem = tmapData->m_nextSize; | ||
|  | 		btChunk* chunk = serializer->allocate(sz,numElem); | ||
|  | 		int* memPtr = (int*)chunk->m_oldPtr; | ||
|  | 		for (int i=0;i<numElem;i++,memPtr++) | ||
|  | 		{ | ||
|  | 			*memPtr = m_next[i]; | ||
|  | 		} | ||
|  | 		serializer->finalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*)&m_next[0]); | ||
|  | 	} | ||
|  | 	 | ||
|  | 	tmapData->m_numValues = m_valueArray.size(); | ||
|  | 	tmapData->m_valueArrayPtr = tmapData->m_numValues ? (btTriangleInfoData*)serializer->getUniquePointer((void*)&m_valueArray[0]): 0; | ||
|  | 	if (tmapData->m_valueArrayPtr) | ||
|  | 	{ | ||
|  | 		int sz = sizeof(btTriangleInfoData); | ||
|  | 		int numElem = tmapData->m_numValues; | ||
|  | 		btChunk* chunk = serializer->allocate(sz,numElem); | ||
|  | 		btTriangleInfoData* memPtr = (btTriangleInfoData*)chunk->m_oldPtr; | ||
|  | 		for (int i=0;i<numElem;i++,memPtr++) | ||
|  | 		{ | ||
|  | 			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; | ||
|  | 		} | ||
|  | 		serializer->finalizeChunk(chunk,"btTriangleInfoData",BT_ARRAY_CODE,(void*) &m_valueArray[0]); | ||
|  | 	} | ||
|  | 	 | ||
|  | 	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; | ||
|  | 		btChunk* chunk = serializer->allocate(sz,numElem); | ||
|  | 		int* memPtr = (int*)chunk->m_oldPtr; | ||
|  | 		for (int i=0;i<numElem;i++,memPtr++) | ||
|  | 		{ | ||
|  | 			*memPtr = m_keyArray[i].getUid1(); | ||
|  | 		} | ||
|  | 		serializer->finalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*) &m_keyArray[0]); | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// 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)
 | ||
|  | SIMD_FORCE_INLINE	void	btTriangleInfoMap::deSerialize(btTriangleInfoMapData& tmapData ) | ||
|  | { | ||
|  | 
 | ||
|  | 
 | ||
|  | 	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); | ||
|  | 	int i =0; | ||
|  | 	for (i=0;i<tmapData.m_hashTableSize;i++) | ||
|  | 	{ | ||
|  | 		m_hashTable[i] = tmapData.m_hashTablePtr[i]; | ||
|  | 	} | ||
|  | 	m_next.resize(tmapData.m_nextSize); | ||
|  | 	for (i=0;i<tmapData.m_nextSize;i++) | ||
|  | 	{ | ||
|  | 		m_next[i] = tmapData.m_nextPtr[i]; | ||
|  | 	} | ||
|  | 	m_valueArray.resize(tmapData.m_numValues); | ||
|  | 	for (i=0;i<tmapData.m_numValues;i++) | ||
|  | 	{ | ||
|  | 		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; | ||
|  | 	} | ||
|  | 	 | ||
|  | 	m_keyArray.resize(tmapData.m_numKeys,btHashInt(0)); | ||
|  | 	for (i=0;i<tmapData.m_numKeys;i++) | ||
|  | 	{ | ||
|  | 		m_keyArray[i].setUid1(tmapData.m_keyArrayPtr[i]); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | #endif //_BT_TRIANGLE_INFO_MAP_H
 |