2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
11 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
15 ///btSoftBody implementation by Nathanael Presson
17 #include "btSoftBodyInternals.h"
20 btSoftBody::btSoftBody(btSoftBodyWorldInfo* worldInfo,int node_count, const btVector3* x, const btScalar* m)
21 :m_worldInfo(worldInfo)
24 m_internalType = CO_SOFT_BODY;
25 m_cfg.aeromodel = eAeroModel::V_Point;
32 m_cfg.kDF = (btScalar)0.2;
34 m_cfg.kCHR = (btScalar)1.0;
35 m_cfg.kKHR = (btScalar)0.1;
36 m_cfg.kSHR = (btScalar)1.0;
37 m_cfg.kAHR = (btScalar)0.7;
38 m_cfg.kSRHR_CL = (btScalar)0.1;
39 m_cfg.kSKHR_CL = (btScalar)1;
40 m_cfg.kSSHR_CL = (btScalar)0.5;
41 m_cfg.kSR_SPLT_CL = (btScalar)0.5;
42 m_cfg.kSK_SPLT_CL = (btScalar)0.5;
43 m_cfg.kSS_SPLT_CL = (btScalar)0.5;
44 m_cfg.maxvolume = (btScalar)1;
46 m_cfg.viterations = 0;
47 m_cfg.piterations = 1;
48 m_cfg.diterations = 0;
49 m_cfg.citerations = 4;
50 m_cfg.collisions = fCollision::Default;
51 m_pose.m_bvolume = false;
52 m_pose.m_bframe = false;
54 m_pose.m_com = btVector3(0,0,0);
55 m_pose.m_rot.setIdentity();
56 m_pose.m_scl.setIdentity();
59 m_bUpdateRtCst = true;
60 m_bounds[0] = btVector3(0,0,0);
61 m_bounds[1] = btVector3(0,0,0);
62 m_worldTransform.setIdentity();
63 setSolver(eSolverPresets::Positions);
64 /* Default material */
65 Material* pm=appendMaterial();
69 pm->m_flags = fMaterial::Default;
71 ///for now, create a collision shape internally
72 setCollisionShape(new btSoftBodyCollisionShape(this));
73 m_collisionShape->setMargin(0.25);
75 const btScalar margin=getCollisionShape()->getMargin();
76 m_nodes.resize(node_count);
77 for(int i=0,ni=node_count;i<ni;++i)
81 n.m_x = x?*x++:btVector3(0,0,0);
84 n.m_im = n.m_im>0?1/n.m_im:0;
85 n.m_leaf = m_ndbvt.insert(btDbvtVolume::FromCR(n.m_x,margin),&n);
94 btSoftBody::~btSoftBody()
96 //for now, delete the internal shape
97 delete m_collisionShape;
100 for(i=0;i<m_clusters.size();++i)
101 btAlignedFree(m_clusters[i]);
102 for(i=0;i<m_materials.size();++i)
103 btAlignedFree(m_materials[i]);
104 for(i=0;i<m_joints.size();++i)
105 btAlignedFree(m_joints[i]);
109 bool btSoftBody::checkLink(int node0,int node1) const
111 return(checkLink(&m_nodes[node0],&m_nodes[node1]));
115 bool btSoftBody::checkLink(const Node* node0,const Node* node1) const
117 const Node* n[]={node0,node1};
118 for(int i=0,ni=m_links.size();i<ni;++i)
120 const Link& l=m_links[i];
121 if( (l.m_n[0]==n[0]&&l.m_n[1]==n[1])||
122 (l.m_n[0]==n[1]&&l.m_n[1]==n[0]))
131 bool btSoftBody::checkFace(int node0,int node1,int node2) const
133 const Node* n[]={ &m_nodes[node0],
136 for(int i=0,ni=m_faces.size();i<ni;++i)
138 const Face& f=m_faces[i];
142 if( (f.m_n[j]==n[0])||
144 (f.m_n[j]==n[2])) c|=1<<j; else break;
146 if(c==7) return(true);
152 btSoftBody::Material* btSoftBody::appendMaterial()
154 Material* pm=new(btAlignedAlloc(sizeof(Material),16)) Material();
155 if(m_materials.size()>0)
159 m_materials.push_back(pm);
164 void btSoftBody::appendNote( const char* text,
177 n.m_coords[0] = c.x();
178 n.m_coords[1] = c.y();
179 n.m_coords[2] = c.z();
180 n.m_coords[3] = c.w();
181 n.m_nodes[0] = n0;n.m_rank+=n0?1:0;
182 n.m_nodes[1] = n1;n.m_rank+=n1?1:0;
183 n.m_nodes[2] = n2;n.m_rank+=n2?1:0;
184 n.m_nodes[3] = n3;n.m_rank+=n3?1:0;
185 m_notes.push_back(n);
189 void btSoftBody::appendNote( const char* text,
193 appendNote(text,o,btVector4(1,0,0,0),feature);
197 void btSoftBody::appendNote( const char* text,
201 static const btScalar w=1/(btScalar)2;
202 appendNote(text,o,btVector4(w,w,0,0), feature->m_n[0],
207 void btSoftBody::appendNote( const char* text,
211 static const btScalar w=1/(btScalar)3;
212 appendNote(text,o,btVector4(w,w,w,0), feature->m_n[0],
218 void btSoftBody::appendNode( const btVector3& x,btScalar m)
220 if(m_nodes.capacity()==m_nodes.size())
223 m_nodes.reserve(m_nodes.size()*2+1);
226 const btScalar margin=getCollisionShape()->getMargin();
227 m_nodes.push_back(Node());
228 Node& n=m_nodes[m_nodes.size()-1];
233 n.m_material = m_materials[0];
234 n.m_leaf = m_ndbvt.insert(btDbvtVolume::FromCR(n.m_x,margin),&n);
238 void btSoftBody::appendLink(int model,Material* mat)
244 { ZeroInitialize(l);l.m_material=mat?mat:m_materials[0]; }
245 m_links.push_back(l);
249 void btSoftBody::appendLink( int node0,
254 appendLink(&m_nodes[node0],&m_nodes[node1],mat,bcheckexist);
258 void btSoftBody::appendLink( Node* node0,
263 if((!bcheckexist)||(!checkLink(node0,node1)))
266 Link& l=m_links[m_links.size()-1];
269 l.m_rl = (l.m_n[0]->m_x-l.m_n[1]->m_x).length();
275 void btSoftBody::appendFace(int model,Material* mat)
279 { f=m_faces[model]; }
281 { ZeroInitialize(f);f.m_material=mat?mat:m_materials[0]; }
282 m_faces.push_back(f);
286 void btSoftBody::appendFace(int node0,int node1,int node2,Material* mat)
289 Face& f=m_faces[m_faces.size()-1];
290 btAssert(node0!=node1);
291 btAssert(node1!=node2);
292 btAssert(node2!=node0);
293 f.m_n[0] = &m_nodes[node0];
294 f.m_n[1] = &m_nodes[node1];
295 f.m_n[2] = &m_nodes[node2];
296 f.m_ra = AreaOf( f.m_n[0]->m_x,
303 void btSoftBody::appendAnchor(int node,btRigidBody* body)
306 a.m_node = &m_nodes[node];
308 a.m_local = body->getInterpolationWorldTransform().inverse()*a.m_node->m_x;
309 a.m_node->m_battach = 1;
310 m_anchors.push_back(a);
314 void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1)
316 LJoint* pj = new(btAlignedAlloc(sizeof(LJoint),16)) LJoint();
317 pj->m_bodies[0] = body0;
318 pj->m_bodies[1] = body1;
319 pj->m_refs[0] = pj->m_bodies[0].xform().inverse()*specs.position;
320 pj->m_refs[1] = pj->m_bodies[1].xform().inverse()*specs.position;
321 pj->m_cfm = specs.cfm;
322 pj->m_erp = specs.erp;
323 pj->m_split = specs.split;
324 m_joints.push_back(pj);
328 void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,Body body)
330 appendLinearJoint(specs,m_clusters[0],body);
334 void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,btSoftBody* body)
336 appendLinearJoint(specs,m_clusters[0],body->m_clusters[0]);
340 void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,Cluster* body0,Body body1)
342 AJoint* pj = new(btAlignedAlloc(sizeof(AJoint),16)) AJoint();
343 pj->m_bodies[0] = body0;
344 pj->m_bodies[1] = body1;
345 pj->m_refs[0] = pj->m_bodies[0].xform().inverse().getBasis()*specs.axis;
346 pj->m_refs[1] = pj->m_bodies[1].xform().inverse().getBasis()*specs.axis;
347 pj->m_cfm = specs.cfm;
348 pj->m_erp = specs.erp;
349 pj->m_split = specs.split;
350 pj->m_icontrol = specs.icontrol;
351 m_joints.push_back(pj);
355 void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,Body body)
357 appendAngularJoint(specs,m_clusters[0],body);
361 void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,btSoftBody* body)
363 appendAngularJoint(specs,m_clusters[0],body->m_clusters[0]);
367 void btSoftBody::addForce(const btVector3& force)
369 for(int i=0,ni=m_nodes.size();i<ni;++i) addForce(force,i);
373 void btSoftBody::addForce(const btVector3& force,int node)
375 Node& n=m_nodes[node];
383 void btSoftBody::addVelocity(const btVector3& velocity)
385 for(int i=0,ni=m_nodes.size();i<ni;++i) addVelocity(velocity,i);
389 void btSoftBody::addVelocity(const btVector3& velocity,int node)
391 Node& n=m_nodes[node];
399 void btSoftBody::setMass(int node,btScalar mass)
401 m_nodes[node].m_im=mass>0?1/mass:0;
406 btScalar btSoftBody::getMass(int node) const
408 return(m_nodes[node].m_im>0?1/m_nodes[node].m_im:0);
412 btScalar btSoftBody::getTotalMass() const
415 for(int i=0;i<m_nodes.size();++i)
423 void btSoftBody::setTotalMass(btScalar mass,bool fromfaces)
430 for(i=0;i<m_nodes.size();++i)
434 for(i=0;i<m_faces.size();++i)
436 const Face& f=m_faces[i];
437 const btScalar twicearea=AreaOf( f.m_n[0]->m_x,
442 f.m_n[j]->m_im+=twicearea;
445 for( i=0;i<m_nodes.size();++i)
447 m_nodes[i].m_im=1/m_nodes[i].m_im;
450 const btScalar tm=getTotalMass();
451 const btScalar itm=1/tm;
452 for( i=0;i<m_nodes.size();++i)
454 m_nodes[i].m_im/=itm*mass;
460 void btSoftBody::setTotalDensity(btScalar density)
462 setTotalMass(getVolume()*density,true);
466 void btSoftBody::transform(const btTransform& trs)
468 const btScalar margin=getCollisionShape()->getMargin();
469 for(int i=0,ni=m_nodes.size();i<ni;++i)
474 n.m_n=trs.getBasis()*n.m_n;
475 m_ndbvt.update(n.m_leaf,btDbvtVolume::FromCR(n.m_x,margin));
483 void btSoftBody::translate(const btVector3& trs)
492 void btSoftBody::rotate( const btQuaternion& rot)
501 void btSoftBody::scale(const btVector3& scl)
503 const btScalar margin=getCollisionShape()->getMargin();
504 for(int i=0,ni=m_nodes.size();i<ni;++i)
509 m_ndbvt.update(n.m_leaf,btDbvtVolume::FromCR(n.m_x,margin));
517 void btSoftBody::setPose(bool bvolume,bool bframe)
519 m_pose.m_bvolume = bvolume;
520 m_pose.m_bframe = bframe;
524 const btScalar omass=getTotalMass();
525 const btScalar kmass=omass*m_nodes.size()*1000;
526 btScalar tmass=omass;
527 m_pose.m_wgh.resize(m_nodes.size());
528 for(i=0,ni=m_nodes.size();i<ni;++i)
530 if(m_nodes[i].m_im<=0) tmass+=kmass;
532 for( i=0,ni=m_nodes.size();i<ni;++i)
535 m_pose.m_wgh[i]= n.m_im>0 ?
536 1/(m_nodes[i].m_im*tmass) :
540 const btVector3 com=evaluateCom();
541 m_pose.m_pos.resize(m_nodes.size());
542 for( i=0,ni=m_nodes.size();i<ni;++i)
544 m_pose.m_pos[i]=m_nodes[i].m_x-com;
546 m_pose.m_volume = bvolume?getVolume():0;
548 m_pose.m_rot.setIdentity();
549 m_pose.m_scl.setIdentity();
553 m_pose.m_aqq[2] = btVector3(0,0,0);
554 for( i=0,ni=m_nodes.size();i<ni;++i)
556 const btVector3& q=m_pose.m_pos[i];
557 const btVector3 mq=m_pose.m_wgh[i]*q;
558 m_pose.m_aqq[0]+=mq.x()*q;
559 m_pose.m_aqq[1]+=mq.y()*q;
560 m_pose.m_aqq[2]+=mq.z()*q;
562 m_pose.m_aqq=m_pose.m_aqq.inverse();
567 btScalar btSoftBody::getVolume() const
574 const btVector3 org=m_nodes[0].m_x;
575 for(i=0,ni=m_faces.size();i<ni;++i)
577 const Face& f=m_faces[i];
578 vol+=dot(f.m_n[0]->m_x-org,cross(f.m_n[1]->m_x-org,f.m_n[2]->m_x-org));
586 int btSoftBody::clusterCount() const
588 return(m_clusters.size());
592 btVector3 btSoftBody::clusterCom(const Cluster* cluster)
594 btVector3 com(0,0,0);
595 for(int i=0,ni=cluster->m_nodes.size();i<ni;++i)
597 com+=cluster->m_nodes[i]->m_x*cluster->m_masses[i];
599 return(com*cluster->m_imass);
603 btVector3 btSoftBody::clusterCom(int cluster) const
605 return(clusterCom(m_clusters[cluster]));
609 btVector3 btSoftBody::clusterVelocity(const Cluster* cluster,const btVector3& rpos)
611 return(cluster->m_lv+cross(cluster->m_av,rpos));
615 void btSoftBody::clusterVImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse)
617 const btVector3 li=cluster->m_imass*impulse;
618 const btVector3 ai=cluster->m_invwi*cross(rpos,impulse);
619 cluster->m_vimpulses[0]+=li;cluster->m_lv+=li;
620 cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai;
621 cluster->m_nvimpulses++;
625 void btSoftBody::clusterDImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse)
627 const btVector3 li=cluster->m_imass*impulse;
628 const btVector3 ai=cluster->m_invwi*cross(rpos,impulse);
629 cluster->m_dimpulses[0]+=li;
630 cluster->m_dimpulses[1]+=ai;
631 cluster->m_ndimpulses++;
635 void btSoftBody::clusterImpulse(Cluster* cluster,const btVector3& rpos,const Impulse& impulse)
637 if(impulse.m_asVelocity) clusterVImpulse(cluster,rpos,impulse.m_velocity);
638 if(impulse.m_asDrift) clusterDImpulse(cluster,rpos,impulse.m_drift);
642 void btSoftBody::clusterVAImpulse(Cluster* cluster,const btVector3& impulse)
644 const btVector3 ai=cluster->m_invwi*impulse;
645 cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai;
646 cluster->m_nvimpulses++;
650 void btSoftBody::clusterDAImpulse(Cluster* cluster,const btVector3& impulse)
652 const btVector3 ai=cluster->m_invwi*impulse;
653 cluster->m_dimpulses[1]+=ai;
654 cluster->m_ndimpulses++;
658 void btSoftBody::clusterAImpulse(Cluster* cluster,const Impulse& impulse)
660 if(impulse.m_asVelocity) clusterVAImpulse(cluster,impulse.m_velocity);
661 if(impulse.m_asDrift) clusterDAImpulse(cluster,impulse.m_drift);
665 void btSoftBody::clusterDCImpulse(Cluster* cluster,const btVector3& impulse)
667 cluster->m_dimpulses[0]+=impulse*cluster->m_imass;
668 cluster->m_ndimpulses++;
672 int btSoftBody::generateBendingConstraints(int distance,Material* mat)
679 const int n=m_nodes.size();
680 const unsigned inf=(~(unsigned)0)>>1;
681 unsigned* adj=new unsigned[n*n];
682 #define IDX(_x_,_y_) ((_y_)*n+(_x_))
687 if(i!=j) adj[IDX(i,j)]=adj[IDX(j,i)]=inf;
689 adj[IDX(i,j)]=adj[IDX(j,i)]=0;
692 for( i=0;i<m_links.size();++i)
694 const int ia=(int)(m_links[i].m_n[0]-&m_nodes[0]);
695 const int ib=(int)(m_links[i].m_n[1]-&m_nodes[0]);
705 const unsigned sum=adj[IDX(i,k)]+adj[IDX(k,j)];
706 if(adj[IDX(i,j)]>sum)
708 adj[IDX(i,j)]=adj[IDX(j,i)]=sum;
719 if(adj[IDX(i,j)]==(unsigned)distance)
722 m_links[m_links.size()-1].m_bbending=1;
734 void btSoftBody::randomizeConstraints()
736 unsigned long seed=243703;
737 #define NEXTRAND (seed=(1664525L*seed+1013904223L)&0xffffffff)
740 for(i=0,ni=m_links.size();i<ni;++i)
742 btSwap(m_links[i],m_links[NEXTRAND%ni]);
744 for(i=0,ni=m_faces.size();i<ni;++i)
746 btSwap(m_faces[i],m_faces[NEXTRAND%ni]);
752 int btSoftBody::generateClusters(int k,int maxiterations)
756 for(i=0;i<m_clusters.size();++i)
758 if(m_clusters[i]->m_leaf) m_cdbvt.remove(m_clusters[i]->m_leaf);
759 btAlignedFree(m_clusters[i]);
761 m_clusters.resize(btMin(k,m_nodes.size()));
765 for(i=0;i<m_clusters.size();++i)
767 m_clusters[i] = new(btAlignedAlloc(sizeof(Cluster),16)) Cluster();
768 m_clusters[i]->m_collide= true;
774 btAlignedObjectArray<btVector3> centers;
775 btVector3 cog(0,0,0);
777 for(i=0;i<m_nodes.size();++i)
780 m_clusters[(i*29873)%m_clusters.size()]->m_nodes.push_back(&m_nodes[i]);
782 cog/=(btScalar)m_nodes.size();
783 centers.resize(k,cog);
785 const btScalar slope=16;
789 const btScalar w=2-btMin<btScalar>(1,iterations/slope);
797 for(int j=0;j<m_clusters[i]->m_nodes.size();++j)
799 c+=m_clusters[i]->m_nodes[j]->m_x;
801 if(m_clusters[i]->m_nodes.size())
803 c /= (btScalar)m_clusters[i]->m_nodes.size();
804 c = centers[i]+(c-centers[i])*w;
805 changed |= ((c-centers[i]).length2()>SIMD_EPSILON);
807 m_clusters[i]->m_nodes.resize(0);
810 for(i=0;i<m_nodes.size();++i)
812 const btVector3 nx=m_nodes[i].m_x;
814 btScalar kdist=ClusterMetric(centers[0],nx);
817 const btScalar d=ClusterMetric(centers[j],nx);
824 m_clusters[kbest]->m_nodes.push_back(&m_nodes[i]);
826 } while(changed&&(iterations<maxiterations));
828 btAlignedObjectArray<int> cids;
829 cids.resize(m_nodes.size(),-1);
830 for(i=0;i<m_clusters.size();++i)
832 for(int j=0;j<m_clusters[i]->m_nodes.size();++j)
834 cids[int(m_clusters[i]->m_nodes[j]-&m_nodes[0])]=i;
837 for(i=0;i<m_faces.size();++i)
839 const int idx[]={ int(m_faces[i].m_n[0]-&m_nodes[0]),
840 int(m_faces[i].m_n[1]-&m_nodes[0]),
841 int(m_faces[i].m_n[2]-&m_nodes[0])};
844 const int cid=cids[idx[j]];
847 const int kid=idx[(j+q)%3];
850 if(m_clusters[cid]->m_nodes.findLinearSearch(&m_nodes[kid])==m_clusters[cid]->m_nodes.size())
852 m_clusters[cid]->m_nodes.push_back(&m_nodes[kid]);
859 if(m_clusters.size()>1)
861 Cluster* pmaster=new(btAlignedAlloc(sizeof(Cluster),16)) Cluster();
862 pmaster->m_collide = false;
863 pmaster->m_nodes.reserve(m_nodes.size());
864 for(int i=0;i<m_nodes.size();++i) pmaster->m_nodes.push_back(&m_nodes[i]);
865 m_clusters.push_back(pmaster);
866 btSwap(m_clusters[0],m_clusters[m_clusters.size()-1]);
869 for(i=0;i<m_clusters.size();++i)
871 if(m_clusters[i]->m_nodes.size()==0)
873 btAlignedFree(m_clusters[i]);
874 btSwap(m_clusters[i],m_clusters[m_clusters.size()-1]);
875 m_clusters.pop_back();
880 initializeClusters();
882 return(m_clusters.size());
888 void btSoftBody::refine(ImplicitFn* ifn,btScalar accurary,bool cut)
890 const Node* nbase = &m_nodes[0];
891 int ncount = m_nodes.size();
892 btSymMatrix<int> edges(ncount,-2);
897 for(i=0;i<m_links.size();++i)
902 if(!SameSign(ifn->Eval(l.m_n[0]->m_x),ifn->Eval(l.m_n[1]->m_x)))
904 btSwap(m_links[i],m_links[m_links.size()-1]);
905 m_links.pop_back();--i;
910 for(i=0;i<m_links.size();++i)
913 edges(int(l.m_n[0]-nbase),int(l.m_n[1]-nbase))=-1;
915 for(i=0;i<m_faces.size();++i)
918 edges(int(f.m_n[0]-nbase),int(f.m_n[1]-nbase))=-1;
919 edges(int(f.m_n[1]-nbase),int(f.m_n[2]-nbase))=-1;
920 edges(int(f.m_n[2]-nbase),int(f.m_n[0]-nbase))=-1;
923 for(i=0;i<ncount;++i)
925 for(j=i+1;j<ncount;++j)
931 const btScalar t=ImplicitSolve(ifn,a.m_x,b.m_x,accurary);
934 const btVector3 x=Lerp(a.m_x,b.m_x,t);
935 const btVector3 v=Lerp(a.m_v,b.m_v,t);
941 const btScalar ma=1/a.m_im;
942 const btScalar mb=1/b.m_im;
943 const btScalar mc=Lerp(ma,mb,t);
944 const btScalar f=(ma+mb)/(ma+mb+mc);
950 { a.m_im/=0.5;m=1/a.m_im; }
955 { b.m_im/=0.5;m=1/b.m_im; }
960 edges(i,j)=m_nodes.size()-1;
961 m_nodes[edges(i,j)].m_v=v;
969 for(i=0,ni=m_links.size();i<ni;++i)
971 Link& feat=m_links[i];
972 const int idx[]={ int(feat.m_n[0]-nbase),
973 int(feat.m_n[1]-nbase)};
974 if((idx[0]<ncount)&&(idx[1]<ncount))
976 const int ni=edges(idx[0],idx[1]);
980 Link* pft[]={ &m_links[i],
981 &m_links[m_links.size()-1]};
982 pft[0]->m_n[0]=&m_nodes[idx[0]];
983 pft[0]->m_n[1]=&m_nodes[ni];
984 pft[1]->m_n[0]=&m_nodes[ni];
985 pft[1]->m_n[1]=&m_nodes[idx[1]];
990 for(i=0;i<m_faces.size();++i)
992 const Face& feat=m_faces[i];
993 const int idx[]={ int(feat.m_n[0]-nbase),
994 int(feat.m_n[1]-nbase),
995 int(feat.m_n[2]-nbase)};
996 for(j=2,k=0;k<3;j=k++)
998 if((idx[j]<ncount)&&(idx[k]<ncount))
1000 const int ni=edges(idx[j],idx[k]);
1004 const int l=(k+1)%3;
1005 Face* pft[]={ &m_faces[i],
1006 &m_faces[m_faces.size()-1]};
1007 pft[0]->m_n[0]=&m_nodes[idx[l]];
1008 pft[0]->m_n[1]=&m_nodes[idx[j]];
1009 pft[0]->m_n[2]=&m_nodes[ni];
1010 pft[1]->m_n[0]=&m_nodes[ni];
1011 pft[1]->m_n[1]=&m_nodes[idx[k]];
1012 pft[1]->m_n[2]=&m_nodes[idx[l]];
1013 appendLink(ni,idx[l],pft[0]->m_material);
1022 btAlignedObjectArray<int> cnodes;
1023 const int pcount=ncount;
1025 ncount=m_nodes.size();
1026 cnodes.resize(ncount,0);
1028 for(i=0;i<ncount;++i)
1030 const btVector3 x=m_nodes[i].m_x;
1031 if((i>=pcount)||(btFabs(ifn->Eval(x))<accurary))
1033 const btVector3 v=m_nodes[i].m_v;
1034 btScalar m=getMass(i);
1035 if(m>0) { m*=0.5;m_nodes[i].m_im/=0.5; }
1037 cnodes[i]=m_nodes.size()-1;
1038 m_nodes[cnodes[i]].m_v=v;
1043 for(i=0,ni=m_links.size();i<ni;++i)
1045 const int id[]={ int(m_links[i].m_n[0]-nbase),
1046 int(m_links[i].m_n[1]-nbase)};
1048 if(cnodes[id[0]]&&cnodes[id[1]])
1051 todetach=m_links.size()-1;
1055 if(( (ifn->Eval(m_nodes[id[0]].m_x)<accurary)&&
1056 (ifn->Eval(m_nodes[id[1]].m_x)<accurary)))
1061 Link& l=m_links[todetach];
1062 for(int j=0;j<2;++j)
1064 int cn=cnodes[int(l.m_n[j]-nbase)];
1065 if(cn) l.m_n[j]=&m_nodes[cn];
1070 for(i=0,ni=m_faces.size();i<ni;++i)
1072 Node** n= m_faces[i].m_n;
1073 if( (ifn->Eval(n[0]->m_x)<accurary)&&
1074 (ifn->Eval(n[1]->m_x)<accurary)&&
1075 (ifn->Eval(n[2]->m_x)<accurary))
1077 for(int j=0;j<3;++j)
1079 int cn=cnodes[int(n[j]-nbase)];
1080 if(cn) n[j]=&m_nodes[cn];
1085 int nnodes=m_nodes.size();
1086 btAlignedObjectArray<int> ranks;
1087 btAlignedObjectArray<int> todelete;
1088 ranks.resize(nnodes,0);
1089 for(i=0,ni=m_links.size();i<ni;++i)
1091 for(int j=0;j<2;++j) ranks[int(m_links[i].m_n[j]-nbase)]++;
1093 for(i=0,ni=m_faces.size();i<ni;++i)
1095 for(int j=0;j<3;++j) ranks[int(m_faces[i].m_n[j]-nbase)]++;
1097 for(i=0;i<m_links.size();++i)
1099 const int id[]={ int(m_links[i].m_n[0]-nbase),
1100 int(m_links[i].m_n[1]-nbase)};
1101 const bool sg[]={ ranks[id[0]]==1,
1107 btSwap(m_links[i],m_links[m_links.size()-1]);
1108 m_links.pop_back();--i;
1112 for(i=nnodes-1;i>=0;--i)
1114 if(!ranks[i]) todelete.push_back(i);
1118 btAlignedObjectArray<int>& map=ranks;
1119 for(int i=0;i<nnodes;++i) map[i]=i;
1120 PointersToIndices(this);
1121 for(int i=0,ni=todelete.size();i<ni;++i)
1125 int& b=map[--nnodes];
1126 m_ndbvt.remove(m_nodes[a].m_leaf);m_nodes[a].m_leaf=0;
1127 btSwap(m_nodes[a],m_nodes[b]);
1130 IndicesToPointers(this,&map[0]);
1131 m_nodes.resize(nnodes);
1135 m_bUpdateRtCst=true;
1139 bool btSoftBody::cutLink(const Node* node0,const Node* node1,btScalar position)
1141 return(cutLink(int(node0-&m_nodes[0]),int(node1-&m_nodes[0]),position));
1145 bool btSoftBody::cutLink(int node0,int node1,btScalar position)
1149 const btVector3 d=m_nodes[node0].m_x-m_nodes[node1].m_x;
1150 const btVector3 x=Lerp(m_nodes[node0].m_x,m_nodes[node1].m_x,position);
1151 const btVector3 v=Lerp(m_nodes[node0].m_v,m_nodes[node1].m_v,position);
1155 Node* pa=&m_nodes[node0];
1156 Node* pb=&m_nodes[node1];
1157 Node* pn[2]={ &m_nodes[m_nodes.size()-2],
1158 &m_nodes[m_nodes.size()-1]};
1161 for(i=0,ni=m_links.size();i<ni;++i)
1163 const int mtch=MatchEdge(m_links[i].m_n[0],m_links[i].m_n[1],pa,pb);
1167 Link* pft[]={&m_links[i],&m_links[m_links.size()-1]};
1168 pft[0]->m_n[1]=pn[mtch];
1169 pft[1]->m_n[0]=pn[1-mtch];
1173 for(i=0,ni=m_faces.size();i<ni;++i)
1175 for(int k=2,l=0;l<3;k=l++)
1177 const int mtch=MatchEdge(m_faces[i].m_n[k],m_faces[i].m_n[l],pa,pb);
1181 Face* pft[]={&m_faces[i],&m_faces[m_faces.size()-1]};
1182 pft[0]->m_n[l]=pn[mtch];
1183 pft[1]->m_n[k]=pn[1-mtch];
1184 appendLink(pn[0],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true);
1185 appendLink(pn[1],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true);
1191 m_ndbvt.remove(pn[0]->m_leaf);
1192 m_ndbvt.remove(pn[1]->m_leaf);
1200 bool btSoftBody::rayCast(const btVector3& org,
1201 const btVector3& dir,
1205 if(m_faces.size()&&m_fdbvt.empty()) initializeFaceTree();
1206 results.body = this;
1207 results.time = maxtime;
1208 results.feature = eFeature::None;
1210 return(rayCast(org,dir,results.time,results.feature,results.index,false)!=0);
1214 void btSoftBody::setSolver(eSolverPresets::_ preset)
1216 m_cfg.m_vsequence.clear();
1217 m_cfg.m_psequence.clear();
1218 m_cfg.m_dsequence.clear();
1221 case eSolverPresets::Positions:
1222 m_cfg.m_psequence.push_back(ePSolver::Anchors);
1223 m_cfg.m_psequence.push_back(ePSolver::RContacts);
1224 m_cfg.m_psequence.push_back(ePSolver::SContacts);
1225 m_cfg.m_psequence.push_back(ePSolver::Linear);
1227 case eSolverPresets::Velocities:
1228 m_cfg.m_vsequence.push_back(eVSolver::Linear);
1230 m_cfg.m_psequence.push_back(ePSolver::Anchors);
1231 m_cfg.m_psequence.push_back(ePSolver::RContacts);
1232 m_cfg.m_psequence.push_back(ePSolver::SContacts);
1234 m_cfg.m_dsequence.push_back(ePSolver::Linear);
1240 void btSoftBody::predictMotion(btScalar dt)
1247 m_bUpdateRtCst=false;
1250 if(m_cfg.collisions&fCollision::VF_SS)
1252 initializeFaceTree();
1257 m_sst.sdt = dt*m_cfg.timescale;
1258 m_sst.isdt = 1/m_sst.sdt;
1259 m_sst.velmrg = m_sst.sdt*3;
1260 m_sst.radmrg = getCollisionShape()->getMargin();
1261 m_sst.updmrg = m_sst.radmrg*(btScalar)0.25;
1263 addVelocity(m_worldInfo->m_gravity*m_sst.sdt);
1266 for(i=0,ni=m_nodes.size();i<ni;++i)
1270 n.m_v += n.m_f*n.m_im*m_sst.sdt;
1271 n.m_x += n.m_v*m_sst.sdt;
1272 n.m_f = btVector3(0,0,0);
1279 for(i=0,ni=m_nodes.size();i<ni;++i)
1282 m_ndbvt.update( n.m_leaf,
1283 btDbvtVolume::FromCR(n.m_x,m_sst.radmrg),
1288 if(!m_fdbvt.empty())
1290 for(int i=0;i<m_faces.size();++i)
1293 const btVector3 v=( f.m_n[0]->m_v+
1296 m_fdbvt.update( f.m_leaf,
1297 VolumeOf(f,m_sst.radmrg),
1305 if(m_pose.m_bframe&&(m_cfg.kMT>0))
1307 const btMatrix3x3 posetrs=m_pose.m_rot;
1308 for(int i=0,ni=m_nodes.size();i<ni;++i)
1313 const btVector3 x=posetrs*m_pose.m_pos[i]+m_pose.m_com;
1314 n.m_x=Lerp(n.m_x,x,m_cfg.kMT);
1318 /* Clear contacts */
1319 m_rcontacts.resize(0);
1320 m_scontacts.resize(0);
1321 /* Optimize dbvt's */
1322 m_ndbvt.optimizeIncremental(1);
1323 m_fdbvt.optimizeIncremental(1);
1324 m_cdbvt.optimizeIncremental(1);
1328 void btSoftBody::solveConstraints()
1330 /* Apply clusters */
1331 applyClusters(false);
1336 for(i=0,ni=m_links.size();i<ni;++i)
1339 l.m_c3 = l.m_n[1]->m_q-l.m_n[0]->m_q;
1340 l.m_c2 = 1/(l.m_c3.length2()*l.m_c0);
1342 /* Prepare anchors */
1343 for(i=0,ni=m_anchors.size();i<ni;++i)
1345 Anchor& a=m_anchors[i];
1346 const btVector3 ra=a.m_body->getWorldTransform().getBasis()*a.m_local;
1347 a.m_c0 = ImpulseMatrix( m_sst.sdt,
1349 a.m_body->getInvMass(),
1350 a.m_body->getInvInertiaTensorWorld(),
1353 a.m_c2 = m_sst.sdt*a.m_node->m_im;
1354 a.m_body->activate();
1356 /* Solve velocities */
1357 if(m_cfg.viterations>0)
1360 for(int isolve=0;isolve<m_cfg.viterations;++isolve)
1362 for(int iseq=0;iseq<m_cfg.m_vsequence.size();++iseq)
1364 getSolver(m_cfg.m_vsequence[iseq])(this,1);
1368 for(i=0,ni=m_nodes.size();i<ni;++i)
1371 n.m_x = n.m_q+n.m_v*m_sst.sdt;
1374 /* Solve positions */
1375 if(m_cfg.piterations>0)
1377 for(int isolve=0;isolve<m_cfg.piterations;++isolve)
1379 const btScalar ti=isolve/(btScalar)m_cfg.piterations;
1380 for(int iseq=0;iseq<m_cfg.m_psequence.size();++iseq)
1382 getSolver(m_cfg.m_psequence[iseq])(this,1,ti);
1385 const btScalar vc=m_sst.isdt*(1-m_cfg.kDP);
1386 for(i=0,ni=m_nodes.size();i<ni;++i)
1389 n.m_v = (n.m_x-n.m_q)*vc;
1390 n.m_f = btVector3(0,0,0);
1394 if(m_cfg.diterations>0)
1396 const btScalar vcf=m_cfg.kVCF*m_sst.isdt;
1397 for(i=0,ni=m_nodes.size();i<ni;++i)
1402 for(int idrift=0;idrift<m_cfg.diterations;++idrift)
1404 for(int iseq=0;iseq<m_cfg.m_dsequence.size();++iseq)
1406 getSolver(m_cfg.m_dsequence[iseq])(this,1,0);
1409 for(int i=0,ni=m_nodes.size();i<ni;++i)
1412 n.m_v += (n.m_x-n.m_q)*vcf;
1415 /* Apply clusters */
1417 applyClusters(true);
1421 void btSoftBody::staticSolve(int iterations)
1423 for(int isolve=0;isolve<iterations;++isolve)
1425 for(int iseq=0;iseq<m_cfg.m_psequence.size();++iseq)
1427 getSolver(m_cfg.m_psequence[iseq])(this,1,0);
1433 void btSoftBody::solveCommonConstraints(btSoftBody** /*bodies*/,int /*count*/,int /*iterations*/)
1439 void btSoftBody::solveClusters(const btAlignedObjectArray<btSoftBody*>& bodies)
1441 const int nb=bodies.size();
1447 iterations=btMax(iterations,bodies[i]->m_cfg.citerations);
1451 bodies[i]->prepareClusters(iterations);
1453 for(i=0;i<iterations;++i)
1455 const btScalar sor=1;
1456 for(int j=0;j<nb;++j)
1458 bodies[j]->solveClusters(sor);
1463 bodies[i]->cleanupClusters();
1468 void btSoftBody::integrateMotion()
1475 btSoftBody::RayCaster::RayCaster(const btVector3& org,const btVector3& dir,btScalar mxt)
1485 void btSoftBody::RayCaster::Process(const btDbvtNode* leaf)
1487 btSoftBody::Face& f=*(btSoftBody::Face*)leaf->data;
1488 const btScalar t=rayTriangle( o,d,
1493 if((t>0)&&(t<mint)) { mint=t;face=&f; }
1498 btScalar btSoftBody::RayCaster::rayTriangle( const btVector3& org,
1499 const btVector3& dir,
1505 static const btScalar ceps=-SIMD_EPSILON*10;
1506 static const btScalar teps=SIMD_EPSILON*10;
1507 const btVector3 n=cross(b-a,c-a);
1508 const btScalar d=dot(a,n);
1509 const btScalar den=dot(dir,n);
1510 if(!btFuzzyZero(den))
1512 const btScalar num=dot(org,n)-d;
1513 const btScalar t=-num/den;
1514 if((t>teps)&&(t<maxt))
1516 const btVector3 hit=org+dir*t;
1517 if( (dot(n,cross(a-hit,b-hit))>ceps) &&
1518 (dot(n,cross(b-hit,c-hit))>ceps) &&
1519 (dot(n,cross(c-hit,a-hit))>ceps))
1529 void btSoftBody::pointersToIndices()
1531 #define PTR2IDX(_p_,_b_) reinterpret_cast<btSoftBody::Node*>((_p_)-(_b_))
1532 btSoftBody::Node* base=&m_nodes[0];
1535 for(i=0,ni=m_nodes.size();i<ni;++i)
1537 if(m_nodes[i].m_leaf)
1539 m_nodes[i].m_leaf->data=*(void**)&i;
1542 for(i=0,ni=m_links.size();i<ni;++i)
1544 m_links[i].m_n[0]=PTR2IDX(m_links[i].m_n[0],base);
1545 m_links[i].m_n[1]=PTR2IDX(m_links[i].m_n[1],base);
1547 for(i=0,ni=m_faces.size();i<ni;++i)
1549 m_faces[i].m_n[0]=PTR2IDX(m_faces[i].m_n[0],base);
1550 m_faces[i].m_n[1]=PTR2IDX(m_faces[i].m_n[1],base);
1551 m_faces[i].m_n[2]=PTR2IDX(m_faces[i].m_n[2],base);
1552 if(m_faces[i].m_leaf)
1554 m_faces[i].m_leaf->data=*(void**)&i;
1557 for(i=0,ni=m_anchors.size();i<ni;++i)
1559 m_anchors[i].m_node=PTR2IDX(m_anchors[i].m_node,base);
1561 for(i=0,ni=m_notes.size();i<ni;++i)
1563 for(int j=0;j<m_notes[i].m_rank;++j)
1565 m_notes[i].m_nodes[j]=PTR2IDX(m_notes[i].m_nodes[j],base);
1572 void btSoftBody::indicesToPointers(const int* map)
1574 #define IDX2PTR(_p_,_b_) map?(&(_b_)[map[(((char*)_p_)-(char*)0)]]): \
1575 (&(_b_)[(((char*)_p_)-(char*)0)])
1576 btSoftBody::Node* base=&m_nodes[0];
1579 for(i=0,ni=m_nodes.size();i<ni;++i)
1581 if(m_nodes[i].m_leaf)
1583 m_nodes[i].m_leaf->data=&m_nodes[i];
1586 for(i=0,ni=m_links.size();i<ni;++i)
1588 m_links[i].m_n[0]=IDX2PTR(m_links[i].m_n[0],base);
1589 m_links[i].m_n[1]=IDX2PTR(m_links[i].m_n[1],base);
1591 for(i=0,ni=m_faces.size();i<ni;++i)
1593 m_faces[i].m_n[0]=IDX2PTR(m_faces[i].m_n[0],base);
1594 m_faces[i].m_n[1]=IDX2PTR(m_faces[i].m_n[1],base);
1595 m_faces[i].m_n[2]=IDX2PTR(m_faces[i].m_n[2],base);
1596 if(m_faces[i].m_leaf)
1598 m_faces[i].m_leaf->data=&m_faces[i];
1601 for(i=0,ni=m_anchors.size();i<ni;++i)
1603 m_anchors[i].m_node=IDX2PTR(m_anchors[i].m_node,base);
1605 for(i=0,ni=m_notes.size();i<ni;++i)
1607 for(int j=0;j<m_notes[i].m_rank;++j)
1609 m_notes[i].m_nodes[j]=IDX2PTR(m_notes[i].m_nodes[j],base);
1616 int btSoftBody::rayCast(const btVector3& org,const btVector3& dir,
1617 btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const
1620 if(bcountonly||m_fdbvt.empty())
1622 for(int i=0,ni=m_faces.size();i<ni;++i)
1624 const btSoftBody::Face& f=m_faces[i];
1625 const btScalar t=RayCaster::rayTriangle( org,dir,
1635 feature=btSoftBody::eFeature::Face;
1644 RayCaster collider(org,dir,mint);
1645 btDbvt::collideRAY(m_fdbvt.m_root,org,dir,collider);
1649 feature=btSoftBody::eFeature::Face;
1650 index=(int)(collider.face-&m_faces[0]);
1658 void btSoftBody::initializeFaceTree()
1661 for(int i=0;i<m_faces.size();++i)
1664 f.m_leaf=m_fdbvt.insert(VolumeOf(f,0),&f);
1669 btVector3 btSoftBody::evaluateCom() const
1671 btVector3 com(0,0,0);
1674 for(int i=0,ni=m_nodes.size();i<ni;++i)
1676 com+=m_nodes[i].m_x*m_pose.m_wgh[i];
1683 bool btSoftBody::checkContact( btRigidBody* prb,
1686 btSoftBody::sCti& cti) const
1689 btCollisionShape* shp=prb->getCollisionShape();
1690 const btTransform& wtr=prb->getInterpolationWorldTransform();
1691 btScalar dst=m_worldInfo->m_sparsesdf.Evaluate( wtr.invXform(x),
1698 cti.m_normal = wtr.getBasis()*nrm;
1699 cti.m_offset = -dot( cti.m_normal,
1700 x-cti.m_normal*dst);
1707 void btSoftBody::updateNormals()
1709 const btVector3 zv(0,0,0);
1712 for(i=0,ni=m_nodes.size();i<ni;++i)
1716 for(i=0,ni=m_faces.size();i<ni;++i)
1718 btSoftBody::Face& f=m_faces[i];
1719 const btVector3 n=cross(f.m_n[1]->m_x-f.m_n[0]->m_x,
1720 f.m_n[2]->m_x-f.m_n[0]->m_x);
1721 f.m_normal=n.normalized();
1726 for(i=0,ni=m_nodes.size();i<ni;++i)
1728 btScalar len = m_nodes[i].m_n.length();
1729 if (len>SIMD_EPSILON)
1730 m_nodes[i].m_n /= len;
1735 void btSoftBody::updateBounds()
1739 const btVector3& mins=m_ndbvt.m_root->volume.Mins();
1740 const btVector3& maxs=m_ndbvt.m_root->volume.Maxs();
1741 const btScalar csm=getCollisionShape()->getMargin();
1742 const btVector3 mrg=btVector3( csm,
1744 csm)*1; // ??? to investigate...
1745 m_bounds[0]=mins-mrg;
1746 m_bounds[1]=maxs+mrg;
1747 if(0!=getBroadphaseHandle())
1749 m_worldInfo->m_broadphase->setAabb( getBroadphaseHandle(),
1752 m_worldInfo->m_dispatcher);
1758 m_bounds[1]=btVector3(0,0,0);
1764 void btSoftBody::updatePose()
1768 btSoftBody::Pose& pose=m_pose;
1769 const btVector3 com=evaluateCom();
1774 const btScalar eps=SIMD_EPSILON;
1775 Apq[0]=Apq[1]=Apq[2]=btVector3(0,0,0);
1776 Apq[0].setX(eps);Apq[1].setY(eps*2);Apq[2].setZ(eps*3);
1777 for(int i=0,ni=m_nodes.size();i<ni;++i)
1779 const btVector3 a=pose.m_wgh[i]*(m_nodes[i].m_x-com);
1780 const btVector3& b=pose.m_pos[i];
1786 PolarDecompose(Apq,r,s);
1788 pose.m_scl=pose.m_aqq*r.transpose()*Apq;
1789 if(m_cfg.maxvolume>1)
1791 const btScalar idet=Clamp<btScalar>( 1/pose.m_scl.determinant(),
1793 pose.m_scl=Mul(pose.m_scl,idet);
1800 void btSoftBody::updateConstants()
1805 for(i=0,ni=m_links.size();i<ni;++i)
1808 Material& m=*l.m_material;
1809 l.m_rl = (l.m_n[0]->m_x-l.m_n[1]->m_x).length();
1810 l.m_c0 = (l.m_n[0]->m_im+l.m_n[1]->m_im)/m.m_kLST;
1811 l.m_c1 = l.m_rl*l.m_rl;
1814 for(i=0,ni=m_faces.size();i<ni;++i)
1817 f.m_ra = AreaOf(f.m_n[0]->m_x,f.m_n[1]->m_x,f.m_n[2]->m_x);
1820 btAlignedObjectArray<int> counts;
1821 counts.resize(m_nodes.size(),0);
1822 for(i=0,ni=m_nodes.size();i<ni;++i)
1824 m_nodes[i].m_area = 0;
1826 for(i=0,ni=m_faces.size();i<ni;++i)
1828 btSoftBody::Face& f=m_faces[i];
1829 for(int j=0;j<3;++j)
1831 const int index=(int)(f.m_n[j]-&m_nodes[0]);
1833 f.m_n[j]->m_area+=btFabs(f.m_ra);
1836 for(i=0,ni=m_nodes.size();i<ni;++i)
1839 m_nodes[i].m_area/=(btScalar)counts[i];
1841 m_nodes[i].m_area=0;
1846 void btSoftBody::initializeClusters()
1850 for( i=0;i<m_clusters.size();++i)
1852 Cluster& c=*m_clusters[i];
1854 c.m_masses.resize(c.m_nodes.size());
1855 for(int j=0;j<c.m_nodes.size();++j)
1857 c.m_masses[j] = c.m_nodes[j]->m_im>0?1/c.m_nodes[j]->m_im:0;
1858 c.m_imass += c.m_masses[j];
1860 c.m_imass = 1/c.m_imass;
1861 c.m_com = btSoftBody::clusterCom(&c);
1862 c.m_lv = btVector3(0,0,0);
1863 c.m_av = btVector3(0,0,0);
1866 btMatrix3x3& ii=c.m_locii;
1867 ii[0]=ii[1]=ii[2]=btVector3(0,0,0);
1871 for(i=0,ni=c.m_nodes.size();i<ni;++i)
1873 const btVector3 k=c.m_nodes[i]->m_x-c.m_com;
1874 const btVector3 q=k*k;
1875 const btScalar m=c.m_masses[i];
1876 ii[0][0] += m*(q[1]+q[2]);
1877 ii[1][1] += m*(q[0]+q[2]);
1878 ii[2][2] += m*(q[0]+q[1]);
1879 ii[0][1] -= m*k[0]*k[1];
1880 ii[0][2] -= m*k[0]*k[2];
1881 ii[1][2] -= m*k[1]*k[2];
1889 c.m_framexform.setIdentity();
1890 c.m_framexform.setOrigin(c.m_com);
1891 c.m_framerefs.resize(c.m_nodes.size());
1894 for(i=0;i<c.m_framerefs.size();++i)
1896 c.m_framerefs[i]=c.m_nodes[i]->m_x-c.m_com;
1903 void btSoftBody::updateClusters()
1905 BT_PROFILE("UpdateClusters");
1908 for(i=0;i<m_clusters.size();++i)
1910 btSoftBody::Cluster& c=*m_clusters[i];
1911 const int n=c.m_nodes.size();
1912 const btScalar invn=1/(btScalar)n;
1916 const btScalar eps=btScalar(0.0001);
1918 m[0]=m[1]=m[2]=btVector3(0,0,0);
1922 c.m_com=clusterCom(&c);
1923 for(int i=0;i<c.m_nodes.size();++i)
1925 const btVector3 a=c.m_nodes[i]->m_x-c.m_com;
1926 const btVector3& b=c.m_framerefs[i];
1927 m[0]+=a[0]*b;m[1]+=a[1]*b;m[2]+=a[2]*b;
1929 PolarDecompose(m,r,s);
1930 c.m_framexform.setOrigin(c.m_com);
1931 c.m_framexform.setBasis(r);
1934 c.m_invwi=c.m_framexform.getBasis()*c.m_locii*c.m_framexform.getBasis().transpose();
1937 const btScalar rk=(2*c.m_extents.length2())/(5*c.m_imass);
1938 const btVector3 inertia(rk,rk,rk);
1939 const btVector3 iin(btFabs(inertia[0])>SIMD_EPSILON?1/inertia[0]:0,
1940 btFabs(inertia[1])>SIMD_EPSILON?1/inertia[1]:0,
1941 btFabs(inertia[2])>SIMD_EPSILON?1/inertia[2]:0);
1943 c.m_invwi=c.m_xform.getBasis().scaled(iin)*c.m_xform.getBasis().transpose();
1945 c.m_invwi[0]=c.m_invwi[1]=c.m_invwi[2]=btVector3(0,0,0);
1946 for(int i=0;i<n;++i)
1948 const btVector3 k=c.m_nodes[i]->m_x-c.m_com;
1949 const btVector3 q=k*k;
1950 const btScalar m=1/c.m_nodes[i]->m_im;
1951 c.m_invwi[0][0] += m*(q[1]+q[2]);
1952 c.m_invwi[1][1] += m*(q[0]+q[2]);
1953 c.m_invwi[2][2] += m*(q[0]+q[1]);
1954 c.m_invwi[0][1] -= m*k[0]*k[1];
1955 c.m_invwi[0][2] -= m*k[0]*k[2];
1956 c.m_invwi[1][2] -= m*k[1]*k[2];
1958 c.m_invwi[1][0]=c.m_invwi[0][1];
1959 c.m_invwi[2][0]=c.m_invwi[0][2];
1960 c.m_invwi[2][1]=c.m_invwi[1][2];
1961 c.m_invwi=c.m_invwi.inverse();
1965 c.m_lv=btVector3(0,0,0);
1966 c.m_av=btVector3(0,0,0);
1972 const btVector3 v=c.m_nodes[i]->m_v*c.m_masses[i];
1974 c.m_av += cross(c.m_nodes[i]->m_x-c.m_com,v);
1977 c.m_lv=c.m_imass*c.m_lv*(1-c.m_ldamping);
1978 c.m_av=c.m_invwi*c.m_av*(1-c.m_adamping);
1980 c.m_vimpulses[1] = btVector3(0,0,0);
1982 c.m_dimpulses[1] = btVector3(0,0,0);
1988 for(int j=0;j<c.m_nodes.size();++j)
1990 Node& n=*c.m_nodes[j];
1991 const btVector3 x=c.m_framexform*c.m_framerefs[j];
1992 n.m_x=Lerp(n.m_x,x,c.m_matching);
1998 btVector3 mi=c.m_nodes[0]->m_x;
2000 for(int j=1;j<n;++j)
2002 mi.setMin(c.m_nodes[j]->m_x);
2003 mx.setMax(c.m_nodes[j]->m_x);
2005 const btDbvtVolume bounds=btDbvtVolume::FromMM(mi,mx);
2007 m_cdbvt.update(c.m_leaf,bounds,c.m_lv*m_sst.sdt*3,m_sst.radmrg);
2009 c.m_leaf=m_cdbvt.insert(bounds,&c);
2016 void btSoftBody::cleanupClusters()
2018 for(int i=0;i<m_joints.size();++i)
2020 m_joints[i]->Terminate(m_sst.sdt);
2021 if(m_joints[i]->m_delete)
2023 btAlignedFree(m_joints[i]);
2024 m_joints.remove(m_joints[i--]);
2030 void btSoftBody::prepareClusters(int iterations)
2032 for(int i=0;i<m_joints.size();++i)
2034 m_joints[i]->Prepare(m_sst.sdt,iterations);
2040 void btSoftBody::solveClusters(btScalar sor)
2042 for(int i=0,ni=m_joints.size();i<ni;++i)
2044 m_joints[i]->Solve(m_sst.sdt,sor);
2049 void btSoftBody::applyClusters(bool drift)
2051 BT_PROFILE("ApplyClusters");
2052 const btScalar f0=m_sst.sdt;
2053 const btScalar f1=f0/2;
2054 btAlignedObjectArray<btVector3> deltas;
2055 btAlignedObjectArray<btScalar> weights;
2056 deltas.resize(m_nodes.size(),btVector3(0,0,0));
2057 weights.resize(m_nodes.size(),0);
2062 for(i=0;i<m_clusters.size();++i)
2064 Cluster& c=*m_clusters[i];
2067 c.m_dimpulses[0]/=(btScalar)c.m_ndimpulses;
2068 c.m_dimpulses[1]/=(btScalar)c.m_ndimpulses;
2072 for(i=0;i<m_clusters.size();++i)
2074 Cluster& c=*m_clusters[i];
2075 if(0<(drift?c.m_ndimpulses:c.m_nvimpulses))
2077 const btVector3 v=(drift?c.m_dimpulses[0]:c.m_vimpulses[0])*m_sst.sdt;
2078 const btVector3 w=(drift?c.m_dimpulses[1]:c.m_vimpulses[1])*m_sst.sdt;
2079 for(int j=0;j<c.m_nodes.size();++j)
2081 const int idx=int(c.m_nodes[j]-&m_nodes[0]);
2082 const btVector3& x=c.m_nodes[j]->m_x;
2083 const btScalar q=c.m_masses[j];
2084 deltas[idx] += (v+cross(w,x-c.m_com))*q;
2089 for(i=0;i<deltas.size();++i)
2091 if(weights[i]>0) m_nodes[i].m_x+=deltas[i]/weights[i];
2096 void btSoftBody::dampClusters()
2100 for(i=0;i<m_clusters.size();++i)
2102 Cluster& c=*m_clusters[i];
2105 for(int j=0;j<c.m_nodes.size();++j)
2107 Node& n=*c.m_nodes[j];
2110 const btVector3 vx=c.m_lv+cross(c.m_av,c.m_nodes[j]->m_q-c.m_com);
2111 n.m_v += c.m_ndamping*(vx-n.m_v);
2119 void btSoftBody::Joint::Prepare(btScalar dt,int)
2121 m_bodies[0].activate();
2122 m_bodies[1].activate();
2126 void btSoftBody::LJoint::Prepare(btScalar dt,int iterations)
2128 static const btScalar maxdrift=4;
2129 Joint::Prepare(dt,iterations);
2130 m_rpos[0] = m_bodies[0].xform()*m_refs[0];
2131 m_rpos[1] = m_bodies[1].xform()*m_refs[1];
2132 m_drift = Clamp(m_rpos[0]-m_rpos[1],maxdrift)*m_erp/dt;
2133 m_rpos[0] -= m_bodies[0].xform().getOrigin();
2134 m_rpos[1] -= m_bodies[1].xform().getOrigin();
2135 m_massmatrix = ImpulseMatrix( m_bodies[0].invMass(),m_bodies[0].invWorldInertia(),m_rpos[0],
2136 m_bodies[1].invMass(),m_bodies[1].invWorldInertia(),m_rpos[1]);
2139 m_sdrift = m_massmatrix*(m_drift*m_split);
2140 m_drift *= 1-m_split;
2142 m_drift /=(btScalar)iterations;
2146 void btSoftBody::LJoint::Solve(btScalar dt,btScalar sor)
2148 const btVector3 va=m_bodies[0].velocity(m_rpos[0]);
2149 const btVector3 vb=m_bodies[1].velocity(m_rpos[1]);
2150 const btVector3 vr=va-vb;
2151 btSoftBody::Impulse impulse;
2152 impulse.m_asVelocity = 1;
2153 impulse.m_velocity = m_massmatrix*(m_drift+vr*m_cfm)*sor;
2154 m_bodies[0].applyImpulse(-impulse,m_rpos[0]);
2155 m_bodies[1].applyImpulse( impulse,m_rpos[1]);
2159 void btSoftBody::LJoint::Terminate(btScalar dt)
2163 m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]);
2164 m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]);
2169 void btSoftBody::AJoint::Prepare(btScalar dt,int iterations)
2171 static const btScalar maxdrift=SIMD_PI/16;
2172 m_icontrol->Prepare(this);
2173 Joint::Prepare(dt,iterations);
2174 m_axis[0] = m_bodies[0].xform().getBasis()*m_refs[0];
2175 m_axis[1] = m_bodies[1].xform().getBasis()*m_refs[1];
2176 m_drift = NormalizeAny(cross(m_axis[1],m_axis[0]));
2177 m_drift *= btMin(maxdrift,btAcos(Clamp<btScalar>(dot(m_axis[0],m_axis[1]),-1,+1)));
2178 m_drift *= m_erp/dt;
2179 m_massmatrix= AngularImpulseMatrix(m_bodies[0].invWorldInertia(),m_bodies[1].invWorldInertia());
2182 m_sdrift = m_massmatrix*(m_drift*m_split);
2183 m_drift *= 1-m_split;
2185 m_drift /=(btScalar)iterations;
2189 void btSoftBody::AJoint::Solve(btScalar dt,btScalar sor)
2191 const btVector3 va=m_bodies[0].angularVelocity();
2192 const btVector3 vb=m_bodies[1].angularVelocity();
2193 const btVector3 vr=va-vb;
2194 const btScalar sp=dot(vr,m_axis[0]);
2195 const btVector3 vc=vr-m_axis[0]*m_icontrol->Speed(this,sp);
2196 btSoftBody::Impulse impulse;
2197 impulse.m_asVelocity = 1;
2198 impulse.m_velocity = m_massmatrix*(m_drift+vc*m_cfm)*sor;
2199 m_bodies[0].applyAImpulse(-impulse);
2200 m_bodies[1].applyAImpulse( impulse);
2204 void btSoftBody::AJoint::Terminate(btScalar dt)
2208 m_bodies[0].applyDAImpulse(-m_sdrift);
2209 m_bodies[1].applyDAImpulse( m_sdrift);
2214 void btSoftBody::CJoint::Prepare(btScalar dt,int iterations)
2216 Joint::Prepare(dt,iterations);
2217 const bool dodrift=(m_life==0);
2218 m_delete=(++m_life)>m_maxlife;
2221 m_drift=m_drift*m_erp/dt;
2224 m_sdrift = m_massmatrix*(m_drift*m_split);
2225 m_drift *= 1-m_split;
2227 m_drift/=(btScalar)iterations;
2231 m_drift=m_sdrift=btVector3(0,0,0);
2236 void btSoftBody::CJoint::Solve(btScalar dt,btScalar sor)
2238 const btVector3 va=m_bodies[0].velocity(m_rpos[0]);
2239 const btVector3 vb=m_bodies[1].velocity(m_rpos[1]);
2240 const btVector3 vrel=va-vb;
2241 const btScalar rvac=dot(vrel,m_normal);
2242 btSoftBody::Impulse impulse;
2243 impulse.m_asVelocity = 1;
2244 impulse.m_velocity = m_drift;
2247 const btVector3 iv=m_normal*rvac;
2248 const btVector3 fv=vrel-iv;
2249 impulse.m_velocity += iv+fv*m_friction;
2251 impulse.m_velocity=m_massmatrix*impulse.m_velocity*sor;
2252 m_bodies[0].applyImpulse(-impulse,m_rpos[0]);
2253 m_bodies[1].applyImpulse( impulse,m_rpos[1]);
2257 void btSoftBody::CJoint::Terminate(btScalar dt)
2261 m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]);
2262 m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]);
2267 void btSoftBody::applyForces()
2269 BT_PROFILE("SoftBody applyForces");
2270 const btScalar dt=m_sst.sdt;
2271 const btScalar kLF=m_cfg.kLF;
2272 const btScalar kDG=m_cfg.kDG;
2273 const btScalar kPR=m_cfg.kPR;
2274 const btScalar kVC=m_cfg.kVC;
2275 const bool as_lift=kLF>0;
2276 const bool as_drag=kDG>0;
2277 const bool as_pressure=kPR!=0;
2278 const bool as_volume=kVC>0;
2279 const bool as_aero= as_lift ||
2281 const bool as_vaero= as_aero &&
2282 (m_cfg.aeromodel<btSoftBody::eAeroModel::F_TwoSided);
2283 const bool as_faero= as_aero &&
2284 (m_cfg.aeromodel>=btSoftBody::eAeroModel::F_TwoSided);
2285 const bool use_medium= as_aero;
2286 const bool use_volume= as_pressure ||
2289 btScalar ivolumetp=0;
2290 btScalar dvolumetv=0;
2291 btSoftBody::sMedium medium;
2294 volume = getVolume();
2295 ivolumetp = 1/btFabs(volume)*kPR;
2296 dvolumetv = (m_pose.m_volume-volume)*kVC;
2298 /* Per vertex forces */
2301 for(i=0,ni=m_nodes.size();i<ni;++i)
2303 btSoftBody::Node& n=m_nodes[i];
2308 EvaluateMedium(m_worldInfo,n.m_x,medium);
2312 const btVector3 rel_v=n.m_v-medium.m_velocity;
2313 const btScalar rel_v2=rel_v.length2();
2314 if(rel_v2>SIMD_EPSILON)
2316 btVector3 nrm=n.m_n;
2318 switch(m_cfg.aeromodel)
2320 case btSoftBody::eAeroModel::V_Point:
2321 nrm=NormalizeAny(rel_v);break;
2322 case btSoftBody::eAeroModel::V_TwoSided:
2323 nrm*=(btScalar)(dot(nrm,rel_v)<0?-1:+1);break;
2325 const btScalar dvn=dot(rel_v,nrm);
2326 /* Compute forces */
2329 btVector3 force(0,0,0);
2330 const btScalar c0 = n.m_area*dvn*rel_v2/2;
2331 const btScalar c1 = c0*medium.m_density;
2332 force += nrm*(-c1*kLF);
2333 force += rel_v.normalized()*(-c1*kDG);
2334 ApplyClampedForce(n,force,dt);
2342 n.m_f += n.m_n*(n.m_area*ivolumetp);
2347 n.m_f += n.m_n*(n.m_area*dvolumetv);
2351 /* Per face forces */
2352 for(i=0,ni=m_faces.size();i<ni;++i)
2354 btSoftBody::Face& f=m_faces[i];
2357 const btVector3 v=(f.m_n[0]->m_v+f.m_n[1]->m_v+f.m_n[2]->m_v)/3;
2358 const btVector3 x=(f.m_n[0]->m_x+f.m_n[1]->m_x+f.m_n[2]->m_x)/3;
2359 EvaluateMedium(m_worldInfo,x,medium);
2360 const btVector3 rel_v=v-medium.m_velocity;
2361 const btScalar rel_v2=rel_v.length2();
2362 if(rel_v2>SIMD_EPSILON)
2364 btVector3 nrm=f.m_normal;
2366 switch(m_cfg.aeromodel)
2368 case btSoftBody::eAeroModel::F_TwoSided:
2369 nrm*=(btScalar)(dot(nrm,rel_v)<0?-1:+1);break;
2371 const btScalar dvn=dot(rel_v,nrm);
2372 /* Compute forces */
2375 btVector3 force(0,0,0);
2376 const btScalar c0 = f.m_ra*dvn*rel_v2;
2377 const btScalar c1 = c0*medium.m_density;
2378 force += nrm*(-c1*kLF);
2379 force += rel_v.normalized()*(-c1*kDG);
2381 for(int j=0;j<3;++j) ApplyClampedForce(*f.m_n[j],force,dt);
2389 void btSoftBody::PSolve_Anchors(btSoftBody* psb,btScalar kst,btScalar ti)
2391 const btScalar kAHR=psb->m_cfg.kAHR*kst;
2392 const btScalar dt=psb->m_sst.sdt;
2393 for(int i=0,ni=psb->m_anchors.size();i<ni;++i)
2395 const Anchor& a=psb->m_anchors[i];
2396 const btTransform& t=a.m_body->getInterpolationWorldTransform();
2398 const btVector3 wa=t*a.m_local;
2399 const btVector3 va=a.m_body->getVelocityInLocalPoint(a.m_c1)*dt;
2400 const btVector3 vb=n.m_x-n.m_q;
2401 const btVector3 vr=(va-vb)+(wa-n.m_x)*kAHR;
2402 const btVector3 impulse=a.m_c0*vr;
2403 n.m_x+=impulse*a.m_c2;
2404 a.m_body->applyImpulse(-impulse,a.m_c1);
2409 void btSoftBody::PSolve_RContacts(btSoftBody* psb,btScalar kst,btScalar ti)
2411 const btScalar dt=psb->m_sst.sdt;
2412 const btScalar mrg=psb->getCollisionShape()->getMargin();
2413 for(int i=0,ni=psb->m_rcontacts.size();i<ni;++i)
2415 const RContact& c=psb->m_rcontacts[i];
2416 const sCti& cti=c.m_cti;
2417 const btVector3 va=cti.m_body->getVelocityInLocalPoint(c.m_c1)*dt;
2418 const btVector3 vb=c.m_node->m_x-c.m_node->m_q;
2419 const btVector3 vr=vb-va;
2420 const btScalar dn=dot(vr,cti.m_normal);
2421 if(dn<=SIMD_EPSILON)
2423 const btScalar dp=btMin(dot(c.m_node->m_x,cti.m_normal)+cti.m_offset,mrg);
2424 const btVector3 fv=vr-cti.m_normal*dn;
2425 const btVector3 impulse=c.m_c0*((vr-fv*c.m_c3+cti.m_normal*(dp*c.m_c4))*kst);
2426 c.m_node->m_x-=impulse*c.m_c2;
2427 c.m_cti.m_body->applyImpulse(impulse,c.m_c1);
2433 void btSoftBody::PSolve_SContacts(btSoftBody* psb,btScalar,btScalar ti)
2435 for(int i=0,ni=psb->m_scontacts.size();i<ni;++i)
2437 const SContact& c=psb->m_scontacts[i];
2438 const btVector3& nr=c.m_normal;
2441 const btVector3 p=BaryEval( f.m_n[0]->m_x,
2445 const btVector3 q=BaryEval( f.m_n[0]->m_q,
2449 const btVector3 vr=(n.m_x-n.m_q)-(p-q);
2450 btVector3 corr(0,0,0);
2453 const btScalar j=c.m_margin-(dot(nr,n.m_x)-dot(nr,p));
2456 corr -= ProjectOnPlane(vr,nr)*c.m_friction;
2457 n.m_x += corr*c.m_cfm[0];
2458 f.m_n[0]->m_x -= corr*(c.m_cfm[1]*c.m_weights.x());
2459 f.m_n[1]->m_x -= corr*(c.m_cfm[1]*c.m_weights.y());
2460 f.m_n[2]->m_x -= corr*(c.m_cfm[1]*c.m_weights.z());
2465 void btSoftBody::PSolve_Links(btSoftBody* psb,btScalar kst,btScalar ti)
2467 for(int i=0,ni=psb->m_links.size();i<ni;++i)
2469 Link& l=psb->m_links[i];
2474 const btVector3 del=b.m_x-a.m_x;
2475 const btScalar len=del.length2();
2476 const btScalar k=((l.m_c1-len)/(l.m_c0*(l.m_c1+len)))*kst;
2477 const btScalar t=k*a.m_im;
2478 a.m_x-=del*(k*a.m_im);
2479 b.m_x+=del*(k*b.m_im);
2485 void btSoftBody::VSolve_Links(btSoftBody* psb,btScalar kst)
2487 for(int i=0,ni=psb->m_links.size();i<ni;++i)
2489 Link& l=psb->m_links[i];
2491 const btScalar j=-dot(l.m_c3,n[0]->m_v-n[1]->m_v)*l.m_c2*kst;
2492 n[0]->m_v+= l.m_c3*(j*n[0]->m_im);
2493 n[1]->m_v-= l.m_c3*(j*n[1]->m_im);
2498 btSoftBody::psolver_t btSoftBody::getSolver(ePSolver::_ solver)
2502 case ePSolver::Anchors: return(&btSoftBody::PSolve_Anchors);
2503 case ePSolver::Linear: return(&btSoftBody::PSolve_Links);
2504 case ePSolver::RContacts: return(&btSoftBody::PSolve_RContacts);
2505 case ePSolver::SContacts: return(&btSoftBody::PSolve_SContacts);
2511 btSoftBody::vsolver_t btSoftBody::getSolver(eVSolver::_ solver)
2515 case eVSolver::Linear: return(&btSoftBody::VSolve_Links);
2521 void btSoftBody::defaultCollisionHandler(btCollisionObject* pco)
2523 switch(m_cfg.collisions&fCollision::RVSmask)
2525 case fCollision::SDF_RS:
2527 btSoftColliders::CollideSDF_RS docollide;
2528 btRigidBody* prb=btRigidBody::upcast(pco);
2529 const btTransform wtr=prb->getInterpolationWorldTransform();
2530 const btTransform ctr=prb->getWorldTransform();
2531 const btScalar timemargin=(wtr.getOrigin()-ctr.getOrigin()).length();
2532 const btScalar basemargin=getCollisionShape()->getMargin();
2535 btDbvtVolume volume;
2536 pco->getCollisionShape()->getAabb( pco->getInterpolationWorldTransform(),
2539 volume=btDbvtVolume::FromMM(mins,maxs);
2540 volume.Expand(btVector3(basemargin,basemargin,basemargin));
2541 docollide.psb = this;
2542 docollide.prb = prb;
2543 docollide.dynmargin = basemargin+timemargin;
2544 docollide.stamargin = basemargin;
2545 btDbvt::collideTV(m_ndbvt.m_root,volume,docollide);
2548 case fCollision::CL_RS:
2550 btSoftColliders::CollideCL_RS collider;
2551 collider.Process(this,btRigidBody::upcast(pco));
2558 void btSoftBody::defaultCollisionHandler(btSoftBody* psb)
2560 const int cf=m_cfg.collisions&psb->m_cfg.collisions;
2561 switch(cf&fCollision::SVSmask)
2563 case fCollision::CL_SS:
2565 btSoftColliders::CollideCL_SS docollide;
2566 docollide.Process(this,psb);
2569 case fCollision::VF_SS:
2571 btSoftColliders::CollideVF_SS docollide;
2573 docollide.mrg= getCollisionShape()->getMargin()+
2574 psb->getCollisionShape()->getMargin();
2575 /* psb0 nodes vs psb1 faces */
2576 docollide.psb[0]=this;
2577 docollide.psb[1]=psb;
2578 btDbvt::collideTT( docollide.psb[0]->m_ndbvt.m_root,
2579 docollide.psb[1]->m_fdbvt.m_root,
2581 /* psb1 nodes vs psb0 faces */
2582 docollide.psb[0]=psb;
2583 docollide.psb[1]=this;
2584 btDbvt::collideTT( docollide.psb[0]->m_ndbvt.m_root,
2585 docollide.psb[1]->m_fdbvt.m_root,