btMultiSphereShape.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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
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*)&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