Bullet Collision Detection & Physics Library

btConvexHullShape.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 "btConvexHullShape.h"
00017 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
00018 
00019 #include "LinearMath/btQuaternion.h"
00020 #include "LinearMath/btSerializer.h"
00021 
00022 btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int stride) : btPolyhedralConvexAabbCachingShape ()
00023 {
00024         m_shapeType = CONVEX_HULL_SHAPE_PROXYTYPE;
00025         m_unscaledPoints.resize(numPoints);
00026 
00027         unsigned char* pointsAddress = (unsigned char*)points;
00028 
00029         for (int i=0;i<numPoints;i++)
00030         {
00031                 btScalar* point = (btScalar*)pointsAddress;
00032                 m_unscaledPoints[i] = btVector3(point[0], point[1], point[2]);
00033                 pointsAddress += stride;
00034         }
00035 
00036         recalcLocalAabb();
00037 
00038 }
00039 
00040 
00041 
00042 void btConvexHullShape::setLocalScaling(const btVector3& scaling)
00043 {
00044         m_localScaling = scaling;
00045         recalcLocalAabb();
00046 }
00047 
00048 void btConvexHullShape::addPoint(const btVector3& point)
00049 {
00050         m_unscaledPoints.push_back(point);
00051         recalcLocalAabb();
00052 
00053 }
00054 
00055 btVector3       btConvexHullShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
00056 {
00057         btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
00058         btScalar newDot,maxDot = btScalar(-BT_LARGE_FLOAT);
00059 
00060         for (int i=0;i<m_unscaledPoints.size();i++)
00061         {
00062                 btVector3 vtx = m_unscaledPoints[i] * m_localScaling;
00063 
00064                 newDot = vec.dot(vtx);
00065                 if (newDot > maxDot)
00066                 {
00067                         maxDot = newDot;
00068                         supVec = vtx;
00069                 }
00070         }
00071         return supVec;
00072 }
00073 
00074 void    btConvexHullShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
00075 {
00076         btScalar newDot;
00077         //use 'w' component of supportVerticesOut?
00078         {
00079                 for (int i=0;i<numVectors;i++)
00080                 {
00081                         supportVerticesOut[i][3] = btScalar(-BT_LARGE_FLOAT);
00082                 }
00083         }
00084         for (int i=0;i<m_unscaledPoints.size();i++)
00085         {
00086                 btVector3 vtx = getScaledPoint(i);
00087 
00088                 for (int j=0;j<numVectors;j++)
00089                 {
00090                         const btVector3& vec = vectors[j];
00091                         
00092                         newDot = vec.dot(vtx);
00093                         if (newDot > supportVerticesOut[j][3])
00094                         {
00095                                 //WARNING: don't swap next lines, the w component would get overwritten!
00096                                 supportVerticesOut[j] = vtx;
00097                                 supportVerticesOut[j][3] = newDot;
00098                         }
00099                 }
00100         }
00101 
00102 
00103 
00104 }
00105         
00106 
00107 
00108 btVector3       btConvexHullShape::localGetSupportingVertex(const btVector3& vec)const
00109 {
00110         btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
00111 
00112         if ( getMargin()!=btScalar(0.) )
00113         {
00114                 btVector3 vecnorm = vec;
00115                 if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
00116                 {
00117                         vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
00118                 } 
00119                 vecnorm.normalize();
00120                 supVertex+= getMargin() * vecnorm;
00121         }
00122         return supVertex;
00123 }
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00132 
00133 //currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection
00134 //Please note that you can debug-draw btConvexHullShape with the Raytracer Demo
00135 int     btConvexHullShape::getNumVertices() const
00136 {
00137         return m_unscaledPoints.size();
00138 }
00139 
00140 int btConvexHullShape::getNumEdges() const
00141 {
00142         return m_unscaledPoints.size();
00143 }
00144 
00145 void btConvexHullShape::getEdge(int i,btVector3& pa,btVector3& pb) const
00146 {
00147 
00148         int index0 = i%m_unscaledPoints.size();
00149         int index1 = (i+1)%m_unscaledPoints.size();
00150         pa = getScaledPoint(index0);
00151         pb = getScaledPoint(index1);
00152 }
00153 
00154 void btConvexHullShape::getVertex(int i,btVector3& vtx) const
00155 {
00156         vtx = getScaledPoint(i);
00157 }
00158 
00159 int     btConvexHullShape::getNumPlanes() const
00160 {
00161         return 0;
00162 }
00163 
00164 void btConvexHullShape::getPlane(btVector3& ,btVector3& ,int ) const
00165 {
00166 
00167         btAssert(0);
00168 }
00169 
00170 //not yet
00171 bool btConvexHullShape::isInside(const btVector3& ,btScalar ) const
00172 {
00173         btAssert(0);
00174         return false;
00175 }
00176 
00178 const char*     btConvexHullShape::serialize(void* dataBuffer, btSerializer* serializer) const
00179 {
00180         //int szc = sizeof(btConvexHullShapeData);
00181         btConvexHullShapeData* shapeData = (btConvexHullShapeData*) dataBuffer;
00182         btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData, serializer);
00183 
00184         int numElem = m_unscaledPoints.size();
00185         shapeData->m_numUnscaledPoints = numElem;
00186 #ifdef BT_USE_DOUBLE_PRECISION
00187         shapeData->m_unscaledPointsFloatPtr = 0;
00188         shapeData->m_unscaledPointsDoublePtr = numElem ? (btVector3Data*)serializer->getUniquePointer((void*)&m_unscaledPoints[0]):  0;
00189 #else
00190         shapeData->m_unscaledPointsFloatPtr = numElem ? (btVector3Data*)serializer->getUniquePointer((void*)&m_unscaledPoints[0]):  0;
00191         shapeData->m_unscaledPointsDoublePtr = 0;
00192 #endif
00193         
00194         if (numElem)
00195         {
00196                 int sz = sizeof(btVector3Data);
00197         //      int sz2 = sizeof(btVector3DoubleData);
00198         //      int sz3 = sizeof(btVector3FloatData);
00199                 btChunk* chunk = serializer->allocate(sz,numElem);
00200                 btVector3Data* memPtr = (btVector3Data*)chunk->m_oldPtr;
00201                 for (int i=0;i<numElem;i++,memPtr++)
00202                 {
00203                         m_unscaledPoints[i].serialize(*memPtr);
00204                 }
00205                 serializer->finalizeChunk(chunk,btVector3DataName,BT_ARRAY_CODE,(void*)&m_unscaledPoints[0]);
00206         }
00207         
00208         return "btConvexHullShapeData";
00209 }
00210 
00211 void btConvexHullShape::project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max) const
00212 {
00213 #if 1
00214         min = FLT_MAX;
00215         max = -FLT_MAX;
00216         btVector3 witnesPtMin;
00217         btVector3 witnesPtMax;
00218 
00219         int numVerts = m_unscaledPoints.size();
00220         for(int i=0;i<numVerts;i++)
00221         {
00222                 btVector3 vtx = m_unscaledPoints[i] * m_localScaling;
00223                 btVector3 pt = trans * vtx;
00224                 btScalar dp = pt.dot(dir);
00225                 if(dp < min)    
00226                 {
00227                         min = dp;
00228                         witnesPtMin = pt;
00229                 }
00230                 if(dp > max)    
00231                 {
00232                         max = dp;
00233                         witnesPtMax=pt;
00234                 }
00235         }
00236 #else
00237         btVector3 localAxis = dir*trans.getBasis();
00238         btVector3 vtx1 = trans(localGetSupportingVertex(localAxis));
00239         btVector3 vtx2 = trans(localGetSupportingVertex(-localAxis));
00240 
00241         min = vtx1.dot(dir);
00242         max = vtx2.dot(dir);
00243 #endif
00244 
00245         if(min>max)
00246         {
00247                 btScalar tmp = min;
00248                 min = max;
00249                 max = tmp;
00250         }
00251 
00252 
00253 }
00254 
00255