Applied polar decomposition patch. Fixes Issue 621. Thanks to Christian for the report, Joshua for the fix, Dongsoo for checking the fix.

Applied picking cloth patch. Fixes Issue 646. Thanks to Dongsoo.
Applied patch Softbody updateConstraints. Fixes Issue 503. Thanks to Dave Bruce Phillips and Dongsoo.
Fix various warnigns under Mac OSX.
This commit is contained in:
erwin.coumans
2012-09-09 17:22:30 +00:00
parent e208f99289
commit 3b83428a7f
40 changed files with 811 additions and 154 deletions

View File

@@ -110,7 +110,7 @@ void btSoftBody::initDefaults()
m_initialWorldTransform.setIdentity();
m_windVelocity = btVector3(0,0,0);
m_restLengthScale = btScalar(1.0);
}
//
@@ -505,6 +505,18 @@ void btSoftBody::addAeroForceToNode(const btVector3& windVelocity,int nodeInde
if ( 0 < n_dot_v && n_dot_v < 0.98480f)
fLift = 0.5f * kLF * medium.m_density * rel_v_len * tri_area * btSqrt(1.0f-n_dot_v*n_dot_v) * (nrm.cross(rel_v_nrm).cross(rel_v_nrm));
// Check if the velocity change resulted by aero drag force exceeds the current velocity of the node.
btVector3 del_v_by_fDrag = fDrag*n.m_im*m_sst.sdt;
btScalar del_v_by_fDrag_len2 = del_v_by_fDrag.length2();
btScalar v_len2 = n.m_v.length2();
if (del_v_by_fDrag_len2 >= v_len2 && del_v_by_fDrag_len2 > 0)
{
btScalar del_v_by_fDrag_len = del_v_by_fDrag.length();
btScalar v_len = n.m_v.length();
fDrag *= 0.8*(v_len / del_v_by_fDrag_len);
}
n.m_f += fDrag;
n.m_f += fLift;
}
@@ -535,8 +547,8 @@ void btSoftBody::addAeroForceToFace(const btVector3& windVelocity,int faceInde
const btScalar dt = m_sst.sdt;
const btScalar kLF = m_cfg.kLF;
const btScalar kDG = m_cfg.kDG;
const btScalar kPR = m_cfg.kPR;
const btScalar kVC = m_cfg.kVC;
// const btScalar kPR = m_cfg.kPR;
// const btScalar kVC = m_cfg.kVC;
const bool as_lift = kLF>0;
const bool as_drag = kDG>0;
const bool as_aero = as_lift || as_drag;
@@ -586,6 +598,18 @@ void btSoftBody::addAeroForceToFace(const btVector3& windVelocity,int faceInde
{
if (f.m_n[j]->m_im>0)
{
// Check if the velocity change resulted by aero drag force exceeds the current velocity of the node.
btVector3 del_v_by_fDrag = fDrag*f.m_n[j]->m_im*m_sst.sdt;
btScalar del_v_by_fDrag_len2 = del_v_by_fDrag.length2();
btScalar v_len2 = f.m_n[j]->m_v.length2();
if (del_v_by_fDrag_len2 >= v_len2 && del_v_by_fDrag_len2 > 0)
{
btScalar del_v_by_fDrag_len = del_v_by_fDrag.length();
btScalar v_len = f.m_n[j]->m_v.length();
fDrag *= 0.8*(v_len / del_v_by_fDrag_len);
}
f.m_n[j]->m_f += fDrag;
f.m_n[j]->m_f += fLift;
}
@@ -816,6 +840,27 @@ void btSoftBody::scale(const btVector3& scl)
updateConstants();
}
//
btScalar btSoftBody::getRestLengthScale()
{
return m_restLengthScale;
}
//
void btSoftBody::setRestLengthScale(btScalar restLengthScale)
{
for(int i=0, ni=m_links.size(); i<ni; ++i)
{
Link& l=m_links[i];
l.m_rl = l.m_rl / m_restLengthScale * restLengthScale;
l.m_c1 = l.m_rl*l.m_rl;
}
m_restLengthScale = restLengthScale;
if (getActivationState() == ISLAND_SLEEPING);
activate();
}
//
void btSoftBody::setPose(bool bvolume,bool bframe)
{
@@ -863,9 +908,20 @@ void btSoftBody::setPose(bool bvolume,bool bframe)
m_pose.m_aqq[2]+=mq.z()*q;
}
m_pose.m_aqq=m_pose.m_aqq.inverse();
updateConstants();
}
void btSoftBody::resetLinkRestLengths()
{
for(int i=0, ni=m_links.size();i<ni;++i)
{
Link& l = m_links[i];
l.m_rl = (l.m_n[0]->m_x-l.m_n[1]->m_x).length();
l.m_c1 = l.m_rl*l.m_rl;
}
}
//
btScalar btSoftBody::getVolume() const
{
@@ -1587,7 +1643,7 @@ 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 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;
@@ -2178,7 +2234,7 @@ bool btSoftBody::checkContact( const btCollisionObjectWrapper* colObjWrap,
{
btVector3 nrm;
const btCollisionShape *shp = colObjWrap->getCollisionShape();
const btRigidBody *tmpRigid = btRigidBody::upcast(colObjWrap->getCollisionObject());
// const btRigidBody *tmpRigid = btRigidBody::upcast(colObjWrap->getCollisionObject());
//const btTransform &wtr = tmpRigid ? tmpRigid->getWorldTransform() : colObjWrap->getWorldTransform();
const btTransform &wtr = colObjWrap->getWorldTransform();
//todo: check which transform is needed here
@@ -2307,51 +2363,93 @@ void btSoftBody::updatePose()
}
//
void btSoftBody::updateConstants()
void btSoftBody::updateArea(bool averageArea)
{
int i,ni;
/* Face area */
for(i=0,ni=m_faces.size();i<ni;++i)
{
Face& f=m_faces[i];
f.m_ra = AreaOf(f.m_n[0]->m_x,f.m_n[1]->m_x,f.m_n[2]->m_x);
}
/* Node area */
if (averageArea)
{
btAlignedObjectArray<int> counts;
counts.resize(m_nodes.size(),0);
for(i=0,ni=m_nodes.size();i<ni;++i)
{
m_nodes[i].m_area = 0;
}
for(i=0,ni=m_faces.size();i<ni;++i)
{
btSoftBody::Face& f=m_faces[i];
for(int j=0;j<3;++j)
{
const int index=(int)(f.m_n[j]-&m_nodes[0]);
counts[index]++;
f.m_n[j]->m_area+=btFabs(f.m_ra);
}
}
for(i=0,ni=m_nodes.size();i<ni;++i)
{
if(counts[i]>0)
m_nodes[i].m_area/=(btScalar)counts[i];
else
m_nodes[i].m_area=0;
}
}
else
{
// initialize node area as zero
for(i=0,ni=m_nodes.size();i<ni;++i)
{
m_nodes[i].m_area=0;
}
for(i=0,ni=m_faces.size();i<ni;++i)
{
btSoftBody::Face& f=m_faces[i];
for(int j=0;j<3;++j)
{
f.m_n[j]->m_area += f.m_ra;
}
}
for(i=0,ni=m_nodes.size();i<ni;++i)
{
m_nodes[i].m_area *= 0.3333333f;
}
}
}
void btSoftBody::updateLinkConstants()
{
int i,ni;
/* Links */
for(i=0,ni=m_links.size();i<ni;++i)
{
Link& l=m_links[i];
Material& m=*l.m_material;
l.m_rl = (l.m_n[0]->m_x-l.m_n[1]->m_x).length();
l.m_c0 = (l.m_n[0]->m_im+l.m_n[1]->m_im)/m.m_kLST;
l.m_c1 = l.m_rl*l.m_rl;
}
/* Faces */
for(i=0,ni=m_faces.size();i<ni;++i)
{
Face& f=m_faces[i];
f.m_ra = AreaOf(f.m_n[0]->m_x,f.m_n[1]->m_x,f.m_n[2]->m_x);
}
/* Area's */
btAlignedObjectArray<int> counts;
counts.resize(m_nodes.size(),0);
for(i=0,ni=m_nodes.size();i<ni;++i)
{
m_nodes[i].m_area = 0;
}
for(i=0,ni=m_faces.size();i<ni;++i)
{
btSoftBody::Face& f=m_faces[i];
for(int j=0;j<3;++j)
{
const int index=(int)(f.m_n[j]-&m_nodes[0]);
counts[index]++;
f.m_n[j]->m_area+=btFabs(f.m_ra);
}
}
for(i=0,ni=m_nodes.size();i<ni;++i)
{
if(counts[i]>0)
m_nodes[i].m_area/=(btScalar)counts[i];
else
m_nodes[i].m_area=0;
}
}
void btSoftBody::updateConstants()
{
resetLinkRestLengths();
updateLinkConstants();
updateArea();
}
//
void btSoftBody::initializeClusters()
{
@@ -2820,7 +2918,7 @@ void btSoftBody::applyForces()
{
BT_PROFILE("SoftBody applyForces");
const btScalar dt = m_sst.sdt;
// const btScalar dt = m_sst.sdt;
const btScalar kLF = m_cfg.kLF;
const btScalar kDG = m_cfg.kDG;
const btScalar kPR = m_cfg.kPR;
@@ -2831,10 +2929,10 @@ void btSoftBody::applyForces()
const bool as_volume = kVC>0;
const bool as_aero = as_lift ||
as_drag ;
const bool as_vaero = as_aero &&
(m_cfg.aeromodel < btSoftBody::eAeroModel::F_TwoSided);
const bool as_faero = as_aero &&
(m_cfg.aeromodel >= btSoftBody::eAeroModel::F_TwoSided);
//const bool as_vaero = as_aero &&
// (m_cfg.aeromodel < btSoftBody::eAeroModel::F_TwoSided);
//const bool as_faero = as_aero &&
// (m_cfg.aeromodel >= btSoftBody::eAeroModel::F_TwoSided);
const bool use_medium = as_aero;
const bool use_volume = as_pressure ||
as_volume ;
@@ -2877,7 +2975,7 @@ void btSoftBody::applyForces()
/* Per face forces */
for(i=0,ni=m_faces.size();i<ni;++i)
{
btSoftBody::Face& f=m_faces[i];
// btSoftBody::Face& f=m_faces[i];
/* Aerodynamics */
addAeroForceToFace(m_windVelocity, i);
@@ -3068,7 +3166,7 @@ void btSoftBody::defaultCollisionHandler(const btCollisionObjectWrapper* pcoWr
case fCollision::CL_RS:
{
btSoftColliders::CollideCL_RS collider;
collider.Process(this,pcoWrap);
collider.ProcessColObj(this,pcoWrap);
}
break;
}
@@ -3087,7 +3185,7 @@ void btSoftBody::defaultCollisionHandler(btSoftBody* psb)
if (this!=psb || psb->m_cfg.collisions&fCollision::CL_SELF)
{
btSoftColliders::CollideCL_SS docollide;
docollide.Process(this,psb);
docollide.ProcessSoftSoft(this,psb);
}
}

View File

@@ -671,6 +671,9 @@ public:
btTransform m_initialWorldTransform;
btVector3 m_windVelocity;
btScalar m_restLengthScale;
//
// Api
//
@@ -810,9 +813,15 @@ public:
void rotate( const btQuaternion& rot);
/* Scale */
void scale( const btVector3& scl);
/* Get link resting lengths scale */
btScalar getRestLengthScale();
/* Scale resting length of all springs */
void setRestLengthScale(btScalar restLength);
/* Set current state as pose */
void setPose( bool bvolume,
bool bframe);
/* Set current link lengths as resting lengths */
void resetLinkRestLengths();
/* Return the volume */
btScalar getVolume() const;
/* Cluster count */
@@ -954,6 +963,8 @@ public:
void updateBounds();
void updatePose();
void updateConstants();
void updateLinkConstants();
void updateArea(bool averageArea = true);
void initializeClusters();
void updateClusters();
void cleanupClusters();

View File

@@ -21,6 +21,7 @@ subject to the following restrictions:
#include "LinearMath/btQuickprof.h"
#include "LinearMath/btPolarDecomposition.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
#include "BulletCollision/CollisionShapes/btConvexInternalShape.h"
@@ -614,32 +615,8 @@ private:
//
static inline int PolarDecompose( const btMatrix3x3& m,btMatrix3x3& q,btMatrix3x3& s)
{
static const btScalar half=(btScalar)0.5;
static const btScalar accuracy=(btScalar)0.0001;
static const int maxiterations=16;
int i=0;
btScalar det=0;
q = Mul(m,1/btVector3(m[0][0],m[1][1],m[2][2]).length());
det = q.determinant();
if(!btFuzzyZero(det))
{
for(;i<maxiterations;++i)
{
q=Mul(Add(q,Mul(q.adjoint(),1/det).transpose()),half);
const btScalar ndet=q.determinant();
if(Sq(ndet-det)>accuracy) det=ndet; else break;
}
/* Final orthogonalization */
Orthogonalize(q);
/* Compute 'S' */
s=q.transpose()*m;
}
else
{
q.setIdentity();
s.setIdentity();
}
return(i);
static const btPolarDecomposition polar;
return polar.decompose(m, q, s);
}
//
@@ -753,7 +730,7 @@ struct btSoftColliders
}
}
}
void Process(btSoftBody* ps,const btCollisionObjectWrapper* colObWrap)
void ProcessColObj(btSoftBody* ps,const btCollisionObjectWrapper* colObWrap)
{
psb = ps;
m_colObjWrap = colObWrap;
@@ -815,7 +792,7 @@ struct btSoftColliders
}
}
void Process(btSoftBody* psa,btSoftBody* psb)
void ProcessSoftSoft(btSoftBody* psa,btSoftBody* psb)
{
idt = psa->m_sst.isdt;
//m_margin = (psa->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin())/2;

View File

@@ -58,8 +58,8 @@ void btSoftRigidCollisionAlgorithm::processCollision (const btCollisionObjectWra
(void)dispatchInfo;
(void)resultOut;
//printf("btSoftRigidCollisionAlgorithm\n");
const btCollisionObjectWrapper* softWrap = m_isSwapped?body1Wrap:body0Wrap;
const btCollisionObjectWrapper* rigidWrap = m_isSwapped?body0Wrap:body1Wrap;
// const btCollisionObjectWrapper* softWrap = m_isSwapped?body1Wrap:body0Wrap;
// const btCollisionObjectWrapper* rigidWrap = m_isSwapped?body0Wrap:body1Wrap;
btSoftBody* softBody = m_isSwapped? (btSoftBody*)body1Wrap->getCollisionObject() : (btSoftBody*)body0Wrap->getCollisionObject();
const btCollisionObjectWrapper* rigidCollisionObjectWrap = m_isSwapped? body0Wrap : body1Wrap;