Bullet Collision Detection & Physics Library
btCompoundShape.cpp
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16#include "btCompoundShape.h"
17#include "btCollisionShape.h"
20
24m_dynamicAabbTree(0),
25m_updateRevision(1),
26m_collisionMargin(btScalar(0.)),
27m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.))
28{
30
32 {
33 void* mem = btAlignedAlloc(sizeof(btDbvt),16);
36 }
37
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
67 for (int i=0;i<3;i++)
68 {
69 if (m_localAabbMin[i] > localAabbMin[i])
70 {
72 }
73 if (m_localAabbMax[i] < localAabbMax[i])
74 {
76 }
77
78 }
80 {
82 size_t index = m_children.size();
83 child.m_node = m_dynamicAabbTree->insert(bounds,reinterpret_cast<void*>(index) );
84 }
85
87
88}
89
91{
93
95 {
100 //int index = m_children.size()-1;
102 }
103
105 {
107 }
108}
109
111{
115 {
117 }
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 {
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])
162 if (m_localAabbMax[i] < localAabbMax[i])
164 }
165 }
166}
167
170{
173
174 //avoid an illegal AABB when there are no children
175 if (!m_children.size())
176 {
178 localCenter.setValue(0,0,0);
179 }
181
182
183 btMatrix3x3 abs_b = trans.getBasis().absolute();
184
185 btVector3 center = trans(localCenter);
186
188 aabbMin = center-extent;
189 aabbMax = center+extent;
190
191}
192
194{
195 //approximation: take the inertia from the aabb for now
200
202
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
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
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 {
286 btVector3 childScale = m_children[i].m_childShape->getLocalScaling();
287// childScale = childScale * (childTrans.getBasis() * scaling);
289 m_children[i].m_childShape->setLocalScaling(childScale);
290 childTrans.setOrigin((childTrans.getOrigin()) * scaling / m_localScaling);
292 }
293
294 m_localScaling = scaling;
296
297}
298
299
301{
302 if ( !m_dynamicAabbTree )
303 {
304 void* mem = btAlignedAlloc(sizeof(btDbvt),16);
307
308 for ( int index = 0; index < m_children.size(); index++ )
309 {
311
312 //extend the local aabbMin/aabbMax
314 child.m_childShape->getAabb(child.m_transform,localAabbMin,localAabbMax);
315
317 size_t index2 = index;
318 child.m_node = m_dynamicAabbTree->insert(bounds, reinterpret_cast<void*>(index2) );
319 }
320 }
321}
322
323
326{
327
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
#define btAlignedFree(ptr)
#define btAlignedAlloc(size, alignment)
@ COMPOUND_SHAPE_PROXYTYPE
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition btDbvt.cpp:284
const T & btMax(const T &a, const T &b)
Definition btMinMax.h:29
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition btScalar.h:292
#define ATTRIBUTE_ALIGNED16(a)
Definition btScalar.h:82
#define BT_LARGE_FLOAT
Definition btScalar.h:294
#define btAssert(x)
Definition btScalar.h:131
#define BT_SHAPE_CODE
#define BT_ARRAY_CODE
int size() const
return the number of elements in the array
void swap(int index0, int index1)
void push_back(const T &_Val)
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
virtual void setLocalScaling(const btVector3 &scaling)
btCompoundShape(bool enableDynamicAabbTree=true, const int initialChildCapacity=0)
virtual void calculateLocalInertia(btScalar mass, btVector3 &inertia) const
btVector3 m_localAabbMax
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
void createAabbTreeFromChildren()
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)
virtual ~btCompoundShape()
btAlignedObjectArray< btCompoundShapeChild > m_children
virtual void removeChildShape(btCollisionShape *shape)
Remove all children shapes that contain the specified shape.
void removeChildShapeByIndex(int childShapeindex)
btVector3 m_localScaling
btTransform & getChildTransform(int index)
btScalar m_collisionMargin
int m_updateRevision
increment m_updateRevision when adding/removing/replacing child shapes, so that some caches can be up...
void addChildShape(const btTransform &localTransform, btCollisionShape *shape)
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...
btDbvt * m_dynamicAabbTree
btVector3 m_localAabbMin
virtual btScalar getMargin() const
virtual void recalculateLocalAabb()
Re-calculate the local Aabb.
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...
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition btMatrix3x3.h:48
btMatrix3x3 transpose() const
Return the transpose of the matrix.
btMatrix3x3 absolute() const
Return the matrix with all values non negative.
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition btTransform.h:34
void setIdentity()
Set this transformation to the identity.
btVector3 can be used to represent 3D points and vectors.
Definition btVector3.h:84
btVector3 dot3(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2) const
Definition btVector3.h:731
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition btVector3.h:652
btScalar length2() const
Return the length of the vector squared.
Definition btVector3.h:257
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btDbvtNode * m_node
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
static btDbvtAabbMm FromMM(const btVector3 &mi, const btVector3 &mx)
Definition btDbvt.h:425
The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes ...
Definition btDbvt.h:199
btDbvtNode * insert(const btDbvtVolume &box, void *data)
Definition btDbvt.cpp:517
~btDbvt()
Definition btDbvt.cpp:453
void update(btDbvtNode *leaf, int lookahead=-1)
Definition btDbvt.cpp:526
void remove(btDbvtNode *leaf)
Definition btDbvt.cpp:589