Bullet Collision Detection & Physics Library

btMultiSphereShape.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 
00017 
00018 #include "btMultiSphereShape.h"
00019 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
00020 #include "LinearMath/btQuaternion.h"
00021 #include "LinearMath/btSerializer.h"
00022 
00023 btMultiSphereShape::btMultiSphereShape (const btVector3* positions,const btScalar* radi,int numSpheres)
00024 :btConvexInternalAabbCachingShape ()
00025 {
00026         m_shapeType = MULTI_SPHERE_SHAPE_PROXYTYPE;
00027         //btScalar startMargin = btScalar(BT_LARGE_FLOAT);
00028 
00029         m_localPositionArray.resize(numSpheres);
00030         m_radiArray.resize(numSpheres);
00031         for (int i=0;i<numSpheres;i++)
00032         {
00033                 m_localPositionArray[i] = positions[i];
00034                 m_radiArray[i] = radi[i];
00035                 
00036         }
00037 
00038         recalcLocalAabb();
00039 
00040 }
00041 
00042  
00043  btVector3      btMultiSphereShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
00044 {
00045         int i;
00046         btVector3 supVec(0,0,0);
00047 
00048         btScalar maxDot(btScalar(-BT_LARGE_FLOAT));
00049 
00050 
00051         btVector3 vec = vec0;
00052         btScalar lenSqr = vec.length2();
00053         if (lenSqr < (SIMD_EPSILON*SIMD_EPSILON))
00054         {
00055                 vec.setValue(1,0,0);
00056         } else
00057         {
00058                 btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
00059                 vec *= rlen;
00060         }
00061 
00062         btVector3 vtx;
00063         btScalar newDot;
00064 
00065         const btVector3* pos = &m_localPositionArray[0];
00066         const btScalar* rad = &m_radiArray[0];
00067         int numSpheres = m_localPositionArray.size();
00068 
00069         for (i=0;i<numSpheres;i++)
00070         {
00071                 vtx = (*pos) +vec*m_localScaling*(*rad) - vec * getMargin();
00072                 pos++;
00073                 rad++;
00074                 newDot = vec.dot(vtx);
00075                 if (newDot > maxDot)
00076                 {
00077                         maxDot = newDot;
00078                         supVec = vtx;
00079                 }
00080         }
00081 
00082         return supVec;
00083 
00084 }
00085 
00086  void   btMultiSphereShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
00087 {
00088 
00089         for (int j=0;j<numVectors;j++)
00090         {
00091                 btScalar maxDot(btScalar(-BT_LARGE_FLOAT));
00092 
00093                 const btVector3& vec = vectors[j];
00094 
00095                 btVector3 vtx;
00096                 btScalar newDot;
00097 
00098                 const btVector3* pos = &m_localPositionArray[0];
00099                 const btScalar* rad = &m_radiArray[0];
00100                 int numSpheres = m_localPositionArray.size();
00101                 for (int i=0;i<numSpheres;i++)
00102                 {
00103                         vtx = (*pos) +vec*m_localScaling*(*rad) - vec * getMargin();
00104                         pos++;
00105                         rad++;
00106                         newDot = vec.dot(vtx);
00107                         if (newDot > maxDot)
00108                         {
00109                                 maxDot = newDot;
00110                                 supportVerticesOut[j] = vtx;
00111                         }
00112                 }
00113         }
00114 }
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 void    btMultiSphereShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
00124 {
00125         //as an approximation, take the inertia of the box that bounds the spheres
00126 
00127         btVector3 localAabbMin,localAabbMax;
00128         getCachedLocalAabb(localAabbMin,localAabbMax);
00129         btVector3 halfExtents = (localAabbMax-localAabbMin)*btScalar(0.5);
00130 
00131         btScalar lx=btScalar(2.)*(halfExtents.x());
00132         btScalar ly=btScalar(2.)*(halfExtents.y());
00133         btScalar lz=btScalar(2.)*(halfExtents.z());
00134 
00135         inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz),
00136                                         mass/(btScalar(12.0)) * (lx*lx + lz*lz),
00137                                         mass/(btScalar(12.0)) * (lx*lx + ly*ly));
00138 
00139 }
00140 
00141 
00143 const char*     btMultiSphereShape::serialize(void* dataBuffer, btSerializer* serializer) const
00144 {
00145         btMultiSphereShapeData* shapeData = (btMultiSphereShapeData*) dataBuffer;
00146         btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData, serializer);
00147 
00148         int numElem = m_localPositionArray.size();
00149         shapeData->m_localPositionArrayPtr = numElem ? (btPositionAndRadius*)serializer->getUniquePointer((void*)&m_localPositionArray[0]):  0;
00150         
00151         shapeData->m_localPositionArraySize = numElem;
00152         if (numElem)
00153         {
00154                 btChunk* chunk = serializer->allocate(sizeof(btPositionAndRadius),numElem);
00155                 btPositionAndRadius* memPtr = (btPositionAndRadius*)chunk->m_oldPtr;
00156                 for (int i=0;i<numElem;i++,memPtr++)
00157                 {
00158                         m_localPositionArray[i].serializeFloat(memPtr->m_pos);
00159                         memPtr->m_radius = float(m_radiArray[i]);
00160                 }
00161                 serializer->finalizeChunk(chunk,"btPositionAndRadius",BT_ARRAY_CODE,(void*)&m_localPositionArray[0]);
00162         }
00163         
00164         return "btMultiSphereShapeData";
00165 }
00166 
00167