2
Bullet Continuous Collision Detection and Physics Library
3
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
5
This software is provided 'as-is', without any express or implied warranty.
6
In no event will the authors be held liable for any damages arising from the use of this software.
7
Permission is granted to anyone to use this software for any purpose,
8
including commercial applications, and to alter it and redistribute it freely,
9
subject to the following restrictions:
11
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13
3. This notice may not be removed or altered from any source distribution.
15
///btSoftBodyHelpers.cpp by Nathanael Presson
17
#include "btSoftBodyInternals.h"
20
#include "btSoftBodyHelpers.h"
21
#include "LinearMath/btConvexHull.h"
22
#include "LinearMath/btConvexHullComputer.h"
26
static void drawVertex( btIDebugDraw* idraw,
27
const btVector3& x,btScalar s,const btVector3& c)
29
idraw->drawLine(x-btVector3(s,0,0),x+btVector3(s,0,0),c);
30
idraw->drawLine(x-btVector3(0,s,0),x+btVector3(0,s,0),c);
31
idraw->drawLine(x-btVector3(0,0,s),x+btVector3(0,0,s),c);
35
static void drawBox( btIDebugDraw* idraw,
36
const btVector3& mins,
37
const btVector3& maxs,
38
const btVector3& color)
40
const btVector3 c[]={ btVector3(mins.x(),mins.y(),mins.z()),
41
btVector3(maxs.x(),mins.y(),mins.z()),
42
btVector3(maxs.x(),maxs.y(),mins.z()),
43
btVector3(mins.x(),maxs.y(),mins.z()),
44
btVector3(mins.x(),mins.y(),maxs.z()),
45
btVector3(maxs.x(),mins.y(),maxs.z()),
46
btVector3(maxs.x(),maxs.y(),maxs.z()),
47
btVector3(mins.x(),maxs.y(),maxs.z())};
48
idraw->drawLine(c[0],c[1],color);idraw->drawLine(c[1],c[2],color);
49
idraw->drawLine(c[2],c[3],color);idraw->drawLine(c[3],c[0],color);
50
idraw->drawLine(c[4],c[5],color);idraw->drawLine(c[5],c[6],color);
51
idraw->drawLine(c[6],c[7],color);idraw->drawLine(c[7],c[4],color);
52
idraw->drawLine(c[0],c[4],color);idraw->drawLine(c[1],c[5],color);
53
idraw->drawLine(c[2],c[6],color);idraw->drawLine(c[3],c[7],color);
57
static void drawTree( btIDebugDraw* idraw,
58
const btDbvtNode* node,
60
const btVector3& ncolor,
61
const btVector3& lcolor,
67
if(node->isinternal()&&((depth<maxdepth)||(maxdepth<0)))
69
drawTree(idraw,node->childs[0],depth+1,ncolor,lcolor,mindepth,maxdepth);
70
drawTree(idraw,node->childs[1],depth+1,ncolor,lcolor,mindepth,maxdepth);
74
const btScalar scl=(btScalar)(node->isinternal()?1:1);
75
const btVector3 mi=node->volume.Center()-node->volume.Extents()*scl;
76
const btVector3 mx=node->volume.Center()+node->volume.Extents()*scl;
77
drawBox(idraw,mi,mx,node->isleaf()?lcolor:ncolor);
84
static inline T sum(const btAlignedObjectArray<T>& items)
90
for(int i=1,ni=items.size();i<ni;++i)
99
template <typename T,typename Q>
100
static inline void add(btAlignedObjectArray<T>& items,const Q& value)
102
for(int i=0,ni=items.size();i<ni;++i)
109
template <typename T,typename Q>
110
static inline void mul(btAlignedObjectArray<T>& items,const Q& value)
112
for(int i=0,ni=items.size();i<ni;++i)
119
template <typename T>
120
static inline T average(const btAlignedObjectArray<T>& items)
122
const btScalar n=(btScalar)(items.size()>0?items.size():1);
123
return(sum(items)/n);
127
static inline btScalar tetravolume(const btVector3& x0,
132
const btVector3 a=x1-x0;
133
const btVector3 b=x2-x0;
134
const btVector3 c=x3-x0;
135
return(btDot(a,btCross(b,c)));
140
static btVector3 stresscolor(btScalar stress)
142
static const btVector3 spectrum[]= { btVector3(1,0,1),
149
static const int ncolors=sizeof(spectrum)/sizeof(spectrum[0])-1;
150
static const btScalar one=1;
151
stress=btMax<btScalar>(0,btMin<btScalar>(1,stress))*ncolors;
152
const int sel=(int)stress;
153
const btScalar frc=stress-sel;
154
return(spectrum[sel]+(spectrum[sel+1]-spectrum[sel])*frc);
159
void btSoftBodyHelpers::Draw( btSoftBody* psb,
163
const btScalar scl=(btScalar)0.1;
164
const btScalar nscl=scl*5;
165
const btVector3 lcolor=btVector3(0,0,0);
166
const btVector3 ncolor=btVector3(1,1,1);
167
const btVector3 ccolor=btVector3(1,0,0);
171
if(0!=(drawflags&fDrawFlags::Clusters))
174
for(i=0;i<psb->m_clusters.size();++i)
176
if(psb->m_clusters[i]->m_collide)
178
btVector3 color( rand()/(btScalar)RAND_MAX,
179
rand()/(btScalar)RAND_MAX,
180
rand()/(btScalar)RAND_MAX);
181
color=color.normalized()*0.75;
182
btAlignedObjectArray<btVector3> vertices;
183
vertices.resize(psb->m_clusters[i]->m_nodes.size());
184
for(j=0,nj=vertices.size();j<nj;++j)
186
vertices[j]=psb->m_clusters[i]->m_nodes[j]->m_x;
188
#define USE_NEW_CONVEX_HULL_COMPUTER
189
#ifdef USE_NEW_CONVEX_HULL_COMPUTER
190
btConvexHullComputer computer;
191
int stride = sizeof(btVector3);
192
int count = vertices.size();
194
btScalar shrinkClamp=0.f;
195
computer.compute(&vertices[0].getX(),stride,count,shrink,shrinkClamp);
196
for (int i=0;i<computer.faces.size();i++)
199
int face = computer.faces[i];
200
//printf("face=%d\n",face);
201
const btConvexHullComputer::Edge* firstEdge = &computer.edges[face];
202
const btConvexHullComputer::Edge* edge = firstEdge->getNextEdgeOfFace();
204
int v0 = firstEdge->getSourceVertex();
205
int v1 = firstEdge->getTargetVertex();
206
while (edge!=firstEdge)
208
int v2 = edge->getTargetVertex();
209
idraw->drawTriangle(computer.vertices[v0],computer.vertices[v1],computer.vertices[v2],color,1);
210
edge = edge->getNextEdgeOfFace();
217
HullDesc hdsc(QF_TRIANGLES,vertices.size(),&vertices[0]);
220
hdsc.mMaxVertices=vertices.size();
221
hlib.CreateConvexHull(hdsc,hres);
222
const btVector3 center=average(hres.m_OutputVertices);
223
add(hres.m_OutputVertices,-center);
224
mul(hres.m_OutputVertices,(btScalar)1);
225
add(hres.m_OutputVertices,center);
226
for(j=0;j<(int)hres.mNumFaces;++j)
228
const int idx[]={hres.m_Indices[j*3+0],hres.m_Indices[j*3+1],hres.m_Indices[j*3+2]};
229
idraw->drawTriangle(hres.m_OutputVertices[idx[0]],
230
hres.m_OutputVertices[idx[1]],
231
hres.m_OutputVertices[idx[2]],
234
hlib.ReleaseResult(hres);
240
for(int j=0;j<psb->m_clusters[i].m_nodes.size();++j)
242
const btSoftBody::Cluster& c=psb->m_clusters[i];
243
const btVector3 r=c.m_nodes[j]->m_x-c.m_com;
244
const btVector3 v=c.m_lv+btCross(c.m_av,r);
245
idraw->drawLine(c.m_nodes[j]->m_x,c.m_nodes[j]->m_x+v,btVector3(1,0,0));
249
// btSoftBody::Cluster& c=*psb->m_clusters[i];
250
// idraw->drawLine(c.m_com,c.m_framexform*btVector3(10,0,0),btVector3(1,0,0));
251
// idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,10,0),btVector3(0,1,0));
252
// idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,0,10),btVector3(0,0,1));
258
if(0!=(drawflags&fDrawFlags::Nodes))
260
for(i=0;i<psb->m_nodes.size();++i)
262
const btSoftBody::Node& n=psb->m_nodes[i];
263
if(0==(n.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue;
264
idraw->drawLine(n.m_x-btVector3(scl,0,0),n.m_x+btVector3(scl,0,0),btVector3(1,0,0));
265
idraw->drawLine(n.m_x-btVector3(0,scl,0),n.m_x+btVector3(0,scl,0),btVector3(0,1,0));
266
idraw->drawLine(n.m_x-btVector3(0,0,scl),n.m_x+btVector3(0,0,scl),btVector3(0,0,1));
270
if(0!=(drawflags&fDrawFlags::Links))
272
for(i=0;i<psb->m_links.size();++i)
274
const btSoftBody::Link& l=psb->m_links[i];
275
if(0==(l.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue;
276
idraw->drawLine(l.m_n[0]->m_x,l.m_n[1]->m_x,lcolor);
280
if(0!=(drawflags&fDrawFlags::Normals))
282
for(i=0;i<psb->m_nodes.size();++i)
284
const btSoftBody::Node& n=psb->m_nodes[i];
285
if(0==(n.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue;
286
const btVector3 d=n.m_n*nscl;
287
idraw->drawLine(n.m_x,n.m_x+d,ncolor);
288
idraw->drawLine(n.m_x,n.m_x-d,ncolor*0.5);
292
if(0!=(drawflags&fDrawFlags::Contacts))
294
static const btVector3 axis[]={btVector3(1,0,0),
297
for(i=0;i<psb->m_rcontacts.size();++i)
299
const btSoftBody::RContact& c=psb->m_rcontacts[i];
300
const btVector3 o= c.m_node->m_x-c.m_cti.m_normal*
301
(btDot(c.m_node->m_x,c.m_cti.m_normal)+c.m_cti.m_offset);
302
const btVector3 x=btCross(c.m_cti.m_normal,axis[c.m_cti.m_normal.minAxis()]).normalized();
303
const btVector3 y=btCross(x,c.m_cti.m_normal).normalized();
304
idraw->drawLine(o-x*nscl,o+x*nscl,ccolor);
305
idraw->drawLine(o-y*nscl,o+y*nscl,ccolor);
306
idraw->drawLine(o,o+c.m_cti.m_normal*nscl*3,btVector3(1,1,0));
310
if(0!=(drawflags&fDrawFlags::Faces))
312
const btScalar scl=(btScalar)0.8;
313
const btScalar alp=(btScalar)1;
314
const btVector3 col(0,(btScalar)0.7,0);
315
for(i=0;i<psb->m_faces.size();++i)
317
const btSoftBody::Face& f=psb->m_faces[i];
318
if(0==(f.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue;
319
const btVector3 x[]={f.m_n[0]->m_x,f.m_n[1]->m_x,f.m_n[2]->m_x};
320
const btVector3 c=(x[0]+x[1]+x[2])/3;
321
idraw->drawTriangle((x[0]-c)*scl+c,
328
if(0!=(drawflags&fDrawFlags::Tetras))
330
const btScalar scl=(btScalar)0.8;
331
const btScalar alp=(btScalar)1;
332
const btVector3 col((btScalar)0.7,(btScalar)0.7,(btScalar)0.7);
333
for(int i=0;i<psb->m_tetras.size();++i)
335
const btSoftBody::Tetra& t=psb->m_tetras[i];
336
if(0==(t.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue;
337
const btVector3 x[]={t.m_n[0]->m_x,t.m_n[1]->m_x,t.m_n[2]->m_x,t.m_n[3]->m_x};
338
const btVector3 c=(x[0]+x[1]+x[2]+x[3])/4;
339
idraw->drawTriangle((x[0]-c)*scl+c,(x[1]-c)*scl+c,(x[2]-c)*scl+c,col,alp);
340
idraw->drawTriangle((x[0]-c)*scl+c,(x[1]-c)*scl+c,(x[3]-c)*scl+c,col,alp);
341
idraw->drawTriangle((x[1]-c)*scl+c,(x[2]-c)*scl+c,(x[3]-c)*scl+c,col,alp);
342
idraw->drawTriangle((x[2]-c)*scl+c,(x[0]-c)*scl+c,(x[3]-c)*scl+c,col,alp);
347
if(0!=(drawflags&fDrawFlags::Anchors))
349
for(i=0;i<psb->m_anchors.size();++i)
351
const btSoftBody::Anchor& a=psb->m_anchors[i];
352
const btVector3 q=a.m_body->getWorldTransform()*a.m_local;
353
drawVertex(idraw,a.m_node->m_x,0.25,btVector3(1,0,0));
354
drawVertex(idraw,q,0.25,btVector3(0,1,0));
355
idraw->drawLine(a.m_node->m_x,q,btVector3(1,1,1));
357
for(i=0;i<psb->m_nodes.size();++i)
359
const btSoftBody::Node& n=psb->m_nodes[i];
360
if(0==(n.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue;
363
drawVertex(idraw,n.m_x,0.25,btVector3(1,0,0));
370
if(0!=(drawflags&fDrawFlags::Notes))
372
for(i=0;i<psb->m_notes.size();++i)
374
const btSoftBody::Note& n=psb->m_notes[i];
375
btVector3 p=n.m_offset;
376
for(int j=0;j<n.m_rank;++j)
378
p+=n.m_nodes[j]->m_x*n.m_coords[j];
380
idraw->draw3dText(p,n.m_text);
384
if(0!=(drawflags&fDrawFlags::NodeTree)) DrawNodeTree(psb,idraw);
386
if(0!=(drawflags&fDrawFlags::FaceTree)) DrawFaceTree(psb,idraw);
388
if(0!=(drawflags&fDrawFlags::ClusterTree)) DrawClusterTree(psb,idraw);
390
if(0!=(drawflags&fDrawFlags::Joints))
392
for(i=0;i<psb->m_joints.size();++i)
394
const btSoftBody::Joint* pj=psb->m_joints[i];
397
case btSoftBody::Joint::eType::Linear:
399
const btSoftBody::LJoint* pjl=(const btSoftBody::LJoint*)pj;
400
const btVector3 a0=pj->m_bodies[0].xform()*pjl->m_refs[0];
401
const btVector3 a1=pj->m_bodies[1].xform()*pjl->m_refs[1];
402
idraw->drawLine(pj->m_bodies[0].xform().getOrigin(),a0,btVector3(1,1,0));
403
idraw->drawLine(pj->m_bodies[1].xform().getOrigin(),a1,btVector3(0,1,1));
404
drawVertex(idraw,a0,0.25,btVector3(1,1,0));
405
drawVertex(idraw,a1,0.25,btVector3(0,1,1));
408
case btSoftBody::Joint::eType::Angular:
410
//const btSoftBody::AJoint* pja=(const btSoftBody::AJoint*)pj;
411
const btVector3 o0=pj->m_bodies[0].xform().getOrigin();
412
const btVector3 o1=pj->m_bodies[1].xform().getOrigin();
413
const btVector3 a0=pj->m_bodies[0].xform().getBasis()*pj->m_refs[0];
414
const btVector3 a1=pj->m_bodies[1].xform().getBasis()*pj->m_refs[1];
415
idraw->drawLine(o0,o0+a0*10,btVector3(1,1,0));
416
idraw->drawLine(o0,o0+a1*10,btVector3(1,1,0));
417
idraw->drawLine(o1,o1+a0*10,btVector3(0,1,1));
418
idraw->drawLine(o1,o1+a1*10,btVector3(0,1,1));
431
void btSoftBodyHelpers::DrawInfos( btSoftBody* psb,
437
for(int i=0;i<psb->m_nodes.size();++i)
439
const btSoftBody::Node& n=psb->m_nodes[i];
444
sprintf(buff," M(%.2f)",1/n.m_im);
449
sprintf(buff," A(%.2f)",n.m_area);
452
if(text[0]) idraw->draw3dText(n.m_x,text);
457
void btSoftBodyHelpers::DrawNodeTree( btSoftBody* psb,
462
drawTree(idraw,psb->m_ndbvt.m_root,0,btVector3(1,0,1),btVector3(1,1,1),mindepth,maxdepth);
466
void btSoftBodyHelpers::DrawFaceTree( btSoftBody* psb,
471
drawTree(idraw,psb->m_fdbvt.m_root,0,btVector3(0,1,0),btVector3(1,0,0),mindepth,maxdepth);
475
void btSoftBodyHelpers::DrawClusterTree( btSoftBody* psb,
480
drawTree(idraw,psb->m_cdbvt.m_root,0,btVector3(0,1,1),btVector3(1,0,0),mindepth,maxdepth);
484
void btSoftBodyHelpers::DrawFrame( btSoftBody* psb,
487
if(psb->m_pose.m_bframe)
489
static const btScalar ascl=10;
490
static const btScalar nscl=(btScalar)0.1;
491
const btVector3 com=psb->m_pose.m_com;
492
const btMatrix3x3 trs=psb->m_pose.m_rot*psb->m_pose.m_scl;
493
const btVector3 Xaxis=(trs*btVector3(1,0,0)).normalized();
494
const btVector3 Yaxis=(trs*btVector3(0,1,0)).normalized();
495
const btVector3 Zaxis=(trs*btVector3(0,0,1)).normalized();
496
idraw->drawLine(com,com+Xaxis*ascl,btVector3(1,0,0));
497
idraw->drawLine(com,com+Yaxis*ascl,btVector3(0,1,0));
498
idraw->drawLine(com,com+Zaxis*ascl,btVector3(0,0,1));
499
for(int i=0;i<psb->m_pose.m_pos.size();++i)
501
const btVector3 x=com+trs*psb->m_pose.m_pos[i];
502
drawVertex(idraw,x,nscl,btVector3(1,0,1));
508
btSoftBody* btSoftBodyHelpers::CreateRope( btSoftBodyWorldInfo& worldInfo, const btVector3& from,
515
btVector3* x=new btVector3[r];
516
btScalar* m=new btScalar[r];
521
const btScalar t=i/(btScalar)(r-1);
522
x[i]=lerp(from,to,t);
525
btSoftBody* psb= new btSoftBody(&worldInfo,r,x,m);
526
if(fixeds&1) psb->setMass(0,0);
527
if(fixeds&2) psb->setMass(r-1,0);
533
psb->appendLink(i-1,i);
540
btSoftBody* btSoftBodyHelpers::CreatePatch(btSoftBodyWorldInfo& worldInfo,const btVector3& corner00,
541
const btVector3& corner10,
542
const btVector3& corner01,
543
const btVector3& corner11,
549
#define IDX(_x_,_y_) ((_y_)*rx+(_x_))
551
if((resx<2)||(resy<2)) return(0);
555
btVector3* x=new btVector3[tot];
556
btScalar* m=new btScalar[tot];
561
const btScalar ty=iy/(btScalar)(ry-1);
562
const btVector3 py0=lerp(corner00,corner01,ty);
563
const btVector3 py1=lerp(corner10,corner11,ty);
564
for(int ix=0;ix<rx;++ix)
566
const btScalar tx=ix/(btScalar)(rx-1);
567
x[IDX(ix,iy)]=lerp(py0,py1,tx);
571
btSoftBody* psb=new btSoftBody(&worldInfo,tot,x,m);
572
if(fixeds&1) psb->setMass(IDX(0,0),0);
573
if(fixeds&2) psb->setMass(IDX(rx-1,0),0);
574
if(fixeds&4) psb->setMass(IDX(0,ry-1),0);
575
if(fixeds&8) psb->setMass(IDX(rx-1,ry-1),0);
578
/* Create links and faces */
581
for(int ix=0;ix<rx;++ix)
583
const int idx=IDX(ix,iy);
584
const bool mdx=(ix+1)<rx;
585
const bool mdy=(iy+1)<ry;
586
if(mdx) psb->appendLink(idx,IDX(ix+1,iy));
587
if(mdy) psb->appendLink(idx,IDX(ix,iy+1));
592
psb->appendFace(IDX(ix,iy),IDX(ix+1,iy),IDX(ix+1,iy+1));
593
psb->appendFace(IDX(ix,iy),IDX(ix+1,iy+1),IDX(ix,iy+1));
596
psb->appendLink(IDX(ix,iy),IDX(ix+1,iy+1));
601
psb->appendFace(IDX(ix,iy+1),IDX(ix,iy),IDX(ix+1,iy));
602
psb->appendFace(IDX(ix,iy+1),IDX(ix+1,iy),IDX(ix+1,iy+1));
605
psb->appendLink(IDX(ix+1,iy),IDX(ix,iy+1));
617
btSoftBody* btSoftBodyHelpers::CreatePatchUV(btSoftBodyWorldInfo& worldInfo,
618
const btVector3& corner00,
619
const btVector3& corner10,
620
const btVector3& corner01,
621
const btVector3& corner11,
633
* [0][0] corner00 ------- corner01 [resx][0]
636
* [0][resy] corner10 -------- corner11 [resx][resy]
649
* upper middle --> +16
650
* left middle --> +32
651
* right middle --> +64
652
* lower middle --> +128
656
* tex_coords size (resx-1)*(resy-1)*12
660
* SINGLE QUAD INTERNALS
662
* 1) btSoftBody's nodes and links,
663
* diagonal link is optional ("gendiags")
666
* node00 ------ node01
678
* UV Coordinates (hier example for single quad)
696
#define IDX(_x_,_y_) ((_y_)*rx+(_x_))
698
if((resx<2)||(resy<2)) return(0);
702
btVector3* x=new btVector3[tot];
703
btScalar* m=new btScalar[tot];
709
const btScalar ty=iy/(btScalar)(ry-1);
710
const btVector3 py0=lerp(corner00,corner01,ty);
711
const btVector3 py1=lerp(corner10,corner11,ty);
712
for(int ix=0;ix<rx;++ix)
714
const btScalar tx=ix/(btScalar)(rx-1);
715
x[IDX(ix,iy)]=lerp(py0,py1,tx);
719
btSoftBody* psb=new btSoftBody(&worldInfo,tot,x,m);
720
if(fixeds&1) psb->setMass(IDX(0,0),0);
721
if(fixeds&2) psb->setMass(IDX(rx-1,0),0);
722
if(fixeds&4) psb->setMass(IDX(0,ry-1),0);
723
if(fixeds&8) psb->setMass(IDX(rx-1,ry-1),0);
724
if(fixeds&16) psb->setMass(IDX((rx-1)/2,0),0);
725
if(fixeds&32) psb->setMass(IDX(0,(ry-1)/2),0);
726
if(fixeds&64) psb->setMass(IDX(rx-1,(ry-1)/2),0);
727
if(fixeds&128) psb->setMass(IDX((rx-1)/2,ry-1),0);
728
if(fixeds&256) psb->setMass(IDX((rx-1)/2,(ry-1)/2),0);
734
/* Create links and faces */
737
for(int ix=0;ix<rx;++ix)
739
const bool mdx=(ix+1)<rx;
740
const bool mdy=(iy+1)<ry;
742
int node00=IDX(ix,iy);
743
int node01=IDX(ix+1,iy);
744
int node10=IDX(ix,iy+1);
745
int node11=IDX(ix+1,iy+1);
747
if(mdx) psb->appendLink(node00,node01);
748
if(mdy) psb->appendLink(node00,node10);
751
psb->appendFace(node00,node10,node11);
753
tex_coords[z+0]=CalculateUV(resx,resy,ix,iy,0);
754
tex_coords[z+1]=CalculateUV(resx,resy,ix,iy,1);
755
tex_coords[z+2]=CalculateUV(resx,resy,ix,iy,0);
756
tex_coords[z+3]=CalculateUV(resx,resy,ix,iy,2);
757
tex_coords[z+4]=CalculateUV(resx,resy,ix,iy,3);
758
tex_coords[z+5]=CalculateUV(resx,resy,ix,iy,2);
760
psb->appendFace(node11,node01,node00);
762
tex_coords[z+6 ]=CalculateUV(resx,resy,ix,iy,3);
763
tex_coords[z+7 ]=CalculateUV(resx,resy,ix,iy,2);
764
tex_coords[z+8 ]=CalculateUV(resx,resy,ix,iy,3);
765
tex_coords[z+9 ]=CalculateUV(resx,resy,ix,iy,1);
766
tex_coords[z+10]=CalculateUV(resx,resy,ix,iy,0);
767
tex_coords[z+11]=CalculateUV(resx,resy,ix,iy,1);
769
if (gendiags) psb->appendLink(node00,node11);
779
float btSoftBodyHelpers::CalculateUV(int resx,int resy,int ix,int iy,int id)
809
tc = (1.0f/((resx-1))*ix);
812
tc = (1.0f/((resy-1))*(resy-1-iy));
815
tc = (1.0f/((resy-1))*(resy-1-iy-1));
818
tc = (1.0f/((resx-1))*(ix+1));
823
btSoftBody* btSoftBodyHelpers::CreateEllipsoid(btSoftBodyWorldInfo& worldInfo,const btVector3& center,
824
const btVector3& radius,
829
static void Generate(btVector3* x,int n)
834
for(int j=i;j;p*=0.5,j>>=1) if(j&1) t+=p;
836
btScalar a=(SIMD_PI+2*i*SIMD_PI)/n;
837
btScalar s=btSqrt(1-w*w);
838
*x++=btVector3(s*btCos(a),s*btSin(a),w);
842
btAlignedObjectArray<btVector3> vtx;
844
Hammersley::Generate(&vtx[0],vtx.size());
845
for(int i=0;i<vtx.size();++i)
847
vtx[i]=vtx[i]*radius+center;
849
return(CreateFromConvexHull(worldInfo,&vtx[0],vtx.size()));
855
btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBodyWorldInfo& worldInfo,const btScalar* vertices,
856
const int* triangles,
857
int ntriangles, bool randomizeConstraints)
862
for(i=0,ni=ntriangles*3;i<ni;++i)
864
maxidx=btMax(triangles[i],maxidx);
867
btAlignedObjectArray<bool> chks;
868
btAlignedObjectArray<btVector3> vtx;
869
chks.resize(maxidx*maxidx,false);
871
for(i=0,j=0,ni=maxidx*3;i<ni;++j,i+=3)
873
vtx[j]=btVector3(vertices[i],vertices[i+1],vertices[i+2]);
875
btSoftBody* psb=new btSoftBody(&worldInfo,vtx.size(),&vtx[0],0);
876
for( i=0,ni=ntriangles*3;i<ni;i+=3)
878
const int idx[]={triangles[i],triangles[i+1],triangles[i+2]};
879
#define IDX(_x_,_y_) ((_y_)*maxidx+(_x_))
880
for(int j=2,k=0;k<3;j=k++)
882
if(!chks[IDX(idx[j],idx[k])])
884
chks[IDX(idx[j],idx[k])]=true;
885
chks[IDX(idx[k],idx[j])]=true;
886
psb->appendLink(idx[j],idx[k]);
890
psb->appendFace(idx[0],idx[1],idx[2]);
893
if (randomizeConstraints)
895
psb->randomizeConstraints();
902
btSoftBody* btSoftBodyHelpers::CreateFromConvexHull(btSoftBodyWorldInfo& worldInfo, const btVector3* vertices,
903
int nvertices, bool randomizeConstraints)
905
HullDesc hdsc(QF_TRIANGLES,nvertices,vertices);
907
HullLibrary hlib;/*??*/
908
hdsc.mMaxVertices=nvertices;
909
hlib.CreateConvexHull(hdsc,hres);
910
btSoftBody* psb=new btSoftBody(&worldInfo,(int)hres.mNumOutputVertices,
911
&hres.m_OutputVertices[0],0);
912
for(int i=0;i<(int)hres.mNumFaces;++i)
914
const int idx[]={ hres.m_Indices[i*3+0],
915
hres.m_Indices[i*3+1],
916
hres.m_Indices[i*3+2]};
917
if(idx[0]<idx[1]) psb->appendLink( idx[0],idx[1]);
918
if(idx[1]<idx[2]) psb->appendLink( idx[1],idx[2]);
919
if(idx[2]<idx[0]) psb->appendLink( idx[2],idx[0]);
920
psb->appendFace(idx[0],idx[1],idx[2]);
922
hlib.ReleaseResult(hres);
923
if (randomizeConstraints)
925
psb->randomizeConstraints();
933
static int nextLine(const char* buffer)
937
while (*buffer != '\n')
952
/* Create from TetGen .ele, .face, .node data */
953
btSoftBody* btSoftBodyHelpers::CreateFromTetGenData(btSoftBodyWorldInfo& worldInfo,
959
bool bfacesfromtetras)
961
btAlignedObjectArray<btVector3> pos;
966
int result = sscanf(node,"%d %d %d %d",&nnode,&ndims,&nattrb,&hasbounds);
967
result = sscanf(node,"%d %d %d %d",&nnode,&ndims,&nattrb,&hasbounds);
968
node += nextLine(node);
971
for(int i=0;i<pos.size();++i)
976
sscanf(node,"%d %f %f %f",&index,&x,&y,&z);
979
// sn>>x;sn>>y;sn>>z;
980
node += nextLine(node);
982
//for(int j=0;j<nattrb;++j)
988
pos[index].setX(btScalar(x));
989
pos[index].setY(btScalar(y));
990
pos[index].setZ(btScalar(z));
992
btSoftBody* psb=new btSoftBody(&worldInfo,nnode,&pos[0],0);
997
sf>>nface;sf>>hasbounds;
998
for(int i=0;i<nface;++i)
1004
sf>>ni[0];sf>>ni[1];sf>>ni[2];
1006
psb->appendFace(ni[0],ni[1],ni[2]);
1009
psb->appendLink(ni[0],ni[1],0,true);
1010
psb->appendLink(ni[1],ni[2],0,true);
1011
psb->appendLink(ni[2],ni[0],0,true);
1022
sscanf(ele,"%d %d %d",&ntetra,&ncorner,&neattrb);
1023
ele += nextLine(ele);
1025
//se>>ntetra;se>>ncorner;se>>neattrb;
1026
for(int i=0;i<ntetra;++i)
1032
//se>>ni[0];se>>ni[1];se>>ni[2];se>>ni[3];
1033
sscanf(ele,"%d %d %d %d %d",&index,&ni[0],&ni[1],&ni[2],&ni[3]);
1035
//for(int j=0;j<neattrb;++j)
1037
psb->appendTetra(ni[0],ni[1],ni[2],ni[3]);
1040
psb->appendLink(ni[0],ni[1],0,true);
1041
psb->appendLink(ni[1],ni[2],0,true);
1042
psb->appendLink(ni[2],ni[0],0,true);
1043
psb->appendLink(ni[0],ni[3],0,true);
1044
psb->appendLink(ni[1],ni[3],0,true);
1045
psb->appendLink(ni[2],ni[3],0,true);
1049
printf("Nodes: %u\r\n",psb->m_nodes.size());
1050
printf("Links: %u\r\n",psb->m_links.size());
1051
printf("Faces: %u\r\n",psb->m_faces.size());
1052
printf("Tetras: %u\r\n",psb->m_tetras.size());