Blender V2.61 - r43446
|
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