Bullet Collision Detection & Physics Library
btCompoundShape.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 #include "btCompoundShape.h"
17 #include "btCollisionShape.h"
20 
21 btCompoundShape::btCompoundShape(bool enableDynamicAabbTree, const int initialChildCapacity)
24 m_dynamicAabbTree(0),
25 m_updateRevision(1),
26 m_collisionMargin(btScalar(0.)),
27 m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.))
28 {
30 
31  if (enableDynamicAabbTree)
32  {
33  void* mem = btAlignedAlloc(sizeof(btDbvt),16);
34  m_dynamicAabbTree = new(mem) btDbvt();
36  }
37 
38  m_children.reserve(initialChildCapacity);
39 }
40 
41 
43 {
45  {
48  }
49 }
50 
52 {
54  //m_childTransforms.push_back(localTransform);
55  //m_childShapes.push_back(shape);
57  child.m_node = 0;
58  child.m_transform = localTransform;
59  child.m_childShape = shape;
60  child.m_childShapeType = shape->getShapeType();
61  child.m_childMargin = shape->getMargin();
62 
63 
64  //extend the local aabbMin/aabbMax
65  btVector3 localAabbMin,localAabbMax;
66  shape->getAabb(localTransform,localAabbMin,localAabbMax);
67  for (int i=0;i<3;i++)
68  {
69  if (m_localAabbMin[i] > localAabbMin[i])
70  {
71  m_localAabbMin[i] = localAabbMin[i];
72  }
73  if (m_localAabbMax[i] < localAabbMax[i])
74  {
75  m_localAabbMax[i] = localAabbMax[i];
76  }
77 
78  }
80  {
81  const btDbvtVolume bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
82  size_t index = m_children.size();
83  child.m_node = m_dynamicAabbTree->insert(bounds,reinterpret_cast<void*>(index) );
84  }
85 
86  m_children.push_back(child);
87 
88 }
89 
90 void btCompoundShape::updateChildTransform(int childIndex, const btTransform& newChildTransform,bool shouldRecalculateLocalAabb)
91 {
92  m_children[childIndex].m_transform = newChildTransform;
93 
95  {
97  btVector3 localAabbMin,localAabbMax;
98  m_children[childIndex].m_childShape->getAabb(newChildTransform,localAabbMin,localAabbMax);
99  ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
100  //int index = m_children.size()-1;
101  m_dynamicAabbTree->update(m_children[childIndex].m_node,bounds);
102  }
103 
104  if (shouldRecalculateLocalAabb)
105  {
107  }
108 }
109 
111 {
113  btAssert(childShapeIndex >=0 && childShapeIndex < m_children.size());
114  if (m_dynamicAabbTree)
115  {
116  m_dynamicAabbTree->remove(m_children[childShapeIndex].m_node);
117  }
118  m_children.swap(childShapeIndex,m_children.size()-1);
119  if (m_dynamicAabbTree)
120  m_children[childShapeIndex].m_node->dataAsInt = childShapeIndex;
122 
123 }
124 
125 
126 
128 {
130  // Find the children containing the shape specified, and remove those children.
131  //note: there might be multiple children using the same shape!
132  for(int i = m_children.size()-1; i >= 0 ; i--)
133  {
134  if(m_children[i].m_childShape == shape)
135  {
137  }
138  }
139 
140 
141 
143 }
144 
146 {
147  // Recalculate the local aabb
148  // Brute force, it iterates over all the shapes left.
149 
152 
153  //extend the local aabbMin/aabbMax
154  for (int j = 0; j < m_children.size(); j++)
155  {
156  btVector3 localAabbMin,localAabbMax;
157  m_children[j].m_childShape->getAabb(m_children[j].m_transform, localAabbMin, localAabbMax);
158  for (int i=0;i<3;i++)
159  {
160  if (m_localAabbMin[i] > localAabbMin[i])
161  m_localAabbMin[i] = localAabbMin[i];
162  if (m_localAabbMax[i] < localAabbMax[i])
163  m_localAabbMax[i] = localAabbMax[i];
164  }
165  }
166 }
167 
169 void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
170 {
171  btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
172  btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
173 
174  //avoid an illegal AABB when there are no children
175  if (!m_children.size())
176  {
177  localHalfExtents.setValue(0,0,0);
178  localCenter.setValue(0,0,0);
179  }
180  localHalfExtents += btVector3(getMargin(),getMargin(),getMargin());
181 
182 
183  btMatrix3x3 abs_b = trans.getBasis().absolute();
184 
185  btVector3 center = trans(localCenter);
186 
187  btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
188  aabbMin = center-extent;
189  aabbMax = center+extent;
190 
191 }
192 
194 {
195  //approximation: take the inertia from the aabb for now
196  btTransform ident;
197  ident.setIdentity();
198  btVector3 aabbMin,aabbMax;
199  getAabb(ident,aabbMin,aabbMax);
200 
201  btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5);
202 
203  btScalar lx=btScalar(2.)*(halfExtents.x());
204  btScalar ly=btScalar(2.)*(halfExtents.y());
205  btScalar lz=btScalar(2.)*(halfExtents.z());
206 
207  inertia[0] = mass/(btScalar(12.0)) * (ly*ly + lz*lz);
208  inertia[1] = mass/(btScalar(12.0)) * (lx*lx + lz*lz);
209  inertia[2] = mass/(btScalar(12.0)) * (lx*lx + ly*ly);
210 
211 }
212 
213 
214 
215 
217 {
218  int n = m_children.size();
219 
220  btScalar totalMass = 0;
221  btVector3 center(0, 0, 0);
222  int k;
223 
224  for (k = 0; k < n; k++)
225  {
226  btAssert(masses[k]>0);
227  center += m_children[k].m_transform.getOrigin() * masses[k];
228  totalMass += masses[k];
229  }
230 
231  btAssert(totalMass>0);
232 
233  center /= totalMass;
234  principal.setOrigin(center);
235 
236  btMatrix3x3 tensor(0, 0, 0, 0, 0, 0, 0, 0, 0);
237  for ( k = 0; k < n; k++)
238  {
239  btVector3 i;
240  m_children[k].m_childShape->calculateLocalInertia(masses[k], i);
241 
242  const btTransform& t = m_children[k].m_transform;
243  btVector3 o = t.getOrigin() - center;
244 
245  //compute inertia tensor in coordinate system of compound shape
246  btMatrix3x3 j = t.getBasis().transpose();
247  j[0] *= i[0];
248  j[1] *= i[1];
249  j[2] *= i[2];
250  j = t.getBasis() * j;
251 
252  //add inertia tensor
253  tensor[0] += j[0];
254  tensor[1] += j[1];
255  tensor[2] += j[2];
256 
257  //compute inertia tensor of pointmass at o
258  btScalar o2 = o.length2();
259  j[0].setValue(o2, 0, 0);
260  j[1].setValue(0, o2, 0);
261  j[2].setValue(0, 0, o2);
262  j[0] += o * -o.x();
263  j[1] += o * -o.y();
264  j[2] += o * -o.z();
265 
266  //add inertia tensor of pointmass
267  tensor[0] += masses[k] * j[0];
268  tensor[1] += masses[k] * j[1];
269  tensor[2] += masses[k] * j[2];
270  }
271 
272  tensor.diagonalize(principal.getBasis(), btScalar(0.00001), 20);
273  inertia.setValue(tensor[0][0], tensor[1][1], tensor[2][2]);
274 }
275 
276 
277 
278 
279 
281 {
282 
283  for(int i = 0; i < m_children.size(); i++)
284  {
285  btTransform childTrans = getChildTransform(i);
286  btVector3 childScale = m_children[i].m_childShape->getLocalScaling();
287 // childScale = childScale * (childTrans.getBasis() * scaling);
288  childScale = childScale * scaling / m_localScaling;
289  m_children[i].m_childShape->setLocalScaling(childScale);
290  childTrans.setOrigin((childTrans.getOrigin()) * scaling / m_localScaling);
291  updateChildTransform(i, childTrans,false);
292  }
293 
294  m_localScaling = scaling;
296 
297 }
298 
299 
301 {
302  if ( !m_dynamicAabbTree )
303  {
304  void* mem = btAlignedAlloc(sizeof(btDbvt),16);
305  m_dynamicAabbTree = new(mem) btDbvt();
307 
308  for ( int index = 0; index < m_children.size(); index++ )
309  {
310  btCompoundShapeChild &child = m_children[index];
311 
312  //extend the local aabbMin/aabbMax
313  btVector3 localAabbMin,localAabbMax;
314  child.m_childShape->getAabb(child.m_transform,localAabbMin,localAabbMax);
315 
316  const btDbvtVolume bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
317  size_t index2 = index;
318  child.m_node = m_dynamicAabbTree->insert(bounds, reinterpret_cast<void*>(index2) );
319  }
320  }
321 }
322 
323 
325 const char* btCompoundShape::serialize(void* dataBuffer, btSerializer* serializer) const
326 {
327 
328  btCompoundShapeData* shapeData = (btCompoundShapeData*) dataBuffer;
329  btCollisionShape::serialize(&shapeData->m_collisionShapeData, serializer);
330 
331  shapeData->m_collisionMargin = float(m_collisionMargin);
332  shapeData->m_numChildShapes = m_children.size();
333  shapeData->m_childShapePtr = 0;
334  if (shapeData->m_numChildShapes)
335  {
336  btChunk* chunk = serializer->allocate(sizeof(btCompoundShapeChildData),shapeData->m_numChildShapes);
338  shapeData->m_childShapePtr = (btCompoundShapeChildData*)serializer->getUniquePointer(memPtr);
339 
340  for (int i=0;i<shapeData->m_numChildShapes;i++,memPtr++)
341  {
342  memPtr->m_childMargin = float(m_children[i].m_childMargin);
343  memPtr->m_childShape = (btCollisionShapeData*)serializer->getUniquePointer(m_children[i].m_childShape);
344  //don't serialize shapes that already have been serialized
345  if (!serializer->findPointer(m_children[i].m_childShape))
346  {
347  btChunk* chunk = serializer->allocate(m_children[i].m_childShape->calculateSerializeBufferSize(),1);
348  const char* structType = m_children[i].m_childShape->serialize(chunk->m_oldPtr,serializer);
349  serializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,m_children[i].m_childShape);
350  }
351 
352  memPtr->m_childShapeType = m_children[i].m_childShapeType;
353  m_children[i].m_transform.serializeFloat(memPtr->m_transform);
354  }
355  serializer->finalizeChunk(chunk,"btCompoundShapeChildData",BT_ARRAY_CODE,chunk->m_oldPtr);
356  }
357  return "btCompoundShapeData";
358 }
359 
btCollisionShapeData
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
Definition: btCollisionShape.h:155
btCompoundShapeChildData::m_childShape
btCollisionShapeData * m_childShape
Definition: btCompoundShape.h:182
btAlignedFree
#define btAlignedFree(ptr)
Definition: btAlignedAllocator.h:48
btCollisionShape.h
btCollisionShape::getShapeType
int getShapeType() const
Definition: btCollisionShape.h:112
btCompoundShape::recalculateLocalAabb
virtual void recalculateLocalAabb()
Re-calculate the local Aabb.
Definition: btCompoundShape.cpp:145
btCompoundShape::btCompoundShape
btCompoundShape(bool enableDynamicAabbTree=true, const int initialChildCapacity=0)
Definition: btCompoundShape.cpp:21
btVector3::dot3
btVector3 dot3(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2) const
Definition: btVector3.h:731
btCompoundShape::getChildTransform
btTransform & getChildTransform(int index)
Definition: btCompoundShape.h:99
btVector3::setValue
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:652
btScalar
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
btCompoundShapeChild::m_node
struct btDbvtNode * m_node
Definition: btCompoundShape.h:38
btCompoundShape.h
btCompoundShape::getMargin
virtual btScalar getMargin() const
Definition: btCompoundShape.h:137
btCompoundShapeChildData::m_transform
btTransformFloatData m_transform
Definition: btCompoundShape.h:181
btCompoundShape::removeChildShapeByIndex
void removeChildShapeByIndex(int childShapeindex)
Definition: btCompoundShape.cpp:110
btSerializer::getUniquePointer
virtual void * getUniquePointer(void *oldPtr)=0
btCompoundShape::m_updateRevision
int m_updateRevision
increment m_updateRevision when adding/removing/replacing child shapes, so that some caches can be up...
Definition: btCompoundShape.h:64
btChunk
Definition: btSerializer.h:51
btCompoundShape::removeChildShape
virtual void removeChildShape(btCollisionShape *shape)
Remove all children shapes that contain the specified shape.
Definition: btCompoundShape.cpp:127
BT_SHAPE_CODE
#define BT_SHAPE_CODE
Definition: btSerializer.h:125
btCompoundShapeChild::m_transform
btTransform m_transform
Definition: btCompoundShape.h:34
btAlignedAlloc
#define btAlignedAlloc(size, alignment)
Definition: btAlignedAllocator.h:47
btCompoundShape::~btCompoundShape
virtual ~btCompoundShape()
Definition: btCompoundShape.cpp:42
btDbvt::~btDbvt
~btDbvt()
Definition: btDbvt.cpp:453
btCompoundShape::getAabb
virtual void getAabb(const btTransform &t, btVector3 &aabbMin, btVector3 &aabbMax) const
getAabb's default implementation is brute force, expected derived classes to implement a fast dedicat...
Definition: btCompoundShape.cpp:169
btTransform::setIdentity
void setIdentity()
Set this transformation to the identity.
Definition: btTransform.h:172
btCompoundShape::calculateLocalInertia
virtual void calculateLocalInertia(btScalar mass, btVector3 &inertia) const
Definition: btCompoundShape.cpp:193
btVector3::y
const btScalar & y() const
Return the y value.
Definition: btVector3.h:589
btCollisionShape::m_shapeType
int m_shapeType
Definition: btCollisionShape.h:30
btCompoundShape::serialize
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
Definition: btCompoundShape.cpp:325
btDbvt::update
void update(btDbvtNode *leaf, int lookahead=-1)
Definition: btDbvt.cpp:526
btCollisionShape
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
Definition: btCollisionShape.h:27
btAssert
#define btAssert(x)
Definition: btScalar.h:131
btCollisionShape::getMargin
virtual btScalar getMargin() const =0
BT_LARGE_FLOAT
#define BT_LARGE_FLOAT
Definition: btScalar.h:294
btAlignedObjectArray::swap
void swap(int index0, int index1)
Definition: btAlignedObjectArray.h:405
btDbvt
The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes ...
Definition: btDbvt.h:198
btCompoundShapeChild::m_childShapeType
int m_childShapeType
Definition: btCompoundShape.h:36
btCompoundShape::createAabbTreeFromChildren
void createAabbTreeFromChildren()
Definition: btCompoundShape.cpp:300
bounds
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition: btDbvt.cpp:284
btTransform::getBasis
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
Definition: btTransform.h:112
btCompoundShapeData::m_collisionMargin
float m_collisionMargin
Definition: btCompoundShape.h:196
btCompoundShape::m_localAabbMax
btVector3 m_localAabbMax
Definition: btCompoundShape.h:59
btAlignedObjectArray::pop_back
void pop_back()
Definition: btAlignedObjectArray.h:199
btCollisionShape::getAabb
virtual void getAabb(const btTransform &t, btVector3 &aabbMin, btVector3 &aabbMax) const =0
getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t.
btCompoundShapeData::m_childShapePtr
btCompoundShapeChildData * m_childShapePtr
Definition: btCompoundShape.h:192
btMatrix3x3
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition: btMatrix3x3.h:48
btMatrix3x3::transpose
btMatrix3x3 transpose() const
Return the transpose of the matrix.
Definition: btMatrix3x3.h:958
btMatrix3x3::diagonalize
void diagonalize(btMatrix3x3 &rot, btScalar tolerance=1.0e-9, int maxIter=100)
diagonalizes this matrix
Definition: btMatrix3x3.h:682
btSerializer.h
btTransform
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
btSerializer::finalizeChunk
virtual void finalizeChunk(btChunk *chunk, const char *structType, int chunkCode, void *oldPtr)=0
btCompoundShape::setLocalScaling
virtual void setLocalScaling(const btVector3 &scaling)
Definition: btCompoundShape.cpp:280
btCompoundShapeData::m_numChildShapes
int m_numChildShapes
Definition: btCompoundShape.h:194
btCompoundShape::m_children
btAlignedObjectArray< btCompoundShapeChild > m_children
Definition: btCompoundShape.h:57
btVector3
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
btTransform::getOrigin
btVector3 & getOrigin()
Return the origin vector translation.
Definition: btTransform.h:117
btCompoundShape::m_localScaling
btVector3 m_localScaling
Definition: btCompoundShape.h:68
btDbvtAabbMm::FromMM
static btDbvtAabbMm FromMM(const btVector3 &mi, const btVector3 &mx)
Definition: btDbvt.h:425
btChunk::m_oldPtr
void * m_oldPtr
Definition: btSerializer.h:56
btCompoundShape::m_dynamicAabbTree
btDbvt * m_dynamicAabbTree
Definition: btCompoundShape.h:61
ATTRIBUTE_ALIGNED16
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:82
btCollisionShape::serialize
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
Definition: btCollisionShape.cpp:99
btMatrix3x3::setValue
void setValue(const btScalar &xx, const btScalar &xy, const btScalar &xz, const btScalar &yx, const btScalar &yy, const btScalar &yz, const btScalar &zx, const btScalar &zy, const btScalar &zz)
Set the values of the matrix explicitly (row major)
Definition: btMatrix3x3.h:198
btCompoundShapeChild::m_childShape
btCollisionShape * m_childShape
Definition: btCompoundShape.h:35
btCompoundShapeChildData::m_childShapeType
int m_childShapeType
Definition: btCompoundShape.h:183
btSerializer
Definition: btSerializer.h:68
btVector3::x
const btScalar & x() const
Return the x value.
Definition: btVector3.h:587
btCompoundShape::updateChildTransform
void updateChildTransform(int childIndex, const btTransform &newChildTransform, bool shouldRecalculateLocalAabb=true)
set a new transform for a child, and update internal data structures (local aabb and dynamic tree)
Definition: btCompoundShape.cpp:90
BT_ARRAY_CODE
#define BT_ARRAY_CODE
Definition: btSerializer.h:126
btCompoundShape::addChildShape
void addChildShape(const btTransform &localTransform, btCollisionShape *shape)
Definition: btCompoundShape.cpp:51
btAlignedObjectArray::reserve
void reserve(int _Count)
Definition: btAlignedObjectArray.h:298
btCompoundShape::calculatePrincipalAxisTransform
void calculatePrincipalAxisTransform(btScalar *masses, btTransform &principal, btVector3 &inertia) const
computes the exact moment of inertia and the transform from the coordinate system defined by the prin...
Definition: btCompoundShape.cpp:216
btCompoundShape::m_collisionMargin
btScalar m_collisionMargin
Definition: btCompoundShape.h:66
btCompoundShapeChild::m_childMargin
btScalar m_childMargin
Definition: btCompoundShape.h:37
btCompoundShape::m_localAabbMin
btVector3 m_localAabbMin
Definition: btCompoundShape.h:58
btCompoundShapeChild
Definition: btCompoundShape.h:30
btDbvtAabbMm
Definition: btDbvt.h:131
btMatrix3x3::absolute
btMatrix3x3 absolute() const
Return the matrix with all values non negative.
Definition: btMatrix3x3.h:937
btDbvt::insert
btDbvtNode * insert(const btDbvtVolume &box, void *data)
Definition: btDbvt.cpp:517
btSerializer::findPointer
virtual void * findPointer(void *oldPtr)=0
btCompoundShapeData::m_collisionShapeData
btCollisionShapeData m_collisionShapeData
Definition: btCompoundShape.h:190
btCompoundShapeChildData::m_childMargin
float m_childMargin
Definition: btCompoundShape.h:184
btCompoundShapeData
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
Definition: btCompoundShape.h:188
btAlignedObjectArray::push_back
void push_back(const T &_Val)
Definition: btAlignedObjectArray.h:274
btDbvt::remove
void remove(btDbvtNode *leaf)
Definition: btDbvt.cpp:589
btTransform::setOrigin
void setOrigin(const btVector3 &origin)
Set the translational element.
Definition: btTransform.h:150
btSerializer::allocate
virtual btChunk * allocate(size_t size, int numElements)=0
btDbvt.h
btVector3::z
const btScalar & z() const
Return the z value.
Definition: btVector3.h:591
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:155
btCompoundShapeChildData
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
Definition: btCompoundShape.h:179
btVector3::length2
btScalar length2() const
Return the length of the vector squared.
Definition: btVector3.h:257
COMPOUND_SHAPE_PROXYTYPE
@ COMPOUND_SHAPE_PROXYTYPE
Definition: btBroadphaseProxy.h:71