btStridingMeshInterface.cpp

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 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.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 #include "btStridingMeshInterface.h"
00017 #include "LinearMath/btSerializer.h"
00018 
00019 btStridingMeshInterface::~btStridingMeshInterface()
00020 {
00021 
00022 }
00023 
00024 
00025 void    btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
00026 {
00027         (void)aabbMin;
00028         (void)aabbMax;
00029         int numtotalphysicsverts = 0;
00030         int part,graphicssubparts = getNumSubParts();
00031         const unsigned char * vertexbase;
00032         const unsigned char * indexbase;
00033         int indexstride;
00034         PHY_ScalarType type;
00035         PHY_ScalarType gfxindextype;
00036         int stride,numverts,numtriangles;
00037         int gfxindex;
00038         btVector3 triangle[3];
00039 
00040         btVector3 meshScaling = getScaling();
00041 
00043         for (part=0;part<graphicssubparts ;part++)
00044         {
00045                 getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part);
00046                 numtotalphysicsverts+=numtriangles*3; //upper bound
00047 
00051 
00052                 switch (type)
00053                 {
00054                 case PHY_FLOAT:
00055                  {
00056 
00057                          float* graphicsbase;
00058 
00059                          switch (gfxindextype)
00060                          {
00061                          case PHY_INTEGER:
00062                                  {
00063                                          for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
00064                                          {
00065                                                  unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
00066                                                  graphicsbase = (float*)(vertexbase+tri_indices[0]*stride);
00067                                                  triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
00068                                                  graphicsbase = (float*)(vertexbase+tri_indices[1]*stride);
00069                                                  triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),    graphicsbase[2]*meshScaling.getZ());
00070                                                  graphicsbase = (float*)(vertexbase+tri_indices[2]*stride);
00071                                                  triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),    graphicsbase[2]*meshScaling.getZ());
00072                                                  callback->internalProcessTriangleIndex(triangle,part,gfxindex);
00073                                          }
00074                                          break;
00075                                  }
00076                          case PHY_SHORT:
00077                                  {
00078                                          for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
00079                                          {
00080                                                  unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
00081                                                  graphicsbase = (float*)(vertexbase+tri_indices[0]*stride);
00082                                                  triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
00083                                                  graphicsbase = (float*)(vertexbase+tri_indices[1]*stride);
00084                                                  triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),    graphicsbase[2]*meshScaling.getZ());
00085                                                  graphicsbase = (float*)(vertexbase+tri_indices[2]*stride);
00086                                                  triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),    graphicsbase[2]*meshScaling.getZ());
00087                                                  callback->internalProcessTriangleIndex(triangle,part,gfxindex);
00088                                          }
00089                                          break;
00090                                  }
00091                         case PHY_UCHAR:
00092                                  {
00093                                          for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
00094                                          {
00095                                                  unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride);
00096                                                  graphicsbase = (float*)(vertexbase+tri_indices[0]*stride);
00097                                                  triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
00098                                                  graphicsbase = (float*)(vertexbase+tri_indices[1]*stride);
00099                                                  triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),    graphicsbase[2]*meshScaling.getZ());
00100                                                  graphicsbase = (float*)(vertexbase+tri_indices[2]*stride);
00101                                                  triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),    graphicsbase[2]*meshScaling.getZ());
00102                                                  callback->internalProcessTriangleIndex(triangle,part,gfxindex);
00103                                          }
00104                                          break;
00105                                  }
00106                          default:
00107                                  btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
00108                          }
00109                          break;
00110                  }
00111 
00112                 case PHY_DOUBLE:
00113                         {
00114                                 double* graphicsbase;
00115 
00116                                 switch (gfxindextype)
00117                                 {
00118                                 case PHY_INTEGER:
00119                                         {
00120                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
00121                                                 {
00122                                                         unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
00123                                                         graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
00124                                                         triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
00125                                                         graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
00126                                                         triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
00127                                                         graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
00128                                                         triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
00129                                                         callback->internalProcessTriangleIndex(triangle,part,gfxindex);
00130                                                 }
00131                                                 break;
00132                                         }
00133                                 case PHY_SHORT:
00134                                         {
00135                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
00136                                                 {
00137                                                         unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
00138                                                         graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
00139                                                         triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
00140                                                         graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
00141                                                         triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
00142                                                         graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
00143                                                         triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
00144                                                         callback->internalProcessTriangleIndex(triangle,part,gfxindex);
00145                                                 }
00146                                                 break;
00147                                         }
00148                                 case PHY_UCHAR:
00149                                         {
00150                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
00151                                                 {
00152                                                         unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride);
00153                                                         graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
00154                                                         triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
00155                                                         graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
00156                                                         triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
00157                                                         graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
00158                                                         triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
00159                                                         callback->internalProcessTriangleIndex(triangle,part,gfxindex);
00160                                                 }
00161                                                 break;
00162                                         }
00163                                 default:
00164                                         btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
00165                                 }
00166                                 break;
00167                         }
00168                 default:
00169                         btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
00170                 }
00171 
00172                 unLockReadOnlyVertexBase(part);
00173         }
00174 }
00175 
00176 void    btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax)
00177 {
00178 
00179         struct  AabbCalculationCallback : public btInternalTriangleIndexCallback
00180         {
00181                 btVector3       m_aabbMin;
00182                 btVector3       m_aabbMax;
00183 
00184                 AabbCalculationCallback()
00185                 {
00186                         m_aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
00187                         m_aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
00188                 }
00189 
00190                 virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
00191                 {
00192                         (void)partId;
00193                         (void)triangleIndex;
00194 
00195                         m_aabbMin.setMin(triangle[0]);
00196                         m_aabbMax.setMax(triangle[0]);
00197                         m_aabbMin.setMin(triangle[1]);
00198                         m_aabbMax.setMax(triangle[1]);
00199                         m_aabbMin.setMin(triangle[2]);
00200                         m_aabbMax.setMax(triangle[2]);
00201                 }
00202         };
00203 
00204         //first calculate the total aabb for all triangles
00205         AabbCalculationCallback aabbCallback;
00206         aabbMin.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
00207         aabbMax.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
00208         InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax);
00209 
00210         aabbMin = aabbCallback.m_aabbMin;
00211         aabbMax = aabbCallback.m_aabbMax;
00212 }
00213 
00214 
00215 
00217 const char*     btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* serializer) const
00218 {
00219         btStridingMeshInterfaceData* trimeshData = (btStridingMeshInterfaceData*) dataBuffer;
00220 
00221         trimeshData->m_numMeshParts = getNumSubParts();
00222 
00223         //void* uniquePtr = 0;
00224 
00225         trimeshData->m_meshPartsPtr = 0;
00226 
00227         if (trimeshData->m_numMeshParts)
00228         {
00229                 btChunk* chunk = serializer->allocate(sizeof(btMeshPartData),trimeshData->m_numMeshParts);
00230                 btMeshPartData* memPtr = (btMeshPartData*)chunk->m_oldPtr;
00231                 trimeshData->m_meshPartsPtr = (btMeshPartData *)serializer->getUniquePointer(memPtr);
00232 
00233 
00234         //      int numtotalphysicsverts = 0;
00235                 int part,graphicssubparts = getNumSubParts();
00236                 const unsigned char * vertexbase;
00237                 const unsigned char * indexbase;
00238                 int indexstride;
00239                 PHY_ScalarType type;
00240                 PHY_ScalarType gfxindextype;
00241                 int stride,numverts,numtriangles;
00242                 int gfxindex;
00243         //      btVector3 triangle[3];
00244 
00245         //      btVector3 meshScaling = getScaling();
00246 
00248                 for (part=0;part<graphicssubparts ;part++,memPtr++)
00249                 {
00250                         getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part);
00251                         memPtr->m_numTriangles = numtriangles;//indices = 3*numtriangles
00252                         memPtr->m_numVertices = numverts;
00253                         memPtr->m_indices16 = 0;
00254                         memPtr->m_indices32 = 0;
00255                         memPtr->m_3indices16 = 0;
00256                         memPtr->m_3indices8 = 0;
00257                         memPtr->m_vertices3f = 0;
00258                         memPtr->m_vertices3d = 0;
00259 
00260 
00261                         switch (gfxindextype)
00262                         {
00263                         case PHY_INTEGER:
00264                                 {
00265                                         int numindices = numtriangles*3;
00266                                 
00267                                         if (numindices)
00268                                         {
00269                                                 btChunk* chunk = serializer->allocate(sizeof(btIntIndexData),numindices);
00270                                                 btIntIndexData* tmpIndices = (btIntIndexData*)chunk->m_oldPtr;
00271                                                 memPtr->m_indices32 = (btIntIndexData*)serializer->getUniquePointer(tmpIndices);
00272                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
00273                                                 {
00274                                                         unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
00275                                                         tmpIndices[gfxindex*3].m_value = tri_indices[0];
00276                                                         tmpIndices[gfxindex*3+1].m_value = tri_indices[1];
00277                                                         tmpIndices[gfxindex*3+2].m_value = tri_indices[2];
00278                                                 }
00279                                                 serializer->finalizeChunk(chunk,"btIntIndexData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
00280                                         }
00281                                         break;
00282                                 }
00283                         case PHY_SHORT:
00284                                 {
00285                                         if (numtriangles)
00286                                         {
00287                                                 btChunk* chunk = serializer->allocate(sizeof(btShortIntIndexTripletData),numtriangles);
00288                                                 btShortIntIndexTripletData* tmpIndices = (btShortIntIndexTripletData*)chunk->m_oldPtr;
00289                                                 memPtr->m_3indices16 = (btShortIntIndexTripletData*) serializer->getUniquePointer(tmpIndices);
00290                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
00291                                                 {
00292                                                         unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
00293                                                         tmpIndices[gfxindex].m_values[0] = tri_indices[0];
00294                                                         tmpIndices[gfxindex].m_values[1] = tri_indices[1];
00295                                                         tmpIndices[gfxindex].m_values[2] = tri_indices[2];
00296                                                 }
00297                                                 serializer->finalizeChunk(chunk,"btShortIntIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
00298                                         }
00299                                         break;
00300                                 }
00301                                 case PHY_UCHAR:
00302                                 {
00303                                         if (numtriangles)
00304                                         {
00305                                                 btChunk* chunk = serializer->allocate(sizeof(btCharIndexTripletData),numtriangles);
00306                                                 btCharIndexTripletData* tmpIndices = (btCharIndexTripletData*)chunk->m_oldPtr;
00307                                                 memPtr->m_3indices8 = (btCharIndexTripletData*) serializer->getUniquePointer(tmpIndices);
00308                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
00309                                                 {
00310                                                         unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride);
00311                                                         tmpIndices[gfxindex].m_values[0] = tri_indices[0];
00312                                                         tmpIndices[gfxindex].m_values[1] = tri_indices[1];
00313                                                         tmpIndices[gfxindex].m_values[2] = tri_indices[2];
00314                                                 }
00315                                                 serializer->finalizeChunk(chunk,"btCharIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
00316                                         }
00317                                         break;
00318                                 }
00319                         default:
00320                                 {
00321                                         btAssert(0);
00322                                         //unknown index type
00323                                 }
00324                         }
00325 
00326                         switch (type)
00327                         {
00328                         case PHY_FLOAT:
00329                          {
00330                                  float* graphicsbase;
00331 
00332                                  if (numverts)
00333                                  {
00334                                          btChunk* chunk = serializer->allocate(sizeof(btVector3FloatData),numverts);
00335                                          btVector3FloatData* tmpVertices = (btVector3FloatData*) chunk->m_oldPtr;
00336                                          memPtr->m_vertices3f = (btVector3FloatData *)serializer->getUniquePointer(tmpVertices);
00337                                          for (int i=0;i<numverts;i++)
00338                                          {
00339                                                  graphicsbase = (float*)(vertexbase+i*stride);
00340                                                  tmpVertices[i].m_floats[0] = graphicsbase[0];
00341                                                  tmpVertices[i].m_floats[1] = graphicsbase[1];
00342                                                  tmpVertices[i].m_floats[2] = graphicsbase[2];
00343                                          }
00344                                          serializer->finalizeChunk(chunk,"btVector3FloatData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
00345                                  }
00346                                  break;
00347                                 }
00348 
00349                         case PHY_DOUBLE:
00350                                 {
00351                                         if (numverts)
00352                                         {
00353                                                 btChunk* chunk = serializer->allocate(sizeof(btVector3DoubleData),numverts);
00354                                                 btVector3DoubleData* tmpVertices = (btVector3DoubleData*) chunk->m_oldPtr;
00355                                                 memPtr->m_vertices3d = (btVector3DoubleData *) serializer->getUniquePointer(tmpVertices);
00356                                                 for (int i=0;i<numverts;i++)
00357                                          {
00358                                                  double* graphicsbase = (double*)(vertexbase+i*stride);//for now convert to float, might leave it at double
00359                                                  tmpVertices[i].m_floats[0] = graphicsbase[0];
00360                                                  tmpVertices[i].m_floats[1] = graphicsbase[1];
00361                                                  tmpVertices[i].m_floats[2] = graphicsbase[2];
00362                                          }
00363                                                 serializer->finalizeChunk(chunk,"btVector3DoubleData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
00364                                         }
00365                                         break;
00366                                 }
00367 
00368                         default:
00369                                 btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
00370                         }
00371 
00372                         unLockReadOnlyVertexBase(part);
00373                 }
00374 
00375                 serializer->finalizeChunk(chunk,"btMeshPartData",BT_ARRAY_CODE,chunk->m_oldPtr);
00376         }
00377 
00378 
00379         m_scaling.serializeFloat(trimeshData->m_scaling);
00380         return "btStridingMeshInterfaceData";
00381 }