== SoC Bullet - Bullet Upgrade to 2.76 ==
[blender.git] / extern / bullet2 / BulletCollision / CollisionShapes / btBox2dShape.h
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
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 OBB_BOX_2D_SHAPE_H
17 #define OBB_BOX_2D_SHAPE_H
18
19 #include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
20 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
21 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
22 #include "LinearMath/btVector3.h"
23 #include "LinearMath/btMinMax.h"
24
25 ///The btBox2dShape 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 btBox2dShape: public btPolyhedralConvexShape
27 {
28
29         //btVector3     m_boxHalfExtents1; //use m_implicitShapeDimensions instead
30
31         btVector3 m_centroid;
32         btVector3 m_vertices[4];
33         btVector3 m_normals[4];
34
35 public:
36
37         btVector3 getHalfExtentsWithMargin() const
38         {
39                 btVector3 halfExtents = getHalfExtentsWithoutMargin();
40                 btVector3 margin(getMargin(),getMargin(),getMargin());
41                 halfExtents += margin;
42                 return halfExtents;
43         }
44         
45         const btVector3& getHalfExtentsWithoutMargin() const
46         {
47                 return m_implicitShapeDimensions;//changed in Bullet 2.63: assume the scaling and margin are included
48         }
49         
50
51         virtual btVector3       localGetSupportingVertex(const btVector3& vec) const
52         {
53                 btVector3 halfExtents = getHalfExtentsWithoutMargin();
54                 btVector3 margin(getMargin(),getMargin(),getMargin());
55                 halfExtents += margin;
56                 
57                 return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
58                         btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
59                         btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
60         }
61
62         SIMD_FORCE_INLINE  btVector3    localGetSupportingVertexWithoutMargin(const btVector3& vec)const
63         {
64                 const btVector3& halfExtents = getHalfExtentsWithoutMargin();
65                 
66                 return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
67                         btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
68                         btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
69         }
70
71         virtual void    batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
72         {
73                 const btVector3& halfExtents = getHalfExtentsWithoutMargin();
74         
75                 for (int i=0;i<numVectors;i++)
76                 {
77                         const btVector3& vec = vectors[i];
78                         supportVerticesOut[i].setValue(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
79                                 btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
80                                 btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); 
81                 }
82
83         }
84
85
86         btBox2dShape( const btVector3& boxHalfExtents) 
87                 : btPolyhedralConvexShape(),
88                 m_centroid(0,0,0)
89         {
90                 m_vertices[0].setValue(-boxHalfExtents.getX(),-boxHalfExtents.getY(),0);
91                 m_vertices[1].setValue(boxHalfExtents.getX(),-boxHalfExtents.getY(),0);
92                 m_vertices[2].setValue(boxHalfExtents.getX(),boxHalfExtents.getY(),0);
93                 m_vertices[3].setValue(-boxHalfExtents.getX(),boxHalfExtents.getY(),0);
94
95                 m_normals[0].setValue(0,-1,0);
96                 m_normals[1].setValue(1,0,0);
97                 m_normals[2].setValue(0,1,0);
98                 m_normals[3].setValue(-1,0,0);
99
100                 m_shapeType = BOX_2D_SHAPE_PROXYTYPE;
101                 btVector3 margin(getMargin(),getMargin(),getMargin());
102                 m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
103         };
104
105         virtual void setMargin(btScalar collisionMargin)
106         {
107                 //correct the m_implicitShapeDimensions for the margin
108                 btVector3 oldMargin(getMargin(),getMargin(),getMargin());
109                 btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
110                 
111                 btConvexInternalShape::setMargin(collisionMargin);
112                 btVector3 newMargin(getMargin(),getMargin(),getMargin());
113                 m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;
114
115         }
116         virtual void    setLocalScaling(const btVector3& scaling)
117         {
118                 btVector3 oldMargin(getMargin(),getMargin(),getMargin());
119                 btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
120                 btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
121
122                 btConvexInternalShape::setLocalScaling(scaling);
123
124                 m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
125
126         }
127
128         virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
129
130         
131
132         virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) const;
133
134
135
136
137
138         int     getVertexCount() const
139         {
140                 return 4;
141         }
142
143         virtual int getNumVertices()const
144         {
145                 return 4;
146         }
147
148         const btVector3* getVertices() const
149         {
150                 return &m_vertices[0];
151         }
152
153         const btVector3* getNormals() const
154         {
155                 return &m_normals[0];
156         }
157
158
159
160
161
162
163
164         virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const
165         {
166                 //this plane might not be aligned...
167                 btVector4 plane ;
168                 getPlaneEquation(plane,i);
169                 planeNormal = btVector3(plane.getX(),plane.getY(),plane.getZ());
170                 planeSupport = localGetSupportingVertex(-planeNormal);
171         }
172
173
174         const btVector3& getCentroid() const
175         {
176                 return m_centroid;
177         }
178         
179         virtual int getNumPlanes() const
180         {
181                 return 6;
182         }       
183         
184         
185
186         virtual int getNumEdges() const
187         {
188                 return 12;
189         }
190
191
192         virtual void getVertex(int i,btVector3& vtx) const
193         {
194                 btVector3 halfExtents = getHalfExtentsWithoutMargin();
195
196                 vtx = btVector3(
197                                 halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1),
198                                 halfExtents.y() * (1-((i&2)>>1)) - halfExtents.y() * ((i&2)>>1),
199                                 halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2));
200         }
201         
202
203         virtual void    getPlaneEquation(btVector4& plane,int i) const
204         {
205                 btVector3 halfExtents = getHalfExtentsWithoutMargin();
206
207                 switch (i)
208                 {
209                 case 0:
210                         plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x());
211                         break;
212                 case 1:
213                         plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x());
214                         break;
215                 case 2:
216                         plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y());
217                         break;
218                 case 3:
219                         plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y());
220                         break;
221                 case 4:
222                         plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z());
223                         break;
224                 case 5:
225                         plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z());
226                         break;
227                 default:
228                         btAssert(0);
229                 }
230         }
231
232         
233         virtual void getEdge(int i,btVector3& pa,btVector3& pb) const
234         //virtual void getEdge(int i,Edge& edge) const
235         {
236                 int edgeVert0 = 0;
237                 int edgeVert1 = 0;
238
239                 switch (i)
240                 {
241                 case 0:
242                                 edgeVert0 = 0;
243                                 edgeVert1 = 1;
244                         break;
245                 case 1:
246                                 edgeVert0 = 0;
247                                 edgeVert1 = 2;
248                         break;
249                 case 2:
250                         edgeVert0 = 1;
251                         edgeVert1 = 3;
252
253                         break;
254                 case 3:
255                         edgeVert0 = 2;
256                         edgeVert1 = 3;
257                         break;
258                 case 4:
259                         edgeVert0 = 0;
260                         edgeVert1 = 4;
261                         break;
262                 case 5:
263                         edgeVert0 = 1;
264                         edgeVert1 = 5;
265
266                         break;
267                 case 6:
268                         edgeVert0 = 2;
269                         edgeVert1 = 6;
270                         break;
271                 case 7:
272                         edgeVert0 = 3;
273                         edgeVert1 = 7;
274                         break;
275                 case 8:
276                         edgeVert0 = 4;
277                         edgeVert1 = 5;
278                         break;
279                 case 9:
280                         edgeVert0 = 4;
281                         edgeVert1 = 6;
282                         break;
283                 case 10:
284                         edgeVert0 = 5;
285                         edgeVert1 = 7;
286                         break;
287                 case 11:
288                         edgeVert0 = 6;
289                         edgeVert1 = 7;
290                         break;
291                 default:
292                         btAssert(0);
293
294                 }
295
296                 getVertex(edgeVert0,pa );
297                 getVertex(edgeVert1,pb );
298         }
299
300
301
302
303         
304         virtual bool isInside(const btVector3& pt,btScalar tolerance) const
305         {
306                 btVector3 halfExtents = getHalfExtentsWithoutMargin();
307
308                 //btScalar minDist = 2*tolerance;
309                 
310                 bool result =   (pt.x() <= (halfExtents.x()+tolerance)) &&
311                                                 (pt.x() >= (-halfExtents.x()-tolerance)) &&
312                                                 (pt.y() <= (halfExtents.y()+tolerance)) &&
313                                                 (pt.y() >= (-halfExtents.y()-tolerance)) &&
314                                                 (pt.z() <= (halfExtents.z()+tolerance)) &&
315                                                 (pt.z() >= (-halfExtents.z()-tolerance));
316                 
317                 return result;
318         }
319
320
321         //debugging
322         virtual const char*     getName()const
323         {
324                 return "Box2d";
325         }
326
327         virtual int             getNumPreferredPenetrationDirections() const
328         {
329                 return 6;
330         }
331         
332         virtual void    getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
333         {
334                 switch (index)
335                 {
336                 case 0:
337                         penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.));
338                         break;
339                 case 1:
340                         penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.));
341                         break;
342                 case 2:
343                         penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.));
344                         break;
345                 case 3:
346                         penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.));
347                         break;
348                 case 4:
349                         penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.));
350                         break;
351                 case 5:
352                         penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
353                         break;
354                 default:
355                         btAssert(0);
356                 }
357         }
358
359 };
360
361 #endif //OBB_BOX_2D_SHAPE_H
362
363