Changeset 1972 for code/branches/physics/src/bullet/BulletSoftBody
- Timestamp:
- Oct 20, 2008, 5:40:38 PM (16 years ago)
- Location:
- code/branches/physics/src/bullet/BulletSoftBody
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/physics/src/bullet/BulletSoftBody/btSoftBody.cpp
r1963 r1972 151 151 btSoftBody::Material* btSoftBody::appendMaterial() 152 152 { 153 154 155 153 Material* pm=new(btAlignedAlloc(sizeof(Material),16)) Material(); 154 if(m_materials.size()>0) 155 *pm=*m_materials[0]; 156 156 else 157 158 159 157 ZeroInitialize(*pm); 158 m_materials.push_back(pm); 159 return(pm); 160 160 } 161 161 162 162 // 163 163 void btSoftBody::appendNote( const char* text, 164 165 166 167 168 169 170 { 171 172 173 174 175 176 177 178 179 180 181 182 183 184 164 const btVector3& o, 165 const btVector4& c, 166 Node* n0, 167 Node* n1, 168 Node* n2, 169 Node* n3) 170 { 171 Note n; 172 ZeroInitialize(n); 173 n.m_rank = 0; 174 n.m_text = text; 175 n.m_offset = o; 176 n.m_coords[0] = c.x(); 177 n.m_coords[1] = c.y(); 178 n.m_coords[2] = c.z(); 179 n.m_coords[3] = c.w(); 180 n.m_nodes[0] = n0;n.m_rank+=n0?1:0; 181 n.m_nodes[1] = n1;n.m_rank+=n1?1:0; 182 n.m_nodes[2] = n2;n.m_rank+=n2?1:0; 183 n.m_nodes[3] = n3;n.m_rank+=n3?1:0; 184 m_notes.push_back(n); 185 185 } 186 186 187 187 // 188 188 void btSoftBody::appendNote( const char* text, 189 190 191 { 192 189 const btVector3& o, 190 Node* feature) 191 { 192 appendNote(text,o,btVector4(1,0,0,0),feature); 193 193 } 194 194 195 195 // 196 196 void btSoftBody::appendNote( const char* text, 197 198 199 { 200 201 202 feature->m_n[1]);203 } 204 197 const btVector3& o, 198 Link* feature) 199 { 200 static const btScalar w=1/(btScalar)2; 201 appendNote(text,o,btVector4(w,w,0,0), feature->m_n[0], 202 feature->m_n[1]); 203 } 204 205 205 // 206 206 void btSoftBody::appendNote( const char* text, 207 208 209 { 210 211 212 feature->m_n[1],213 feature->m_n[2]);207 const btVector3& o, 208 Face* feature) 209 { 210 static const btScalar w=1/(btScalar)3; 211 appendNote(text,o,btVector4(w,w,w,0), feature->m_n[0], 212 feature->m_n[1], 213 feature->m_n[2]); 214 214 } 215 215 … … 217 217 void btSoftBody::appendNode( const btVector3& x,btScalar m) 218 218 { 219 220 { 221 222 223 224 } 225 226 227 228 229 230 231 232 233 219 if(m_nodes.capacity()==m_nodes.size()) 220 { 221 pointersToIndices(); 222 m_nodes.reserve(m_nodes.size()*2+1); 223 indicesToPointers(); 224 } 225 const btScalar margin=getCollisionShape()->getMargin(); 226 m_nodes.push_back(Node()); 227 Node& n=m_nodes[m_nodes.size()-1]; 228 ZeroInitialize(n); 229 n.m_x = x; 230 n.m_q = n.m_x; 231 n.m_im = m>0?1/m:0; 232 n.m_material = m_materials[0]; 233 n.m_leaf = m_ndbvt.insert(btDbvtVolume::FromCR(n.m_x,margin),&n); 234 234 } 235 235 … … 237 237 void btSoftBody::appendLink(int model,Material* mat) 238 238 { 239 240 241 239 Link l; 240 if(model>=0) 241 l=m_links[model]; 242 242 else 243 243 { ZeroInitialize(l);l.m_material=mat?mat:m_materials[0]; } 244 244 m_links.push_back(l); 245 245 } 246 246 … … 274 274 void btSoftBody::appendFace(int model,Material* mat) 275 275 { 276 277 276 Face f; 277 if(model>=0) 278 278 { f=m_faces[model]; } 279 279 else 280 280 { ZeroInitialize(f);f.m_material=mat?mat:m_materials[0]; } 281 281 m_faces.push_back(f); 282 282 } 283 283 … … 320 320 void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1) 321 321 { 322 323 324 325 326 327 328 329 330 322 LJoint* pj = new(btAlignedAlloc(sizeof(LJoint),16)) LJoint(); 323 pj->m_bodies[0] = body0; 324 pj->m_bodies[1] = body1; 325 pj->m_refs[0] = pj->m_bodies[0].xform().inverse()*specs.position; 326 pj->m_refs[1] = pj->m_bodies[1].xform().inverse()*specs.position; 327 pj->m_cfm = specs.cfm; 328 pj->m_erp = specs.erp; 329 pj->m_split = specs.split; 330 m_joints.push_back(pj); 331 331 } 332 332 … … 334 334 void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,Body body) 335 335 { 336 336 appendLinearJoint(specs,m_clusters[0],body); 337 337 } 338 338 … … 340 340 void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,btSoftBody* body) 341 341 { 342 342 appendLinearJoint(specs,m_clusters[0],body->m_clusters[0]); 343 343 } 344 344 … … 346 346 void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,Cluster* body0,Body body1) 347 347 { 348 349 350 351 352 353 354 355 356 357 348 AJoint* pj = new(btAlignedAlloc(sizeof(AJoint),16)) AJoint(); 349 pj->m_bodies[0] = body0; 350 pj->m_bodies[1] = body1; 351 pj->m_refs[0] = pj->m_bodies[0].xform().inverse().getBasis()*specs.axis; 352 pj->m_refs[1] = pj->m_bodies[1].xform().inverse().getBasis()*specs.axis; 353 pj->m_cfm = specs.cfm; 354 pj->m_erp = specs.erp; 355 pj->m_split = specs.split; 356 pj->m_icontrol = specs.icontrol; 357 m_joints.push_back(pj); 358 358 } 359 359 … … 361 361 void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,Body body) 362 362 { 363 363 appendAngularJoint(specs,m_clusters[0],body); 364 364 } 365 365 … … 367 367 void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,btSoftBody* body) 368 368 { 369 369 appendAngularJoint(specs,m_clusters[0],body->m_clusters[0]); 370 370 } 371 371 … … 456 456 const Face& f=m_faces[i]; 457 457 const btScalar twicearea=AreaOf( f.m_n[0]->m_x, 458 f.m_n[1]->m_x,459 f.m_n[2]->m_x);458 f.m_n[1]->m_x, 459 f.m_n[2]->m_x); 460 460 for(int j=0;j<3;++j) 461 461 { … … 503 503 void btSoftBody::translate(const btVector3& trs) 504 504 { 505 506 507 508 505 btTransform t; 506 t.setIdentity(); 507 t.setOrigin(trs); 508 transform(t); 509 509 } 510 510 … … 512 512 void btSoftBody::rotate( const btQuaternion& rot) 513 513 { 514 515 516 517 514 btTransform t; 515 t.setIdentity(); 516 t.setRotation(rot); 517 transform(t); 518 518 } 519 519 … … 554 554 Node& n=m_nodes[i]; 555 555 m_pose.m_wgh[i]= n.m_im>0 ? 556 1/(m_nodes[i].m_im*tmass) :557 kmass/tmass;556 1/(m_nodes[i].m_im*tmass) : 557 kmass/tmass; 558 558 } 559 559 /* Pos */ … … 570 570 /* Aqq */ 571 571 m_pose.m_aqq[0] = 572 573 572 m_pose.m_aqq[1] = 573 m_pose.m_aqq[2] = btVector3(0,0,0); 574 574 for( i=0,ni=m_nodes.size();i<ni;++i) 575 {575 { 576 576 const btVector3& q=m_pose.m_pos[i]; 577 577 const btVector3 mq=m_pose.m_wgh[i]*q; … … 579 579 m_pose.m_aqq[1]+=mq.y()*q; 580 580 m_pose.m_aqq[2]+=mq.z()*q; 581 }581 } 582 582 m_pose.m_aqq=m_pose.m_aqq.inverse(); 583 583 updateConstants(); … … 606 606 int btSoftBody::clusterCount() const 607 607 { 608 608 return(m_clusters.size()); 609 609 } 610 610 … … 612 612 btVector3 btSoftBody::clusterCom(const Cluster* cluster) 613 613 { 614 615 616 { 617 618 } 619 614 btVector3 com(0,0,0); 615 for(int i=0,ni=cluster->m_nodes.size();i<ni;++i) 616 { 617 com+=cluster->m_nodes[i]->m_x*cluster->m_masses[i]; 618 } 619 return(com*cluster->m_imass); 620 620 } 621 621 … … 623 623 btVector3 btSoftBody::clusterCom(int cluster) const 624 624 { 625 625 return(clusterCom(m_clusters[cluster])); 626 626 } 627 627 … … 629 629 btVector3 btSoftBody::clusterVelocity(const Cluster* cluster,const btVector3& rpos) 630 630 { 631 631 return(cluster->m_lv+cross(cluster->m_av,rpos)); 632 632 } 633 633 … … 635 635 void btSoftBody::clusterVImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse) 636 636 { 637 638 639 640 641 637 const btVector3 li=cluster->m_imass*impulse; 638 const btVector3 ai=cluster->m_invwi*cross(rpos,impulse); 639 cluster->m_vimpulses[0]+=li;cluster->m_lv+=li; 640 cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai; 641 cluster->m_nvimpulses++; 642 642 } 643 643 … … 645 645 void btSoftBody::clusterDImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse) 646 646 { 647 648 649 650 651 647 const btVector3 li=cluster->m_imass*impulse; 648 const btVector3 ai=cluster->m_invwi*cross(rpos,impulse); 649 cluster->m_dimpulses[0]+=li; 650 cluster->m_dimpulses[1]+=ai; 651 cluster->m_ndimpulses++; 652 652 } 653 653 … … 655 655 void btSoftBody::clusterImpulse(Cluster* cluster,const btVector3& rpos,const Impulse& impulse) 656 656 { 657 658 657 if(impulse.m_asVelocity) clusterVImpulse(cluster,rpos,impulse.m_velocity); 658 if(impulse.m_asDrift) clusterDImpulse(cluster,rpos,impulse.m_drift); 659 659 } 660 660 … … 662 662 void btSoftBody::clusterVAImpulse(Cluster* cluster,const btVector3& impulse) 663 663 { 664 665 666 664 const btVector3 ai=cluster->m_invwi*impulse; 665 cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai; 666 cluster->m_nvimpulses++; 667 667 } 668 668 … … 670 670 void btSoftBody::clusterDAImpulse(Cluster* cluster,const btVector3& impulse) 671 671 { 672 673 674 672 const btVector3 ai=cluster->m_invwi*impulse; 673 cluster->m_dimpulses[1]+=ai; 674 cluster->m_ndimpulses++; 675 675 } 676 676 … … 678 678 void btSoftBody::clusterAImpulse(Cluster* cluster,const Impulse& impulse) 679 679 { 680 681 680 if(impulse.m_asVelocity) clusterVAImpulse(cluster,impulse.m_velocity); 681 if(impulse.m_asDrift) clusterDAImpulse(cluster,impulse.m_drift); 682 682 } 683 683 … … 685 685 void btSoftBody::clusterDCImpulse(Cluster* cluster,const btVector3& impulse) 686 686 { 687 688 687 cluster->m_dimpulses[0]+=impulse*cluster->m_imass; 688 cluster->m_ndimpulses++; 689 689 } 690 690 … … 754 754 void btSoftBody::randomizeConstraints() 755 755 { 756 756 unsigned long seed=243703; 757 757 #define NEXTRAND (seed=(1664525L*seed+1013904223L)&0xffffffff) 758 758 int i,ni; 759 759 760 760 for(i=0,ni=m_links.size();i<ni;++i) … … 772 772 void btSoftBody::releaseCluster(int index) 773 773 { 774 775 776 777 778 774 Cluster* c=m_clusters[index]; 775 if(c->m_leaf) m_cdbvt.remove(c->m_leaf); 776 c->~Cluster(); 777 btAlignedFree(c); 778 m_clusters.remove(c); 779 779 } 780 780 … … 782 782 void btSoftBody::releaseClusters() 783 783 { 784 784 while(m_clusters.size()>0) releaseCluster(0); 785 785 } 786 786 … … 788 788 int btSoftBody::generateClusters(int k,int maxiterations) 789 789 { 790 int i; 791 releaseClusters(); 792 m_clusters.resize(btMin(k,m_nodes.size())); 793 for(i=0;i<m_clusters.size();++i) 794 { 795 m_clusters[i] = new(btAlignedAlloc(sizeof(Cluster),16)) Cluster(); 796 m_clusters[i]->m_collide= true; 797 } 798 k=m_clusters.size(); 799 if(k>0) 800 { 801 /* Initialize */ 802 btAlignedObjectArray<btVector3> centers; 803 btVector3 cog(0,0,0); 804 int i; 790 int i; 791 releaseClusters(); 792 m_clusters.resize(btMin(k,m_nodes.size())); 793 for(i=0;i<m_clusters.size();++i) 794 { 795 m_clusters[i] = new(btAlignedAlloc(sizeof(Cluster),16)) Cluster(); 796 m_clusters[i]->m_collide= true; 797 } 798 k=m_clusters.size(); 799 if(k>0) 800 { 801 /* Initialize */ 802 btAlignedObjectArray<btVector3> centers; 803 btVector3 cog(0,0,0); 804 int i; 805 for(i=0;i<m_nodes.size();++i) 806 { 807 cog+=m_nodes[i].m_x; 808 m_clusters[(i*29873)%m_clusters.size()]->m_nodes.push_back(&m_nodes[i]); 809 } 810 cog/=(btScalar)m_nodes.size(); 811 centers.resize(k,cog); 812 /* Iterate */ 813 const btScalar slope=16; 814 bool changed; 815 int iterations=0; 816 do { 817 const btScalar w=2-btMin<btScalar>(1,iterations/slope); 818 changed=false; 819 iterations++; 820 int i; 821 822 for(i=0;i<k;++i) 823 { 824 btVector3 c(0,0,0); 825 for(int j=0;j<m_clusters[i]->m_nodes.size();++j) 826 { 827 c+=m_clusters[i]->m_nodes[j]->m_x; 828 } 829 if(m_clusters[i]->m_nodes.size()) 830 { 831 c /= (btScalar)m_clusters[i]->m_nodes.size(); 832 c = centers[i]+(c-centers[i])*w; 833 changed |= ((c-centers[i]).length2()>SIMD_EPSILON); 834 centers[i] = c; 835 m_clusters[i]->m_nodes.resize(0); 836 } 837 } 805 838 for(i=0;i<m_nodes.size();++i) 806 { 807 cog+=m_nodes[i].m_x; 808 m_clusters[(i*29873)%m_clusters.size()]->m_nodes.push_back(&m_nodes[i]); 809 } 810 cog/=(btScalar)m_nodes.size(); 811 centers.resize(k,cog); 812 /* Iterate */ 813 const btScalar slope=16; 814 bool changed; 815 int iterations=0; 816 do { 817 const btScalar w=2-btMin<btScalar>(1,iterations/slope); 818 changed=false; 819 iterations++; 820 int i; 821 822 for(i=0;i<k;++i) 823 { 824 btVector3 c(0,0,0); 825 for(int j=0;j<m_clusters[i]->m_nodes.size();++j) 839 { 840 const btVector3 nx=m_nodes[i].m_x; 841 int kbest=0; 842 btScalar kdist=ClusterMetric(centers[0],nx); 843 for(int j=1;j<k;++j) 826 844 { 827 c+=m_clusters[i]->m_nodes[j]->m_x; 828 } 829 if(m_clusters[i]->m_nodes.size()) 830 { 831 c /= (btScalar)m_clusters[i]->m_nodes.size(); 832 c = centers[i]+(c-centers[i])*w; 833 changed |= ((c-centers[i]).length2()>SIMD_EPSILON); 834 centers[i] = c; 835 m_clusters[i]->m_nodes.resize(0); 836 } 837 } 838 for(i=0;i<m_nodes.size();++i) 839 { 840 const btVector3 nx=m_nodes[i].m_x; 841 int kbest=0; 842 btScalar kdist=ClusterMetric(centers[0],nx); 843 for(int j=1;j<k;++j) 844 { 845 const btScalar d=ClusterMetric(centers[j],nx); 846 if(d<kdist) 845 const btScalar d=ClusterMetric(centers[j],nx); 846 if(d<kdist) 847 847 { 848 849 848 kbest=j; 849 kdist=d; 850 850 } 851 851 } 852 852 m_clusters[kbest]->m_nodes.push_back(&m_nodes[i]); 853 853 } 854 854 } while(changed&&(iterations<maxiterations)); 855 856 857 858 859 { 860 861 { 862 863 } 864 } 865 866 { 867 868 int(m_faces[i].m_n[1]-&m_nodes[0]),869 int(m_faces[i].m_n[2]-&m_nodes[0])};870 871 { 872 873 855 /* Merge */ 856 btAlignedObjectArray<int> cids; 857 cids.resize(m_nodes.size(),-1); 858 for(i=0;i<m_clusters.size();++i) 859 { 860 for(int j=0;j<m_clusters[i]->m_nodes.size();++j) 861 { 862 cids[int(m_clusters[i]->m_nodes[j]-&m_nodes[0])]=i; 863 } 864 } 865 for(i=0;i<m_faces.size();++i) 866 { 867 const int idx[]={ int(m_faces[i].m_n[0]-&m_nodes[0]), 868 int(m_faces[i].m_n[1]-&m_nodes[0]), 869 int(m_faces[i].m_n[2]-&m_nodes[0])}; 870 for(int j=0;j<3;++j) 871 { 872 const int cid=cids[idx[j]]; 873 for(int q=1;q<3;++q) 874 874 { 875 876 875 const int kid=idx[(j+q)%3]; 876 if(cids[kid]!=cid) 877 877 { 878 878 if(m_clusters[cid]->m_nodes.findLinearSearch(&m_nodes[kid])==m_clusters[cid]->m_nodes.size()) 879 879 { 880 880 m_clusters[cid]->m_nodes.push_back(&m_nodes[kid]); 881 881 } 882 882 } … … 884 884 } 885 885 } 886 887 888 { 889 890 891 892 893 894 895 } 896 897 898 { 899 900 { 901 902 } 903 } 904 905 906 907 908 } 909 886 /* Master */ 887 if(m_clusters.size()>1) 888 { 889 Cluster* pmaster=new(btAlignedAlloc(sizeof(Cluster),16)) Cluster(); 890 pmaster->m_collide = false; 891 pmaster->m_nodes.reserve(m_nodes.size()); 892 for(int i=0;i<m_nodes.size();++i) pmaster->m_nodes.push_back(&m_nodes[i]); 893 m_clusters.push_back(pmaster); 894 btSwap(m_clusters[0],m_clusters[m_clusters.size()-1]); 895 } 896 /* Terminate */ 897 for(i=0;i<m_clusters.size();++i) 898 { 899 if(m_clusters[i]->m_nodes.size()==0) 900 { 901 releaseCluster(i--); 902 } 903 } 904 905 initializeClusters(); 906 updateClusters(); 907 return(m_clusters.size()); 908 } 909 return(0); 910 910 } 911 911 … … 913 913 void btSoftBody::refine(ImplicitFn* ifn,btScalar accurary,bool cut) 914 914 { 915 916 917 918 919 920 921 922 923 { 924 925 926 { 927 928 { 929 930 915 const Node* nbase = &m_nodes[0]; 916 int ncount = m_nodes.size(); 917 btSymMatrix<int> edges(ncount,-2); 918 int newnodes=0; 919 int i,j,k,ni; 920 921 /* Filter out */ 922 for(i=0;i<m_links.size();++i) 923 { 924 Link& l=m_links[i]; 925 if(l.m_bbending) 926 { 927 if(!SameSign(ifn->Eval(l.m_n[0]->m_x),ifn->Eval(l.m_n[1]->m_x))) 928 { 929 btSwap(m_links[i],m_links[m_links.size()-1]); 930 m_links.pop_back();--i; 931 931 } 932 932 } 933 933 } 934 935 936 { 937 938 939 } 940 934 /* Fill edges */ 935 for(i=0;i<m_links.size();++i) 936 { 937 Link& l=m_links[i]; 938 edges(int(l.m_n[0]-nbase),int(l.m_n[1]-nbase))=-1; 939 } 940 for(i=0;i<m_faces.size();++i) 941 941 { 942 943 944 945 946 } 947 948 949 { 950 951 { 952 953 { 954 955 956 957 942 Face& f=m_faces[i]; 943 edges(int(f.m_n[0]-nbase),int(f.m_n[1]-nbase))=-1; 944 edges(int(f.m_n[1]-nbase),int(f.m_n[2]-nbase))=-1; 945 edges(int(f.m_n[2]-nbase),int(f.m_n[0]-nbase))=-1; 946 } 947 /* Intersect */ 948 for(i=0;i<ncount;++i) 949 { 950 for(j=i+1;j<ncount;++j) 951 { 952 if(edges(i,j)==-1) 953 { 954 Node& a=m_nodes[i]; 955 Node& b=m_nodes[j]; 956 const btScalar t=ImplicitSolve(ifn,a.m_x,b.m_x,accurary); 957 if(t>0) 958 958 { 959 960 961 962 959 const btVector3 x=Lerp(a.m_x,b.m_x,t); 960 const btVector3 v=Lerp(a.m_v,b.m_v,t); 961 btScalar m=0; 962 if(a.m_im>0) 963 963 { 964 964 if(b.m_im>0) 965 965 { 966 967 968 969 970 971 972 966 const btScalar ma=1/a.m_im; 967 const btScalar mb=1/b.m_im; 968 const btScalar mc=Lerp(ma,mb,t); 969 const btScalar f=(ma+mb)/(ma+mb+mc); 970 a.m_im=1/(ma*f); 971 b.m_im=1/(mb*f); 972 m=mc*f; 973 973 } 974 974 else … … 977 977 else 978 978 { 979 979 if(b.m_im>0) 980 980 { b.m_im/=0.5;m=1/b.m_im; } 981 981 else 982 982 m=0; 983 983 } 984 985 986 987 984 appendNode(x,m); 985 edges(i,j)=m_nodes.size()-1; 986 m_nodes[edges(i,j)].m_v=v; 987 ++newnodes; 988 988 } 989 989 } 990 990 } 991 991 } 992 nbase=&m_nodes[0]; 993 /* Refine links */ 994 for(i=0,ni=m_links.size();i<ni;++i) 995 { 996 Link& feat=m_links[i]; 997 const int idx[]={ int(feat.m_n[0]-nbase), 998 int(feat.m_n[1]-nbase)}; 999 if((idx[0]<ncount)&&(idx[1]<ncount)) 1000 { 1001 const int ni=edges(idx[0],idx[1]); 1002 if(ni>0) 1003 { 1004 appendLink(i); 1005 Link* pft[]={ &m_links[i], 1006 &m_links[m_links.size()-1]}; 1007 pft[0]->m_n[0]=&m_nodes[idx[0]]; 1008 pft[0]->m_n[1]=&m_nodes[ni]; 1009 pft[1]->m_n[0]=&m_nodes[ni]; 1010 pft[1]->m_n[1]=&m_nodes[idx[1]]; 1011 } 1012 } 1013 } 1014 /* Refine faces */ 1015 for(i=0;i<m_faces.size();++i) 1016 { 1017 const Face& feat=m_faces[i]; 1018 const int idx[]={ int(feat.m_n[0]-nbase), 1019 int(feat.m_n[1]-nbase), 1020 int(feat.m_n[2]-nbase)}; 1021 for(j=2,k=0;k<3;j=k++) 1022 { 1023 if((idx[j]<ncount)&&(idx[k]<ncount)) 1024 { 1025 const int ni=edges(idx[j],idx[k]); 1026 if(ni>0) 1027 { 1028 appendFace(i); 1029 const int l=(k+1)%3; 1030 Face* pft[]={ &m_faces[i], 1031 &m_faces[m_faces.size()-1]}; 1032 pft[0]->m_n[0]=&m_nodes[idx[l]]; 1033 pft[0]->m_n[1]=&m_nodes[idx[j]]; 1034 pft[0]->m_n[2]=&m_nodes[ni]; 1035 pft[1]->m_n[0]=&m_nodes[ni]; 1036 pft[1]->m_n[1]=&m_nodes[idx[k]]; 1037 pft[1]->m_n[2]=&m_nodes[idx[l]]; 1038 appendLink(ni,idx[l],pft[0]->m_material); 1039 --i;break; 1040 } 1041 } 1042 } 1043 } 1044 /* Cut */ 1045 if(cut) 1046 { 1047 btAlignedObjectArray<int> cnodes; 1048 const int pcount=ncount; 1049 int i; 1050 ncount=m_nodes.size(); 1051 cnodes.resize(ncount,0); 1052 /* Nodes */ 1053 for(i=0;i<ncount;++i) 1054 { 1055 const btVector3 x=m_nodes[i].m_x; 1056 if((i>=pcount)||(btFabs(ifn->Eval(x))<accurary)) 1057 { 1058 const btVector3 v=m_nodes[i].m_v; 1059 btScalar m=getMass(i); 1060 if(m>0) { m*=0.5;m_nodes[i].m_im/=0.5; } 1061 appendNode(x,m); 1062 cnodes[i]=m_nodes.size()-1; 1063 m_nodes[cnodes[i]].m_v=v; 1064 } 1065 } 992 1066 nbase=&m_nodes[0]; 993 /* Refine links */1067 /* Links */ 994 1068 for(i=0,ni=m_links.size();i<ni;++i) 995 { 996 Link& feat=m_links[i]; 997 const int idx[]={ int(feat.m_n[0]-nbase), 998 int(feat.m_n[1]-nbase)}; 999 if((idx[0]<ncount)&&(idx[1]<ncount)) 1000 { 1001 const int ni=edges(idx[0],idx[1]); 1002 if(ni>0) 1003 { 1004 appendLink(i); 1005 Link* pft[]={ &m_links[i], 1006 &m_links[m_links.size()-1]}; 1007 pft[0]->m_n[0]=&m_nodes[idx[0]]; 1008 pft[0]->m_n[1]=&m_nodes[ni]; 1009 pft[1]->m_n[0]=&m_nodes[ni]; 1010 pft[1]->m_n[1]=&m_nodes[idx[1]]; 1011 } 1012 } 1013 } 1014 /* Refine faces */ 1015 for(i=0;i<m_faces.size();++i) 1016 { 1017 const Face& feat=m_faces[i]; 1018 const int idx[]={ int(feat.m_n[0]-nbase), 1019 int(feat.m_n[1]-nbase), 1020 int(feat.m_n[2]-nbase)}; 1021 for(j=2,k=0;k<3;j=k++) 1022 { 1023 if((idx[j]<ncount)&&(idx[k]<ncount)) 1024 { 1025 const int ni=edges(idx[j],idx[k]); 1026 if(ni>0) 1069 { 1070 const int id[]={ int(m_links[i].m_n[0]-nbase), 1071 int(m_links[i].m_n[1]-nbase)}; 1072 int todetach=0; 1073 if(cnodes[id[0]]&&cnodes[id[1]]) 1074 { 1075 appendLink(i); 1076 todetach=m_links.size()-1; 1077 } 1078 else 1079 { 1080 if(( (ifn->Eval(m_nodes[id[0]].m_x)<accurary)&& 1081 (ifn->Eval(m_nodes[id[1]].m_x)<accurary))) 1082 todetach=i; 1083 } 1084 if(todetach) 1085 { 1086 Link& l=m_links[todetach]; 1087 for(int j=0;j<2;++j) 1027 1088 { 1028 appendFace(i); 1029 const int l=(k+1)%3; 1030 Face* pft[]={ &m_faces[i], 1031 &m_faces[m_faces.size()-1]}; 1032 pft[0]->m_n[0]=&m_nodes[idx[l]]; 1033 pft[0]->m_n[1]=&m_nodes[idx[j]]; 1034 pft[0]->m_n[2]=&m_nodes[ni]; 1035 pft[1]->m_n[0]=&m_nodes[ni]; 1036 pft[1]->m_n[1]=&m_nodes[idx[k]]; 1037 pft[1]->m_n[2]=&m_nodes[idx[l]]; 1038 appendLink(ni,idx[l],pft[0]->m_material); 1039 --i;break; 1089 int cn=cnodes[int(l.m_n[j]-nbase)]; 1090 if(cn) l.m_n[j]=&m_nodes[cn]; 1091 } 1092 } 1093 } 1094 /* Faces */ 1095 for(i=0,ni=m_faces.size();i<ni;++i) 1096 { 1097 Node** n= m_faces[i].m_n; 1098 if( (ifn->Eval(n[0]->m_x)<accurary)&& 1099 (ifn->Eval(n[1]->m_x)<accurary)&& 1100 (ifn->Eval(n[2]->m_x)<accurary)) 1101 { 1102 for(int j=0;j<3;++j) 1103 { 1104 int cn=cnodes[int(n[j]-nbase)]; 1105 if(cn) n[j]=&m_nodes[cn]; 1040 1106 } 1041 1107 } 1042 1108 } 1043 } 1044 /* Cut */ 1045 if(cut) 1046 { 1047 btAlignedObjectArray<int> cnodes; 1048 const int pcount=ncount; 1049 int i; 1050 ncount=m_nodes.size(); 1051 cnodes.resize(ncount,0); 1052 /* Nodes */ 1053 for(i=0;i<ncount;++i) 1054 { 1055 const btVector3 x=m_nodes[i].m_x; 1056 if((i>=pcount)||(btFabs(ifn->Eval(x))<accurary)) 1057 { 1058 const btVector3 v=m_nodes[i].m_v; 1059 btScalar m=getMass(i); 1060 if(m>0) { m*=0.5;m_nodes[i].m_im/=0.5; } 1061 appendNode(x,m); 1062 cnodes[i]=m_nodes.size()-1; 1063 m_nodes[cnodes[i]].m_v=v; 1064 } 1065 } 1066 nbase=&m_nodes[0]; 1067 /* Links */ 1068 for(i=0,ni=m_links.size();i<ni;++i) 1069 { 1070 const int id[]={ int(m_links[i].m_n[0]-nbase), 1071 int(m_links[i].m_n[1]-nbase)}; 1072 int todetach=0; 1073 if(cnodes[id[0]]&&cnodes[id[1]]) 1074 { 1075 appendLink(i); 1076 todetach=m_links.size()-1; 1077 } 1078 else 1079 { 1080 if(( (ifn->Eval(m_nodes[id[0]].m_x)<accurary)&& 1081 (ifn->Eval(m_nodes[id[1]].m_x)<accurary))) 1082 todetach=i; 1083 } 1084 if(todetach) 1085 { 1086 Link& l=m_links[todetach]; 1087 for(int j=0;j<2;++j) 1088 { 1089 int cn=cnodes[int(l.m_n[j]-nbase)]; 1090 if(cn) l.m_n[j]=&m_nodes[cn]; 1091 } 1092 } 1093 } 1094 /* Faces */ 1095 for(i=0,ni=m_faces.size();i<ni;++i) 1096 { 1097 Node** n= m_faces[i].m_n; 1098 if( (ifn->Eval(n[0]->m_x)<accurary)&& 1099 (ifn->Eval(n[1]->m_x)<accurary)&& 1100 (ifn->Eval(n[2]->m_x)<accurary)) 1101 { 1102 for(int j=0;j<3;++j) 1103 { 1104 int cn=cnodes[int(n[j]-nbase)]; 1105 if(cn) n[j]=&m_nodes[cn]; 1106 } 1107 } 1108 } 1109 /* Clean orphans */ 1110 int nnodes=m_nodes.size(); 1111 btAlignedObjectArray<int> ranks; 1112 btAlignedObjectArray<int> todelete; 1113 ranks.resize(nnodes,0); 1114 for(i=0,ni=m_links.size();i<ni;++i) 1115 { 1116 for(int j=0;j<2;++j) ranks[int(m_links[i].m_n[j]-nbase)]++; 1117 } 1118 for(i=0,ni=m_faces.size();i<ni;++i) 1119 { 1120 for(int j=0;j<3;++j) ranks[int(m_faces[i].m_n[j]-nbase)]++; 1121 } 1122 for(i=0;i<m_links.size();++i) 1123 { 1124 const int id[]={ int(m_links[i].m_n[0]-nbase), 1125 int(m_links[i].m_n[1]-nbase)}; 1126 const bool sg[]={ ranks[id[0]]==1, 1127 ranks[id[1]]==1}; 1128 if(sg[0]||sg[1]) 1129 { 1130 --ranks[id[0]]; 1131 --ranks[id[1]]; 1132 btSwap(m_links[i],m_links[m_links.size()-1]); 1133 m_links.pop_back();--i; 1134 } 1135 } 1136 #if 0 1137 for(i=nnodes-1;i>=0;--i) 1138 { 1139 if(!ranks[i]) todelete.push_back(i); 1109 /* Clean orphans */ 1110 int nnodes=m_nodes.size(); 1111 btAlignedObjectArray<int> ranks; 1112 btAlignedObjectArray<int> todelete; 1113 ranks.resize(nnodes,0); 1114 for(i=0,ni=m_links.size();i<ni;++i) 1115 { 1116 for(int j=0;j<2;++j) ranks[int(m_links[i].m_n[j]-nbase)]++; 1117 } 1118 for(i=0,ni=m_faces.size();i<ni;++i) 1119 { 1120 for(int j=0;j<3;++j) ranks[int(m_faces[i].m_n[j]-nbase)]++; 1121 } 1122 for(i=0;i<m_links.size();++i) 1123 { 1124 const int id[]={ int(m_links[i].m_n[0]-nbase), 1125 int(m_links[i].m_n[1]-nbase)}; 1126 const bool sg[]={ ranks[id[0]]==1, 1127 ranks[id[1]]==1}; 1128 if(sg[0]||sg[1]) 1129 { 1130 --ranks[id[0]]; 1131 --ranks[id[1]]; 1132 btSwap(m_links[i],m_links[m_links.size()-1]); 1133 m_links.pop_back();--i; 1134 } 1135 } 1136 #if 0 1137 for(i=nnodes-1;i>=0;--i) 1138 { 1139 if(!ranks[i]) todelete.push_back(i); 1140 1140 } 1141 1141 if(todelete.size()) 1142 1142 { 1143 1144 1145 1146 1147 { 1148 1149 1150 1151 1152 1153 1154 } 1155 1156 1157 } 1158 #endif1159 } 1160 1143 btAlignedObjectArray<int>& map=ranks; 1144 for(int i=0;i<nnodes;++i) map[i]=i; 1145 PointersToIndices(this); 1146 for(int i=0,ni=todelete.size();i<ni;++i) 1147 { 1148 int j=todelete[i]; 1149 int& a=map[j]; 1150 int& b=map[--nnodes]; 1151 m_ndbvt.remove(m_nodes[a].m_leaf);m_nodes[a].m_leaf=0; 1152 btSwap(m_nodes[a],m_nodes[b]); 1153 j=a;a=b;b=j; 1154 } 1155 IndicesToPointers(this,&map[0]); 1156 m_nodes.resize(nnodes); 1157 } 1158 #endif 1159 } 1160 m_bUpdateRtCst=true; 1161 1161 } 1162 1162 … … 1164 1164 bool btSoftBody::cutLink(const Node* node0,const Node* node1,btScalar position) 1165 1165 { 1166 1166 return(cutLink(int(node0-&m_nodes[0]),int(node1-&m_nodes[0]),position)); 1167 1167 } 1168 1168 … … 1170 1170 bool btSoftBody::cutLink(int node0,int node1,btScalar position) 1171 1171 { 1172 bool done=false; 1173 int i,ni; 1174 const btVector3 d=m_nodes[node0].m_x-m_nodes[node1].m_x; 1175 const btVector3 x=Lerp(m_nodes[node0].m_x,m_nodes[node1].m_x,position); 1176 const btVector3 v=Lerp(m_nodes[node0].m_v,m_nodes[node1].m_v,position); 1177 const btScalar m=1; 1178 appendNode(x,m); 1179 appendNode(x,m); 1180 Node* pa=&m_nodes[node0]; 1181 Node* pb=&m_nodes[node1]; 1182 Node* pn[2]={ &m_nodes[m_nodes.size()-2], 1183 &m_nodes[m_nodes.size()-1]}; 1184 pn[0]->m_v=v; 1185 pn[1]->m_v=v; 1186 for(i=0,ni=m_links.size();i<ni;++i) 1187 { 1188 const int mtch=MatchEdge(m_links[i].m_n[0],m_links[i].m_n[1],pa,pb); 1172 bool done=false; 1173 int i,ni; 1174 const btVector3 d=m_nodes[node0].m_x-m_nodes[node1].m_x; 1175 const btVector3 x=Lerp(m_nodes[node0].m_x,m_nodes[node1].m_x,position); 1176 const btVector3 v=Lerp(m_nodes[node0].m_v,m_nodes[node1].m_v,position); 1177 const btScalar m=1; 1178 appendNode(x,m); 1179 appendNode(x,m); 1180 Node* pa=&m_nodes[node0]; 1181 Node* pb=&m_nodes[node1]; 1182 Node* pn[2]={ &m_nodes[m_nodes.size()-2], 1183 &m_nodes[m_nodes.size()-1]}; 1184 pn[0]->m_v=v; 1185 pn[1]->m_v=v; 1186 for(i=0,ni=m_links.size();i<ni;++i) 1187 { 1188 const int mtch=MatchEdge(m_links[i].m_n[0],m_links[i].m_n[1],pa,pb); 1189 if(mtch!=-1) 1190 { 1191 appendLink(i); 1192 Link* pft[]={&m_links[i],&m_links[m_links.size()-1]}; 1193 pft[0]->m_n[1]=pn[mtch]; 1194 pft[1]->m_n[0]=pn[1-mtch]; 1195 done=true; 1196 } 1197 } 1198 for(i=0,ni=m_faces.size();i<ni;++i) 1199 { 1200 for(int k=2,l=0;l<3;k=l++) 1201 { 1202 const int mtch=MatchEdge(m_faces[i].m_n[k],m_faces[i].m_n[l],pa,pb); 1189 1203 if(mtch!=-1) 1190 { 1191 appendLink(i); 1192 Link* pft[]={&m_links[i],&m_links[m_links.size()-1]}; 1193 pft[0]->m_n[1]=pn[mtch]; 1194 pft[1]->m_n[0]=pn[1-mtch]; 1195 done=true; 1196 } 1197 } 1198 for(i=0,ni=m_faces.size();i<ni;++i) 1199 { 1200 for(int k=2,l=0;l<3;k=l++) 1201 { 1202 const int mtch=MatchEdge(m_faces[i].m_n[k],m_faces[i].m_n[l],pa,pb); 1203 if(mtch!=-1) 1204 { 1205 appendFace(i); 1206 Face* pft[]={&m_faces[i],&m_faces[m_faces.size()-1]}; 1207 pft[0]->m_n[l]=pn[mtch]; 1208 pft[1]->m_n[k]=pn[1-mtch]; 1209 appendLink(pn[0],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true); 1210 appendLink(pn[1],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true); 1211 } 1212 } 1213 } 1214 if(!done) 1215 { 1216 m_ndbvt.remove(pn[0]->m_leaf); 1217 m_ndbvt.remove(pn[1]->m_leaf); 1218 m_nodes.pop_back(); 1219 m_nodes.pop_back(); 1220 } 1221 return(done); 1222 } 1223 1224 // 1225 bool btSoftBody::rayTest(const btVector3& rayFrom, 1226 const btVector3& rayTo, 1227 sRayCast& results) 1228 { 1229 if(m_faces.size()&&m_fdbvt.empty()) 1230 initializeFaceTree(); 1231 1232 results.body = this; 1233 results.fraction = 1.f; 1234 results.feature = eFeature::None; 1235 results.index = -1; 1236 1237 return(rayTest(rayFrom,rayTo,results.fraction,results.feature,results.index,false)!=0); 1204 { 1205 appendFace(i); 1206 Face* pft[]={&m_faces[i],&m_faces[m_faces.size()-1]}; 1207 pft[0]->m_n[l]=pn[mtch]; 1208 pft[1]->m_n[k]=pn[1-mtch]; 1209 appendLink(pn[0],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true); 1210 appendLink(pn[1],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true); 1211 } 1212 } 1213 } 1214 if(!done) 1215 { 1216 m_ndbvt.remove(pn[0]->m_leaf); 1217 m_ndbvt.remove(pn[1]->m_leaf); 1218 m_nodes.pop_back(); 1219 m_nodes.pop_back(); 1220 } 1221 return(done); 1222 } 1223 1224 // 1225 bool btSoftBody::rayCast(const btVector3& org, 1226 const btVector3& dir, 1227 sRayCast& results, 1228 btScalar maxtime) 1229 { 1230 if(m_faces.size()&&m_fdbvt.empty()) initializeFaceTree(); 1231 results.body = this; 1232 results.time = maxtime; 1233 results.feature = eFeature::None; 1234 results.index = -1; 1235 return(rayCast(org,dir,results.time,results.feature,results.index,false)!=0); 1238 1236 } 1239 1237 … … 1241 1239 void btSoftBody::setSolver(eSolverPresets::_ preset) 1242 1240 { 1243 1244 1245 1246 1241 m_cfg.m_vsequence.clear(); 1242 m_cfg.m_psequence.clear(); 1243 m_cfg.m_dsequence.clear(); 1244 switch(preset) 1247 1245 { 1248 1246 case eSolverPresets::Positions: 1249 1250 1251 1252 1253 1247 m_cfg.m_psequence.push_back(ePSolver::Anchors); 1248 m_cfg.m_psequence.push_back(ePSolver::RContacts); 1249 m_cfg.m_psequence.push_back(ePSolver::SContacts); 1250 m_cfg.m_psequence.push_back(ePSolver::Linear); 1251 break; 1254 1252 case eSolverPresets::Velocities: 1255 1256 1257 1258 1259 1260 1261 1262 1253 m_cfg.m_vsequence.push_back(eVSolver::Linear); 1254 1255 m_cfg.m_psequence.push_back(ePSolver::Anchors); 1256 m_cfg.m_psequence.push_back(ePSolver::RContacts); 1257 m_cfg.m_psequence.push_back(ePSolver::SContacts); 1258 1259 m_cfg.m_dsequence.push_back(ePSolver::Linear); 1260 break; 1263 1261 } 1264 1262 } … … 1276 1274 m_fdbvt.clear(); 1277 1275 if(m_cfg.collisions&fCollision::VF_SS) 1278 {1276 { 1279 1277 initializeFaceTree(); 1280 }1281 } 1282 1278 } 1279 } 1280 1283 1281 /* Prepare */ 1284 1282 m_sst.sdt = dt*m_cfg.timescale; … … 1308 1306 Node& n=m_nodes[i]; 1309 1307 m_ndbvt.update( n.m_leaf, 1310 btDbvtVolume::FromCR(n.m_x,m_sst.radmrg),1311 n.m_v*m_sst.velmrg,1312 m_sst.updmrg);1308 btDbvtVolume::FromCR(n.m_x,m_sst.radmrg), 1309 n.m_v*m_sst.velmrg, 1310 m_sst.updmrg); 1313 1311 } 1314 1312 /* Faces */ 1315 1313 if(!m_fdbvt.empty()) 1316 {1314 { 1317 1315 for(int i=0;i<m_faces.size();++i) 1318 {1316 { 1319 1317 Face& f=m_faces[i]; 1320 1318 const btVector3 v=( f.m_n[0]->m_v+ 1321 f.m_n[1]->m_v+1322 f.m_n[2]->m_v)/3;1319 f.m_n[1]->m_v+ 1320 f.m_n[2]->m_v)/3; 1323 1321 m_fdbvt.update( f.m_leaf, 1324 VolumeOf(f,m_sst.radmrg),1325 v*m_sst.velmrg,1326 m_sst.updmrg);1327 }1328 }1322 VolumeOf(f,m_sst.radmrg), 1323 v*m_sst.velmrg, 1324 m_sst.updmrg); 1325 } 1326 } 1329 1327 /* Pose */ 1330 1328 updatePose(); 1331 1329 /* Match */ 1332 1330 if(m_pose.m_bframe&&(m_cfg.kMT>0)) 1333 {1331 { 1334 1332 const btMatrix3x3 posetrs=m_pose.m_rot; 1335 1333 for(int i=0,ni=m_nodes.size();i<ni;++i) 1336 {1334 { 1337 1335 Node& n=m_nodes[i]; 1338 1336 if(n.m_im>0) 1339 {1337 { 1340 1338 const btVector3 x=posetrs*m_pose.m_pos[i]+m_pose.m_com; 1341 1339 n.m_x=Lerp(n.m_x,x,m_cfg.kMT); 1342 }1343 }1344 }1340 } 1341 } 1342 } 1345 1343 /* Clear contacts */ 1346 1344 m_rcontacts.resize(0); … … 1355 1353 void btSoftBody::solveConstraints() 1356 1354 { 1357 1358 1359 1360 1361 1362 1363 1364 { 1365 1366 1367 1368 } 1369 1370 1371 { 1372 1373 1374 1375 a.m_node->m_im,1376 a.m_body->getInvMass(),1377 a.m_body->getInvInertiaTensorWorld(),1378 ra);1379 1380 1381 1382 } 1383 1384 1385 { 1386 1387 1388 { 1389 1390 { 1391 1392 } 1393 } 1394 1395 1396 { 1397 1398 1399 } 1400 } 1401 1402 1403 { 1404 1405 { 1406 1407 1408 { 1409 1410 } 1411 } 1412 1413 1414 { 1415 1416 1417 1418 } 1419 } 1420 1421 1422 { 1423 1424 1425 { 1426 1427 1428 } 1429 1430 { 1431 1432 { 1433 1434 } 1435 } 1436 1437 { 1438 1439 1440 } 1441 } 1442 1443 1444 1355 /* Apply clusters */ 1356 applyClusters(false); 1357 /* Prepare links */ 1358 1359 int i,ni; 1360 1361 for(i=0,ni=m_links.size();i<ni;++i) 1362 { 1363 Link& l=m_links[i]; 1364 l.m_c3 = l.m_n[1]->m_q-l.m_n[0]->m_q; 1365 l.m_c2 = 1/(l.m_c3.length2()*l.m_c0); 1366 } 1367 /* Prepare anchors */ 1368 for(i=0,ni=m_anchors.size();i<ni;++i) 1369 { 1370 Anchor& a=m_anchors[i]; 1371 const btVector3 ra=a.m_body->getWorldTransform().getBasis()*a.m_local; 1372 a.m_c0 = ImpulseMatrix( m_sst.sdt, 1373 a.m_node->m_im, 1374 a.m_body->getInvMass(), 1375 a.m_body->getInvInertiaTensorWorld(), 1376 ra); 1377 a.m_c1 = ra; 1378 a.m_c2 = m_sst.sdt*a.m_node->m_im; 1379 a.m_body->activate(); 1380 } 1381 /* Solve velocities */ 1382 if(m_cfg.viterations>0) 1383 { 1384 /* Solve */ 1385 for(int isolve=0;isolve<m_cfg.viterations;++isolve) 1386 { 1387 for(int iseq=0;iseq<m_cfg.m_vsequence.size();++iseq) 1388 { 1389 getSolver(m_cfg.m_vsequence[iseq])(this,1); 1390 } 1391 } 1392 /* Update */ 1393 for(i=0,ni=m_nodes.size();i<ni;++i) 1394 { 1395 Node& n=m_nodes[i]; 1396 n.m_x = n.m_q+n.m_v*m_sst.sdt; 1397 } 1398 } 1399 /* Solve positions */ 1400 if(m_cfg.piterations>0) 1401 { 1402 for(int isolve=0;isolve<m_cfg.piterations;++isolve) 1403 { 1404 const btScalar ti=isolve/(btScalar)m_cfg.piterations; 1405 for(int iseq=0;iseq<m_cfg.m_psequence.size();++iseq) 1406 { 1407 getSolver(m_cfg.m_psequence[iseq])(this,1,ti); 1408 } 1409 } 1410 const btScalar vc=m_sst.isdt*(1-m_cfg.kDP); 1411 for(i=0,ni=m_nodes.size();i<ni;++i) 1412 { 1413 Node& n=m_nodes[i]; 1414 n.m_v = (n.m_x-n.m_q)*vc; 1415 n.m_f = btVector3(0,0,0); 1416 } 1417 } 1418 /* Solve drift */ 1419 if(m_cfg.diterations>0) 1420 { 1421 const btScalar vcf=m_cfg.kVCF*m_sst.isdt; 1422 for(i=0,ni=m_nodes.size();i<ni;++i) 1423 { 1424 Node& n=m_nodes[i]; 1425 n.m_q = n.m_x; 1426 } 1427 for(int idrift=0;idrift<m_cfg.diterations;++idrift) 1428 { 1429 for(int iseq=0;iseq<m_cfg.m_dsequence.size();++iseq) 1430 { 1431 getSolver(m_cfg.m_dsequence[iseq])(this,1,0); 1432 } 1433 } 1434 for(int i=0,ni=m_nodes.size();i<ni;++i) 1435 { 1436 Node& n=m_nodes[i]; 1437 n.m_v += (n.m_x-n.m_q)*vcf; 1438 } 1439 } 1440 /* Apply clusters */ 1441 dampClusters(); 1442 applyClusters(true); 1445 1443 } 1446 1444 … … 1448 1446 void btSoftBody::staticSolve(int iterations) 1449 1447 { 1450 1451 { 1452 1453 { 1454 1448 for(int isolve=0;isolve<iterations;++isolve) 1449 { 1450 for(int iseq=0;iseq<m_cfg.m_psequence.size();++iseq) 1451 { 1452 getSolver(m_cfg.m_psequence[iseq])(this,1,0); 1455 1453 } 1456 1454 } … … 1460 1458 void btSoftBody::solveCommonConstraints(btSoftBody** /*bodies*/,int /*count*/,int /*iterations*/) 1461 1459 { 1462 1460 /// placeholder 1463 1461 } 1464 1462 … … 1466 1464 void btSoftBody::solveClusters(const btAlignedObjectArray<btSoftBody*>& bodies) 1467 1465 { 1468 1469 1470 1471 1472 1473 { 1474 1475 } 1476 1477 { 1478 1479 } 1480 1481 { 1482 1483 1484 { 1485 1486 } 1487 } 1488 1489 { 1490 1466 const int nb=bodies.size(); 1467 int iterations=0; 1468 int i; 1469 1470 for(i=0;i<nb;++i) 1471 { 1472 iterations=btMax(iterations,bodies[i]->m_cfg.citerations); 1473 } 1474 for(i=0;i<nb;++i) 1475 { 1476 bodies[i]->prepareClusters(iterations); 1477 } 1478 for(i=0;i<iterations;++i) 1479 { 1480 const btScalar sor=1; 1481 for(int j=0;j<nb;++j) 1482 { 1483 bodies[j]->solveClusters(sor); 1484 } 1485 } 1486 for(i=0;i<nb;++i) 1487 { 1488 bodies[i]->cleanupClusters(); 1491 1489 } 1492 1490 } … … 1500 1498 1501 1499 // 1502 btSoftBody::RayFromToCaster::RayFromToCaster(const btVector3& rayFrom,const btVector3& rayTo,btScalar mxt) 1503 { 1504 m_rayFrom = rayFrom; 1505 m_rayNormalizedDirection = (rayTo-rayFrom); 1506 m_rayTo = rayTo; 1507 m_mint = mxt; 1508 m_face = 0; 1509 m_tests = 0; 1510 } 1511 1512 // 1513 void btSoftBody::RayFromToCaster::Process(const btDbvtNode* leaf) 1514 { 1515 btSoftBody::Face& f=*(btSoftBody::Face*)leaf->data; 1516 const btScalar t=rayFromToTriangle( m_rayFrom,m_rayTo,m_rayNormalizedDirection, 1517 f.m_n[0]->m_x, 1518 f.m_n[1]->m_x, 1519 f.m_n[2]->m_x, 1520 m_mint); 1521 if((t>0)&&(t<m_mint)) 1522 { 1523 m_mint=t;m_face=&f; 1524 } 1525 ++m_tests; 1526 } 1527 1528 // 1529 btScalar btSoftBody::RayFromToCaster::rayFromToTriangle( const btVector3& rayFrom, 1530 const btVector3& rayTo, 1531 const btVector3& rayNormalizedDirection, 1532 const btVector3& a, 1533 const btVector3& b, 1534 const btVector3& c, 1535 btScalar maxt) 1500 btSoftBody::RayCaster::RayCaster(const btVector3& org,const btVector3& dir,btScalar mxt) 1501 { 1502 o = org; 1503 d = dir; 1504 mint = mxt; 1505 face = 0; 1506 tests = 0; 1507 } 1508 1509 // 1510 void btSoftBody::RayCaster::Process(const btDbvtNode* leaf) 1511 { 1512 btSoftBody::Face& f=*(btSoftBody::Face*)leaf->data; 1513 const btScalar t=rayTriangle( o,d, 1514 f.m_n[0]->m_x, 1515 f.m_n[1]->m_x, 1516 f.m_n[2]->m_x, 1517 mint); 1518 if((t>0)&&(t<mint)) { mint=t;face=&f; } 1519 ++tests; 1520 } 1521 1522 // 1523 btScalar btSoftBody::RayCaster::rayTriangle( const btVector3& org, 1524 const btVector3& dir, 1525 const btVector3& a, 1526 const btVector3& b, 1527 const btVector3& c, 1528 btScalar maxt) 1536 1529 { 1537 1530 static const btScalar ceps=-SIMD_EPSILON*10; 1538 1531 static const btScalar teps=SIMD_EPSILON*10; 1539 1540 1532 const btVector3 n=cross(b-a,c-a); 1541 1533 const btScalar d=dot(a,n); 1542 const btScalar den=dot( rayNormalizedDirection,n);1534 const btScalar den=dot(dir,n); 1543 1535 if(!btFuzzyZero(den)) 1544 1536 { 1545 const btScalar num=dot( rayFrom,n)-d;1537 const btScalar num=dot(org,n)-d; 1546 1538 const btScalar t=-num/den; 1547 1539 if((t>teps)&&(t<maxt)) 1548 1540 { 1549 const btVector3 hit= rayFrom+rayNormalizedDirection*t;1541 const btVector3 hit=org+dir*t; 1550 1542 if( (dot(n,cross(a-hit,b-hit))>ceps) && 1551 1543 (dot(n,cross(b-hit,c-hit))>ceps) && … … 1569 1561 { 1570 1562 if(m_nodes[i].m_leaf) 1571 {1563 { 1572 1564 m_nodes[i].m_leaf->data=*(void**)&i; 1573 }1565 } 1574 1566 } 1575 1567 for(i=0,ni=m_links.size();i<ni;++i) … … 1584 1576 m_faces[i].m_n[2]=PTR2IDX(m_faces[i].m_n[2],base); 1585 1577 if(m_faces[i].m_leaf) 1586 {1578 { 1587 1579 m_faces[i].m_leaf->data=*(void**)&i; 1588 }1580 } 1589 1581 } 1590 1582 for(i=0,ni=m_anchors.size();i<ni;++i) 1591 {1583 { 1592 1584 m_anchors[i].m_node=PTR2IDX(m_anchors[i].m_node,base); 1593 }1585 } 1594 1586 for(i=0,ni=m_notes.size();i<ni;++i) 1595 {1587 { 1596 1588 for(int j=0;j<m_notes[i].m_rank;++j) 1597 {1589 { 1598 1590 m_notes[i].m_nodes[j]=PTR2IDX(m_notes[i].m_nodes[j],base); 1599 }1600 }1591 } 1592 } 1601 1593 #undef PTR2IDX 1602 1594 } … … 1606 1598 { 1607 1599 #define IDX2PTR(_p_,_b_) map?(&(_b_)[map[(((char*)_p_)-(char*)0)]]): \ 1608 (&(_b_)[(((char*)_p_)-(char*)0)])1600 (&(_b_)[(((char*)_p_)-(char*)0)]) 1609 1601 btSoftBody::Node* base=&m_nodes[0]; 1610 1602 int i,ni; … … 1613 1605 { 1614 1606 if(m_nodes[i].m_leaf) 1615 {1607 { 1616 1608 m_nodes[i].m_leaf->data=&m_nodes[i]; 1617 }1609 } 1618 1610 } 1619 1611 for(i=0,ni=m_links.size();i<ni;++i) … … 1628 1620 m_faces[i].m_n[2]=IDX2PTR(m_faces[i].m_n[2],base); 1629 1621 if(m_faces[i].m_leaf) 1630 {1622 { 1631 1623 m_faces[i].m_leaf->data=&m_faces[i]; 1632 }1624 } 1633 1625 } 1634 1626 for(i=0,ni=m_anchors.size();i<ni;++i) 1635 {1627 { 1636 1628 m_anchors[i].m_node=IDX2PTR(m_anchors[i].m_node,base); 1637 }1629 } 1638 1630 for(i=0,ni=m_notes.size();i<ni;++i) 1639 {1631 { 1640 1632 for(int j=0;j<m_notes[i].m_rank;++j) 1641 {1633 { 1642 1634 m_notes[i].m_nodes[j]=IDX2PTR(m_notes[i].m_nodes[j],base); 1643 }1644 }1635 } 1636 } 1645 1637 #undef IDX2PTR 1646 1638 } 1647 1639 1648 1640 // 1649 int btSoftBody::ray Test(const btVector3& rayFrom,const btVector3& rayTo,1641 int btSoftBody::rayCast(const btVector3& org,const btVector3& dir, 1650 1642 btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const 1651 1643 { 1652 1644 int cnt=0; 1653 1645 if(bcountonly||m_fdbvt.empty()) 1654 {/* Full search */ 1655 btVector3 dir = rayTo-rayFrom; 1656 dir.normalize(); 1657 1646 {/* Full search */ 1658 1647 for(int i=0,ni=m_faces.size();i<ni;++i) 1659 {1648 { 1660 1649 const btSoftBody::Face& f=m_faces[i]; 1661 1662 const btScalar t=RayFromToCaster::rayFromToTriangle( rayFrom,rayTo,dir, 1663 f.m_n[0]->m_x, 1664 f.m_n[1]->m_x, 1665 f.m_n[2]->m_x, 1666 mint); 1650 const btScalar t=RayCaster::rayTriangle( org,dir, 1651 f.m_n[0]->m_x, 1652 f.m_n[1]->m_x, 1653 f.m_n[2]->m_x, 1654 mint); 1667 1655 if(t>0) 1668 {1656 { 1669 1657 ++cnt; 1670 1658 if(!bcountonly) 1671 {1659 { 1672 1660 feature=btSoftBody::eFeature::Face; 1673 1661 index=i; 1674 1662 mint=t; 1663 } 1675 1664 } 1676 1665 } 1677 1666 } 1678 } 1679 else 1680 {/* Use dbvt */ 1681 RayFromToCaster collider(rayFrom,rayTo,mint); 1682 1683 btDbvt::rayTest(m_fdbvt.m_root,rayFrom,rayTo,collider); 1684 if(collider.m_face) 1685 { 1686 mint=collider.m_mint; 1667 else 1668 {/* Use dbvt */ 1669 RayCaster collider(org,dir,mint); 1670 btDbvt::collideRAY(m_fdbvt.m_root,org,dir,collider); 1671 if(collider.face) 1672 { 1673 mint=collider.mint; 1687 1674 feature=btSoftBody::eFeature::Face; 1688 index=(int)(collider. m_face-&m_faces[0]);1675 index=(int)(collider.face-&m_faces[0]); 1689 1676 cnt=1; 1690 }1691 }1677 } 1678 } 1692 1679 return(cnt); 1693 1680 } … … 1696 1683 void btSoftBody::initializeFaceTree() 1697 1684 { 1698 1699 1700 { 1701 1702 1685 m_fdbvt.clear(); 1686 for(int i=0;i<m_faces.size();++i) 1687 { 1688 Face& f=m_faces[i]; 1689 f.m_leaf=m_fdbvt.insert(VolumeOf(f,0),&f); 1703 1690 } 1704 1691 } … … 1707 1694 btVector3 btSoftBody::evaluateCom() const 1708 1695 { 1709 1710 1711 { 1712 1713 { 1714 1696 btVector3 com(0,0,0); 1697 if(m_pose.m_bframe) 1698 { 1699 for(int i=0,ni=m_nodes.size();i<ni;++i) 1700 { 1701 com+=m_nodes[i].m_x*m_pose.m_wgh[i]; 1715 1702 } 1716 1703 } 1717 1704 return(com); 1718 1705 } 1719 1706 1720 1707 // 1721 1708 bool btSoftBody::checkContact( btRigidBody* prb, 1722 1723 1724 1709 const btVector3& x, 1710 btScalar margin, 1711 btSoftBody::sCti& cti) const 1725 1712 { 1726 1713 btVector3 nrm; … … 1728 1715 const btTransform& wtr=prb->getInterpolationWorldTransform(); 1729 1716 btScalar dst=m_worldInfo->m_sparsesdf.Evaluate( wtr.invXform(x), 1730 shp,1731 nrm,1732 margin);1717 shp, 1718 nrm, 1719 margin); 1733 1720 if(dst<0) 1734 1721 { … … 1736 1723 cti.m_normal = wtr.getBasis()*nrm; 1737 1724 cti.m_offset = -dot( cti.m_normal, 1738 x-cti.m_normal*dst);1725 x-cti.m_normal*dst); 1739 1726 return(true); 1740 1727 } … … 1756 1743 btSoftBody::Face& f=m_faces[i]; 1757 1744 const btVector3 n=cross(f.m_n[1]->m_x-f.m_n[0]->m_x, 1758 f.m_n[2]->m_x-f.m_n[0]->m_x);1745 f.m_n[2]->m_x-f.m_n[0]->m_x); 1759 1746 f.m_normal=n.normalized(); 1760 1747 f.m_n[0]->m_n+=n; … … 1774 1761 { 1775 1762 if(m_ndbvt.m_root) 1776 {1763 { 1777 1764 const btVector3& mins=m_ndbvt.m_root->volume.Mins(); 1778 1765 const btVector3& maxs=m_ndbvt.m_root->volume.Maxs(); 1779 1766 const btScalar csm=getCollisionShape()->getMargin(); 1780 1767 const btVector3 mrg=btVector3( csm, 1781 csm,1782 csm)*1; // ??? to investigate...1768 csm, 1769 csm)*1; // ??? to investigate... 1783 1770 m_bounds[0]=mins-mrg; 1784 1771 m_bounds[1]=maxs+mrg; 1785 if(0!=getBroadphaseHandle())1786 {1787 m_worldInfo->m_broadphase->setAabb( getBroadphaseHandle(),1788 m_bounds[0],1789 m_bounds[1],1790 m_worldInfo->m_dispatcher);1791 }1792 }1793 else1794 {1772 if(0!=getBroadphaseHandle()) 1773 { 1774 m_worldInfo->m_broadphase->setAabb( getBroadphaseHandle(), 1775 m_bounds[0], 1776 m_bounds[1], 1777 m_worldInfo->m_dispatcher); 1778 } 1779 } 1780 else 1781 { 1795 1782 m_bounds[0]= 1796 1797 }1783 m_bounds[1]=btVector3(0,0,0); 1784 } 1798 1785 } 1799 1786 … … 1826 1813 pose.m_scl=pose.m_aqq*r.transpose()*Apq; 1827 1814 if(m_cfg.maxvolume>1) 1828 {1815 { 1829 1816 const btScalar idet=Clamp<btScalar>( 1/pose.m_scl.determinant(), 1830 1,m_cfg.maxvolume);1817 1,m_cfg.maxvolume); 1831 1818 pose.m_scl=Mul(pose.m_scl,idet); 1832 }1833 1819 } 1820 1834 1821 } 1835 1822 } … … 1886 1873 int i; 1887 1874 1888 for( i=0;i<m_clusters.size();++i) 1889 { 1890 Cluster& c=*m_clusters[i]; 1891 c.m_imass=0; 1892 c.m_masses.resize(c.m_nodes.size()); 1893 for(int j=0;j<c.m_nodes.size();++j) 1894 { 1895 c.m_masses[j] = c.m_nodes[j]->m_im>0?1/c.m_nodes[j]->m_im:0; 1896 c.m_imass += c.m_masses[j]; 1897 } 1898 c.m_imass = 1/c.m_imass; 1899 c.m_com = btSoftBody::clusterCom(&c); 1900 c.m_lv = btVector3(0,0,0); 1901 c.m_av = btVector3(0,0,0); 1902 c.m_leaf = 0; 1903 /* Inertia */ 1904 btMatrix3x3& ii=c.m_locii; 1905 ii[0]=ii[1]=ii[2]=btVector3(0,0,0); 1906 { 1907 int i,ni; 1908 1909 for(i=0,ni=c.m_nodes.size();i<ni;++i) 1910 { 1911 const btVector3 k=c.m_nodes[i]->m_x-c.m_com; 1912 const btVector3 q=k*k; 1913 const btScalar m=c.m_masses[i]; 1914 ii[0][0] += m*(q[1]+q[2]); 1915 ii[1][1] += m*(q[0]+q[2]); 1916 ii[2][2] += m*(q[0]+q[1]); 1917 ii[0][1] -= m*k[0]*k[1]; 1918 ii[0][2] -= m*k[0]*k[2]; 1919 ii[1][2] -= m*k[1]*k[2]; 1920 } 1921 } 1922 ii[1][0]=ii[0][1]; 1923 ii[2][0]=ii[0][2]; 1924 ii[2][1]=ii[1][2]; 1925 ii=ii.inverse(); 1926 /* Frame */ 1927 c.m_framexform.setIdentity(); 1875 for( i=0;i<m_clusters.size();++i) 1876 { 1877 Cluster& c=*m_clusters[i]; 1878 c.m_imass=0; 1879 c.m_masses.resize(c.m_nodes.size()); 1880 for(int j=0;j<c.m_nodes.size();++j) 1881 { 1882 c.m_masses[j] = c.m_nodes[j]->m_im>0?1/c.m_nodes[j]->m_im:0; 1883 c.m_imass += c.m_masses[j]; 1884 } 1885 c.m_imass = 1/c.m_imass; 1886 c.m_com = btSoftBody::clusterCom(&c); 1887 c.m_lv = btVector3(0,0,0); 1888 c.m_av = btVector3(0,0,0); 1889 c.m_leaf = 0; 1890 /* Inertia */ 1891 btMatrix3x3& ii=c.m_locii; 1892 ii[0]=ii[1]=ii[2]=btVector3(0,0,0); 1893 { 1894 int i,ni; 1895 1896 for(i=0,ni=c.m_nodes.size();i<ni;++i) 1897 { 1898 const btVector3 k=c.m_nodes[i]->m_x-c.m_com; 1899 const btVector3 q=k*k; 1900 const btScalar m=c.m_masses[i]; 1901 ii[0][0] += m*(q[1]+q[2]); 1902 ii[1][1] += m*(q[0]+q[2]); 1903 ii[2][2] += m*(q[0]+q[1]); 1904 ii[0][1] -= m*k[0]*k[1]; 1905 ii[0][2] -= m*k[0]*k[2]; 1906 ii[1][2] -= m*k[1]*k[2]; 1907 } 1908 } 1909 ii[1][0]=ii[0][1]; 1910 ii[2][0]=ii[0][2]; 1911 ii[2][1]=ii[1][2]; 1912 ii=ii.inverse(); 1913 /* Frame */ 1914 c.m_framexform.setIdentity(); 1915 c.m_framexform.setOrigin(c.m_com); 1916 c.m_framerefs.resize(c.m_nodes.size()); 1917 { 1918 int i; 1919 for(i=0;i<c.m_framerefs.size();++i) 1920 { 1921 c.m_framerefs[i]=c.m_nodes[i]->m_x-c.m_com; 1922 } 1923 } 1924 } 1925 } 1926 1927 // 1928 void btSoftBody::updateClusters() 1929 { 1930 BT_PROFILE("UpdateClusters"); 1931 int i; 1932 1933 for(i=0;i<m_clusters.size();++i) 1934 { 1935 btSoftBody::Cluster& c=*m_clusters[i]; 1936 const int n=c.m_nodes.size(); 1937 const btScalar invn=1/(btScalar)n; 1938 if(n) 1939 { 1940 /* Frame */ 1941 const btScalar eps=btScalar(0.0001); 1942 btMatrix3x3 m,r,s; 1943 m[0]=m[1]=m[2]=btVector3(0,0,0); 1944 m[0][0]=eps*1; 1945 m[1][1]=eps*2; 1946 m[2][2]=eps*3; 1947 c.m_com=clusterCom(&c); 1948 for(int i=0;i<c.m_nodes.size();++i) 1949 { 1950 const btVector3 a=c.m_nodes[i]->m_x-c.m_com; 1951 const btVector3& b=c.m_framerefs[i]; 1952 m[0]+=a[0]*b;m[1]+=a[1]*b;m[2]+=a[2]*b; 1953 } 1954 PolarDecompose(m,r,s); 1928 1955 c.m_framexform.setOrigin(c.m_com); 1929 c.m_framerefs.resize(c.m_nodes.size()); 1930 { 1931 int i; 1932 for(i=0;i<c.m_framerefs.size();++i) 1933 { 1934 c.m_framerefs[i]=c.m_nodes[i]->m_x-c.m_com; 1935 } 1936 } 1937 } 1938 } 1939 1940 // 1941 void btSoftBody::updateClusters() 1942 { 1943 BT_PROFILE("UpdateClusters"); 1944 int i; 1945 1946 for(i=0;i<m_clusters.size();++i) 1947 { 1948 btSoftBody::Cluster& c=*m_clusters[i]; 1949 const int n=c.m_nodes.size(); 1950 const btScalar invn=1/(btScalar)n; 1951 if(n) 1952 { 1953 /* Frame */ 1954 const btScalar eps=btScalar(0.0001); 1955 btMatrix3x3 m,r,s; 1956 m[0]=m[1]=m[2]=btVector3(0,0,0); 1957 m[0][0]=eps*1; 1958 m[1][1]=eps*2; 1959 m[2][2]=eps*3; 1960 c.m_com=clusterCom(&c); 1961 for(int i=0;i<c.m_nodes.size();++i) 1962 { 1963 const btVector3 a=c.m_nodes[i]->m_x-c.m_com; 1964 const btVector3& b=c.m_framerefs[i]; 1965 m[0]+=a[0]*b;m[1]+=a[1]*b;m[2]+=a[2]*b; 1966 } 1967 PolarDecompose(m,r,s); 1968 c.m_framexform.setOrigin(c.m_com); 1969 c.m_framexform.setBasis(r); 1970 /* Inertia */ 1971 #if 1/* Constant */ 1972 c.m_invwi=c.m_framexform.getBasis()*c.m_locii*c.m_framexform.getBasis().transpose(); 1973 #else 1974 #if 0/* Sphere */ 1956 c.m_framexform.setBasis(r); 1957 /* Inertia */ 1958 #if 1/* Constant */ 1959 c.m_invwi=c.m_framexform.getBasis()*c.m_locii*c.m_framexform.getBasis().transpose(); 1960 #else 1961 #if 0/* Sphere */ 1975 1962 const btScalar rk=(2*c.m_extents.length2())/(5*c.m_imass); 1976 1963 const btVector3 inertia(rk,rk,rk); 1977 1964 const btVector3 iin(btFabs(inertia[0])>SIMD_EPSILON?1/inertia[0]:0, 1978 btFabs(inertia[1])>SIMD_EPSILON?1/inertia[1]:0,1979 btFabs(inertia[2])>SIMD_EPSILON?1/inertia[2]:0);1980 1965 btFabs(inertia[1])>SIMD_EPSILON?1/inertia[1]:0, 1966 btFabs(inertia[2])>SIMD_EPSILON?1/inertia[2]:0); 1967 1981 1968 c.m_invwi=c.m_xform.getBasis().scaled(iin)*c.m_xform.getBasis().transpose(); 1982 #else/* Actual */1969 #else/* Actual */ 1983 1970 c.m_invwi[0]=c.m_invwi[1]=c.m_invwi[2]=btVector3(0,0,0); 1984 1971 for(int i=0;i<n;++i) 1985 {1972 { 1986 1973 const btVector3 k=c.m_nodes[i]->m_x-c.m_com; 1987 1974 const btVector3 q=k*k; … … 1993 1980 c.m_invwi[0][2] -= m*k[0]*k[2]; 1994 1981 c.m_invwi[1][2] -= m*k[1]*k[2]; 1995 }1982 } 1996 1983 c.m_invwi[1][0]=c.m_invwi[0][1]; 1997 1984 c.m_invwi[2][0]=c.m_invwi[0][2]; 1998 1985 c.m_invwi[2][1]=c.m_invwi[1][2]; 1999 1986 c.m_invwi=c.m_invwi.inverse(); 2000 #endif 2001 #endif 2002 /* Velocities */ 2003 c.m_lv=btVector3(0,0,0); 2004 c.m_av=btVector3(0,0,0); 2005 { 2006 int i; 2007 2008 for(i=0;i<n;++i) 1987 #endif 1988 #endif 1989 /* Velocities */ 1990 c.m_lv=btVector3(0,0,0); 1991 c.m_av=btVector3(0,0,0); 1992 { 1993 int i; 1994 1995 for(i=0;i<n;++i) 1996 { 1997 const btVector3 v=c.m_nodes[i]->m_v*c.m_masses[i]; 1998 c.m_lv += v; 1999 c.m_av += cross(c.m_nodes[i]->m_x-c.m_com,v); 2000 } 2001 } 2002 c.m_lv=c.m_imass*c.m_lv*(1-c.m_ldamping); 2003 c.m_av=c.m_invwi*c.m_av*(1-c.m_adamping); 2004 c.m_vimpulses[0] = 2005 c.m_vimpulses[1] = btVector3(0,0,0); 2006 c.m_dimpulses[0] = 2007 c.m_dimpulses[1] = btVector3(0,0,0); 2008 c.m_nvimpulses = 0; 2009 c.m_ndimpulses = 0; 2010 /* Matching */ 2011 if(c.m_matching>0) 2012 { 2013 for(int j=0;j<c.m_nodes.size();++j) 2009 2014 { 2010 const btVector3 v=c.m_nodes[i]->m_v*c.m_masses[i];2011 c.m_lv += v;2012 c.m_av += cross(c.m_nodes[i]->m_x-c.m_com,v);2015 Node& n=*c.m_nodes[j]; 2016 const btVector3 x=c.m_framexform*c.m_framerefs[j]; 2017 n.m_x=Lerp(n.m_x,x,c.m_matching); 2013 2018 } 2014 2019 } 2015 c.m_lv=c.m_imass*c.m_lv*(1-c.m_ldamping); 2016 c.m_av=c.m_invwi*c.m_av*(1-c.m_adamping); 2017 c.m_vimpulses[0] = 2018 c.m_vimpulses[1] = btVector3(0,0,0); 2019 c.m_dimpulses[0] = 2020 c.m_dimpulses[1] = btVector3(0,0,0); 2021 c.m_nvimpulses = 0; 2022 c.m_ndimpulses = 0; 2023 /* Matching */ 2024 if(c.m_matching>0) 2025 { 2026 for(int j=0;j<c.m_nodes.size();++j) 2020 /* Dbvt */ 2021 if(c.m_collide) 2022 { 2023 btVector3 mi=c.m_nodes[0]->m_x; 2024 btVector3 mx=mi; 2025 for(int j=1;j<n;++j) 2027 2026 { 2028 Node& n=*c.m_nodes[j]; 2029 const btVector3 x=c.m_framexform*c.m_framerefs[j]; 2030 n.m_x=Lerp(n.m_x,x,c.m_matching); 2027 mi.setMin(c.m_nodes[j]->m_x); 2028 mx.setMax(c.m_nodes[j]->m_x); 2029 } 2030 const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(mi,mx); 2031 if(c.m_leaf) 2032 m_cdbvt.update(c.m_leaf,bounds,c.m_lv*m_sst.sdt*3,m_sst.radmrg); 2033 else 2034 c.m_leaf=m_cdbvt.insert(bounds,&c); 2035 } 2036 } 2037 } 2038 } 2039 2040 // 2041 void btSoftBody::cleanupClusters() 2042 { 2043 for(int i=0;i<m_joints.size();++i) 2044 { 2045 m_joints[i]->Terminate(m_sst.sdt); 2046 if(m_joints[i]->m_delete) 2047 { 2048 btAlignedFree(m_joints[i]); 2049 m_joints.remove(m_joints[i--]); 2050 } 2051 } 2052 } 2053 2054 // 2055 void btSoftBody::prepareClusters(int iterations) 2056 { 2057 for(int i=0;i<m_joints.size();++i) 2058 { 2059 m_joints[i]->Prepare(m_sst.sdt,iterations); 2060 } 2061 } 2062 2063 2064 // 2065 void btSoftBody::solveClusters(btScalar sor) 2066 { 2067 for(int i=0,ni=m_joints.size();i<ni;++i) 2068 { 2069 m_joints[i]->Solve(m_sst.sdt,sor); 2070 } 2071 } 2072 2073 // 2074 void btSoftBody::applyClusters(bool drift) 2075 { 2076 BT_PROFILE("ApplyClusters"); 2077 const btScalar f0=m_sst.sdt; 2078 const btScalar f1=f0/2; 2079 btAlignedObjectArray<btVector3> deltas; 2080 btAlignedObjectArray<btScalar> weights; 2081 deltas.resize(m_nodes.size(),btVector3(0,0,0)); 2082 weights.resize(m_nodes.size(),0); 2083 int i; 2084 2085 if(drift) 2086 { 2087 for(i=0;i<m_clusters.size();++i) 2088 { 2089 Cluster& c=*m_clusters[i]; 2090 if(c.m_ndimpulses) 2091 { 2092 c.m_dimpulses[0]/=(btScalar)c.m_ndimpulses; 2093 c.m_dimpulses[1]/=(btScalar)c.m_ndimpulses; 2094 } 2095 } 2096 } 2097 for(i=0;i<m_clusters.size();++i) 2098 { 2099 Cluster& c=*m_clusters[i]; 2100 if(0<(drift?c.m_ndimpulses:c.m_nvimpulses)) 2101 { 2102 const btVector3 v=(drift?c.m_dimpulses[0]:c.m_vimpulses[0])*m_sst.sdt; 2103 const btVector3 w=(drift?c.m_dimpulses[1]:c.m_vimpulses[1])*m_sst.sdt; 2104 for(int j=0;j<c.m_nodes.size();++j) 2105 { 2106 const int idx=int(c.m_nodes[j]-&m_nodes[0]); 2107 const btVector3& x=c.m_nodes[j]->m_x; 2108 const btScalar q=c.m_masses[j]; 2109 deltas[idx] += (v+cross(w,x-c.m_com))*q; 2110 weights[idx] += q; 2111 } 2112 } 2113 } 2114 for(i=0;i<deltas.size();++i) 2115 { 2116 if(weights[i]>0) m_nodes[i].m_x+=deltas[i]/weights[i]; 2117 } 2118 } 2119 2120 // 2121 void btSoftBody::dampClusters() 2122 { 2123 int i; 2124 2125 for(i=0;i<m_clusters.size();++i) 2126 { 2127 Cluster& c=*m_clusters[i]; 2128 if(c.m_ndamping>0) 2129 { 2130 for(int j=0;j<c.m_nodes.size();++j) 2131 { 2132 Node& n=*c.m_nodes[j]; 2133 if(n.m_im>0) 2134 { 2135 const btVector3 vx=c.m_lv+cross(c.m_av,c.m_nodes[j]->m_q-c.m_com); 2136 n.m_v += c.m_ndamping*(vx-n.m_v); 2031 2137 } 2032 2138 } 2033 /* Dbvt */2034 if(c.m_collide)2035 {2036 btVector3 mi=c.m_nodes[0]->m_x;2037 btVector3 mx=mi;2038 for(int j=1;j<n;++j)2039 {2040 mi.setMin(c.m_nodes[j]->m_x);2041 mx.setMax(c.m_nodes[j]->m_x);2042 }2043 const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(mi,mx);2044 if(c.m_leaf)2045 m_cdbvt.update(c.m_leaf,bounds,c.m_lv*m_sst.sdt*3,m_sst.radmrg);2046 else2047 c.m_leaf=m_cdbvt.insert(bounds,&c);2048 }2049 }2050 }2051 }2052 2053 //2054 void btSoftBody::cleanupClusters()2055 {2056 for(int i=0;i<m_joints.size();++i)2057 {2058 m_joints[i]->Terminate(m_sst.sdt);2059 if(m_joints[i]->m_delete)2060 {2061 btAlignedFree(m_joints[i]);2062 m_joints.remove(m_joints[i--]);2063 }2064 }2065 }2066 2067 //2068 void btSoftBody::prepareClusters(int iterations)2069 {2070 for(int i=0;i<m_joints.size();++i)2071 {2072 m_joints[i]->Prepare(m_sst.sdt,iterations);2073 }2074 }2075 2076 2077 //2078 void btSoftBody::solveClusters(btScalar sor)2079 {2080 for(int i=0,ni=m_joints.size();i<ni;++i)2081 {2082 m_joints[i]->Solve(m_sst.sdt,sor);2083 }2084 }2085 2086 //2087 void btSoftBody::applyClusters(bool drift)2088 {2089 BT_PROFILE("ApplyClusters");2090 const btScalar f0=m_sst.sdt;2091 const btScalar f1=f0/2;2092 btAlignedObjectArray<btVector3> deltas;2093 btAlignedObjectArray<btScalar> weights;2094 deltas.resize(m_nodes.size(),btVector3(0,0,0));2095 weights.resize(m_nodes.size(),0);2096 int i;2097 2098 if(drift)2099 {2100 for(i=0;i<m_clusters.size();++i)2101 {2102 Cluster& c=*m_clusters[i];2103 if(c.m_ndimpulses)2104 {2105 c.m_dimpulses[0]/=(btScalar)c.m_ndimpulses;2106 c.m_dimpulses[1]/=(btScalar)c.m_ndimpulses;2107 }2108 }2109 }2110 for(i=0;i<m_clusters.size();++i)2111 {2112 Cluster& c=*m_clusters[i];2113 if(0<(drift?c.m_ndimpulses:c.m_nvimpulses))2114 {2115 const btVector3 v=(drift?c.m_dimpulses[0]:c.m_vimpulses[0])*m_sst.sdt;2116 const btVector3 w=(drift?c.m_dimpulses[1]:c.m_vimpulses[1])*m_sst.sdt;2117 for(int j=0;j<c.m_nodes.size();++j)2118 {2119 const int idx=int(c.m_nodes[j]-&m_nodes[0]);2120 const btVector3& x=c.m_nodes[j]->m_x;2121 const btScalar q=c.m_masses[j];2122 deltas[idx] += (v+cross(w,x-c.m_com))*q;2123 weights[idx] += q;2124 }2125 }2126 }2127 for(i=0;i<deltas.size();++i)2128 {2129 if(weights[i]>0) m_nodes[i].m_x+=deltas[i]/weights[i];2130 }2131 }2132 2133 //2134 void btSoftBody::dampClusters()2135 {2136 int i;2137 2138 for(i=0;i<m_clusters.size();++i)2139 {2140 Cluster& c=*m_clusters[i];2141 if(c.m_ndamping>0)2142 {2143 for(int j=0;j<c.m_nodes.size();++j)2144 {2145 Node& n=*c.m_nodes[j];2146 if(n.m_im>0)2147 {2148 const btVector3 vx=c.m_lv+cross(c.m_av,c.m_nodes[j]->m_q-c.m_com);2149 n.m_v += c.m_ndamping*(vx-n.m_v);2150 }2151 }2152 2139 } 2153 2140 } … … 2157 2144 void btSoftBody::Joint::Prepare(btScalar dt,int) 2158 2145 { 2159 2160 2146 m_bodies[0].activate(); 2147 m_bodies[1].activate(); 2161 2148 } 2162 2149 … … 2164 2151 void btSoftBody::LJoint::Prepare(btScalar dt,int iterations) 2165 2152 { 2166 static const btScalar maxdrift=4; 2167 Joint::Prepare(dt,iterations); 2168 m_rpos[0] = m_bodies[0].xform()*m_refs[0]; 2169 m_rpos[1] = m_bodies[1].xform()*m_refs[1]; 2170 m_drift = Clamp(m_rpos[0]-m_rpos[1],maxdrift)*m_erp/dt; 2171 m_rpos[0] -= m_bodies[0].xform().getOrigin(); 2172 m_rpos[1] -= m_bodies[1].xform().getOrigin(); 2173 m_massmatrix = ImpulseMatrix( m_bodies[0].invMass(),m_bodies[0].invWorldInertia(),m_rpos[0], 2174 m_bodies[1].invMass(),m_bodies[1].invWorldInertia(),m_rpos[1]); 2153 static const btScalar maxdrift=4; 2154 Joint::Prepare(dt,iterations); 2155 m_rpos[0] = m_bodies[0].xform()*m_refs[0]; 2156 m_rpos[1] = m_bodies[1].xform()*m_refs[1]; 2157 m_drift = Clamp(m_rpos[0]-m_rpos[1],maxdrift)*m_erp/dt; 2158 m_rpos[0] -= m_bodies[0].xform().getOrigin(); 2159 m_rpos[1] -= m_bodies[1].xform().getOrigin(); 2160 m_massmatrix = ImpulseMatrix( m_bodies[0].invMass(),m_bodies[0].invWorldInertia(),m_rpos[0], 2161 m_bodies[1].invMass(),m_bodies[1].invWorldInertia(),m_rpos[1]); 2162 if(m_split>0) 2163 { 2164 m_sdrift = m_massmatrix*(m_drift*m_split); 2165 m_drift *= 1-m_split; 2166 } 2167 m_drift /=(btScalar)iterations; 2168 } 2169 2170 // 2171 void btSoftBody::LJoint::Solve(btScalar dt,btScalar sor) 2172 { 2173 const btVector3 va=m_bodies[0].velocity(m_rpos[0]); 2174 const btVector3 vb=m_bodies[1].velocity(m_rpos[1]); 2175 const btVector3 vr=va-vb; 2176 btSoftBody::Impulse impulse; 2177 impulse.m_asVelocity = 1; 2178 impulse.m_velocity = m_massmatrix*(m_drift+vr*m_cfm)*sor; 2179 m_bodies[0].applyImpulse(-impulse,m_rpos[0]); 2180 m_bodies[1].applyImpulse( impulse,m_rpos[1]); 2181 } 2182 2183 // 2184 void btSoftBody::LJoint::Terminate(btScalar dt) 2185 { 2186 if(m_split>0) 2187 { 2188 m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]); 2189 m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]); 2190 } 2191 } 2192 2193 // 2194 void btSoftBody::AJoint::Prepare(btScalar dt,int iterations) 2195 { 2196 static const btScalar maxdrift=SIMD_PI/16; 2197 m_icontrol->Prepare(this); 2198 Joint::Prepare(dt,iterations); 2199 m_axis[0] = m_bodies[0].xform().getBasis()*m_refs[0]; 2200 m_axis[1] = m_bodies[1].xform().getBasis()*m_refs[1]; 2201 m_drift = NormalizeAny(cross(m_axis[1],m_axis[0])); 2202 m_drift *= btMin(maxdrift,btAcos(Clamp<btScalar>(dot(m_axis[0],m_axis[1]),-1,+1))); 2203 m_drift *= m_erp/dt; 2204 m_massmatrix= AngularImpulseMatrix(m_bodies[0].invWorldInertia(),m_bodies[1].invWorldInertia()); 2205 if(m_split>0) 2206 { 2207 m_sdrift = m_massmatrix*(m_drift*m_split); 2208 m_drift *= 1-m_split; 2209 } 2210 m_drift /=(btScalar)iterations; 2211 } 2212 2213 // 2214 void btSoftBody::AJoint::Solve(btScalar dt,btScalar sor) 2215 { 2216 const btVector3 va=m_bodies[0].angularVelocity(); 2217 const btVector3 vb=m_bodies[1].angularVelocity(); 2218 const btVector3 vr=va-vb; 2219 const btScalar sp=dot(vr,m_axis[0]); 2220 const btVector3 vc=vr-m_axis[0]*m_icontrol->Speed(this,sp); 2221 btSoftBody::Impulse impulse; 2222 impulse.m_asVelocity = 1; 2223 impulse.m_velocity = m_massmatrix*(m_drift+vc*m_cfm)*sor; 2224 m_bodies[0].applyAImpulse(-impulse); 2225 m_bodies[1].applyAImpulse( impulse); 2226 } 2227 2228 // 2229 void btSoftBody::AJoint::Terminate(btScalar dt) 2230 { 2231 if(m_split>0) 2232 { 2233 m_bodies[0].applyDAImpulse(-m_sdrift); 2234 m_bodies[1].applyDAImpulse( m_sdrift); 2235 } 2236 } 2237 2238 // 2239 void btSoftBody::CJoint::Prepare(btScalar dt,int iterations) 2240 { 2241 Joint::Prepare(dt,iterations); 2242 const bool dodrift=(m_life==0); 2243 m_delete=(++m_life)>m_maxlife; 2244 if(dodrift) 2245 { 2246 m_drift=m_drift*m_erp/dt; 2175 2247 if(m_split>0) 2176 {2248 { 2177 2249 m_sdrift = m_massmatrix*(m_drift*m_split); 2178 2250 m_drift *= 1-m_split; 2179 } 2180 m_drift /=(btScalar)iterations; 2181 } 2182 2183 // 2184 void btSoftBody::LJoint::Solve(btScalar dt,btScalar sor) 2185 { 2186 const btVector3 va=m_bodies[0].velocity(m_rpos[0]); 2187 const btVector3 vb=m_bodies[1].velocity(m_rpos[1]); 2188 const btVector3 vr=va-vb; 2189 btSoftBody::Impulse impulse; 2190 impulse.m_asVelocity = 1; 2191 impulse.m_velocity = m_massmatrix*(m_drift+vr*m_cfm)*sor; 2192 m_bodies[0].applyImpulse(-impulse,m_rpos[0]); 2193 m_bodies[1].applyImpulse( impulse,m_rpos[1]); 2194 } 2195 2196 // 2197 void btSoftBody::LJoint::Terminate(btScalar dt) 2198 { 2199 if(m_split>0) 2200 { 2201 m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]); 2202 m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]); 2203 } 2204 } 2205 2206 // 2207 void btSoftBody::AJoint::Prepare(btScalar dt,int iterations) 2208 { 2209 static const btScalar maxdrift=SIMD_PI/16; 2210 m_icontrol->Prepare(this); 2211 Joint::Prepare(dt,iterations); 2212 m_axis[0] = m_bodies[0].xform().getBasis()*m_refs[0]; 2213 m_axis[1] = m_bodies[1].xform().getBasis()*m_refs[1]; 2214 m_drift = NormalizeAny(cross(m_axis[1],m_axis[0])); 2215 m_drift *= btMin(maxdrift,btAcos(Clamp<btScalar>(dot(m_axis[0],m_axis[1]),-1,+1))); 2216 m_drift *= m_erp/dt; 2217 m_massmatrix= AngularImpulseMatrix(m_bodies[0].invWorldInertia(),m_bodies[1].invWorldInertia()); 2218 if(m_split>0) 2219 { 2220 m_sdrift = m_massmatrix*(m_drift*m_split); 2221 m_drift *= 1-m_split; 2222 } 2223 m_drift /=(btScalar)iterations; 2224 } 2225 2226 // 2227 void btSoftBody::AJoint::Solve(btScalar dt,btScalar sor) 2228 { 2229 const btVector3 va=m_bodies[0].angularVelocity(); 2230 const btVector3 vb=m_bodies[1].angularVelocity(); 2231 const btVector3 vr=va-vb; 2232 const btScalar sp=dot(vr,m_axis[0]); 2233 const btVector3 vc=vr-m_axis[0]*m_icontrol->Speed(this,sp); 2234 btSoftBody::Impulse impulse; 2235 impulse.m_asVelocity = 1; 2236 impulse.m_velocity = m_massmatrix*(m_drift+vc*m_cfm)*sor; 2237 m_bodies[0].applyAImpulse(-impulse); 2238 m_bodies[1].applyAImpulse( impulse); 2239 } 2240 2241 // 2242 void btSoftBody::AJoint::Terminate(btScalar dt) 2243 { 2244 if(m_split>0) 2245 { 2246 m_bodies[0].applyDAImpulse(-m_sdrift); 2247 m_bodies[1].applyDAImpulse( m_sdrift); 2248 } 2249 } 2250 2251 // 2252 void btSoftBody::CJoint::Prepare(btScalar dt,int iterations) 2253 { 2254 Joint::Prepare(dt,iterations); 2255 const bool dodrift=(m_life==0); 2256 m_delete=(++m_life)>m_maxlife; 2257 if(dodrift) 2258 { 2259 m_drift=m_drift*m_erp/dt; 2260 if(m_split>0) 2261 { 2262 m_sdrift = m_massmatrix*(m_drift*m_split); 2263 m_drift *= 1-m_split; 2264 } 2265 m_drift/=(btScalar)iterations; 2251 } 2252 m_drift/=(btScalar)iterations; 2266 2253 } 2267 2254 else 2268 2255 { 2269 2256 m_drift=m_sdrift=btVector3(0,0,0); 2270 2257 } 2271 2258 } … … 2274 2261 void btSoftBody::CJoint::Solve(btScalar dt,btScalar sor) 2275 2262 { 2276 2277 2278 2279 2280 2281 2282 2283 2284 { 2285 2286 2287 2288 } 2289 2290 2291 2263 const btVector3 va=m_bodies[0].velocity(m_rpos[0]); 2264 const btVector3 vb=m_bodies[1].velocity(m_rpos[1]); 2265 const btVector3 vrel=va-vb; 2266 const btScalar rvac=dot(vrel,m_normal); 2267 btSoftBody::Impulse impulse; 2268 impulse.m_asVelocity = 1; 2269 impulse.m_velocity = m_drift; 2270 if(rvac<0) 2271 { 2272 const btVector3 iv=m_normal*rvac; 2273 const btVector3 fv=vrel-iv; 2274 impulse.m_velocity += iv+fv*m_friction; 2275 } 2276 impulse.m_velocity=m_massmatrix*impulse.m_velocity*sor; 2277 m_bodies[0].applyImpulse(-impulse,m_rpos[0]); 2278 m_bodies[1].applyImpulse( impulse,m_rpos[1]); 2292 2279 } 2293 2280 … … 2295 2282 void btSoftBody::CJoint::Terminate(btScalar dt) 2296 2283 { 2297 2298 { 2299 2300 2284 if(m_split>0) 2285 { 2286 m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]); 2287 m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]); 2301 2288 } 2302 2289 } … … 2316 2303 const bool as_volume=kVC>0; 2317 2304 const bool as_aero= as_lift || 2318 as_drag ;2305 as_drag ; 2319 2306 const bool as_vaero= as_aero && 2320 (m_cfg.aeromodel<btSoftBody::eAeroModel::F_TwoSided);2307 (m_cfg.aeromodel<btSoftBody::eAeroModel::F_TwoSided); 2321 2308 const bool as_faero= as_aero && 2322 (m_cfg.aeromodel>=btSoftBody::eAeroModel::F_TwoSided);2309 (m_cfg.aeromodel>=btSoftBody::eAeroModel::F_TwoSided); 2323 2310 const bool use_medium= as_aero; 2324 2311 const bool use_volume= as_pressure || 2325 as_volume ;2312 as_volume ; 2326 2313 btScalar volume=0; 2327 2314 btScalar ivolumetp=0; … … 2471 2458 void btSoftBody::PSolve_SContacts(btSoftBody* psb,btScalar,btScalar ti) 2472 2459 { 2473 2474 { 2475 2476 2477 2478 2479 2480 f.m_n[1]->m_x,2481 f.m_n[2]->m_x,2482 c.m_weights);2483 2484 f.m_n[1]->m_q,2485 f.m_n[2]->m_q,2486 c.m_weights);2487 2488 2489 2490 { 2491 2492 2493 } 2494 2495 2496 2497 2498 2460 for(int i=0,ni=psb->m_scontacts.size();i<ni;++i) 2461 { 2462 const SContact& c=psb->m_scontacts[i]; 2463 const btVector3& nr=c.m_normal; 2464 Node& n=*c.m_node; 2465 Face& f=*c.m_face; 2466 const btVector3 p=BaryEval( f.m_n[0]->m_x, 2467 f.m_n[1]->m_x, 2468 f.m_n[2]->m_x, 2469 c.m_weights); 2470 const btVector3 q=BaryEval( f.m_n[0]->m_q, 2471 f.m_n[1]->m_q, 2472 f.m_n[2]->m_q, 2473 c.m_weights); 2474 const btVector3 vr=(n.m_x-n.m_q)-(p-q); 2475 btVector3 corr(0,0,0); 2476 if(dot(vr,nr)<0) 2477 { 2478 const btScalar j=c.m_margin-(dot(nr,n.m_x)-dot(nr,p)); 2479 corr+=c.m_normal*j; 2480 } 2481 corr -= ProjectOnPlane(vr,nr)*c.m_friction; 2482 n.m_x += corr*c.m_cfm[0]; 2483 f.m_n[0]->m_x -= corr*(c.m_cfm[1]*c.m_weights.x()); 2484 f.m_n[1]->m_x -= corr*(c.m_cfm[1]*c.m_weights.y()); 2485 f.m_n[2]->m_x -= corr*(c.m_cfm[1]*c.m_weights.z()); 2499 2486 } 2500 2487 } … … 2523 2510 void btSoftBody::VSolve_Links(btSoftBody* psb,btScalar kst) 2524 2511 { 2525 2512 for(int i=0,ni=psb->m_links.size();i<ni;++i) 2526 2513 { 2527 2528 2529 2530 2531 2514 Link& l=psb->m_links[i]; 2515 Node** n=l.m_n; 2516 const btScalar j=-dot(l.m_c3,n[0]->m_v-n[1]->m_v)*l.m_c2*kst; 2517 n[0]->m_v+= l.m_c3*(j*n[0]->m_im); 2518 n[1]->m_v-= l.m_c3*(j*n[1]->m_im); 2532 2519 } 2533 2520 } … … 2536 2523 btSoftBody::psolver_t btSoftBody::getSolver(ePSolver::_ solver) 2537 2524 { 2538 2525 switch(solver) 2539 2526 { 2540 2527 case ePSolver::Anchors: return(&btSoftBody::PSolve_Anchors); … … 2543 2530 case ePSolver::SContacts: return(&btSoftBody::PSolve_SContacts); 2544 2531 } 2545 2532 return(0); 2546 2533 } 2547 2534 … … 2549 2536 btSoftBody::vsolver_t btSoftBody::getSolver(eVSolver::_ solver) 2550 2537 { 2551 2538 switch(solver) 2552 2539 { 2553 2540 case eVSolver::Linear: return(&btSoftBody::VSolve_Links); 2554 2541 } 2555 2542 return(0); 2556 2543 } 2557 2544 … … 2559 2546 void btSoftBody::defaultCollisionHandler(btCollisionObject* pco) 2560 2547 { 2561 2548 switch(m_cfg.collisions&fCollision::RVSmask) 2562 2549 { 2563 2550 case fCollision::SDF_RS: 2564 2551 { 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 mins,2576 maxs);2577 2578 2579 2580 2581 2582 2583 2584 } 2585 2552 btSoftColliders::CollideSDF_RS docollide; 2553 btRigidBody* prb=btRigidBody::upcast(pco); 2554 const btTransform wtr=prb->getInterpolationWorldTransform(); 2555 const btTransform ctr=prb->getWorldTransform(); 2556 const btScalar timemargin=(wtr.getOrigin()-ctr.getOrigin()).length(); 2557 const btScalar basemargin=getCollisionShape()->getMargin(); 2558 btVector3 mins; 2559 btVector3 maxs; 2560 ATTRIBUTE_ALIGNED16(btDbvtVolume) volume; 2561 pco->getCollisionShape()->getAabb( pco->getInterpolationWorldTransform(), 2562 mins, 2563 maxs); 2564 volume=btDbvtVolume::FromMM(mins,maxs); 2565 volume.Expand(btVector3(basemargin,basemargin,basemargin)); 2566 docollide.psb = this; 2567 docollide.prb = prb; 2568 docollide.dynmargin = basemargin+timemargin; 2569 docollide.stamargin = basemargin; 2570 btDbvt::collideTV(m_ndbvt.m_root,volume,docollide); 2571 } 2572 break; 2586 2573 case fCollision::CL_RS: 2587 2574 { 2588 2589 2590 } 2591 2575 btSoftColliders::CollideCL_RS collider; 2576 collider.Process(this,btRigidBody::upcast(pco)); 2577 } 2578 break; 2592 2579 } 2593 2580 } … … 2596 2583 void btSoftBody::defaultCollisionHandler(btSoftBody* psb) 2597 2584 { 2598 2599 2585 const int cf=m_cfg.collisions&psb->m_cfg.collisions; 2586 switch(cf&fCollision::SVSmask) 2600 2587 { 2601 2588 case fCollision::CL_SS: 2602 2589 { 2603 2604 2605 } 2606 2590 btSoftColliders::CollideCL_SS docollide; 2591 docollide.Process(this,psb); 2592 } 2593 break; 2607 2594 case fCollision::VF_SS: 2608 2595 { 2609 2610 2611 2612 psb->getCollisionShape()->getMargin();2613 2614 2615 2616 2617 docollide.psb[1]->m_fdbvt.m_root,2618 docollide);2619 2620 2621 2622 2623 docollide.psb[1]->m_fdbvt.m_root,2624 docollide);2625 } 2626 2627 } 2628 } 2596 btSoftColliders::CollideVF_SS docollide; 2597 /* common */ 2598 docollide.mrg= getCollisionShape()->getMargin()+ 2599 psb->getCollisionShape()->getMargin(); 2600 /* psb0 nodes vs psb1 faces */ 2601 docollide.psb[0]=this; 2602 docollide.psb[1]=psb; 2603 btDbvt::collideTT( docollide.psb[0]->m_ndbvt.m_root, 2604 docollide.psb[1]->m_fdbvt.m_root, 2605 docollide); 2606 /* psb1 nodes vs psb0 faces */ 2607 docollide.psb[0]=psb; 2608 docollide.psb[1]=this; 2609 btDbvt::collideTT( docollide.psb[0]->m_ndbvt.m_root, 2610 docollide.psb[1]->m_fdbvt.m_root, 2611 docollide); 2612 } 2613 break; 2614 } 2615 } -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBody.h
r1963 r1972 63 63 END 64 64 };}; 65 65 66 66 ///eVSolver : velocities solvers 67 67 struct eVSolver { enum _ { … … 69 69 END 70 70 };}; 71 71 72 72 ///ePSolver : positions solvers 73 73 struct ePSolver { enum _ { … … 78 78 END 79 79 };}; 80 80 81 81 ///eSolverPresets 82 82 struct eSolverPresets { enum _ { … … 86 86 END 87 87 };}; 88 88 89 89 ///eFeature 90 90 struct eFeature { enum _ { … … 95 95 END 96 96 };}; 97 97 98 98 typedef btAlignedObjectArray<eVSolver::_> tVSolverArray; 99 99 typedef btAlignedObjectArray<ePSolver::_> tPSolverArray; 100 100 101 101 // 102 102 // Flags 103 103 // 104 104 105 105 ///fCollision 106 106 struct fCollision { enum _ { … … 108 108 SDF_RS = 0x0001, ///SDF based rigid vs soft 109 109 CL_RS = 0x0002, ///Cluster vs convex rigid vs soft 110 110 111 111 SVSmask = 0x00f0, ///Rigid versus soft mask 112 112 VF_SS = 0x0010, ///Vertex vs face soft vs soft handling … … 116 116 END 117 117 };}; 118 118 119 119 ///fMaterial 120 120 struct fMaterial { enum _ { … … 124 124 END 125 125 };}; 126 126 127 127 // 128 128 // API Types 129 129 // 130 130 131 131 /* sRayCast */ 132 132 struct sRayCast … … 135 135 eFeature::_ feature; /// feature type 136 136 int index; /// feature index 137 btScalar fraction; /// time of impact fraction (rayorg+(rayto-rayfrom)*fraction)138 }; 139 137 btScalar time; /// time of impact (rayorg+raydir*time) 138 }; 139 140 140 /* ImplicitFn */ 141 141 struct ImplicitFn … … 143 143 virtual btScalar Eval(const btVector3& x)=0; 144 144 }; 145 145 146 146 // 147 147 // Internal types … … 181 181 int m_flags; // Flags 182 182 }; 183 183 184 184 /* Feature */ 185 185 struct Feature : Element … … 297 297 btScalar m_matching; 298 298 bool m_collide; 299 Cluster() : m_leaf(0),m_ndamping(0),m_ldamping(0),m_adamping(0),m_matching(0) {}299 Cluster() : m_leaf(0),m_ndamping(0),m_ldamping(0),m_adamping(0),m_matching(0) {} 300 300 }; 301 301 /* Impulse */ … … 308 308 Impulse() : m_velocity(0,0,0),m_drift(0,0,0),m_asVelocity(0),m_asDrift(0) {} 309 309 Impulse operator -() const 310 {310 { 311 311 Impulse i=*this; 312 312 i.m_velocity=-i.m_velocity; 313 313 i.m_drift=-i.m_drift; 314 314 return(i); 315 }315 } 316 316 Impulse operator*(btScalar x) const 317 {317 { 318 318 Impulse i=*this; 319 319 i.m_velocity*=x; 320 320 i.m_drift*=x; 321 321 return(i); 322 }322 } 323 323 }; 324 324 /* Body */ … … 327 327 Cluster* m_soft; 328 328 btRigidBody* m_rigid; 329 Body() : m_soft(0),m_rigid(0) {}330 Body(Cluster* p) : m_soft(p),m_rigid(0) {}331 Body(btRigidBody* p) : m_soft(0),m_rigid(p) {}329 Body() : m_soft(0),m_rigid(0) {} 330 Body(Cluster* p) : m_soft(p),m_rigid(0) {} 331 Body(btRigidBody* p) : m_soft(0),m_rigid(p) {} 332 332 void activate() const 333 {333 { 334 334 if(m_rigid) m_rigid->activate(); 335 }335 } 336 336 const btMatrix3x3& invWorldInertia() const 337 {337 { 338 338 static const btMatrix3x3 iwi(0,0,0,0,0,0,0,0,0); 339 339 if(m_rigid) return(m_rigid->getInvInertiaTensorWorld()); 340 340 if(m_soft) return(m_soft->m_invwi); 341 341 return(iwi); 342 }342 } 343 343 btScalar invMass() const 344 {344 { 345 345 if(m_rigid) return(m_rigid->getInvMass()); 346 346 if(m_soft) return(m_soft->m_imass); 347 347 return(0); 348 }348 } 349 349 const btTransform& xform() const 350 {350 { 351 351 static const btTransform identity=btTransform::getIdentity(); 352 352 if(m_rigid) return(m_rigid->getInterpolationWorldTransform()); 353 353 if(m_soft) return(m_soft->m_framexform); 354 354 return(identity); 355 }355 } 356 356 btVector3 linearVelocity() const 357 {357 { 358 358 if(m_rigid) return(m_rigid->getLinearVelocity()); 359 359 if(m_soft) return(m_soft->m_lv); 360 360 return(btVector3(0,0,0)); 361 }361 } 362 362 btVector3 angularVelocity(const btVector3& rpos) const 363 {363 { 364 364 if(m_rigid) return(cross(m_rigid->getAngularVelocity(),rpos)); 365 365 if(m_soft) return(cross(m_soft->m_av,rpos)); 366 366 return(btVector3(0,0,0)); 367 }367 } 368 368 btVector3 angularVelocity() const 369 {369 { 370 370 if(m_rigid) return(m_rigid->getAngularVelocity()); 371 371 if(m_soft) return(m_soft->m_av); 372 372 return(btVector3(0,0,0)); 373 }373 } 374 374 btVector3 velocity(const btVector3& rpos) const 375 {375 { 376 376 return(linearVelocity()+angularVelocity(rpos)); 377 }377 } 378 378 void applyVImpulse(const btVector3& impulse,const btVector3& rpos) const 379 {379 { 380 380 if(m_rigid) m_rigid->applyImpulse(impulse,rpos); 381 381 if(m_soft) btSoftBody::clusterVImpulse(m_soft,rpos,impulse); 382 }382 } 383 383 void applyDImpulse(const btVector3& impulse,const btVector3& rpos) const 384 {384 { 385 385 if(m_rigid) m_rigid->applyImpulse(impulse,rpos); 386 386 if(m_soft) btSoftBody::clusterDImpulse(m_soft,rpos,impulse); 387 }387 } 388 388 void applyImpulse(const Impulse& impulse,const btVector3& rpos) const 389 {389 { 390 390 if(impulse.m_asVelocity) applyVImpulse(impulse.m_velocity,rpos); 391 391 if(impulse.m_asDrift) applyDImpulse(impulse.m_drift,rpos); 392 }392 } 393 393 void applyVAImpulse(const btVector3& impulse) const 394 {394 { 395 395 if(m_rigid) m_rigid->applyTorqueImpulse(impulse); 396 396 if(m_soft) btSoftBody::clusterVAImpulse(m_soft,impulse); 397 }397 } 398 398 void applyDAImpulse(const btVector3& impulse) const 399 {399 { 400 400 if(m_rigid) m_rigid->applyTorqueImpulse(impulse); 401 401 if(m_soft) btSoftBody::clusterDAImpulse(m_soft,impulse); 402 }402 } 403 403 void applyAImpulse(const Impulse& impulse) const 404 {404 { 405 405 if(impulse.m_asVelocity) applyVAImpulse(impulse.m_velocity); 406 406 if(impulse.m_asDrift) applyDAImpulse(impulse.m_drift); 407 }407 } 408 408 void applyDCImpulse(const btVector3& impulse) const 409 {409 { 410 410 if(m_rigid) m_rigid->applyCentralImpulse(impulse); 411 411 if(m_soft) btSoftBody::clusterDCImpulse(m_soft,impulse); 412 }412 } 413 413 }; 414 414 /* Joint */ … … 421 421 };}; 422 422 struct Specs 423 {424 Specs() : erp(1),cfm(1),split(1) {}423 { 424 Specs() : erp(1),cfm(1),split(1) {} 425 425 btScalar erp; 426 426 btScalar cfm; 427 427 btScalar split; 428 };428 }; 429 429 Body m_bodies[2]; 430 430 btVector3 m_refs[2]; … … 437 437 bool m_delete; 438 438 virtual ~Joint() {} 439 Joint() : m_delete(false) {}439 Joint() : m_delete(false) {} 440 440 virtual void Prepare(btScalar dt,int iterations); 441 441 virtual void Solve(btScalar dt,btScalar sor)=0; … … 447 447 { 448 448 struct Specs : Joint::Specs 449 {449 { 450 450 btVector3 position; 451 };451 }; 452 452 btVector3 m_rpos[2]; 453 453 void Prepare(btScalar dt,int iterations); … … 460 460 { 461 461 struct IControl 462 {462 { 463 463 virtual void Prepare(AJoint*) {} 464 464 virtual btScalar Speed(AJoint*,btScalar current) { return(current); } 465 465 static IControl* Default() { static IControl def;return(&def); } 466 };466 }; 467 467 struct Specs : Joint::Specs 468 {469 Specs() : icontrol(IControl::Default()) {}468 { 469 Specs() : icontrol(IControl::Default()) {} 470 470 btVector3 axis; 471 471 IControl* icontrol; 472 };472 }; 473 473 btVector3 m_axis[2]; 474 474 IControl* m_icontrol; … … 533 533 btScalar updmrg; // Update margin 534 534 }; 535 /// RayFromToCaster takes a ray from, ray to (instead of direction!) 536 struct RayFromToCaster : btDbvt::ICollide 537 { 538 btVector3 m_rayFrom; 539 btVector3 m_rayTo; 540 btVector3 m_rayNormalizedDirection; 541 btScalar m_mint; 542 Face* m_face; 543 int m_tests; 544 RayFromToCaster(const btVector3& rayFrom,const btVector3& rayTo,btScalar mxt); 535 /* RayCaster */ 536 struct RayCaster : btDbvt::ICollide 537 { 538 btVector3 o; 539 btVector3 d; 540 btScalar mint; 541 Face* face; 542 int tests; 543 RayCaster(const btVector3& org,const btVector3& dir,btScalar mxt); 545 544 void Process(const btDbvtNode* leaf); 546 547 static inline btScalar rayFromToTriangle(const btVector3& rayFrom, 548 const btVector3& rayTo, 549 const btVector3& rayNormalizedDirection, 550 const btVector3& a, 551 const btVector3& b, 552 const btVector3& c, 553 btScalar maxt=SIMD_INFINITY); 554 }; 545 static inline btScalar rayTriangle(const btVector3& org, 546 const btVector3& dir, 547 const btVector3& a, 548 const btVector3& b, 549 const btVector3& c, 550 btScalar maxt=SIMD_INFINITY); 551 }; 555 552 556 553 // … … 598 595 btDbvt m_cdbvt; // Clusters tree 599 596 tClusterArray m_clusters; // Clusters 600 597 601 598 // 602 599 // Api 603 600 // 604 601 605 602 /* ctor */ 606 603 btSoftBody( btSoftBodyWorldInfo* worldInfo,int node_count, 607 const btVector3* x,608 const btScalar* m);604 const btVector3* x, 605 const btScalar* m); 609 606 /* dtor */ 610 607 virtual ~btSoftBody(); … … 626 623 int node1) const; 627 624 bool checkLink( const Node* node0, 628 const Node* node1) const;625 const Node* node1) const; 629 626 /* Check for existring face */ 630 627 bool checkFace( int node0, 631 int node1,632 int node2) const;628 int node1, 629 int node2) const; 633 630 /* Append material */ 634 631 Material* appendMaterial(); 635 632 /* Append note */ 636 633 void appendNote( const char* text, 637 const btVector3& o,638 const btVector4& c=btVector4(1,0,0,0),639 Node* n0=0,640 Node* n1=0,641 Node* n2=0,642 Node* n3=0);634 const btVector3& o, 635 const btVector4& c=btVector4(1,0,0,0), 636 Node* n0=0, 637 Node* n1=0, 638 Node* n2=0, 639 Node* n3=0); 643 640 void appendNote( const char* text, 644 const btVector3& o,645 Node* feature);641 const btVector3& o, 642 Node* feature); 646 643 void appendNote( const char* text, 647 const btVector3& o,648 Link* feature);644 const btVector3& o, 645 Link* feature); 649 646 void appendNote( const char* text, 650 const btVector3& o,651 Face* feature);647 const btVector3& o, 648 Face* feature); 652 649 /* Append node */ 653 650 void appendNode( const btVector3& x,btScalar m); … … 655 652 void appendLink(int model=-1,Material* mat=0); 656 653 void appendLink( int node0, 657 int node1,658 Material* mat=0,659 bool bcheckexist=false);654 int node1, 655 Material* mat=0, 656 bool bcheckexist=false); 660 657 void appendLink( Node* node0, 661 Node* node1,662 Material* mat=0,663 bool bcheckexist=false);658 Node* node1, 659 Material* mat=0, 660 bool bcheckexist=false); 664 661 /* Append face */ 665 662 void appendFace(int model=-1,Material* mat=0); 666 663 void appendFace( int node0, 667 int node1,668 int node2,669 Material* mat=0);664 int node1, 665 int node2, 666 Material* mat=0); 670 667 /* Append anchor */ 671 668 void appendAnchor( int node, 672 btRigidBody* body);669 btRigidBody* body); 673 670 /* Append linear joint */ 674 671 void appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1); … … 683 680 /* Add force (or gravity) to a node of the body */ 684 681 void addForce( const btVector3& force, 685 int node);682 int node); 686 683 /* Add velocity to the entire body */ 687 684 void addVelocity( const btVector3& velocity); … … 692 689 /* Add velocity to a node of the body */ 693 690 void addVelocity( const btVector3& velocity, 694 int node);691 int node); 695 692 /* Set mass */ 696 693 void setMass( int node, 697 btScalar mass);694 btScalar mass); 698 695 /* Get mass */ 699 696 btScalar getMass( int node) const; … … 702 699 /* Set total mass (weighted by previous masses) */ 703 700 void setTotalMass( btScalar mass, 704 bool fromfaces=false);701 bool fromfaces=false); 705 702 /* Set total density */ 706 703 void setTotalDensity(btScalar density); … … 715 712 /* Set current state as pose */ 716 713 void setPose( bool bvolume, 717 bool bframe);714 bool bframe); 718 715 /* Return the volume */ 719 716 btScalar getVolume() const; … … 735 732 /* Generate bending constraints based on distance in the adjency graph */ 736 733 int generateBendingConstraints( int distance, 737 Material* mat=0);734 Material* mat=0); 738 735 /* Randomize constraints to reduce solver bias */ 739 736 void randomizeConstraints(); … … 748 745 bool cutLink(int node0,int node1,btScalar position); 749 746 bool cutLink(const Node* node0,const Node* node1,btScalar position); 750 751 ///Ray casting using rayFrom and rayTo in worldspace, (not direction!)752 bool rayTest(const btVector3& rayFrom,753 const btVector3& rayTo,754 sRayCast& results);747 /* Ray casting */ 748 bool rayCast(const btVector3& org, 749 const btVector3& dir, 750 sRayCast& results, 751 btScalar maxtime=SIMD_INFINITY); 755 752 /* Solver presets */ 756 753 void setSolver(eSolverPresets::_ preset); … … 770 767 void defaultCollisionHandler(btCollisionObject* pco); 771 768 void defaultCollisionHandler(btSoftBody* psb); 772 769 773 770 // 774 771 // Cast 775 772 // 776 773 777 774 static const btSoftBody* upcast(const btCollisionObject* colObj) 778 775 { … … 802 799 void pointersToIndices(); 803 800 void indicesToPointers(const int* map=0); 804 805 int rayTest(const btVector3& rayFrom,const btVector3& rayTo, 806 btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const; 801 int rayCast(const btVector3& org,const btVector3& dir, 802 btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const; 807 803 void initializeFaceTree(); 808 804 btVector3 evaluateCom() const; … … 827 823 static psolver_t getSolver(ePSolver::_ solver); 828 824 static vsolver_t getSolver(eVSolver::_ solver); 829 825 830 826 }; 831 827 -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp
r1963 r1972 51 51 52 52 btSoftBodyTriangleCallback::btSoftBodyTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped): 53 m_dispatcher(dispatcher),54 m_dispatchInfoPtr(0)53 m_dispatcher(dispatcher), 54 m_dispatchInfoPtr(0) 55 55 { 56 56 m_softBody = (btSoftBody*) (isSwapped? body1:body0); 57 57 m_triBody = isSwapped? body0:body1; 58 59 // 60 // create the manifold from the dispatcher 'manifold pool' 61 // 62 // m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBody,m_triBody); 63 58 59 // 60 // create the manifold from the dispatcher 'manifold pool' 61 // 62 // m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBody,m_triBody); 63 64 clearCache(); 65 } 66 67 btSoftBodyTriangleCallback::~btSoftBodyTriangleCallback() 68 { 64 69 clearCache(); 65 } 66 67 btSoftBodyTriangleCallback::~btSoftBodyTriangleCallback() 68 { 69 clearCache(); 70 // m_dispatcher->releaseManifold( m_manifoldPtr ); 71 72 } 73 70 // m_dispatcher->releaseManifold( m_manifoldPtr ); 71 72 } 73 74 74 75 75 void btSoftBodyTriangleCallback::clearCache() … … 89 89 void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex) 90 90 { 91 //just for debugging purposes91 //just for debugging purposes 92 92 //printf("triangle %d",m_triangleCount++); 93 93 btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody); … … 95 95 ci.m_dispatcher1 = m_dispatcher; 96 96 97 ///debug drawing of the overlapping triangles97 ///debug drawing of the overlapping triangles 98 98 if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && m_dispatchInfoPtr->m_debugDraw->getDebugMode() > 0) 99 99 { … … 108 108 btHashKey<btTriIndex> triKey(triIndex.getUid()); 109 109 110 110 111 111 btTriIndex* shapeIndex = m_shapeCache[triKey]; 112 112 if (shapeIndex) … … 117 117 //copy over user pointers to temporary shape 118 118 tm->setUserPointer(ob->getRootCollisionShape()->getUserPointer()); 119 119 120 120 btCollisionShape* tmpShape = ob->getCollisionShape(); 121 121 ob->internalSetTemporaryCollisionShape( tm ); 122 122 123 123 124 124 btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_softBody,m_triBody,0);//m_manifoldPtr); 125 125 126 126 colAlgo->processCollision(m_softBody,m_triBody,*m_dispatchInfoPtr,m_resultOut); 127 127 colAlgo->~btCollisionAlgorithm(); … … 134 134 135 135 //btCollisionObject* colObj = static_cast<btCollisionObject*>(m_convexProxy->m_clientObject); 136 137 138 { 139 136 137 // if (m_softBody->getCollisionShape()->getShapeType()== 138 { 139 // btVector3 other; 140 140 btVector3 normal = (triangle[1]-triangle[0]).cross(triangle[2]-triangle[0]); 141 141 normal.normalize(); 142 142 normal*= BT_SOFTBODY_TRIANGLE_EXTRUSION; 143 144 143 // other=(triangle[0]+triangle[1]+triangle[2])*0.333333f; 144 // other+=normal*22.f; 145 145 btVector3 pts[6] = {triangle[0]+normal, 146 146 triangle[1]+normal, 147 148 149 150 147 triangle[2]+normal, 148 triangle[0]-normal, 149 triangle[1]-normal, 150 triangle[2]-normal}; 151 151 152 152 btConvexHullShape* tm = new btConvexHullShape(&pts[0].getX(),6); 153 153 154 154 155 156 155 // btBU_Simplex1to4 tm(triangle[0],triangle[1],triangle[2],other); 156 157 157 //btTriangleShape tm(triangle[0],triangle[1],triangle[2]); 158 159 158 // tm.setMargin(m_collisionMarginTriangle); 159 160 160 //copy over user pointers to temporary shape 161 161 tm->setUserPointer(ob->getRootCollisionShape()->getUserPointer()); 162 162 163 163 btCollisionShape* tmpShape = ob->getCollisionShape(); 164 164 ob->internalSetTemporaryCollisionShape( tm ); 165 165 166 166 167 167 btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_softBody,m_triBody,0);//m_manifoldPtr); … … 170 170 171 171 //m_resultOut->setShapeIdentifiers(-1,-1,partId,triangleIndex); 172 173 172 // cvxcvxalgo.setShapeIdentifiers(-1,-1,partId,triangleIndex); 173 // cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut); 174 174 colAlgo->processCollision(m_softBody,m_triBody,*m_dispatchInfoPtr,m_resultOut); 175 175 colAlgo->~btCollisionAlgorithm(); 176 176 ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo); 177 178 177 178 179 179 ob->internalSetTemporaryCollisionShape( tmpShape ); 180 180 triIndex.m_childShape = tm; … … 183 183 } 184 184 185 185 186 186 187 187 } … … 195 195 m_resultOut = resultOut; 196 196 197 197 198 198 btVector3 aabbWorldSpaceMin,aabbWorldSpaceMax; 199 199 m_softBody->getAabb(aabbWorldSpaceMin,aabbWorldSpaceMax); … … 218 218 void btSoftBodyConcaveCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) 219 219 { 220 221 220 221 222 222 btCollisionObject* convexBody = m_isSwapped ? body1 : body0; 223 223 btCollisionObject* triBody = m_isSwapped ? body0 : body1; … … 229 229 btCollisionObject* triOb = triBody; 230 230 btConcaveShape* concaveShape = static_cast<btConcaveShape*>( triOb->getCollisionShape()); 231 232 231 232 // if (convexBody->getCollisionShape()->isConvex()) 233 233 { 234 234 btScalar collisionMarginTriangle = concaveShape->getMargin(); 235 236 235 236 // resultOut->setPersistentManifold(m_btSoftBodyTriangleCallback.m_manifoldPtr); 237 237 m_btSoftBodyTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,resultOut); 238 238 … … 240 240 //m_dispatcher->clearManifold(m_btSoftBodyTriangleCallback.m_manifoldPtr); 241 241 242 242 // m_btSoftBodyTriangleCallback.m_manifoldPtr->setBodies(convexBody,triBody); 243 243 244 244 245 245 concaveShape->processAllTriangles( &m_btSoftBodyTriangleCallback,m_btSoftBodyTriangleCallback.getAabbMin(),m_btSoftBodyTriangleCallback.getAabbMax()); 246 247 248 249 } 250 246 247 // resultOut->refreshContactPoints(); 248 249 } 250 251 251 } 252 252 … … 288 288 btScalar m_ccdSphereRadius; 289 289 btScalar m_hitFraction; 290 290 291 291 292 292 LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,btScalar ccdSphereRadius,btScalar hitFraction) … … 297 297 { 298 298 } 299 300 299 300 301 301 virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) 302 302 { … … 328 328 329 329 330 331 332 330 331 332 333 333 if (triBody->getCollisionShape()->isConcave()) 334 334 { … … 350 350 351 351 btConcaveShape* triangleMesh = (btConcaveShape*) concavebody->getCollisionShape(); 352 352 353 353 if (triangleMesh) 354 354 { 355 355 triangleMesh->processAllTriangles(&raycastCallback,rayAabbMin,rayAabbMax); 356 356 } 357 357 358 358 359 359 -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h
r1963 r1972 36 36 int m_PartIdTriangleIndex; 37 37 class btCollisionShape* m_childShape; 38 38 39 39 btTriIndex(int partId,int triangleIndex,btCollisionShape* shape) 40 40 { … … 76 76 77 77 btHashMap<btHashKey<btTriIndex>,btTriIndex> m_shapeCache; 78 78 79 79 public: 80 81 82 80 int m_triangleCount; 81 82 // btPersistentManifold* m_manifoldPtr; 83 83 84 84 btSoftBodyTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped); … … 89 89 90 90 virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); 91 91 92 92 void clearCache(); 93 93 -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBodyHelpers.cpp
r1963 r1972 23 23 // 24 24 static void drawVertex( btIDebugDraw* idraw, 25 26 {27 idraw->drawLine(x-btVector3(s,0,0),x+btVector3(s,0,0),c);28 idraw->drawLine(x-btVector3(0,s,0),x+btVector3(0,s,0),c);29 idraw->drawLine(x-btVector3(0,0,s),x+btVector3(0,0,s),c);30 }25 const btVector3& x,btScalar s,const btVector3& c) 26 { 27 idraw->drawLine(x-btVector3(s,0,0),x+btVector3(s,0,0),c); 28 idraw->drawLine(x-btVector3(0,s,0),x+btVector3(0,s,0),c); 29 idraw->drawLine(x-btVector3(0,0,s),x+btVector3(0,0,s),c); 30 } 31 31 32 32 // 33 33 static void drawBox( btIDebugDraw* idraw, 34 const btVector3& mins,35 const btVector3& maxs,36 const btVector3& color)37 { 38 39 btVector3(maxs.x(),mins.y(),mins.z()),40 btVector3(maxs.x(),maxs.y(),mins.z()),41 btVector3(mins.x(),maxs.y(),mins.z()),42 btVector3(mins.x(),mins.y(),maxs.z()),43 btVector3(maxs.x(),mins.y(),maxs.z()),44 btVector3(maxs.x(),maxs.y(),maxs.z()),45 btVector3(mins.x(),maxs.y(),maxs.z())};46 47 48 49 50 51 34 const btVector3& mins, 35 const btVector3& maxs, 36 const btVector3& color) 37 { 38 const btVector3 c[]={ btVector3(mins.x(),mins.y(),mins.z()), 39 btVector3(maxs.x(),mins.y(),mins.z()), 40 btVector3(maxs.x(),maxs.y(),mins.z()), 41 btVector3(mins.x(),maxs.y(),mins.z()), 42 btVector3(mins.x(),mins.y(),maxs.z()), 43 btVector3(maxs.x(),mins.y(),maxs.z()), 44 btVector3(maxs.x(),maxs.y(),maxs.z()), 45 btVector3(mins.x(),maxs.y(),maxs.z())}; 46 idraw->drawLine(c[0],c[1],color);idraw->drawLine(c[1],c[2],color); 47 idraw->drawLine(c[2],c[3],color);idraw->drawLine(c[3],c[0],color); 48 idraw->drawLine(c[4],c[5],color);idraw->drawLine(c[5],c[6],color); 49 idraw->drawLine(c[6],c[7],color);idraw->drawLine(c[7],c[4],color); 50 idraw->drawLine(c[0],c[4],color);idraw->drawLine(c[1],c[5],color); 51 idraw->drawLine(c[2],c[6],color);idraw->drawLine(c[3],c[7],color); 52 52 } 53 53 54 54 // 55 55 static void drawTree( btIDebugDraw* idraw, 56 57 58 59 60 61 62 { 63 64 { 65 66 { 67 68 69 } 70 71 { 72 73 74 75 56 const btDbvtNode* node, 57 int depth, 58 const btVector3& ncolor, 59 const btVector3& lcolor, 60 int mindepth, 61 int maxdepth) 62 { 63 if(node) 64 { 65 if(node->isinternal()&&((depth<maxdepth)||(maxdepth<0))) 66 { 67 drawTree(idraw,node->childs[0],depth+1,ncolor,lcolor,mindepth,maxdepth); 68 drawTree(idraw,node->childs[1],depth+1,ncolor,lcolor,mindepth,maxdepth); 69 } 70 if(depth>=mindepth) 71 { 72 const btScalar scl=(btScalar)(node->isinternal()?1:1); 73 const btVector3 mi=node->volume.Center()-node->volume.Extents()*scl; 74 const btVector3 mx=node->volume.Center()+node->volume.Extents()*scl; 75 drawBox(idraw,mi,mx,node->isleaf()?lcolor:ncolor); 76 76 } 77 77 } … … 82 82 static inline T sum(const btAlignedObjectArray<T>& items) 83 83 { 84 85 86 { 87 88 89 { 90 91 } 92 } 93 84 T v; 85 if(items.size()) 86 { 87 v=items[0]; 88 for(int i=1,ni=items.size();i<ni;++i) 89 { 90 v+=items[i]; 91 } 92 } 93 return(v); 94 94 } 95 95 … … 98 98 static inline void add(btAlignedObjectArray<T>& items,const Q& value) 99 99 { 100 101 { 102 100 for(int i=0,ni=items.size();i<ni;++i) 101 { 102 items[i]+=value; 103 103 } 104 104 } … … 108 108 static inline void mul(btAlignedObjectArray<T>& items,const Q& value) 109 109 { 110 111 { 112 110 for(int i=0,ni=items.size();i<ni;++i) 111 { 112 items[i]*=value; 113 113 } 114 114 } … … 118 118 static inline T average(const btAlignedObjectArray<T>& items) 119 119 { 120 121 120 const btScalar n=(btScalar)(items.size()>0?items.size():1); 121 return(sum(items)/n); 122 122 } 123 123 … … 137 137 #if 0 138 138 static btVector3 stresscolor(btScalar stress) 139 {139 { 140 140 static const btVector3 spectrum[]= { btVector3(1,0,1), 141 btVector3(0,0,1),142 btVector3(0,1,1),143 btVector3(0,1,0),144 btVector3(1,1,0),145 btVector3(1,0,0),146 btVector3(1,0,0)};141 btVector3(0,0,1), 142 btVector3(0,1,1), 143 btVector3(0,1,0), 144 btVector3(1,1,0), 145 btVector3(1,0,0), 146 btVector3(1,0,0)}; 147 147 static const int ncolors=sizeof(spectrum)/sizeof(spectrum[0])-1; 148 148 static const btScalar one=1; … … 151 151 const btScalar frc=stress-sel; 152 152 return(spectrum[sel]+(spectrum[sel+1]-spectrum[sel])*frc); 153 }153 } 154 154 #endif 155 155 156 156 // 157 157 void btSoftBodyHelpers::Draw( btSoftBody* psb, 158 159 158 btIDebugDraw* idraw, 159 int drawflags) 160 160 { 161 161 const btScalar scl=(btScalar)0.1; … … 252 252 const btVector3 c=(x[0]+x[1]+x[2])/3; 253 253 idraw->drawTriangle((x[0]-c)*scl+c, 254 (x[1]-c)*scl+c,255 (x[2]-c)*scl+c,256 col,alp);254 (x[1]-c)*scl+c, 255 (x[2]-c)*scl+c, 256 col,alp); 257 257 } 258 258 } 259 259 /* Clusters */ 260 260 if(0!=(drawflags&fDrawFlags::Clusters)) 261 {261 { 262 262 srand(1806); 263 263 for(i=0;i<psb->m_clusters.size();++i) 264 {264 { 265 265 if(psb->m_clusters[i]->m_collide) 266 {266 { 267 267 btVector3 color( rand()/(btScalar)RAND_MAX, 268 rand()/(btScalar)RAND_MAX,269 rand()/(btScalar)RAND_MAX);268 rand()/(btScalar)RAND_MAX, 269 rand()/(btScalar)RAND_MAX); 270 270 color=color.normalized()*0.75; 271 271 btAlignedObjectArray<btVector3> vertices; 272 272 vertices.resize(psb->m_clusters[i]->m_nodes.size()); 273 273 for(j=0,nj=vertices.size();j<nj;++j) 274 {274 { 275 275 vertices[j]=psb->m_clusters[i]->m_nodes[j]->m_x; 276 }276 } 277 277 HullDesc hdsc(QF_TRIANGLES,vertices.size(),&vertices[0]); 278 278 HullResult hres; … … 285 285 add(hres.m_OutputVertices,center); 286 286 for(j=0;j<(int)hres.mNumFaces;++j) 287 {287 { 288 288 const int idx[]={hres.m_Indices[j*3+0],hres.m_Indices[j*3+1],hres.m_Indices[j*3+2]}; 289 289 idraw->drawTriangle(hres.m_OutputVertices[idx[0]], 290 hres.m_OutputVertices[idx[1]], 291 hres.m_OutputVertices[idx[2]], 292 color,1); 290 hres.m_OutputVertices[idx[1]], 291 hres.m_OutputVertices[idx[2]], 292 color,1); 293 } 294 hlib.ReleaseResult(hres); 293 295 } 294 hlib.ReleaseResult(hres);295 }296 296 /* Velocities */ 297 #if 0297 #if 0 298 298 for(int j=0;j<psb->m_clusters[i].m_nodes.size();++j) 299 {299 { 300 300 const btSoftBody::Cluster& c=psb->m_clusters[i]; 301 301 const btVector3 r=c.m_nodes[j]->m_x-c.m_com; 302 302 const btVector3 v=c.m_lv+cross(c.m_av,r); 303 303 idraw->drawLine(c.m_nodes[j]->m_x,c.m_nodes[j]->m_x+v,btVector3(1,0,0)); 304 }305 #endif304 } 305 #endif 306 306 /* Frame */ 307 307 btSoftBody::Cluster& c=*psb->m_clusters[i]; … … 309 309 idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,10,0),btVector3(0,1,0)); 310 310 idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,0,10),btVector3(0,0,1)); 311 }312 }311 } 312 } 313 313 /* Notes */ 314 314 if(0!=(drawflags&fDrawFlags::Notes)) … … 319 319 btVector3 p=n.m_offset; 320 320 for(int j=0;j<n.m_rank;++j) 321 {321 { 322 322 p+=n.m_nodes[j]->m_x*n.m_coords[j]; 323 }323 } 324 324 idraw->draw3dText(p,n.m_text); 325 325 } … … 334 334 if(0!=(drawflags&fDrawFlags::Joints)) 335 335 { 336 337 { 338 339 336 for(i=0;i<psb->m_joints.size();++i) 337 { 338 const btSoftBody::Joint* pj=psb->m_joints[i]; 339 switch(pj->Type()) 340 340 { 341 341 case btSoftBody::Joint::eType::Linear: 342 342 { 343 344 345 346 347 348 349 343 const btSoftBody::LJoint* pjl=(const btSoftBody::LJoint*)pj; 344 const btVector3 a0=pj->m_bodies[0].xform()*pjl->m_refs[0]; 345 const btVector3 a1=pj->m_bodies[1].xform()*pjl->m_refs[1]; 346 idraw->drawLine(pj->m_bodies[0].xform().getOrigin(),a0,btVector3(1,1,0)); 347 idraw->drawLine(pj->m_bodies[1].xform().getOrigin(),a1,btVector3(0,1,1)); 348 drawVertex(idraw,a0,0.25,btVector3(1,1,0)); 349 drawVertex(idraw,a1,0.25,btVector3(0,1,1)); 350 350 } 351 351 break; 352 352 case btSoftBody::Joint::eType::Angular: 353 353 { 354 355 356 357 358 359 360 361 362 354 const btSoftBody::AJoint* pja=(const btSoftBody::AJoint*)pj; 355 const btVector3 o0=pj->m_bodies[0].xform().getOrigin(); 356 const btVector3 o1=pj->m_bodies[1].xform().getOrigin(); 357 const btVector3 a0=pj->m_bodies[0].xform().getBasis()*pj->m_refs[0]; 358 const btVector3 a1=pj->m_bodies[1].xform().getBasis()*pj->m_refs[1]; 359 idraw->drawLine(o0,o0+a0*10,btVector3(1,1,0)); 360 idraw->drawLine(o0,o0+a1*10,btVector3(1,1,0)); 361 idraw->drawLine(o1,o1+a0*10,btVector3(0,1,1)); 362 idraw->drawLine(o1,o1+a1*10,btVector3(0,1,1)); 363 363 } 364 364 } … … 369 369 // 370 370 void btSoftBodyHelpers::DrawInfos( btSoftBody* psb, 371 372 373 374 371 btIDebugDraw* idraw, 372 bool masses, 373 bool areas, 374 bool /*stress*/) 375 375 { 376 376 for(int i=0;i<psb->m_nodes.size();++i) … … 395 395 // 396 396 void btSoftBodyHelpers::DrawNodeTree( btSoftBody* psb, 397 btIDebugDraw* idraw,398 int mindepth,399 int maxdepth)400 { 401 397 btIDebugDraw* idraw, 398 int mindepth, 399 int maxdepth) 400 { 401 drawTree(idraw,psb->m_ndbvt.m_root,0,btVector3(1,0,1),btVector3(1,1,1),mindepth,maxdepth); 402 402 } 403 403 404 404 // 405 405 void btSoftBodyHelpers::DrawFaceTree( btSoftBody* psb, 406 btIDebugDraw* idraw,407 int mindepth,408 int maxdepth)409 { 410 406 btIDebugDraw* idraw, 407 int mindepth, 408 int maxdepth) 409 { 410 drawTree(idraw,psb->m_fdbvt.m_root,0,btVector3(0,1,0),btVector3(1,0,0),mindepth,maxdepth); 411 411 } 412 412 413 413 // 414 414 void btSoftBodyHelpers::DrawClusterTree( btSoftBody* psb, 415 416 417 418 { 419 415 btIDebugDraw* idraw, 416 int mindepth, 417 int maxdepth) 418 { 419 drawTree(idraw,psb->m_cdbvt.m_root,0,btVector3(0,1,1),btVector3(1,0,0),mindepth,maxdepth); 420 420 } 421 421 422 422 // 423 423 void btSoftBodyHelpers::DrawFrame( btSoftBody* psb, 424 424 btIDebugDraw* idraw) 425 425 { 426 426 if(psb->m_pose.m_bframe) … … 446 446 // 447 447 btSoftBody* btSoftBodyHelpers::CreateRope( btSoftBodyWorldInfo& worldInfo, const btVector3& from, 448 449 450 448 const btVector3& to, 449 int res, 450 int fixeds) 451 451 { 452 452 /* Create nodes */ … … 478 478 // 479 479 btSoftBody* btSoftBodyHelpers::CreatePatch(btSoftBodyWorldInfo& worldInfo,const btVector3& corner00, 480 481 482 483 484 485 486 480 const btVector3& corner10, 481 const btVector3& corner01, 482 const btVector3& corner11, 483 int resx, 484 int resy, 485 int fixeds, 486 bool gendiags) 487 487 { 488 488 #define IDX(_x_,_y_) ((_y_)*rx+(_x_)) … … 554 554 555 555 // 556 btSoftBody* btSoftBodyHelpers::CreatePatchUV(btSoftBodyWorldInfo& worldInfo,557 const btVector3& corner00,558 const btVector3& corner10,559 const btVector3& corner01,560 const btVector3& corner11,561 int resx,562 int resy,563 int fixeds,564 bool gendiags,565 float* tex_coords)566 {567 568 /*569 *570 * corners:571 *572 * [0][0] corner00 ------- corner01 [resx][0]573 * | |574 * | |575 * [0][resy] corner10 -------- corner11 [resx][resy]576 *577 *578 *579 *580 *581 *582 * "fixedgs" map:583 *584 * corner00 --> +1585 * corner01 --> +2586 * corner10 --> +4587 * corner11 --> +8588 * upper middle --> +16589 * left middle --> +32590 * right middle --> +64591 * lower middle --> +128592 * center --> +256593 *594 *595 * tex_coords size (resx-1)*(resy-1)*12596 *597 *598 *599 * SINGLE QUAD INTERNALS600 *601 * 1) btSoftBody's nodes and links,602 * diagonal link is optional ("gendiags")603 *604 *605 * node00 ------ node01606 * | .607 * | .608 * | .609 * | .610 * | .611 * node10 node11612 *613 *614 *615 * 2) Faces:616 * two triangles,617 * UV Coordinates (hier example for single quad)618 *619 * (0,1) (0,1) (1,1)620 * 1 |\ 3 \-----| 2621 * | \ \ |622 * | \ \ |623 * | \ \ |624 * | \ \ |625 * 2 |-----\ 3 \| 1626 * (0,0) (1,0) (1,0)627 *628 *629 *630 *631 *632 *633 */634 635 #define IDX(_x_,_y_) ((_y_)*rx+(_x_))636 /* Create nodes */637 if((resx<2)||(resy<2)) return(0);638 const int rx=resx;639 const int ry=resy;640 const int tot=rx*ry;641 btVector3* x=new btVector3[tot];642 btScalar* m=new btScalar[tot];643 644 for(int iy=0;iy<ry;++iy)645 {646 const btScalar ty=iy/(btScalar)(ry-1);647 const btVector3 py0=lerp(corner00,corner01,ty);648 const btVector3 py1=lerp(corner10,corner11,ty);649 for(int ix=0;ix<rx;++ix)650 {651 const btScalar tx=ix/(btScalar)(rx-1);652 x[IDX(ix,iy)]=lerp(py0,py1,tx);653 m[IDX(ix,iy)]=1;654 }655 }656 btSoftBody* psb=new btSoftBody(&worldInfo,tot,x,m);657 if(fixeds&1) psb->setMass(IDX(0,0),0);658 if(fixeds&2) psb->setMass(IDX(rx-1,0),0);659 if(fixeds&4) psb->setMass(IDX(0,ry-1),0);660 if(fixeds&8) psb->setMass(IDX(rx-1,ry-1),0);661 if(fixeds&16) psb->setMass(IDX((rx-1)/2,0),0);662 if(fixeds&32) psb->setMass(IDX(0,(ry-1)/2),0);663 if(fixeds&64) psb->setMass(IDX(rx-1,(ry-1)/2),0);664 if(fixeds&128) psb->setMass(IDX((rx-1)/2,ry-1),0);665 if(fixeds&256) psb->setMass(IDX((rx-1)/2,(ry-1)/2),0);666 delete[] x;667 delete[] m;668 669 670 int z = 0;671 /* Create links and faces */672 for(int iy=0;iy<ry;++iy)673 {674 for(int ix=0;ix<rx;++ix)675 {676 const bool mdx=(ix+1)<rx;677 const bool mdy=(iy+1)<ry;678 679 int node00=IDX(ix,iy);680 int node01=IDX(ix+1,iy);681 int node10=IDX(ix,iy+1);682 int node11=IDX(ix+1,iy+1);683 684 if(mdx) psb->appendLink(node00,node01);685 if(mdy) psb->appendLink(node00,node10);686 if(mdx&&mdy)687 {688 psb->appendFace(node00,node10,node11);689 if (tex_coords) {690 tex_coords[z+0]=CalculateUV(resx,resy,ix,iy,0);691 tex_coords[z+1]=CalculateUV(resx,resy,ix,iy,1);692 tex_coords[z+2]=CalculateUV(resx,resy,ix,iy,0);693 tex_coords[z+3]=CalculateUV(resx,resy,ix,iy,2);694 tex_coords[z+4]=CalculateUV(resx,resy,ix,iy,3);695 tex_coords[z+5]=CalculateUV(resx,resy,ix,iy,2);696 }697 psb->appendFace(node11,node01,node00);698 if (tex_coords) {699 tex_coords[z+6 ]=CalculateUV(resx,resy,ix,iy,3);700 tex_coords[z+7 ]=CalculateUV(resx,resy,ix,iy,2);701 tex_coords[z+8 ]=CalculateUV(resx,resy,ix,iy,3);702 tex_coords[z+9 ]=CalculateUV(resx,resy,ix,iy,1);703 tex_coords[z+10]=CalculateUV(resx,resy,ix,iy,0);704 tex_coords[z+11]=CalculateUV(resx,resy,ix,iy,1);705 }706 if (gendiags) psb->appendLink(node00,node11);707 z += 12;708 }709 }710 }711 /* Finished */712 #undef IDX713 return(psb);714 }715 716 float btSoftBodyHelpers::CalculateUV(int resx,int resy,int ix,int iy,int id)717 {718 719 /*720 *721 *722 * node00 --- node01723 * | |724 * node10 --- node11725 *726 *727 * ID map:728 *729 * node00 s --> 0730 * node00 t --> 1731 *732 * node01 s --> 3733 * node01 t --> 1734 *735 * node10 s --> 0736 * node10 t --> 2737 *738 * node11 s --> 3739 * node11 t --> 2740 *741 *742 */743 744 float tc=0.0f;745 if (id == 0) {746 tc = (1.0f/((resx-1))*ix);747 }748 else if (id==1) {749 tc = (1.0f/((resy-1))*(resy-1-iy));750 }751 else if (id==2) {752 tc = (1.0f/((resy-1))*(resy-1-iy-1));753 }754 else if (id==3) {755 tc = (1.0f/((resx-1))*(ix+1));756 }757 return tc;758 }759 //760 556 btSoftBody* btSoftBodyHelpers::CreateEllipsoid(btSoftBodyWorldInfo& worldInfo,const btVector3& center, 761 762 557 const btVector3& radius, 558 int res) 763 559 { 764 560 struct Hammersley … … 791 587 // 792 588 btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBodyWorldInfo& worldInfo,const btScalar* vertices, 793 794 589 const int* triangles, 590 int ntriangles) 795 591 { 796 592 int maxidx=0; … … 833 629 // 834 630 btSoftBody* btSoftBodyHelpers::CreateFromConvexHull(btSoftBodyWorldInfo& worldInfo, const btVector3* vertices, 835 631 int nvertices) 836 632 { 837 633 HullDesc hdsc(QF_TRIANGLES,nvertices,vertices); -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBodyHelpers.h
r1963 r1972 47 47 /* Draw body */ 48 48 static void Draw( btSoftBody* psb, 49 btIDebugDraw* idraw,50 int drawflags=fDrawFlags::Std);49 btIDebugDraw* idraw, 50 int drawflags=fDrawFlags::Std); 51 51 /* Draw body infos */ 52 52 static void DrawInfos( btSoftBody* psb, 53 btIDebugDraw* idraw,54 bool masses,55 bool areas,56 bool stress);53 btIDebugDraw* idraw, 54 bool masses, 55 bool areas, 56 bool stress); 57 57 /* Draw node tree */ 58 58 static void DrawNodeTree( btSoftBody* psb, 59 btIDebugDraw* idraw,60 int mindepth=0,61 int maxdepth=-1);59 btIDebugDraw* idraw, 60 int mindepth=0, 61 int maxdepth=-1); 62 62 /* Draw face tree */ 63 63 static void DrawFaceTree( btSoftBody* psb, 64 btIDebugDraw* idraw,65 int mindepth=0,66 int maxdepth=-1);64 btIDebugDraw* idraw, 65 int mindepth=0, 66 int maxdepth=-1); 67 67 /* Draw cluster tree */ 68 68 static void DrawClusterTree(btSoftBody* psb, 69 btIDebugDraw* idraw,70 int mindepth=0,71 int maxdepth=-1);69 btIDebugDraw* idraw, 70 int mindepth=0, 71 int maxdepth=-1); 72 72 /* Draw rigid frame */ 73 73 static void DrawFrame( btSoftBody* psb, 74 btIDebugDraw* idraw);74 btIDebugDraw* idraw); 75 75 /* Create a rope */ 76 76 static btSoftBody* CreateRope( btSoftBodyWorldInfo& worldInfo, 77 const btVector3& from,78 const btVector3& to,79 int res,80 int fixeds);77 const btVector3& from, 78 const btVector3& to, 79 int res, 80 int fixeds); 81 81 /* Create a patch */ 82 82 static btSoftBody* CreatePatch(btSoftBodyWorldInfo& worldInfo, 83 const btVector3& corner00, 84 const btVector3& corner10, 85 const btVector3& corner01, 86 const btVector3& corner11, 87 int resx, 88 int resy, 89 int fixeds, 90 bool gendiags); 91 /* Create a patch with UV Texture Coordinates */ 92 static btSoftBody* CreatePatchUV(btSoftBodyWorldInfo& worldInfo, 93 const btVector3& corner00, 94 const btVector3& corner10, 95 const btVector3& corner01, 96 const btVector3& corner11, 97 int resx, 98 int resy, 99 int fixeds, 100 bool gendiags, 101 float* tex_coords=0); 102 static float CalculateUV(int resx,int resy,int ix,int iy,int id); 83 const btVector3& corner00, 84 const btVector3& corner10, 85 const btVector3& corner01, 86 const btVector3& corner11, 87 int resx, 88 int resy, 89 int fixeds, 90 bool gendiags); 103 91 /* Create an ellipsoid */ 104 92 static btSoftBody* CreateEllipsoid(btSoftBodyWorldInfo& worldInfo, 105 const btVector3& center,106 const btVector3& radius,107 int res);93 const btVector3& center, 94 const btVector3& radius, 95 int res); 108 96 /* Create from trimesh */ 109 97 static btSoftBody* CreateFromTriMesh( btSoftBodyWorldInfo& worldInfo, 110 const btScalar* vertices,111 const int* triangles,112 int ntriangles);98 const btScalar* vertices, 99 const int* triangles, 100 int ntriangles); 113 101 /* Create from convex-hull */ 114 102 static btSoftBody* CreateFromConvexHull( btSoftBodyWorldInfo& worldInfo, 115 const btVector3* vertices,116 int nvertices);103 const btVector3* vertices, 104 int nvertices); 117 105 }; 118 106 -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBodyInternals.h
r1963 r1972 32 32 struct btSymMatrix 33 33 { 34 btSymMatrix() : dim(0) {}35 btSymMatrix(int n,const T& init=T()) { resize(n,init); }36 37 38 39 40 41 34 btSymMatrix() : dim(0) {} 35 btSymMatrix(int n,const T& init=T()) { resize(n,init); } 36 void resize(int n,const T& init=T()) { dim=n;store.resize((n*(n+1))/2,init); } 37 int index(int c,int r) const { if(c>r) btSwap(c,r);btAssert(r<dim);return((r*(r+1))/2+c); } 38 T& operator()(int c,int r) { return(store[index(c,r)]); } 39 const T& operator()(int c,int r) const { return(store[index(c,r)]); } 40 btAlignedObjectArray<T> store; 41 int dim; 42 42 }; 43 43 … … 49 49 public: 50 50 btSoftBody* m_body; 51 51 52 52 btSoftBodyCollisionShape(btSoftBody* backptr) 53 53 { … … 70 70 virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const 71 71 { 72 73 74 75 76 t*btVector3(maxs.x(),mins.y(),mins.z()),77 t*btVector3(maxs.x(),maxs.y(),mins.z()),78 t*btVector3(mins.x(),maxs.y(),mins.z()),79 t*btVector3(mins.x(),mins.y(),maxs.z()),80 t*btVector3(maxs.x(),mins.y(),maxs.z()),81 t*btVector3(maxs.x(),maxs.y(),maxs.z()),82 t*btVector3(mins.x(),maxs.y(),maxs.z())};83 84 85 { 86 87 88 } 89 } 90 91 72 /* t should be identity, but better be safe than...fast? */ 73 const btVector3 mins=m_body->m_bounds[0]; 74 const btVector3 maxs=m_body->m_bounds[1]; 75 const btVector3 crns[]={t*btVector3(mins.x(),mins.y(),mins.z()), 76 t*btVector3(maxs.x(),mins.y(),mins.z()), 77 t*btVector3(maxs.x(),maxs.y(),mins.z()), 78 t*btVector3(mins.x(),maxs.y(),mins.z()), 79 t*btVector3(mins.x(),mins.y(),maxs.z()), 80 t*btVector3(maxs.x(),mins.y(),maxs.z()), 81 t*btVector3(maxs.x(),maxs.y(),maxs.z()), 82 t*btVector3(mins.x(),maxs.y(),maxs.z())}; 83 aabbMin=aabbMax=crns[0]; 84 for(int i=1;i<8;++i) 85 { 86 aabbMin.setMin(crns[i]); 87 aabbMax.setMax(crns[i]); 88 } 89 } 90 91 92 92 virtual void setLocalScaling(const btVector3& /*scaling*/) 93 93 { … … 96 96 virtual const btVector3& getLocalScaling() const 97 97 { 98 99 98 static const btVector3 dummy(1,1,1); 99 return dummy; 100 100 } 101 101 virtual void calculateLocalInertia(btScalar /*mass*/,btVector3& /*inertia*/) const … … 120 120 121 121 btSoftClusterCollisionShape (const btSoftBody::Cluster* cluster) : m_cluster(cluster) { setMargin(0); } 122 123 122 123 124 124 virtual btVector3 localGetSupportingVertex(const btVector3& vec) const 125 {125 { 126 126 btSoftBody::Node* const * n=&m_cluster->m_nodes[0]; 127 127 btScalar d=dot(vec,n[0]->m_x); 128 128 int j=0; 129 129 for(int i=1,ni=m_cluster->m_nodes.size();i<ni;++i) 130 {130 { 131 131 const btScalar k=dot(vec,n[i]->m_x); 132 132 if(k>d) { d=k;j=i; } 133 }133 } 134 134 return(n[j]->m_x); 135 }135 } 136 136 virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const 137 {137 { 138 138 return(localGetSupportingVertex(vec)); 139 }139 } 140 140 //notice that the vectors should be unit length 141 141 virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const … … 150 150 151 151 virtual int getShapeType() const { return SOFTBODY_SHAPE_PROXYTYPE; } 152 152 153 153 //debugging 154 154 virtual const char* getName()const {return "SOFTCLUSTER";} … … 172 172 static inline void ZeroInitialize(T& value) 173 173 { 174 175 174 static const T zerodummy; 175 value=zerodummy; 176 176 } 177 177 // … … 193 193 // 194 194 static inline btMatrix3x3 Lerp( const btMatrix3x3& a, 195 196 197 { 198 199 200 201 202 195 const btMatrix3x3& b, 196 btScalar t) 197 { 198 btMatrix3x3 r; 199 r[0]=Lerp(a[0],b[0],t); 200 r[1]=Lerp(a[1],b[1],t); 201 r[2]=Lerp(a[2],b[2],t); 202 return(r); 203 203 } 204 204 // 205 205 static inline btVector3 Clamp(const btVector3& v,btScalar maxlength) 206 206 { 207 208 209 207 const btScalar sql=v.length2(); 208 if(sql>(maxlength*maxlength)) 209 return((v*maxlength)/btSqrt(sql)); 210 210 else 211 211 return(v); 212 212 } 213 213 // … … 234 234 static inline btScalar ClusterMetric(const btVector3& x,const btVector3& y) 235 235 { 236 237 236 const btVector3 d=x-y; 237 return(btFabs(d[0])+btFabs(d[1])+btFabs(d[2])); 238 238 } 239 239 // … … 272 272 // 273 273 static inline btMatrix3x3 Add(const btMatrix3x3& a, 274 274 const btMatrix3x3& b) 275 275 { 276 276 btMatrix3x3 r; … … 280 280 // 281 281 static inline btMatrix3x3 Sub(const btMatrix3x3& a, 282 282 const btMatrix3x3& b) 283 283 { 284 284 btMatrix3x3 r; … … 288 288 // 289 289 static inline btMatrix3x3 Mul(const btMatrix3x3& a, 290 290 btScalar b) 291 291 { 292 292 btMatrix3x3 r; … … 297 297 static inline void Orthogonalize(btMatrix3x3& m) 298 298 { 299 300 301 299 m[2]=cross(m[0],m[1]).normalized(); 300 m[1]=cross(m[2],m[0]).normalized(); 301 m[0]=cross(m[1],m[2]).normalized(); 302 302 } 303 303 // … … 310 310 // 311 311 static inline btMatrix3x3 ImpulseMatrix( btScalar dt, 312 313 314 315 312 btScalar ima, 313 btScalar imb, 314 const btMatrix3x3& iwi, 315 const btVector3& r) 316 316 { 317 317 return(Diagonal(1/dt)*Add(Diagonal(ima),MassMatrix(imb,iwi,r)).inverse()); … … 320 320 // 321 321 static inline btMatrix3x3 ImpulseMatrix( btScalar ima,const btMatrix3x3& iia,const btVector3& ra, 322 323 { 324 322 btScalar imb,const btMatrix3x3& iib,const btVector3& rb) 323 { 324 return(Add(MassMatrix(ima,iia,ra),MassMatrix(imb,iib,rb)).inverse()); 325 325 } 326 326 327 327 // 328 328 static inline btMatrix3x3 AngularImpulseMatrix( const btMatrix3x3& iia, 329 330 { 331 329 const btMatrix3x3& iib) 330 { 331 return(Add(iia,iib).inverse()); 332 332 } 333 333 334 334 // 335 335 static inline btVector3 ProjectOnAxis( const btVector3& v, 336 336 const btVector3& a) 337 337 { 338 338 return(a*dot(v,a)); … … 340 340 // 341 341 static inline btVector3 ProjectOnPlane( const btVector3& v, 342 342 const btVector3& a) 343 343 { 344 344 return(v-ProjectOnAxis(v,a)); … … 347 347 // 348 348 static inline void ProjectOrigin( const btVector3& a, 349 350 351 352 { 353 354 355 349 const btVector3& b, 350 btVector3& prj, 351 btScalar& sqd) 352 { 353 const btVector3 d=b-a; 354 const btScalar m2=d.length2(); 355 if(m2>SIMD_EPSILON) 356 356 { 357 const btScalar t=Clamp<btScalar>(-dot(a,d)/m2,0,1); 358 const btVector3 p=a+d*t; 359 const btScalar l2=p.length2(); 360 if(l2<sqd) 361 { 357 const btScalar t=Clamp<btScalar>(-dot(a,d)/m2,0,1); 358 const btVector3 p=a+d*t; 359 const btScalar l2=p.length2(); 360 if(l2<sqd) 361 { 362 prj=p; 363 sqd=l2; 364 } 365 } 366 } 367 // 368 static inline void ProjectOrigin( const btVector3& a, 369 const btVector3& b, 370 const btVector3& c, 371 btVector3& prj, 372 btScalar& sqd) 373 { 374 const btVector3& q=cross(b-a,c-a); 375 const btScalar m2=q.length2(); 376 if(m2>SIMD_EPSILON) 377 { 378 const btVector3 n=q/btSqrt(m2); 379 const btScalar k=dot(a,n); 380 const btScalar k2=k*k; 381 if(k2<sqd) 382 { 383 const btVector3 p=n*k; 384 if( (dot(cross(a-p,b-p),q)>0)&& 385 (dot(cross(b-p,c-p),q)>0)&& 386 (dot(cross(c-p,a-p),q)>0)) 387 { 362 388 prj=p; 363 sqd=l2; 364 } 365 } 366 } 367 // 368 static inline void ProjectOrigin( const btVector3& a, 369 const btVector3& b, 370 const btVector3& c, 371 btVector3& prj, 372 btScalar& sqd) 373 { 374 const btVector3& q=cross(b-a,c-a); 375 const btScalar m2=q.length2(); 376 if(m2>SIMD_EPSILON) 377 { 378 const btVector3 n=q/btSqrt(m2); 379 const btScalar k=dot(a,n); 380 const btScalar k2=k*k; 381 if(k2<sqd) 382 { 383 const btVector3 p=n*k; 384 if( (dot(cross(a-p,b-p),q)>0)&& 385 (dot(cross(b-p,c-p),q)>0)&& 386 (dot(cross(c-p,a-p),q)>0)) 387 { 388 prj=p; 389 sqd=k2; 389 sqd=k2; 390 390 } 391 391 else 392 392 { 393 394 395 393 ProjectOrigin(a,b,prj,sqd); 394 ProjectOrigin(b,c,prj,sqd); 395 ProjectOrigin(c,a,prj,sqd); 396 396 } 397 397 } … … 402 402 template <typename T> 403 403 static inline T BaryEval( const T& a, 404 405 406 404 const T& b, 405 const T& c, 406 const btVector3& coord) 407 407 { 408 408 return(a*coord.x()+b*coord.y()+c*coord.z()); … … 410 410 // 411 411 static inline btVector3 BaryCoord( const btVector3& a, 412 413 414 415 { 416 417 cross(b-p,c-p).length(),418 cross(c-p,a-p).length()};419 420 412 const btVector3& b, 413 const btVector3& c, 414 const btVector3& p) 415 { 416 const btScalar w[]={ cross(a-p,b-p).length(), 417 cross(b-p,c-p).length(), 418 cross(c-p,a-p).length()}; 419 const btScalar isum=1/(w[0]+w[1]+w[2]); 420 return(btVector3(w[1]*isum,w[2]*isum,w[0]*isum)); 421 421 } 422 422 423 423 // 424 424 static btScalar ImplicitSolve( btSoftBody::ImplicitFn* fn, 425 426 427 428 429 { 430 431 432 433 { 434 435 436 } 437 438 439 440 { 441 442 443 444 445 425 const btVector3& a, 426 const btVector3& b, 427 const btScalar accuracy, 428 const int maxiterations=256) 429 { 430 btScalar span[2]={0,1}; 431 btScalar values[2]={fn->Eval(a),fn->Eval(b)}; 432 if(values[0]>values[1]) 433 { 434 btSwap(span[0],span[1]); 435 btSwap(values[0],values[1]); 436 } 437 if(values[0]>-accuracy) return(-1); 438 if(values[1]<+accuracy) return(-1); 439 for(int i=0;i<maxiterations;++i) 440 { 441 const btScalar t=Lerp(span[0],span[1],values[0]/(values[0]-values[1])); 442 const btScalar v=fn->Eval(Lerp(a,b,t)); 443 if((t<=0)||(t>=1)) break; 444 if(btFabs(v)<accuracy) return(t); 445 if(v<0) 446 446 { span[0]=t;values[0]=v; } 447 447 else 448 448 { span[1]=t;values[1]=v; } 449 449 } 450 450 return(-1); 451 451 } 452 452 … … 463 463 // 464 464 static inline btDbvtVolume VolumeOf( const btSoftBody::Face& f, 465 466 { 467 468 &f.m_n[1]->m_x,469 &f.m_n[2]->m_x};470 471 472 465 btScalar margin) 466 { 467 const btVector3* pts[]={ &f.m_n[0]->m_x, 468 &f.m_n[1]->m_x, 469 &f.m_n[2]->m_x}; 470 btDbvtVolume vol=btDbvtVolume::FromPoints(pts,3); 471 vol.Expand(btVector3(margin,margin,margin)); 472 return(vol); 473 473 } 474 474 … … 476 476 static inline btVector3 CenterOf( const btSoftBody::Face& f) 477 477 { 478 478 return((f.m_n[0]->m_x+f.m_n[1]->m_x+f.m_n[2]->m_x)/3); 479 479 } 480 480 481 481 // 482 482 static inline btScalar AreaOf( const btVector3& x0, 483 484 483 const btVector3& x1, 484 const btVector3& x2) 485 485 { 486 486 const btVector3 a=x1-x0; … … 493 493 // 494 494 static inline btScalar VolumeOf( const btVector3& x0, 495 496 497 495 const btVector3& x1, 496 const btVector3& x2, 497 const btVector3& x3) 498 498 { 499 499 const btVector3 a=x1-x0; … … 505 505 // 506 506 static void EvaluateMedium( const btSoftBodyWorldInfo* wfi, 507 508 507 const btVector3& x, 508 btSoftBody::sMedium& medium) 509 509 { 510 510 medium.m_velocity = btVector3(0,0,0); … … 524 524 // 525 525 static inline void ApplyClampedForce( btSoftBody::Node& n, 526 527 526 const btVector3& f, 527 btScalar dt) 528 528 { 529 529 const btScalar dtim=dt*n.m_im; … … 540 540 // 541 541 static inline int MatchEdge( const btSoftBody::Node* a, 542 543 544 545 { 546 547 548 542 const btSoftBody::Node* b, 543 const btSoftBody::Node* ma, 544 const btSoftBody::Node* mb) 545 { 546 if((a==ma)&&(b==mb)) return(0); 547 if((a==mb)&&(b==ma)) return(1); 548 return(-1); 549 549 } 550 550 … … 556 556 struct btEigen 557 557 { 558 559 { 560 561 562 563 564 565 566 567 568 569 558 static int system(btMatrix3x3& a,btMatrix3x3* vectors,btVector3* values=0) 559 { 560 static const int maxiterations=16; 561 static const btScalar accuracy=(btScalar)0.0001; 562 btMatrix3x3& v=*vectors; 563 int iterations=0; 564 vectors->setIdentity(); 565 do { 566 int p=0,q=1; 567 if(btFabs(a[p][q])<btFabs(a[0][2])) { p=0;q=2; } 568 if(btFabs(a[p][q])<btFabs(a[1][2])) { p=1;q=2; } 569 if(btFabs(a[p][q])>accuracy) 570 570 { 571 572 573 574 571 const btScalar w=(a[q][q]-a[p][p])/(2*a[p][q]); 572 const btScalar z=btFabs(w); 573 const btScalar t=w/(z*(btSqrt(1+w*w)+z)); 574 if(t==t)/* [WARNING] let hope that one does not get thrown aways by some compilers... */ 575 575 { 576 577 578 579 580 576 const btScalar c=1/btSqrt(t*t+1); 577 const btScalar s=c*t; 578 mulPQ(a,c,s,p,q); 579 mulTPQ(a,c,s,p,q); 580 mulPQ(v,c,s,p,q); 581 581 } else break; 582 582 } else break; 583 583 } while((++iterations)<maxiterations); 584 585 { 586 587 } 588 584 if(values) 585 { 586 *values=btVector3(a[0][0],a[1][1],a[2][2]); 587 } 588 return(iterations); 589 589 } 590 590 private: 591 592 { 593 594 {a[q][0],a[q][1],a[q][2]}};595 596 597 598 599 } 600 601 { 602 603 {a[0][q],a[1][q],a[2][q]}};604 605 606 607 591 static inline void mulTPQ(btMatrix3x3& a,btScalar c,btScalar s,int p,int q) 592 { 593 const btScalar m[2][3]={ {a[p][0],a[p][1],a[p][2]}, 594 {a[q][0],a[q][1],a[q][2]}}; 595 int i; 596 597 for(i=0;i<3;++i) a[p][i]=c*m[0][i]-s*m[1][i]; 598 for(i=0;i<3;++i) a[q][i]=c*m[1][i]+s*m[0][i]; 599 } 600 static inline void mulPQ(btMatrix3x3& a,btScalar c,btScalar s,int p,int q) 601 { 602 const btScalar m[2][3]={ {a[0][p],a[1][p],a[2][p]}, 603 {a[0][q],a[1][q],a[2][q]}}; 604 int i; 605 606 for(i=0;i<3;++i) a[i][p]=c*m[0][i]-s*m[1][i]; 607 for(i=0;i<3;++i) a[i][q]=c*m[1][i]+s*m[0][i]; 608 608 } 609 609 }; … … 640 640 s.setIdentity(); 641 641 } 642 642 return(i); 643 643 } 644 644 … … 653 653 struct ClusterBase : btDbvt::ICollide 654 654 { 655 656 657 658 659 660 ClusterBase()661 { 662 663 664 665 666 667 } 668 669 btSoftBody::Body ba,btSoftBody::Body bb,670 btSoftBody::CJoint& joint)671 { 672 655 btScalar erp; 656 btScalar idt; 657 btScalar margin; 658 btScalar friction; 659 btScalar threshold; 660 ClusterBase() 661 { 662 erp =(btScalar)1; 663 idt =0; 664 margin =0; 665 friction =0; 666 threshold =(btScalar)0; 667 } 668 bool SolveContact( const btGjkEpaSolver2::sResults& res, 669 btSoftBody::Body ba,btSoftBody::Body bb, 670 btSoftBody::CJoint& joint) 671 { 672 if(res.distance<margin) 673 673 { 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 bb.invMass(),bb.invWorldInertia(),joint.m_rpos[1]);700 674 const btVector3 ra=res.witnesses[0]-ba.xform().getOrigin(); 675 const btVector3 rb=res.witnesses[1]-bb.xform().getOrigin(); 676 const btVector3 va=ba.velocity(ra); 677 const btVector3 vb=bb.velocity(rb); 678 const btVector3 vrel=va-vb; 679 const btScalar rvac=dot(vrel,res.normal); 680 const btScalar depth=res.distance-margin; 681 const btVector3 iv=res.normal*rvac; 682 const btVector3 fv=vrel-iv; 683 joint.m_bodies[0] = ba; 684 joint.m_bodies[1] = bb; 685 joint.m_refs[0] = ra*ba.xform().getBasis(); 686 joint.m_refs[1] = rb*bb.xform().getBasis(); 687 joint.m_rpos[0] = ra; 688 joint.m_rpos[1] = rb; 689 joint.m_cfm = 1; 690 joint.m_erp = 1; 691 joint.m_life = 0; 692 joint.m_maxlife = 0; 693 joint.m_split = 1; 694 joint.m_drift = depth*res.normal; 695 joint.m_normal = res.normal; 696 joint.m_delete = false; 697 joint.m_friction = fv.length2()<(-rvac*friction)?1:friction; 698 joint.m_massmatrix = ImpulseMatrix( ba.invMass(),ba.invWorldInertia(),joint.m_rpos[0], 699 bb.invMass(),bb.invWorldInertia(),joint.m_rpos[1]); 700 return(true); 701 701 } 702 702 return(false); 703 703 } 704 704 }; … … 708 708 struct CollideCL_RS : ClusterBase 709 709 { 710 711 712 713 { 714 715 716 717 718 719 rshape,prb->getInterpolationWorldTransform(),720 btVector3(1,0,0),res))710 btSoftBody* psb; 711 btRigidBody* prb; 712 void Process(const btDbvtNode* leaf) 713 { 714 btSoftBody::Cluster* cluster=(btSoftBody::Cluster*)leaf->data; 715 btSoftClusterCollisionShape cshape(cluster); 716 const btConvexShape* rshape=(const btConvexShape*)prb->getCollisionShape(); 717 btGjkEpaSolver2::sResults res; 718 if(btGjkEpaSolver2::SignedDistance( &cshape,btTransform::getIdentity(), 719 rshape,prb->getInterpolationWorldTransform(), 720 btVector3(1,0,0),res)) 721 721 { 722 723 722 btSoftBody::CJoint joint; 723 if(SolveContact(res,cluster,prb,joint)) 724 724 { 725 726 727 725 btSoftBody::CJoint* pj=new(btAlignedAlloc(sizeof(btSoftBody::CJoint),16)) btSoftBody::CJoint(); 726 *pj=joint;psb->m_joints.push_back(pj); 727 if(prb->isStaticOrKinematicObject()) 728 728 { 729 730 729 pj->m_erp *= psb->m_cfg.kSKHR_CL; 730 pj->m_split *= psb->m_cfg.kSK_SPLT_CL; 731 731 } 732 732 else 733 733 { 734 735 734 pj->m_erp *= psb->m_cfg.kSRHR_CL; 735 pj->m_split *= psb->m_cfg.kSR_SPLT_CL; 736 736 } 737 737 } 738 738 } 739 739 } 740 741 { 742 743 744 745 746 pr->getCollisionShape()->getMargin();747 748 749 750 751 752 753 754 755 740 void Process(btSoftBody* ps,btRigidBody* pr) 741 { 742 psb = ps; 743 prb = pr; 744 idt = ps->m_sst.isdt; 745 margin = ps->getCollisionShape()->getMargin()+ 746 pr->getCollisionShape()->getMargin(); 747 friction = btMin(psb->m_cfg.kDF,prb->getFriction()); 748 btVector3 mins; 749 btVector3 maxs; 750 751 ATTRIBUTE_ALIGNED16(btDbvtVolume) volume; 752 pr->getCollisionShape()->getAabb(pr->getInterpolationWorldTransform(),mins,maxs); 753 volume=btDbvtVolume::FromMM(mins,maxs); 754 volume.Expand(btVector3(1,1,1)*margin); 755 btDbvt::collideTV(ps->m_cdbvt.m_root,volume,*this); 756 756 } 757 757 }; … … 761 761 struct CollideCL_SS : ClusterBase 762 762 { 763 764 765 { 766 767 768 769 770 771 772 &csb,btTransform::getIdentity(),773 cla->m_com-clb->m_com,res))763 btSoftBody* bodies[2]; 764 void Process(const btDbvtNode* la,const btDbvtNode* lb) 765 { 766 btSoftBody::Cluster* cla=(btSoftBody::Cluster*)la->data; 767 btSoftBody::Cluster* clb=(btSoftBody::Cluster*)lb->data; 768 btSoftClusterCollisionShape csa(cla); 769 btSoftClusterCollisionShape csb(clb); 770 btGjkEpaSolver2::sResults res; 771 if(btGjkEpaSolver2::SignedDistance( &csa,btTransform::getIdentity(), 772 &csb,btTransform::getIdentity(), 773 cla->m_com-clb->m_com,res)) 774 774 { 775 776 775 btSoftBody::CJoint joint; 776 if(SolveContact(res,cla,clb,joint)) 777 777 { 778 779 780 781 778 btSoftBody::CJoint* pj=new(btAlignedAlloc(sizeof(btSoftBody::CJoint),16)) btSoftBody::CJoint(); 779 *pj=joint;bodies[0]->m_joints.push_back(pj); 780 pj->m_erp *= btMax(bodies[0]->m_cfg.kSSHR_CL,bodies[1]->m_cfg.kSSHR_CL); 781 pj->m_split *= (bodies[0]->m_cfg.kSS_SPLT_CL+bodies[1]->m_cfg.kSS_SPLT_CL)/2; 782 782 } 783 783 } 784 784 } 785 786 { 787 788 789 790 791 792 785 void Process(btSoftBody* psa,btSoftBody* psb) 786 { 787 idt = psa->m_sst.isdt; 788 margin = (psa->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin())/2; 789 friction = btMin(psa->m_cfg.kDF,psb->m_cfg.kDF); 790 bodies[0] = psa; 791 bodies[1] = psb; 792 btDbvt::collideTT(psa->m_cdbvt.m_root,psb->m_cdbvt.m_root,*this); 793 793 } 794 794 }; … … 798 798 struct CollideSDF_RS : btDbvt::ICollide 799 799 { 800 801 { 802 803 804 } 805 806 { 807 808 809 810 800 void Process(const btDbvtNode* leaf) 801 { 802 btSoftBody::Node* node=(btSoftBody::Node*)leaf->data; 803 DoNode(*node); 804 } 805 void DoNode(btSoftBody::Node& n) const 806 { 807 const btScalar m=n.m_im>0?dynmargin:stamargin; 808 btSoftBody::RContact c; 809 if( (!n.m_battach)&& 810 psb->checkContact(prb,n.m_x,m,c.m_cti)) 811 811 { 812 813 814 815 812 const btScalar ima=n.m_im; 813 const btScalar imb=prb->getInvMass(); 814 const btScalar ms=ima+imb; 815 if(ms>0) 816 816 { 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 817 const btTransform& wtr=prb->getInterpolationWorldTransform(); 818 const btMatrix3x3& iwi=prb->getInvInertiaTensorWorld(); 819 const btVector3 ra=n.m_x-wtr.getOrigin(); 820 const btVector3 va=prb->getVelocityInLocalPoint(ra)*psb->m_sst.sdt; 821 const btVector3 vb=n.m_x-n.m_q; 822 const btVector3 vr=vb-va; 823 const btScalar dn=dot(vr,c.m_cti.m_normal); 824 const btVector3 fv=vr-c.m_cti.m_normal*dn; 825 const btScalar fc=psb->m_cfg.kDF*prb->getFriction(); 826 c.m_node = &n; 827 c.m_c0 = ImpulseMatrix(psb->m_sst.sdt,ima,imb,iwi,ra); 828 c.m_c1 = ra; 829 c.m_c2 = ima*psb->m_sst.sdt; 830 c.m_c3 = fv.length2()<(btFabs(dn)*fc)?0:1-fc; 831 c.m_c4 = prb->isStaticOrKinematicObject()?psb->m_cfg.kKHR:psb->m_cfg.kCHR; 832 psb->m_rcontacts.push_back(c); 833 prb->activate(); 834 834 } 835 835 } 836 836 } 837 838 839 840 837 btSoftBody* psb; 838 btRigidBody* prb; 839 btScalar dynmargin; 840 btScalar stamargin; 841 841 }; 842 842 // … … 845 845 struct CollideVF_SS : btDbvt::ICollide 846 846 { 847 848 const btDbvtNode* lface)849 { 850 851 852 853 854 855 856 face->m_n[1]->m_x-o,857 face->m_n[2]->m_x-o,858 p,d);859 860 847 void Process(const btDbvtNode* lnode, 848 const btDbvtNode* lface) 849 { 850 btSoftBody::Node* node=(btSoftBody::Node*)lnode->data; 851 btSoftBody::Face* face=(btSoftBody::Face*)lface->data; 852 btVector3 o=node->m_x; 853 btVector3 p; 854 btScalar d=SIMD_INFINITY; 855 ProjectOrigin( face->m_n[0]->m_x-o, 856 face->m_n[1]->m_x-o, 857 face->m_n[2]->m_x-o, 858 p,d); 859 const btScalar m=mrg+(o-node->m_q).length()*2; 860 if(d<(m*m)) 861 861 { 862 863 864 865 866 867 868 862 const btSoftBody::Node* n[]={face->m_n[0],face->m_n[1],face->m_n[2]}; 863 const btVector3 w=BaryCoord(n[0]->m_x,n[1]->m_x,n[2]->m_x,p+o); 864 const btScalar ma=node->m_im; 865 btScalar mb=BaryEval(n[0]->m_im,n[1]->m_im,n[2]->m_im,w); 866 if( (n[0]->m_im<=0)|| 867 (n[1]->m_im<=0)|| 868 (n[2]->m_im<=0)) 869 869 { 870 870 mb=0; 871 871 } 872 873 872 const btScalar ms=ma+mb; 873 if(ms>0) 874 874 { 875 876 877 878 879 880 881 882 883 884 875 btSoftBody::SContact c; 876 c.m_normal = p/-btSqrt(d); 877 c.m_margin = m; 878 c.m_node = node; 879 c.m_face = face; 880 c.m_weights = w; 881 c.m_friction = btMax(psb[0]->m_cfg.kDF,psb[1]->m_cfg.kDF); 882 c.m_cfm[0] = ma/ms*psb[0]->m_cfg.kSHR; 883 c.m_cfm[1] = mb/ms*psb[1]->m_cfg.kSHR; 884 psb[0]->m_scontacts.push_back(c); 885 885 } 886 886 } 887 887 } 888 889 888 btSoftBody* psb[2]; 889 btScalar mrg; 890 890 }; 891 891 }; -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp
r1963 r1972 30 30 mem = btAlignedAlloc(sizeof(btSoftSoftCollisionAlgorithm::CreateFunc),16); 31 31 m_softSoftCreateFunc = new(mem) btSoftSoftCollisionAlgorithm::CreateFunc; 32 32 33 33 mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc),16); 34 34 m_softRigidConvexCreateFunc = new(mem) btSoftRigidCollisionAlgorithm::CreateFunc; 35 35 36 36 mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc),16); 37 37 m_swappedSoftRigidConvexCreateFunc = new(mem) btSoftRigidCollisionAlgorithm::CreateFunc; … … 41 41 mem = btAlignedAlloc(sizeof(btSoftBodyConcaveCollisionAlgorithm::CreateFunc),16); 42 42 m_softRigidConcaveCreateFunc = new(mem) btSoftBodyConcaveCollisionAlgorithm::CreateFunc; 43 43 44 44 mem = btAlignedAlloc(sizeof(btSoftBodyConcaveCollisionAlgorithm::CreateFunc),16); 45 45 m_swappedSoftRigidConcaveCreateFunc = new(mem) btSoftBodyConcaveCollisionAlgorithm::SwappedCreateFunc; … … 48 48 49 49 //replace pool by a new one, with potential larger size 50 50 51 51 if (m_ownsCollisionAlgorithmPool && m_collisionAlgorithmPool) 52 52 { 53 53 int curElemSize = m_collisionAlgorithmPool->getElementSize(); 54 54 ///calculate maximum element size, big enough to fit any collision algorithm in the memory pool 55 56 55 56 57 57 int maxSize0 = sizeof(btSoftSoftCollisionAlgorithm); 58 58 int maxSize1 = sizeof(btSoftRigidCollisionAlgorithm); … … 93 93 #endif 94 94 } 95 95 96 96 ///creation of soft-soft and soft-rigid, and otherwise fallback to base class implementation 97 97 btCollisionAlgorithmCreateFunc* btSoftBodyRigidBodyCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h
r1963 r1972 33 33 btCollisionAlgorithmCreateFunc* m_softRigidConcaveCreateFunc; 34 34 btCollisionAlgorithmCreateFunc* m_swappedSoftRigidConcaveCreateFunc; 35 35 36 36 public: 37 37 -
code/branches/physics/src/bullet/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp
r1963 r1972 36 36 btSoftRigidCollisionAlgorithm::~btSoftRigidCollisionAlgorithm() 37 37 { 38 38 39 39 //m_softBody->m_overlappingRigidBodies.remove(m_rigidCollisionObject); 40 40 41 41 /*if (m_ownManifold) 42 42 { 43 if (m_manifoldPtr)44 m_dispatcher->releaseManifold(m_manifoldPtr);43 if (m_manifoldPtr) 44 m_dispatcher->releaseManifold(m_manifoldPtr); 45 45 } 46 46 */ … … 59 59 btSoftBody* softBody = m_isSwapped? (btSoftBody*)body1 : (btSoftBody*)body0; 60 60 btCollisionObject* rigidCollisionObject = m_isSwapped? body0 : body1; 61 61 62 62 softBody->defaultCollisionHandler(rigidCollisionObject); 63 63 -
code/branches/physics/src/bullet/BulletSoftBody/btSoftRigidCollisionAlgorithm.h
r1963 r1972 29 29 class btSoftRigidCollisionAlgorithm : public btCollisionAlgorithm 30 30 { 31 32 31 // bool m_ownManifold; 32 // btPersistentManifold* m_manifoldPtr; 33 33 34 34 btSoftBody* m_softBody; … … 37 37 ///for rigid versus soft (instead of soft versus rigid), we use this swapped boolean 38 38 bool m_isSwapped; 39 39 40 40 public: 41 41 … … 53 53 } 54 54 55 55 56 56 struct CreateFunc :public btCollisionAlgorithmCreateFunc 57 57 { -
code/branches/physics/src/bullet/BulletSoftBody/btSoftRigidDynamicsWorld.cpp
r1963 r1972 29 29 :btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration) 30 30 { 31 32 33 34 35 36 37 38 31 m_drawFlags = fDrawFlags::Std; 32 m_drawNodeTree = true; 33 m_drawFaceTree = false; 34 m_drawClusterTree = false; 35 m_sbi.m_broadphase = pairCache; 36 m_sbi.m_dispatcher = dispatcher; 37 m_sbi.m_sparsesdf.Initialize(); 38 m_sbi.m_sparsesdf.Reset(); 39 39 40 40 } 41 41 42 42 btSoftRigidDynamicsWorld::~btSoftRigidDynamicsWorld() 43 43 { … … 56 56 } 57 57 } 58 58 59 59 void btSoftRigidDynamicsWorld::internalSingleStepSimulation( btScalar timeStep) 60 60 { … … 72 72 { 73 73 BT_PROFILE("updateSoftBodies"); 74 74 75 75 for ( int i=0;i<m_softBodies.size();i++) 76 76 { … … 83 83 { 84 84 BT_PROFILE("solveSoftConstraints"); 85 85 86 86 if(m_softBodies.size()) 87 {87 { 88 88 btSoftBody::solveClusters(m_softBodies); 89 }90 89 } 90 91 91 for(int i=0;i<m_softBodies.size();++i) 92 92 { … … 101 101 102 102 btCollisionWorld::addCollisionObject(body, 103 btBroadphaseProxy::DefaultFilter,104 btBroadphaseProxy::AllFilter);103 btBroadphaseProxy::DefaultFilter, 104 btBroadphaseProxy::AllFilter); 105 105 106 106 } -
code/branches/physics/src/bullet/BulletSoftBody/btSoftRigidDynamicsWorld.h
r1963 r1972 24 24 class btSoftRigidDynamicsWorld : public btDiscreteDynamicsWorld 25 25 { 26 26 27 27 btSoftBodyArray m_softBodies; 28 28 int m_drawFlags; … … 33 33 34 34 protected: 35 35 36 36 virtual void predictUnconstraintMotion(btScalar timeStep); 37 37 38 38 virtual void internalSingleStepSimulation( btScalar timeStep); 39 39 … … 44 44 45 45 public: 46 46 47 47 btSoftRigidDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration); 48 48 49 49 virtual ~btSoftRigidDynamicsWorld(); 50 50 51 51 virtual void debugDrawWorld(); 52 52 53 53 void addSoftBody(btSoftBody* body); 54 54 55 55 void removeSoftBody(btSoftBody* body); 56 56 57 57 int getDrawFlags() const { return(m_drawFlags); } 58 58 void setDrawFlags(int f) { m_drawFlags=f; } … … 67 67 } 68 68 69 69 70 70 btSoftBodyArray& getSoftBodyArray() 71 71 { … … 77 77 return m_softBodies; 78 78 } 79 79 80 80 }; 81 81 -
code/branches/physics/src/bullet/BulletSoftBody/btSoftSoftCollisionAlgorithm.h
r1963 r1972 34 34 btSoftBody* m_softBody1; 35 35 36 36 37 37 public: 38 38 btSoftSoftCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) -
code/branches/physics/src/bullet/BulletSoftBody/btSparseSDF.h
r1963 r1972 24 24 template <const int DWORDLEN> 25 25 unsigned int HsiehHash(const void* pdata) 26 {26 { 27 27 const unsigned short* data=(const unsigned short*)pdata; 28 28 unsigned hash=DWORDLEN<<2,tmp; 29 29 for(int i=0;i<DWORDLEN;++i) 30 {30 { 31 31 hash += data[0]; 32 32 tmp = (data[1]<<11)^hash; … … 34 34 data += 2; 35 35 hash += hash>>11; 36 }36 } 37 37 hash^=hash<<3;hash+=hash>>5; 38 38 hash^=hash<<4;hash+=hash>>17; 39 39 hash^=hash<<25;hash+=hash>>6; 40 40 return(hash); 41 }41 } 42 42 43 43 template <const int CELLSIZE> 44 44 struct btSparseSdf 45 {45 { 46 46 // 47 47 // Inner types 48 48 // 49 49 struct IntFrac 50 {50 { 51 51 int b; 52 52 int i; 53 53 btScalar f; 54 };54 }; 55 55 struct Cell 56 {56 { 57 57 btScalar d[CELLSIZE+1][CELLSIZE+1][CELLSIZE+1]; 58 58 int c[3]; … … 61 61 btCollisionShape* pclient; 62 62 Cell* next; 63 };63 }; 64 64 // 65 65 // Fields 66 66 // 67 67 68 68 btAlignedObjectArray<Cell*> cells; 69 69 btScalar voxelsz; … … 72 72 int nprobes; 73 73 int nqueries; 74 74 75 75 // 76 76 // Methods 77 77 // 78 78 79 79 // 80 80 void Initialize(int hashsize=2383) 81 {81 { 82 82 cells.resize(hashsize,0); 83 83 Reset(); 84 }84 } 85 85 // 86 86 void Reset() 87 {87 { 88 88 for(int i=0,ni=cells.size();i<ni;++i) 89 {89 { 90 90 Cell* pc=cells[i]; 91 91 cells[i]=0; 92 92 while(pc) 93 {93 { 94 94 Cell* pn=pc->next; 95 95 delete pc; 96 96 pc=pn; 97 }98 }97 } 98 } 99 99 voxelsz =0.25; 100 100 puid =0; … … 102 102 nprobes =1; 103 103 nqueries =1; 104 }104 } 105 105 // 106 106 void GarbageCollect(int lifetime=256) 107 {107 { 108 108 const int life=puid-lifetime; 109 109 for(int i=0;i<cells.size();++i) 110 {110 { 111 111 Cell*& root=cells[i]; 112 112 Cell* pp=0; 113 113 Cell* pc=root; 114 114 while(pc) 115 {115 { 116 116 Cell* pn=pc->next; 117 117 if(pc->puid<life) 118 {118 { 119 119 if(pp) pp->next=pn; else root=pn; 120 120 delete pc;pc=pp;--ncells; 121 } 122 pp=pc;pc=pn; 121 123 } 122 pp=pc;pc=pn; 123 } 124 } 124 } 125 125 //printf("GC[%d]: %d cells, PpQ: %f\r\n",puid,ncells,nprobes/(btScalar)nqueries); 126 126 nqueries=1; 127 127 nprobes=1; 128 128 ++puid; /* TODO: Reset puid's when int range limit is reached */ 129 /* else setup a priority list... */130 }129 /* else setup a priority list... */ 130 } 131 131 // 132 132 int RemoveReferences(btCollisionShape* pcs) 133 {133 { 134 134 int refcount=0; 135 135 for(int i=0;i<cells.size();++i) 136 {136 { 137 137 Cell*& root=cells[i]; 138 138 Cell* pp=0; 139 139 Cell* pc=root; 140 140 while(pc) 141 {141 { 142 142 Cell* pn=pc->next; 143 143 if(pc->pclient==pcs) 144 {144 { 145 145 if(pp) pp->next=pn; else root=pn; 146 146 delete pc;pc=pp;++refcount; 147 } 148 pp=pc;pc=pn; 147 149 } 148 pp=pc;pc=pn; 149 } 150 } 150 } 151 151 return(refcount); 152 }152 } 153 153 // 154 154 btScalar Evaluate( const btVector3& x, 155 btCollisionShape* shape,156 btVector3& normal,157 btScalar margin)158 {155 btCollisionShape* shape, 156 btVector3& normal, 157 btScalar margin) 158 { 159 159 /* Lookup cell */ 160 160 const btVector3 scx=x/voxelsz; … … 167 167 ++nqueries; 168 168 while(c) 169 {169 { 170 170 ++nprobes; 171 171 if( (c->hash==h) && … … 174 174 (c->c[2]==iz.b) && 175 175 (c->pclient==shape)) 176 { break; }177 else178 { c=c->next; }179 }176 { break; } 177 else 178 { c=c->next; } 179 } 180 180 if(!c) 181 {181 { 182 182 ++nprobes; 183 183 ++ncells; … … 188 188 c->c[0]=ix.b;c->c[1]=iy.b;c->c[2]=iz.b; 189 189 BuildCell(*c); 190 }190 } 191 191 c->puid=puid; 192 192 /* Extract infos */ 193 193 const int o[]={ ix.i,iy.i,iz.i}; 194 194 const btScalar d[]={ c->d[o[0]+0][o[1]+0][o[2]+0], 195 c->d[o[0]+1][o[1]+0][o[2]+0],196 c->d[o[0]+1][o[1]+1][o[2]+0],197 c->d[o[0]+0][o[1]+1][o[2]+0],198 c->d[o[0]+0][o[1]+0][o[2]+1],199 c->d[o[0]+1][o[1]+0][o[2]+1],200 c->d[o[0]+1][o[1]+1][o[2]+1],201 c->d[o[0]+0][o[1]+1][o[2]+1]};195 c->d[o[0]+1][o[1]+0][o[2]+0], 196 c->d[o[0]+1][o[1]+1][o[2]+0], 197 c->d[o[0]+0][o[1]+1][o[2]+0], 198 c->d[o[0]+0][o[1]+0][o[2]+1], 199 c->d[o[0]+1][o[1]+0][o[2]+1], 200 c->d[o[0]+1][o[1]+1][o[2]+1], 201 c->d[o[0]+0][o[1]+1][o[2]+1]}; 202 202 /* Normal */ 203 #if 1203 #if 1 204 204 const btScalar gx[]={ d[1]-d[0],d[2]-d[3], 205 d[5]-d[4],d[6]-d[7]};205 d[5]-d[4],d[6]-d[7]}; 206 206 const btScalar gy[]={ d[3]-d[0],d[2]-d[1], 207 d[7]-d[4],d[6]-d[5]};207 d[7]-d[4],d[6]-d[5]}; 208 208 const btScalar gz[]={ d[4]-d[0],d[5]-d[1], 209 d[7]-d[3],d[6]-d[2]};209 d[7]-d[3],d[6]-d[2]}; 210 210 normal.setX(Lerp( Lerp(gx[0],gx[1],iy.f), 211 Lerp(gx[2],gx[3],iy.f),iz.f));211 Lerp(gx[2],gx[3],iy.f),iz.f)); 212 212 normal.setY(Lerp( Lerp(gy[0],gy[1],ix.f), 213 Lerp(gy[2],gy[3],ix.f),iz.f));213 Lerp(gy[2],gy[3],ix.f),iz.f)); 214 214 normal.setZ(Lerp( Lerp(gz[0],gz[1],ix.f), 215 Lerp(gz[2],gz[3],ix.f),iy.f));215 Lerp(gz[2],gz[3],ix.f),iy.f)); 216 216 normal = normal.normalized(); 217 #else217 #else 218 218 normal = btVector3(d[1]-d[0],d[3]-d[0],d[4]-d[0]).normalized(); 219 #endif219 #endif 220 220 /* Distance */ 221 221 const btScalar d0=Lerp(Lerp(d[0],d[1],ix.f), 222 Lerp(d[3],d[2],ix.f),iy.f);222 Lerp(d[3],d[2],ix.f),iy.f); 223 223 const btScalar d1=Lerp(Lerp(d[4],d[5],ix.f), 224 Lerp(d[7],d[6],ix.f),iy.f);224 Lerp(d[7],d[6],ix.f),iy.f); 225 225 return(Lerp(d0,d1,iz.f)-margin); 226 }226 } 227 227 // 228 228 void BuildCell(Cell& c) 229 {229 { 230 230 const btVector3 org=btVector3( (btScalar)c.c[0], 231 (btScalar)c.c[1],232 (btScalar)c.c[2]) *233 CELLSIZE*voxelsz;231 (btScalar)c.c[1], 232 (btScalar)c.c[2]) * 233 CELLSIZE*voxelsz; 234 234 for(int k=0;k<=CELLSIZE;++k) 235 {235 { 236 236 const btScalar z=voxelsz*k+org.z(); 237 237 for(int j=0;j<=CELLSIZE;++j) 238 {238 { 239 239 const btScalar y=voxelsz*j+org.y(); 240 240 for(int i=0;i<=CELLSIZE;++i) 241 {241 { 242 242 const btScalar x=voxelsz*i+org.x(); 243 243 c.d[i][j][k]=DistanceToShape( btVector3(x,y,z), 244 c.pclient); 244 c.pclient); 245 } 245 246 } 246 247 } 247 248 } 248 }249 249 // 250 250 static inline btScalar DistanceToShape(const btVector3& x, 251 btCollisionShape* shape)252 {251 btCollisionShape* shape) 252 { 253 253 btTransform unit; 254 254 unit.setIdentity(); 255 255 if(shape->isConvex()) 256 {256 { 257 257 btGjkEpaSolver2::sResults res; 258 258 btConvexShape* csh=static_cast<btConvexShape*>(shape); 259 259 return(btGjkEpaSolver2::SignedDistance(x,0,csh,unit,res)); 260 }260 } 261 261 return(0); 262 }262 } 263 263 // 264 264 static inline IntFrac Decompose(btScalar x) 265 {265 { 266 266 /* That one need a lot of improvements... */ 267 267 /* Remove test, faster floor... */ … … 273 273 r.i=(int)k;r.f=k-r.i;r.b-=o; 274 274 return(r); 275 }275 } 276 276 // 277 277 static inline btScalar Lerp(btScalar a,btScalar b,btScalar t) 278 {278 { 279 279 return(a+(b-a)*t); 280 }281 282 280 } 281 282 283 283 284 284 // 285 285 static inline unsigned int Hash(int x,int y,int z,btCollisionShape* shape) 286 {286 { 287 287 struct btS 288 288 { … … 292 292 293 293 btS myset; 294 294 295 295 myset.x=x;myset.y=y;myset.z=z;myset.p=shape; 296 296 const void* ptr = &myset; 297 297 298 298 unsigned int result = HsiehHash<sizeof(btS)/4> (ptr); 299 299 300 300 301 301 return result; 302 }302 } 303 303 }; 304 304 305 305 306 306 #endif
Note: See TracChangeset
for help on using the changeset viewer.