Blender  V2.59
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_vertices3f = 0;
00257                         memPtr->m_vertices3d = 0;
00258 
00259                         switch (gfxindextype)
00260                         {
00261                         case PHY_INTEGER:
00262                                 {
00263                                         int numindices = numtriangles*3;
00264                                 
00265                                         if (numindices)
00266                                         {
00267                                                 btChunk* chunk = serializer->allocate(sizeof(btIntIndexData),numindices);
00268                                                 btIntIndexData* tmpIndices = (btIntIndexData*)chunk->m_oldPtr;
00269                                                 memPtr->m_indices32 = (btIntIndexData*)serializer->getUniquePointer(tmpIndices);
00270                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
00271                                                 {
00272                                                         unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
00273                                                         tmpIndices[gfxindex*3].m_value = tri_indices[0];
00274                                                         tmpIndices[gfxindex*3+1].m_value = tri_indices[1];
00275                                                         tmpIndices[gfxindex*3+2].m_value = tri_indices[2];
00276                                                 }
00277                                                 serializer->finalizeChunk(chunk,"btIntIndexData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
00278                                         }
00279                                         break;
00280                                 }
00281                         case PHY_SHORT:
00282                                 {
00283                                         if (numtriangles)
00284                                         {
00285                                                 btChunk* chunk = serializer->allocate(sizeof(btShortIntIndexTripletData),numtriangles);
00286                                                 btShortIntIndexTripletData* tmpIndices = (btShortIntIndexTripletData*)chunk->m_oldPtr;
00287                                                 memPtr->m_3indices16 = (btShortIntIndexTripletData*) serializer->getUniquePointer(tmpIndices);
00288                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
00289                                                 {
00290                                                         unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
00291                                                         tmpIndices[gfxindex].m_values[0] = tri_indices[0];
00292                                                         tmpIndices[gfxindex].m_values[1] = tri_indices[1];
00293                                                         tmpIndices[gfxindex].m_values[2] = tri_indices[2];
00294                                                 }
00295                                                 serializer->finalizeChunk(chunk,"btShortIntIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
00296                                         }
00297                                         break;
00298                                 }
00299                                 case PHY_UCHAR:
00300                                 {
00301                                         if (numtriangles)
00302                                         {
00303                                                 btChunk* chunk = serializer->allocate(sizeof(btCharIndexTripletData),numtriangles);
00304                                                 btCharIndexTripletData* tmpIndices = (btCharIndexTripletData*)chunk->m_oldPtr;
00305                                                 memPtr->m_3indices8 = (btCharIndexTripletData*) serializer->getUniquePointer(tmpIndices);
00306                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
00307                                                 {
00308                                                         unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride);
00309                                                         tmpIndices[gfxindex].m_values[0] = tri_indices[0];
00310                                                         tmpIndices[gfxindex].m_values[1] = tri_indices[1];
00311                                                         tmpIndices[gfxindex].m_values[2] = tri_indices[2];
00312                                                 }
00313                                                 serializer->finalizeChunk(chunk,"btCharIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
00314                                         }
00315                                         break;
00316                                 }
00317                         default:
00318                                 {
00319                                         btAssert(0);
00320                                         //unknown index type
00321                                 }
00322                         }
00323 
00324                         switch (type)
00325                         {
00326                         case PHY_FLOAT:
00327                          {
00328                                  float* graphicsbase;
00329 
00330                                  if (numverts)
00331                                  {
00332                                          btChunk* chunk = serializer->allocate(sizeof(btVector3FloatData),numverts);
00333                                          btVector3FloatData* tmpVertices = (btVector3FloatData*) chunk->m_oldPtr;
00334                                          memPtr->m_vertices3f = (btVector3FloatData *)serializer->getUniquePointer(tmpVertices);
00335                                          for (int i=0;i<numverts;i++)
00336                                          {
00337                                                  graphicsbase = (float*)(vertexbase+i*stride);
00338                                                  tmpVertices[i].m_floats[0] = graphicsbase[0];
00339                                                  tmpVertices[i].m_floats[1] = graphicsbase[1];
00340                                                  tmpVertices[i].m_floats[2] = graphicsbase[2];
00341                                          }
00342                                          serializer->finalizeChunk(chunk,"btVector3FloatData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
00343                                  }
00344                                  break;
00345                                 }
00346 
00347                         case PHY_DOUBLE:
00348                                 {
00349                                         if (numverts)
00350                                         {
00351                                                 btChunk* chunk = serializer->allocate(sizeof(btVector3DoubleData),numverts);
00352                                                 btVector3DoubleData* tmpVertices = (btVector3DoubleData*) chunk->m_oldPtr;
00353                                                 memPtr->m_vertices3d = (btVector3DoubleData *) serializer->getUniquePointer(tmpVertices);
00354                                                 for (int i=0;i<numverts;i++)
00355                                          {
00356                                                  double* graphicsbase = (double*)(vertexbase+i*stride);//for now convert to float, might leave it at double
00357                                                  tmpVertices[i].m_floats[0] = graphicsbase[0];
00358                                                  tmpVertices[i].m_floats[1] = graphicsbase[1];
00359                                                  tmpVertices[i].m_floats[2] = graphicsbase[2];
00360                                          }
00361                                                 serializer->finalizeChunk(chunk,"btVector3DoubleData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
00362                                         }
00363                                         break;
00364                                 }
00365 
00366                         default:
00367                                 btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
00368                         }
00369 
00370                         unLockReadOnlyVertexBase(part);
00371                 }
00372 
00373                 serializer->finalizeChunk(chunk,"btMeshPartData",BT_ARRAY_CODE,chunk->m_oldPtr);
00374         }
00375 
00376 
00377         m_scaling.serializeFloat(trimeshData->m_scaling);
00378         return "btStridingMeshInterfaceData";
00379 }