Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCompoundShape.cpp @ 1972

Last change on this file since 1972 was 1963, checked in by rgrieder, 16 years ago

Added Bullet physics engine.

  • Property svn:eol-style set to native
File size: 6.8 KB
Line 
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
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"
18#include "BulletCollision/BroadphaseCollision/btDbvt.h"
19
20btCompoundShape::btCompoundShape()
21: m_localAabbMin(btScalar(1e30),btScalar(1e30),btScalar(1e30)),
22m_localAabbMax(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)),
23m_collisionMargin(btScalar(0.)),
24m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
25m_dynamicAabbTree(0)
26{
27        m_shapeType = COMPOUND_SHAPE_PROXYTYPE;
28        void* mem = btAlignedAlloc(sizeof(btDbvt),16);
29        m_dynamicAabbTree = new(mem) btDbvt();
30        btAssert(mem==m_dynamicAabbTree);
31}
32
33
34btCompoundShape::~btCompoundShape()
35{
36        if (m_dynamicAabbTree)
37        {
38                m_dynamicAabbTree->~btDbvt();
39                btAlignedFree(m_dynamicAabbTree);
40        }
41}
42
43void    btCompoundShape::addChildShape(const btTransform& localTransform,btCollisionShape* shape)
44{
45        //m_childTransforms.push_back(localTransform);
46        //m_childShapes.push_back(shape);
47        btCompoundShapeChild child;
48        child.m_transform = localTransform;
49        child.m_childShape = shape;
50        child.m_childShapeType = shape->getShapeType();
51        child.m_childMargin = shape->getMargin();
52
53        m_children.push_back(child);
54
55        //extend the local aabbMin/aabbMax
56        btVector3 localAabbMin,localAabbMax;
57        shape->getAabb(localTransform,localAabbMin,localAabbMax);
58        for (int i=0;i<3;i++)
59        {
60                if (m_localAabbMin[i] > localAabbMin[i])
61                {
62                        m_localAabbMin[i] = localAabbMin[i];
63                }
64                if (m_localAabbMax[i] < localAabbMax[i])
65                {
66                        m_localAabbMax[i] = localAabbMax[i];
67                }
68
69        }
70        if (m_dynamicAabbTree)
71        {
72                const btDbvtVolume      bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
73                int index = m_children.size()-1;
74                child.m_node = m_dynamicAabbTree->insert(bounds,(void*)index);
75        }
76
77}
78
79void btCompoundShape::removeChildShapeByIndex(int childShapeIndex)
80{
81        btAssert(childShapeIndex >=0 && childShapeIndex < m_children.size());
82        if (m_dynamicAabbTree)
83        {
84                m_dynamicAabbTree->remove(m_children[childShapeIndex].m_node);
85        }
86        m_children.swap(childShapeIndex,m_children.size()-1);
87        m_children.pop_back();
88
89}
90
91void btCompoundShape::removeChildShape(btCollisionShape* shape)
92{
93        // Find the children containing the shape specified, and remove those children.
94        //note: there might be multiple children using the same shape!
95        for(int i = m_children.size()-1; i >= 0 ; i--)
96        {
97                if(m_children[i].m_childShape == shape)
98                {
99                        m_children.swap(i,m_children.size()-1);
100                        m_children.pop_back();
101                        //remove it from the m_dynamicAabbTree too
102                        //m_dynamicAabbTree->remove(m_aabbProxies[i]);
103                        //m_aabbProxies.swap(i,m_children.size()-1);
104                        //m_aabbProxies.pop_back();
105                }
106        }
107
108
109
110        recalculateLocalAabb();
111}
112
113void btCompoundShape::recalculateLocalAabb()
114{
115        // Recalculate the local aabb
116        // Brute force, it iterates over all the shapes left.
117        m_localAabbMin = btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30));
118        m_localAabbMax = btVector3(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
119
120        //extend the local aabbMin/aabbMax
121        for (int j = 0; j < m_children.size(); j++)
122        {
123                btVector3 localAabbMin,localAabbMax;
124                m_children[j].m_childShape->getAabb(m_children[j].m_transform, localAabbMin, localAabbMax);
125                for (int i=0;i<3;i++)
126                {
127                        if (m_localAabbMin[i] > localAabbMin[i])
128                                m_localAabbMin[i] = localAabbMin[i];
129                        if (m_localAabbMax[i] < localAabbMax[i])
130                                m_localAabbMax[i] = localAabbMax[i];
131                }
132        }
133}
134
135///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
136void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
137{
138        btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
139        localHalfExtents += btVector3(getMargin(),getMargin(),getMargin());
140        btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
141
142        btMatrix3x3 abs_b = trans.getBasis().absolute(); 
143
144        btPoint3 center = trans(localCenter);
145
146        btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
147                abs_b[1].dot(localHalfExtents),
148                abs_b[2].dot(localHalfExtents));
149        aabbMin = center-extent;
150        aabbMax = center+extent;
151
152}
153
154void    btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
155{
156        //approximation: take the inertia from the aabb for now
157        btTransform ident;
158        ident.setIdentity();
159        btVector3 aabbMin,aabbMax;
160        getAabb(ident,aabbMin,aabbMax);
161
162        btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5);
163
164        btScalar lx=btScalar(2.)*(halfExtents.x());
165        btScalar ly=btScalar(2.)*(halfExtents.y());
166        btScalar lz=btScalar(2.)*(halfExtents.z());
167
168        inertia[0] = mass/(btScalar(12.0)) * (ly*ly + lz*lz);
169        inertia[1] = mass/(btScalar(12.0)) * (lx*lx + lz*lz);
170        inertia[2] = mass/(btScalar(12.0)) * (lx*lx + ly*ly);
171
172}
173
174
175
176
177void btCompoundShape::calculatePrincipalAxisTransform(btScalar* masses, btTransform& principal, btVector3& inertia) const
178{
179        int n = m_children.size();
180
181        btScalar totalMass = 0;
182        btVector3 center(0, 0, 0);
183        for (int k = 0; k < n; k++)
184        {
185                center += m_children[k].m_transform.getOrigin() * masses[k];
186                totalMass += masses[k];
187        }
188        center /= totalMass;
189        principal.setOrigin(center);
190
191        btMatrix3x3 tensor(0, 0, 0, 0, 0, 0, 0, 0, 0);
192        for (int k = 0; k < n; k++)
193        {
194                btVector3 i;
195                m_children[k].m_childShape->calculateLocalInertia(masses[k], i);
196
197                const btTransform& t = m_children[k].m_transform;
198                btVector3 o = t.getOrigin() - center;
199
200                //compute inertia tensor in coordinate system of compound shape
201                btMatrix3x3 j = t.getBasis().transpose();
202                j[0] *= i[0];
203                j[1] *= i[1];
204                j[2] *= i[2];
205                j = t.getBasis() * j;
206
207                //add inertia tensor
208                tensor[0] += j[0];
209                tensor[1] += j[1];
210                tensor[2] += j[2];
211
212                //compute inertia tensor of pointmass at o
213                btScalar o2 = o.length2();
214                j[0].setValue(o2, 0, 0);
215                j[1].setValue(0, o2, 0);
216                j[2].setValue(0, 0, o2);
217                j[0] += o * -o.x(); 
218                j[1] += o * -o.y(); 
219                j[2] += o * -o.z();
220
221                //add inertia tensor of pointmass
222                tensor[0] += masses[k] * j[0];
223                tensor[1] += masses[k] * j[1];
224                tensor[2] += masses[k] * j[2];
225        }
226
227        tensor.diagonalize(principal.getBasis(), btScalar(0.00001), 20);
228        inertia.setValue(tensor[0][0], tensor[1][1], tensor[2][2]);
229}
230
231
232
Note: See TracBrowser for help on using the repository browser.