2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
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:
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.
16 #include "btConvexShape.h"
17 #include "btTriangleShape.h"
18 #include "btSphereShape.h"
19 #include "btCylinderShape.h"
20 #include "btCapsuleShape.h"
21 #include "btConvexHullShape.h"
22 #include "btConvexPointCloudShape.h"
24 ///not supported on IBM SDK, until we fix the alignment of btVector3
25 #if defined (__CELLOS_LV2__) && defined (__SPU__)
26 #include <spu_intrinsics.h>
27 static inline vec_float4 vec_dot3( vec_float4 vec0, vec_float4 vec1 )
30 result = spu_mul( vec0, vec1 );
31 result = spu_madd( spu_rlqwbyte( vec0, 4 ), spu_rlqwbyte( vec1, 4 ), result );
32 return spu_madd( spu_rlqwbyte( vec0, 8 ), spu_rlqwbyte( vec1, 8 ), result );
36 btConvexShape::btConvexShape ()
40 btConvexShape::~btConvexShape()
46 void btConvexShape::project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max) const
48 btVector3 localAxis = dir*trans.getBasis();
49 btVector3 vtx1 = trans(localGetSupportingVertex(localAxis));
50 btVector3 vtx2 = trans(localGetSupportingVertex(-localAxis));
64 static btVector3 convexHullSupport (const btVector3& localDirOrg, const btVector3* points, int numPoints, const btVector3& localScaling)
67 btVector3 vec = localDirOrg * localScaling;
69 #if defined (__CELLOS_LV2__) && defined (__SPU__)
71 btVector3 localDir = vec;
73 vec_float4 v_distMax = {-FLT_MAX,0,0,0};
74 vec_int4 v_idxMax = {-999,0,0,0};
76 int numverts = numPoints;
78 for(;v<(int)numverts-4;v+=4) {
79 vec_float4 p0 = vec_dot3(points[v ].get128(),localDir.get128());
80 vec_float4 p1 = vec_dot3(points[v+1].get128(),localDir.get128());
81 vec_float4 p2 = vec_dot3(points[v+2].get128(),localDir.get128());
82 vec_float4 p3 = vec_dot3(points[v+3].get128(),localDir.get128());
83 const vec_int4 i0 = {v ,0,0,0};
84 const vec_int4 i1 = {v+1,0,0,0};
85 const vec_int4 i2 = {v+2,0,0,0};
86 const vec_int4 i3 = {v+3,0,0,0};
87 vec_uint4 retGt01 = spu_cmpgt(p0,p1);
88 vec_float4 pmax01 = spu_sel(p1,p0,retGt01);
89 vec_int4 imax01 = spu_sel(i1,i0,retGt01);
90 vec_uint4 retGt23 = spu_cmpgt(p2,p3);
91 vec_float4 pmax23 = spu_sel(p3,p2,retGt23);
92 vec_int4 imax23 = spu_sel(i3,i2,retGt23);
93 vec_uint4 retGt0123 = spu_cmpgt(pmax01,pmax23);
94 vec_float4 pmax0123 = spu_sel(pmax23,pmax01,retGt0123);
95 vec_int4 imax0123 = spu_sel(imax23,imax01,retGt0123);
96 vec_uint4 retGtMax = spu_cmpgt(v_distMax,pmax0123);
97 v_distMax = spu_sel(pmax0123,v_distMax,retGtMax);
98 v_idxMax = spu_sel(imax0123,v_idxMax,retGtMax);
100 for(;v<(int)numverts;v++) {
101 vec_float4 p = vec_dot3(points[v].get128(),localDir.get128());
102 const vec_int4 i = {v,0,0,0};
103 vec_uint4 retGtMax = spu_cmpgt(v_distMax,p);
104 v_distMax = spu_sel(p,v_distMax,retGtMax);
105 v_idxMax = spu_sel(i,v_idxMax,retGtMax);
107 int ptIndex = spu_extract(v_idxMax,0);
108 const btVector3& supVec= points[ptIndex] * localScaling;
112 btScalar newDot,maxDot = btScalar(-BT_LARGE_FLOAT);
115 for (int i=0;i<numPoints;i++)
118 newDot = vec.dot(points[i]);
125 btAssert(ptIndex >= 0);
126 btVector3 supVec = points[ptIndex] * localScaling;
131 btVector3 btConvexShape::localGetSupportVertexWithoutMarginNonVirtual (const btVector3& localDir) const
135 case SPHERE_SHAPE_PROXYTYPE:
137 return btVector3(0,0,0);
139 case BOX_SHAPE_PROXYTYPE:
141 btBoxShape* convexShape = (btBoxShape*)this;
142 const btVector3& halfExtents = convexShape->getImplicitShapeDimensions();
144 return btVector3(btFsels(localDir.x(), halfExtents.x(), -halfExtents.x()),
145 btFsels(localDir.y(), halfExtents.y(), -halfExtents.y()),
146 btFsels(localDir.z(), halfExtents.z(), -halfExtents.z()));
148 case TRIANGLE_SHAPE_PROXYTYPE:
150 btTriangleShape* triangleShape = (btTriangleShape*)this;
151 btVector3 dir(localDir.getX(),localDir.getY(),localDir.getZ());
152 btVector3* vertices = &triangleShape->m_vertices1[0];
153 btVector3 dots(dir.dot(vertices[0]), dir.dot(vertices[1]), dir.dot(vertices[2]));
154 btVector3 sup = vertices[dots.maxAxis()];
155 return btVector3(sup.getX(),sup.getY(),sup.getZ());
157 case CYLINDER_SHAPE_PROXYTYPE:
159 btCylinderShape* cylShape = (btCylinderShape*)this;
160 //mapping of halfextents/dimension onto radius/height depends on how cylinder local orientation is (upAxis)
162 btVector3 halfExtents = cylShape->getImplicitShapeDimensions();
163 btVector3 v(localDir.getX(),localDir.getY(),localDir.getZ());
164 int cylinderUpAxis = cylShape->getUpAxis();
165 int XX(1),YY(0),ZZ(2);
167 switch (cylinderUpAxis)
196 btScalar radius = halfExtents[XX];
197 btScalar halfHeight = halfExtents[cylinderUpAxis];
202 btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
203 if (s != btScalar(0.0))
207 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
209 return btVector3(tmp.getX(),tmp.getY(),tmp.getZ());
212 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
213 tmp[ZZ] = btScalar(0.0);
214 return btVector3(tmp.getX(),tmp.getY(),tmp.getZ());
217 case CAPSULE_SHAPE_PROXYTYPE:
219 btVector3 vec0(localDir.getX(),localDir.getY(),localDir.getZ());
221 btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
222 btScalar halfHeight = capsuleShape->getHalfHeight();
223 int capsuleUpAxis = capsuleShape->getUpAxis();
225 btScalar radius = capsuleShape->getRadius();
226 btVector3 supVec(0,0,0);
228 btScalar maxDot(btScalar(-BT_LARGE_FLOAT));
230 btVector3 vec = vec0;
231 btScalar lenSqr = vec.length2();
232 if (lenSqr < btScalar(0.0001))
237 btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
243 btVector3 pos(0,0,0);
244 pos[capsuleUpAxis] = halfHeight;
246 //vtx = pos +vec*(radius);
247 vtx = pos +vec*(radius) - vec * capsuleShape->getMarginNV();
248 newDot = vec.dot(vtx);
258 btVector3 pos(0,0,0);
259 pos[capsuleUpAxis] = -halfHeight;
261 //vtx = pos +vec*(radius);
262 vtx = pos +vec*(radius) - vec * capsuleShape->getMarginNV();
263 newDot = vec.dot(vtx);
270 return btVector3(supVec.getX(),supVec.getY(),supVec.getZ());
272 case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
274 btConvexPointCloudShape* convexPointCloudShape = (btConvexPointCloudShape*)this;
275 btVector3* points = convexPointCloudShape->getUnscaledPoints ();
276 int numPoints = convexPointCloudShape->getNumPoints ();
277 return convexHullSupport (localDir, points, numPoints,convexPointCloudShape->getLocalScalingNV());
279 case CONVEX_HULL_SHAPE_PROXYTYPE:
281 btConvexHullShape* convexHullShape = (btConvexHullShape*)this;
282 btVector3* points = convexHullShape->getUnscaledPoints();
283 int numPoints = convexHullShape->getNumPoints ();
284 return convexHullSupport (localDir, points, numPoints,convexHullShape->getLocalScalingNV());
288 return this->localGetSupportingVertexWithoutMargin (localDir);
294 // should never reach here
296 return btVector3 (btScalar(0.0f), btScalar(0.0f), btScalar(0.0f));
299 btVector3 btConvexShape::localGetSupportVertexNonVirtual (const btVector3& localDir) const
301 btVector3 localDirNorm = localDir;
302 if (localDirNorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
304 localDirNorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
306 localDirNorm.normalize ();
308 return localGetSupportVertexWithoutMarginNonVirtual(localDirNorm)+ getMarginNonVirtual() * localDirNorm;
311 /* TODO: This should be bumped up to btCollisionShape () */
312 btScalar btConvexShape::getMarginNonVirtual () const
316 case SPHERE_SHAPE_PROXYTYPE:
318 btSphereShape* sphereShape = (btSphereShape*)this;
319 return sphereShape->getRadius ();
321 case BOX_SHAPE_PROXYTYPE:
323 btBoxShape* convexShape = (btBoxShape*)this;
324 return convexShape->getMarginNV ();
326 case TRIANGLE_SHAPE_PROXYTYPE:
328 btTriangleShape* triangleShape = (btTriangleShape*)this;
329 return triangleShape->getMarginNV ();
331 case CYLINDER_SHAPE_PROXYTYPE:
333 btCylinderShape* cylShape = (btCylinderShape*)this;
334 return cylShape->getMarginNV();
336 case CAPSULE_SHAPE_PROXYTYPE:
338 btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
339 return capsuleShape->getMarginNV();
341 case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
343 case CONVEX_HULL_SHAPE_PROXYTYPE:
345 btPolyhedralConvexShape* convexHullShape = (btPolyhedralConvexShape*)this;
346 return convexHullShape->getMarginNV();
350 return this->getMargin ();
356 // should never reach here
358 return btScalar(0.0f);
361 void btConvexShape::getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
365 case SPHERE_SHAPE_PROXYTYPE:
367 btSphereShape* sphereShape = (btSphereShape*)this;
368 btScalar radius = sphereShape->getImplicitShapeDimensions().getX();// * convexShape->getLocalScaling().getX();
369 btScalar margin = radius + sphereShape->getMarginNonVirtual();
370 const btVector3& center = t.getOrigin();
371 btVector3 extent(margin,margin,margin);
372 aabbMin = center - extent;
373 aabbMax = center + extent;
376 case CYLINDER_SHAPE_PROXYTYPE:
378 case BOX_SHAPE_PROXYTYPE:
380 btBoxShape* convexShape = (btBoxShape*)this;
381 btScalar margin=convexShape->getMarginNonVirtual();
382 btVector3 halfExtents = convexShape->getImplicitShapeDimensions();
383 halfExtents += btVector3(margin,margin,margin);
384 btMatrix3x3 abs_b = t.getBasis().absolute();
385 btVector3 center = t.getOrigin();
386 btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
388 aabbMin = center - extent;
389 aabbMax = center + extent;
392 case TRIANGLE_SHAPE_PROXYTYPE:
394 btTriangleShape* triangleShape = (btTriangleShape*)this;
395 btScalar margin = triangleShape->getMarginNonVirtual();
396 for (int i=0;i<3;i++)
398 btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
399 vec[i] = btScalar(1.);
401 btVector3 sv = localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis());
403 btVector3 tmp = t(sv);
404 aabbMax[i] = tmp[i]+margin;
405 vec[i] = btScalar(-1.);
406 tmp = t(localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis()));
407 aabbMin[i] = tmp[i]-margin;
411 case CAPSULE_SHAPE_PROXYTYPE:
413 btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
414 btVector3 halfExtents(capsuleShape->getRadius(),capsuleShape->getRadius(),capsuleShape->getRadius());
415 int m_upAxis = capsuleShape->getUpAxis();
416 halfExtents[m_upAxis] = capsuleShape->getRadius() + capsuleShape->getHalfHeight();
417 halfExtents += btVector3(capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual());
418 btMatrix3x3 abs_b = t.getBasis().absolute();
419 btVector3 center = t.getOrigin();
420 btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
421 aabbMin = center - extent;
422 aabbMax = center + extent;
425 case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
426 case CONVEX_HULL_SHAPE_PROXYTYPE:
428 btPolyhedralConvexAabbCachingShape* convexHullShape = (btPolyhedralConvexAabbCachingShape*)this;
429 btScalar margin = convexHullShape->getMarginNonVirtual();
430 convexHullShape->getNonvirtualAabb (t, aabbMin, aabbMax, margin);
435 this->getAabb (t, aabbMin, aabbMax);
442 // should never reach here