Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/external/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp @ 9366

Last change on this file since 9366 was 8393, checked in by rgrieder, 14 years ago

Updated Bullet from v2.77 to v2.78.
(I'm not going to make a branch for that since the update from 2.74 to 2.77 hasn't been tested that much either).

You will HAVE to do a complete RECOMPILE! I tested with MSVC and MinGW and they both threw linker errors at me.

  • Property svn:eol-style set to native
File size: 14.9 KB
Line 
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16#include "btStridingMeshInterface.h"
17#include "LinearMath/btSerializer.h"
18
19btStridingMeshInterface::~btStridingMeshInterface()
20{
21
22}
23
24
25void    btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
26{
27        (void)aabbMin;
28        (void)aabbMax;
29        int numtotalphysicsverts = 0;
30        int part,graphicssubparts = getNumSubParts();
31        const unsigned char * vertexbase;
32        const unsigned char * indexbase;
33        int indexstride;
34        PHY_ScalarType type;
35        PHY_ScalarType gfxindextype;
36        int stride,numverts,numtriangles;
37        int gfxindex;
38        btVector3 triangle[3];
39
40        btVector3 meshScaling = getScaling();
41
42        ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype
43        for (part=0;part<graphicssubparts ;part++)
44        {
45                getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part);
46                numtotalphysicsverts+=numtriangles*3; //upper bound
47
48                ///unlike that developers want to pass in double-precision meshes in single-precision Bullet build
49                ///so disable this feature by default
50                ///see patch http://code.google.com/p/bullet/issues/detail?id=213
51
52                switch (type)
53                {
54                case PHY_FLOAT:
55                 {
56
57                         float* graphicsbase;
58
59                         switch (gfxindextype)
60                         {
61                         case PHY_INTEGER:
62                                 {
63                                         for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
64                                         {
65                                                 unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
66                                                 graphicsbase = (float*)(vertexbase+tri_indices[0]*stride);
67                                                 triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
68                                                 graphicsbase = (float*)(vertexbase+tri_indices[1]*stride);
69                                                 triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),    graphicsbase[2]*meshScaling.getZ());
70                                                 graphicsbase = (float*)(vertexbase+tri_indices[2]*stride);
71                                                 triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),    graphicsbase[2]*meshScaling.getZ());
72                                                 callback->internalProcessTriangleIndex(triangle,part,gfxindex);
73                                         }
74                                         break;
75                                 }
76                         case PHY_SHORT:
77                                 {
78                                         for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
79                                         {
80                                                 unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
81                                                 graphicsbase = (float*)(vertexbase+tri_indices[0]*stride);
82                                                 triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
83                                                 graphicsbase = (float*)(vertexbase+tri_indices[1]*stride);
84                                                 triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),    graphicsbase[2]*meshScaling.getZ());
85                                                 graphicsbase = (float*)(vertexbase+tri_indices[2]*stride);
86                                                 triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),    graphicsbase[2]*meshScaling.getZ());
87                                                 callback->internalProcessTriangleIndex(triangle,part,gfxindex);
88                                         }
89                                         break;
90                                 }
91                        case PHY_UCHAR:
92                                 {
93                                         for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
94                                         {
95                                                 unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride);
96                                                 graphicsbase = (float*)(vertexbase+tri_indices[0]*stride);
97                                                 triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
98                                                 graphicsbase = (float*)(vertexbase+tri_indices[1]*stride);
99                                                 triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),    graphicsbase[2]*meshScaling.getZ());
100                                                 graphicsbase = (float*)(vertexbase+tri_indices[2]*stride);
101                                                 triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),    graphicsbase[2]*meshScaling.getZ());
102                                                 callback->internalProcessTriangleIndex(triangle,part,gfxindex);
103                                         }
104                                         break;
105                                 }
106                         default:
107                                 btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
108                         }
109                         break;
110                 }
111
112                case PHY_DOUBLE:
113                        {
114                                double* graphicsbase;
115
116                                switch (gfxindextype)
117                                {
118                                case PHY_INTEGER:
119                                        {
120                                                for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
121                                                {
122                                                        unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
123                                                        graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
124                                                        triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
125                                                        graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
126                                                        triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
127                                                        graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
128                                                        triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
129                                                        callback->internalProcessTriangleIndex(triangle,part,gfxindex);
130                                                }
131                                                break;
132                                        }
133                                case PHY_SHORT:
134                                        {
135                                                for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
136                                                {
137                                                        unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
138                                                        graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
139                                                        triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
140                                                        graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
141                                                        triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
142                                                        graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
143                                                        triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
144                                                        callback->internalProcessTriangleIndex(triangle,part,gfxindex);
145                                                }
146                                                break;
147                                        }
148                                case PHY_UCHAR:
149                                        {
150                                                for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
151                                                {
152                                                        unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride);
153                                                        graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
154                                                        triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
155                                                        graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
156                                                        triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
157                                                        graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
158                                                        triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
159                                                        callback->internalProcessTriangleIndex(triangle,part,gfxindex);
160                                                }
161                                                break;
162                                        }
163                                default:
164                                        btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
165                                }
166                                break;
167                        }
168                default:
169                        btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
170                }
171
172                unLockReadOnlyVertexBase(part);
173        }
174}
175
176void    btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax)
177{
178
179        struct  AabbCalculationCallback : public btInternalTriangleIndexCallback
180        {
181                btVector3       m_aabbMin;
182                btVector3       m_aabbMax;
183
184                AabbCalculationCallback()
185                {
186                        m_aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
187                        m_aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
188                }
189
190                virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
191                {
192                        (void)partId;
193                        (void)triangleIndex;
194
195                        m_aabbMin.setMin(triangle[0]);
196                        m_aabbMax.setMax(triangle[0]);
197                        m_aabbMin.setMin(triangle[1]);
198                        m_aabbMax.setMax(triangle[1]);
199                        m_aabbMin.setMin(triangle[2]);
200                        m_aabbMax.setMax(triangle[2]);
201                }
202        };
203
204        //first calculate the total aabb for all triangles
205        AabbCalculationCallback aabbCallback;
206        aabbMin.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
207        aabbMax.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
208        InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax);
209
210        aabbMin = aabbCallback.m_aabbMin;
211        aabbMax = aabbCallback.m_aabbMax;
212}
213
214
215
216///fills the dataBuffer and returns the struct name (and 0 on failure)
217const char*     btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* serializer) const
218{
219        btStridingMeshInterfaceData* trimeshData = (btStridingMeshInterfaceData*) dataBuffer;
220
221        trimeshData->m_numMeshParts = getNumSubParts();
222
223        //void* uniquePtr = 0;
224
225        trimeshData->m_meshPartsPtr = 0;
226
227        if (trimeshData->m_numMeshParts)
228        {
229                btChunk* chunk = serializer->allocate(sizeof(btMeshPartData),trimeshData->m_numMeshParts);
230                btMeshPartData* memPtr = (btMeshPartData*)chunk->m_oldPtr;
231                trimeshData->m_meshPartsPtr = (btMeshPartData *)serializer->getUniquePointer(memPtr);
232
233
234        //      int numtotalphysicsverts = 0;
235                int part,graphicssubparts = getNumSubParts();
236                const unsigned char * vertexbase;
237                const unsigned char * indexbase;
238                int indexstride;
239                PHY_ScalarType type;
240                PHY_ScalarType gfxindextype;
241                int stride,numverts,numtriangles;
242                int gfxindex;
243        //      btVector3 triangle[3];
244
245                btVector3 meshScaling = getScaling();
246
247                ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype
248                for (part=0;part<graphicssubparts ;part++,memPtr++)
249                {
250                        getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part);
251                        memPtr->m_numTriangles = numtriangles;//indices = 3*numtriangles
252                        memPtr->m_numVertices = numverts;
253                        memPtr->m_indices16 = 0;
254                        memPtr->m_indices32 = 0;
255                        memPtr->m_3indices16 = 0;
256                        memPtr->m_vertices3f = 0;
257                        memPtr->m_vertices3d = 0;
258
259                        switch (gfxindextype)
260                        {
261                        case PHY_INTEGER:
262                                {
263                                        int numindices = numtriangles*3;
264                               
265                                        if (numindices)
266                                        {
267                                                btChunk* chunk = serializer->allocate(sizeof(btIntIndexData),numindices);
268                                                btIntIndexData* tmpIndices = (btIntIndexData*)chunk->m_oldPtr;
269                                                memPtr->m_indices32 = (btIntIndexData*)serializer->getUniquePointer(tmpIndices);
270                                                for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
271                                                {
272                                                        unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
273                                                        tmpIndices[gfxindex*3].m_value = tri_indices[0];
274                                                        tmpIndices[gfxindex*3+1].m_value = tri_indices[1];
275                                                        tmpIndices[gfxindex*3+2].m_value = tri_indices[2];
276                                                }
277                                                serializer->finalizeChunk(chunk,"btIntIndexData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
278                                        }
279                                        break;
280                                }
281                        case PHY_SHORT:
282                                {
283                                        if (numtriangles)
284                                        {
285                                                btChunk* chunk = serializer->allocate(sizeof(btShortIntIndexTripletData),numtriangles);
286                                                btShortIntIndexTripletData* tmpIndices = (btShortIntIndexTripletData*)chunk->m_oldPtr;
287                                                memPtr->m_3indices16 = (btShortIntIndexTripletData*) serializer->getUniquePointer(tmpIndices);
288                                                for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
289                                                {
290                                                        unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
291                                                        tmpIndices[gfxindex].m_values[0] = tri_indices[0];
292                                                        tmpIndices[gfxindex].m_values[1] = tri_indices[1];
293                                                        tmpIndices[gfxindex].m_values[2] = tri_indices[2];
294                                                }
295                                                serializer->finalizeChunk(chunk,"btShortIntIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
296                                        }
297                                        break;
298                                }
299                                case PHY_UCHAR:
300                                {
301                                        if (numtriangles)
302                                        {
303                                                btChunk* chunk = serializer->allocate(sizeof(btCharIndexTripletData),numtriangles);
304                                                btCharIndexTripletData* tmpIndices = (btCharIndexTripletData*)chunk->m_oldPtr;
305                                                memPtr->m_3indices8 = (btCharIndexTripletData*) serializer->getUniquePointer(tmpIndices);
306                                                for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
307                                                {
308                                                        unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride);
309                                                        tmpIndices[gfxindex].m_values[0] = tri_indices[0];
310                                                        tmpIndices[gfxindex].m_values[1] = tri_indices[1];
311                                                        tmpIndices[gfxindex].m_values[2] = tri_indices[2];
312                                                }
313                                                serializer->finalizeChunk(chunk,"btCharIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
314                                        }
315                                        break;
316                                }
317                        default:
318                                {
319                                        btAssert(0);
320                                        //unknown index type
321                                }
322                        }
323
324                        switch (type)
325                        {
326                        case PHY_FLOAT:
327                         {
328                                 float* graphicsbase;
329
330                                 if (numverts)
331                                 {
332                                         btChunk* chunk = serializer->allocate(sizeof(btVector3FloatData),numverts);
333                                         btVector3FloatData* tmpVertices = (btVector3FloatData*) chunk->m_oldPtr;
334                                         memPtr->m_vertices3f = (btVector3FloatData *)serializer->getUniquePointer(tmpVertices);
335                                         for (int i=0;i<numverts;i++)
336                                         {
337                                                 graphicsbase = (float*)(vertexbase+i*stride);
338                                                 tmpVertices[i].m_floats[0] = graphicsbase[0];
339                                                 tmpVertices[i].m_floats[1] = graphicsbase[1];
340                                                 tmpVertices[i].m_floats[2] = graphicsbase[2];
341                                         }
342                                         serializer->finalizeChunk(chunk,"btVector3FloatData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
343                                 }
344                                 break;
345                                }
346
347                        case PHY_DOUBLE:
348                                {
349                                        if (numverts)
350                                        {
351                                                btChunk* chunk = serializer->allocate(sizeof(btVector3DoubleData),numverts);
352                                                btVector3DoubleData* tmpVertices = (btVector3DoubleData*) chunk->m_oldPtr;
353                                                memPtr->m_vertices3d = (btVector3DoubleData *) serializer->getUniquePointer(tmpVertices);
354                                                for (int i=0;i<numverts;i++)
355                                         {
356                                                 double* graphicsbase = (double*)(vertexbase+i*stride);//for now convert to float, might leave it at double
357                                                 tmpVertices[i].m_floats[0] = graphicsbase[0];
358                                                 tmpVertices[i].m_floats[1] = graphicsbase[1];
359                                                 tmpVertices[i].m_floats[2] = graphicsbase[2];
360                                         }
361                                                serializer->finalizeChunk(chunk,"btVector3DoubleData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
362                                        }
363                                        break;
364                                }
365
366                        default:
367                                btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
368                        }
369
370                        unLockReadOnlyVertexBase(part);
371                }
372
373                serializer->finalizeChunk(chunk,"btMeshPartData",BT_ARRAY_CODE,chunk->m_oldPtr);
374        }
375
376
377        m_scaling.serializeFloat(trimeshData->m_scaling);
378        return "btStridingMeshInterfaceData";
379}
Note: See TracBrowser for help on using the repository browser.