00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "btConvexShape.h"
00017 #include "btTriangleShape.h"
00018 #include "btSphereShape.h"
00019 #include "btCylinderShape.h"
00020 #include "btCapsuleShape.h"
00021 #include "btConvexHullShape.h"
00022 #include "btConvexPointCloudShape.h"
00023
00025 #if defined (__CELLOS_LV2__) && defined (__SPU__)
00026 #include <spu_intrinsics.h>
00027 static inline vec_float4 vec_dot3( vec_float4 vec0, vec_float4 vec1 )
00028 {
00029 vec_float4 result;
00030 result = spu_mul( vec0, vec1 );
00031 result = spu_madd( spu_rlqwbyte( vec0, 4 ), spu_rlqwbyte( vec1, 4 ), result );
00032 return spu_madd( spu_rlqwbyte( vec0, 8 ), spu_rlqwbyte( vec1, 8 ), result );
00033 }
00034 #endif //__SPU__
00035
00036 btConvexShape::btConvexShape ()
00037 {
00038 }
00039
00040 btConvexShape::~btConvexShape()
00041 {
00042
00043 }
00044
00045
00046
00047 static btVector3 convexHullSupport (const btVector3& localDirOrg, const btVector3* points, int numPoints, const btVector3& localScaling)
00048 {
00049
00050 btVector3 vec = localDirOrg * localScaling;
00051
00052 #if defined (__CELLOS_LV2__) && defined (__SPU__)
00053
00054 btVector3 localDir = vec;
00055
00056 vec_float4 v_distMax = {-FLT_MAX,0,0,0};
00057 vec_int4 v_idxMax = {-999,0,0,0};
00058 int v=0;
00059 int numverts = numPoints;
00060
00061 for(;v<(int)numverts-4;v+=4) {
00062 vec_float4 p0 = vec_dot3(points[v ].get128(),localDir.get128());
00063 vec_float4 p1 = vec_dot3(points[v+1].get128(),localDir.get128());
00064 vec_float4 p2 = vec_dot3(points[v+2].get128(),localDir.get128());
00065 vec_float4 p3 = vec_dot3(points[v+3].get128(),localDir.get128());
00066 const vec_int4 i0 = {v ,0,0,0};
00067 const vec_int4 i1 = {v+1,0,0,0};
00068 const vec_int4 i2 = {v+2,0,0,0};
00069 const vec_int4 i3 = {v+3,0,0,0};
00070 vec_uint4 retGt01 = spu_cmpgt(p0,p1);
00071 vec_float4 pmax01 = spu_sel(p1,p0,retGt01);
00072 vec_int4 imax01 = spu_sel(i1,i0,retGt01);
00073 vec_uint4 retGt23 = spu_cmpgt(p2,p3);
00074 vec_float4 pmax23 = spu_sel(p3,p2,retGt23);
00075 vec_int4 imax23 = spu_sel(i3,i2,retGt23);
00076 vec_uint4 retGt0123 = spu_cmpgt(pmax01,pmax23);
00077 vec_float4 pmax0123 = spu_sel(pmax23,pmax01,retGt0123);
00078 vec_int4 imax0123 = spu_sel(imax23,imax01,retGt0123);
00079 vec_uint4 retGtMax = spu_cmpgt(v_distMax,pmax0123);
00080 v_distMax = spu_sel(pmax0123,v_distMax,retGtMax);
00081 v_idxMax = spu_sel(imax0123,v_idxMax,retGtMax);
00082 }
00083 for(;v<(int)numverts;v++) {
00084 vec_float4 p = vec_dot3(points[v].get128(),localDir.get128());
00085 const vec_int4 i = {v,0,0,0};
00086 vec_uint4 retGtMax = spu_cmpgt(v_distMax,p);
00087 v_distMax = spu_sel(p,v_distMax,retGtMax);
00088 v_idxMax = spu_sel(i,v_idxMax,retGtMax);
00089 }
00090 int ptIndex = spu_extract(v_idxMax,0);
00091 const btVector3& supVec= points[ptIndex] * localScaling;
00092 return supVec;
00093 #else
00094
00095 btScalar newDot,maxDot = btScalar(-BT_LARGE_FLOAT);
00096 int ptIndex = -1;
00097
00098 for (int i=0;i<numPoints;i++)
00099 {
00100
00101 newDot = vec.dot(points[i]);
00102 if (newDot > maxDot)
00103 {
00104 maxDot = newDot;
00105 ptIndex = i;
00106 }
00107 }
00108 btAssert(ptIndex >= 0);
00109 btVector3 supVec = points[ptIndex] * localScaling;
00110 return supVec;
00111 #endif //__SPU__
00112 }
00113
00114 btVector3 btConvexShape::localGetSupportVertexWithoutMarginNonVirtual (const btVector3& localDir) const
00115 {
00116 switch (m_shapeType)
00117 {
00118 case SPHERE_SHAPE_PROXYTYPE:
00119 {
00120 return btVector3(0,0,0);
00121 }
00122 case BOX_SHAPE_PROXYTYPE:
00123 {
00124 btBoxShape* convexShape = (btBoxShape*)this;
00125 const btVector3& halfExtents = convexShape->getImplicitShapeDimensions();
00126
00127 return btVector3(btFsels(localDir.x(), halfExtents.x(), -halfExtents.x()),
00128 btFsels(localDir.y(), halfExtents.y(), -halfExtents.y()),
00129 btFsels(localDir.z(), halfExtents.z(), -halfExtents.z()));
00130 }
00131 case TRIANGLE_SHAPE_PROXYTYPE:
00132 {
00133 btTriangleShape* triangleShape = (btTriangleShape*)this;
00134 btVector3 dir(localDir.getX(),localDir.getY(),localDir.getZ());
00135 btVector3* vertices = &triangleShape->m_vertices1[0];
00136 btVector3 dots(dir.dot(vertices[0]), dir.dot(vertices[1]), dir.dot(vertices[2]));
00137 btVector3 sup = vertices[dots.maxAxis()];
00138 return btVector3(sup.getX(),sup.getY(),sup.getZ());
00139 }
00140 case CYLINDER_SHAPE_PROXYTYPE:
00141 {
00142 btCylinderShape* cylShape = (btCylinderShape*)this;
00143
00144
00145 btVector3 halfExtents = cylShape->getImplicitShapeDimensions();
00146 btVector3 v(localDir.getX(),localDir.getY(),localDir.getZ());
00147 int cylinderUpAxis = cylShape->getUpAxis();
00148 int XX(1),YY(0),ZZ(2);
00149
00150 switch (cylinderUpAxis)
00151 {
00152 case 0:
00153 {
00154 XX = 1;
00155 YY = 0;
00156 ZZ = 2;
00157 }
00158 break;
00159 case 1:
00160 {
00161 XX = 0;
00162 YY = 1;
00163 ZZ = 2;
00164 }
00165 break;
00166 case 2:
00167 {
00168 XX = 0;
00169 YY = 2;
00170 ZZ = 1;
00171
00172 }
00173 break;
00174 default:
00175 btAssert(0);
00176 break;
00177 };
00178
00179 btScalar radius = halfExtents[XX];
00180 btScalar halfHeight = halfExtents[cylinderUpAxis];
00181
00182 btVector3 tmp;
00183 btScalar d ;
00184
00185 btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
00186 if (s != btScalar(0.0))
00187 {
00188 d = radius / s;
00189 tmp[XX] = v[XX] * d;
00190 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
00191 tmp[ZZ] = v[ZZ] * d;
00192 return btVector3(tmp.getX(),tmp.getY(),tmp.getZ());
00193 } else {
00194 tmp[XX] = radius;
00195 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
00196 tmp[ZZ] = btScalar(0.0);
00197 return btVector3(tmp.getX(),tmp.getY(),tmp.getZ());
00198 }
00199 }
00200 case CAPSULE_SHAPE_PROXYTYPE:
00201 {
00202 btVector3 vec0(localDir.getX(),localDir.getY(),localDir.getZ());
00203
00204 btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
00205 btScalar halfHeight = capsuleShape->getHalfHeight();
00206 int capsuleUpAxis = capsuleShape->getUpAxis();
00207
00208 btScalar radius = capsuleShape->getRadius();
00209 btVector3 supVec(0,0,0);
00210
00211 btScalar maxDot(btScalar(-BT_LARGE_FLOAT));
00212
00213 btVector3 vec = vec0;
00214 btScalar lenSqr = vec.length2();
00215 if (lenSqr < btScalar(0.0001))
00216 {
00217 vec.setValue(1,0,0);
00218 } else
00219 {
00220 btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
00221 vec *= rlen;
00222 }
00223 btVector3 vtx;
00224 btScalar newDot;
00225 {
00226 btVector3 pos(0,0,0);
00227 pos[capsuleUpAxis] = halfHeight;
00228
00229
00230 vtx = pos +vec*capsuleShape->getLocalScalingNV()*(radius) - vec * capsuleShape->getMarginNV();
00231 newDot = vec.dot(vtx);
00232
00233
00234 if (newDot > maxDot)
00235 {
00236 maxDot = newDot;
00237 supVec = vtx;
00238 }
00239 }
00240 {
00241 btVector3 pos(0,0,0);
00242 pos[capsuleUpAxis] = -halfHeight;
00243
00244
00245 vtx = pos +vec*capsuleShape->getLocalScalingNV()*(radius) - vec * capsuleShape->getMarginNV();
00246 newDot = vec.dot(vtx);
00247 if (newDot > maxDot)
00248 {
00249 maxDot = newDot;
00250 supVec = vtx;
00251 }
00252 }
00253 return btVector3(supVec.getX(),supVec.getY(),supVec.getZ());
00254 }
00255 case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
00256 {
00257 btConvexPointCloudShape* convexPointCloudShape = (btConvexPointCloudShape*)this;
00258 btVector3* points = convexPointCloudShape->getUnscaledPoints ();
00259 int numPoints = convexPointCloudShape->getNumPoints ();
00260 return convexHullSupport (localDir, points, numPoints,convexPointCloudShape->getLocalScalingNV());
00261 }
00262 case CONVEX_HULL_SHAPE_PROXYTYPE:
00263 {
00264 btConvexHullShape* convexHullShape = (btConvexHullShape*)this;
00265 btVector3* points = convexHullShape->getUnscaledPoints();
00266 int numPoints = convexHullShape->getNumPoints ();
00267 return convexHullSupport (localDir, points, numPoints,convexHullShape->getLocalScalingNV());
00268 }
00269 default:
00270 #ifndef __SPU__
00271 return this->localGetSupportingVertexWithoutMargin (localDir);
00272 #else
00273 btAssert (0);
00274 #endif
00275 }
00276
00277
00278 btAssert (0);
00279 return btVector3 (btScalar(0.0f), btScalar(0.0f), btScalar(0.0f));
00280 }
00281
00282 btVector3 btConvexShape::localGetSupportVertexNonVirtual (const btVector3& localDir) const
00283 {
00284 btVector3 localDirNorm = localDir;
00285 if (localDirNorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
00286 {
00287 localDirNorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
00288 }
00289 localDirNorm.normalize ();
00290
00291 return localGetSupportVertexWithoutMarginNonVirtual(localDirNorm)+ getMarginNonVirtual() * localDirNorm;
00292 }
00293
00294
00295 btScalar btConvexShape::getMarginNonVirtual () const
00296 {
00297 switch (m_shapeType)
00298 {
00299 case SPHERE_SHAPE_PROXYTYPE:
00300 {
00301 btSphereShape* sphereShape = (btSphereShape*)this;
00302 return sphereShape->getRadius ();
00303 }
00304 case BOX_SHAPE_PROXYTYPE:
00305 {
00306 btBoxShape* convexShape = (btBoxShape*)this;
00307 return convexShape->getMarginNV ();
00308 }
00309 case TRIANGLE_SHAPE_PROXYTYPE:
00310 {
00311 btTriangleShape* triangleShape = (btTriangleShape*)this;
00312 return triangleShape->getMarginNV ();
00313 }
00314 case CYLINDER_SHAPE_PROXYTYPE:
00315 {
00316 btCylinderShape* cylShape = (btCylinderShape*)this;
00317 return cylShape->getMarginNV();
00318 }
00319 case CAPSULE_SHAPE_PROXYTYPE:
00320 {
00321 btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
00322 return capsuleShape->getMarginNV();
00323 }
00324 case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
00325
00326 case CONVEX_HULL_SHAPE_PROXYTYPE:
00327 {
00328 btPolyhedralConvexShape* convexHullShape = (btPolyhedralConvexShape*)this;
00329 return convexHullShape->getMarginNV();
00330 }
00331 default:
00332 #ifndef __SPU__
00333 return this->getMargin ();
00334 #else
00335 btAssert (0);
00336 #endif
00337 }
00338
00339
00340 btAssert (0);
00341 return btScalar(0.0f);
00342 }
00343 #ifndef __SPU__
00344 void btConvexShape::getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
00345 {
00346 switch (m_shapeType)
00347 {
00348 case SPHERE_SHAPE_PROXYTYPE:
00349 {
00350 btSphereShape* sphereShape = (btSphereShape*)this;
00351 btScalar radius = sphereShape->getImplicitShapeDimensions().getX();
00352 btScalar margin = radius + sphereShape->getMarginNonVirtual();
00353 const btVector3& center = t.getOrigin();
00354 btVector3 extent(margin,margin,margin);
00355 aabbMin = center - extent;
00356 aabbMax = center + extent;
00357 }
00358 break;
00359 case CYLINDER_SHAPE_PROXYTYPE:
00360
00361 case BOX_SHAPE_PROXYTYPE:
00362 {
00363 btBoxShape* convexShape = (btBoxShape*)this;
00364 btScalar margin=convexShape->getMarginNonVirtual();
00365 btVector3 halfExtents = convexShape->getImplicitShapeDimensions();
00366 halfExtents += btVector3(margin,margin,margin);
00367 btMatrix3x3 abs_b = t.getBasis().absolute();
00368 btVector3 center = t.getOrigin();
00369 btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
00370
00371 aabbMin = center - extent;
00372 aabbMax = center + extent;
00373 break;
00374 }
00375 case TRIANGLE_SHAPE_PROXYTYPE:
00376 {
00377 btTriangleShape* triangleShape = (btTriangleShape*)this;
00378 btScalar margin = triangleShape->getMarginNonVirtual();
00379 for (int i=0;i<3;i++)
00380 {
00381 btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
00382 vec[i] = btScalar(1.);
00383
00384 btVector3 sv = localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis());
00385
00386 btVector3 tmp = t(sv);
00387 aabbMax[i] = tmp[i]+margin;
00388 vec[i] = btScalar(-1.);
00389 tmp = t(localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis()));
00390 aabbMin[i] = tmp[i]-margin;
00391 }
00392 }
00393 break;
00394 case CAPSULE_SHAPE_PROXYTYPE:
00395 {
00396 btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
00397 btVector3 halfExtents(capsuleShape->getRadius(),capsuleShape->getRadius(),capsuleShape->getRadius());
00398 int m_upAxis = capsuleShape->getUpAxis();
00399 halfExtents[m_upAxis] = capsuleShape->getRadius() + capsuleShape->getHalfHeight();
00400 halfExtents += btVector3(capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual());
00401 btMatrix3x3 abs_b = t.getBasis().absolute();
00402 btVector3 center = t.getOrigin();
00403 btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
00404 aabbMin = center - extent;
00405 aabbMax = center + extent;
00406 }
00407 break;
00408 case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
00409 case CONVEX_HULL_SHAPE_PROXYTYPE:
00410 {
00411 btPolyhedralConvexAabbCachingShape* convexHullShape = (btPolyhedralConvexAabbCachingShape*)this;
00412 btScalar margin = convexHullShape->getMarginNonVirtual();
00413 convexHullShape->getNonvirtualAabb (t, aabbMin, aabbMax, margin);
00414 }
00415 break;
00416 default:
00417 #ifndef __SPU__
00418 this->getAabb (t, aabbMin, aabbMax);
00419 #else
00420 btAssert (0);
00421 #endif
00422 break;
00423 }
00424
00425
00426 btAssert (0);
00427 }
00428
00429 #endif //__SPU__