Tizen 2.1 base
[platform/upstream/libbullet.git] / src / BulletCollision / CollisionShapes / btTriangleInfoMap.h
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2010 Erwin Coumans  http://bulletphysics.org
4
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose, 
8 including commercial applications, and to alter it and redistribute it freely, 
9 subject to the following restrictions:
10
11 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15
16 #ifndef _BT_TRIANGLE_INFO_MAP_H
17 #define _BT_TRIANGLE_INFO_MAP_H
18
19
20 #include "LinearMath/btHashMap.h"
21 #include "LinearMath/btSerializer.h"
22
23
24 ///for btTriangleInfo m_flags
25 #define TRI_INFO_V0V1_CONVEX 1
26 #define TRI_INFO_V1V2_CONVEX 2
27 #define TRI_INFO_V2V0_CONVEX 4
28
29 #define TRI_INFO_V0V1_SWAP_NORMALB 8
30 #define TRI_INFO_V1V2_SWAP_NORMALB 16
31 #define TRI_INFO_V2V0_SWAP_NORMALB 32
32
33
34 ///The btTriangleInfo structure stores information to adjust collision normals to avoid collisions against internal edges
35 ///it can be generated using 
36 struct  btTriangleInfo
37 {
38         btTriangleInfo()
39         {
40                 m_edgeV0V1Angle = SIMD_2_PI;
41                 m_edgeV1V2Angle = SIMD_2_PI;
42                 m_edgeV2V0Angle = SIMD_2_PI;
43                 m_flags=0;
44         }
45
46         int                     m_flags;
47
48         btScalar        m_edgeV0V1Angle;
49         btScalar        m_edgeV1V2Angle;
50         btScalar        m_edgeV2V0Angle;
51
52 };
53
54 typedef btHashMap<btHashInt,btTriangleInfo> btInternalTriangleInfoMap;
55
56
57 ///The btTriangleInfoMap stores edge angle information for some triangles. You can compute this information yourself or using btGenerateInternalEdgeInfo.
58 struct  btTriangleInfoMap : public btInternalTriangleInfoMap
59 {
60         btScalar        m_convexEpsilon;///used to determine if an edge or contact normal is convex, using the dot product
61         btScalar        m_planarEpsilon; ///used to determine if a triangle edge is planar with zero angle
62         btScalar        m_equalVertexThreshold; ///used to compute connectivity: if the distance between two vertices is smaller than m_equalVertexThreshold, they are considered to be 'shared'
63         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"
64         btScalar        m_maxEdgeAngleThreshold; //ignore edges that connect triangles at an angle larger than this m_maxEdgeAngleThreshold
65         btScalar        m_zeroAreaThreshold; ///used to determine if a triangle is degenerate (length squared of cross product of 2 triangle edges < threshold)
66         
67         
68         btTriangleInfoMap()
69         {
70                 m_convexEpsilon = 0.00f;
71                 m_planarEpsilon = 0.0001f;
72                 m_equalVertexThreshold = btScalar(0.0001)*btScalar(0.0001);
73                 m_edgeDistanceThreshold = btScalar(0.1);
74                 m_zeroAreaThreshold = btScalar(0.0001)*btScalar(0.0001);
75                 m_maxEdgeAngleThreshold = SIMD_2_PI;
76         }
77         virtual ~btTriangleInfoMap() {}
78
79         virtual int     calculateSerializeBufferSize() const;
80
81         ///fills the dataBuffer and returns the struct name (and 0 on failure)
82         virtual const char*     serialize(void* dataBuffer, btSerializer* serializer) const;
83
84         void    deSerialize(struct btTriangleInfoMapData& data);
85
86 };
87
88 ///those fields have to be float and not btScalar for the serialization to work properly
89 struct  btTriangleInfoData
90 {
91         int                     m_flags;
92         float   m_edgeV0V1Angle;
93         float   m_edgeV1V2Angle;
94         float   m_edgeV2V0Angle;
95 };
96
97 struct  btTriangleInfoMapData
98 {
99         int                                     *m_hashTablePtr;
100         int                                     *m_nextPtr;
101         btTriangleInfoData      *m_valueArrayPtr;
102         int                                     *m_keyArrayPtr;
103
104         float   m_convexEpsilon;
105         float   m_planarEpsilon;
106         float   m_equalVertexThreshold; 
107         float   m_edgeDistanceThreshold;
108         float   m_zeroAreaThreshold;
109
110         int             m_nextSize;
111         int             m_hashTableSize;
112         int             m_numValues;
113         int             m_numKeys;
114         char    m_padding[4];
115 };
116
117 SIMD_FORCE_INLINE       int     btTriangleInfoMap::calculateSerializeBufferSize() const
118 {
119         return sizeof(btTriangleInfoMapData);
120 }
121
122 ///fills the dataBuffer and returns the struct name (and 0 on failure)
123 SIMD_FORCE_INLINE       const char*     btTriangleInfoMap::serialize(void* dataBuffer, btSerializer* serializer) const
124 {
125         btTriangleInfoMapData* tmapData = (btTriangleInfoMapData*) dataBuffer;
126         tmapData->m_convexEpsilon = m_convexEpsilon;
127         tmapData->m_planarEpsilon = m_planarEpsilon;
128         tmapData->m_equalVertexThreshold = m_equalVertexThreshold;
129         tmapData->m_edgeDistanceThreshold = m_edgeDistanceThreshold;
130         tmapData->m_zeroAreaThreshold = m_zeroAreaThreshold;
131         
132         tmapData->m_hashTableSize = m_hashTable.size();
133
134         tmapData->m_hashTablePtr = tmapData->m_hashTableSize ? (int*)serializer->getUniquePointer((void*)&m_hashTable[0]) : 0;
135         if (tmapData->m_hashTablePtr)
136         { 
137                 //serialize an int buffer
138                 int sz = sizeof(int);
139                 int numElem = tmapData->m_hashTableSize;
140                 btChunk* chunk = serializer->allocate(sz,numElem);
141                 int* memPtr = (int*)chunk->m_oldPtr;
142                 for (int i=0;i<numElem;i++,memPtr++)
143                 {
144                         *memPtr = m_hashTable[i];
145                 }
146                 serializer->finalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*)&m_hashTable[0]);
147
148         }
149
150         tmapData->m_nextSize = m_next.size();
151         tmapData->m_nextPtr = tmapData->m_nextSize? (int*)serializer->getUniquePointer((void*)&m_next[0]): 0;
152         if (tmapData->m_nextPtr)
153         {
154                 int sz = sizeof(int);
155                 int numElem = tmapData->m_nextSize;
156                 btChunk* chunk = serializer->allocate(sz,numElem);
157                 int* memPtr = (int*)chunk->m_oldPtr;
158                 for (int i=0;i<numElem;i++,memPtr++)
159                 {
160                         *memPtr = m_next[i];
161                 }
162                 serializer->finalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*)&m_next[0]);
163         }
164         
165         tmapData->m_numValues = m_valueArray.size();
166         tmapData->m_valueArrayPtr = tmapData->m_numValues ? (btTriangleInfoData*)serializer->getUniquePointer((void*)&m_valueArray[0]): 0;
167         if (tmapData->m_valueArrayPtr)
168         {
169                 int sz = sizeof(btTriangleInfoData);
170                 int numElem = tmapData->m_numValues;
171                 btChunk* chunk = serializer->allocate(sz,numElem);
172                 btTriangleInfoData* memPtr = (btTriangleInfoData*)chunk->m_oldPtr;
173                 for (int i=0;i<numElem;i++,memPtr++)
174                 {
175                         memPtr->m_edgeV0V1Angle = m_valueArray[i].m_edgeV0V1Angle;
176                         memPtr->m_edgeV1V2Angle = m_valueArray[i].m_edgeV1V2Angle;
177                         memPtr->m_edgeV2V0Angle = m_valueArray[i].m_edgeV2V0Angle;
178                         memPtr->m_flags = m_valueArray[i].m_flags;
179                 }
180                 serializer->finalizeChunk(chunk,"btTriangleInfoData",BT_ARRAY_CODE,(void*) &m_valueArray[0]);
181         }
182         
183         tmapData->m_numKeys = m_keyArray.size();
184         tmapData->m_keyArrayPtr = tmapData->m_numKeys ? (int*)serializer->getUniquePointer((void*)&m_keyArray[0]) : 0;
185         if (tmapData->m_keyArrayPtr)
186         {
187                 int sz = sizeof(int);
188                 int numElem = tmapData->m_numValues;
189                 btChunk* chunk = serializer->allocate(sz,numElem);
190                 int* memPtr = (int*)chunk->m_oldPtr;
191                 for (int i=0;i<numElem;i++,memPtr++)
192                 {
193                         *memPtr = m_keyArray[i].getUid1();
194                 }
195                 serializer->finalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*) &m_keyArray[0]);
196
197         }
198         return "btTriangleInfoMapData";
199 }
200
201
202
203 ///fills the dataBuffer and returns the struct name (and 0 on failure)
204 SIMD_FORCE_INLINE       void    btTriangleInfoMap::deSerialize(btTriangleInfoMapData& tmapData )
205 {
206
207
208         m_convexEpsilon = tmapData.m_convexEpsilon;
209         m_planarEpsilon = tmapData.m_planarEpsilon;
210         m_equalVertexThreshold = tmapData.m_equalVertexThreshold;
211         m_edgeDistanceThreshold = tmapData.m_edgeDistanceThreshold;
212         m_zeroAreaThreshold = tmapData.m_zeroAreaThreshold;
213         m_hashTable.resize(tmapData.m_hashTableSize);
214         int i =0;
215         for (i=0;i<tmapData.m_hashTableSize;i++)
216         {
217                 m_hashTable[i] = tmapData.m_hashTablePtr[i];
218         }
219         m_next.resize(tmapData.m_nextSize);
220         for (i=0;i<tmapData.m_nextSize;i++)
221         {
222                 m_next[i] = tmapData.m_nextPtr[i];
223         }
224         m_valueArray.resize(tmapData.m_numValues);
225         for (i=0;i<tmapData.m_numValues;i++)
226         {
227                 m_valueArray[i].m_edgeV0V1Angle = tmapData.m_valueArrayPtr[i].m_edgeV0V1Angle;
228                 m_valueArray[i].m_edgeV1V2Angle = tmapData.m_valueArrayPtr[i].m_edgeV1V2Angle;
229                 m_valueArray[i].m_edgeV2V0Angle = tmapData.m_valueArrayPtr[i].m_edgeV2V0Angle;
230                 m_valueArray[i].m_flags = tmapData.m_valueArrayPtr[i].m_flags;
231         }
232         
233         m_keyArray.resize(tmapData.m_numKeys,btHashInt(0));
234         for (i=0;i<tmapData.m_numKeys;i++)
235         {
236                 m_keyArray[i].setUid1(tmapData.m_keyArrayPtr[i]);
237         }
238 }
239
240
241 #endif //_BT_TRIANGLE_INFO_MAP_H