Initialize libbullet git in 2.0_beta.
[platform/upstream/libbullet.git] / src / 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 BT_OBB_BOX_2D_SHAPE_H
17 #define BT_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         ///a btBox2dShape is a flat 2D box in the X-Y plane (Z extents are zero)
87         btBox2dShape( const btVector3& boxHalfExtents) 
88                 : btPolyhedralConvexShape(),
89                 m_centroid(0,0,0)
90         {
91                 m_vertices[0].setValue(-boxHalfExtents.getX(),-boxHalfExtents.getY(),0);
92                 m_vertices[1].setValue(boxHalfExtents.getX(),-boxHalfExtents.getY(),0);
93                 m_vertices[2].setValue(boxHalfExtents.getX(),boxHalfExtents.getY(),0);
94                 m_vertices[3].setValue(-boxHalfExtents.getX(),boxHalfExtents.getY(),0);
95
96                 m_normals[0].setValue(0,-1,0);
97                 m_normals[1].setValue(1,0,0);
98                 m_normals[2].setValue(0,1,0);
99                 m_normals[3].setValue(-1,0,0);
100
101                 btScalar minDimension = boxHalfExtents.getX();
102                 if (minDimension>boxHalfExtents.getY())
103                         minDimension = boxHalfExtents.getY();
104                 setSafeMargin(minDimension);
105
106                 m_shapeType = BOX_2D_SHAPE_PROXYTYPE;
107                 btVector3 margin(getMargin(),getMargin(),getMargin());
108                 m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
109         };
110
111         virtual void setMargin(btScalar collisionMargin)
112         {
113                 //correct the m_implicitShapeDimensions for the margin
114                 btVector3 oldMargin(getMargin(),getMargin(),getMargin());
115                 btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
116                 
117                 btConvexInternalShape::setMargin(collisionMargin);
118                 btVector3 newMargin(getMargin(),getMargin(),getMargin());
119                 m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;
120
121         }
122         virtual void    setLocalScaling(const btVector3& scaling)
123         {
124                 btVector3 oldMargin(getMargin(),getMargin(),getMargin());
125                 btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
126                 btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
127
128                 btConvexInternalShape::setLocalScaling(scaling);
129
130                 m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
131
132         }
133
134         virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
135
136         
137
138         virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) const;
139
140
141
142
143
144         int     getVertexCount() const
145         {
146                 return 4;
147         }
148
149         virtual int getNumVertices()const
150         {
151                 return 4;
152         }
153
154         const btVector3* getVertices() const
155         {
156                 return &m_vertices[0];
157         }
158
159         const btVector3* getNormals() const
160         {
161                 return &m_normals[0];
162         }
163
164
165
166
167
168
169
170         virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const
171         {
172                 //this plane might not be aligned...
173                 btVector4 plane ;
174                 getPlaneEquation(plane,i);
175                 planeNormal = btVector3(plane.getX(),plane.getY(),plane.getZ());
176                 planeSupport = localGetSupportingVertex(-planeNormal);
177         }
178
179
180         const btVector3& getCentroid() const
181         {
182                 return m_centroid;
183         }
184         
185         virtual int getNumPlanes() const
186         {
187                 return 6;
188         }       
189         
190         
191
192         virtual int getNumEdges() const
193         {
194                 return 12;
195         }
196
197
198         virtual void getVertex(int i,btVector3& vtx) const
199         {
200                 btVector3 halfExtents = getHalfExtentsWithoutMargin();
201
202                 vtx = btVector3(
203                                 halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1),
204                                 halfExtents.y() * (1-((i&2)>>1)) - halfExtents.y() * ((i&2)>>1),
205                                 halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2));
206         }
207         
208
209         virtual void    getPlaneEquation(btVector4& plane,int i) const
210         {
211                 btVector3 halfExtents = getHalfExtentsWithoutMargin();
212
213                 switch (i)
214                 {
215                 case 0:
216                         plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x());
217                         break;
218                 case 1:
219                         plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x());
220                         break;
221                 case 2:
222                         plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y());
223                         break;
224                 case 3:
225                         plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y());
226                         break;
227                 case 4:
228                         plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z());
229                         break;
230                 case 5:
231                         plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z());
232                         break;
233                 default:
234                         btAssert(0);
235                 }
236         }
237
238         
239         virtual void getEdge(int i,btVector3& pa,btVector3& pb) const
240         //virtual void getEdge(int i,Edge& edge) const
241         {
242                 int edgeVert0 = 0;
243                 int edgeVert1 = 0;
244
245                 switch (i)
246                 {
247                 case 0:
248                                 edgeVert0 = 0;
249                                 edgeVert1 = 1;
250                         break;
251                 case 1:
252                                 edgeVert0 = 0;
253                                 edgeVert1 = 2;
254                         break;
255                 case 2:
256                         edgeVert0 = 1;
257                         edgeVert1 = 3;
258
259                         break;
260                 case 3:
261                         edgeVert0 = 2;
262                         edgeVert1 = 3;
263                         break;
264                 case 4:
265                         edgeVert0 = 0;
266                         edgeVert1 = 4;
267                         break;
268                 case 5:
269                         edgeVert0 = 1;
270                         edgeVert1 = 5;
271
272                         break;
273                 case 6:
274                         edgeVert0 = 2;
275                         edgeVert1 = 6;
276                         break;
277                 case 7:
278                         edgeVert0 = 3;
279                         edgeVert1 = 7;
280                         break;
281                 case 8:
282                         edgeVert0 = 4;
283                         edgeVert1 = 5;
284                         break;
285                 case 9:
286                         edgeVert0 = 4;
287                         edgeVert1 = 6;
288                         break;
289                 case 10:
290                         edgeVert0 = 5;
291                         edgeVert1 = 7;
292                         break;
293                 case 11:
294                         edgeVert0 = 6;
295                         edgeVert1 = 7;
296                         break;
297                 default:
298                         btAssert(0);
299
300                 }
301
302                 getVertex(edgeVert0,pa );
303                 getVertex(edgeVert1,pb );
304         }
305
306
307
308
309         
310         virtual bool isInside(const btVector3& pt,btScalar tolerance) const
311         {
312                 btVector3 halfExtents = getHalfExtentsWithoutMargin();
313
314                 //btScalar minDist = 2*tolerance;
315                 
316                 bool result =   (pt.x() <= (halfExtents.x()+tolerance)) &&
317                                                 (pt.x() >= (-halfExtents.x()-tolerance)) &&
318                                                 (pt.y() <= (halfExtents.y()+tolerance)) &&
319                                                 (pt.y() >= (-halfExtents.y()-tolerance)) &&
320                                                 (pt.z() <= (halfExtents.z()+tolerance)) &&
321                                                 (pt.z() >= (-halfExtents.z()-tolerance));
322                 
323                 return result;
324         }
325
326
327         //debugging
328         virtual const char*     getName()const
329         {
330                 return "Box2d";
331         }
332
333         virtual int             getNumPreferredPenetrationDirections() const
334         {
335                 return 6;
336         }
337         
338         virtual void    getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
339         {
340                 switch (index)
341                 {
342                 case 0:
343                         penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.));
344                         break;
345                 case 1:
346                         penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.));
347                         break;
348                 case 2:
349                         penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.));
350                         break;
351                 case 3:
352                         penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.));
353                         break;
354                 case 4:
355                         penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.));
356                         break;
357                 case 5:
358                         penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
359                         break;
360                 default:
361                         btAssert(0);
362                 }
363         }
364
365 };
366
367 #endif //BT_OBB_BOX_2D_SHAPE_H
368
369