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:
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user