Bullet Collision Detection & Physics Library
btMultiSphereShape.cpp
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
4 
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10 
11 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15 
16 
17 
18 #include "btMultiSphereShape.h"
22 
23 btMultiSphereShape::btMultiSphereShape (const btVector3* positions,const btScalar* radi,int numSpheres)
25 {
27  //btScalar startMargin = btScalar(BT_LARGE_FLOAT);
28 
29  m_localPositionArray.resize(numSpheres);
30  m_radiArray.resize(numSpheres);
31  for (int i=0;i<numSpheres;i++)
32  {
33  m_localPositionArray[i] = positions[i];
34  m_radiArray[i] = radi[i];
35 
36  }
37 
39 
40 }
41 
42 #ifndef MIN
43  #define MIN( _a, _b) ((_a) < (_b) ? (_a) : (_b))
44 #endif
46 {
47  btVector3 supVec(0,0,0);
48 
50 
51 
52  btVector3 vec = vec0;
53  btScalar lenSqr = vec.length2();
54  if (lenSqr < (SIMD_EPSILON*SIMD_EPSILON))
55  {
56  vec.setValue(1,0,0);
57  } else
58  {
59  btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
60  vec *= rlen;
61  }
62 
63  btVector3 vtx;
64  btScalar newDot;
65 
66  const btVector3* pos = &m_localPositionArray[0];
67  const btScalar* rad = &m_radiArray[0];
68  int numSpheres = m_localPositionArray.size();
69 
70  for( int k = 0; k < numSpheres; k+= 128 )
71  {
72  btVector3 temp[128];
73  int inner_count = MIN( numSpheres - k, 128 );
74  for( long i = 0; i < inner_count; i++ )
75  {
76  temp[i] = (*pos) +vec*m_localScaling*(*rad) - vec * getMargin();
77  pos++;
78  rad++;
79  }
80  long i = vec.maxDot( temp, inner_count, newDot);
81  if( newDot > maxDot )
82  {
83  maxDot = newDot;
84  supVec = temp[i];
85  }
86  }
87 
88  return supVec;
89 
90 }
91 
92  void btMultiSphereShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
93 {
94 
95  for (int j=0;j<numVectors;j++)
96  {
98 
99  const btVector3& vec = vectors[j];
100 
101  btVector3 vtx;
102  btScalar newDot;
103 
104  const btVector3* pos = &m_localPositionArray[0];
105  const btScalar* rad = &m_radiArray[0];
106  int numSpheres = m_localPositionArray.size();
107 
108  for( int k = 0; k < numSpheres; k+= 128 )
109  {
110  btVector3 temp[128];
111  int inner_count = MIN( numSpheres - k, 128 );
112  for( long i = 0; i < inner_count; i++ )
113  {
114  temp[i] = (*pos) +vec*m_localScaling*(*rad) - vec * getMargin();
115  pos++;
116  rad++;
117  }
118  long i = vec.maxDot( temp, inner_count, newDot);
119  if( newDot > maxDot )
120  {
121  maxDot = newDot;
122  supportVerticesOut[j] = temp[i];
123  }
124  }
125 
126  }
127 }
128 
129 
130 
131 
132 
133 
134 
135 
137 {
138  //as an approximation, take the inertia of the box that bounds the spheres
139 
140  btVector3 localAabbMin,localAabbMax;
141  getCachedLocalAabb(localAabbMin,localAabbMax);
142  btVector3 halfExtents = (localAabbMax-localAabbMin)*btScalar(0.5);
143 
144  btScalar lx=btScalar(2.)*(halfExtents.x());
145  btScalar ly=btScalar(2.)*(halfExtents.y());
146  btScalar lz=btScalar(2.)*(halfExtents.z());
147 
148  inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz),
149  mass/(btScalar(12.0)) * (lx*lx + lz*lz),
150  mass/(btScalar(12.0)) * (lx*lx + ly*ly));
151 
152 }
153 
154 
156 const char* btMultiSphereShape::serialize(void* dataBuffer, btSerializer* serializer) const
157 {
158  btMultiSphereShapeData* shapeData = (btMultiSphereShapeData*) dataBuffer;
160 
161  int numElem = m_localPositionArray.size();
162  shapeData->m_localPositionArrayPtr = numElem ? (btPositionAndRadius*)serializer->getUniquePointer((void*)&m_localPositionArray[0]): 0;
163 
164  shapeData->m_localPositionArraySize = numElem;
165  if (numElem)
166  {
167  btChunk* chunk = serializer->allocate(sizeof(btPositionAndRadius),numElem);
169  for (int i=0;i<numElem;i++,memPtr++)
170  {
171  m_localPositionArray[i].serializeFloat(memPtr->m_pos);
172  memPtr->m_radius = float(m_radiArray[i]);
173  }
174  serializer->finalizeChunk(chunk,"btPositionAndRadius",BT_ARRAY_CODE,(void*)&m_localPositionArray[0]);
175  }
176 
177  return "btMultiSphereShapeData";
178 }
179 
180