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
24 m_dynamicAabbTree(0),
25 m_updateRevision(1),
26 m_collisionMargin(btScalar(0.)),
27 m_localScaling(btScalar(1.), btScalar(1.), btScalar(1.))
28{
30
32 {
33 void* mem = btAlignedAlloc(sizeof(btDbvt), 16);
36 }
37
39}
40
42{
44 {
47 }
48}
49
51{
53 //m_childTransforms.push_back(localTransform);
54 //m_childShapes.push_back(shape);
56 child.m_node = 0;
57 child.m_transform = localTransform;
58 child.m_childShape = shape;
59 child.m_childShapeType = shape->getShapeType();
60 child.m_childMargin = shape->getMargin();
61
62 //extend the local aabbMin/aabbMax
65 for (int i = 0; i < 3; i++)
66 {
67 if (m_localAabbMin[i] > localAabbMin[i])
68 {
70 }
71 if (m_localAabbMax[i] < localAabbMax[i])
72 {
74 }
75 }
77 {
79 size_t index = m_children.size();
80 child.m_node = m_dynamicAabbTree->insert(bounds, reinterpret_cast<void*>(index));
81 }
82
84}
85
87{
89
91 {
97 //int index = m_children.size()-1;
99 }
100
102 {
104 }
105}
106
108{
112 {
114 }
117 m_children[childShapeIndex].m_node->dataAsInt = childShapeIndex;
119}
120
122{
124 // Find the children containing the shape specified, and remove those children.
125 //note: there might be multiple children using the same shape!
126 for (int i = m_children.size() - 1; i >= 0; i--)
127 {
128 if (m_children[i].m_childShape == shape)
129 {
131 }
132 }
133
135}
136
138{
139 // Recalculate the local aabb
140 // Brute force, it iterates over all the shapes left.
141
144
145 //extend the local aabbMin/aabbMax
146 for (int j = 0; j < m_children.size(); j++)
147 {
149 m_children[j].m_childShape->getAabb(m_children[j].m_transform, localAabbMin, localAabbMax);
150 for (int i = 0; i < 3; i++)
151 {
152 if (m_localAabbMin[i] > localAabbMin[i])
154 if (m_localAabbMax[i] < localAabbMax[i])
156 }
157 }
158}
159
162{
165
166 //avoid an illegal AABB when there are no children
167 if (!m_children.size())
168 {
169 localHalfExtents.setValue(0, 0, 0);
170 localCenter.setValue(0, 0, 0);
171 }
173
174 btMatrix3x3 abs_b = trans.getBasis().absolute();
175
176 btVector3 center = trans(localCenter);
177
179 aabbMin = center - extent;
180 aabbMax = center + extent;
181}
182
184{
185 //approximation: take the inertia from the aabb for now
190
192
193 btScalar lx = btScalar(2.) * (halfExtents.x());
194 btScalar ly = btScalar(2.) * (halfExtents.y());
195 btScalar lz = btScalar(2.) * (halfExtents.z());
196
197 inertia[0] = mass / (btScalar(12.0)) * (ly * ly + lz * lz);
198 inertia[1] = mass / (btScalar(12.0)) * (lx * lx + lz * lz);
199 inertia[2] = mass / (btScalar(12.0)) * (lx * lx + ly * ly);
200}
201
203{
204 int n = m_children.size();
205
207 btVector3 center(0, 0, 0);
208 int k;
209
210 for (k = 0; k < n; k++)
211 {
212 btAssert(masses[k] > 0);
213 center += m_children[k].m_transform.getOrigin() * masses[k];
214 totalMass += masses[k];
215 }
216
217 btAssert(totalMass > 0);
218
219 center /= totalMass;
220 principal.setOrigin(center);
221
222 btMatrix3x3 tensor(0, 0, 0, 0, 0, 0, 0, 0, 0);
223 for (k = 0; k < n; k++)
224 {
225 btVector3 i;
226 m_children[k].m_childShape->calculateLocalInertia(masses[k], i);
227
228 const btTransform& t = m_children[k].m_transform;
229 btVector3 o = t.getOrigin() - center;
230
231 //compute inertia tensor in coordinate system of compound shape
232 btMatrix3x3 j = t.getBasis().transpose();
233 j[0] *= i[0];
234 j[1] *= i[1];
235 j[2] *= i[2];
236 j = t.getBasis() * j;
237
238 //add inertia tensor
239 tensor[0] += j[0];
240 tensor[1] += j[1];
241 tensor[2] += j[2];
242
243 //compute inertia tensor of pointmass at o
244 btScalar o2 = o.length2();
245 j[0].setValue(o2, 0, 0);
246 j[1].setValue(0, o2, 0);
247 j[2].setValue(0, 0, o2);
248 j[0] += o * -o.x();
249 j[1] += o * -o.y();
250 j[2] += o * -o.z();
251
252 //add inertia tensor of pointmass
253 tensor[0] += masses[k] * j[0];
254 tensor[1] += masses[k] * j[1];
255 tensor[2] += masses[k] * j[2];
256 }
257
258 tensor.diagonalize(principal.getBasis(), btScalar(0.00001), 20);
259 inertia.setValue(tensor[0][0], tensor[1][1], tensor[2][2]);
260}
261
263{
264 for (int i = 0; i < m_children.size(); i++)
265 {
267 btVector3 childScale = m_children[i].m_childShape->getLocalScaling();
268 // childScale = childScale * (childTrans.getBasis() * scaling);
270 m_children[i].m_childShape->setLocalScaling(childScale);
271 childTrans.setOrigin((childTrans.getOrigin()) * scaling / m_localScaling);
273 }
274
275 m_localScaling = scaling;
277}
278
280{
282 {
283 void* mem = btAlignedAlloc(sizeof(btDbvt), 16);
284 m_dynamicAabbTree = new (mem) btDbvt();
286
287 for (int index = 0; index < m_children.size(); index++)
288 {
290
291 //extend the local aabbMin/aabbMax
293 child.m_childShape->getAabb(child.m_transform, localAabbMin, localAabbMax);
294
296 size_t index2 = index;
297 child.m_node = m_dynamicAabbTree->insert(bounds, reinterpret_cast<void*>(index2));
298 }
299 }
300}
301
304{
306 btCollisionShape::serialize(&shapeData->m_collisionShapeData, serializer);
307
308 shapeData->m_collisionMargin = float(m_collisionMargin);
309 shapeData->m_numChildShapes = m_children.size();
310 shapeData->m_childShapePtr = 0;
311 if (shapeData->m_numChildShapes)
312 {
313 btChunk* chunk = serializer->allocate(sizeof(btCompoundShapeChildData), shapeData->m_numChildShapes);
315 shapeData->m_childShapePtr = (btCompoundShapeChildData*)serializer->getUniquePointer(memPtr);
316
317 for (int i = 0; i < shapeData->m_numChildShapes; i++, memPtr++)
318 {
319 memPtr->m_childMargin = float(m_children[i].m_childMargin);
320 memPtr->m_childShape = (btCollisionShapeData*)serializer->getUniquePointer(m_children[i].m_childShape);
321 //don't serialize shapes that already have been serialized
322 if (!serializer->findPointer(m_children[i].m_childShape))
323 {
324 btChunk* chunk = serializer->allocate(m_children[i].m_childShape->calculateSerializeBufferSize(), 1);
325 const char* structType = m_children[i].m_childShape->serialize(chunk->m_oldPtr, serializer);
326 serializer->finalizeChunk(chunk, structType, BT_SHAPE_CODE, m_children[i].m_childShape);
327 }
328
329 memPtr->m_childShapeType = m_children[i].m_childShapeType;
330 m_children[i].m_transform.serializeFloat(memPtr->m_transform);
331 }
332 serializer->finalizeChunk(chunk, "btCompoundShapeChildData", BT_ARRAY_CODE, chunk->m_oldPtr);
333 }
334 return "btCompoundShapeData";
335}
#define btAlignedFree(ptr)
#define btAlignedAlloc(size, alignment)
@ COMPOUND_SHAPE_PROXYTYPE
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition btDbvt.cpp:299
const T & btMax(const T &a, const T &b)
Definition btMinMax.h:27
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition btScalar.h:314
#define ATTRIBUTE_ALIGNED16(a)
Definition btScalar.h:99
#define BT_LARGE_FLOAT
Definition btScalar.h:316
#define btAssert(x)
Definition btScalar.h:153
#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...
int getShapeType() const
virtual btScalar getMargin() const =0
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.
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
void calculatePrincipalAxisTransform(const btScalar *masses, btTransform &principal, btVector3 &inertia) const
computes the exact moment of inertia and the transform from the coordinate system defined by the prin...
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)
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:50
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:30
void setIdentity()
Set this transformation to the identity.
btVector3 can be used to represent 3D points and vectors.
Definition btVector3.h:82
btVector3 dot3(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2) const
Definition btVector3.h:720
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition btVector3.h:640
btScalar length2() const
Return the length of the vector squared.
Definition btVector3.h:251
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:479
The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes ...
Definition btDbvt.h:229
btDbvtNode * insert(const btDbvtVolume &box, void *data)
Definition btDbvt.cpp:535
~btDbvt()
Definition btDbvt.cpp:471
void update(btDbvtNode *leaf, int lookahead=-1)
Definition btDbvt.cpp:544
void remove(btDbvtNode *leaf)
Definition btDbvt.cpp:611