btSoftBodyInternals.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908
  1. /*
  2. Bullet Continuous Collision Detection and Physics Library
  3. Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
  4. This software is provided 'as-is', without any express or implied warranty.
  5. In no event will the authors be held liable for any damages arising from the use of this software.
  6. Permission is granted to anyone to use this software for any purpose,
  7. including commercial applications, and to alter it and redistribute it freely,
  8. subject to the following restrictions:
  9. 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.
  10. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  11. 3. This notice may not be removed or altered from any source distribution.
  12. */
  13. ///btSoftBody implementation by Nathanael Presson
  14. #ifndef _BT_SOFT_BODY_INTERNALS_H
  15. #define _BT_SOFT_BODY_INTERNALS_H
  16. #include "btSoftBody.h"
  17. #include "LinearMath/btQuickprof.h"
  18. #include "LinearMath/btPolarDecomposition.h"
  19. #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
  20. #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
  21. #include "BulletCollision/CollisionShapes/btConvexInternalShape.h"
  22. #include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
  23. #include <string.h> //for memset
  24. //
  25. // btSymMatrix
  26. //
  27. template <typename T>
  28. struct btSymMatrix
  29. {
  30. btSymMatrix() : dim(0) {}
  31. btSymMatrix(int n,const T& init=T()) { resize(n,init); }
  32. void resize(int n,const T& init=T()) { dim=n;store.resize((n*(n+1))/2,init); }
  33. int index(int c,int r) const { if(c>r) btSwap(c,r);btAssert(r<dim);return((r*(r+1))/2+c); }
  34. T& operator()(int c,int r) { return(store[index(c,r)]); }
  35. const T& operator()(int c,int r) const { return(store[index(c,r)]); }
  36. btAlignedObjectArray<T> store;
  37. int dim;
  38. };
  39. //
  40. // btSoftBodyCollisionShape
  41. //
  42. class btSoftBodyCollisionShape : public btConcaveShape
  43. {
  44. public:
  45. btSoftBody* m_body;
  46. btSoftBodyCollisionShape(btSoftBody* backptr)
  47. {
  48. m_shapeType = SOFTBODY_SHAPE_PROXYTYPE;
  49. m_body=backptr;
  50. }
  51. virtual ~btSoftBodyCollisionShape()
  52. {
  53. }
  54. void processAllTriangles(btTriangleCallback* /*callback*/,const btVector3& /*aabbMin*/,const btVector3& /*aabbMax*/) const
  55. {
  56. //not yet
  57. btAssert(0);
  58. }
  59. ///getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t.
  60. virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
  61. {
  62. /* t is usually identity, except when colliding against btCompoundShape. See Issue 512 */
  63. const btVector3 mins=m_body->m_bounds[0];
  64. const btVector3 maxs=m_body->m_bounds[1];
  65. const btVector3 crns[]={t*btVector3(mins.x(),mins.y(),mins.z()),
  66. t*btVector3(maxs.x(),mins.y(),mins.z()),
  67. t*btVector3(maxs.x(),maxs.y(),mins.z()),
  68. t*btVector3(mins.x(),maxs.y(),mins.z()),
  69. t*btVector3(mins.x(),mins.y(),maxs.z()),
  70. t*btVector3(maxs.x(),mins.y(),maxs.z()),
  71. t*btVector3(maxs.x(),maxs.y(),maxs.z()),
  72. t*btVector3(mins.x(),maxs.y(),maxs.z())};
  73. aabbMin=aabbMax=crns[0];
  74. for(int i=1;i<8;++i)
  75. {
  76. aabbMin.setMin(crns[i]);
  77. aabbMax.setMax(crns[i]);
  78. }
  79. }
  80. virtual void setLocalScaling(const btVector3& /*scaling*/)
  81. {
  82. ///na
  83. }
  84. virtual const btVector3& getLocalScaling() const
  85. {
  86. static const btVector3 dummy(1,1,1);
  87. return dummy;
  88. }
  89. virtual void calculateLocalInertia(btScalar /*mass*/,btVector3& /*inertia*/) const
  90. {
  91. ///not yet
  92. btAssert(0);
  93. }
  94. virtual const char* getName()const
  95. {
  96. return "SoftBody";
  97. }
  98. };
  99. //
  100. // btSoftClusterCollisionShape
  101. //
  102. class btSoftClusterCollisionShape : public btConvexInternalShape
  103. {
  104. public:
  105. const btSoftBody::Cluster* m_cluster;
  106. btSoftClusterCollisionShape (const btSoftBody::Cluster* cluster) : m_cluster(cluster) { setMargin(0); }
  107. virtual btVector3 localGetSupportingVertex(const btVector3& vec) const
  108. {
  109. btSoftBody::Node* const * n=&m_cluster->m_nodes[0];
  110. btScalar d=btDot(vec,n[0]->m_x);
  111. int j=0;
  112. for(int i=1,ni=m_cluster->m_nodes.size();i<ni;++i)
  113. {
  114. const btScalar k=btDot(vec,n[i]->m_x);
  115. if(k>d) { d=k;j=i; }
  116. }
  117. return(n[j]->m_x);
  118. }
  119. virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const
  120. {
  121. return(localGetSupportingVertex(vec));
  122. }
  123. //notice that the vectors should be unit length
  124. virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
  125. {}
  126. virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const
  127. {}
  128. virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
  129. {}
  130. virtual int getShapeType() const { return SOFTBODY_SHAPE_PROXYTYPE; }
  131. //debugging
  132. virtual const char* getName()const {return "SOFTCLUSTER";}
  133. virtual void setMargin(btScalar margin)
  134. {
  135. btConvexInternalShape::setMargin(margin);
  136. }
  137. virtual btScalar getMargin() const
  138. {
  139. return getMargin();
  140. }
  141. };
  142. //
  143. // Inline's
  144. //
  145. //
  146. template <typename T>
  147. static inline void ZeroInitialize(T& value)
  148. {
  149. memset(&value,0,sizeof(T));
  150. }
  151. //
  152. template <typename T>
  153. static inline bool CompLess(const T& a,const T& b)
  154. { return(a<b); }
  155. //
  156. template <typename T>
  157. static inline bool CompGreater(const T& a,const T& b)
  158. { return(a>b); }
  159. //
  160. template <typename T>
  161. static inline T Lerp(const T& a,const T& b,btScalar t)
  162. { return(a+(b-a)*t); }
  163. //
  164. template <typename T>
  165. static inline T InvLerp(const T& a,const T& b,btScalar t)
  166. { return((b+a*t-b*t)/(a*b)); }
  167. //
  168. static inline btMatrix3x3 Lerp( const btMatrix3x3& a,
  169. const btMatrix3x3& b,
  170. btScalar t)
  171. {
  172. btMatrix3x3 r;
  173. r[0]=Lerp(a[0],b[0],t);
  174. r[1]=Lerp(a[1],b[1],t);
  175. r[2]=Lerp(a[2],b[2],t);
  176. return(r);
  177. }
  178. //
  179. static inline btVector3 Clamp(const btVector3& v,btScalar maxlength)
  180. {
  181. const btScalar sql=v.length2();
  182. if(sql>(maxlength*maxlength))
  183. return((v*maxlength)/btSqrt(sql));
  184. else
  185. return(v);
  186. }
  187. //
  188. template <typename T>
  189. static inline T Clamp(const T& x,const T& l,const T& h)
  190. { return(x<l?l:x>h?h:x); }
  191. //
  192. template <typename T>
  193. static inline T Sq(const T& x)
  194. { return(x*x); }
  195. //
  196. template <typename T>
  197. static inline T Cube(const T& x)
  198. { return(x*x*x); }
  199. //
  200. template <typename T>
  201. static inline T Sign(const T& x)
  202. { return((T)(x<0?-1:+1)); }
  203. //
  204. template <typename T>
  205. static inline bool SameSign(const T& x,const T& y)
  206. { return((x*y)>0); }
  207. //
  208. static inline btScalar ClusterMetric(const btVector3& x,const btVector3& y)
  209. {
  210. const btVector3 d=x-y;
  211. return(btFabs(d[0])+btFabs(d[1])+btFabs(d[2]));
  212. }
  213. //
  214. static inline btMatrix3x3 ScaleAlongAxis(const btVector3& a,btScalar s)
  215. {
  216. const btScalar xx=a.x()*a.x();
  217. const btScalar yy=a.y()*a.y();
  218. const btScalar zz=a.z()*a.z();
  219. const btScalar xy=a.x()*a.y();
  220. const btScalar yz=a.y()*a.z();
  221. const btScalar zx=a.z()*a.x();
  222. btMatrix3x3 m;
  223. m[0]=btVector3(1-xx+xx*s,xy*s-xy,zx*s-zx);
  224. m[1]=btVector3(xy*s-xy,1-yy+yy*s,yz*s-yz);
  225. m[2]=btVector3(zx*s-zx,yz*s-yz,1-zz+zz*s);
  226. return(m);
  227. }
  228. //
  229. static inline btMatrix3x3 Cross(const btVector3& v)
  230. {
  231. btMatrix3x3 m;
  232. m[0]=btVector3(0,-v.z(),+v.y());
  233. m[1]=btVector3(+v.z(),0,-v.x());
  234. m[2]=btVector3(-v.y(),+v.x(),0);
  235. return(m);
  236. }
  237. //
  238. static inline btMatrix3x3 Diagonal(btScalar x)
  239. {
  240. btMatrix3x3 m;
  241. m[0]=btVector3(x,0,0);
  242. m[1]=btVector3(0,x,0);
  243. m[2]=btVector3(0,0,x);
  244. return(m);
  245. }
  246. //
  247. static inline btMatrix3x3 Add(const btMatrix3x3& a,
  248. const btMatrix3x3& b)
  249. {
  250. btMatrix3x3 r;
  251. for(int i=0;i<3;++i) r[i]=a[i]+b[i];
  252. return(r);
  253. }
  254. //
  255. static inline btMatrix3x3 Sub(const btMatrix3x3& a,
  256. const btMatrix3x3& b)
  257. {
  258. btMatrix3x3 r;
  259. for(int i=0;i<3;++i) r[i]=a[i]-b[i];
  260. return(r);
  261. }
  262. //
  263. static inline btMatrix3x3 Mul(const btMatrix3x3& a,
  264. btScalar b)
  265. {
  266. btMatrix3x3 r;
  267. for(int i=0;i<3;++i) r[i]=a[i]*b;
  268. return(r);
  269. }
  270. //
  271. static inline void Orthogonalize(btMatrix3x3& m)
  272. {
  273. m[2]=btCross(m[0],m[1]).normalized();
  274. m[1]=btCross(m[2],m[0]).normalized();
  275. m[0]=btCross(m[1],m[2]).normalized();
  276. }
  277. //
  278. static inline btMatrix3x3 MassMatrix(btScalar im,const btMatrix3x3& iwi,const btVector3& r)
  279. {
  280. const btMatrix3x3 cr=Cross(r);
  281. return(Sub(Diagonal(im),cr*iwi*cr));
  282. }
  283. //
  284. static inline btMatrix3x3 ImpulseMatrix( btScalar dt,
  285. btScalar ima,
  286. btScalar imb,
  287. const btMatrix3x3& iwi,
  288. const btVector3& r)
  289. {
  290. return(Diagonal(1/dt)*Add(Diagonal(ima),MassMatrix(imb,iwi,r)).inverse());
  291. }
  292. //
  293. static inline btMatrix3x3 ImpulseMatrix( btScalar ima,const btMatrix3x3& iia,const btVector3& ra,
  294. btScalar imb,const btMatrix3x3& iib,const btVector3& rb)
  295. {
  296. return(Add(MassMatrix(ima,iia,ra),MassMatrix(imb,iib,rb)).inverse());
  297. }
  298. //
  299. static inline btMatrix3x3 AngularImpulseMatrix( const btMatrix3x3& iia,
  300. const btMatrix3x3& iib)
  301. {
  302. return(Add(iia,iib).inverse());
  303. }
  304. //
  305. static inline btVector3 ProjectOnAxis( const btVector3& v,
  306. const btVector3& a)
  307. {
  308. return(a*btDot(v,a));
  309. }
  310. //
  311. static inline btVector3 ProjectOnPlane( const btVector3& v,
  312. const btVector3& a)
  313. {
  314. return(v-ProjectOnAxis(v,a));
  315. }
  316. //
  317. static inline void ProjectOrigin( const btVector3& a,
  318. const btVector3& b,
  319. btVector3& prj,
  320. btScalar& sqd)
  321. {
  322. const btVector3 d=b-a;
  323. const btScalar m2=d.length2();
  324. if(m2>SIMD_EPSILON)
  325. {
  326. const btScalar t=Clamp<btScalar>(-btDot(a,d)/m2,0,1);
  327. const btVector3 p=a+d*t;
  328. const btScalar l2=p.length2();
  329. if(l2<sqd)
  330. {
  331. prj=p;
  332. sqd=l2;
  333. }
  334. }
  335. }
  336. //
  337. static inline void ProjectOrigin( const btVector3& a,
  338. const btVector3& b,
  339. const btVector3& c,
  340. btVector3& prj,
  341. btScalar& sqd)
  342. {
  343. const btVector3& q=btCross(b-a,c-a);
  344. const btScalar m2=q.length2();
  345. if(m2>SIMD_EPSILON)
  346. {
  347. const btVector3 n=q/btSqrt(m2);
  348. const btScalar k=btDot(a,n);
  349. const btScalar k2=k*k;
  350. if(k2<sqd)
  351. {
  352. const btVector3 p=n*k;
  353. if( (btDot(btCross(a-p,b-p),q)>0)&&
  354. (btDot(btCross(b-p,c-p),q)>0)&&
  355. (btDot(btCross(c-p,a-p),q)>0))
  356. {
  357. prj=p;
  358. sqd=k2;
  359. }
  360. else
  361. {
  362. ProjectOrigin(a,b,prj,sqd);
  363. ProjectOrigin(b,c,prj,sqd);
  364. ProjectOrigin(c,a,prj,sqd);
  365. }
  366. }
  367. }
  368. }
  369. //
  370. template <typename T>
  371. static inline T BaryEval( const T& a,
  372. const T& b,
  373. const T& c,
  374. const btVector3& coord)
  375. {
  376. return(a*coord.x()+b*coord.y()+c*coord.z());
  377. }
  378. //
  379. static inline btVector3 BaryCoord( const btVector3& a,
  380. const btVector3& b,
  381. const btVector3& c,
  382. const btVector3& p)
  383. {
  384. const btScalar w[]={ btCross(a-p,b-p).length(),
  385. btCross(b-p,c-p).length(),
  386. btCross(c-p,a-p).length()};
  387. const btScalar isum=1/(w[0]+w[1]+w[2]);
  388. return(btVector3(w[1]*isum,w[2]*isum,w[0]*isum));
  389. }
  390. //
  391. static btScalar ImplicitSolve( btSoftBody::ImplicitFn* fn,
  392. const btVector3& a,
  393. const btVector3& b,
  394. const btScalar accuracy,
  395. const int maxiterations=256)
  396. {
  397. btScalar span[2]={0,1};
  398. btScalar values[2]={fn->Eval(a),fn->Eval(b)};
  399. if(values[0]>values[1])
  400. {
  401. btSwap(span[0],span[1]);
  402. btSwap(values[0],values[1]);
  403. }
  404. if(values[0]>-accuracy) return(-1);
  405. if(values[1]<+accuracy) return(-1);
  406. for(int i=0;i<maxiterations;++i)
  407. {
  408. const btScalar t=Lerp(span[0],span[1],values[0]/(values[0]-values[1]));
  409. const btScalar v=fn->Eval(Lerp(a,b,t));
  410. if((t<=0)||(t>=1)) break;
  411. if(btFabs(v)<accuracy) return(t);
  412. if(v<0)
  413. { span[0]=t;values[0]=v; }
  414. else
  415. { span[1]=t;values[1]=v; }
  416. }
  417. return(-1);
  418. }
  419. //
  420. static inline btVector3 NormalizeAny(const btVector3& v)
  421. {
  422. const btScalar l=v.length();
  423. if(l>SIMD_EPSILON)
  424. return(v/l);
  425. else
  426. return(btVector3(0,0,0));
  427. }
  428. //
  429. static inline btDbvtVolume VolumeOf( const btSoftBody::Face& f,
  430. btScalar margin)
  431. {
  432. const btVector3* pts[]={ &f.m_n[0]->m_x,
  433. &f.m_n[1]->m_x,
  434. &f.m_n[2]->m_x};
  435. btDbvtVolume vol=btDbvtVolume::FromPoints(pts,3);
  436. vol.Expand(btVector3(margin,margin,margin));
  437. return(vol);
  438. }
  439. //
  440. static inline btVector3 CenterOf( const btSoftBody::Face& f)
  441. {
  442. return((f.m_n[0]->m_x+f.m_n[1]->m_x+f.m_n[2]->m_x)/3);
  443. }
  444. //
  445. static inline btScalar AreaOf( const btVector3& x0,
  446. const btVector3& x1,
  447. const btVector3& x2)
  448. {
  449. const btVector3 a=x1-x0;
  450. const btVector3 b=x2-x0;
  451. const btVector3 cr=btCross(a,b);
  452. const btScalar area=cr.length();
  453. return(area);
  454. }
  455. //
  456. static inline btScalar VolumeOf( const btVector3& x0,
  457. const btVector3& x1,
  458. const btVector3& x2,
  459. const btVector3& x3)
  460. {
  461. const btVector3 a=x1-x0;
  462. const btVector3 b=x2-x0;
  463. const btVector3 c=x3-x0;
  464. return(btDot(a,btCross(b,c)));
  465. }
  466. //
  467. static void EvaluateMedium( const btSoftBodyWorldInfo* wfi,
  468. const btVector3& x,
  469. btSoftBody::sMedium& medium)
  470. {
  471. medium.m_velocity = btVector3(0,0,0);
  472. medium.m_pressure = 0;
  473. medium.m_density = wfi->air_density;
  474. if(wfi->water_density>0)
  475. {
  476. const btScalar depth=-(btDot(x,wfi->water_normal)+wfi->water_offset);
  477. if(depth>0)
  478. {
  479. medium.m_density = wfi->water_density;
  480. medium.m_pressure = depth*wfi->water_density*wfi->m_gravity.length();
  481. }
  482. }
  483. }
  484. //
  485. static inline void ApplyClampedForce( btSoftBody::Node& n,
  486. const btVector3& f,
  487. btScalar dt)
  488. {
  489. const btScalar dtim=dt*n.m_im;
  490. if((f*dtim).length2()>n.m_v.length2())
  491. {/* Clamp */
  492. n.m_f-=ProjectOnAxis(n.m_v,f.normalized())/dtim;
  493. }
  494. else
  495. {/* Apply */
  496. n.m_f+=f;
  497. }
  498. }
  499. //
  500. static inline int MatchEdge( const btSoftBody::Node* a,
  501. const btSoftBody::Node* b,
  502. const btSoftBody::Node* ma,
  503. const btSoftBody::Node* mb)
  504. {
  505. if((a==ma)&&(b==mb)) return(0);
  506. if((a==mb)&&(b==ma)) return(1);
  507. return(-1);
  508. }
  509. //
  510. // btEigen : Extract eigen system,
  511. // straitforward implementation of http://math.fullerton.edu/mathews/n2003/JacobiMethodMod.html
  512. // outputs are NOT sorted.
  513. //
  514. struct btEigen
  515. {
  516. static int system(btMatrix3x3& a,btMatrix3x3* vectors,btVector3* values=0)
  517. {
  518. static const int maxiterations=16;
  519. static const btScalar accuracy=(btScalar)0.0001;
  520. btMatrix3x3& v=*vectors;
  521. int iterations=0;
  522. vectors->setIdentity();
  523. do {
  524. int p=0,q=1;
  525. if(btFabs(a[p][q])<btFabs(a[0][2])) { p=0;q=2; }
  526. if(btFabs(a[p][q])<btFabs(a[1][2])) { p=1;q=2; }
  527. if(btFabs(a[p][q])>accuracy)
  528. {
  529. const btScalar w=(a[q][q]-a[p][p])/(2*a[p][q]);
  530. const btScalar z=btFabs(w);
  531. const btScalar t=w/(z*(btSqrt(1+w*w)+z));
  532. if(t==t)/* [WARNING] let hope that one does not get thrown aways by some compilers... */
  533. {
  534. const btScalar c=1/btSqrt(t*t+1);
  535. const btScalar s=c*t;
  536. mulPQ(a,c,s,p,q);
  537. mulTPQ(a,c,s,p,q);
  538. mulPQ(v,c,s,p,q);
  539. } else break;
  540. } else break;
  541. } while((++iterations)<maxiterations);
  542. if(values)
  543. {
  544. *values=btVector3(a[0][0],a[1][1],a[2][2]);
  545. }
  546. return(iterations);
  547. }
  548. private:
  549. static inline void mulTPQ(btMatrix3x3& a,btScalar c,btScalar s,int p,int q)
  550. {
  551. const btScalar m[2][3]={ {a[p][0],a[p][1],a[p][2]},
  552. {a[q][0],a[q][1],a[q][2]}};
  553. int i;
  554. for(i=0;i<3;++i) a[p][i]=c*m[0][i]-s*m[1][i];
  555. for(i=0;i<3;++i) a[q][i]=c*m[1][i]+s*m[0][i];
  556. }
  557. static inline void mulPQ(btMatrix3x3& a,btScalar c,btScalar s,int p,int q)
  558. {
  559. const btScalar m[2][3]={ {a[0][p],a[1][p],a[2][p]},
  560. {a[0][q],a[1][q],a[2][q]}};
  561. int i;
  562. for(i=0;i<3;++i) a[i][p]=c*m[0][i]-s*m[1][i];
  563. for(i=0;i<3;++i) a[i][q]=c*m[1][i]+s*m[0][i];
  564. }
  565. };
  566. //
  567. // Polar decomposition,
  568. // "Computing the Polar Decomposition with Applications", Nicholas J. Higham, 1986.
  569. //
  570. static inline int PolarDecompose( const btMatrix3x3& m,btMatrix3x3& q,btMatrix3x3& s)
  571. {
  572. static const btPolarDecomposition polar;
  573. return polar.decompose(m, q, s);
  574. }
  575. //
  576. // btSoftColliders
  577. //
  578. struct btSoftColliders
  579. {
  580. //
  581. // ClusterBase
  582. //
  583. struct ClusterBase : btDbvt::ICollide
  584. {
  585. btScalar erp;
  586. btScalar idt;
  587. btScalar m_margin;
  588. btScalar friction;
  589. btScalar threshold;
  590. ClusterBase()
  591. {
  592. erp =(btScalar)1;
  593. idt =0;
  594. m_margin =0;
  595. friction =0;
  596. threshold =(btScalar)0;
  597. }
  598. bool SolveContact( const btGjkEpaSolver2::sResults& res,
  599. btSoftBody::Body ba,const btSoftBody::Body bb,
  600. btSoftBody::CJoint& joint)
  601. {
  602. if(res.distance<m_margin)
  603. {
  604. btVector3 norm = res.normal;
  605. norm.normalize();//is it necessary?
  606. const btVector3 ra=res.witnesses[0]-ba.xform().getOrigin();
  607. const btVector3 rb=res.witnesses[1]-bb.xform().getOrigin();
  608. const btVector3 va=ba.velocity(ra);
  609. const btVector3 vb=bb.velocity(rb);
  610. const btVector3 vrel=va-vb;
  611. const btScalar rvac=btDot(vrel,norm);
  612. btScalar depth=res.distance-m_margin;
  613. // printf("depth=%f\n",depth);
  614. const btVector3 iv=norm*rvac;
  615. const btVector3 fv=vrel-iv;
  616. joint.m_bodies[0] = ba;
  617. joint.m_bodies[1] = bb;
  618. joint.m_refs[0] = ra*ba.xform().getBasis();
  619. joint.m_refs[1] = rb*bb.xform().getBasis();
  620. joint.m_rpos[0] = ra;
  621. joint.m_rpos[1] = rb;
  622. joint.m_cfm = 1;
  623. joint.m_erp = 1;
  624. joint.m_life = 0;
  625. joint.m_maxlife = 0;
  626. joint.m_split = 1;
  627. joint.m_drift = depth*norm;
  628. joint.m_normal = norm;
  629. // printf("normal=%f,%f,%f\n",res.normal.getX(),res.normal.getY(),res.normal.getZ());
  630. joint.m_delete = false;
  631. joint.m_friction = fv.length2()<(rvac*friction*rvac*friction)?1:friction;
  632. joint.m_massmatrix = ImpulseMatrix( ba.invMass(),ba.invWorldInertia(),joint.m_rpos[0],
  633. bb.invMass(),bb.invWorldInertia(),joint.m_rpos[1]);
  634. return(true);
  635. }
  636. return(false);
  637. }
  638. };
  639. //
  640. // CollideCL_RS
  641. //
  642. struct CollideCL_RS : ClusterBase
  643. {
  644. btSoftBody* psb;
  645. const btCollisionObjectWrapper* m_colObjWrap;
  646. void Process(const btDbvtNode* leaf)
  647. {
  648. btSoftBody::Cluster* cluster=(btSoftBody::Cluster*)leaf->data;
  649. btSoftClusterCollisionShape cshape(cluster);
  650. const btConvexShape* rshape=(const btConvexShape*)m_colObjWrap->getCollisionShape();
  651. ///don't collide an anchored cluster with a static/kinematic object
  652. if(m_colObjWrap->getCollisionObject()->isStaticOrKinematicObject() && cluster->m_containsAnchor)
  653. return;
  654. btGjkEpaSolver2::sResults res;
  655. if(btGjkEpaSolver2::SignedDistance( &cshape,btTransform::getIdentity(),
  656. rshape,m_colObjWrap->getWorldTransform(),
  657. btVector3(1,0,0),res))
  658. {
  659. btSoftBody::CJoint joint;
  660. if(SolveContact(res,cluster,m_colObjWrap->getCollisionObject(),joint))//prb,joint))
  661. {
  662. btSoftBody::CJoint* pj=new(btAlignedAlloc(sizeof(btSoftBody::CJoint),16)) btSoftBody::CJoint();
  663. *pj=joint;psb->m_joints.push_back(pj);
  664. if(m_colObjWrap->getCollisionObject()->isStaticOrKinematicObject())
  665. {
  666. pj->m_erp *= psb->m_cfg.kSKHR_CL;
  667. pj->m_split *= psb->m_cfg.kSK_SPLT_CL;
  668. }
  669. else
  670. {
  671. pj->m_erp *= psb->m_cfg.kSRHR_CL;
  672. pj->m_split *= psb->m_cfg.kSR_SPLT_CL;
  673. }
  674. }
  675. }
  676. }
  677. void ProcessColObj(btSoftBody* ps,const btCollisionObjectWrapper* colObWrap)
  678. {
  679. psb = ps;
  680. m_colObjWrap = colObWrap;
  681. idt = ps->m_sst.isdt;
  682. m_margin = m_colObjWrap->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin();
  683. ///Bullet rigid body uses multiply instead of minimum to determine combined friction. Some customization would be useful.
  684. friction = btMin(psb->m_cfg.kDF,m_colObjWrap->getCollisionObject()->getFriction());
  685. btVector3 mins;
  686. btVector3 maxs;
  687. ATTRIBUTE_ALIGNED16(btDbvtVolume) volume;
  688. colObWrap->getCollisionShape()->getAabb(colObWrap->getWorldTransform(),mins,maxs);
  689. volume=btDbvtVolume::FromMM(mins,maxs);
  690. volume.Expand(btVector3(1,1,1)*m_margin);
  691. ps->m_cdbvt.collideTV(ps->m_cdbvt.m_root,volume,*this);
  692. }
  693. };
  694. //
  695. // CollideCL_SS
  696. //
  697. struct CollideCL_SS : ClusterBase
  698. {
  699. btSoftBody* bodies[2];
  700. void Process(const btDbvtNode* la,const btDbvtNode* lb)
  701. {
  702. btSoftBody::Cluster* cla=(btSoftBody::Cluster*)la->data;
  703. btSoftBody::Cluster* clb=(btSoftBody::Cluster*)lb->data;
  704. bool connected=false;
  705. if ((bodies[0]==bodies[1])&&(bodies[0]->m_clusterConnectivity.size()))
  706. {
  707. connected = bodies[0]->m_clusterConnectivity[cla->m_clusterIndex+bodies[0]->m_clusters.size()*clb->m_clusterIndex];
  708. }
  709. if (!connected)
  710. {
  711. btSoftClusterCollisionShape csa(cla);
  712. btSoftClusterCollisionShape csb(clb);
  713. btGjkEpaSolver2::sResults res;
  714. if(btGjkEpaSolver2::SignedDistance( &csa,btTransform::getIdentity(),
  715. &csb,btTransform::getIdentity(),
  716. cla->m_com-clb->m_com,res))
  717. {
  718. btSoftBody::CJoint joint;
  719. if(SolveContact(res,cla,clb,joint))
  720. {
  721. btSoftBody::CJoint* pj=new(btAlignedAlloc(sizeof(btSoftBody::CJoint),16)) btSoftBody::CJoint();
  722. *pj=joint;bodies[0]->m_joints.push_back(pj);
  723. pj->m_erp *= btMax(bodies[0]->m_cfg.kSSHR_CL,bodies[1]->m_cfg.kSSHR_CL);
  724. pj->m_split *= (bodies[0]->m_cfg.kSS_SPLT_CL+bodies[1]->m_cfg.kSS_SPLT_CL)/2;
  725. }
  726. }
  727. } else
  728. {
  729. static int count=0;
  730. count++;
  731. //printf("count=%d\n",count);
  732. }
  733. }
  734. void ProcessSoftSoft(btSoftBody* psa,btSoftBody* psb)
  735. {
  736. idt = psa->m_sst.isdt;
  737. //m_margin = (psa->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin())/2;
  738. m_margin = (psa->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin());
  739. friction = btMin(psa->m_cfg.kDF,psb->m_cfg.kDF);
  740. bodies[0] = psa;
  741. bodies[1] = psb;
  742. psa->m_cdbvt.collideTT(psa->m_cdbvt.m_root,psb->m_cdbvt.m_root,*this);
  743. }
  744. };
  745. //
  746. // CollideSDF_RS
  747. //
  748. struct CollideSDF_RS : btDbvt::ICollide
  749. {
  750. void Process(const btDbvtNode* leaf)
  751. {
  752. btSoftBody::Node* node=(btSoftBody::Node*)leaf->data;
  753. DoNode(*node);
  754. }
  755. void DoNode(btSoftBody::Node& n) const
  756. {
  757. const btScalar m=n.m_im>0?dynmargin:stamargin;
  758. btSoftBody::RContact c;
  759. if( (!n.m_battach)&&
  760. psb->checkContact(m_colObj1Wrap,n.m_x,m,c.m_cti))
  761. {
  762. const btScalar ima=n.m_im;
  763. const btScalar imb= m_rigidBody? m_rigidBody->getInvMass() : 0.f;
  764. const btScalar ms=ima+imb;
  765. if(ms>0)
  766. {
  767. const btTransform& wtr=m_rigidBody?m_rigidBody->getWorldTransform() : m_colObj1Wrap->getCollisionObject()->getWorldTransform();
  768. static const btMatrix3x3 iwiStatic(0,0,0,0,0,0,0,0,0);
  769. const btMatrix3x3& iwi=m_rigidBody?m_rigidBody->getInvInertiaTensorWorld() : iwiStatic;
  770. const btVector3 ra=n.m_x-wtr.getOrigin();
  771. const btVector3 va=m_rigidBody ? m_rigidBody->getVelocityInLocalPoint(ra)*psb->m_sst.sdt : btVector3(0,0,0);
  772. const btVector3 vb=n.m_x-n.m_q;
  773. const btVector3 vr=vb-va;
  774. const btScalar dn=btDot(vr,c.m_cti.m_normal);
  775. const btVector3 fv=vr-c.m_cti.m_normal*dn;
  776. const btScalar fc=psb->m_cfg.kDF*m_colObj1Wrap->getCollisionObject()->getFriction();
  777. c.m_node = &n;
  778. c.m_c0 = ImpulseMatrix(psb->m_sst.sdt,ima,imb,iwi,ra);
  779. c.m_c1 = ra;
  780. c.m_c2 = ima*psb->m_sst.sdt;
  781. c.m_c3 = fv.length2()<(dn*fc*dn*fc)?0:1-fc;
  782. c.m_c4 = m_colObj1Wrap->getCollisionObject()->isStaticOrKinematicObject()?psb->m_cfg.kKHR:psb->m_cfg.kCHR;
  783. psb->m_rcontacts.push_back(c);
  784. if (m_rigidBody)
  785. m_rigidBody->activate();
  786. }
  787. }
  788. }
  789. btSoftBody* psb;
  790. const btCollisionObjectWrapper* m_colObj1Wrap;
  791. btRigidBody* m_rigidBody;
  792. btScalar dynmargin;
  793. btScalar stamargin;
  794. };
  795. //
  796. // CollideVF_SS
  797. //
  798. struct CollideVF_SS : btDbvt::ICollide
  799. {
  800. void Process(const btDbvtNode* lnode,
  801. const btDbvtNode* lface)
  802. {
  803. btSoftBody::Node* node=(btSoftBody::Node*)lnode->data;
  804. btSoftBody::Face* face=(btSoftBody::Face*)lface->data;
  805. btVector3 o=node->m_x;
  806. btVector3 p;
  807. btScalar d=SIMD_INFINITY;
  808. ProjectOrigin( face->m_n[0]->m_x-o,
  809. face->m_n[1]->m_x-o,
  810. face->m_n[2]->m_x-o,
  811. p,d);
  812. const btScalar m=mrg+(o-node->m_q).length()*2;
  813. if(d<(m*m))
  814. {
  815. const btSoftBody::Node* n[]={face->m_n[0],face->m_n[1],face->m_n[2]};
  816. const btVector3 w=BaryCoord(n[0]->m_x,n[1]->m_x,n[2]->m_x,p+o);
  817. const btScalar ma=node->m_im;
  818. btScalar mb=BaryEval(n[0]->m_im,n[1]->m_im,n[2]->m_im,w);
  819. if( (n[0]->m_im<=0)||
  820. (n[1]->m_im<=0)||
  821. (n[2]->m_im<=0))
  822. {
  823. mb=0;
  824. }
  825. const btScalar ms=ma+mb;
  826. if(ms>0)
  827. {
  828. btSoftBody::SContact c;
  829. c.m_normal = p/-btSqrt(d);
  830. c.m_margin = m;
  831. c.m_node = node;
  832. c.m_face = face;
  833. c.m_weights = w;
  834. c.m_friction = btMax(psb[0]->m_cfg.kDF,psb[1]->m_cfg.kDF);
  835. c.m_cfm[0] = ma/ms*psb[0]->m_cfg.kSHR;
  836. c.m_cfm[1] = mb/ms*psb[1]->m_cfg.kSHR;
  837. psb[0]->m_scontacts.push_back(c);
  838. }
  839. }
  840. }
  841. btSoftBody* psb[2];
  842. btScalar mrg;
  843. };
  844. };
  845. #endif //_BT_SOFT_BODY_INTERNALS_H