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