Added several updates for btSoftBody: convex cluster collision detection, new constraints, new demos (only enabled in SoftBodyDemo, todo for AllBulletDemos) etc.

Thanks a lot to Nathanael Presson for this update.
This commit is contained in:
erwin.coumans
2008-07-22 02:22:01 +00:00
parent fe5033119b
commit d71f8d6623
9 changed files with 3223 additions and 1347 deletions

View File

@@ -14,7 +14,7 @@ subject to the following restrictions:
*/
///btSoftBodyHelpers.cpp by Nathanael Presson
#include "btSoftBody.h"
#include "btSoftBodyInternals.h"
#include <stdio.h>
#include <string.h>
#include "btSoftBodyHelpers.h"
@@ -78,6 +78,49 @@ if(node)
}
//
template <typename T>
static inline T sum(const btAlignedObjectArray<T>& items)
{
T v;
if(items.size())
{
v=items[0];
for(int i=1,ni=items.size();i<ni;++i)
{
v+=items[i];
}
}
return(v);
}
//
template <typename T,typename Q>
static inline void add(btAlignedObjectArray<T>& items,const Q& value)
{
for(int i=0,ni=items.size();i<ni;++i)
{
items[i]+=value;
}
}
//
template <typename T,typename Q>
static inline void mul(btAlignedObjectArray<T>& items,const Q& value)
{
for(int i=0,ni=items.size();i<ni;++i)
{
items[i]*=value;
}
}
//
template <typename T>
static inline T average(const btAlignedObjectArray<T>& items)
{
const btScalar n=(btScalar)(items.size()>0?items.size():1);
return(sum(items)/n);
}
//
static inline btScalar tetravolume(const btVector3& x0,
const btVector3& x1,
@@ -175,9 +218,7 @@ void btSoftBodyHelpers::Draw( btSoftBody* psb,
/* Anchors */
if(0!=(drawflags&fDrawFlags::Anchors))
{
int i;
for(i=0;i<psb->m_anchors.size();++i)
for(int i=0;i<psb->m_anchors.size();++i)
{
const btSoftBody::Anchor& a=psb->m_anchors[i];
const btVector3 q=a.m_body->getWorldTransform()*a.m_local;
@@ -185,7 +226,7 @@ void btSoftBodyHelpers::Draw( btSoftBody* psb,
drawVertex(idraw,q,0.25,btVector3(0,1,0));
idraw->drawLine(a.m_node->m_x,q,btVector3(1,1,1));
}
for(i=0;i<psb->m_nodes.size();++i)
for(int i=0;i<psb->m_nodes.size();++i)
{
const btSoftBody::Node& n=psb->m_nodes[i];
if(0==(n.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue;
@@ -207,20 +248,66 @@ void btSoftBodyHelpers::Draw( btSoftBody* psb,
if(0==(f.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue;
const btVector3 x[]={f.m_n[0]->m_x,f.m_n[1]->m_x,f.m_n[2]->m_x};
const btVector3 c=(x[0]+x[1]+x[2])/3;
/*idraw->drawLine((x[0]-c)*scl+c,(x[1]-c)*scl+c,col);
idraw->drawLine((x[1]-c)*scl+c,(x[2]-c)*scl+c,col);
idraw->drawLine((x[2]-c)*scl+c,(x[0]-c)*scl+c,col);*/
idraw->drawTriangle((x[0]-c)*scl+c,
(x[1]-c)*scl+c,
(x[2]-c)*scl+c,
col,alp);
/*idraw->drawTriangle((x[0]-c)*scl+c,
(x[1]-c)*scl+c,
(x[2]-c)*scl+c,
f.m_n[0]->m_n,f.m_n[1]->m_n,f.m_n[2]->m_n,
col,alp);*/
}
}
/* Clusters */
if(0!=(drawflags&fDrawFlags::Clusters))
{
srand(1806);
for(int i=0;i<psb->m_clusters.size();++i)
{
if(psb->m_clusters[i]->m_collide)
{
btVector3 color( rand()/(btScalar)RAND_MAX,
rand()/(btScalar)RAND_MAX,
rand()/(btScalar)RAND_MAX);
color=color.normalized()*0.75;
btAlignedObjectArray<btVector3> vertices;
vertices.resize(psb->m_clusters[i]->m_nodes.size());
for(int j=0,nj=vertices.size();j<nj;++j)
{
vertices[j]=psb->m_clusters[i]->m_nodes[j]->m_x;
}
HullDesc hdsc(QF_TRIANGLES,vertices.size(),&vertices[0]);
HullResult hres;
HullLibrary hlib;
hdsc.mMaxVertices=vertices.size();
hlib.CreateConvexHull(hdsc,hres);
const btVector3 center=average(hres.m_OutputVertices);
add(hres.m_OutputVertices,-center);
mul(hres.m_OutputVertices,(btScalar)1);
add(hres.m_OutputVertices,center);
for(int j=0;j<(int)hres.mNumFaces;++j)
{
const int idx[]={hres.m_Indices[j*3+0],hres.m_Indices[j*3+1],hres.m_Indices[j*3+2]};
idraw->drawTriangle(hres.m_OutputVertices[idx[0]],
hres.m_OutputVertices[idx[1]],
hres.m_OutputVertices[idx[2]],
color,1);
}
hlib.ReleaseResult(hres);
}
/* Velocities */
#if 0
for(int j=0;j<psb->m_clusters[i].m_nodes.size();++j)
{
const btSoftBody::Cluster& c=psb->m_clusters[i];
const btVector3 r=c.m_nodes[j]->m_x-c.m_com;
const btVector3 v=c.m_lv+cross(c.m_av,r);
idraw->drawLine(c.m_nodes[j]->m_x,c.m_nodes[j]->m_x+v,btVector3(1,0,0));
}
#endif
/* Frame */
btSoftBody::Cluster& c=*psb->m_clusters[i];
idraw->drawLine(c.m_com,c.m_framexform*btVector3(10,0,0),btVector3(1,0,0));
idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,10,0),btVector3(0,1,0));
idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,0,10),btVector3(0,0,1));
}
}
/* Notes */
if(0!=(drawflags&fDrawFlags::Notes))
{
@@ -235,6 +322,46 @@ void btSoftBodyHelpers::Draw( btSoftBody* psb,
idraw->draw3dText(p,n.m_text);
}
}
/* Node tree */
if(0!=(drawflags&fDrawFlags::NodeTree)) DrawNodeTree(psb,idraw);
/* Face tree */
if(0!=(drawflags&fDrawFlags::FaceTree)) DrawFaceTree(psb,idraw);
/* Cluster tree */
if(0!=(drawflags&fDrawFlags::ClusterTree)) DrawClusterTree(psb,idraw);
/* Joints */
if(0!=(drawflags&fDrawFlags::Joints))
{
for(int i=0;i<psb->m_joints.size();++i)
{
const btSoftBody::Joint* pj=psb->m_joints[i];
switch(pj->Type())
{
case btSoftBody::Joint::eType::Linear:
{
const btSoftBody::LJoint* pjl=(const btSoftBody::LJoint*)pj;
const btVector3 a0=pj->m_bodies[0].xform()*pjl->m_refs[0];
const btVector3 a1=pj->m_bodies[1].xform()*pjl->m_refs[1];
idraw->drawLine(pj->m_bodies[0].xform().getOrigin(),a0,btVector3(1,1,0));
idraw->drawLine(pj->m_bodies[1].xform().getOrigin(),a1,btVector3(0,1,1));
drawVertex(idraw,a0,0.25,btVector3(1,1,0));
drawVertex(idraw,a1,0.25,btVector3(0,1,1));
}
break;
case btSoftBody::Joint::eType::Angular:
{
const btSoftBody::AJoint* pja=(const btSoftBody::AJoint*)pj;
const btVector3 o0=pj->m_bodies[0].xform().getOrigin();
const btVector3 o1=pj->m_bodies[1].xform().getOrigin();
const btVector3 a0=pj->m_bodies[0].xform().getBasis()*pj->m_refs[0];
const btVector3 a1=pj->m_bodies[1].xform().getBasis()*pj->m_refs[1];
idraw->drawLine(o0,o0+a0*10,btVector3(1,1,0));
idraw->drawLine(o0,o0+a1*10,btVector3(1,1,0));
idraw->drawLine(o1,o1+a0*10,btVector3(0,1,1));
idraw->drawLine(o1,o1+a1*10,btVector3(0,1,1));
}
}
}
}
}
//
@@ -281,6 +408,15 @@ void btSoftBodyHelpers::DrawFaceTree( btSoftBody* psb,
drawTree(idraw,psb->m_fdbvt.m_root,0,btVector3(0,1,0),btVector3(1,0,0),mindepth,maxdepth);
}
//
void btSoftBodyHelpers::DrawClusterTree( btSoftBody* psb,
btIDebugDraw* idraw,
int mindepth,
int maxdepth)
{
drawTree(idraw,psb->m_cdbvt.m_root,0,btVector3(0,1,1),btVector3(1,0,0),mindepth,maxdepth);
}
//
void btSoftBodyHelpers::DrawFrame( btSoftBody* psb,
btIDebugDraw* idraw)
@@ -315,9 +451,7 @@ btSoftBody* btSoftBodyHelpers::CreateRope( btSoftBody::btSoftBodyWorldInfo& wor
const int r=res+2;
btVector3* x=new btVector3[r];
btScalar* m=new btScalar[r];
int i;
for(i=0;i<r;++i)
for(int i=0;i<r;++i)
{
const btScalar t=i/(btScalar)(r-1);
x[i]=lerp(from,to,t);
@@ -329,7 +463,7 @@ btSoftBody* btSoftBodyHelpers::CreateRope( btSoftBody::btSoftBodyWorldInfo& wor
delete[] x;
delete[] m;
/* Create links */
for(i=1;i<r;++i)
for(int i=1;i<r;++i)
{
psb->appendLink(i-1,i);
}
@@ -355,9 +489,7 @@ btSoftBody* btSoftBodyHelpers::CreatePatch(btSoftBody::btSoftBodyWorldInfo& wor
const int tot=rx*ry;
btVector3* x=new btVector3[tot];
btScalar* m=new btScalar[tot];
int iy;
for(iy=0;iy<ry;++iy)
for(int iy=0;iy<ry;++iy)
{
const btScalar ty=iy/(btScalar)(ry-1);
const btVector3 py0=lerp(corner00,corner01,ty);
@@ -377,7 +509,7 @@ btSoftBody* btSoftBodyHelpers::CreatePatch(btSoftBody::btSoftBodyWorldInfo& wor
delete[] x;
delete[] m;
/* Create links and faces */
for(iy=0;iy<ry;++iy)
for(int iy=0;iy<ry;++iy)
{
for(int ix=0;ix<rx;++ix)
{
@@ -452,10 +584,7 @@ btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBody::btSoftBodyWorldInf
int ntriangles)
{
int maxidx=0;
int i,j;
int ni;
for( i=0,ni=ntriangles*3;i<ni;++i)
for(int i=0,ni=ntriangles*3;i<ni;++i)
{
maxidx=btMax(triangles[i],maxidx);
}
@@ -464,12 +593,12 @@ btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBody::btSoftBodyWorldInf
btAlignedObjectArray<btVector3> vtx;
chks.resize(maxidx*maxidx,false);
vtx.resize(maxidx);
for( i=0,j=0,ni=maxidx*3;i<ni;++j,i+=3)
for(int i=0,j=0,ni=maxidx*3;i<ni;++j,i+=3)
{
vtx[j]=btVector3(vertices[i],vertices[i+1],vertices[i+2]);
}
btSoftBody* psb=new btSoftBody(&worldInfo,vtx.size(),&vtx[0],0);
for(i=0,ni=ntriangles*3;i<ni;i+=3)
for(int i=0,ni=ntriangles*3;i<ni;i+=3)
{
const int idx[]={triangles[i],triangles[i+1],triangles[i+2]};
#define IDX(_x_,_y_) ((_y_)*maxidx+(_x_))
@@ -513,4 +642,4 @@ btSoftBody* btSoftBodyHelpers::CreateFromConvexHull(btSoftBody::btSoftBodyWorld
hlib.ReleaseResult(hres);
psb->randomizeConstraints();
return(psb);
}
}