Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/bullet2/src/BulletSoftBody/btSoftBody.cpp')
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBody.cpp2043
1 files changed, 1056 insertions, 987 deletions
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBody.cpp b/extern/bullet2/src/BulletSoftBody/btSoftBody.cpp
index 1ec668c9c78..ee810c54082 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBody.cpp
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBody.cpp
@@ -150,98 +150,98 @@ bool btSoftBody::checkFace(int node0,int node1,int node2) const
//
btSoftBody::Material* btSoftBody::appendMaterial()
{
-Material* pm=new(btAlignedAlloc(sizeof(Material),16)) Material();
-if(m_materials.size()>0)
- *pm=*m_materials[0];
+ Material* pm=new(btAlignedAlloc(sizeof(Material),16)) Material();
+ if(m_materials.size()>0)
+ *pm=*m_materials[0];
else
- ZeroInitialize(*pm);
-m_materials.push_back(pm);
-return(pm);
+ ZeroInitialize(*pm);
+ m_materials.push_back(pm);
+ return(pm);
}
//
void btSoftBody::appendNote( const char* text,
- const btVector3& o,
- const btVector4& c,
- Node* n0,
- Node* n1,
- Node* n2,
- Node* n3)
-{
-Note n;
-ZeroInitialize(n);
-n.m_rank = 0;
-n.m_text = text;
-n.m_offset = o;
-n.m_coords[0] = c.x();
-n.m_coords[1] = c.y();
-n.m_coords[2] = c.z();
-n.m_coords[3] = c.w();
-n.m_nodes[0] = n0;n.m_rank+=n0?1:0;
-n.m_nodes[1] = n1;n.m_rank+=n1?1:0;
-n.m_nodes[2] = n2;n.m_rank+=n2?1:0;
-n.m_nodes[3] = n3;n.m_rank+=n3?1:0;
-m_notes.push_back(n);
+ const btVector3& o,
+ const btVector4& c,
+ Node* n0,
+ Node* n1,
+ Node* n2,
+ Node* n3)
+{
+ Note n;
+ ZeroInitialize(n);
+ n.m_rank = 0;
+ n.m_text = text;
+ n.m_offset = o;
+ n.m_coords[0] = c.x();
+ n.m_coords[1] = c.y();
+ n.m_coords[2] = c.z();
+ n.m_coords[3] = c.w();
+ n.m_nodes[0] = n0;n.m_rank+=n0?1:0;
+ n.m_nodes[1] = n1;n.m_rank+=n1?1:0;
+ n.m_nodes[2] = n2;n.m_rank+=n2?1:0;
+ n.m_nodes[3] = n3;n.m_rank+=n3?1:0;
+ m_notes.push_back(n);
}
//
void btSoftBody::appendNote( const char* text,
- const btVector3& o,
- Node* feature)
+ const btVector3& o,
+ Node* feature)
{
-appendNote(text,o,btVector4(1,0,0,0),feature);
+ appendNote(text,o,btVector4(1,0,0,0),feature);
}
//
void btSoftBody::appendNote( const char* text,
- const btVector3& o,
- Link* feature)
+ const btVector3& o,
+ Link* feature)
{
-static const btScalar w=1/(btScalar)2;
-appendNote(text,o,btVector4(w,w,0,0), feature->m_n[0],
- feature->m_n[1]);
+ static const btScalar w=1/(btScalar)2;
+ appendNote(text,o,btVector4(w,w,0,0), feature->m_n[0],
+ feature->m_n[1]);
}
-
+
//
void btSoftBody::appendNote( const char* text,
- const btVector3& o,
- Face* feature)
+ const btVector3& o,
+ Face* feature)
{
-static const btScalar w=1/(btScalar)3;
-appendNote(text,o,btVector4(w,w,w,0), feature->m_n[0],
- feature->m_n[1],
- feature->m_n[2]);
+ static const btScalar w=1/(btScalar)3;
+ appendNote(text,o,btVector4(w,w,w,0), feature->m_n[0],
+ feature->m_n[1],
+ feature->m_n[2]);
}
//
void btSoftBody::appendNode( const btVector3& x,btScalar m)
{
-if(m_nodes.capacity()==m_nodes.size())
+ if(m_nodes.capacity()==m_nodes.size())
{
- pointersToIndices();
- m_nodes.reserve(m_nodes.size()*2+1);
- indicesToPointers();
+ pointersToIndices();
+ m_nodes.reserve(m_nodes.size()*2+1);
+ indicesToPointers();
}
-const btScalar margin=getCollisionShape()->getMargin();
-m_nodes.push_back(Node());
-Node& n=m_nodes[m_nodes.size()-1];
-ZeroInitialize(n);
-n.m_x = x;
-n.m_q = n.m_x;
-n.m_im = m>0?1/m:0;
-n.m_material = m_materials[0];
-n.m_leaf = m_ndbvt.insert(btDbvtVolume::FromCR(n.m_x,margin),&n);
+ const btScalar margin=getCollisionShape()->getMargin();
+ m_nodes.push_back(Node());
+ Node& n=m_nodes[m_nodes.size()-1];
+ ZeroInitialize(n);
+ n.m_x = x;
+ n.m_q = n.m_x;
+ n.m_im = m>0?1/m:0;
+ n.m_material = m_materials[0];
+ n.m_leaf = m_ndbvt.insert(btDbvtVolume::FromCR(n.m_x,margin),&n);
}
//
void btSoftBody::appendLink(int model,Material* mat)
{
-Link l;
-if(model>=0)
- l=m_links[model];
+ Link l;
+ if(model>=0)
+ l=m_links[model];
else
{ ZeroInitialize(l);l.m_material=mat?mat:m_materials[0]; }
-m_links.push_back(l);
+ m_links.push_back(l);
}
//
@@ -273,12 +273,12 @@ void btSoftBody::appendLink( Node* node0,
//
void btSoftBody::appendFace(int model,Material* mat)
{
-Face f;
-if(model>=0)
+ Face f;
+ if(model>=0)
{ f=m_faces[model]; }
else
{ ZeroInitialize(f);f.m_material=mat?mat:m_materials[0]; }
-m_faces.push_back(f);
+ m_faces.push_back(f);
}
//
@@ -306,9 +306,9 @@ void btSoftBody::appendFace(int node0,int node1,int node2,Material* mat)
}
//
-void btSoftBody::appendAnchor(int node,btRigidBody* body,bool disableCollisionWithBody=false)
+void btSoftBody::appendAnchor(int node,btRigidBody* body, bool disableCollisionBetweenLinkedBodies)
{
- if (disableCollisionWithBody)
+ if (disableCollisionBetweenLinkedBodies)
{
if (m_collisionDisabledObjects.findLinearSearch(body)==m_collisionDisabledObjects.size())
{
@@ -327,54 +327,54 @@ void btSoftBody::appendAnchor(int node,btRigidBody* body,bool disableCollision
//
void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1)
{
-LJoint* pj = new(btAlignedAlloc(sizeof(LJoint),16)) LJoint();
-pj->m_bodies[0] = body0;
-pj->m_bodies[1] = body1;
-pj->m_refs[0] = pj->m_bodies[0].xform().inverse()*specs.position;
-pj->m_refs[1] = pj->m_bodies[1].xform().inverse()*specs.position;
-pj->m_cfm = specs.cfm;
-pj->m_erp = specs.erp;
-pj->m_split = specs.split;
-m_joints.push_back(pj);
+ LJoint* pj = new(btAlignedAlloc(sizeof(LJoint),16)) LJoint();
+ pj->m_bodies[0] = body0;
+ pj->m_bodies[1] = body1;
+ pj->m_refs[0] = pj->m_bodies[0].xform().inverse()*specs.position;
+ pj->m_refs[1] = pj->m_bodies[1].xform().inverse()*specs.position;
+ pj->m_cfm = specs.cfm;
+ pj->m_erp = specs.erp;
+ pj->m_split = specs.split;
+ m_joints.push_back(pj);
}
//
void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,Body body)
{
-appendLinearJoint(specs,m_clusters[0],body);
+ appendLinearJoint(specs,m_clusters[0],body);
}
//
void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,btSoftBody* body)
{
-appendLinearJoint(specs,m_clusters[0],body->m_clusters[0]);
+ appendLinearJoint(specs,m_clusters[0],body->m_clusters[0]);
}
//
void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,Cluster* body0,Body body1)
{
-AJoint* pj = new(btAlignedAlloc(sizeof(AJoint),16)) AJoint();
-pj->m_bodies[0] = body0;
-pj->m_bodies[1] = body1;
-pj->m_refs[0] = pj->m_bodies[0].xform().inverse().getBasis()*specs.axis;
-pj->m_refs[1] = pj->m_bodies[1].xform().inverse().getBasis()*specs.axis;
-pj->m_cfm = specs.cfm;
-pj->m_erp = specs.erp;
-pj->m_split = specs.split;
-pj->m_icontrol = specs.icontrol;
-m_joints.push_back(pj);
+ AJoint* pj = new(btAlignedAlloc(sizeof(AJoint),16)) AJoint();
+ pj->m_bodies[0] = body0;
+ pj->m_bodies[1] = body1;
+ pj->m_refs[0] = pj->m_bodies[0].xform().inverse().getBasis()*specs.axis;
+ pj->m_refs[1] = pj->m_bodies[1].xform().inverse().getBasis()*specs.axis;
+ pj->m_cfm = specs.cfm;
+ pj->m_erp = specs.erp;
+ pj->m_split = specs.split;
+ pj->m_icontrol = specs.icontrol;
+ m_joints.push_back(pj);
}
//
void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,Body body)
{
-appendAngularJoint(specs,m_clusters[0],body);
+ appendAngularJoint(specs,m_clusters[0],body);
}
//
void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,btSoftBody* body)
{
-appendAngularJoint(specs,m_clusters[0],body->m_clusters[0]);
+ appendAngularJoint(specs,m_clusters[0],body->m_clusters[0]);
}
//
@@ -463,8 +463,8 @@ void btSoftBody::setTotalMass(btScalar mass,bool fromfaces)
{
const Face& f=m_faces[i];
const btScalar twicearea=AreaOf( f.m_n[0]->m_x,
- f.m_n[1]->m_x,
- f.m_n[2]->m_x);
+ f.m_n[1]->m_x,
+ f.m_n[2]->m_x);
for(int j=0;j<3;++j)
{
f.m_n[j]->m_im+=twicearea;
@@ -494,13 +494,17 @@ void btSoftBody::setTotalDensity(btScalar density)
void btSoftBody::transform(const btTransform& trs)
{
const btScalar margin=getCollisionShape()->getMargin();
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) vol;
+
for(int i=0,ni=m_nodes.size();i<ni;++i)
{
Node& n=m_nodes[i];
n.m_x=trs*n.m_x;
n.m_q=trs*n.m_q;
n.m_n=trs.getBasis()*n.m_n;
- m_ndbvt.update(n.m_leaf,btDbvtVolume::FromCR(n.m_x,margin));
+ vol = btDbvtVolume::FromCR(n.m_x,margin);
+
+ m_ndbvt.update(n.m_leaf,vol);
}
updateNormals();
updateBounds();
@@ -511,31 +515,34 @@ void btSoftBody::transform(const btTransform& trs)
//
void btSoftBody::translate(const btVector3& trs)
{
-btTransform t;
-t.setIdentity();
-t.setOrigin(trs);
-transform(t);
+ btTransform t;
+ t.setIdentity();
+ t.setOrigin(trs);
+ transform(t);
}
//
void btSoftBody::rotate( const btQuaternion& rot)
{
-btTransform t;
-t.setIdentity();
-t.setRotation(rot);
-transform(t);
+ btTransform t;
+ t.setIdentity();
+ t.setRotation(rot);
+ transform(t);
}
//
void btSoftBody::scale(const btVector3& scl)
{
const btScalar margin=getCollisionShape()->getMargin();
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) vol;
+
for(int i=0,ni=m_nodes.size();i<ni;++i)
{
Node& n=m_nodes[i];
n.m_x*=scl;
n.m_q*=scl;
- m_ndbvt.update(n.m_leaf,btDbvtVolume::FromCR(n.m_x,margin));
+ vol = btDbvtVolume::FromCR(n.m_x,margin);
+ m_ndbvt.update(n.m_leaf,vol);
}
updateNormals();
updateBounds();
@@ -562,8 +569,8 @@ void btSoftBody::setPose(bool bvolume,bool bframe)
{
Node& n=m_nodes[i];
m_pose.m_wgh[i]= n.m_im>0 ?
- 1/(m_nodes[i].m_im*tmass) :
- kmass/tmass;
+ 1/(m_nodes[i].m_im*tmass) :
+ kmass/tmass;
}
/* Pos */
const btVector3 com=evaluateCom();
@@ -578,16 +585,16 @@ void btSoftBody::setPose(bool bvolume,bool bframe)
m_pose.m_scl.setIdentity();
/* Aqq */
m_pose.m_aqq[0] =
- m_pose.m_aqq[1] =
- m_pose.m_aqq[2] = btVector3(0,0,0);
+ m_pose.m_aqq[1] =
+ m_pose.m_aqq[2] = btVector3(0,0,0);
for( i=0,ni=m_nodes.size();i<ni;++i)
- {
+ {
const btVector3& q=m_pose.m_pos[i];
const btVector3 mq=m_pose.m_wgh[i]*q;
m_pose.m_aqq[0]+=mq.x()*q;
m_pose.m_aqq[1]+=mq.y()*q;
m_pose.m_aqq[2]+=mq.z()*q;
- }
+ }
m_pose.m_aqq=m_pose.m_aqq.inverse();
updateConstants();
}
@@ -614,87 +621,87 @@ btScalar btSoftBody::getVolume() const
//
int btSoftBody::clusterCount() const
{
-return(m_clusters.size());
+ return(m_clusters.size());
}
//
btVector3 btSoftBody::clusterCom(const Cluster* cluster)
{
-btVector3 com(0,0,0);
-for(int i=0,ni=cluster->m_nodes.size();i<ni;++i)
+ btVector3 com(0,0,0);
+ for(int i=0,ni=cluster->m_nodes.size();i<ni;++i)
{
- com+=cluster->m_nodes[i]->m_x*cluster->m_masses[i];
+ com+=cluster->m_nodes[i]->m_x*cluster->m_masses[i];
}
-return(com*cluster->m_imass);
+ return(com*cluster->m_imass);
}
//
btVector3 btSoftBody::clusterCom(int cluster) const
{
-return(clusterCom(m_clusters[cluster]));
+ return(clusterCom(m_clusters[cluster]));
}
//
btVector3 btSoftBody::clusterVelocity(const Cluster* cluster,const btVector3& rpos)
{
-return(cluster->m_lv+cross(cluster->m_av,rpos));
+ return(cluster->m_lv+cross(cluster->m_av,rpos));
}
//
void btSoftBody::clusterVImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse)
{
-const btVector3 li=cluster->m_imass*impulse;
-const btVector3 ai=cluster->m_invwi*cross(rpos,impulse);
-cluster->m_vimpulses[0]+=li;cluster->m_lv+=li;
-cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai;
-cluster->m_nvimpulses++;
+ const btVector3 li=cluster->m_imass*impulse;
+ const btVector3 ai=cluster->m_invwi*cross(rpos,impulse);
+ cluster->m_vimpulses[0]+=li;cluster->m_lv+=li;
+ cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai;
+ cluster->m_nvimpulses++;
}
//
void btSoftBody::clusterDImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse)
{
-const btVector3 li=cluster->m_imass*impulse;
-const btVector3 ai=cluster->m_invwi*cross(rpos,impulse);
-cluster->m_dimpulses[0]+=li;
-cluster->m_dimpulses[1]+=ai;
-cluster->m_ndimpulses++;
+ const btVector3 li=cluster->m_imass*impulse;
+ const btVector3 ai=cluster->m_invwi*cross(rpos,impulse);
+ cluster->m_dimpulses[0]+=li;
+ cluster->m_dimpulses[1]+=ai;
+ cluster->m_ndimpulses++;
}
//
void btSoftBody::clusterImpulse(Cluster* cluster,const btVector3& rpos,const Impulse& impulse)
{
-if(impulse.m_asVelocity) clusterVImpulse(cluster,rpos,impulse.m_velocity);
-if(impulse.m_asDrift) clusterDImpulse(cluster,rpos,impulse.m_drift);
+ if(impulse.m_asVelocity) clusterVImpulse(cluster,rpos,impulse.m_velocity);
+ if(impulse.m_asDrift) clusterDImpulse(cluster,rpos,impulse.m_drift);
}
//
void btSoftBody::clusterVAImpulse(Cluster* cluster,const btVector3& impulse)
{
-const btVector3 ai=cluster->m_invwi*impulse;
-cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai;
-cluster->m_nvimpulses++;
+ const btVector3 ai=cluster->m_invwi*impulse;
+ cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai;
+ cluster->m_nvimpulses++;
}
//
void btSoftBody::clusterDAImpulse(Cluster* cluster,const btVector3& impulse)
{
-const btVector3 ai=cluster->m_invwi*impulse;
-cluster->m_dimpulses[1]+=ai;
-cluster->m_ndimpulses++;
+ const btVector3 ai=cluster->m_invwi*impulse;
+ cluster->m_dimpulses[1]+=ai;
+ cluster->m_ndimpulses++;
}
//
void btSoftBody::clusterAImpulse(Cluster* cluster,const Impulse& impulse)
{
-if(impulse.m_asVelocity) clusterVAImpulse(cluster,impulse.m_velocity);
-if(impulse.m_asDrift) clusterDAImpulse(cluster,impulse.m_drift);
+ if(impulse.m_asVelocity) clusterVAImpulse(cluster,impulse.m_velocity);
+ if(impulse.m_asDrift) clusterDAImpulse(cluster,impulse.m_drift);
}
//
void btSoftBody::clusterDCImpulse(Cluster* cluster,const btVector3& impulse)
{
-cluster->m_dimpulses[0]+=impulse*cluster->m_imass;
-cluster->m_ndimpulses++;
+ cluster->m_dimpulses[0]+=impulse*cluster->m_imass;
+ cluster->m_ndimpulses++;
}
//
@@ -762,9 +769,9 @@ int btSoftBody::generateBendingConstraints(int distance,Material* mat)
//
void btSoftBody::randomizeConstraints()
{
-unsigned long seed=243703;
+ unsigned long seed=243703;
#define NEXTRAND (seed=(1664525L*seed+1013904223L)&0xffffffff)
-int i,ni;
+ int i,ni;
for(i=0,ni=m_links.size();i<ni;++i)
{
@@ -780,493 +787,524 @@ int i,ni;
//
void btSoftBody::releaseCluster(int index)
{
-Cluster* c=m_clusters[index];
-if(c->m_leaf) m_cdbvt.remove(c->m_leaf);
-c->~Cluster();
-btAlignedFree(c);
-m_clusters.remove(c);
+ Cluster* c=m_clusters[index];
+ if(c->m_leaf) m_cdbvt.remove(c->m_leaf);
+ c->~Cluster();
+ btAlignedFree(c);
+ m_clusters.remove(c);
}
//
void btSoftBody::releaseClusters()
{
-while(m_clusters.size()>0) releaseCluster(0);
+ while(m_clusters.size()>0) releaseCluster(0);
}
//
int btSoftBody::generateClusters(int k,int maxiterations)
{
-int i;
-releaseClusters();
-m_clusters.resize(btMin(k,m_nodes.size()));
-for(i=0;i<m_clusters.size();++i)
- {
- m_clusters[i] = new(btAlignedAlloc(sizeof(Cluster),16)) Cluster();
- m_clusters[i]->m_collide= true;
- }
-k=m_clusters.size();
-if(k>0)
- {
- /* Initialize */
- btAlignedObjectArray<btVector3> centers;
- btVector3 cog(0,0,0);
- int i;
- for(i=0;i<m_nodes.size();++i)
- {
- cog+=m_nodes[i].m_x;
- m_clusters[(i*29873)%m_clusters.size()]->m_nodes.push_back(&m_nodes[i]);
- }
- cog/=(btScalar)m_nodes.size();
- centers.resize(k,cog);
- /* Iterate */
- const btScalar slope=16;
- bool changed;
- int iterations=0;
- do {
- const btScalar w=2-btMin<btScalar>(1,iterations/slope);
- changed=false;
- iterations++;
- int i;
-
- for(i=0;i<k;++i)
+ int i;
+ releaseClusters();
+ m_clusters.resize(btMin(k,m_nodes.size()));
+ for(i=0;i<m_clusters.size();++i)
+ {
+ m_clusters[i] = new(btAlignedAlloc(sizeof(Cluster),16)) Cluster();
+ m_clusters[i]->m_collide= true;
+ }
+ k=m_clusters.size();
+ if(k>0)
+ {
+ /* Initialize */
+ btAlignedObjectArray<btVector3> centers;
+ btVector3 cog(0,0,0);
+ int i;
+ for(i=0;i<m_nodes.size();++i)
+ {
+ cog+=m_nodes[i].m_x;
+ m_clusters[(i*29873)%m_clusters.size()]->m_nodes.push_back(&m_nodes[i]);
+ }
+ cog/=(btScalar)m_nodes.size();
+ centers.resize(k,cog);
+ /* Iterate */
+ const btScalar slope=16;
+ bool changed;
+ int iterations=0;
+ do {
+ const btScalar w=2-btMin<btScalar>(1,iterations/slope);
+ changed=false;
+ iterations++;
+ int i;
+
+ for(i=0;i<k;++i)
{
- btVector3 c(0,0,0);
- for(int j=0;j<m_clusters[i]->m_nodes.size();++j)
+ btVector3 c(0,0,0);
+ for(int j=0;j<m_clusters[i]->m_nodes.size();++j)
{
- c+=m_clusters[i]->m_nodes[j]->m_x;
+ c+=m_clusters[i]->m_nodes[j]->m_x;
}
- if(m_clusters[i]->m_nodes.size())
+ if(m_clusters[i]->m_nodes.size())
{
- c /= (btScalar)m_clusters[i]->m_nodes.size();
- c = centers[i]+(c-centers[i])*w;
- changed |= ((c-centers[i]).length2()>SIMD_EPSILON);
- centers[i] = c;
- m_clusters[i]->m_nodes.resize(0);
+ c /= (btScalar)m_clusters[i]->m_nodes.size();
+ c = centers[i]+(c-centers[i])*w;
+ changed |= ((c-centers[i]).length2()>SIMD_EPSILON);
+ centers[i] = c;
+ m_clusters[i]->m_nodes.resize(0);
}
}
- for(i=0;i<m_nodes.size();++i)
+ for(i=0;i<m_nodes.size();++i)
{
- const btVector3 nx=m_nodes[i].m_x;
- int kbest=0;
- btScalar kdist=ClusterMetric(centers[0],nx);
- for(int j=1;j<k;++j)
+ const btVector3 nx=m_nodes[i].m_x;
+ int kbest=0;
+ btScalar kdist=ClusterMetric(centers[0],nx);
+ for(int j=1;j<k;++j)
{
- const btScalar d=ClusterMetric(centers[j],nx);
- if(d<kdist)
+ const btScalar d=ClusterMetric(centers[j],nx);
+ if(d<kdist)
{
- kbest=j;
- kdist=d;
+ kbest=j;
+ kdist=d;
}
}
- m_clusters[kbest]->m_nodes.push_back(&m_nodes[i]);
+ m_clusters[kbest]->m_nodes.push_back(&m_nodes[i]);
}
} while(changed&&(iterations<maxiterations));
- /* Merge */
- btAlignedObjectArray<int> cids;
- cids.resize(m_nodes.size(),-1);
- for(i=0;i<m_clusters.size();++i)
+ /* Merge */
+ btAlignedObjectArray<int> cids;
+ cids.resize(m_nodes.size(),-1);
+ for(i=0;i<m_clusters.size();++i)
{
- for(int j=0;j<m_clusters[i]->m_nodes.size();++j)
+ for(int j=0;j<m_clusters[i]->m_nodes.size();++j)
{
- cids[int(m_clusters[i]->m_nodes[j]-&m_nodes[0])]=i;
+ cids[int(m_clusters[i]->m_nodes[j]-&m_nodes[0])]=i;
}
}
- for(i=0;i<m_faces.size();++i)
+ for(i=0;i<m_faces.size();++i)
{
- const int idx[]={ int(m_faces[i].m_n[0]-&m_nodes[0]),
- int(m_faces[i].m_n[1]-&m_nodes[0]),
- int(m_faces[i].m_n[2]-&m_nodes[0])};
- for(int j=0;j<3;++j)
+ const int idx[]={ int(m_faces[i].m_n[0]-&m_nodes[0]),
+ int(m_faces[i].m_n[1]-&m_nodes[0]),
+ int(m_faces[i].m_n[2]-&m_nodes[0])};
+ for(int j=0;j<3;++j)
{
- const int cid=cids[idx[j]];
- for(int q=1;q<3;++q)
+ const int cid=cids[idx[j]];
+ for(int q=1;q<3;++q)
{
- const int kid=idx[(j+q)%3];
- if(cids[kid]!=cid)
+ const int kid=idx[(j+q)%3];
+ if(cids[kid]!=cid)
{
- if(m_clusters[cid]->m_nodes.findLinearSearch(&m_nodes[kid])==m_clusters[cid]->m_nodes.size())
+ if(m_clusters[cid]->m_nodes.findLinearSearch(&m_nodes[kid])==m_clusters[cid]->m_nodes.size())
{
- m_clusters[cid]->m_nodes.push_back(&m_nodes[kid]);
+ m_clusters[cid]->m_nodes.push_back(&m_nodes[kid]);
}
}
}
}
}
- /* Master */
- if(m_clusters.size()>1)
+ /* Master */
+ if(m_clusters.size()>1)
{
- Cluster* pmaster=new(btAlignedAlloc(sizeof(Cluster),16)) Cluster();
- pmaster->m_collide = false;
- pmaster->m_nodes.reserve(m_nodes.size());
- for(int i=0;i<m_nodes.size();++i) pmaster->m_nodes.push_back(&m_nodes[i]);
- m_clusters.push_back(pmaster);
- btSwap(m_clusters[0],m_clusters[m_clusters.size()-1]);
+ Cluster* pmaster=new(btAlignedAlloc(sizeof(Cluster),16)) Cluster();
+ pmaster->m_collide = false;
+ pmaster->m_nodes.reserve(m_nodes.size());
+ for(int i=0;i<m_nodes.size();++i) pmaster->m_nodes.push_back(&m_nodes[i]);
+ m_clusters.push_back(pmaster);
+ btSwap(m_clusters[0],m_clusters[m_clusters.size()-1]);
}
- /* Terminate */
- for(i=0;i<m_clusters.size();++i)
+ /* Terminate */
+ for(i=0;i<m_clusters.size();++i)
{
- if(m_clusters[i]->m_nodes.size()==0)
+ if(m_clusters[i]->m_nodes.size()==0)
{
- releaseCluster(i--);
+ releaseCluster(i--);
}
}
-
- initializeClusters();
- updateClusters();
- return(m_clusters.size());
+
+ initializeClusters();
+ updateClusters();
+
+ //for self-collision
+ m_clusterConnectivity.resize(m_clusters.size()*m_clusters.size());
+ {
+ for (int c0=0;c0<m_clusters.size();c0++)
+ {
+ m_clusters[c0]->m_clusterIndex=c0;
+ for (int c1=0;c1<m_clusters.size();c1++)
+ {
+
+ bool connected=false;
+ Cluster* cla = m_clusters[c0];
+ Cluster* clb = m_clusters[c1];
+ for (int i=0;!connected&&i<cla->m_nodes.size();i++)
+ {
+ for (int j=0;j<clb->m_nodes.size();j++)
+ {
+ if (cla->m_nodes[i] == clb->m_nodes[j])
+ {
+ connected=true;
+ break;
+ }
+ }
+ }
+ m_clusterConnectivity[c0+c1*m_clusters.size()]=connected;
+ }
+ }
+ }
+
+ return(m_clusters.size());
}
-return(0);
+ return(0);
}
//
void btSoftBody::refine(ImplicitFn* ifn,btScalar accurary,bool cut)
{
-const Node* nbase = &m_nodes[0];
-int ncount = m_nodes.size();
-btSymMatrix<int> edges(ncount,-2);
-int newnodes=0;
-int i,j,k,ni;
+ const Node* nbase = &m_nodes[0];
+ int ncount = m_nodes.size();
+ btSymMatrix<int> edges(ncount,-2);
+ int newnodes=0;
+ int i,j,k,ni;
-/* Filter out */
-for(i=0;i<m_links.size();++i)
+ /* Filter out */
+ for(i=0;i<m_links.size();++i)
{
- Link& l=m_links[i];
- if(l.m_bbending)
+ Link& l=m_links[i];
+ if(l.m_bbending)
{
- if(!SameSign(ifn->Eval(l.m_n[0]->m_x),ifn->Eval(l.m_n[1]->m_x)))
+ if(!SameSign(ifn->Eval(l.m_n[0]->m_x),ifn->Eval(l.m_n[1]->m_x)))
{
- btSwap(m_links[i],m_links[m_links.size()-1]);
- m_links.pop_back();--i;
+ btSwap(m_links[i],m_links[m_links.size()-1]);
+ m_links.pop_back();--i;
}
}
}
-/* Fill edges */
-for(i=0;i<m_links.size();++i)
+ /* Fill edges */
+ for(i=0;i<m_links.size();++i)
{
- Link& l=m_links[i];
- edges(int(l.m_n[0]-nbase),int(l.m_n[1]-nbase))=-1;
+ Link& l=m_links[i];
+ edges(int(l.m_n[0]-nbase),int(l.m_n[1]-nbase))=-1;
}
-for(i=0;i<m_faces.size();++i)
+ for(i=0;i<m_faces.size();++i)
{
- Face& f=m_faces[i];
- edges(int(f.m_n[0]-nbase),int(f.m_n[1]-nbase))=-1;
- edges(int(f.m_n[1]-nbase),int(f.m_n[2]-nbase))=-1;
- edges(int(f.m_n[2]-nbase),int(f.m_n[0]-nbase))=-1;
+ Face& f=m_faces[i];
+ edges(int(f.m_n[0]-nbase),int(f.m_n[1]-nbase))=-1;
+ edges(int(f.m_n[1]-nbase),int(f.m_n[2]-nbase))=-1;
+ edges(int(f.m_n[2]-nbase),int(f.m_n[0]-nbase))=-1;
}
-/* Intersect */
-for(i=0;i<ncount;++i)
+ /* Intersect */
+ for(i=0;i<ncount;++i)
{
- for(j=i+1;j<ncount;++j)
+ for(j=i+1;j<ncount;++j)
{
- if(edges(i,j)==-1)
+ if(edges(i,j)==-1)
{
- Node& a=m_nodes[i];
- Node& b=m_nodes[j];
- const btScalar t=ImplicitSolve(ifn,a.m_x,b.m_x,accurary);
- if(t>0)
+ Node& a=m_nodes[i];
+ Node& b=m_nodes[j];
+ const btScalar t=ImplicitSolve(ifn,a.m_x,b.m_x,accurary);
+ if(t>0)
{
- const btVector3 x=Lerp(a.m_x,b.m_x,t);
- const btVector3 v=Lerp(a.m_v,b.m_v,t);
- btScalar m=0;
- if(a.m_im>0)
+ const btVector3 x=Lerp(a.m_x,b.m_x,t);
+ const btVector3 v=Lerp(a.m_v,b.m_v,t);
+ btScalar m=0;
+ if(a.m_im>0)
{
- if(b.m_im>0)
+ if(b.m_im>0)
{
- const btScalar ma=1/a.m_im;
- const btScalar mb=1/b.m_im;
- const btScalar mc=Lerp(ma,mb,t);
- const btScalar f=(ma+mb)/(ma+mb+mc);
- a.m_im=1/(ma*f);
- b.m_im=1/(mb*f);
- m=mc*f;
+ const btScalar ma=1/a.m_im;
+ const btScalar mb=1/b.m_im;
+ const btScalar mc=Lerp(ma,mb,t);
+ const btScalar f=(ma+mb)/(ma+mb+mc);
+ a.m_im=1/(ma*f);
+ b.m_im=1/(mb*f);
+ m=mc*f;
}
else
{ a.m_im/=0.5;m=1/a.m_im; }
}
else
{
- if(b.m_im>0)
+ if(b.m_im>0)
{ b.m_im/=0.5;m=1/b.m_im; }
else
- m=0;
+ m=0;
}
- appendNode(x,m);
- edges(i,j)=m_nodes.size()-1;
- m_nodes[edges(i,j)].m_v=v;
- ++newnodes;
+ appendNode(x,m);
+ edges(i,j)=m_nodes.size()-1;
+ m_nodes[edges(i,j)].m_v=v;
+ ++newnodes;
}
}
}
}
-nbase=&m_nodes[0];
-/* Refine links */
-for(i=0,ni=m_links.size();i<ni;++i)
+ nbase=&m_nodes[0];
+ /* Refine links */
+ for(i=0,ni=m_links.size();i<ni;++i)
{
- Link& feat=m_links[i];
- const int idx[]={ int(feat.m_n[0]-nbase),
- int(feat.m_n[1]-nbase)};
- if((idx[0]<ncount)&&(idx[1]<ncount))
+ Link& feat=m_links[i];
+ const int idx[]={ int(feat.m_n[0]-nbase),
+ int(feat.m_n[1]-nbase)};
+ if((idx[0]<ncount)&&(idx[1]<ncount))
{
- const int ni=edges(idx[0],idx[1]);
- if(ni>0)
+ const int ni=edges(idx[0],idx[1]);
+ if(ni>0)
{
- appendLink(i);
- Link* pft[]={ &m_links[i],
- &m_links[m_links.size()-1]};
- pft[0]->m_n[0]=&m_nodes[idx[0]];
- pft[0]->m_n[1]=&m_nodes[ni];
- pft[1]->m_n[0]=&m_nodes[ni];
- pft[1]->m_n[1]=&m_nodes[idx[1]];
+ appendLink(i);
+ Link* pft[]={ &m_links[i],
+ &m_links[m_links.size()-1]};
+ pft[0]->m_n[0]=&m_nodes[idx[0]];
+ pft[0]->m_n[1]=&m_nodes[ni];
+ pft[1]->m_n[0]=&m_nodes[ni];
+ pft[1]->m_n[1]=&m_nodes[idx[1]];
}
}
}
-/* Refine faces */
-for(i=0;i<m_faces.size();++i)
+ /* Refine faces */
+ for(i=0;i<m_faces.size();++i)
{
- const Face& feat=m_faces[i];
- const int idx[]={ int(feat.m_n[0]-nbase),
- int(feat.m_n[1]-nbase),
- int(feat.m_n[2]-nbase)};
- for(j=2,k=0;k<3;j=k++)
+ const Face& feat=m_faces[i];
+ const int idx[]={ int(feat.m_n[0]-nbase),
+ int(feat.m_n[1]-nbase),
+ int(feat.m_n[2]-nbase)};
+ for(j=2,k=0;k<3;j=k++)
{
- if((idx[j]<ncount)&&(idx[k]<ncount))
+ if((idx[j]<ncount)&&(idx[k]<ncount))
{
- const int ni=edges(idx[j],idx[k]);
- if(ni>0)
+ const int ni=edges(idx[j],idx[k]);
+ if(ni>0)
{
- appendFace(i);
- const int l=(k+1)%3;
- Face* pft[]={ &m_faces[i],
- &m_faces[m_faces.size()-1]};
- pft[0]->m_n[0]=&m_nodes[idx[l]];
- pft[0]->m_n[1]=&m_nodes[idx[j]];
- pft[0]->m_n[2]=&m_nodes[ni];
- pft[1]->m_n[0]=&m_nodes[ni];
- pft[1]->m_n[1]=&m_nodes[idx[k]];
- pft[1]->m_n[2]=&m_nodes[idx[l]];
- appendLink(ni,idx[l],pft[0]->m_material);
- --i;break;
+ appendFace(i);
+ const int l=(k+1)%3;
+ Face* pft[]={ &m_faces[i],
+ &m_faces[m_faces.size()-1]};
+ pft[0]->m_n[0]=&m_nodes[idx[l]];
+ pft[0]->m_n[1]=&m_nodes[idx[j]];
+ pft[0]->m_n[2]=&m_nodes[ni];
+ pft[1]->m_n[0]=&m_nodes[ni];
+ pft[1]->m_n[1]=&m_nodes[idx[k]];
+ pft[1]->m_n[2]=&m_nodes[idx[l]];
+ appendLink(ni,idx[l],pft[0]->m_material);
+ --i;break;
}
}
}
}
-/* Cut */
-if(cut)
+ /* Cut */
+ if(cut)
{
- btAlignedObjectArray<int> cnodes;
- const int pcount=ncount;
- int i;
- ncount=m_nodes.size();
- cnodes.resize(ncount,0);
- /* Nodes */
- for(i=0;i<ncount;++i)
- {
- const btVector3 x=m_nodes[i].m_x;
- if((i>=pcount)||(btFabs(ifn->Eval(x))<accurary))
+ btAlignedObjectArray<int> cnodes;
+ const int pcount=ncount;
+ int i;
+ ncount=m_nodes.size();
+ cnodes.resize(ncount,0);
+ /* Nodes */
+ for(i=0;i<ncount;++i)
+ {
+ const btVector3 x=m_nodes[i].m_x;
+ if((i>=pcount)||(btFabs(ifn->Eval(x))<accurary))
{
- const btVector3 v=m_nodes[i].m_v;
- btScalar m=getMass(i);
- if(m>0) { m*=0.5;m_nodes[i].m_im/=0.5; }
- appendNode(x,m);
- cnodes[i]=m_nodes.size()-1;
- m_nodes[cnodes[i]].m_v=v;
+ const btVector3 v=m_nodes[i].m_v;
+ btScalar m=getMass(i);
+ if(m>0) { m*=0.5;m_nodes[i].m_im/=0.5; }
+ appendNode(x,m);
+ cnodes[i]=m_nodes.size()-1;
+ m_nodes[cnodes[i]].m_v=v;
}
}
- nbase=&m_nodes[0];
- /* Links */
- for(i=0,ni=m_links.size();i<ni;++i)
+ nbase=&m_nodes[0];
+ /* Links */
+ for(i=0,ni=m_links.size();i<ni;++i)
{
- const int id[]={ int(m_links[i].m_n[0]-nbase),
- int(m_links[i].m_n[1]-nbase)};
- int todetach=0;
- if(cnodes[id[0]]&&cnodes[id[1]])
+ const int id[]={ int(m_links[i].m_n[0]-nbase),
+ int(m_links[i].m_n[1]-nbase)};
+ int todetach=0;
+ if(cnodes[id[0]]&&cnodes[id[1]])
{
- appendLink(i);
- todetach=m_links.size()-1;
+ appendLink(i);
+ todetach=m_links.size()-1;
}
- else
+ else
{
- if(( (ifn->Eval(m_nodes[id[0]].m_x)<accurary)&&
+ if(( (ifn->Eval(m_nodes[id[0]].m_x)<accurary)&&
(ifn->Eval(m_nodes[id[1]].m_x)<accurary)))
- todetach=i;
+ todetach=i;
}
- if(todetach)
+ if(todetach)
{
- Link& l=m_links[todetach];
- for(int j=0;j<2;++j)
+ Link& l=m_links[todetach];
+ for(int j=0;j<2;++j)
{
- int cn=cnodes[int(l.m_n[j]-nbase)];
- if(cn) l.m_n[j]=&m_nodes[cn];
+ int cn=cnodes[int(l.m_n[j]-nbase)];
+ if(cn) l.m_n[j]=&m_nodes[cn];
}
}
}
- /* Faces */
- for(i=0,ni=m_faces.size();i<ni;++i)
+ /* Faces */
+ for(i=0,ni=m_faces.size();i<ni;++i)
{
- Node** n= m_faces[i].m_n;
- if( (ifn->Eval(n[0]->m_x)<accurary)&&
- (ifn->Eval(n[1]->m_x)<accurary)&&
- (ifn->Eval(n[2]->m_x)<accurary))
+ Node** n= m_faces[i].m_n;
+ if( (ifn->Eval(n[0]->m_x)<accurary)&&
+ (ifn->Eval(n[1]->m_x)<accurary)&&
+ (ifn->Eval(n[2]->m_x)<accurary))
{
- for(int j=0;j<3;++j)
+ for(int j=0;j<3;++j)
{
- int cn=cnodes[int(n[j]-nbase)];
- if(cn) n[j]=&m_nodes[cn];
+ int cn=cnodes[int(n[j]-nbase)];
+ if(cn) n[j]=&m_nodes[cn];
}
}
}
- /* Clean orphans */
- int nnodes=m_nodes.size();
- btAlignedObjectArray<int> ranks;
- btAlignedObjectArray<int> todelete;
- ranks.resize(nnodes,0);
- for(i=0,ni=m_links.size();i<ni;++i)
+ /* Clean orphans */
+ int nnodes=m_nodes.size();
+ btAlignedObjectArray<int> ranks;
+ btAlignedObjectArray<int> todelete;
+ ranks.resize(nnodes,0);
+ for(i=0,ni=m_links.size();i<ni;++i)
{
- for(int j=0;j<2;++j) ranks[int(m_links[i].m_n[j]-nbase)]++;
+ for(int j=0;j<2;++j) ranks[int(m_links[i].m_n[j]-nbase)]++;
}
- for(i=0,ni=m_faces.size();i<ni;++i)
+ for(i=0,ni=m_faces.size();i<ni;++i)
{
- for(int j=0;j<3;++j) ranks[int(m_faces[i].m_n[j]-nbase)]++;
+ for(int j=0;j<3;++j) ranks[int(m_faces[i].m_n[j]-nbase)]++;
}
- for(i=0;i<m_links.size();++i)
+ for(i=0;i<m_links.size();++i)
{
- const int id[]={ int(m_links[i].m_n[0]-nbase),
- int(m_links[i].m_n[1]-nbase)};
- const bool sg[]={ ranks[id[0]]==1,
- ranks[id[1]]==1};
- if(sg[0]||sg[1])
+ const int id[]={ int(m_links[i].m_n[0]-nbase),
+ int(m_links[i].m_n[1]-nbase)};
+ const bool sg[]={ ranks[id[0]]==1,
+ ranks[id[1]]==1};
+ if(sg[0]||sg[1])
{
- --ranks[id[0]];
- --ranks[id[1]];
- btSwap(m_links[i],m_links[m_links.size()-1]);
- m_links.pop_back();--i;
+ --ranks[id[0]];
+ --ranks[id[1]];
+ btSwap(m_links[i],m_links[m_links.size()-1]);
+ m_links.pop_back();--i;
}
}
- #if 0
- for(i=nnodes-1;i>=0;--i)
+#if 0
+ for(i=nnodes-1;i>=0;--i)
{
- if(!ranks[i]) todelete.push_back(i);
+ if(!ranks[i]) todelete.push_back(i);
}
- if(todelete.size())
+ if(todelete.size())
{
- btAlignedObjectArray<int>& map=ranks;
- for(int i=0;i<nnodes;++i) map[i]=i;
- PointersToIndices(this);
- for(int i=0,ni=todelete.size();i<ni;++i)
+ btAlignedObjectArray<int>& map=ranks;
+ for(int i=0;i<nnodes;++i) map[i]=i;
+ PointersToIndices(this);
+ for(int i=0,ni=todelete.size();i<ni;++i)
{
- int j=todelete[i];
- int& a=map[j];
- int& b=map[--nnodes];
- m_ndbvt.remove(m_nodes[a].m_leaf);m_nodes[a].m_leaf=0;
- btSwap(m_nodes[a],m_nodes[b]);
- j=a;a=b;b=j;
+ int j=todelete[i];
+ int& a=map[j];
+ int& b=map[--nnodes];
+ m_ndbvt.remove(m_nodes[a].m_leaf);m_nodes[a].m_leaf=0;
+ btSwap(m_nodes[a],m_nodes[b]);
+ j=a;a=b;b=j;
}
- IndicesToPointers(this,&map[0]);
- m_nodes.resize(nnodes);
+ IndicesToPointers(this,&map[0]);
+ m_nodes.resize(nnodes);
}
- #endif
+#endif
}
-m_bUpdateRtCst=true;
+ m_bUpdateRtCst=true;
}
//
bool btSoftBody::cutLink(const Node* node0,const Node* node1,btScalar position)
{
-return(cutLink(int(node0-&m_nodes[0]),int(node1-&m_nodes[0]),position));
+ return(cutLink(int(node0-&m_nodes[0]),int(node1-&m_nodes[0]),position));
}
//
bool btSoftBody::cutLink(int node0,int node1,btScalar position)
{
-bool done=false;
-int i,ni;
-const btVector3 d=m_nodes[node0].m_x-m_nodes[node1].m_x;
-const btVector3 x=Lerp(m_nodes[node0].m_x,m_nodes[node1].m_x,position);
-const btVector3 v=Lerp(m_nodes[node0].m_v,m_nodes[node1].m_v,position);
-const btScalar m=1;
-appendNode(x,m);
-appendNode(x,m);
-Node* pa=&m_nodes[node0];
-Node* pb=&m_nodes[node1];
-Node* pn[2]={ &m_nodes[m_nodes.size()-2],
- &m_nodes[m_nodes.size()-1]};
-pn[0]->m_v=v;
-pn[1]->m_v=v;
-for(i=0,ni=m_links.size();i<ni;++i)
- {
- const int mtch=MatchEdge(m_links[i].m_n[0],m_links[i].m_n[1],pa,pb);
- if(mtch!=-1)
- {
- appendLink(i);
- Link* pft[]={&m_links[i],&m_links[m_links.size()-1]};
- pft[0]->m_n[1]=pn[mtch];
- pft[1]->m_n[0]=pn[1-mtch];
- done=true;
- }
- }
-for(i=0,ni=m_faces.size();i<ni;++i)
- {
- for(int k=2,l=0;l<3;k=l++)
- {
- const int mtch=MatchEdge(m_faces[i].m_n[k],m_faces[i].m_n[l],pa,pb);
+ bool done=false;
+ int i,ni;
+ const btVector3 d=m_nodes[node0].m_x-m_nodes[node1].m_x;
+ const btVector3 x=Lerp(m_nodes[node0].m_x,m_nodes[node1].m_x,position);
+ const btVector3 v=Lerp(m_nodes[node0].m_v,m_nodes[node1].m_v,position);
+ const btScalar m=1;
+ appendNode(x,m);
+ appendNode(x,m);
+ Node* pa=&m_nodes[node0];
+ Node* pb=&m_nodes[node1];
+ Node* pn[2]={ &m_nodes[m_nodes.size()-2],
+ &m_nodes[m_nodes.size()-1]};
+ pn[0]->m_v=v;
+ pn[1]->m_v=v;
+ for(i=0,ni=m_links.size();i<ni;++i)
+ {
+ const int mtch=MatchEdge(m_links[i].m_n[0],m_links[i].m_n[1],pa,pb);
if(mtch!=-1)
+ {
+ appendLink(i);
+ Link* pft[]={&m_links[i],&m_links[m_links.size()-1]};
+ pft[0]->m_n[1]=pn[mtch];
+ pft[1]->m_n[0]=pn[1-mtch];
+ done=true;
+ }
+ }
+ for(i=0,ni=m_faces.size();i<ni;++i)
+ {
+ for(int k=2,l=0;l<3;k=l++)
+ {
+ const int mtch=MatchEdge(m_faces[i].m_n[k],m_faces[i].m_n[l],pa,pb);
+ if(mtch!=-1)
{
- appendFace(i);
- Face* pft[]={&m_faces[i],&m_faces[m_faces.size()-1]};
- pft[0]->m_n[l]=pn[mtch];
- pft[1]->m_n[k]=pn[1-mtch];
- appendLink(pn[0],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true);
- appendLink(pn[1],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true);
+ appendFace(i);
+ Face* pft[]={&m_faces[i],&m_faces[m_faces.size()-1]};
+ pft[0]->m_n[l]=pn[mtch];
+ pft[1]->m_n[k]=pn[1-mtch];
+ appendLink(pn[0],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true);
+ appendLink(pn[1],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true);
}
}
}
-if(!done)
+ if(!done)
{
- m_ndbvt.remove(pn[0]->m_leaf);
- m_ndbvt.remove(pn[1]->m_leaf);
- m_nodes.pop_back();
- m_nodes.pop_back();
+ m_ndbvt.remove(pn[0]->m_leaf);
+ m_ndbvt.remove(pn[1]->m_leaf);
+ m_nodes.pop_back();
+ m_nodes.pop_back();
}
-return(done);
+ return(done);
}
//
-bool btSoftBody::rayCast(const btVector3& org,
- const btVector3& dir,
- sRayCast& results,
- btScalar maxtime)
+bool btSoftBody::rayTest(const btVector3& rayFrom,
+ const btVector3& rayTo,
+ sRayCast& results)
{
-if(m_faces.size()&&m_fdbvt.empty()) initializeFaceTree();
-results.body = this;
-results.time = maxtime;
-results.feature = eFeature::None;
-results.index = -1;
-return(rayCast(org,dir,results.time,results.feature,results.index,false)!=0);
+ if(m_faces.size()&&m_fdbvt.empty())
+ initializeFaceTree();
+
+ results.body = this;
+ results.fraction = 1.f;
+ results.feature = eFeature::None;
+ results.index = -1;
+
+ return(rayTest(rayFrom,rayTo,results.fraction,results.feature,results.index,false)!=0);
}
//
void btSoftBody::setSolver(eSolverPresets::_ preset)
{
-m_cfg.m_vsequence.clear();
-m_cfg.m_psequence.clear();
-m_cfg.m_dsequence.clear();
-switch(preset)
+ m_cfg.m_vsequence.clear();
+ m_cfg.m_psequence.clear();
+ m_cfg.m_dsequence.clear();
+ switch(preset)
{
case eSolverPresets::Positions:
- m_cfg.m_psequence.push_back(ePSolver::Anchors);
- m_cfg.m_psequence.push_back(ePSolver::RContacts);
- m_cfg.m_psequence.push_back(ePSolver::SContacts);
- m_cfg.m_psequence.push_back(ePSolver::Linear);
- break;
+ m_cfg.m_psequence.push_back(ePSolver::Anchors);
+ m_cfg.m_psequence.push_back(ePSolver::RContacts);
+ m_cfg.m_psequence.push_back(ePSolver::SContacts);
+ m_cfg.m_psequence.push_back(ePSolver::Linear);
+ break;
case eSolverPresets::Velocities:
- m_cfg.m_vsequence.push_back(eVSolver::Linear);
-
- m_cfg.m_psequence.push_back(ePSolver::Anchors);
- m_cfg.m_psequence.push_back(ePSolver::RContacts);
- m_cfg.m_psequence.push_back(ePSolver::SContacts);
-
- m_cfg.m_dsequence.push_back(ePSolver::Linear);
- break;
+ m_cfg.m_vsequence.push_back(eVSolver::Linear);
+
+ m_cfg.m_psequence.push_back(ePSolver::Anchors);
+ m_cfg.m_psequence.push_back(ePSolver::RContacts);
+ m_cfg.m_psequence.push_back(ePSolver::SContacts);
+
+ m_cfg.m_dsequence.push_back(ePSolver::Linear);
+ break;
}
}
@@ -1282,11 +1320,11 @@ void btSoftBody::predictMotion(btScalar dt)
updateConstants();
m_fdbvt.clear();
if(m_cfg.collisions&fCollision::VF_SS)
- {
+ {
initializeFaceTree();
- }
+ }
}
-
+
/* Prepare */
m_sst.sdt = dt*m_cfg.timescale;
m_sst.isdt = 1/m_sst.sdt;
@@ -1310,45 +1348,48 @@ void btSoftBody::predictMotion(btScalar dt)
/* Bounds */
updateBounds();
/* Nodes */
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) vol;
for(i=0,ni=m_nodes.size();i<ni;++i)
{
Node& n=m_nodes[i];
+ vol = btDbvtVolume::FromCR(n.m_x,m_sst.radmrg);
m_ndbvt.update( n.m_leaf,
- btDbvtVolume::FromCR(n.m_x,m_sst.radmrg),
- n.m_v*m_sst.velmrg,
- m_sst.updmrg);
+ vol,
+ n.m_v*m_sst.velmrg,
+ m_sst.updmrg);
}
/* Faces */
if(!m_fdbvt.empty())
- {
+ {
for(int i=0;i<m_faces.size();++i)
- {
+ {
Face& f=m_faces[i];
const btVector3 v=( f.m_n[0]->m_v+
- f.m_n[1]->m_v+
- f.m_n[2]->m_v)/3;
+ f.m_n[1]->m_v+
+ f.m_n[2]->m_v)/3;
+ vol = VolumeOf(f,m_sst.radmrg);
m_fdbvt.update( f.m_leaf,
- VolumeOf(f,m_sst.radmrg),
- v*m_sst.velmrg,
- m_sst.updmrg);
- }
+ vol,
+ v*m_sst.velmrg,
+ m_sst.updmrg);
}
+ }
/* Pose */
updatePose();
/* Match */
if(m_pose.m_bframe&&(m_cfg.kMT>0))
- {
+ {
const btMatrix3x3 posetrs=m_pose.m_rot;
for(int i=0,ni=m_nodes.size();i<ni;++i)
- {
+ {
Node& n=m_nodes[i];
if(n.m_im>0)
- {
+ {
const btVector3 x=posetrs*m_pose.m_pos[i]+m_pose.m_com;
n.m_x=Lerp(n.m_x,x,m_cfg.kMT);
- }
}
}
+ }
/* Clear contacts */
m_rcontacts.resize(0);
m_scontacts.resize(0);
@@ -1361,104 +1402,104 @@ void btSoftBody::predictMotion(btScalar dt)
//
void btSoftBody::solveConstraints()
{
-/* Apply clusters */
-applyClusters(false);
-/* Prepare links */
+ /* Apply clusters */
+ applyClusters(false);
+ /* Prepare links */
-int i,ni;
+ int i,ni;
-for(i=0,ni=m_links.size();i<ni;++i)
+ for(i=0,ni=m_links.size();i<ni;++i)
{
- Link& l=m_links[i];
- l.m_c3 = l.m_n[1]->m_q-l.m_n[0]->m_q;
- l.m_c2 = 1/(l.m_c3.length2()*l.m_c0);
+ Link& l=m_links[i];
+ l.m_c3 = l.m_n[1]->m_q-l.m_n[0]->m_q;
+ l.m_c2 = 1/(l.m_c3.length2()*l.m_c0);
}
-/* Prepare anchors */
-for(i=0,ni=m_anchors.size();i<ni;++i)
+ /* Prepare anchors */
+ for(i=0,ni=m_anchors.size();i<ni;++i)
{
- Anchor& a=m_anchors[i];
- const btVector3 ra=a.m_body->getWorldTransform().getBasis()*a.m_local;
- a.m_c0 = ImpulseMatrix( m_sst.sdt,
- a.m_node->m_im,
- a.m_body->getInvMass(),
- a.m_body->getInvInertiaTensorWorld(),
- ra);
- a.m_c1 = ra;
- a.m_c2 = m_sst.sdt*a.m_node->m_im;
- a.m_body->activate();
+ Anchor& a=m_anchors[i];
+ const btVector3 ra=a.m_body->getWorldTransform().getBasis()*a.m_local;
+ a.m_c0 = ImpulseMatrix( m_sst.sdt,
+ a.m_node->m_im,
+ a.m_body->getInvMass(),
+ a.m_body->getInvInertiaTensorWorld(),
+ ra);
+ a.m_c1 = ra;
+ a.m_c2 = m_sst.sdt*a.m_node->m_im;
+ a.m_body->activate();
}
-/* Solve velocities */
-if(m_cfg.viterations>0)
+ /* Solve velocities */
+ if(m_cfg.viterations>0)
{
- /* Solve */
- for(int isolve=0;isolve<m_cfg.viterations;++isolve)
+ /* Solve */
+ for(int isolve=0;isolve<m_cfg.viterations;++isolve)
{
- for(int iseq=0;iseq<m_cfg.m_vsequence.size();++iseq)
+ for(int iseq=0;iseq<m_cfg.m_vsequence.size();++iseq)
{
- getSolver(m_cfg.m_vsequence[iseq])(this,1);
+ getSolver(m_cfg.m_vsequence[iseq])(this,1);
}
}
- /* Update */
- for(i=0,ni=m_nodes.size();i<ni;++i)
+ /* Update */
+ for(i=0,ni=m_nodes.size();i<ni;++i)
{
- Node& n=m_nodes[i];
- n.m_x = n.m_q+n.m_v*m_sst.sdt;
+ Node& n=m_nodes[i];
+ n.m_x = n.m_q+n.m_v*m_sst.sdt;
}
}
-/* Solve positions */
-if(m_cfg.piterations>0)
+ /* Solve positions */
+ if(m_cfg.piterations>0)
{
- for(int isolve=0;isolve<m_cfg.piterations;++isolve)
+ for(int isolve=0;isolve<m_cfg.piterations;++isolve)
{
- const btScalar ti=isolve/(btScalar)m_cfg.piterations;
- for(int iseq=0;iseq<m_cfg.m_psequence.size();++iseq)
+ const btScalar ti=isolve/(btScalar)m_cfg.piterations;
+ for(int iseq=0;iseq<m_cfg.m_psequence.size();++iseq)
{
- getSolver(m_cfg.m_psequence[iseq])(this,1,ti);
+ getSolver(m_cfg.m_psequence[iseq])(this,1,ti);
}
}
- const btScalar vc=m_sst.isdt*(1-m_cfg.kDP);
- for(i=0,ni=m_nodes.size();i<ni;++i)
+ const btScalar vc=m_sst.isdt*(1-m_cfg.kDP);
+ for(i=0,ni=m_nodes.size();i<ni;++i)
{
- Node& n=m_nodes[i];
- n.m_v = (n.m_x-n.m_q)*vc;
- n.m_f = btVector3(0,0,0);
+ Node& n=m_nodes[i];
+ n.m_v = (n.m_x-n.m_q)*vc;
+ n.m_f = btVector3(0,0,0);
}
}
-/* Solve drift */
-if(m_cfg.diterations>0)
+ /* Solve drift */
+ if(m_cfg.diterations>0)
{
- const btScalar vcf=m_cfg.kVCF*m_sst.isdt;
- for(i=0,ni=m_nodes.size();i<ni;++i)
+ const btScalar vcf=m_cfg.kVCF*m_sst.isdt;
+ for(i=0,ni=m_nodes.size();i<ni;++i)
{
- Node& n=m_nodes[i];
- n.m_q = n.m_x;
+ Node& n=m_nodes[i];
+ n.m_q = n.m_x;
}
- for(int idrift=0;idrift<m_cfg.diterations;++idrift)
+ for(int idrift=0;idrift<m_cfg.diterations;++idrift)
{
- for(int iseq=0;iseq<m_cfg.m_dsequence.size();++iseq)
+ for(int iseq=0;iseq<m_cfg.m_dsequence.size();++iseq)
{
- getSolver(m_cfg.m_dsequence[iseq])(this,1,0);
+ getSolver(m_cfg.m_dsequence[iseq])(this,1,0);
}
}
- for(int i=0,ni=m_nodes.size();i<ni;++i)
+ for(int i=0,ni=m_nodes.size();i<ni;++i)
{
- Node& n=m_nodes[i];
- n.m_v += (n.m_x-n.m_q)*vcf;
+ Node& n=m_nodes[i];
+ n.m_v += (n.m_x-n.m_q)*vcf;
}
}
-/* Apply clusters */
-dampClusters();
-applyClusters(true);
+ /* Apply clusters */
+ dampClusters();
+ applyClusters(true);
}
//
void btSoftBody::staticSolve(int iterations)
{
-for(int isolve=0;isolve<iterations;++isolve)
+ for(int isolve=0;isolve<iterations;++isolve)
{
- for(int iseq=0;iseq<m_cfg.m_psequence.size();++iseq)
+ for(int iseq=0;iseq<m_cfg.m_psequence.size();++iseq)
{
- getSolver(m_cfg.m_psequence[iseq])(this,1,0);
+ getSolver(m_cfg.m_psequence[iseq])(this,1,0);
}
}
}
@@ -1466,35 +1507,35 @@ for(int isolve=0;isolve<iterations;++isolve)
//
void btSoftBody::solveCommonConstraints(btSoftBody** /*bodies*/,int /*count*/,int /*iterations*/)
{
-/// placeholder
+ /// placeholder
}
//
void btSoftBody::solveClusters(const btAlignedObjectArray<btSoftBody*>& bodies)
{
-const int nb=bodies.size();
-int iterations=0;
-int i;
+ const int nb=bodies.size();
+ int iterations=0;
+ int i;
-for(i=0;i<nb;++i)
+ for(i=0;i<nb;++i)
{
- iterations=btMax(iterations,bodies[i]->m_cfg.citerations);
+ iterations=btMax(iterations,bodies[i]->m_cfg.citerations);
}
-for(i=0;i<nb;++i)
+ for(i=0;i<nb;++i)
{
- bodies[i]->prepareClusters(iterations);
+ bodies[i]->prepareClusters(iterations);
}
-for(i=0;i<iterations;++i)
+ for(i=0;i<iterations;++i)
{
- const btScalar sor=1;
- for(int j=0;j<nb;++j)
+ const btScalar sor=1;
+ for(int j=0;j<nb;++j)
{
- bodies[j]->solveClusters(sor);
+ bodies[j]->solveClusters(sor);
}
}
-for(i=0;i<nb;++i)
+ for(i=0;i<nb;++i)
{
- bodies[i]->cleanupClusters();
+ bodies[i]->cleanupClusters();
}
}
@@ -1506,48 +1547,54 @@ void btSoftBody::integrateMotion()
}
//
- btSoftBody::RayCaster::RayCaster(const btVector3& org,const btVector3& dir,btScalar mxt)
+btSoftBody::RayFromToCaster::RayFromToCaster(const btVector3& rayFrom,const btVector3& rayTo,btScalar mxt)
{
-o = org;
-d = dir;
-mint = mxt;
-face = 0;
-tests = 0;
+ m_rayFrom = rayFrom;
+ m_rayNormalizedDirection = (rayTo-rayFrom);
+ m_rayTo = rayTo;
+ m_mint = mxt;
+ m_face = 0;
+ m_tests = 0;
}
//
-void btSoftBody::RayCaster::Process(const btDbvtNode* leaf)
+void btSoftBody::RayFromToCaster::Process(const btDbvtNode* leaf)
{
-btSoftBody::Face& f=*(btSoftBody::Face*)leaf->data;
-const btScalar t=rayTriangle( o,d,
- f.m_n[0]->m_x,
- f.m_n[1]->m_x,
- f.m_n[2]->m_x,
- mint);
-if((t>0)&&(t<mint)) { mint=t;face=&f; }
-++tests;
+ btSoftBody::Face& f=*(btSoftBody::Face*)leaf->data;
+ const btScalar t=rayFromToTriangle( m_rayFrom,m_rayTo,m_rayNormalizedDirection,
+ f.m_n[0]->m_x,
+ f.m_n[1]->m_x,
+ f.m_n[2]->m_x,
+ m_mint);
+ if((t>0)&&(t<m_mint))
+ {
+ m_mint=t;m_face=&f;
+ }
+ ++m_tests;
}
//
-btScalar btSoftBody::RayCaster::rayTriangle( const btVector3& org,
- const btVector3& dir,
- const btVector3& a,
- const btVector3& b,
- const btVector3& c,
- btScalar maxt)
+btScalar btSoftBody::RayFromToCaster::rayFromToTriangle( const btVector3& rayFrom,
+ const btVector3& rayTo,
+ const btVector3& rayNormalizedDirection,
+ const btVector3& a,
+ const btVector3& b,
+ const btVector3& c,
+ btScalar maxt)
{
static const btScalar ceps=-SIMD_EPSILON*10;
static const btScalar teps=SIMD_EPSILON*10;
+
const btVector3 n=cross(b-a,c-a);
const btScalar d=dot(a,n);
- const btScalar den=dot(dir,n);
+ const btScalar den=dot(rayNormalizedDirection,n);
if(!btFuzzyZero(den))
{
- const btScalar num=dot(org,n)-d;
+ const btScalar num=dot(rayFrom,n)-d;
const btScalar t=-num/den;
if((t>teps)&&(t<maxt))
{
- const btVector3 hit=org+dir*t;
+ const btVector3 hit=rayFrom+rayNormalizedDirection*t;
if( (dot(n,cross(a-hit,b-hit))>ceps) &&
(dot(n,cross(b-hit,c-hit))>ceps) &&
(dot(n,cross(c-hit,a-hit))>ceps))
@@ -1569,9 +1616,9 @@ void btSoftBody::pointersToIndices()
for(i=0,ni=m_nodes.size();i<ni;++i)
{
if(m_nodes[i].m_leaf)
- {
+ {
m_nodes[i].m_leaf->data=*(void**)&i;
- }
+ }
}
for(i=0,ni=m_links.size();i<ni;++i)
{
@@ -1584,21 +1631,21 @@ void btSoftBody::pointersToIndices()
m_faces[i].m_n[1]=PTR2IDX(m_faces[i].m_n[1],base);
m_faces[i].m_n[2]=PTR2IDX(m_faces[i].m_n[2],base);
if(m_faces[i].m_leaf)
- {
+ {
m_faces[i].m_leaf->data=*(void**)&i;
- }
+ }
}
for(i=0,ni=m_anchors.size();i<ni;++i)
- {
+ {
m_anchors[i].m_node=PTR2IDX(m_anchors[i].m_node,base);
- }
+ }
for(i=0,ni=m_notes.size();i<ni;++i)
- {
+ {
for(int j=0;j<m_notes[i].m_rank;++j)
- {
+ {
m_notes[i].m_nodes[j]=PTR2IDX(m_notes[i].m_nodes[j],base);
- }
}
+ }
#undef PTR2IDX
}
@@ -1606,16 +1653,16 @@ void btSoftBody::pointersToIndices()
void btSoftBody::indicesToPointers(const int* map)
{
#define IDX2PTR(_p_,_b_) map?(&(_b_)[map[(((char*)_p_)-(char*)0)]]): \
- (&(_b_)[(((char*)_p_)-(char*)0)])
+ (&(_b_)[(((char*)_p_)-(char*)0)])
btSoftBody::Node* base=&m_nodes[0];
int i,ni;
for(i=0,ni=m_nodes.size();i<ni;++i)
{
if(m_nodes[i].m_leaf)
- {
+ {
m_nodes[i].m_leaf->data=&m_nodes[i];
- }
+ }
}
for(i=0,ni=m_links.size();i<ni;++i)
{
@@ -1628,110 +1675,116 @@ void btSoftBody::indicesToPointers(const int* map)
m_faces[i].m_n[1]=IDX2PTR(m_faces[i].m_n[1],base);
m_faces[i].m_n[2]=IDX2PTR(m_faces[i].m_n[2],base);
if(m_faces[i].m_leaf)
- {
+ {
m_faces[i].m_leaf->data=&m_faces[i];
- }
+ }
}
for(i=0,ni=m_anchors.size();i<ni;++i)
- {
+ {
m_anchors[i].m_node=IDX2PTR(m_anchors[i].m_node,base);
- }
+ }
for(i=0,ni=m_notes.size();i<ni;++i)
- {
+ {
for(int j=0;j<m_notes[i].m_rank;++j)
- {
+ {
m_notes[i].m_nodes[j]=IDX2PTR(m_notes[i].m_nodes[j],base);
- }
}
+ }
#undef IDX2PTR
}
//
-int btSoftBody::rayCast(const btVector3& org,const btVector3& dir,
+int btSoftBody::rayTest(const btVector3& rayFrom,const btVector3& rayTo,
btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const
{
int cnt=0;
if(bcountonly||m_fdbvt.empty())
- {/* Full search */
+ {/* Full search */
+ btVector3 dir = rayTo-rayFrom;
+ dir.normalize();
+
for(int i=0,ni=m_faces.size();i<ni;++i)
- {
+ {
const btSoftBody::Face& f=m_faces[i];
- const btScalar t=RayCaster::rayTriangle( org,dir,
- f.m_n[0]->m_x,
- f.m_n[1]->m_x,
- f.m_n[2]->m_x,
- mint);
+
+ const btScalar t=RayFromToCaster::rayFromToTriangle( rayFrom,rayTo,dir,
+ f.m_n[0]->m_x,
+ f.m_n[1]->m_x,
+ f.m_n[2]->m_x,
+ mint);
if(t>0)
- {
+ {
++cnt;
if(!bcountonly)
- {
+ {
feature=btSoftBody::eFeature::Face;
index=i;
mint=t;
- }
}
}
}
- else
- {/* Use dbvt */
- RayCaster collider(org,dir,mint);
- btDbvt::collideRAY(m_fdbvt.m_root,org,dir,collider);
- if(collider.face)
- {
- mint=collider.mint;
+ }
+ else
+ {/* Use dbvt */
+ RayFromToCaster collider(rayFrom,rayTo,mint);
+
+ btDbvt::rayTest(m_fdbvt.m_root,rayFrom,rayTo,collider);
+ if(collider.m_face)
+ {
+ mint=collider.m_mint;
feature=btSoftBody::eFeature::Face;
- index=(int)(collider.face-&m_faces[0]);
+ index=(int)(collider.m_face-&m_faces[0]);
cnt=1;
- }
}
+ }
return(cnt);
}
//
void btSoftBody::initializeFaceTree()
{
-m_fdbvt.clear();
-for(int i=0;i<m_faces.size();++i)
+ m_fdbvt.clear();
+ for(int i=0;i<m_faces.size();++i)
{
- Face& f=m_faces[i];
- f.m_leaf=m_fdbvt.insert(VolumeOf(f,0),&f);
+ Face& f=m_faces[i];
+ f.m_leaf=m_fdbvt.insert(VolumeOf(f,0),&f);
}
}
//
btVector3 btSoftBody::evaluateCom() const
{
-btVector3 com(0,0,0);
-if(m_pose.m_bframe)
+ btVector3 com(0,0,0);
+ if(m_pose.m_bframe)
{
- for(int i=0,ni=m_nodes.size();i<ni;++i)
+ for(int i=0,ni=m_nodes.size();i<ni;++i)
{
- com+=m_nodes[i].m_x*m_pose.m_wgh[i];
+ com+=m_nodes[i].m_x*m_pose.m_wgh[i];
}
}
return(com);
}
-
+
//
-bool btSoftBody::checkContact( btRigidBody* prb,
- const btVector3& x,
- btScalar margin,
- btSoftBody::sCti& cti) const
+bool btSoftBody::checkContact( btCollisionObject* colObj,
+ const btVector3& x,
+ btScalar margin,
+ btSoftBody::sCti& cti) const
{
btVector3 nrm;
- btCollisionShape* shp=prb->getCollisionShape();
- const btTransform& wtr=prb->getInterpolationWorldTransform();
+ btCollisionShape* shp=colObj->getCollisionShape();
+ btRigidBody* tmpRigid = btRigidBody::upcast(colObj);
+ const btTransform& wtr=tmpRigid? tmpRigid->getInterpolationWorldTransform() : colObj->getWorldTransform();
btScalar dst=m_worldInfo->m_sparsesdf.Evaluate( wtr.invXform(x),
- shp,
- nrm,
- margin);
+ shp,
+ nrm,
+ margin);
if(dst<0)
{
- cti.m_body = prb;
+ cti.m_colObj = colObj;
cti.m_normal = wtr.getBasis()*nrm;
cti.m_offset = -dot( cti.m_normal,
- x-cti.m_normal*dst);
+ x-cti.m_normal*dst);
return(true);
}
return(false);
@@ -1751,7 +1804,7 @@ void btSoftBody::updateNormals()
{
btSoftBody::Face& f=m_faces[i];
const btVector3 n=cross(f.m_n[1]->m_x-f.m_n[0]->m_x,
- f.m_n[2]->m_x-f.m_n[0]->m_x);
+ f.m_n[2]->m_x-f.m_n[0]->m_x);
f.m_normal=n.normalized();
f.m_n[0]->m_n+=n;
f.m_n[1]->m_n+=n;
@@ -1769,28 +1822,28 @@ void btSoftBody::updateNormals()
void btSoftBody::updateBounds()
{
if(m_ndbvt.m_root)
- {
+ {
const btVector3& mins=m_ndbvt.m_root->volume.Mins();
const btVector3& maxs=m_ndbvt.m_root->volume.Maxs();
const btScalar csm=getCollisionShape()->getMargin();
const btVector3 mrg=btVector3( csm,
- csm,
- csm)*1; // ??? to investigate...
+ csm,
+ csm)*1; // ??? to investigate...
m_bounds[0]=mins-mrg;
m_bounds[1]=maxs+mrg;
- if(0!=getBroadphaseHandle())
- {
- m_worldInfo->m_broadphase->setAabb( getBroadphaseHandle(),
- m_bounds[0],
- m_bounds[1],
- m_worldInfo->m_dispatcher);
- }
+ if(0!=getBroadphaseHandle())
+ {
+ m_worldInfo->m_broadphase->setAabb( getBroadphaseHandle(),
+ m_bounds[0],
+ m_bounds[1],
+ m_worldInfo->m_dispatcher);
}
- else
- {
+ }
+ else
+ {
m_bounds[0]=
- m_bounds[1]=btVector3(0,0,0);
- }
+ m_bounds[1]=btVector3(0,0,0);
+ }
}
@@ -1821,12 +1874,12 @@ void btSoftBody::updatePose()
pose.m_rot=r;
pose.m_scl=pose.m_aqq*r.transpose()*Apq;
if(m_cfg.maxvolume>1)
- {
+ {
const btScalar idet=Clamp<btScalar>( 1/pose.m_scl.determinant(),
- 1,m_cfg.maxvolume);
+ 1,m_cfg.maxvolume);
pose.m_scl=Mul(pose.m_scl,idet);
- }
-
+ }
+
}
}
@@ -1881,53 +1934,53 @@ void btSoftBody::initializeClusters()
{
int i;
-for( i=0;i<m_clusters.size();++i)
+ for( i=0;i<m_clusters.size();++i)
{
- Cluster& c=*m_clusters[i];
- c.m_imass=0;
- c.m_masses.resize(c.m_nodes.size());
- for(int j=0;j<c.m_nodes.size();++j)
+ Cluster& c=*m_clusters[i];
+ c.m_imass=0;
+ c.m_masses.resize(c.m_nodes.size());
+ for(int j=0;j<c.m_nodes.size();++j)
{
- c.m_masses[j] = c.m_nodes[j]->m_im>0?1/c.m_nodes[j]->m_im:0;
- c.m_imass += c.m_masses[j];
+ c.m_masses[j] = c.m_nodes[j]->m_im>0?1/c.m_nodes[j]->m_im:0;
+ c.m_imass += c.m_masses[j];
}
- c.m_imass = 1/c.m_imass;
- c.m_com = btSoftBody::clusterCom(&c);
- c.m_lv = btVector3(0,0,0);
- c.m_av = btVector3(0,0,0);
- c.m_leaf = 0;
- /* Inertia */
- btMatrix3x3& ii=c.m_locii;
- ii[0]=ii[1]=ii[2]=btVector3(0,0,0);
- {
- int i,ni;
+ c.m_imass = 1/c.m_imass;
+ c.m_com = btSoftBody::clusterCom(&c);
+ c.m_lv = btVector3(0,0,0);
+ c.m_av = btVector3(0,0,0);
+ c.m_leaf = 0;
+ /* Inertia */
+ btMatrix3x3& ii=c.m_locii;
+ ii[0]=ii[1]=ii[2]=btVector3(0,0,0);
+ {
+ int i,ni;
- for(i=0,ni=c.m_nodes.size();i<ni;++i)
- {
- const btVector3 k=c.m_nodes[i]->m_x-c.m_com;
- const btVector3 q=k*k;
- const btScalar m=c.m_masses[i];
- ii[0][0] += m*(q[1]+q[2]);
- ii[1][1] += m*(q[0]+q[2]);
- ii[2][2] += m*(q[0]+q[1]);
- ii[0][1] -= m*k[0]*k[1];
- ii[0][2] -= m*k[0]*k[2];
- ii[1][2] -= m*k[1]*k[2];
- }
- }
- ii[1][0]=ii[0][1];
- ii[2][0]=ii[0][2];
- ii[2][1]=ii[1][2];
- ii=ii.inverse();
- /* Frame */
- c.m_framexform.setIdentity();
- c.m_framexform.setOrigin(c.m_com);
- c.m_framerefs.resize(c.m_nodes.size());
- {
- int i;
- for(i=0;i<c.m_framerefs.size();++i)
+ for(i=0,ni=c.m_nodes.size();i<ni;++i)
+ {
+ const btVector3 k=c.m_nodes[i]->m_x-c.m_com;
+ const btVector3 q=k*k;
+ const btScalar m=c.m_masses[i];
+ ii[0][0] += m*(q[1]+q[2]);
+ ii[1][1] += m*(q[0]+q[2]);
+ ii[2][2] += m*(q[0]+q[1]);
+ ii[0][1] -= m*k[0]*k[1];
+ ii[0][2] -= m*k[0]*k[2];
+ ii[1][2] -= m*k[1]*k[2];
+ }
+ }
+ ii[1][0]=ii[0][1];
+ ii[2][0]=ii[0][2];
+ ii[2][1]=ii[1][2];
+ ii=ii.inverse();
+ /* Frame */
+ c.m_framexform.setIdentity();
+ c.m_framexform.setOrigin(c.m_com);
+ c.m_framerefs.resize(c.m_nodes.size());
+ {
+ int i;
+ for(i=0;i<c.m_framerefs.size();++i)
{
- c.m_framerefs[i]=c.m_nodes[i]->m_x-c.m_com;
+ c.m_framerefs[i]=c.m_nodes[i]->m_x-c.m_com;
}
}
}
@@ -1936,49 +1989,49 @@ for( i=0;i<m_clusters.size();++i)
//
void btSoftBody::updateClusters()
{
-BT_PROFILE("UpdateClusters");
-int i;
-
-for(i=0;i<m_clusters.size();++i)
- {
- btSoftBody::Cluster& c=*m_clusters[i];
- const int n=c.m_nodes.size();
- const btScalar invn=1/(btScalar)n;
- if(n)
- {
- /* Frame */
- const btScalar eps=btScalar(0.0001);
- btMatrix3x3 m,r,s;
- m[0]=m[1]=m[2]=btVector3(0,0,0);
- m[0][0]=eps*1;
- m[1][1]=eps*2;
- m[2][2]=eps*3;
- c.m_com=clusterCom(&c);
- for(int i=0;i<c.m_nodes.size();++i)
+ BT_PROFILE("UpdateClusters");
+ int i;
+
+ for(i=0;i<m_clusters.size();++i)
+ {
+ btSoftBody::Cluster& c=*m_clusters[i];
+ const int n=c.m_nodes.size();
+ const btScalar invn=1/(btScalar)n;
+ if(n)
+ {
+ /* Frame */
+ const btScalar eps=btScalar(0.0001);
+ btMatrix3x3 m,r,s;
+ m[0]=m[1]=m[2]=btVector3(0,0,0);
+ m[0][0]=eps*1;
+ m[1][1]=eps*2;
+ m[2][2]=eps*3;
+ c.m_com=clusterCom(&c);
+ for(int i=0;i<c.m_nodes.size();++i)
{
- const btVector3 a=c.m_nodes[i]->m_x-c.m_com;
- const btVector3& b=c.m_framerefs[i];
- m[0]+=a[0]*b;m[1]+=a[1]*b;m[2]+=a[2]*b;
+ const btVector3 a=c.m_nodes[i]->m_x-c.m_com;
+ const btVector3& b=c.m_framerefs[i];
+ m[0]+=a[0]*b;m[1]+=a[1]*b;m[2]+=a[2]*b;
}
- PolarDecompose(m,r,s);
- c.m_framexform.setOrigin(c.m_com);
- c.m_framexform.setBasis(r);
- /* Inertia */
- #if 1/* Constant */
- c.m_invwi=c.m_framexform.getBasis()*c.m_locii*c.m_framexform.getBasis().transpose();
- #else
- #if 0/* Sphere */
+ PolarDecompose(m,r,s);
+ c.m_framexform.setOrigin(c.m_com);
+ c.m_framexform.setBasis(r);
+ /* Inertia */
+#if 1/* Constant */
+ c.m_invwi=c.m_framexform.getBasis()*c.m_locii*c.m_framexform.getBasis().transpose();
+#else
+#if 0/* Sphere */
const btScalar rk=(2*c.m_extents.length2())/(5*c.m_imass);
const btVector3 inertia(rk,rk,rk);
const btVector3 iin(btFabs(inertia[0])>SIMD_EPSILON?1/inertia[0]:0,
- btFabs(inertia[1])>SIMD_EPSILON?1/inertia[1]:0,
- btFabs(inertia[2])>SIMD_EPSILON?1/inertia[2]:0);
-
+ btFabs(inertia[1])>SIMD_EPSILON?1/inertia[1]:0,
+ btFabs(inertia[2])>SIMD_EPSILON?1/inertia[2]:0);
+
c.m_invwi=c.m_xform.getBasis().scaled(iin)*c.m_xform.getBasis().transpose();
- #else/* Actual */
+#else/* Actual */
c.m_invwi[0]=c.m_invwi[1]=c.m_invwi[2]=btVector3(0,0,0);
for(int i=0;i<n;++i)
- {
+ {
const btVector3 k=c.m_nodes[i]->m_x-c.m_com;
const btVector3 q=k*k;
const btScalar m=1/c.m_nodes[i]->m_im;
@@ -1988,74 +2041,79 @@ for(i=0;i<m_clusters.size();++i)
c.m_invwi[0][1] -= m*k[0]*k[1];
c.m_invwi[0][2] -= m*k[0]*k[2];
c.m_invwi[1][2] -= m*k[1]*k[2];
- }
+ }
c.m_invwi[1][0]=c.m_invwi[0][1];
c.m_invwi[2][0]=c.m_invwi[0][2];
c.m_invwi[2][1]=c.m_invwi[1][2];
c.m_invwi=c.m_invwi.inverse();
- #endif
- #endif
- /* Velocities */
- c.m_lv=btVector3(0,0,0);
- c.m_av=btVector3(0,0,0);
- {
- int i;
-
- for(i=0;i<n;++i)
+#endif
+#endif
+ /* Velocities */
+ c.m_lv=btVector3(0,0,0);
+ c.m_av=btVector3(0,0,0);
{
- const btVector3 v=c.m_nodes[i]->m_v*c.m_masses[i];
- c.m_lv += v;
- c.m_av += cross(c.m_nodes[i]->m_x-c.m_com,v);
+ int i;
+
+ for(i=0;i<n;++i)
+ {
+ const btVector3 v=c.m_nodes[i]->m_v*c.m_masses[i];
+ c.m_lv += v;
+ c.m_av += cross(c.m_nodes[i]->m_x-c.m_com,v);
+ }
}
- }
- c.m_lv=c.m_imass*c.m_lv*(1-c.m_ldamping);
- c.m_av=c.m_invwi*c.m_av*(1-c.m_adamping);
- c.m_vimpulses[0] =
- c.m_vimpulses[1] = btVector3(0,0,0);
- c.m_dimpulses[0] =
- c.m_dimpulses[1] = btVector3(0,0,0);
- c.m_nvimpulses = 0;
- c.m_ndimpulses = 0;
- /* Matching */
- if(c.m_matching>0)
+ c.m_lv=c.m_imass*c.m_lv*(1-c.m_ldamping);
+ c.m_av=c.m_invwi*c.m_av*(1-c.m_adamping);
+ c.m_vimpulses[0] =
+ c.m_vimpulses[1] = btVector3(0,0,0);
+ c.m_dimpulses[0] =
+ c.m_dimpulses[1] = btVector3(0,0,0);
+ c.m_nvimpulses = 0;
+ c.m_ndimpulses = 0;
+ /* Matching */
+ if(c.m_matching>0)
{
- for(int j=0;j<c.m_nodes.size();++j)
+ for(int j=0;j<c.m_nodes.size();++j)
{
- Node& n=*c.m_nodes[j];
- const btVector3 x=c.m_framexform*c.m_framerefs[j];
- n.m_x=Lerp(n.m_x,x,c.m_matching);
+ Node& n=*c.m_nodes[j];
+ const btVector3 x=c.m_framexform*c.m_framerefs[j];
+ n.m_x=Lerp(n.m_x,x,c.m_matching);
}
- }
- /* Dbvt */
- if(c.m_collide)
+ }
+ /* Dbvt */
+ if(c.m_collide)
{
- btVector3 mi=c.m_nodes[0]->m_x;
- btVector3 mx=mi;
- for(int j=1;j<n;++j)
+ btVector3 mi=c.m_nodes[0]->m_x;
+ btVector3 mx=mi;
+ for(int j=1;j<n;++j)
{
- mi.setMin(c.m_nodes[j]->m_x);
- mx.setMax(c.m_nodes[j]->m_x);
+ mi.setMin(c.m_nodes[j]->m_x);
+ mx.setMax(c.m_nodes[j]->m_x);
}
- const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(mi,mx);
- if(c.m_leaf)
- m_cdbvt.update(c.m_leaf,bounds,c.m_lv*m_sst.sdt*3,m_sst.radmrg);
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(mi,mx);
+ if(c.m_leaf)
+ m_cdbvt.update(c.m_leaf,bounds,c.m_lv*m_sst.sdt*3,m_sst.radmrg);
else
- c.m_leaf=m_cdbvt.insert(bounds,&c);
+ c.m_leaf=m_cdbvt.insert(bounds,&c);
}
}
}
+
+
}
+
+
+
//
void btSoftBody::cleanupClusters()
{
-for(int i=0;i<m_joints.size();++i)
+ for(int i=0;i<m_joints.size();++i)
{
- m_joints[i]->Terminate(m_sst.sdt);
- if(m_joints[i]->m_delete)
+ m_joints[i]->Terminate(m_sst.sdt);
+ if(m_joints[i]->m_delete)
{
- btAlignedFree(m_joints[i]);
- m_joints.remove(m_joints[i--]);
+ btAlignedFree(m_joints[i]);
+ m_joints.remove(m_joints[i--]);
}
}
}
@@ -2063,9 +2121,9 @@ for(int i=0;i<m_joints.size();++i)
//
void btSoftBody::prepareClusters(int iterations)
{
-for(int i=0;i<m_joints.size();++i)
+ for(int i=0;i<m_joints.size();++i)
{
- m_joints[i]->Prepare(m_sst.sdt,iterations);
+ m_joints[i]->Prepare(m_sst.sdt,iterations);
}
}
@@ -2073,50 +2131,51 @@ for(int i=0;i<m_joints.size();++i)
//
void btSoftBody::solveClusters(btScalar sor)
{
-for(int i=0,ni=m_joints.size();i<ni;++i)
+ for(int i=0,ni=m_joints.size();i<ni;++i)
{
- m_joints[i]->Solve(m_sst.sdt,sor);
+ m_joints[i]->Solve(m_sst.sdt,sor);
}
}
//
void btSoftBody::applyClusters(bool drift)
{
-BT_PROFILE("ApplyClusters");
-const btScalar f0=m_sst.sdt;
-const btScalar f1=f0/2;
-btAlignedObjectArray<btVector3> deltas;
-btAlignedObjectArray<btScalar> weights;
-deltas.resize(m_nodes.size(),btVector3(0,0,0));
-weights.resize(m_nodes.size(),0);
-int i;
+ BT_PROFILE("ApplyClusters");
+ const btScalar f0=m_sst.sdt;
+ const btScalar f1=f0/2;
+ btAlignedObjectArray<btVector3> deltas;
+ btAlignedObjectArray<btScalar> weights;
+ deltas.resize(m_nodes.size(),btVector3(0,0,0));
+ weights.resize(m_nodes.size(),0);
+ int i;
-if(drift)
+ if(drift)
{
- for(i=0;i<m_clusters.size();++i)
+ for(i=0;i<m_clusters.size();++i)
{
- Cluster& c=*m_clusters[i];
- if(c.m_ndimpulses)
+ Cluster& c=*m_clusters[i];
+ if(c.m_ndimpulses)
{
- c.m_dimpulses[0]/=(btScalar)c.m_ndimpulses;
- c.m_dimpulses[1]/=(btScalar)c.m_ndimpulses;
+ c.m_dimpulses[0]/=(btScalar)c.m_ndimpulses;
+ c.m_dimpulses[1]/=(btScalar)c.m_ndimpulses;
}
}
}
-for(i=0;i<m_clusters.size();++i)
+
+ for(i=0;i<m_clusters.size();++i)
{
- Cluster& c=*m_clusters[i];
- if(0<(drift?c.m_ndimpulses:c.m_nvimpulses))
+ Cluster& c=*m_clusters[i];
+ if(0<(drift?c.m_ndimpulses:c.m_nvimpulses))
{
- const btVector3 v=(drift?c.m_dimpulses[0]:c.m_vimpulses[0])*m_sst.sdt;
- const btVector3 w=(drift?c.m_dimpulses[1]:c.m_vimpulses[1])*m_sst.sdt;
- for(int j=0;j<c.m_nodes.size();++j)
+ const btVector3 v=(drift?c.m_dimpulses[0]:c.m_vimpulses[0])*m_sst.sdt;
+ const btVector3 w=(drift?c.m_dimpulses[1]:c.m_vimpulses[1])*m_sst.sdt;
+ for(int j=0;j<c.m_nodes.size();++j)
{
- const int idx=int(c.m_nodes[j]-&m_nodes[0]);
- const btVector3& x=c.m_nodes[j]->m_x;
- const btScalar q=c.m_masses[j];
- deltas[idx] += (v+cross(w,x-c.m_com))*q;
- weights[idx] += q;
+ const int idx=int(c.m_nodes[j]-&m_nodes[0]);
+ const btVector3& x=c.m_nodes[j]->m_x;
+ const btScalar q=c.m_masses[j];
+ deltas[idx] += (v+cross(w,x-c.m_com))*q;
+ weights[idx] += q;
}
}
}
@@ -2131,18 +2190,21 @@ void btSoftBody::dampClusters()
{
int i;
-for(i=0;i<m_clusters.size();++i)
+ for(i=0;i<m_clusters.size();++i)
{
- Cluster& c=*m_clusters[i];
- if(c.m_ndamping>0)
+ Cluster& c=*m_clusters[i];
+ if(c.m_ndamping>0)
{
- for(int j=0;j<c.m_nodes.size();++j)
+ for(int j=0;j<c.m_nodes.size();++j)
{
- Node& n=*c.m_nodes[j];
- if(n.m_im>0)
+ Node& n=*c.m_nodes[j];
+ if(n.m_im>0)
{
- const btVector3 vx=c.m_lv+cross(c.m_av,c.m_nodes[j]->m_q-c.m_com);
- n.m_v += c.m_ndamping*(vx-n.m_v);
+ const btVector3 vx=c.m_lv+cross(c.m_av,c.m_nodes[j]->m_q-c.m_com);
+ if(vx.length2()<=n.m_v.length2())
+ {
+ n.m_v += c.m_ndamping*(vx-n.m_v);
+ }
}
}
}
@@ -2152,154 +2214,155 @@ for(i=0;i<m_clusters.size();++i)
//
void btSoftBody::Joint::Prepare(btScalar dt,int)
{
-m_bodies[0].activate();
-m_bodies[1].activate();
+ m_bodies[0].activate();
+ m_bodies[1].activate();
}
//
void btSoftBody::LJoint::Prepare(btScalar dt,int iterations)
{
-static const btScalar maxdrift=4;
-Joint::Prepare(dt,iterations);
-m_rpos[0] = m_bodies[0].xform()*m_refs[0];
-m_rpos[1] = m_bodies[1].xform()*m_refs[1];
-m_drift = Clamp(m_rpos[0]-m_rpos[1],maxdrift)*m_erp/dt;
-m_rpos[0] -= m_bodies[0].xform().getOrigin();
-m_rpos[1] -= m_bodies[1].xform().getOrigin();
-m_massmatrix = ImpulseMatrix( m_bodies[0].invMass(),m_bodies[0].invWorldInertia(),m_rpos[0],
- m_bodies[1].invMass(),m_bodies[1].invWorldInertia(),m_rpos[1]);
-if(m_split>0)
+ static const btScalar maxdrift=4;
+ Joint::Prepare(dt,iterations);
+ m_rpos[0] = m_bodies[0].xform()*m_refs[0];
+ m_rpos[1] = m_bodies[1].xform()*m_refs[1];
+ m_drift = Clamp(m_rpos[0]-m_rpos[1],maxdrift)*m_erp/dt;
+ m_rpos[0] -= m_bodies[0].xform().getOrigin();
+ m_rpos[1] -= m_bodies[1].xform().getOrigin();
+ m_massmatrix = ImpulseMatrix( m_bodies[0].invMass(),m_bodies[0].invWorldInertia(),m_rpos[0],
+ m_bodies[1].invMass(),m_bodies[1].invWorldInertia(),m_rpos[1]);
+ if(m_split>0)
{
- m_sdrift = m_massmatrix*(m_drift*m_split);
- m_drift *= 1-m_split;
+ m_sdrift = m_massmatrix*(m_drift*m_split);
+ m_drift *= 1-m_split;
}
-m_drift /=(btScalar)iterations;
+ m_drift /=(btScalar)iterations;
}
//
void btSoftBody::LJoint::Solve(btScalar dt,btScalar sor)
{
-const btVector3 va=m_bodies[0].velocity(m_rpos[0]);
-const btVector3 vb=m_bodies[1].velocity(m_rpos[1]);
-const btVector3 vr=va-vb;
-btSoftBody::Impulse impulse;
-impulse.m_asVelocity = 1;
-impulse.m_velocity = m_massmatrix*(m_drift+vr*m_cfm)*sor;
-m_bodies[0].applyImpulse(-impulse,m_rpos[0]);
-m_bodies[1].applyImpulse( impulse,m_rpos[1]);
+ const btVector3 va=m_bodies[0].velocity(m_rpos[0]);
+ const btVector3 vb=m_bodies[1].velocity(m_rpos[1]);
+ const btVector3 vr=va-vb;
+ btSoftBody::Impulse impulse;
+ impulse.m_asVelocity = 1;
+ impulse.m_velocity = m_massmatrix*(m_drift+vr*m_cfm)*sor;
+ m_bodies[0].applyImpulse(-impulse,m_rpos[0]);
+ m_bodies[1].applyImpulse( impulse,m_rpos[1]);
}
//
void btSoftBody::LJoint::Terminate(btScalar dt)
{
-if(m_split>0)
+ if(m_split>0)
{
- m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]);
- m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]);
+ m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]);
+ m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]);
}
}
//
void btSoftBody::AJoint::Prepare(btScalar dt,int iterations)
{
-static const btScalar maxdrift=SIMD_PI/16;
-m_icontrol->Prepare(this);
-Joint::Prepare(dt,iterations);
-m_axis[0] = m_bodies[0].xform().getBasis()*m_refs[0];
-m_axis[1] = m_bodies[1].xform().getBasis()*m_refs[1];
-m_drift = NormalizeAny(cross(m_axis[1],m_axis[0]));
-m_drift *= btMin(maxdrift,btAcos(Clamp<btScalar>(dot(m_axis[0],m_axis[1]),-1,+1)));
-m_drift *= m_erp/dt;
-m_massmatrix= AngularImpulseMatrix(m_bodies[0].invWorldInertia(),m_bodies[1].invWorldInertia());
-if(m_split>0)
+ static const btScalar maxdrift=SIMD_PI/16;
+ m_icontrol->Prepare(this);
+ Joint::Prepare(dt,iterations);
+ m_axis[0] = m_bodies[0].xform().getBasis()*m_refs[0];
+ m_axis[1] = m_bodies[1].xform().getBasis()*m_refs[1];
+ m_drift = NormalizeAny(cross(m_axis[1],m_axis[0]));
+ m_drift *= btMin(maxdrift,btAcos(Clamp<btScalar>(dot(m_axis[0],m_axis[1]),-1,+1)));
+ m_drift *= m_erp/dt;
+ m_massmatrix= AngularImpulseMatrix(m_bodies[0].invWorldInertia(),m_bodies[1].invWorldInertia());
+ if(m_split>0)
{
- m_sdrift = m_massmatrix*(m_drift*m_split);
- m_drift *= 1-m_split;
+ m_sdrift = m_massmatrix*(m_drift*m_split);
+ m_drift *= 1-m_split;
}
-m_drift /=(btScalar)iterations;
+ m_drift /=(btScalar)iterations;
}
//
void btSoftBody::AJoint::Solve(btScalar dt,btScalar sor)
{
-const btVector3 va=m_bodies[0].angularVelocity();
-const btVector3 vb=m_bodies[1].angularVelocity();
-const btVector3 vr=va-vb;
-const btScalar sp=dot(vr,m_axis[0]);
-const btVector3 vc=vr-m_axis[0]*m_icontrol->Speed(this,sp);
-btSoftBody::Impulse impulse;
-impulse.m_asVelocity = 1;
-impulse.m_velocity = m_massmatrix*(m_drift+vc*m_cfm)*sor;
-m_bodies[0].applyAImpulse(-impulse);
-m_bodies[1].applyAImpulse( impulse);
+ const btVector3 va=m_bodies[0].angularVelocity();
+ const btVector3 vb=m_bodies[1].angularVelocity();
+ const btVector3 vr=va-vb;
+ const btScalar sp=dot(vr,m_axis[0]);
+ const btVector3 vc=vr-m_axis[0]*m_icontrol->Speed(this,sp);
+ btSoftBody::Impulse impulse;
+ impulse.m_asVelocity = 1;
+ impulse.m_velocity = m_massmatrix*(m_drift+vc*m_cfm)*sor;
+ m_bodies[0].applyAImpulse(-impulse);
+ m_bodies[1].applyAImpulse( impulse);
}
//
void btSoftBody::AJoint::Terminate(btScalar dt)
{
-if(m_split>0)
+ if(m_split>0)
{
- m_bodies[0].applyDAImpulse(-m_sdrift);
- m_bodies[1].applyDAImpulse( m_sdrift);
+ m_bodies[0].applyDAImpulse(-m_sdrift);
+ m_bodies[1].applyDAImpulse( m_sdrift);
}
}
//
void btSoftBody::CJoint::Prepare(btScalar dt,int iterations)
{
-Joint::Prepare(dt,iterations);
-const bool dodrift=(m_life==0);
-m_delete=(++m_life)>m_maxlife;
-if(dodrift)
+ Joint::Prepare(dt,iterations);
+ const bool dodrift=(m_life==0);
+ m_delete=(++m_life)>m_maxlife;
+ if(dodrift)
{
- m_drift=m_drift*m_erp/dt;
- if(m_split>0)
+ m_drift=m_drift*m_erp/dt;
+ if(m_split>0)
{
- m_sdrift = m_massmatrix*(m_drift*m_split);
- m_drift *= 1-m_split;
+ m_sdrift = m_massmatrix*(m_drift*m_split);
+ m_drift *= 1-m_split;
}
- m_drift/=(btScalar)iterations;
+ m_drift/=(btScalar)iterations;
}
else
{
- m_drift=m_sdrift=btVector3(0,0,0);
+ m_drift=m_sdrift=btVector3(0,0,0);
}
}
//
void btSoftBody::CJoint::Solve(btScalar dt,btScalar sor)
{
-const btVector3 va=m_bodies[0].velocity(m_rpos[0]);
-const btVector3 vb=m_bodies[1].velocity(m_rpos[1]);
-const btVector3 vrel=va-vb;
-const btScalar rvac=dot(vrel,m_normal);
-btSoftBody::Impulse impulse;
-impulse.m_asVelocity = 1;
-impulse.m_velocity = m_drift;
-if(rvac<0)
+ const btVector3 va=m_bodies[0].velocity(m_rpos[0]);
+ const btVector3 vb=m_bodies[1].velocity(m_rpos[1]);
+ const btVector3 vrel=va-vb;
+ const btScalar rvac=dot(vrel,m_normal);
+ btSoftBody::Impulse impulse;
+ impulse.m_asVelocity = 1;
+ impulse.m_velocity = m_drift;
+ if(rvac<0)
{
- const btVector3 iv=m_normal*rvac;
- const btVector3 fv=vrel-iv;
- impulse.m_velocity += iv+fv*m_friction;
+ const btVector3 iv=m_normal*rvac;
+ const btVector3 fv=vrel-iv;
+ impulse.m_velocity += iv+fv*m_friction;
}
-impulse.m_velocity=m_massmatrix*impulse.m_velocity*sor;
-m_bodies[0].applyImpulse(-impulse,m_rpos[0]);
-m_bodies[1].applyImpulse( impulse,m_rpos[1]);
+ impulse.m_velocity=m_massmatrix*impulse.m_velocity*sor;
+ m_bodies[0].applyImpulse(-impulse,m_rpos[0]);
+ m_bodies[1].applyImpulse( impulse,m_rpos[1]);
}
//
void btSoftBody::CJoint::Terminate(btScalar dt)
{
-if(m_split>0)
+ if(m_split>0)
{
- m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]);
- m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]);
+ m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]);
+ m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]);
}
}
//
void btSoftBody::applyForces()
{
+
BT_PROFILE("SoftBody applyForces");
const btScalar dt=m_sst.sdt;
const btScalar kLF=m_cfg.kLF;
@@ -2311,14 +2374,14 @@ void btSoftBody::applyForces()
const bool as_pressure=kPR!=0;
const bool as_volume=kVC>0;
const bool as_aero= as_lift ||
- as_drag ;
+ as_drag ;
const bool as_vaero= as_aero &&
- (m_cfg.aeromodel<btSoftBody::eAeroModel::F_TwoSided);
+ (m_cfg.aeromodel<btSoftBody::eAeroModel::F_TwoSided);
const bool as_faero= as_aero &&
- (m_cfg.aeromodel>=btSoftBody::eAeroModel::F_TwoSided);
+ (m_cfg.aeromodel>=btSoftBody::eAeroModel::F_TwoSided);
const bool use_medium= as_aero;
const bool use_volume= as_pressure ||
- as_volume ;
+ as_volume ;
btScalar volume=0;
btScalar ivolumetp=0;
btScalar dvolumetv=0;
@@ -2447,12 +2510,10 @@ void btSoftBody::PSolve_RContacts(btSoftBody* psb,btScalar kst,btScalar ti)
for(int i=0,ni=psb->m_rcontacts.size();i<ni;++i)
{
const RContact& c=psb->m_rcontacts[i];
- ///skip object that don't have collision response
- if (!psb->getWorldInfo()->m_dispatcher->needsResponse(psb,c.m_cti.m_body))
- continue;
-
const sCti& cti=c.m_cti;
- const btVector3 va=cti.m_body->getVelocityInLocalPoint(c.m_c1)*dt;
+ btRigidBody* tmpRigid = btRigidBody::upcast(cti.m_colObj);
+
+ const btVector3 va=tmpRigid ? tmpRigid->getVelocityInLocalPoint(c.m_c1)*dt : btVector3(0,0,0);
const btVector3 vb=c.m_node->m_x-c.m_node->m_q;
const btVector3 vr=vb-va;
const btScalar dn=dot(vr,cti.m_normal);
@@ -2462,7 +2523,8 @@ void btSoftBody::PSolve_RContacts(btSoftBody* psb,btScalar kst,btScalar ti)
const btVector3 fv=vr-cti.m_normal*dn;
const btVector3 impulse=c.m_c0*((vr-fv*c.m_c3+cti.m_normal*(dp*c.m_c4))*kst);
c.m_node->m_x-=impulse*c.m_c2;
- c.m_cti.m_body->applyImpulse(impulse,c.m_c1);
+ if (tmpRigid)
+ tmpRigid->applyImpulse(impulse,c.m_c1);
}
}
}
@@ -2470,32 +2532,32 @@ void btSoftBody::PSolve_RContacts(btSoftBody* psb,btScalar kst,btScalar ti)
//
void btSoftBody::PSolve_SContacts(btSoftBody* psb,btScalar,btScalar ti)
{
-for(int i=0,ni=psb->m_scontacts.size();i<ni;++i)
+ for(int i=0,ni=psb->m_scontacts.size();i<ni;++i)
{
- const SContact& c=psb->m_scontacts[i];
- const btVector3& nr=c.m_normal;
- Node& n=*c.m_node;
- Face& f=*c.m_face;
- const btVector3 p=BaryEval( f.m_n[0]->m_x,
- f.m_n[1]->m_x,
- f.m_n[2]->m_x,
- c.m_weights);
- const btVector3 q=BaryEval( f.m_n[0]->m_q,
- f.m_n[1]->m_q,
- f.m_n[2]->m_q,
- c.m_weights);
- const btVector3 vr=(n.m_x-n.m_q)-(p-q);
- btVector3 corr(0,0,0);
- if(dot(vr,nr)<0)
+ const SContact& c=psb->m_scontacts[i];
+ const btVector3& nr=c.m_normal;
+ Node& n=*c.m_node;
+ Face& f=*c.m_face;
+ const btVector3 p=BaryEval( f.m_n[0]->m_x,
+ f.m_n[1]->m_x,
+ f.m_n[2]->m_x,
+ c.m_weights);
+ const btVector3 q=BaryEval( f.m_n[0]->m_q,
+ f.m_n[1]->m_q,
+ f.m_n[2]->m_q,
+ c.m_weights);
+ const btVector3 vr=(n.m_x-n.m_q)-(p-q);
+ btVector3 corr(0,0,0);
+ if(dot(vr,nr)<0)
{
- const btScalar j=c.m_margin-(dot(nr,n.m_x)-dot(nr,p));
- corr+=c.m_normal*j;
+ const btScalar j=c.m_margin-(dot(nr,n.m_x)-dot(nr,p));
+ corr+=c.m_normal*j;
}
- corr -= ProjectOnPlane(vr,nr)*c.m_friction;
- n.m_x += corr*c.m_cfm[0];
- f.m_n[0]->m_x -= corr*(c.m_cfm[1]*c.m_weights.x());
- f.m_n[1]->m_x -= corr*(c.m_cfm[1]*c.m_weights.y());
- f.m_n[2]->m_x -= corr*(c.m_cfm[1]*c.m_weights.z());
+ corr -= ProjectOnPlane(vr,nr)*c.m_friction;
+ n.m_x += corr*c.m_cfm[0];
+ f.m_n[0]->m_x -= corr*(c.m_cfm[1]*c.m_weights.x());
+ f.m_n[1]->m_x -= corr*(c.m_cfm[1]*c.m_weights.y());
+ f.m_n[2]->m_x -= corr*(c.m_cfm[1]*c.m_weights.z());
}
}
@@ -2522,107 +2584,114 @@ void btSoftBody::PSolve_Links(btSoftBody* psb,btScalar kst,btScalar ti)
//
void btSoftBody::VSolve_Links(btSoftBody* psb,btScalar kst)
{
-for(int i=0,ni=psb->m_links.size();i<ni;++i)
+ for(int i=0,ni=psb->m_links.size();i<ni;++i)
{
- Link& l=psb->m_links[i];
- Node** n=l.m_n;
- const btScalar j=-dot(l.m_c3,n[0]->m_v-n[1]->m_v)*l.m_c2*kst;
- n[0]->m_v+= l.m_c3*(j*n[0]->m_im);
- n[1]->m_v-= l.m_c3*(j*n[1]->m_im);
+ Link& l=psb->m_links[i];
+ Node** n=l.m_n;
+ const btScalar j=-dot(l.m_c3,n[0]->m_v-n[1]->m_v)*l.m_c2*kst;
+ n[0]->m_v+= l.m_c3*(j*n[0]->m_im);
+ n[1]->m_v-= l.m_c3*(j*n[1]->m_im);
}
}
//
btSoftBody::psolver_t btSoftBody::getSolver(ePSolver::_ solver)
{
-switch(solver)
+ switch(solver)
{
case ePSolver::Anchors: return(&btSoftBody::PSolve_Anchors);
case ePSolver::Linear: return(&btSoftBody::PSolve_Links);
case ePSolver::RContacts: return(&btSoftBody::PSolve_RContacts);
case ePSolver::SContacts: return(&btSoftBody::PSolve_SContacts);
}
-return(0);
+ return(0);
}
//
btSoftBody::vsolver_t btSoftBody::getSolver(eVSolver::_ solver)
{
-switch(solver)
+ switch(solver)
{
case eVSolver::Linear: return(&btSoftBody::VSolve_Links);
}
-return(0);
+ return(0);
}
//
void btSoftBody::defaultCollisionHandler(btCollisionObject* pco)
{
-switch(m_cfg.collisions&fCollision::RVSmask)
+ switch(m_cfg.collisions&fCollision::RVSmask)
{
case fCollision::SDF_RS:
{
- btSoftColliders::CollideSDF_RS docollide;
- btRigidBody* prb=btRigidBody::upcast(pco);
- const btTransform wtr=prb->getInterpolationWorldTransform();
- const btTransform ctr=prb->getWorldTransform();
- const btScalar timemargin=(wtr.getOrigin()-ctr.getOrigin()).length();
- const btScalar basemargin=getCollisionShape()->getMargin();
- btVector3 mins;
- btVector3 maxs;
- ATTRIBUTE_ALIGNED16(btDbvtVolume) volume;
- pco->getCollisionShape()->getAabb( pco->getInterpolationWorldTransform(),
- mins,
- maxs);
- volume=btDbvtVolume::FromMM(mins,maxs);
- volume.Expand(btVector3(basemargin,basemargin,basemargin));
- docollide.psb = this;
- docollide.prb = prb;
- docollide.dynmargin = basemargin+timemargin;
- docollide.stamargin = basemargin;
- btDbvt::collideTV(m_ndbvt.m_root,volume,docollide);
- }
- break;
+ btSoftColliders::CollideSDF_RS docollide;
+ btRigidBody* prb1=btRigidBody::upcast(pco);
+ btTransform wtr=prb1 ? prb1->getInterpolationWorldTransform() : pco->getWorldTransform();
+
+ const btTransform ctr=pco->getWorldTransform();
+ const btScalar timemargin=(wtr.getOrigin()-ctr.getOrigin()).length();
+ const btScalar basemargin=getCollisionShape()->getMargin();
+ btVector3 mins;
+ btVector3 maxs;
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) volume;
+ pco->getCollisionShape()->getAabb( pco->getInterpolationWorldTransform(),
+ mins,
+ maxs);
+ volume=btDbvtVolume::FromMM(mins,maxs);
+ volume.Expand(btVector3(basemargin,basemargin,basemargin));
+ docollide.psb = this;
+ docollide.m_colObj1 = pco;
+ docollide.m_rigidBody = prb1;
+
+ docollide.dynmargin = basemargin+timemargin;
+ docollide.stamargin = basemargin;
+ m_ndbvt.collideTV(m_ndbvt.m_root,volume,docollide);
+ }
+ break;
case fCollision::CL_RS:
{
- btSoftColliders::CollideCL_RS collider;
- collider.Process(this,btRigidBody::upcast(pco));
+ btSoftColliders::CollideCL_RS collider;
+ collider.Process(this,pco);
}
- break;
+ break;
}
}
//
void btSoftBody::defaultCollisionHandler(btSoftBody* psb)
{
-const int cf=m_cfg.collisions&psb->m_cfg.collisions;
-switch(cf&fCollision::SVSmask)
+ const int cf=m_cfg.collisions&psb->m_cfg.collisions;
+ switch(cf&fCollision::SVSmask)
{
case fCollision::CL_SS:
{
- btSoftColliders::CollideCL_SS docollide;
- docollide.Process(this,psb);
+ btSoftColliders::CollideCL_SS docollide;
+ docollide.Process(this,psb);
}
- break;
+ break;
case fCollision::VF_SS:
{
- btSoftColliders::CollideVF_SS docollide;
- /* common */
- docollide.mrg= getCollisionShape()->getMargin()+
- psb->getCollisionShape()->getMargin();
- /* psb0 nodes vs psb1 faces */
- docollide.psb[0]=this;
- docollide.psb[1]=psb;
- btDbvt::collideTT( docollide.psb[0]->m_ndbvt.m_root,
- docollide.psb[1]->m_fdbvt.m_root,
- docollide);
- /* psb1 nodes vs psb0 faces */
- docollide.psb[0]=psb;
- docollide.psb[1]=this;
- btDbvt::collideTT( docollide.psb[0]->m_ndbvt.m_root,
- docollide.psb[1]->m_fdbvt.m_root,
- docollide);
- }
- break;
+ //only self-collision for Cluster, not Vertex-Face yet
+ if (this!=psb)
+ {
+ btSoftColliders::CollideVF_SS docollide;
+ /* common */
+ docollide.mrg= getCollisionShape()->getMargin()+
+ psb->getCollisionShape()->getMargin();
+ /* psb0 nodes vs psb1 faces */
+ docollide.psb[0]=this;
+ docollide.psb[1]=psb;
+ docollide.psb[0]->m_ndbvt.collideTT( docollide.psb[0]->m_ndbvt.m_root,
+ docollide.psb[1]->m_fdbvt.m_root,
+ docollide);
+ /* psb1 nodes vs psb0 faces */
+ docollide.psb[0]=psb;
+ docollide.psb[1]=this;
+ docollide.psb[0]->m_ndbvt.collideTT( docollide.psb[0]->m_ndbvt.m_root,
+ docollide.psb[1]->m_fdbvt.m_root,
+ docollide);
+ }
+ }
+ break;
}
}