0c5857dae624151e902ffe6e0c8c7061c91590c3
[blender.git] / extern / bullet2 / src / BulletCollision / CollisionShapes / btBoxShape.h
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 #ifndef BT_OBB_BOX_MINKOWSKI_H
17 #define BT_OBB_BOX_MINKOWSKI_H
18
19 #include "btPolyhedralConvexShape.h"
20 #include "btCollisionMargin.h"
21 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
22 #include "LinearMath/btVector3.h"
23 #include "LinearMath/btMinMax.h"
24
25 ///The btBoxShape is a box primitive around the origin, its sides axis aligned with length specified by half extents, in local shape coordinates. When used as part of a btCollisionObject or btRigidBody it will be an oriented box in world space.
26 class btBoxShape: public btPolyhedralConvexShape
27 {
28
29         //btVector3     m_boxHalfExtents1; //use m_implicitShapeDimensions instead
30
31
32 public:
33
34         btVector3 getHalfExtentsWithMargin() const
35         {
36                 btVector3 halfExtents = getHalfExtentsWithoutMargin();
37                 btVector3 margin(getMargin(),getMargin(),getMargin());
38                 halfExtents += margin;
39                 return halfExtents;
40         }
41         
42         const btVector3& getHalfExtentsWithoutMargin() const
43         {
44                 return m_implicitShapeDimensions;//scaling is included, margin is not
45         }
46         
47
48         virtual btVector3       localGetSupportingVertex(const btVector3& vec) const
49         {
50                 btVector3 halfExtents = getHalfExtentsWithoutMargin();
51                 btVector3 margin(getMargin(),getMargin(),getMargin());
52                 halfExtents += margin;
53                 
54                 return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
55                         btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
56                         btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
57         }
58
59         SIMD_FORCE_INLINE  btVector3    localGetSupportingVertexWithoutMargin(const btVector3& vec)const
60         {
61                 const btVector3& halfExtents = getHalfExtentsWithoutMargin();
62                 
63                 return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
64                         btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
65                         btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
66         }
67
68         virtual void    batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
69         {
70                 const btVector3& halfExtents = getHalfExtentsWithoutMargin();
71         
72                 for (int i=0;i<numVectors;i++)
73                 {
74                         const btVector3& vec = vectors[i];
75                         supportVerticesOut[i].setValue(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
76                                 btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
77                                 btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); 
78                 }
79
80         }
81
82
83         btBoxShape( const btVector3& boxHalfExtents);
84
85         virtual void setMargin(btScalar collisionMargin)
86         {
87                 //correct the m_implicitShapeDimensions for the margin
88                 btVector3 oldMargin(getMargin(),getMargin(),getMargin());
89                 btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
90                 
91                 btConvexInternalShape::setMargin(collisionMargin);
92                 btVector3 newMargin(getMargin(),getMargin(),getMargin());
93                 m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;
94
95         }
96         virtual void    setLocalScaling(const btVector3& scaling)
97         {
98                 btVector3 oldMargin(getMargin(),getMargin(),getMargin());
99                 btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
100                 btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
101
102                 btConvexInternalShape::setLocalScaling(scaling);
103
104                 m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
105
106         }
107
108         virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
109
110         
111
112         virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) const;
113
114         virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const
115         {
116                 //this plane might not be aligned...
117                 btVector4 plane ;
118                 getPlaneEquation(plane,i);
119                 planeNormal = btVector3(plane.getX(),plane.getY(),plane.getZ());
120                 planeSupport = localGetSupportingVertex(-planeNormal);
121         }
122
123         
124         virtual int getNumPlanes() const
125         {
126                 return 6;
127         }       
128         
129         virtual int     getNumVertices() const 
130         {
131                 return 8;
132         }
133
134         virtual int getNumEdges() const
135         {
136                 return 12;
137         }
138
139
140         virtual void getVertex(int i,btVector3& vtx) const
141         {
142                 btVector3 halfExtents = getHalfExtentsWithMargin();
143
144                 vtx = btVector3(
145                                 halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1),
146                                 halfExtents.y() * (1-((i&2)>>1)) - halfExtents.y() * ((i&2)>>1),
147                                 halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2));
148         }
149         
150
151         virtual void    getPlaneEquation(btVector4& plane,int i) const
152         {
153                 btVector3 halfExtents = getHalfExtentsWithoutMargin();
154
155                 switch (i)
156                 {
157                 case 0:
158                         plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x());
159                         break;
160                 case 1:
161                         plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x());
162                         break;
163                 case 2:
164                         plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y());
165                         break;
166                 case 3:
167                         plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y());
168                         break;
169                 case 4:
170                         plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z());
171                         break;
172                 case 5:
173                         plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z());
174                         break;
175                 default:
176                         btAssert(0);
177                 }
178         }
179
180         
181         virtual void getEdge(int i,btVector3& pa,btVector3& pb) const
182         //virtual void getEdge(int i,Edge& edge) const
183         {
184                 int edgeVert0 = 0;
185                 int edgeVert1 = 0;
186
187                 switch (i)
188                 {
189                 case 0:
190                                 edgeVert0 = 0;
191                                 edgeVert1 = 1;
192                         break;
193                 case 1:
194                                 edgeVert0 = 0;
195                                 edgeVert1 = 2;
196                         break;
197                 case 2:
198                         edgeVert0 = 1;
199                         edgeVert1 = 3;
200
201                         break;
202                 case 3:
203                         edgeVert0 = 2;
204                         edgeVert1 = 3;
205                         break;
206                 case 4:
207                         edgeVert0 = 0;
208                         edgeVert1 = 4;
209                         break;
210                 case 5:
211                         edgeVert0 = 1;
212                         edgeVert1 = 5;
213
214                         break;
215                 case 6:
216                         edgeVert0 = 2;
217                         edgeVert1 = 6;
218                         break;
219                 case 7:
220                         edgeVert0 = 3;
221                         edgeVert1 = 7;
222                         break;
223                 case 8:
224                         edgeVert0 = 4;
225                         edgeVert1 = 5;
226                         break;
227                 case 9:
228                         edgeVert0 = 4;
229                         edgeVert1 = 6;
230                         break;
231                 case 10:
232                         edgeVert0 = 5;
233                         edgeVert1 = 7;
234                         break;
235                 case 11:
236                         edgeVert0 = 6;
237                         edgeVert1 = 7;
238                         break;
239                 default:
240                         btAssert(0);
241
242                 }
243
244                 getVertex(edgeVert0,pa );
245                 getVertex(edgeVert1,pb );
246         }
247
248
249
250
251         
252         virtual bool isInside(const btVector3& pt,btScalar tolerance) const
253         {
254                 btVector3 halfExtents = getHalfExtentsWithoutMargin();
255
256                 //btScalar minDist = 2*tolerance;
257                 
258                 bool result =   (pt.x() <= (halfExtents.x()+tolerance)) &&
259                                                 (pt.x() >= (-halfExtents.x()-tolerance)) &&
260                                                 (pt.y() <= (halfExtents.y()+tolerance)) &&
261                                                 (pt.y() >= (-halfExtents.y()-tolerance)) &&
262                                                 (pt.z() <= (halfExtents.z()+tolerance)) &&
263                                                 (pt.z() >= (-halfExtents.z()-tolerance));
264                 
265                 return result;
266         }
267
268
269         //debugging
270         virtual const char*     getName()const
271         {
272                 return "Box";
273         }
274
275         virtual int             getNumPreferredPenetrationDirections() const
276         {
277                 return 6;
278         }
279         
280         virtual void    getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
281         {
282                 switch (index)
283                 {
284                 case 0:
285                         penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.));
286                         break;
287                 case 1:
288                         penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.));
289                         break;
290                 case 2:
291                         penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.));
292                         break;
293                 case 3:
294                         penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.));
295                         break;
296                 case 4:
297                         penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.));
298                         break;
299                 case 5:
300                         penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
301                         break;
302                 default:
303                         btAssert(0);
304                 }
305         }
306
307 };
308
309
310 #endif //BT_OBB_BOX_MINKOWSKI_H
311
312