Blender V2.61 - r43446
|
00001 /* 00002 Bullet Continuous Collision Detection and Physics Library 00003 Copyright (c) 2003-2008 Erwin Coumans http://continuousphysics.com/Bullet/ 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 00007 use of this software. 00008 Permission is granted to anyone to use this software for any purpose, 00009 including commercial applications, and to alter it and redistribute it 00010 freely, 00011 subject to the following restrictions: 00012 00013 1. The origin of this software must not be misrepresented; you must not 00014 claim that you wrote the original software. If you use this software in a 00015 product, an acknowledgment in the product documentation would be appreciated 00016 but is not required. 00017 2. Altered source versions must be plainly marked as such, and must not be 00018 misrepresented as being the original software. 00019 3. This notice may not be removed or altered from any source distribution. 00020 */ 00021 00022 /* 00023 GJK-EPA collision solver by Nathanael Presson, 2008 00024 */ 00025 #include "BulletCollision/CollisionShapes/btConvexInternalShape.h" 00026 #include "BulletCollision/CollisionShapes/btSphereShape.h" 00027 #include "btGjkEpa2.h" 00028 00029 #if defined(DEBUG) || defined (_DEBUG) 00030 #include <stdio.h> //for debug printf 00031 #ifdef __SPU__ 00032 #include <spu_printf.h> 00033 #define printf spu_printf 00034 #endif //__SPU__ 00035 #endif 00036 00037 namespace gjkepa2_impl 00038 { 00039 00040 // Config 00041 00042 /* GJK */ 00043 #define GJK_MAX_ITERATIONS 128 00044 #define GJK_ACCURARY ((btScalar)0.0001) 00045 #define GJK_MIN_DISTANCE ((btScalar)0.0001) 00046 #define GJK_DUPLICATED_EPS ((btScalar)0.0001) 00047 #define GJK_SIMPLEX2_EPS ((btScalar)0.0) 00048 #define GJK_SIMPLEX3_EPS ((btScalar)0.0) 00049 #define GJK_SIMPLEX4_EPS ((btScalar)0.0) 00050 00051 /* EPA */ 00052 #define EPA_MAX_VERTICES 64 00053 #define EPA_MAX_FACES (EPA_MAX_VERTICES*2) 00054 #define EPA_MAX_ITERATIONS 255 00055 #define EPA_ACCURACY ((btScalar)0.0001) 00056 #define EPA_FALLBACK (10*EPA_ACCURACY) 00057 #define EPA_PLANE_EPS ((btScalar)0.00001) 00058 #define EPA_INSIDE_EPS ((btScalar)0.01) 00059 00060 00061 // Shorthands 00062 typedef unsigned int U; 00063 typedef unsigned char U1; 00064 00065 // MinkowskiDiff 00066 struct MinkowskiDiff 00067 { 00068 const btConvexShape* m_shapes[2]; 00069 btMatrix3x3 m_toshape1; 00070 btTransform m_toshape0; 00071 #ifdef __SPU__ 00072 bool m_enableMargin; 00073 #else 00074 btVector3 (btConvexShape::*Ls)(const btVector3&) const; 00075 #endif//__SPU__ 00076 00077 00078 MinkowskiDiff() 00079 { 00080 00081 } 00082 #ifdef __SPU__ 00083 void EnableMargin(bool enable) 00084 { 00085 m_enableMargin = enable; 00086 } 00087 inline btVector3 Support0(const btVector3& d) const 00088 { 00089 if (m_enableMargin) 00090 { 00091 return m_shapes[0]->localGetSupportVertexNonVirtual(d); 00092 } else 00093 { 00094 return m_shapes[0]->localGetSupportVertexWithoutMarginNonVirtual(d); 00095 } 00096 } 00097 inline btVector3 Support1(const btVector3& d) const 00098 { 00099 if (m_enableMargin) 00100 { 00101 return m_toshape0*(m_shapes[1]->localGetSupportVertexNonVirtual(m_toshape1*d)); 00102 } else 00103 { 00104 return m_toshape0*(m_shapes[1]->localGetSupportVertexWithoutMarginNonVirtual(m_toshape1*d)); 00105 } 00106 } 00107 #else 00108 void EnableMargin(bool enable) 00109 { 00110 if(enable) 00111 Ls=&btConvexShape::localGetSupportVertexNonVirtual; 00112 else 00113 Ls=&btConvexShape::localGetSupportVertexWithoutMarginNonVirtual; 00114 } 00115 inline btVector3 Support0(const btVector3& d) const 00116 { 00117 return(((m_shapes[0])->*(Ls))(d)); 00118 } 00119 inline btVector3 Support1(const btVector3& d) const 00120 { 00121 return(m_toshape0*((m_shapes[1])->*(Ls))(m_toshape1*d)); 00122 } 00123 #endif //__SPU__ 00124 00125 inline btVector3 Support(const btVector3& d) const 00126 { 00127 return(Support0(d)-Support1(-d)); 00128 } 00129 btVector3 Support(const btVector3& d,U index) const 00130 { 00131 if(index) 00132 return(Support1(d)); 00133 else 00134 return(Support0(d)); 00135 } 00136 }; 00137 00138 typedef MinkowskiDiff tShape; 00139 00140 00141 // GJK 00142 struct GJK 00143 { 00144 /* Types */ 00145 struct sSV 00146 { 00147 btVector3 d,w; 00148 }; 00149 struct sSimplex 00150 { 00151 sSV* c[4]; 00152 btScalar p[4]; 00153 U rank; 00154 }; 00155 struct eStatus { enum _ { 00156 Valid, 00157 Inside, 00158 Failed };}; 00159 /* Fields */ 00160 tShape m_shape; 00161 btVector3 m_ray; 00162 btScalar m_distance; 00163 sSimplex m_simplices[2]; 00164 sSV m_store[4]; 00165 sSV* m_free[4]; 00166 U m_nfree; 00167 U m_current; 00168 sSimplex* m_simplex; 00169 eStatus::_ m_status; 00170 /* Methods */ 00171 GJK() 00172 { 00173 Initialize(); 00174 } 00175 void Initialize() 00176 { 00177 m_ray = btVector3(0,0,0); 00178 m_nfree = 0; 00179 m_status = eStatus::Failed; 00180 m_current = 0; 00181 m_distance = 0; 00182 } 00183 eStatus::_ Evaluate(const tShape& shapearg,const btVector3& guess) 00184 { 00185 U iterations=0; 00186 btScalar sqdist=0; 00187 btScalar alpha=0; 00188 btVector3 lastw[4]; 00189 U clastw=0; 00190 /* Initialize solver */ 00191 m_free[0] = &m_store[0]; 00192 m_free[1] = &m_store[1]; 00193 m_free[2] = &m_store[2]; 00194 m_free[3] = &m_store[3]; 00195 m_nfree = 4; 00196 m_current = 0; 00197 m_status = eStatus::Valid; 00198 m_shape = shapearg; 00199 m_distance = 0; 00200 /* Initialize simplex */ 00201 m_simplices[0].rank = 0; 00202 m_ray = guess; 00203 const btScalar sqrl= m_ray.length2(); 00204 appendvertice(m_simplices[0],sqrl>0?-m_ray:btVector3(1,0,0)); 00205 m_simplices[0].p[0] = 1; 00206 m_ray = m_simplices[0].c[0]->w; 00207 sqdist = sqrl; 00208 lastw[0] = 00209 lastw[1] = 00210 lastw[2] = 00211 lastw[3] = m_ray; 00212 /* Loop */ 00213 do { 00214 const U next=1-m_current; 00215 sSimplex& cs=m_simplices[m_current]; 00216 sSimplex& ns=m_simplices[next]; 00217 /* Check zero */ 00218 const btScalar rl=m_ray.length(); 00219 if(rl<GJK_MIN_DISTANCE) 00220 {/* Touching or inside */ 00221 m_status=eStatus::Inside; 00222 break; 00223 } 00224 /* Append new vertice in -'v' direction */ 00225 appendvertice(cs,-m_ray); 00226 const btVector3& w=cs.c[cs.rank-1]->w; 00227 bool found=false; 00228 for(U i=0;i<4;++i) 00229 { 00230 if((w-lastw[i]).length2()<GJK_DUPLICATED_EPS) 00231 { found=true;break; } 00232 } 00233 if(found) 00234 {/* Return old simplex */ 00235 removevertice(m_simplices[m_current]); 00236 break; 00237 } 00238 else 00239 {/* Update lastw */ 00240 lastw[clastw=(clastw+1)&3]=w; 00241 } 00242 /* Check for termination */ 00243 const btScalar omega=btDot(m_ray,w)/rl; 00244 alpha=btMax(omega,alpha); 00245 if(((rl-alpha)-(GJK_ACCURARY*rl))<=0) 00246 {/* Return old simplex */ 00247 removevertice(m_simplices[m_current]); 00248 break; 00249 } 00250 /* Reduce simplex */ 00251 btScalar weights[4]; 00252 U mask=0; 00253 switch(cs.rank) 00254 { 00255 case 2: sqdist=projectorigin( cs.c[0]->w, 00256 cs.c[1]->w, 00257 weights,mask);break; 00258 case 3: sqdist=projectorigin( cs.c[0]->w, 00259 cs.c[1]->w, 00260 cs.c[2]->w, 00261 weights,mask);break; 00262 case 4: sqdist=projectorigin( cs.c[0]->w, 00263 cs.c[1]->w, 00264 cs.c[2]->w, 00265 cs.c[3]->w, 00266 weights,mask);break; 00267 } 00268 if(sqdist>=0) 00269 {/* Valid */ 00270 ns.rank = 0; 00271 m_ray = btVector3(0,0,0); 00272 m_current = next; 00273 for(U i=0,ni=cs.rank;i<ni;++i) 00274 { 00275 if(mask&(1<<i)) 00276 { 00277 ns.c[ns.rank] = cs.c[i]; 00278 ns.p[ns.rank++] = weights[i]; 00279 m_ray += cs.c[i]->w*weights[i]; 00280 } 00281 else 00282 { 00283 m_free[m_nfree++] = cs.c[i]; 00284 } 00285 } 00286 if(mask==15) m_status=eStatus::Inside; 00287 } 00288 else 00289 {/* Return old simplex */ 00290 removevertice(m_simplices[m_current]); 00291 break; 00292 } 00293 m_status=((++iterations)<GJK_MAX_ITERATIONS)?m_status:eStatus::Failed; 00294 } while(m_status==eStatus::Valid); 00295 m_simplex=&m_simplices[m_current]; 00296 switch(m_status) 00297 { 00298 case eStatus::Valid: m_distance=m_ray.length();break; 00299 case eStatus::Inside: m_distance=0;break; 00300 default: 00301 { 00302 } 00303 } 00304 return(m_status); 00305 } 00306 bool EncloseOrigin() 00307 { 00308 switch(m_simplex->rank) 00309 { 00310 case 1: 00311 { 00312 for(U i=0;i<3;++i) 00313 { 00314 btVector3 axis=btVector3(0,0,0); 00315 axis[i]=1; 00316 appendvertice(*m_simplex, axis); 00317 if(EncloseOrigin()) return(true); 00318 removevertice(*m_simplex); 00319 appendvertice(*m_simplex,-axis); 00320 if(EncloseOrigin()) return(true); 00321 removevertice(*m_simplex); 00322 } 00323 } 00324 break; 00325 case 2: 00326 { 00327 const btVector3 d=m_simplex->c[1]->w-m_simplex->c[0]->w; 00328 for(U i=0;i<3;++i) 00329 { 00330 btVector3 axis=btVector3(0,0,0); 00331 axis[i]=1; 00332 const btVector3 p=btCross(d,axis); 00333 if(p.length2()>0) 00334 { 00335 appendvertice(*m_simplex, p); 00336 if(EncloseOrigin()) return(true); 00337 removevertice(*m_simplex); 00338 appendvertice(*m_simplex,-p); 00339 if(EncloseOrigin()) return(true); 00340 removevertice(*m_simplex); 00341 } 00342 } 00343 } 00344 break; 00345 case 3: 00346 { 00347 const btVector3 n=btCross(m_simplex->c[1]->w-m_simplex->c[0]->w, 00348 m_simplex->c[2]->w-m_simplex->c[0]->w); 00349 if(n.length2()>0) 00350 { 00351 appendvertice(*m_simplex,n); 00352 if(EncloseOrigin()) return(true); 00353 removevertice(*m_simplex); 00354 appendvertice(*m_simplex,-n); 00355 if(EncloseOrigin()) return(true); 00356 removevertice(*m_simplex); 00357 } 00358 } 00359 break; 00360 case 4: 00361 { 00362 if(btFabs(det( m_simplex->c[0]->w-m_simplex->c[3]->w, 00363 m_simplex->c[1]->w-m_simplex->c[3]->w, 00364 m_simplex->c[2]->w-m_simplex->c[3]->w))>0) 00365 return(true); 00366 } 00367 break; 00368 } 00369 return(false); 00370 } 00371 /* Internals */ 00372 void getsupport(const btVector3& d,sSV& sv) const 00373 { 00374 sv.d = d/d.length(); 00375 sv.w = m_shape.Support(sv.d); 00376 } 00377 void removevertice(sSimplex& simplex) 00378 { 00379 m_free[m_nfree++]=simplex.c[--simplex.rank]; 00380 } 00381 void appendvertice(sSimplex& simplex,const btVector3& v) 00382 { 00383 simplex.p[simplex.rank]=0; 00384 simplex.c[simplex.rank]=m_free[--m_nfree]; 00385 getsupport(v,*simplex.c[simplex.rank++]); 00386 } 00387 static btScalar det(const btVector3& a,const btVector3& b,const btVector3& c) 00388 { 00389 return( a.y()*b.z()*c.x()+a.z()*b.x()*c.y()- 00390 a.x()*b.z()*c.y()-a.y()*b.x()*c.z()+ 00391 a.x()*b.y()*c.z()-a.z()*b.y()*c.x()); 00392 } 00393 static btScalar projectorigin( const btVector3& a, 00394 const btVector3& b, 00395 btScalar* w,U& m) 00396 { 00397 const btVector3 d=b-a; 00398 const btScalar l=d.length2(); 00399 if(l>GJK_SIMPLEX2_EPS) 00400 { 00401 const btScalar t(l>0?-btDot(a,d)/l:0); 00402 if(t>=1) { w[0]=0;w[1]=1;m=2;return(b.length2()); } 00403 else if(t<=0) { w[0]=1;w[1]=0;m=1;return(a.length2()); } 00404 else { w[0]=1-(w[1]=t);m=3;return((a+d*t).length2()); } 00405 } 00406 return(-1); 00407 } 00408 static btScalar projectorigin( const btVector3& a, 00409 const btVector3& b, 00410 const btVector3& c, 00411 btScalar* w,U& m) 00412 { 00413 static const U imd3[]={1,2,0}; 00414 const btVector3* vt[]={&a,&b,&c}; 00415 const btVector3 dl[]={a-b,b-c,c-a}; 00416 const btVector3 n=btCross(dl[0],dl[1]); 00417 const btScalar l=n.length2(); 00418 if(l>GJK_SIMPLEX3_EPS) 00419 { 00420 btScalar mindist=-1; 00421 btScalar subw[2]={0.f,0.f}; 00422 U subm(0); 00423 for(U i=0;i<3;++i) 00424 { 00425 if(btDot(*vt[i],btCross(dl[i],n))>0) 00426 { 00427 const U j=imd3[i]; 00428 const btScalar subd(projectorigin(*vt[i],*vt[j],subw,subm)); 00429 if((mindist<0)||(subd<mindist)) 00430 { 00431 mindist = subd; 00432 m = static_cast<U>(((subm&1)?1<<i:0)+((subm&2)?1<<j:0)); 00433 w[i] = subw[0]; 00434 w[j] = subw[1]; 00435 w[imd3[j]] = 0; 00436 } 00437 } 00438 } 00439 if(mindist<0) 00440 { 00441 const btScalar d=btDot(a,n); 00442 const btScalar s=btSqrt(l); 00443 const btVector3 p=n*(d/l); 00444 mindist = p.length2(); 00445 m = 7; 00446 w[0] = (btCross(dl[1],b-p)).length()/s; 00447 w[1] = (btCross(dl[2],c-p)).length()/s; 00448 w[2] = 1-(w[0]+w[1]); 00449 } 00450 return(mindist); 00451 } 00452 return(-1); 00453 } 00454 static btScalar projectorigin( const btVector3& a, 00455 const btVector3& b, 00456 const btVector3& c, 00457 const btVector3& d, 00458 btScalar* w,U& m) 00459 { 00460 static const U imd3[]={1,2,0}; 00461 const btVector3* vt[]={&a,&b,&c,&d}; 00462 const btVector3 dl[]={a-d,b-d,c-d}; 00463 const btScalar vl=det(dl[0],dl[1],dl[2]); 00464 const bool ng=(vl*btDot(a,btCross(b-c,a-b)))<=0; 00465 if(ng&&(btFabs(vl)>GJK_SIMPLEX4_EPS)) 00466 { 00467 btScalar mindist=-1; 00468 btScalar subw[3]={0.f,0.f,0.f}; 00469 U subm(0); 00470 for(U i=0;i<3;++i) 00471 { 00472 const U j=imd3[i]; 00473 const btScalar s=vl*btDot(d,btCross(dl[i],dl[j])); 00474 if(s>0) 00475 { 00476 const btScalar subd=projectorigin(*vt[i],*vt[j],d,subw,subm); 00477 if((mindist<0)||(subd<mindist)) 00478 { 00479 mindist = subd; 00480 m = static_cast<U>((subm&1?1<<i:0)+ 00481 (subm&2?1<<j:0)+ 00482 (subm&4?8:0)); 00483 w[i] = subw[0]; 00484 w[j] = subw[1]; 00485 w[imd3[j]] = 0; 00486 w[3] = subw[2]; 00487 } 00488 } 00489 } 00490 if(mindist<0) 00491 { 00492 mindist = 0; 00493 m = 15; 00494 w[0] = det(c,b,d)/vl; 00495 w[1] = det(a,c,d)/vl; 00496 w[2] = det(b,a,d)/vl; 00497 w[3] = 1-(w[0]+w[1]+w[2]); 00498 } 00499 return(mindist); 00500 } 00501 return(-1); 00502 } 00503 }; 00504 00505 // EPA 00506 struct EPA 00507 { 00508 /* Types */ 00509 typedef GJK::sSV sSV; 00510 struct sFace 00511 { 00512 btVector3 n; 00513 btScalar d; 00514 btScalar p; 00515 sSV* c[3]; 00516 sFace* f[3]; 00517 sFace* l[2]; 00518 U1 e[3]; 00519 U1 pass; 00520 }; 00521 struct sList 00522 { 00523 sFace* root; 00524 U count; 00525 sList() : root(0),count(0) {} 00526 }; 00527 struct sHorizon 00528 { 00529 sFace* cf; 00530 sFace* ff; 00531 U nf; 00532 sHorizon() : cf(0),ff(0),nf(0) {} 00533 }; 00534 struct eStatus { enum _ { 00535 Valid, 00536 Touching, 00537 Degenerated, 00538 NonConvex, 00539 InvalidHull, 00540 OutOfFaces, 00541 OutOfVertices, 00542 AccuraryReached, 00543 FallBack, 00544 Failed };}; 00545 /* Fields */ 00546 eStatus::_ m_status; 00547 GJK::sSimplex m_result; 00548 btVector3 m_normal; 00549 btScalar m_depth; 00550 sSV m_sv_store[EPA_MAX_VERTICES]; 00551 sFace m_fc_store[EPA_MAX_FACES]; 00552 U m_nextsv; 00553 sList m_hull; 00554 sList m_stock; 00555 /* Methods */ 00556 EPA() 00557 { 00558 Initialize(); 00559 } 00560 00561 00562 static inline void bind(sFace* fa,U ea,sFace* fb,U eb) 00563 { 00564 fa->e[ea]=(U1)eb;fa->f[ea]=fb; 00565 fb->e[eb]=(U1)ea;fb->f[eb]=fa; 00566 } 00567 static inline void append(sList& list,sFace* face) 00568 { 00569 face->l[0] = 0; 00570 face->l[1] = list.root; 00571 if(list.root) list.root->l[0]=face; 00572 list.root = face; 00573 ++list.count; 00574 } 00575 static inline void remove(sList& list,sFace* face) 00576 { 00577 if(face->l[1]) face->l[1]->l[0]=face->l[0]; 00578 if(face->l[0]) face->l[0]->l[1]=face->l[1]; 00579 if(face==list.root) list.root=face->l[1]; 00580 --list.count; 00581 } 00582 00583 00584 void Initialize() 00585 { 00586 m_status = eStatus::Failed; 00587 m_normal = btVector3(0,0,0); 00588 m_depth = 0; 00589 m_nextsv = 0; 00590 for(U i=0;i<EPA_MAX_FACES;++i) 00591 { 00592 append(m_stock,&m_fc_store[EPA_MAX_FACES-i-1]); 00593 } 00594 } 00595 eStatus::_ Evaluate(GJK& gjk,const btVector3& guess) 00596 { 00597 GJK::sSimplex& simplex=*gjk.m_simplex; 00598 if((simplex.rank>1)&&gjk.EncloseOrigin()) 00599 { 00600 00601 /* Clean up */ 00602 while(m_hull.root) 00603 { 00604 sFace* f = m_hull.root; 00605 remove(m_hull,f); 00606 append(m_stock,f); 00607 } 00608 m_status = eStatus::Valid; 00609 m_nextsv = 0; 00610 /* Orient simplex */ 00611 if(gjk.det( simplex.c[0]->w-simplex.c[3]->w, 00612 simplex.c[1]->w-simplex.c[3]->w, 00613 simplex.c[2]->w-simplex.c[3]->w)<0) 00614 { 00615 btSwap(simplex.c[0],simplex.c[1]); 00616 btSwap(simplex.p[0],simplex.p[1]); 00617 } 00618 /* Build initial hull */ 00619 sFace* tetra[]={newface(simplex.c[0],simplex.c[1],simplex.c[2],true), 00620 newface(simplex.c[1],simplex.c[0],simplex.c[3],true), 00621 newface(simplex.c[2],simplex.c[1],simplex.c[3],true), 00622 newface(simplex.c[0],simplex.c[2],simplex.c[3],true)}; 00623 if(m_hull.count==4) 00624 { 00625 sFace* best=findbest(); 00626 sFace outer=*best; 00627 U pass=0; 00628 U iterations=0; 00629 bind(tetra[0],0,tetra[1],0); 00630 bind(tetra[0],1,tetra[2],0); 00631 bind(tetra[0],2,tetra[3],0); 00632 bind(tetra[1],1,tetra[3],2); 00633 bind(tetra[1],2,tetra[2],1); 00634 bind(tetra[2],2,tetra[3],1); 00635 m_status=eStatus::Valid; 00636 for(;iterations<EPA_MAX_ITERATIONS;++iterations) 00637 { 00638 if(m_nextsv<EPA_MAX_VERTICES) 00639 { 00640 sHorizon horizon; 00641 sSV* w=&m_sv_store[m_nextsv++]; 00642 bool valid=true; 00643 best->pass = (U1)(++pass); 00644 gjk.getsupport(best->n,*w); 00645 const btScalar wdist=btDot(best->n,w->w)-best->d; 00646 if(wdist>EPA_ACCURACY) 00647 { 00648 for(U j=0;(j<3)&&valid;++j) 00649 { 00650 valid&=expand( pass,w, 00651 best->f[j],best->e[j], 00652 horizon); 00653 } 00654 if(valid&&(horizon.nf>=3)) 00655 { 00656 bind(horizon.cf,1,horizon.ff,2); 00657 remove(m_hull,best); 00658 append(m_stock,best); 00659 best=findbest(); 00660 if(best->p>=outer.p) outer=*best; 00661 } else { m_status=eStatus::InvalidHull;break; } 00662 } else { m_status=eStatus::AccuraryReached;break; } 00663 } else { m_status=eStatus::OutOfVertices;break; } 00664 } 00665 const btVector3 projection=outer.n*outer.d; 00666 m_normal = outer.n; 00667 m_depth = outer.d; 00668 m_result.rank = 3; 00669 m_result.c[0] = outer.c[0]; 00670 m_result.c[1] = outer.c[1]; 00671 m_result.c[2] = outer.c[2]; 00672 m_result.p[0] = btCross( outer.c[1]->w-projection, 00673 outer.c[2]->w-projection).length(); 00674 m_result.p[1] = btCross( outer.c[2]->w-projection, 00675 outer.c[0]->w-projection).length(); 00676 m_result.p[2] = btCross( outer.c[0]->w-projection, 00677 outer.c[1]->w-projection).length(); 00678 const btScalar sum=m_result.p[0]+m_result.p[1]+m_result.p[2]; 00679 m_result.p[0] /= sum; 00680 m_result.p[1] /= sum; 00681 m_result.p[2] /= sum; 00682 return(m_status); 00683 } 00684 } 00685 /* Fallback */ 00686 m_status = eStatus::FallBack; 00687 m_normal = -guess; 00688 const btScalar nl=m_normal.length(); 00689 if(nl>0) 00690 m_normal = m_normal/nl; 00691 else 00692 m_normal = btVector3(1,0,0); 00693 m_depth = 0; 00694 m_result.rank=1; 00695 m_result.c[0]=simplex.c[0]; 00696 m_result.p[0]=1; 00697 return(m_status); 00698 } 00699 sFace* newface(sSV* a,sSV* b,sSV* c,bool forced) 00700 { 00701 if(m_stock.root) 00702 { 00703 sFace* face=m_stock.root; 00704 remove(m_stock,face); 00705 append(m_hull,face); 00706 face->pass = 0; 00707 face->c[0] = a; 00708 face->c[1] = b; 00709 face->c[2] = c; 00710 face->n = btCross(b->w-a->w,c->w-a->w); 00711 const btScalar l=face->n.length(); 00712 const bool v=l>EPA_ACCURACY; 00713 face->p = btMin(btMin( 00714 btDot(a->w,btCross(face->n,a->w-b->w)), 00715 btDot(b->w,btCross(face->n,b->w-c->w))), 00716 btDot(c->w,btCross(face->n,c->w-a->w))) / 00717 (v?l:1); 00718 face->p = face->p>=-EPA_INSIDE_EPS?0:face->p; 00719 if(v) 00720 { 00721 face->d = btDot(a->w,face->n)/l; 00722 face->n /= l; 00723 if(forced||(face->d>=-EPA_PLANE_EPS)) 00724 { 00725 return(face); 00726 } else m_status=eStatus::NonConvex; 00727 } else m_status=eStatus::Degenerated; 00728 remove(m_hull,face); 00729 append(m_stock,face); 00730 return(0); 00731 } 00732 m_status=m_stock.root?eStatus::OutOfVertices:eStatus::OutOfFaces; 00733 return(0); 00734 } 00735 sFace* findbest() 00736 { 00737 sFace* minf=m_hull.root; 00738 btScalar mind=minf->d*minf->d; 00739 btScalar maxp=minf->p; 00740 for(sFace* f=minf->l[1];f;f=f->l[1]) 00741 { 00742 const btScalar sqd=f->d*f->d; 00743 if((f->p>=maxp)&&(sqd<mind)) 00744 { 00745 minf=f; 00746 mind=sqd; 00747 maxp=f->p; 00748 } 00749 } 00750 return(minf); 00751 } 00752 bool expand(U pass,sSV* w,sFace* f,U e,sHorizon& horizon) 00753 { 00754 static const U i1m3[]={1,2,0}; 00755 static const U i2m3[]={2,0,1}; 00756 if(f->pass!=pass) 00757 { 00758 const U e1=i1m3[e]; 00759 if((btDot(f->n,w->w)-f->d)<-EPA_PLANE_EPS) 00760 { 00761 sFace* nf=newface(f->c[e1],f->c[e],w,false); 00762 if(nf) 00763 { 00764 bind(nf,0,f,e); 00765 if(horizon.cf) bind(horizon.cf,1,nf,2); else horizon.ff=nf; 00766 horizon.cf=nf; 00767 ++horizon.nf; 00768 return(true); 00769 } 00770 } 00771 else 00772 { 00773 const U e2=i2m3[e]; 00774 f->pass = (U1)pass; 00775 if( expand(pass,w,f->f[e1],f->e[e1],horizon)&& 00776 expand(pass,w,f->f[e2],f->e[e2],horizon)) 00777 { 00778 remove(m_hull,f); 00779 append(m_stock,f); 00780 return(true); 00781 } 00782 } 00783 } 00784 return(false); 00785 } 00786 00787 }; 00788 00789 // 00790 static void Initialize( const btConvexShape* shape0,const btTransform& wtrs0, 00791 const btConvexShape* shape1,const btTransform& wtrs1, 00792 btGjkEpaSolver2::sResults& results, 00793 tShape& shape, 00794 bool withmargins) 00795 { 00796 /* Results */ 00797 results.witnesses[0] = 00798 results.witnesses[1] = btVector3(0,0,0); 00799 results.status = btGjkEpaSolver2::sResults::Separated; 00800 /* Shape */ 00801 shape.m_shapes[0] = shape0; 00802 shape.m_shapes[1] = shape1; 00803 shape.m_toshape1 = wtrs1.getBasis().transposeTimes(wtrs0.getBasis()); 00804 shape.m_toshape0 = wtrs0.inverseTimes(wtrs1); 00805 shape.EnableMargin(withmargins); 00806 } 00807 00808 } 00809 00810 // 00811 // Api 00812 // 00813 00814 using namespace gjkepa2_impl; 00815 00816 // 00817 int btGjkEpaSolver2::StackSizeRequirement() 00818 { 00819 return(sizeof(GJK)+sizeof(EPA)); 00820 } 00821 00822 // 00823 bool btGjkEpaSolver2::Distance( const btConvexShape* shape0, 00824 const btTransform& wtrs0, 00825 const btConvexShape* shape1, 00826 const btTransform& wtrs1, 00827 const btVector3& guess, 00828 sResults& results) 00829 { 00830 tShape shape; 00831 Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,false); 00832 GJK gjk; 00833 GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,guess); 00834 if(gjk_status==GJK::eStatus::Valid) 00835 { 00836 btVector3 w0=btVector3(0,0,0); 00837 btVector3 w1=btVector3(0,0,0); 00838 for(U i=0;i<gjk.m_simplex->rank;++i) 00839 { 00840 const btScalar p=gjk.m_simplex->p[i]; 00841 w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p; 00842 w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p; 00843 } 00844 results.witnesses[0] = wtrs0*w0; 00845 results.witnesses[1] = wtrs0*w1; 00846 results.normal = w0-w1; 00847 results.distance = results.normal.length(); 00848 results.normal /= results.distance>GJK_MIN_DISTANCE?results.distance:1; 00849 return(true); 00850 } 00851 else 00852 { 00853 results.status = gjk_status==GJK::eStatus::Inside? 00854 sResults::Penetrating : 00855 sResults::GJK_Failed ; 00856 return(false); 00857 } 00858 } 00859 00860 // 00861 bool btGjkEpaSolver2::Penetration( const btConvexShape* shape0, 00862 const btTransform& wtrs0, 00863 const btConvexShape* shape1, 00864 const btTransform& wtrs1, 00865 const btVector3& guess, 00866 sResults& results, 00867 bool usemargins) 00868 { 00869 tShape shape; 00870 Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,usemargins); 00871 GJK gjk; 00872 GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,-guess); 00873 switch(gjk_status) 00874 { 00875 case GJK::eStatus::Inside: 00876 { 00877 EPA epa; 00878 EPA::eStatus::_ epa_status=epa.Evaluate(gjk,-guess); 00879 if(epa_status!=EPA::eStatus::Failed) 00880 { 00881 btVector3 w0=btVector3(0,0,0); 00882 for(U i=0;i<epa.m_result.rank;++i) 00883 { 00884 w0+=shape.Support(epa.m_result.c[i]->d,0)*epa.m_result.p[i]; 00885 } 00886 results.status = sResults::Penetrating; 00887 results.witnesses[0] = wtrs0*w0; 00888 results.witnesses[1] = wtrs0*(w0-epa.m_normal*epa.m_depth); 00889 results.normal = -epa.m_normal; 00890 results.distance = -epa.m_depth; 00891 return(true); 00892 } else results.status=sResults::EPA_Failed; 00893 } 00894 break; 00895 case GJK::eStatus::Failed: 00896 results.status=sResults::GJK_Failed; 00897 break; 00898 default: 00899 { 00900 } 00901 } 00902 return(false); 00903 } 00904 00905 #ifndef __SPU__ 00906 // 00907 btScalar btGjkEpaSolver2::SignedDistance(const btVector3& position, 00908 btScalar margin, 00909 const btConvexShape* shape0, 00910 const btTransform& wtrs0, 00911 sResults& results) 00912 { 00913 tShape shape; 00914 btSphereShape shape1(margin); 00915 btTransform wtrs1(btQuaternion(0,0,0,1),position); 00916 Initialize(shape0,wtrs0,&shape1,wtrs1,results,shape,false); 00917 GJK gjk; 00918 GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,btVector3(1,1,1)); 00919 if(gjk_status==GJK::eStatus::Valid) 00920 { 00921 btVector3 w0=btVector3(0,0,0); 00922 btVector3 w1=btVector3(0,0,0); 00923 for(U i=0;i<gjk.m_simplex->rank;++i) 00924 { 00925 const btScalar p=gjk.m_simplex->p[i]; 00926 w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p; 00927 w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p; 00928 } 00929 results.witnesses[0] = wtrs0*w0; 00930 results.witnesses[1] = wtrs0*w1; 00931 const btVector3 delta= results.witnesses[1]- 00932 results.witnesses[0]; 00933 const btScalar margin= shape0->getMarginNonVirtual()+ 00934 shape1.getMarginNonVirtual(); 00935 const btScalar length= delta.length(); 00936 results.normal = delta/length; 00937 results.witnesses[0] += results.normal*margin; 00938 return(length-margin); 00939 } 00940 else 00941 { 00942 if(gjk_status==GJK::eStatus::Inside) 00943 { 00944 if(Penetration(shape0,wtrs0,&shape1,wtrs1,gjk.m_ray,results)) 00945 { 00946 const btVector3 delta= results.witnesses[0]- 00947 results.witnesses[1]; 00948 const btScalar length= delta.length(); 00949 if (length >= SIMD_EPSILON) 00950 results.normal = delta/length; 00951 return(-length); 00952 } 00953 } 00954 } 00955 return(SIMD_INFINITY); 00956 } 00957 00958 // 00959 bool btGjkEpaSolver2::SignedDistance(const btConvexShape* shape0, 00960 const btTransform& wtrs0, 00961 const btConvexShape* shape1, 00962 const btTransform& wtrs1, 00963 const btVector3& guess, 00964 sResults& results) 00965 { 00966 if(!Distance(shape0,wtrs0,shape1,wtrs1,guess,results)) 00967 return(Penetration(shape0,wtrs0,shape1,wtrs1,guess,results,false)); 00968 else 00969 return(true); 00970 } 00971 #endif //__SPU__ 00972 00973 /* Symbols cleanup */ 00974 00975 #undef GJK_MAX_ITERATIONS 00976 #undef GJK_ACCURARY 00977 #undef GJK_MIN_DISTANCE 00978 #undef GJK_DUPLICATED_EPS 00979 #undef GJK_SIMPLEX2_EPS 00980 #undef GJK_SIMPLEX3_EPS 00981 #undef GJK_SIMPLEX4_EPS 00982 00983 #undef EPA_MAX_VERTICES 00984 #undef EPA_MAX_FACES 00985 #undef EPA_MAX_ITERATIONS 00986 #undef EPA_ACCURACY 00987 #undef EPA_FALLBACK 00988 #undef EPA_PLANE_EPS 00989 #undef EPA_INSIDE_EPS