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;
113 long ptIndex = vec.maxDot( points, numPoints, maxDot);
114 btAssert(ptIndex >= 0);
115 btVector3 supVec = points[ptIndex] * localScaling;
120 btVector3 btConvexShape::localGetSupportVertexWithoutMarginNonVirtual (const btVector3& localDir) const
124 case SPHERE_SHAPE_PROXYTYPE:
126 return btVector3(0,0,0);
128 case BOX_SHAPE_PROXYTYPE:
130 btBoxShape* convexShape = (btBoxShape*)this;
131 const btVector3& halfExtents = convexShape->getImplicitShapeDimensions();
133 #if defined( __APPLE__ ) && (defined( BT_USE_SSE )||defined( BT_USE_NEON ))
134 #if defined( BT_USE_SSE )
135 return btVector3( _mm_xor_ps( _mm_and_ps( localDir.mVec128, (__m128){-0.0f, -0.0f, -0.0f, -0.0f }), halfExtents.mVec128 ));
136 #elif defined( BT_USE_NEON )
137 return btVector3( (float32x4_t) (((uint32x4_t) localDir.mVec128 & (uint32x4_t){ 0x80000000, 0x80000000, 0x80000000, 0x80000000}) ^ (uint32x4_t) halfExtents.mVec128 ));
139 #error unknown vector arch
142 return btVector3(btFsels(localDir.x(), halfExtents.x(), -halfExtents.x()),
143 btFsels(localDir.y(), halfExtents.y(), -halfExtents.y()),
144 btFsels(localDir.z(), halfExtents.z(), -halfExtents.z()));
147 case TRIANGLE_SHAPE_PROXYTYPE:
149 btTriangleShape* triangleShape = (btTriangleShape*)this;
150 btVector3 dir(localDir.getX(),localDir.getY(),localDir.getZ());
151 btVector3* vertices = &triangleShape->m_vertices1[0];
152 btVector3 dots = dir.dot3(vertices[0], vertices[1], vertices[2]);
153 btVector3 sup = vertices[dots.maxAxis()];
154 return btVector3(sup.getX(),sup.getY(),sup.getZ());
156 case CYLINDER_SHAPE_PROXYTYPE:
158 btCylinderShape* cylShape = (btCylinderShape*)this;
159 //mapping of halfextents/dimension onto radius/height depends on how cylinder local orientation is (upAxis)
161 btVector3 halfExtents = cylShape->getImplicitShapeDimensions();
162 btVector3 v(localDir.getX(),localDir.getY(),localDir.getZ());
163 int cylinderUpAxis = cylShape->getUpAxis();
164 int XX(1),YY(0),ZZ(2);
166 switch (cylinderUpAxis)
195 btScalar radius = halfExtents[XX];
196 btScalar halfHeight = halfExtents[cylinderUpAxis];
201 btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
202 if (s != btScalar(0.0))
206 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
208 return btVector3(tmp.getX(),tmp.getY(),tmp.getZ());
211 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
212 tmp[ZZ] = btScalar(0.0);
213 return btVector3(tmp.getX(),tmp.getY(),tmp.getZ());
216 case CAPSULE_SHAPE_PROXYTYPE:
218 btVector3 vec0(localDir.getX(),localDir.getY(),localDir.getZ());
220 btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
221 btScalar halfHeight = capsuleShape->getHalfHeight();
222 int capsuleUpAxis = capsuleShape->getUpAxis();
224 btScalar radius = capsuleShape->getRadius();
225 btVector3 supVec(0,0,0);
227 btScalar maxDot(btScalar(-BT_LARGE_FLOAT));
229 btVector3 vec = vec0;
230 btScalar lenSqr = vec.length2();
231 if (lenSqr < btScalar(0.0001))
236 btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
242 btVector3 pos(0,0,0);
243 pos[capsuleUpAxis] = halfHeight;
245 //vtx = pos +vec*(radius);
246 vtx = pos +vec*(radius) - vec * capsuleShape->getMarginNV();
247 newDot = vec.dot(vtx);
257 btVector3 pos(0,0,0);
258 pos[capsuleUpAxis] = -halfHeight;
260 //vtx = pos +vec*(radius);
261 vtx = pos +vec*(radius) - vec * capsuleShape->getMarginNV();
262 newDot = vec.dot(vtx);
269 return btVector3(supVec.getX(),supVec.getY(),supVec.getZ());
271 case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
273 btConvexPointCloudShape* convexPointCloudShape = (btConvexPointCloudShape*)this;
274 btVector3* points = convexPointCloudShape->getUnscaledPoints ();
275 int numPoints = convexPointCloudShape->getNumPoints ();
276 return convexHullSupport (localDir, points, numPoints,convexPointCloudShape->getLocalScalingNV());
278 case CONVEX_HULL_SHAPE_PROXYTYPE:
280 btConvexHullShape* convexHullShape = (btConvexHullShape*)this;
281 btVector3* points = convexHullShape->getUnscaledPoints();
282 int numPoints = convexHullShape->getNumPoints ();
283 return convexHullSupport (localDir, points, numPoints,convexHullShape->getLocalScalingNV());
287 return this->localGetSupportingVertexWithoutMargin (localDir);
293 // should never reach here
295 return btVector3 (btScalar(0.0f), btScalar(0.0f), btScalar(0.0f));
298 btVector3 btConvexShape::localGetSupportVertexNonVirtual (const btVector3& localDir) const
300 btVector3 localDirNorm = localDir;
301 if (localDirNorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
303 localDirNorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
305 localDirNorm.normalize ();
307 return localGetSupportVertexWithoutMarginNonVirtual(localDirNorm)+ getMarginNonVirtual() * localDirNorm;
310 /* TODO: This should be bumped up to btCollisionShape () */
311 btScalar btConvexShape::getMarginNonVirtual () const
315 case SPHERE_SHAPE_PROXYTYPE:
317 btSphereShape* sphereShape = (btSphereShape*)this;
318 return sphereShape->getRadius ();
320 case BOX_SHAPE_PROXYTYPE:
322 btBoxShape* convexShape = (btBoxShape*)this;
323 return convexShape->getMarginNV ();
325 case TRIANGLE_SHAPE_PROXYTYPE:
327 btTriangleShape* triangleShape = (btTriangleShape*)this;
328 return triangleShape->getMarginNV ();
330 case CYLINDER_SHAPE_PROXYTYPE:
332 btCylinderShape* cylShape = (btCylinderShape*)this;
333 return cylShape->getMarginNV();
335 case CAPSULE_SHAPE_PROXYTYPE:
337 btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
338 return capsuleShape->getMarginNV();
340 case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
342 case CONVEX_HULL_SHAPE_PROXYTYPE:
344 btPolyhedralConvexShape* convexHullShape = (btPolyhedralConvexShape*)this;
345 return convexHullShape->getMarginNV();
349 return this->getMargin ();
355 // should never reach here
357 return btScalar(0.0f);
360 void btConvexShape::getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
364 case SPHERE_SHAPE_PROXYTYPE:
366 btSphereShape* sphereShape = (btSphereShape*)this;
367 btScalar radius = sphereShape->getImplicitShapeDimensions().getX();// * convexShape->getLocalScaling().getX();
368 btScalar margin = radius + sphereShape->getMarginNonVirtual();
369 const btVector3& center = t.getOrigin();
370 btVector3 extent(margin,margin,margin);
371 aabbMin = center - extent;
372 aabbMax = center + extent;
375 case CYLINDER_SHAPE_PROXYTYPE:
377 case BOX_SHAPE_PROXYTYPE:
379 btBoxShape* convexShape = (btBoxShape*)this;
380 btScalar margin=convexShape->getMarginNonVirtual();
381 btVector3 halfExtents = convexShape->getImplicitShapeDimensions();
382 halfExtents += btVector3(margin,margin,margin);
383 btMatrix3x3 abs_b = t.getBasis().absolute();
384 btVector3 center = t.getOrigin();
385 btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
387 aabbMin = center - extent;
388 aabbMax = center + extent;
391 case TRIANGLE_SHAPE_PROXYTYPE:
393 btTriangleShape* triangleShape = (btTriangleShape*)this;
394 btScalar margin = triangleShape->getMarginNonVirtual();
395 for (int i=0;i<3;i++)
397 btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
398 vec[i] = btScalar(1.);
400 btVector3 sv = localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis());
402 btVector3 tmp = t(sv);
403 aabbMax[i] = tmp[i]+margin;
404 vec[i] = btScalar(-1.);
405 tmp = t(localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis()));
406 aabbMin[i] = tmp[i]-margin;
410 case CAPSULE_SHAPE_PROXYTYPE:
412 btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
413 btVector3 halfExtents(capsuleShape->getRadius(),capsuleShape->getRadius(),capsuleShape->getRadius());
414 int m_upAxis = capsuleShape->getUpAxis();
415 halfExtents[m_upAxis] = capsuleShape->getRadius() + capsuleShape->getHalfHeight();
416 halfExtents += btVector3(capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual());
417 btMatrix3x3 abs_b = t.getBasis().absolute();
418 btVector3 center = t.getOrigin();
419 btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
420 aabbMin = center - extent;
421 aabbMax = center + extent;
424 case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
425 case CONVEX_HULL_SHAPE_PROXYTYPE:
427 btPolyhedralConvexAabbCachingShape* convexHullShape = (btPolyhedralConvexAabbCachingShape*)this;
428 btScalar margin = convexHullShape->getMarginNonVirtual();
429 convexHullShape->getNonvirtualAabb (t, aabbMin, aabbMax, margin);
434 this->getAabb (t, aabbMin, aabbMax);
441 // should never reach here