Blender V2.61 - r43446

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