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                          default:
00092                                  btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
00093                          }
00094                          break;
00095                  }
00096 
00097                 case PHY_DOUBLE:
00098                         {
00099                                 double* graphicsbase;
00100 
00101                                 switch (gfxindextype)
00102                                 {
00103                                 case PHY_INTEGER:
00104                                         {
00105                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
00106                                                 {
00107                                                         unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
00108                                                         graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
00109                                                         triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
00110                                                         graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
00111                                                         triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
00112                                                         graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
00113                                                         triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
00114                                                         callback->internalProcessTriangleIndex(triangle,part,gfxindex);
00115                                                 }
00116                                                 break;
00117                                         }
00118                                 case PHY_SHORT:
00119                                         {
00120                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
00121                                                 {
00122                                                         unsigned short int* tri_indices= (unsigned short 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                                 default:
00134                                         btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
00135                                 }
00136                                 break;
00137                         }
00138                 default:
00139                         btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
00140                 }
00141 
00142                 unLockReadOnlyVertexBase(part);
00143         }
00144 }
00145 
00146 void    btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax)
00147 {
00148 
00149         struct  AabbCalculationCallback : public btInternalTriangleIndexCallback
00150         {
00151                 btVector3       m_aabbMin;
00152                 btVector3       m_aabbMax;
00153 
00154                 AabbCalculationCallback()
00155                 {
00156                         m_aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
00157                         m_aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
00158                 }
00159 
00160                 virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
00161                 {
00162                         (void)partId;
00163                         (void)triangleIndex;
00164 
00165                         m_aabbMin.setMin(triangle[0]);
00166                         m_aabbMax.setMax(triangle[0]);
00167                         m_aabbMin.setMin(triangle[1]);
00168                         m_aabbMax.setMax(triangle[1]);
00169                         m_aabbMin.setMin(triangle[2]);
00170                         m_aabbMax.setMax(triangle[2]);
00171                 }
00172         };
00173 
00174         //first calculate the total aabb for all triangles
00175         AabbCalculationCallback aabbCallback;
00176         aabbMin.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
00177         aabbMax.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
00178         InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax);
00179 
00180         aabbMin = aabbCallback.m_aabbMin;
00181         aabbMax = aabbCallback.m_aabbMax;
00182 }
00183 
00184 
00185 
00187 const char*     btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* serializer) const
00188 {
00189         btStridingMeshInterfaceData* trimeshData = (btStridingMeshInterfaceData*) dataBuffer;
00190 
00191         trimeshData->m_numMeshParts = getNumSubParts();
00192 
00193         //void* uniquePtr = 0;
00194 
00195         trimeshData->m_meshPartsPtr = 0;
00196 
00197         if (trimeshData->m_numMeshParts)
00198         {
00199                 btChunk* chunk = serializer->allocate(sizeof(btMeshPartData),trimeshData->m_numMeshParts);
00200                 btMeshPartData* memPtr = (btMeshPartData*)chunk->m_oldPtr;
00201                 trimeshData->m_meshPartsPtr = memPtr;
00202 
00203 
00204         //      int numtotalphysicsverts = 0;
00205                 int part,graphicssubparts = getNumSubParts();
00206                 const unsigned char * vertexbase;
00207                 const unsigned char * indexbase;
00208                 int indexstride;
00209                 PHY_ScalarType type;
00210                 PHY_ScalarType gfxindextype;
00211                 int stride,numverts,numtriangles;
00212                 int gfxindex;
00213         //      btVector3 triangle[3];
00214 
00215                 btVector3 meshScaling = getScaling();
00216 
00218                 for (part=0;part<graphicssubparts ;part++,memPtr++)
00219                 {
00220                         getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part);
00221                         memPtr->m_numTriangles = numtriangles;//indices = 3*numtriangles
00222                         memPtr->m_numVertices = numverts;
00223                         memPtr->m_indices32 = 0;
00224                         memPtr->m_indices16 = 0;
00225                         memPtr->m_vertices3f = 0;
00226                         memPtr->m_vertices3d = 0;
00227 
00228                         switch (gfxindextype)
00229                         {
00230                         case PHY_INTEGER:
00231                                 {
00232                                         int numindices = numtriangles*3;
00233                                 
00234                                         if (numindices)
00235                                         {
00236                                                 btChunk* chunk = serializer->allocate(sizeof(btIntIndexData),numindices);
00237                                                 btIntIndexData* tmpIndices = (btIntIndexData*)chunk->m_oldPtr;
00238                                                 memPtr->m_indices32 = tmpIndices;
00239                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
00240                                                 {
00241                                                         unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
00242                                                         tmpIndices[gfxindex*3].m_value = tri_indices[0];
00243                                                         tmpIndices[gfxindex*3+1].m_value = tri_indices[1];
00244                                                         tmpIndices[gfxindex*3+2].m_value = tri_indices[2];
00245                                                 }
00246                                                 serializer->finalizeChunk(chunk,"btIntIndexData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
00247                                         }
00248                                         break;
00249                                 }
00250                         case PHY_SHORT:
00251                                 {
00252                                         int numindices = numtriangles*3;
00253                                         if (numindices)
00254                                         {
00255                                                 btChunk* chunk = serializer->allocate(sizeof(btIntIndexData),numindices);
00256                                                 btShortIntIndexData* tmpIndices = (btShortIntIndexData*)chunk->m_oldPtr;
00257                                                 memPtr->m_indices16 = tmpIndices;
00258                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
00259                                                 {
00260                                                         unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
00261                                                         tmpIndices[gfxindex*3].m_value = tri_indices[0];
00262                                                         tmpIndices[gfxindex*3+1].m_value = tri_indices[1];
00263                                                         tmpIndices[gfxindex*3+2].m_value = tri_indices[2];
00264                                                 }
00265                                                 serializer->finalizeChunk(chunk,"btShortIntIndexData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
00266                                         }
00267                                         break;
00268 
00269                                 }
00270                         default:
00271                                 {
00272                                         btAssert(0);
00273                                         //unknown index type
00274                                 }
00275                         }
00276 
00277                         switch (type)
00278                         {
00279                         case PHY_FLOAT:
00280                          {
00281                                  float* graphicsbase;
00282 
00283                                  if (numverts)
00284                                  {
00285                                          btChunk* chunk = serializer->allocate(sizeof(btVector3FloatData),numverts);
00286                                          btVector3FloatData* tmpVertices = (btVector3FloatData*) chunk->m_oldPtr;
00287                                          memPtr->m_vertices3f = tmpVertices;
00288                                          for (int i=0;i<numverts;i++)
00289                                          {
00290                                                  graphicsbase = (float*)(vertexbase+i*stride);
00291                                                  tmpVertices[i].m_floats[0] = graphicsbase[0];
00292                                                  tmpVertices[i].m_floats[1] = graphicsbase[1];
00293                                                  tmpVertices[i].m_floats[2] = graphicsbase[2];
00294                                          }
00295                                          serializer->finalizeChunk(chunk,"btVector3FloatData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
00296                                  }
00297                                  break;
00298                                 }
00299 
00300                         case PHY_DOUBLE:
00301                                 {
00302                                         if (numverts)
00303                                         {
00304                                                 btChunk* chunk = serializer->allocate(sizeof(btVector3DoubleData),numverts);
00305                                                 btVector3DoubleData* tmpVertices = (btVector3DoubleData*) chunk->m_oldPtr;
00306                                                 memPtr->m_vertices3d = tmpVertices;
00307                                                 for (int i=0;i<numverts;i++)
00308                                          {
00309                                                  double* graphicsbase = (double*)(vertexbase+i*stride);//for now convert to float, might leave it at double
00310                                                  tmpVertices[i].m_floats[0] = graphicsbase[0];
00311                                                  tmpVertices[i].m_floats[1] = graphicsbase[1];
00312                                                  tmpVertices[i].m_floats[2] = graphicsbase[2];
00313                                          }
00314                                                 serializer->finalizeChunk(chunk,"btVector3DoubleData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
00315                                         }
00316                                         break;
00317                                 }
00318 
00319                         default:
00320                                 btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
00321                         }
00322 
00323                         unLockReadOnlyVertexBase(part);
00324                 }
00325 
00326                 serializer->finalizeChunk(chunk,"btMeshPartData",BT_ARRAY_CODE,chunk->m_oldPtr);
00327         }
00328 
00329 
00330         m_scaling.serializeFloat(trimeshData->m_scaling);
00331         return "btStridingMeshInterfaceData";
00332 }

Generated on Mon Feb 15 22:17:07 2010 for Bullet Collision Detection & Physics Library by  doxygen 1.6.1