Changeset View
Changeset View
Standalone View
Standalone View
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp
| /* | /* | ||||
| Bullet Continuous Collision Detection and Physics Library | Bullet Continuous Collision Detection and Physics Library | ||||
| Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org | Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org | ||||
| This software is provided 'as-is', without any express or implied warranty. | This software is provided 'as-is', without any express or implied warranty. | ||||
| In no event will the authors be held liable for any damages arising from the use of this software. | In no event will the authors be held liable for any damages arising from the use of this software. | ||||
| Permission is granted to anyone to use this software for any purpose, | Permission is granted to anyone to use this software for any purpose, | ||||
| including commercial applications, and to alter it and redistribute it freely, | including commercial applications, and to alter it and redistribute it freely, | ||||
| subject to the following restrictions: | subject to the following restrictions: | ||||
| 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. | 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. | ||||
| 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. | ||||
| 3. This notice may not be removed or altered from any source distribution. | 3. This notice may not be removed or altered from any source distribution. | ||||
| */ | */ | ||||
| //#if defined (_WIN32) || defined (__i386__) | #if defined(_WIN32) || defined(__i386__) | ||||
| //#define BT_USE_SSE_IN_API | #define BT_USE_SSE_IN_API | ||||
| //#endif | #endif | ||||
| #include "btConvexShape.h" | #include "btConvexShape.h" | ||||
| #include "btTriangleShape.h" | #include "btTriangleShape.h" | ||||
| #include "btSphereShape.h" | #include "btSphereShape.h" | ||||
| #include "btCylinderShape.h" | #include "btCylinderShape.h" | ||||
| #include "btConeShape.h" | #include "btConeShape.h" | ||||
| #include "btCapsuleShape.h" | #include "btCapsuleShape.h" | ||||
| #include "btConvexHullShape.h" | #include "btConvexHullShape.h" | ||||
| #include "btConvexPointCloudShape.h" | #include "btConvexPointCloudShape.h" | ||||
| ///not supported on IBM SDK, until we fix the alignment of btVector3 | ///not supported on IBM SDK, until we fix the alignment of btVector3 | ||||
| #if defined (__CELLOS_LV2__) && defined (__SPU__) | #if defined(__CELLOS_LV2__) && defined(__SPU__) | ||||
| #include <spu_intrinsics.h> | #include <spu_intrinsics.h> | ||||
| static inline vec_float4 vec_dot3( vec_float4 vec0, vec_float4 vec1 ) | static inline vec_float4 vec_dot3(vec_float4 vec0, vec_float4 vec1) | ||||
| { | { | ||||
| vec_float4 result; | vec_float4 result; | ||||
| result = spu_mul( vec0, vec1 ); | result = spu_mul(vec0, vec1); | ||||
| result = spu_madd( spu_rlqwbyte( vec0, 4 ), spu_rlqwbyte( vec1, 4 ), result ); | result = spu_madd(spu_rlqwbyte(vec0, 4), spu_rlqwbyte(vec1, 4), result); | ||||
| return spu_madd( spu_rlqwbyte( vec0, 8 ), spu_rlqwbyte( vec1, 8 ), result ); | return spu_madd(spu_rlqwbyte(vec0, 8), spu_rlqwbyte(vec1, 8), result); | ||||
| } | } | ||||
| #endif //__SPU__ | #endif //__SPU__ | ||||
| btConvexShape::btConvexShape () | btConvexShape::btConvexShape() | ||||
| { | { | ||||
| } | } | ||||
| btConvexShape::~btConvexShape() | btConvexShape::~btConvexShape() | ||||
| { | { | ||||
| } | } | ||||
| void btConvexShape::project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max, btVector3& witnesPtMin,btVector3& witnesPtMax) const | void btConvexShape::project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max, btVector3& witnesPtMin, btVector3& witnesPtMax) const | ||||
| { | { | ||||
| btVector3 localAxis = dir*trans.getBasis(); | btVector3 localAxis = dir * trans.getBasis(); | ||||
| btVector3 vtx1 = trans(localGetSupportingVertex(localAxis)); | btVector3 vtx1 = trans(localGetSupportingVertex(localAxis)); | ||||
| btVector3 vtx2 = trans(localGetSupportingVertex(-localAxis)); | btVector3 vtx2 = trans(localGetSupportingVertex(-localAxis)); | ||||
| min = vtx1.dot(dir); | min = vtx1.dot(dir); | ||||
| max = vtx2.dot(dir); | max = vtx2.dot(dir); | ||||
| witnesPtMax = vtx2; | witnesPtMax = vtx2; | ||||
| witnesPtMin = vtx1; | witnesPtMin = vtx1; | ||||
| if(min>max) | if (min > max) | ||||
| { | { | ||||
| btScalar tmp = min; | btScalar tmp = min; | ||||
| min = max; | min = max; | ||||
| max = tmp; | max = tmp; | ||||
| witnesPtMax = vtx1; | witnesPtMax = vtx1; | ||||
| witnesPtMin = vtx2; | witnesPtMin = vtx2; | ||||
| } | } | ||||
| } | } | ||||
| static btVector3 convexHullSupport (const btVector3& localDirOrg, const btVector3* points, int numPoints, const btVector3& localScaling) | static btVector3 convexHullSupport(const btVector3& localDirOrg, const btVector3* points, int numPoints, const btVector3& localScaling) | ||||
| { | { | ||||
| btVector3 vec = localDirOrg * localScaling; | btVector3 vec = localDirOrg * localScaling; | ||||
| #if defined (__CELLOS_LV2__) && defined (__SPU__) | #if defined(__CELLOS_LV2__) && defined(__SPU__) | ||||
| btVector3 localDir = vec; | btVector3 localDir = vec; | ||||
| vec_float4 v_distMax = {-FLT_MAX,0,0,0}; | vec_float4 v_distMax = {-FLT_MAX, 0, 0, 0}; | ||||
| vec_int4 v_idxMax = {-999,0,0,0}; | vec_int4 v_idxMax = {-999, 0, 0, 0}; | ||||
| int v=0; | int v = 0; | ||||
| int numverts = numPoints; | int numverts = numPoints; | ||||
| for(;v<(int)numverts-4;v+=4) { | for (; v < (int)numverts - 4; v += 4) | ||||
| { | |||||
| vec_float4 p0 = vec_dot3(points[v ].get128(),localDir.get128()); | vec_float4 p0 = vec_dot3(points[v].get128(), localDir.get128()); | ||||
| vec_float4 p1 = vec_dot3(points[v+1].get128(),localDir.get128()); | vec_float4 p1 = vec_dot3(points[v + 1].get128(), localDir.get128()); | ||||
| vec_float4 p2 = vec_dot3(points[v+2].get128(),localDir.get128()); | vec_float4 p2 = vec_dot3(points[v + 2].get128(), localDir.get128()); | ||||
| vec_float4 p3 = vec_dot3(points[v+3].get128(),localDir.get128()); | vec_float4 p3 = vec_dot3(points[v + 3].get128(), localDir.get128()); | ||||
| const vec_int4 i0 = {v ,0,0,0}; | const vec_int4 i0 = {v, 0, 0, 0}; | ||||
| const vec_int4 i1 = {v+1,0,0,0}; | const vec_int4 i1 = {v + 1, 0, 0, 0}; | ||||
| const vec_int4 i2 = {v+2,0,0,0}; | const vec_int4 i2 = {v + 2, 0, 0, 0}; | ||||
| const vec_int4 i3 = {v+3,0,0,0}; | const vec_int4 i3 = {v + 3, 0, 0, 0}; | ||||
| vec_uint4 retGt01 = spu_cmpgt(p0,p1); | vec_uint4 retGt01 = spu_cmpgt(p0, p1); | ||||
| vec_float4 pmax01 = spu_sel(p1,p0,retGt01); | vec_float4 pmax01 = spu_sel(p1, p0, retGt01); | ||||
| vec_int4 imax01 = spu_sel(i1,i0,retGt01); | vec_int4 imax01 = spu_sel(i1, i0, retGt01); | ||||
| vec_uint4 retGt23 = spu_cmpgt(p2,p3); | vec_uint4 retGt23 = spu_cmpgt(p2, p3); | ||||
| vec_float4 pmax23 = spu_sel(p3,p2,retGt23); | vec_float4 pmax23 = spu_sel(p3, p2, retGt23); | ||||
| vec_int4 imax23 = spu_sel(i3,i2,retGt23); | vec_int4 imax23 = spu_sel(i3, i2, retGt23); | ||||
| vec_uint4 retGt0123 = spu_cmpgt(pmax01,pmax23); | vec_uint4 retGt0123 = spu_cmpgt(pmax01, pmax23); | ||||
| vec_float4 pmax0123 = spu_sel(pmax23,pmax01,retGt0123); | vec_float4 pmax0123 = spu_sel(pmax23, pmax01, retGt0123); | ||||
| vec_int4 imax0123 = spu_sel(imax23,imax01,retGt0123); | vec_int4 imax0123 = spu_sel(imax23, imax01, retGt0123); | ||||
| vec_uint4 retGtMax = spu_cmpgt(v_distMax,pmax0123); | vec_uint4 retGtMax = spu_cmpgt(v_distMax, pmax0123); | ||||
| v_distMax = spu_sel(pmax0123,v_distMax,retGtMax); | v_distMax = spu_sel(pmax0123, v_distMax, retGtMax); | ||||
| v_idxMax = spu_sel(imax0123,v_idxMax,retGtMax); | v_idxMax = spu_sel(imax0123, v_idxMax, retGtMax); | ||||
| } | } | ||||
| for(;v<(int)numverts;v++) { | for (; v < (int)numverts; v++) | ||||
| { | |||||
| vec_float4 p = vec_dot3(points[v].get128(),localDir.get128()); | vec_float4 p = vec_dot3(points[v].get128(), localDir.get128()); | ||||
| const vec_int4 i = {v,0,0,0}; | const vec_int4 i = {v, 0, 0, 0}; | ||||
| vec_uint4 retGtMax = spu_cmpgt(v_distMax,p); | vec_uint4 retGtMax = spu_cmpgt(v_distMax, p); | ||||
| v_distMax = spu_sel(p,v_distMax,retGtMax); | v_distMax = spu_sel(p, v_distMax, retGtMax); | ||||
| v_idxMax = spu_sel(i,v_idxMax,retGtMax); | v_idxMax = spu_sel(i, v_idxMax, retGtMax); | ||||
| } | } | ||||
| int ptIndex = spu_extract(v_idxMax,0); | int ptIndex = spu_extract(v_idxMax, 0); | ||||
| const btVector3& supVec= points[ptIndex] * localScaling; | const btVector3& supVec = points[ptIndex] * localScaling; | ||||
| return supVec; | return supVec; | ||||
| #else | #else | ||||
| btScalar maxDot; | btScalar maxDot; | ||||
| long ptIndex = vec.maxDot( points, numPoints, maxDot); | long ptIndex = vec.maxDot(points, numPoints, maxDot); | ||||
| btAssert(ptIndex >= 0); | btAssert(ptIndex >= 0); | ||||
| if (ptIndex < 0) | |||||
| { | |||||
| ptIndex = 0; | |||||
| } | |||||
| btVector3 supVec = points[ptIndex] * localScaling; | btVector3 supVec = points[ptIndex] * localScaling; | ||||
| return supVec; | return supVec; | ||||
| #endif //__SPU__ | #endif //__SPU__ | ||||
| } | } | ||||
| btVector3 btConvexShape::localGetSupportVertexWithoutMarginNonVirtual (const btVector3& localDir) const | btVector3 btConvexShape::localGetSupportVertexWithoutMarginNonVirtual(const btVector3& localDir) const | ||||
| { | { | ||||
| switch (m_shapeType) | switch (m_shapeType) | ||||
| { | { | ||||
| case SPHERE_SHAPE_PROXYTYPE: | case SPHERE_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| return btVector3(0,0,0); | return btVector3(0, 0, 0); | ||||
| } | } | ||||
| case BOX_SHAPE_PROXYTYPE: | case BOX_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btBoxShape* convexShape = (btBoxShape*)this; | btBoxShape* convexShape = (btBoxShape*)this; | ||||
| const btVector3& halfExtents = convexShape->getImplicitShapeDimensions(); | const btVector3& halfExtents = convexShape->getImplicitShapeDimensions(); | ||||
| #if defined( __APPLE__ ) && (defined( BT_USE_SSE )||defined( BT_USE_NEON )) | #if defined(__APPLE__) && (defined(BT_USE_SSE) || defined(BT_USE_NEON)) | ||||
| #if defined( BT_USE_SSE ) | #if defined(BT_USE_SSE) | ||||
| return btVector3( _mm_xor_ps( _mm_and_ps( localDir.mVec128, (__m128){-0.0f, -0.0f, -0.0f, -0.0f }), halfExtents.mVec128 )); | return btVector3(_mm_xor_ps(_mm_and_ps(localDir.mVec128, (__m128){-0.0f, -0.0f, -0.0f, -0.0f}), halfExtents.mVec128)); | ||||
| #elif defined( BT_USE_NEON ) | #elif defined(BT_USE_NEON) | ||||
| return btVector3( (float32x4_t) (((uint32x4_t) localDir.mVec128 & (uint32x4_t){ 0x80000000, 0x80000000, 0x80000000, 0x80000000}) ^ (uint32x4_t) halfExtents.mVec128 )); | return btVector3((float32x4_t)(((uint32x4_t)localDir.mVec128 & (uint32x4_t){0x80000000, 0x80000000, 0x80000000, 0x80000000}) ^ (uint32x4_t)halfExtents.mVec128)); | ||||
| #else | #else | ||||
| #error unknown vector arch | #error unknown vector arch | ||||
| #endif | #endif | ||||
| #else | #else | ||||
| return btVector3(btFsels(localDir.x(), halfExtents.x(), -halfExtents.x()), | return btVector3(btFsels(localDir.x(), halfExtents.x(), -halfExtents.x()), | ||||
| btFsels(localDir.y(), halfExtents.y(), -halfExtents.y()), | btFsels(localDir.y(), halfExtents.y(), -halfExtents.y()), | ||||
| btFsels(localDir.z(), halfExtents.z(), -halfExtents.z())); | btFsels(localDir.z(), halfExtents.z(), -halfExtents.z())); | ||||
| #endif | #endif | ||||
| } | } | ||||
| case TRIANGLE_SHAPE_PROXYTYPE: | case TRIANGLE_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btTriangleShape* triangleShape = (btTriangleShape*)this; | btTriangleShape* triangleShape = (btTriangleShape*)this; | ||||
| btVector3 dir(localDir.getX(),localDir.getY(),localDir.getZ()); | btVector3 dir(localDir.getX(), localDir.getY(), localDir.getZ()); | ||||
| btVector3* vertices = &triangleShape->m_vertices1[0]; | btVector3* vertices = &triangleShape->m_vertices1[0]; | ||||
| btVector3 dots = dir.dot3(vertices[0], vertices[1], vertices[2]); | btVector3 dots = dir.dot3(vertices[0], vertices[1], vertices[2]); | ||||
| btVector3 sup = vertices[dots.maxAxis()]; | btVector3 sup = vertices[dots.maxAxis()]; | ||||
| return btVector3(sup.getX(),sup.getY(),sup.getZ()); | return btVector3(sup.getX(), sup.getY(), sup.getZ()); | ||||
| } | } | ||||
| case CYLINDER_SHAPE_PROXYTYPE: | case CYLINDER_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btCylinderShape* cylShape = (btCylinderShape*)this; | btCylinderShape* cylShape = (btCylinderShape*)this; | ||||
| //mapping of halfextents/dimension onto radius/height depends on how cylinder local orientation is (upAxis) | //mapping of halfextents/dimension onto radius/height depends on how cylinder local orientation is (upAxis) | ||||
| btVector3 halfExtents = cylShape->getImplicitShapeDimensions(); | btVector3 halfExtents = cylShape->getImplicitShapeDimensions(); | ||||
| btVector3 v(localDir.getX(),localDir.getY(),localDir.getZ()); | btVector3 v(localDir.getX(), localDir.getY(), localDir.getZ()); | ||||
| int cylinderUpAxis = cylShape->getUpAxis(); | int cylinderUpAxis = cylShape->getUpAxis(); | ||||
| int XX(1),YY(0),ZZ(2); | int XX(1), YY(0), ZZ(2); | ||||
| switch (cylinderUpAxis) | switch (cylinderUpAxis) | ||||
| { | { | ||||
| case 0: | case 0: | ||||
| { | { | ||||
| XX = 1; | XX = 1; | ||||
| YY = 0; | YY = 0; | ||||
| ZZ = 2; | ZZ = 2; | ||||
| } | } | ||||
| break; | break; | ||||
| case 1: | case 1: | ||||
| { | { | ||||
| XX = 0; | XX = 0; | ||||
| YY = 1; | YY = 1; | ||||
| ZZ = 2; | ZZ = 2; | ||||
| } | } | ||||
| break; | break; | ||||
| case 2: | case 2: | ||||
| { | { | ||||
| XX = 0; | XX = 0; | ||||
| YY = 2; | YY = 2; | ||||
| ZZ = 1; | ZZ = 1; | ||||
| } | } | ||||
| break; | break; | ||||
| default: | default: | ||||
| btAssert(0); | btAssert(0); | ||||
| break; | break; | ||||
| }; | }; | ||||
| btScalar radius = halfExtents[XX]; | btScalar radius = halfExtents[XX]; | ||||
| btScalar halfHeight = halfExtents[cylinderUpAxis]; | btScalar halfHeight = halfExtents[cylinderUpAxis]; | ||||
| btVector3 tmp; | btVector3 tmp; | ||||
| btScalar d ; | btScalar d; | ||||
| btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); | btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); | ||||
| if (s != btScalar(0.0)) | if (s != btScalar(0.0)) | ||||
| { | { | ||||
| d = radius / s; | d = radius / s; | ||||
| tmp[XX] = v[XX] * d; | tmp[XX] = v[XX] * d; | ||||
| tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; | tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; | ||||
| tmp[ZZ] = v[ZZ] * d; | tmp[ZZ] = v[ZZ] * d; | ||||
| return btVector3(tmp.getX(),tmp.getY(),tmp.getZ()); | return btVector3(tmp.getX(), tmp.getY(), tmp.getZ()); | ||||
| } else { | } | ||||
| else | |||||
| { | |||||
| tmp[XX] = radius; | tmp[XX] = radius; | ||||
| tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; | tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; | ||||
| tmp[ZZ] = btScalar(0.0); | tmp[ZZ] = btScalar(0.0); | ||||
| return btVector3(tmp.getX(),tmp.getY(),tmp.getZ()); | return btVector3(tmp.getX(), tmp.getY(), tmp.getZ()); | ||||
| } | } | ||||
| } | } | ||||
| case CAPSULE_SHAPE_PROXYTYPE: | case CAPSULE_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btVector3 vec0(localDir.getX(),localDir.getY(),localDir.getZ()); | btVector3 vec0(localDir.getX(), localDir.getY(), localDir.getZ()); | ||||
| btCapsuleShape* capsuleShape = (btCapsuleShape*)this; | btCapsuleShape* capsuleShape = (btCapsuleShape*)this; | ||||
| btScalar halfHeight = capsuleShape->getHalfHeight(); | btScalar halfHeight = capsuleShape->getHalfHeight(); | ||||
| int capsuleUpAxis = capsuleShape->getUpAxis(); | int capsuleUpAxis = capsuleShape->getUpAxis(); | ||||
| btScalar radius = capsuleShape->getRadius(); | |||||
| btVector3 supVec(0,0,0); | btVector3 supVec(0, 0, 0); | ||||
| btScalar maxDot(btScalar(-BT_LARGE_FLOAT)); | btScalar maxDot(btScalar(-BT_LARGE_FLOAT)); | ||||
| btVector3 vec = vec0; | btVector3 vec = vec0; | ||||
| btScalar lenSqr = vec.length2(); | btScalar lenSqr = vec.length2(); | ||||
| if (lenSqr < btScalar(0.0001)) | if (lenSqr < SIMD_EPSILON * SIMD_EPSILON) | ||||
| { | { | ||||
| vec.setValue(1,0,0); | vec.setValue(1, 0, 0); | ||||
| } else | } | ||||
| else | |||||
| { | { | ||||
| btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); | btScalar rlen = btScalar(1.) / btSqrt(lenSqr); | ||||
| vec *= rlen; | vec *= rlen; | ||||
| } | } | ||||
| btVector3 vtx; | btVector3 vtx; | ||||
| btScalar newDot; | btScalar newDot; | ||||
| { | { | ||||
| btVector3 pos(0,0,0); | btVector3 pos(0, 0, 0); | ||||
| pos[capsuleUpAxis] = halfHeight; | pos[capsuleUpAxis] = halfHeight; | ||||
| //vtx = pos +vec*(radius); | vtx = pos; | ||||
| vtx = pos +vec*(radius) - vec * capsuleShape->getMarginNV(); | |||||
| newDot = vec.dot(vtx); | newDot = vec.dot(vtx); | ||||
| if (newDot > maxDot) | if (newDot > maxDot) | ||||
| { | { | ||||
| maxDot = newDot; | maxDot = newDot; | ||||
| supVec = vtx; | supVec = vtx; | ||||
| } | } | ||||
| } | } | ||||
| { | { | ||||
| btVector3 pos(0,0,0); | btVector3 pos(0, 0, 0); | ||||
| pos[capsuleUpAxis] = -halfHeight; | pos[capsuleUpAxis] = -halfHeight; | ||||
| //vtx = pos +vec*(radius); | vtx = pos; | ||||
| vtx = pos +vec*(radius) - vec * capsuleShape->getMarginNV(); | |||||
| newDot = vec.dot(vtx); | newDot = vec.dot(vtx); | ||||
| if (newDot > maxDot) | if (newDot > maxDot) | ||||
| { | { | ||||
| maxDot = newDot; | maxDot = newDot; | ||||
| supVec = vtx; | supVec = vtx; | ||||
| } | } | ||||
| } | } | ||||
| return btVector3(supVec.getX(),supVec.getY(),supVec.getZ()); | return btVector3(supVec.getX(), supVec.getY(), supVec.getZ()); | ||||
| } | } | ||||
| case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: | case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btConvexPointCloudShape* convexPointCloudShape = (btConvexPointCloudShape*)this; | btConvexPointCloudShape* convexPointCloudShape = (btConvexPointCloudShape*)this; | ||||
| btVector3* points = convexPointCloudShape->getUnscaledPoints (); | btVector3* points = convexPointCloudShape->getUnscaledPoints(); | ||||
| int numPoints = convexPointCloudShape->getNumPoints (); | int numPoints = convexPointCloudShape->getNumPoints(); | ||||
| return convexHullSupport (localDir, points, numPoints,convexPointCloudShape->getLocalScalingNV()); | return convexHullSupport(localDir, points, numPoints, convexPointCloudShape->getLocalScalingNV()); | ||||
| } | } | ||||
| case CONVEX_HULL_SHAPE_PROXYTYPE: | case CONVEX_HULL_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btConvexHullShape* convexHullShape = (btConvexHullShape*)this; | btConvexHullShape* convexHullShape = (btConvexHullShape*)this; | ||||
| btVector3* points = convexHullShape->getUnscaledPoints(); | btVector3* points = convexHullShape->getUnscaledPoints(); | ||||
| int numPoints = convexHullShape->getNumPoints (); | int numPoints = convexHullShape->getNumPoints(); | ||||
| return convexHullSupport (localDir, points, numPoints,convexHullShape->getLocalScalingNV()); | return convexHullSupport(localDir, points, numPoints, convexHullShape->getLocalScalingNV()); | ||||
| } | } | ||||
| default: | default: | ||||
| #ifndef __SPU__ | #ifndef __SPU__ | ||||
| return this->localGetSupportingVertexWithoutMargin (localDir); | return this->localGetSupportingVertexWithoutMargin(localDir); | ||||
| #else | #else | ||||
| btAssert (0); | btAssert(0); | ||||
| #endif | #endif | ||||
| } | } | ||||
| // should never reach here | // should never reach here | ||||
| btAssert (0); | btAssert(0); | ||||
| return btVector3 (btScalar(0.0f), btScalar(0.0f), btScalar(0.0f)); | return btVector3(btScalar(0.0f), btScalar(0.0f), btScalar(0.0f)); | ||||
| } | } | ||||
| btVector3 btConvexShape::localGetSupportVertexNonVirtual (const btVector3& localDir) const | btVector3 btConvexShape::localGetSupportVertexNonVirtual(const btVector3& localDir) const | ||||
| { | { | ||||
| btVector3 localDirNorm = localDir; | btVector3 localDirNorm = localDir; | ||||
| if (localDirNorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) | if (localDirNorm.length2() < (SIMD_EPSILON * SIMD_EPSILON)) | ||||
| { | { | ||||
| localDirNorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); | localDirNorm.setValue(btScalar(-1.), btScalar(-1.), btScalar(-1.)); | ||||
| } | } | ||||
| localDirNorm.normalize (); | localDirNorm.normalize(); | ||||
| return localGetSupportVertexWithoutMarginNonVirtual(localDirNorm)+ getMarginNonVirtual() * localDirNorm; | return localGetSupportVertexWithoutMarginNonVirtual(localDirNorm) + getMarginNonVirtual() * localDirNorm; | ||||
| } | } | ||||
| /* TODO: This should be bumped up to btCollisionShape () */ | /* TODO: This should be bumped up to btCollisionShape () */ | ||||
| btScalar btConvexShape::getMarginNonVirtual () const | btScalar btConvexShape::getMarginNonVirtual() const | ||||
| { | { | ||||
| switch (m_shapeType) | switch (m_shapeType) | ||||
| { | { | ||||
| case SPHERE_SHAPE_PROXYTYPE: | case SPHERE_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btSphereShape* sphereShape = (btSphereShape*)this; | btSphereShape* sphereShape = (btSphereShape*)this; | ||||
| return sphereShape->getRadius (); | return sphereShape->getRadius(); | ||||
| } | } | ||||
| case BOX_SHAPE_PROXYTYPE: | case BOX_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btBoxShape* convexShape = (btBoxShape*)this; | btBoxShape* convexShape = (btBoxShape*)this; | ||||
| return convexShape->getMarginNV (); | return convexShape->getMarginNV(); | ||||
| } | } | ||||
| case TRIANGLE_SHAPE_PROXYTYPE: | case TRIANGLE_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btTriangleShape* triangleShape = (btTriangleShape*)this; | btTriangleShape* triangleShape = (btTriangleShape*)this; | ||||
| return triangleShape->getMarginNV (); | return triangleShape->getMarginNV(); | ||||
| } | } | ||||
| case CYLINDER_SHAPE_PROXYTYPE: | case CYLINDER_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btCylinderShape* cylShape = (btCylinderShape*)this; | btCylinderShape* cylShape = (btCylinderShape*)this; | ||||
| return cylShape->getMarginNV(); | return cylShape->getMarginNV(); | ||||
| } | } | ||||
| case CONE_SHAPE_PROXYTYPE: | case CONE_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btConeShape* conShape = (btConeShape*)this; | btConeShape* conShape = (btConeShape*)this; | ||||
| return conShape->getMarginNV(); | return conShape->getMarginNV(); | ||||
| } | } | ||||
| case CAPSULE_SHAPE_PROXYTYPE: | case CAPSULE_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btCapsuleShape* capsuleShape = (btCapsuleShape*)this; | btCapsuleShape* capsuleShape = (btCapsuleShape*)this; | ||||
| return capsuleShape->getMarginNV(); | return capsuleShape->getMarginNV(); | ||||
| } | } | ||||
| case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: | case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: | ||||
| /* fall through */ | /* fall through */ | ||||
| case CONVEX_HULL_SHAPE_PROXYTYPE: | case CONVEX_HULL_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btPolyhedralConvexShape* convexHullShape = (btPolyhedralConvexShape*)this; | btPolyhedralConvexShape* convexHullShape = (btPolyhedralConvexShape*)this; | ||||
| return convexHullShape->getMarginNV(); | return convexHullShape->getMarginNV(); | ||||
| } | } | ||||
| default: | default: | ||||
| #ifndef __SPU__ | #ifndef __SPU__ | ||||
| return this->getMargin (); | return this->getMargin(); | ||||
| #else | #else | ||||
| btAssert (0); | btAssert(0); | ||||
| #endif | #endif | ||||
| } | } | ||||
| // should never reach here | // should never reach here | ||||
| btAssert (0); | btAssert(0); | ||||
| return btScalar(0.0f); | return btScalar(0.0f); | ||||
| } | } | ||||
| #ifndef __SPU__ | #ifndef __SPU__ | ||||
| void btConvexShape::getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const | void btConvexShape::getAabbNonVirtual(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const | ||||
| { | { | ||||
| switch (m_shapeType) | switch (m_shapeType) | ||||
| { | { | ||||
| case SPHERE_SHAPE_PROXYTYPE: | case SPHERE_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btSphereShape* sphereShape = (btSphereShape*)this; | btSphereShape* sphereShape = (btSphereShape*)this; | ||||
| btScalar radius = sphereShape->getImplicitShapeDimensions().getX();// * convexShape->getLocalScaling().getX(); | btScalar radius = sphereShape->getImplicitShapeDimensions().getX(); // * convexShape->getLocalScaling().getX(); | ||||
| btScalar margin = radius + sphereShape->getMarginNonVirtual(); | btScalar margin = radius + sphereShape->getMarginNonVirtual(); | ||||
| const btVector3& center = t.getOrigin(); | const btVector3& center = t.getOrigin(); | ||||
| btVector3 extent(margin,margin,margin); | btVector3 extent(margin, margin, margin); | ||||
| aabbMin = center - extent; | aabbMin = center - extent; | ||||
| aabbMax = center + extent; | aabbMax = center + extent; | ||||
| } | } | ||||
| break; | break; | ||||
| case CYLINDER_SHAPE_PROXYTYPE: | case CYLINDER_SHAPE_PROXYTYPE: | ||||
| /* fall through */ | /* fall through */ | ||||
| case BOX_SHAPE_PROXYTYPE: | case BOX_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btBoxShape* convexShape = (btBoxShape*)this; | btBoxShape* convexShape = (btBoxShape*)this; | ||||
| btScalar margin=convexShape->getMarginNonVirtual(); | btScalar margin = convexShape->getMarginNonVirtual(); | ||||
| btVector3 halfExtents = convexShape->getImplicitShapeDimensions(); | btVector3 halfExtents = convexShape->getImplicitShapeDimensions(); | ||||
| halfExtents += btVector3(margin,margin,margin); | halfExtents += btVector3(margin, margin, margin); | ||||
| btMatrix3x3 abs_b = t.getBasis().absolute(); | btMatrix3x3 abs_b = t.getBasis().absolute(); | ||||
| btVector3 center = t.getOrigin(); | btVector3 center = t.getOrigin(); | ||||
| btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); | btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); | ||||
| aabbMin = center - extent; | aabbMin = center - extent; | ||||
| aabbMax = center + extent; | aabbMax = center + extent; | ||||
| break; | break; | ||||
| } | } | ||||
| case TRIANGLE_SHAPE_PROXYTYPE: | case TRIANGLE_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btTriangleShape* triangleShape = (btTriangleShape*)this; | btTriangleShape* triangleShape = (btTriangleShape*)this; | ||||
| btScalar margin = triangleShape->getMarginNonVirtual(); | btScalar margin = triangleShape->getMarginNonVirtual(); | ||||
| for (int i=0;i<3;i++) | for (int i = 0; i < 3; i++) | ||||
| { | { | ||||
| btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); | btVector3 vec(btScalar(0.), btScalar(0.), btScalar(0.)); | ||||
| vec[i] = btScalar(1.); | vec[i] = btScalar(1.); | ||||
| btVector3 sv = localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis()); | btVector3 sv = localGetSupportVertexWithoutMarginNonVirtual(vec * t.getBasis()); | ||||
| btVector3 tmp = t(sv); | btVector3 tmp = t(sv); | ||||
| aabbMax[i] = tmp[i]+margin; | aabbMax[i] = tmp[i] + margin; | ||||
| vec[i] = btScalar(-1.); | vec[i] = btScalar(-1.); | ||||
| tmp = t(localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis())); | tmp = t(localGetSupportVertexWithoutMarginNonVirtual(vec * t.getBasis())); | ||||
| aabbMin[i] = tmp[i]-margin; | aabbMin[i] = tmp[i] - margin; | ||||
| } | } | ||||
| } | } | ||||
| break; | break; | ||||
| case CAPSULE_SHAPE_PROXYTYPE: | case CAPSULE_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btCapsuleShape* capsuleShape = (btCapsuleShape*)this; | btCapsuleShape* capsuleShape = (btCapsuleShape*)this; | ||||
| btVector3 halfExtents(capsuleShape->getRadius(),capsuleShape->getRadius(),capsuleShape->getRadius()); | btVector3 halfExtents(capsuleShape->getRadius(), capsuleShape->getRadius(), capsuleShape->getRadius()); | ||||
| int m_upAxis = capsuleShape->getUpAxis(); | int m_upAxis = capsuleShape->getUpAxis(); | ||||
| halfExtents[m_upAxis] = capsuleShape->getRadius() + capsuleShape->getHalfHeight(); | halfExtents[m_upAxis] = capsuleShape->getRadius() + capsuleShape->getHalfHeight(); | ||||
| halfExtents += btVector3(capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual()); | |||||
| btMatrix3x3 abs_b = t.getBasis().absolute(); | btMatrix3x3 abs_b = t.getBasis().absolute(); | ||||
| btVector3 center = t.getOrigin(); | btVector3 center = t.getOrigin(); | ||||
| btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); | btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); | ||||
| aabbMin = center - extent; | aabbMin = center - extent; | ||||
| aabbMax = center + extent; | aabbMax = center + extent; | ||||
| } | } | ||||
| break; | break; | ||||
| case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: | case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: | ||||
| case CONVEX_HULL_SHAPE_PROXYTYPE: | case CONVEX_HULL_SHAPE_PROXYTYPE: | ||||
| { | { | ||||
| btPolyhedralConvexAabbCachingShape* convexHullShape = (btPolyhedralConvexAabbCachingShape*)this; | btPolyhedralConvexAabbCachingShape* convexHullShape = (btPolyhedralConvexAabbCachingShape*)this; | ||||
| btScalar margin = convexHullShape->getMarginNonVirtual(); | btScalar margin = convexHullShape->getMarginNonVirtual(); | ||||
| convexHullShape->getNonvirtualAabb (t, aabbMin, aabbMax, margin); | convexHullShape->getNonvirtualAabb(t, aabbMin, aabbMax, margin); | ||||
| } | } | ||||
| break; | break; | ||||
| default: | default: | ||||
| #ifndef __SPU__ | #ifndef __SPU__ | ||||
| this->getAabb (t, aabbMin, aabbMax); | this->getAabb(t, aabbMin, aabbMax); | ||||
| #else | #else | ||||
| btAssert (0); | btAssert(0); | ||||
| #endif | #endif | ||||
| break; | break; | ||||
| } | } | ||||
| // should never reach here | // should never reach here | ||||
| btAssert (0); | btAssert(0); | ||||
| } | } | ||||
| #endif //__SPU__ | #endif //__SPU__ | ||||