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 #if defined(_WIN32) || defined(__i386__)
17 #define BT_USE_SSE_IN_API
20 #include "btConvexShape.h"
21 #include "btTriangleShape.h"
22 #include "btSphereShape.h"
23 #include "btCylinderShape.h"
24 #include "btConeShape.h"
25 #include "btCapsuleShape.h"
26 #include "btConvexHullShape.h"
27 #include "btConvexPointCloudShape.h"
29 ///not supported on IBM SDK, until we fix the alignment of btVector3
30 #if defined(__CELLOS_LV2__) && defined(__SPU__)
31 #include <spu_intrinsics.h>
32 static inline vec_float4 vec_dot3(vec_float4 vec0, vec_float4 vec1)
35 result = spu_mul(vec0, vec1);
36 result = spu_madd(spu_rlqwbyte(vec0, 4), spu_rlqwbyte(vec1, 4), result);
37 return spu_madd(spu_rlqwbyte(vec0, 8), spu_rlqwbyte(vec1, 8), result);
41 btConvexShape::btConvexShape()
45 btConvexShape::~btConvexShape()
49 void btConvexShape::project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max, btVector3& witnesPtMin, btVector3& witnesPtMax) const
51 btVector3 localAxis = dir * trans.getBasis();
52 btVector3 vtx1 = trans(localGetSupportingVertex(localAxis));
53 btVector3 vtx2 = trans(localGetSupportingVertex(-localAxis));
70 static btVector3 convexHullSupport(const btVector3& localDirOrg, const btVector3* points, int numPoints, const btVector3& localScaling)
72 btVector3 vec = localDirOrg * localScaling;
74 #if defined(__CELLOS_LV2__) && defined(__SPU__)
76 btVector3 localDir = vec;
78 vec_float4 v_distMax = {-FLT_MAX, 0, 0, 0};
79 vec_int4 v_idxMax = {-999, 0, 0, 0};
81 int numverts = numPoints;
83 for (; v < (int)numverts - 4; v += 4)
85 vec_float4 p0 = vec_dot3(points[v].get128(), localDir.get128());
86 vec_float4 p1 = vec_dot3(points[v + 1].get128(), localDir.get128());
87 vec_float4 p2 = vec_dot3(points[v + 2].get128(), localDir.get128());
88 vec_float4 p3 = vec_dot3(points[v + 3].get128(), localDir.get128());
89 const vec_int4 i0 = {v, 0, 0, 0};
90 const vec_int4 i1 = {v + 1, 0, 0, 0};
91 const vec_int4 i2 = {v + 2, 0, 0, 0};
92 const vec_int4 i3 = {v + 3, 0, 0, 0};
93 vec_uint4 retGt01 = spu_cmpgt(p0, p1);
94 vec_float4 pmax01 = spu_sel(p1, p0, retGt01);
95 vec_int4 imax01 = spu_sel(i1, i0, retGt01);
96 vec_uint4 retGt23 = spu_cmpgt(p2, p3);
97 vec_float4 pmax23 = spu_sel(p3, p2, retGt23);
98 vec_int4 imax23 = spu_sel(i3, i2, retGt23);
99 vec_uint4 retGt0123 = spu_cmpgt(pmax01, pmax23);
100 vec_float4 pmax0123 = spu_sel(pmax23, pmax01, retGt0123);
101 vec_int4 imax0123 = spu_sel(imax23, imax01, retGt0123);
102 vec_uint4 retGtMax = spu_cmpgt(v_distMax, pmax0123);
103 v_distMax = spu_sel(pmax0123, v_distMax, retGtMax);
104 v_idxMax = spu_sel(imax0123, v_idxMax, retGtMax);
106 for (; v < (int)numverts; v++)
108 vec_float4 p = vec_dot3(points[v].get128(), localDir.get128());
109 const vec_int4 i = {v, 0, 0, 0};
110 vec_uint4 retGtMax = spu_cmpgt(v_distMax, p);
111 v_distMax = spu_sel(p, v_distMax, retGtMax);
112 v_idxMax = spu_sel(i, v_idxMax, retGtMax);
114 int ptIndex = spu_extract(v_idxMax, 0);
115 const btVector3& supVec = points[ptIndex] * localScaling;
120 long ptIndex = vec.maxDot(points, numPoints, maxDot);
121 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 #if defined(__APPLE__) && (defined(BT_USE_SSE) || defined(BT_USE_NEON))
145 #if defined(BT_USE_SSE)
146 return btVector3(_mm_xor_ps(_mm_and_ps(localDir.mVec128, (__m128){-0.0f, -0.0f, -0.0f, -0.0f}), halfExtents.mVec128));
147 #elif defined(BT_USE_NEON)
148 return btVector3((float32x4_t)(((uint32x4_t)localDir.mVec128 & (uint32x4_t){0x80000000, 0x80000000, 0x80000000, 0x80000000}) ^ (uint32x4_t)halfExtents.mVec128));
150 #error unknown vector arch
153 return btVector3(btFsels(localDir.x(), halfExtents.x(), -halfExtents.x()),
154 btFsels(localDir.y(), halfExtents.y(), -halfExtents.y()),
155 btFsels(localDir.z(), halfExtents.z(), -halfExtents.z()));
158 case TRIANGLE_SHAPE_PROXYTYPE:
160 btTriangleShape* triangleShape = (btTriangleShape*)this;
161 btVector3 dir(localDir.getX(), localDir.getY(), localDir.getZ());
162 btVector3* vertices = &triangleShape->m_vertices1[0];
163 btVector3 dots = dir.dot3(vertices[0], vertices[1], vertices[2]);
164 btVector3 sup = vertices[dots.maxAxis()];
165 return btVector3(sup.getX(), sup.getY(), sup.getZ());
167 case CYLINDER_SHAPE_PROXYTYPE:
169 btCylinderShape* cylShape = (btCylinderShape*)this;
170 //mapping of halfextents/dimension onto radius/height depends on how cylinder local orientation is (upAxis)
172 btVector3 halfExtents = cylShape->getImplicitShapeDimensions();
173 btVector3 v(localDir.getX(), localDir.getY(), localDir.getZ());
174 int cylinderUpAxis = cylShape->getUpAxis();
175 int XX(1), YY(0), ZZ(2);
177 switch (cylinderUpAxis)
205 btScalar radius = halfExtents[XX];
206 btScalar halfHeight = halfExtents[cylinderUpAxis];
211 btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
212 if (s != btScalar(0.0))
216 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
218 return btVector3(tmp.getX(), tmp.getY(), tmp.getZ());
223 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
224 tmp[ZZ] = btScalar(0.0);
225 return btVector3(tmp.getX(), tmp.getY(), tmp.getZ());
228 case CAPSULE_SHAPE_PROXYTYPE:
230 btVector3 vec0(localDir.getX(), localDir.getY(), localDir.getZ());
232 btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
233 btScalar halfHeight = capsuleShape->getHalfHeight();
234 int capsuleUpAxis = capsuleShape->getUpAxis();
236 btVector3 supVec(0, 0, 0);
238 btScalar maxDot(btScalar(-BT_LARGE_FLOAT));
240 btVector3 vec = vec0;
241 btScalar lenSqr = vec.length2();
242 if (lenSqr < SIMD_EPSILON * SIMD_EPSILON)
244 vec.setValue(1, 0, 0);
248 btScalar rlen = btScalar(1.) / btSqrt(lenSqr);
254 btVector3 pos(0, 0, 0);
255 pos[capsuleUpAxis] = halfHeight;
258 newDot = vec.dot(vtx);
267 btVector3 pos(0, 0, 0);
268 pos[capsuleUpAxis] = -halfHeight;
271 newDot = vec.dot(vtx);
278 return btVector3(supVec.getX(), supVec.getY(), supVec.getZ());
280 case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
282 btConvexPointCloudShape* convexPointCloudShape = (btConvexPointCloudShape*)this;
283 btVector3* points = convexPointCloudShape->getUnscaledPoints();
284 int numPoints = convexPointCloudShape->getNumPoints();
285 return convexHullSupport(localDir, points, numPoints, convexPointCloudShape->getLocalScalingNV());
287 case CONVEX_HULL_SHAPE_PROXYTYPE:
289 btConvexHullShape* convexHullShape = (btConvexHullShape*)this;
290 btVector3* points = convexHullShape->getUnscaledPoints();
291 int numPoints = convexHullShape->getNumPoints();
292 return convexHullSupport(localDir, points, numPoints, convexHullShape->getLocalScalingNV());
296 return this->localGetSupportingVertexWithoutMargin(localDir);
302 // should never reach here
304 return btVector3(btScalar(0.0f), btScalar(0.0f), btScalar(0.0f));
307 btVector3 btConvexShape::localGetSupportVertexNonVirtual(const btVector3& localDir) const
309 btVector3 localDirNorm = localDir;
310 if (localDirNorm.length2() < (SIMD_EPSILON * SIMD_EPSILON))
312 localDirNorm.setValue(btScalar(-1.), btScalar(-1.), btScalar(-1.));
314 localDirNorm.normalize();
316 return localGetSupportVertexWithoutMarginNonVirtual(localDirNorm) + getMarginNonVirtual() * localDirNorm;
319 /* TODO: This should be bumped up to btCollisionShape () */
320 btScalar btConvexShape::getMarginNonVirtual() const
324 case SPHERE_SHAPE_PROXYTYPE:
326 btSphereShape* sphereShape = (btSphereShape*)this;
327 return sphereShape->getRadius();
329 case BOX_SHAPE_PROXYTYPE:
331 btBoxShape* convexShape = (btBoxShape*)this;
332 return convexShape->getMarginNV();
334 case TRIANGLE_SHAPE_PROXYTYPE:
336 btTriangleShape* triangleShape = (btTriangleShape*)this;
337 return triangleShape->getMarginNV();
339 case CYLINDER_SHAPE_PROXYTYPE:
341 btCylinderShape* cylShape = (btCylinderShape*)this;
342 return cylShape->getMarginNV();
344 case CONE_SHAPE_PROXYTYPE:
346 btConeShape* conShape = (btConeShape*)this;
347 return conShape->getMarginNV();
349 case CAPSULE_SHAPE_PROXYTYPE:
351 btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
352 return capsuleShape->getMarginNV();
354 case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
356 case CONVEX_HULL_SHAPE_PROXYTYPE:
358 btPolyhedralConvexShape* convexHullShape = (btPolyhedralConvexShape*)this;
359 return convexHullShape->getMarginNV();
363 return this->getMargin();
369 // should never reach here
371 return btScalar(0.0f);
374 void btConvexShape::getAabbNonVirtual(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
378 case SPHERE_SHAPE_PROXYTYPE:
380 btSphereShape* sphereShape = (btSphereShape*)this;
381 btScalar radius = sphereShape->getImplicitShapeDimensions().getX(); // * convexShape->getLocalScaling().getX();
382 btScalar margin = radius + sphereShape->getMarginNonVirtual();
383 const btVector3& center = t.getOrigin();
384 btVector3 extent(margin, margin, margin);
385 aabbMin = center - extent;
386 aabbMax = center + extent;
389 case CYLINDER_SHAPE_PROXYTYPE:
391 case BOX_SHAPE_PROXYTYPE:
393 btBoxShape* convexShape = (btBoxShape*)this;
394 btScalar margin = convexShape->getMarginNonVirtual();
395 btVector3 halfExtents = convexShape->getImplicitShapeDimensions();
396 halfExtents += btVector3(margin, margin, margin);
397 btMatrix3x3 abs_b = t.getBasis().absolute();
398 btVector3 center = t.getOrigin();
399 btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
401 aabbMin = center - extent;
402 aabbMax = center + extent;
405 case TRIANGLE_SHAPE_PROXYTYPE:
407 btTriangleShape* triangleShape = (btTriangleShape*)this;
408 btScalar margin = triangleShape->getMarginNonVirtual();
409 for (int i = 0; i < 3; i++)
411 btVector3 vec(btScalar(0.), btScalar(0.), btScalar(0.));
412 vec[i] = btScalar(1.);
414 btVector3 sv = localGetSupportVertexWithoutMarginNonVirtual(vec * t.getBasis());
416 btVector3 tmp = t(sv);
417 aabbMax[i] = tmp[i] + margin;
418 vec[i] = btScalar(-1.);
419 tmp = t(localGetSupportVertexWithoutMarginNonVirtual(vec * t.getBasis()));
420 aabbMin[i] = tmp[i] - margin;
424 case CAPSULE_SHAPE_PROXYTYPE:
426 btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
427 btVector3 halfExtents(capsuleShape->getRadius(), capsuleShape->getRadius(), capsuleShape->getRadius());
428 int m_upAxis = capsuleShape->getUpAxis();
429 halfExtents[m_upAxis] = capsuleShape->getRadius() + capsuleShape->getHalfHeight();
430 btMatrix3x3 abs_b = t.getBasis().absolute();
431 btVector3 center = t.getOrigin();
432 btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
433 aabbMin = center - extent;
434 aabbMax = center + extent;
437 case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
438 case CONVEX_HULL_SHAPE_PROXYTYPE:
440 btPolyhedralConvexAabbCachingShape* convexHullShape = (btPolyhedralConvexAabbCachingShape*)this;
441 btScalar margin = convexHullShape->getMarginNonVirtual();
442 convexHullShape->getNonvirtualAabb(t, aabbMin, aabbMax, margin);
447 this->getAabb(t, aabbMin, aabbMax);
454 // should never reach here