Blender V2.61 - r43446
|
00001 /* 00002 Bullet Continuous Collision Detection and Physics Library 00003 Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org 00004 00005 This software is provided 'as-is', without any express or implied warranty. 00006 In no event will the authors be held liable for any damages arising from the use of this software. 00007 Permission is granted to anyone to use this software for any purpose, 00008 including commercial applications, and to alter it and redistribute it freely, 00009 subject to the following restrictions: 00010 00011 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. 00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 00013 3. This notice may not be removed or altered from any source distribution. 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 //mapping of halfextents/dimension onto radius/height depends on how cylinder local orientation is (upAxis) 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 //vtx = pos +vec*(radius); 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 //vtx = pos +vec*(radius); 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 // should never reach here 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 /* TODO: This should be bumped up to btCollisionShape () */ 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 /* fall through */ 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 // should never reach here 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();// * convexShape->getLocalScaling().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 /* fall through */ 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 // should never reach here 00426 btAssert (0); 00427 } 00428 00429 #endif //__SPU__