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
 |