Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp @ 8501

Last change on this file since 8501 was 8284, checked in by rgrieder, 14 years ago

Merged revisions 7978 - 8096 from kicklib to kicklib2.

  • Property svn:eol-style set to native
File size: 12.4 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                         default:
92                                 btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
93                         }
94                         break;
95                 }
96
97                case PHY_DOUBLE:
98                        {
99                                double* graphicsbase;
100
101                                switch (gfxindextype)
102                                {
103                                case PHY_INTEGER:
104                                        {
105                                                for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
106                                                {
107                                                        unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
108                                                        graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
109                                                        triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
110                                                        graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
111                                                        triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
112                                                        graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
113                                                        triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
114                                                        callback->internalProcessTriangleIndex(triangle,part,gfxindex);
115                                                }
116                                                break;
117                                        }
118                                case PHY_SHORT:
119                                        {
120                                                for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
121                                                {
122                                                        unsigned short int* tri_indices= (unsigned short 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                                default:
134                                        btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
135                                }
136                                break;
137                        }
138                default:
139                        btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
140                }
141
142                unLockReadOnlyVertexBase(part);
143        }
144}
145
146void    btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax)
147{
148
149        struct  AabbCalculationCallback : public btInternalTriangleIndexCallback
150        {
151                btVector3       m_aabbMin;
152                btVector3       m_aabbMax;
153
154                AabbCalculationCallback()
155                {
156                        m_aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
157                        m_aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
158                }
159
160                virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
161                {
162                        (void)partId;
163                        (void)triangleIndex;
164
165                        m_aabbMin.setMin(triangle[0]);
166                        m_aabbMax.setMax(triangle[0]);
167                        m_aabbMin.setMin(triangle[1]);
168                        m_aabbMax.setMax(triangle[1]);
169                        m_aabbMin.setMin(triangle[2]);
170                        m_aabbMax.setMax(triangle[2]);
171                }
172        };
173
174        //first calculate the total aabb for all triangles
175        AabbCalculationCallback aabbCallback;
176        aabbMin.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
177        aabbMax.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
178        InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax);
179
180        aabbMin = aabbCallback.m_aabbMin;
181        aabbMax = aabbCallback.m_aabbMax;
182}
183
184
185
186///fills the dataBuffer and returns the struct name (and 0 on failure)
187const char*     btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* serializer) const
188{
189        btStridingMeshInterfaceData* trimeshData = (btStridingMeshInterfaceData*) dataBuffer;
190
191        trimeshData->m_numMeshParts = getNumSubParts();
192
193        //void* uniquePtr = 0;
194
195        trimeshData->m_meshPartsPtr = 0;
196
197        if (trimeshData->m_numMeshParts)
198        {
199                btChunk* chunk = serializer->allocate(sizeof(btMeshPartData),trimeshData->m_numMeshParts);
200                btMeshPartData* memPtr = (btMeshPartData*)chunk->m_oldPtr;
201                trimeshData->m_meshPartsPtr = (btMeshPartData *)serializer->getUniquePointer(memPtr);
202
203
204        //      int numtotalphysicsverts = 0;
205                int part,graphicssubparts = getNumSubParts();
206                const unsigned char * vertexbase;
207                const unsigned char * indexbase;
208                int indexstride;
209                PHY_ScalarType type;
210                PHY_ScalarType gfxindextype;
211                int stride,numverts,numtriangles;
212                int gfxindex;
213        //      btVector3 triangle[3];
214
215                btVector3 meshScaling = getScaling();
216
217                ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype
218                for (part=0;part<graphicssubparts ;part++,memPtr++)
219                {
220                        getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part);
221                        memPtr->m_numTriangles = numtriangles;//indices = 3*numtriangles
222                        memPtr->m_numVertices = numverts;
223                        memPtr->m_indices16 = 0;
224                        memPtr->m_indices32 = 0;
225                        memPtr->m_3indices16 = 0;
226                        memPtr->m_vertices3f = 0;
227                        memPtr->m_vertices3d = 0;
228
229                        switch (gfxindextype)
230                        {
231                        case PHY_INTEGER:
232                                {
233                                        int numindices = numtriangles*3;
234                               
235                                        if (numindices)
236                                        {
237                                                btChunk* chunk = serializer->allocate(sizeof(btIntIndexData),numindices);
238                                                btIntIndexData* tmpIndices = (btIntIndexData*)chunk->m_oldPtr;
239                                                memPtr->m_indices32 = (btIntIndexData*)serializer->getUniquePointer(tmpIndices);
240                                                for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
241                                                {
242                                                        unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
243                                                        tmpIndices[gfxindex*3].m_value = tri_indices[0];
244                                                        tmpIndices[gfxindex*3+1].m_value = tri_indices[1];
245                                                        tmpIndices[gfxindex*3+2].m_value = tri_indices[2];
246                                                }
247                                                serializer->finalizeChunk(chunk,"btIntIndexData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
248                                        }
249                                        break;
250                                }
251                        case PHY_SHORT:
252                                {
253                                        if (numtriangles)
254                                        {
255                                                btChunk* chunk = serializer->allocate(sizeof(btShortIntIndexTripletData),numtriangles);
256                                                btShortIntIndexTripletData* tmpIndices = (btShortIntIndexTripletData*)chunk->m_oldPtr;
257                                                memPtr->m_3indices16 = (btShortIntIndexTripletData*) serializer->getUniquePointer(tmpIndices);
258                                                for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
259                                                {
260                                                        unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
261                                                        tmpIndices[gfxindex].m_values[0] = tri_indices[0];
262                                                        tmpIndices[gfxindex].m_values[1] = tri_indices[1];
263                                                        tmpIndices[gfxindex].m_values[2] = tri_indices[2];
264                                                }
265                                                serializer->finalizeChunk(chunk,"btShortIntIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
266                                        }
267                                        break;
268                                }
269                        default:
270                                {
271                                        btAssert(0);
272                                        //unknown index type
273                                }
274                        }
275
276                        switch (type)
277                        {
278                        case PHY_FLOAT:
279                         {
280                                 float* graphicsbase;
281
282                                 if (numverts)
283                                 {
284                                         btChunk* chunk = serializer->allocate(sizeof(btVector3FloatData),numverts);
285                                         btVector3FloatData* tmpVertices = (btVector3FloatData*) chunk->m_oldPtr;
286                                         memPtr->m_vertices3f = (btVector3FloatData *)serializer->getUniquePointer(tmpVertices);
287                                         for (int i=0;i<numverts;i++)
288                                         {
289                                                 graphicsbase = (float*)(vertexbase+i*stride);
290                                                 tmpVertices[i].m_floats[0] = graphicsbase[0];
291                                                 tmpVertices[i].m_floats[1] = graphicsbase[1];
292                                                 tmpVertices[i].m_floats[2] = graphicsbase[2];
293                                         }
294                                         serializer->finalizeChunk(chunk,"btVector3FloatData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
295                                 }
296                                 break;
297                                }
298
299                        case PHY_DOUBLE:
300                                {
301                                        if (numverts)
302                                        {
303                                                btChunk* chunk = serializer->allocate(sizeof(btVector3DoubleData),numverts);
304                                                btVector3DoubleData* tmpVertices = (btVector3DoubleData*) chunk->m_oldPtr;
305                                                memPtr->m_vertices3d = (btVector3DoubleData *) serializer->getUniquePointer(tmpVertices);
306                                                for (int i=0;i<numverts;i++)
307                                         {
308                                                 double* graphicsbase = (double*)(vertexbase+i*stride);//for now convert to float, might leave it at double
309                                                 tmpVertices[i].m_floats[0] = graphicsbase[0];
310                                                 tmpVertices[i].m_floats[1] = graphicsbase[1];
311                                                 tmpVertices[i].m_floats[2] = graphicsbase[2];
312                                         }
313                                                serializer->finalizeChunk(chunk,"btVector3DoubleData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
314                                        }
315                                        break;
316                                }
317
318                        default:
319                                btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
320                        }
321
322                        unLockReadOnlyVertexBase(part);
323                }
324
325                serializer->finalizeChunk(chunk,"btMeshPartData",BT_ARRAY_CODE,chunk->m_oldPtr);
326        }
327
328
329        m_scaling.serializeFloat(trimeshData->m_scaling);
330        return "btStridingMeshInterfaceData";
331}
Note: See TracBrowser for help on using the repository browser.