Blender V2.61 - r43446

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 }