[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-physics / third-party / bullet3 / 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 ATTRIBUTE_ALIGNED16(class)
27 btBoxShape : public btPolyhedralConvexShape
28 {
29         //btVector3     m_boxHalfExtents1; //use m_implicitShapeDimensions instead
30
31 public:
32         BT_DECLARE_ALIGNED_ALLOCATOR();
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         virtual btVector3 localGetSupportingVertex(const btVector3& vec) const
48         {
49                 btVector3 halfExtents = getHalfExtentsWithoutMargin();
50                 btVector3 margin(getMargin(), getMargin(), getMargin());
51                 halfExtents += margin;
52
53                 return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
54                                                  btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
55                                                  btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
56         }
57
58         SIMD_FORCE_INLINE btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const
59         {
60                 const btVector3& halfExtents = getHalfExtentsWithoutMargin();
61
62                 return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
63                                                  btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
64                                                  btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
65         }
66
67         virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const
68         {
69                 const btVector3& halfExtents = getHalfExtentsWithoutMargin();
70
71                 for (int i = 0; i < numVectors; i++)
72                 {
73                         const btVector3& vec = vectors[i];
74                         supportVerticesOut[i].setValue(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
75                                                                                    btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
76                                                                                    btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
77                 }
78         }
79
80         btBoxShape(const btVector3& boxHalfExtents);
81
82         virtual void setMargin(btScalar collisionMargin)
83         {
84                 //correct the m_implicitShapeDimensions for the margin
85                 btVector3 oldMargin(getMargin(), getMargin(), getMargin());
86                 btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions + oldMargin;
87
88                 btConvexInternalShape::setMargin(collisionMargin);
89                 btVector3 newMargin(getMargin(), getMargin(), getMargin());
90                 m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;
91         }
92         virtual void setLocalScaling(const btVector3& scaling)
93         {
94                 btVector3 oldMargin(getMargin(), getMargin(), getMargin());
95                 btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions + oldMargin;
96                 btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
97
98                 btConvexInternalShape::setLocalScaling(scaling);
99
100                 m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
101         }
102
103         virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const;
104
105         virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const;
106
107         virtual void getPlane(btVector3 & planeNormal, btVector3 & planeSupport, int i) const
108         {
109                 //this plane might not be aligned...
110                 btVector4 plane;
111                 getPlaneEquation(plane, i);
112                 planeNormal = btVector3(plane.getX(), plane.getY(), plane.getZ());
113                 planeSupport = localGetSupportingVertex(-planeNormal);
114         }
115
116         virtual int getNumPlanes() const
117         {
118                 return 6;
119         }
120
121         virtual int getNumVertices() const
122         {
123                 return 8;
124         }
125
126         virtual int getNumEdges() const
127         {
128                 return 12;
129         }
130
131         virtual void getVertex(int i, btVector3& vtx) const
132         {
133                 btVector3 halfExtents = getHalfExtentsWithMargin();
134
135                 vtx = btVector3(
136                         halfExtents.x() * (1 - (i & 1)) - halfExtents.x() * (i & 1),
137                         halfExtents.y() * (1 - ((i & 2) >> 1)) - halfExtents.y() * ((i & 2) >> 1),
138                         halfExtents.z() * (1 - ((i & 4) >> 2)) - halfExtents.z() * ((i & 4) >> 2));
139         }
140
141         virtual void getPlaneEquation(btVector4 & plane, int i) const
142         {
143                 btVector3 halfExtents = getHalfExtentsWithoutMargin();
144
145                 switch (i)
146                 {
147                         case 0:
148                                 plane.setValue(btScalar(1.), btScalar(0.), btScalar(0.), -halfExtents.x());
149                                 break;
150                         case 1:
151                                 plane.setValue(btScalar(-1.), btScalar(0.), btScalar(0.), -halfExtents.x());
152                                 break;
153                         case 2:
154                                 plane.setValue(btScalar(0.), btScalar(1.), btScalar(0.), -halfExtents.y());
155                                 break;
156                         case 3:
157                                 plane.setValue(btScalar(0.), btScalar(-1.), btScalar(0.), -halfExtents.y());
158                                 break;
159                         case 4:
160                                 plane.setValue(btScalar(0.), btScalar(0.), btScalar(1.), -halfExtents.z());
161                                 break;
162                         case 5:
163                                 plane.setValue(btScalar(0.), btScalar(0.), btScalar(-1.), -halfExtents.z());
164                                 break;
165                         default:
166                                 btAssert(0);
167                 }
168         }
169
170         virtual void getEdge(int i, btVector3& pa, btVector3& pb) const
171         //virtual void getEdge(int i,Edge& edge) const
172         {
173                 int edgeVert0 = 0;
174                 int edgeVert1 = 0;
175
176                 switch (i)
177                 {
178                         case 0:
179                                 edgeVert0 = 0;
180                                 edgeVert1 = 1;
181                                 break;
182                         case 1:
183                                 edgeVert0 = 0;
184                                 edgeVert1 = 2;
185                                 break;
186                         case 2:
187                                 edgeVert0 = 1;
188                                 edgeVert1 = 3;
189
190                                 break;
191                         case 3:
192                                 edgeVert0 = 2;
193                                 edgeVert1 = 3;
194                                 break;
195                         case 4:
196                                 edgeVert0 = 0;
197                                 edgeVert1 = 4;
198                                 break;
199                         case 5:
200                                 edgeVert0 = 1;
201                                 edgeVert1 = 5;
202
203                                 break;
204                         case 6:
205                                 edgeVert0 = 2;
206                                 edgeVert1 = 6;
207                                 break;
208                         case 7:
209                                 edgeVert0 = 3;
210                                 edgeVert1 = 7;
211                                 break;
212                         case 8:
213                                 edgeVert0 = 4;
214                                 edgeVert1 = 5;
215                                 break;
216                         case 9:
217                                 edgeVert0 = 4;
218                                 edgeVert1 = 6;
219                                 break;
220                         case 10:
221                                 edgeVert0 = 5;
222                                 edgeVert1 = 7;
223                                 break;
224                         case 11:
225                                 edgeVert0 = 6;
226                                 edgeVert1 = 7;
227                                 break;
228                         default:
229                                 btAssert(0);
230                 }
231
232                 getVertex(edgeVert0, pa);
233                 getVertex(edgeVert1, pb);
234         }
235
236         virtual bool isInside(const btVector3& pt, btScalar tolerance) const
237         {
238                 btVector3 halfExtents = getHalfExtentsWithoutMargin();
239
240                 //btScalar minDist = 2*tolerance;
241
242                 bool result = (pt.x() <= (halfExtents.x() + tolerance)) &&
243                                           (pt.x() >= (-halfExtents.x() - tolerance)) &&
244                                           (pt.y() <= (halfExtents.y() + tolerance)) &&
245                                           (pt.y() >= (-halfExtents.y() - tolerance)) &&
246                                           (pt.z() <= (halfExtents.z() + tolerance)) &&
247                                           (pt.z() >= (-halfExtents.z() - tolerance));
248
249                 return result;
250         }
251
252         //debugging
253         virtual const char* getName() const
254         {
255                 return "Box";
256         }
257
258         virtual int getNumPreferredPenetrationDirections() const
259         {
260                 return 6;
261         }
262
263         virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
264         {
265                 switch (index)
266                 {
267                         case 0:
268                                 penetrationVector.setValue(btScalar(1.), btScalar(0.), btScalar(0.));
269                                 break;
270                         case 1:
271                                 penetrationVector.setValue(btScalar(-1.), btScalar(0.), btScalar(0.));
272                                 break;
273                         case 2:
274                                 penetrationVector.setValue(btScalar(0.), btScalar(1.), btScalar(0.));
275                                 break;
276                         case 3:
277                                 penetrationVector.setValue(btScalar(0.), btScalar(-1.), btScalar(0.));
278                                 break;
279                         case 4:
280                                 penetrationVector.setValue(btScalar(0.), btScalar(0.), btScalar(1.));
281                                 break;
282                         case 5:
283                                 penetrationVector.setValue(btScalar(0.), btScalar(0.), btScalar(-1.));
284                                 break;
285                         default:
286                                 btAssert(0);
287                 }
288         }
289 };
290
291 #endif  //BT_OBB_BOX_MINKOWSKI_H