Bullet Collision Detection & Physics Library
btSoftBodyHelpers.cpp
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
4 
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:
10 
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.
14 */
16 
17 #include "btSoftBodyInternals.h"
18 #include <stdio.h>
19 #include <string.h>
20 #include "btSoftBodyHelpers.h"
23 
24 //
25 static void drawVertex(btIDebugDraw* idraw,
26  const btVector3& x, btScalar s, const btVector3& c)
27 {
28  idraw->drawLine(x - btVector3(s, 0, 0), x + btVector3(s, 0, 0), c);
29  idraw->drawLine(x - btVector3(0, s, 0), x + btVector3(0, s, 0), c);
30  idraw->drawLine(x - btVector3(0, 0, s), x + btVector3(0, 0, s), c);
31 }
32 
33 //
34 static void drawBox(btIDebugDraw* idraw,
35  const btVector3& mins,
36  const btVector3& maxs,
37  const btVector3& color)
38 {
39  const btVector3 c[] = {btVector3(mins.x(), mins.y(), mins.z()),
40  btVector3(maxs.x(), mins.y(), mins.z()),
41  btVector3(maxs.x(), maxs.y(), mins.z()),
42  btVector3(mins.x(), maxs.y(), mins.z()),
43  btVector3(mins.x(), mins.y(), maxs.z()),
44  btVector3(maxs.x(), mins.y(), maxs.z()),
45  btVector3(maxs.x(), maxs.y(), maxs.z()),
46  btVector3(mins.x(), maxs.y(), maxs.z())};
47  idraw->drawLine(c[0], c[1], color);
48  idraw->drawLine(c[1], c[2], color);
49  idraw->drawLine(c[2], c[3], color);
50  idraw->drawLine(c[3], c[0], color);
51  idraw->drawLine(c[4], c[5], color);
52  idraw->drawLine(c[5], c[6], color);
53  idraw->drawLine(c[6], c[7], color);
54  idraw->drawLine(c[7], c[4], color);
55  idraw->drawLine(c[0], c[4], color);
56  idraw->drawLine(c[1], c[5], color);
57  idraw->drawLine(c[2], c[6], color);
58  idraw->drawLine(c[3], c[7], color);
59 }
60 
61 //
62 static void drawTree(btIDebugDraw* idraw,
63  const btDbvtNode* node,
64  int depth,
65  const btVector3& ncolor,
66  const btVector3& lcolor,
67  int mindepth,
68  int maxdepth)
69 {
70  if (node)
71  {
72  if (node->isinternal() && ((depth < maxdepth) || (maxdepth < 0)))
73  {
74  drawTree(idraw, node->childs[0], depth + 1, ncolor, lcolor, mindepth, maxdepth);
75  drawTree(idraw, node->childs[1], depth + 1, ncolor, lcolor, mindepth, maxdepth);
76  }
77  if (depth >= mindepth)
78  {
79  const btScalar scl = (btScalar)(node->isinternal() ? 1 : 1);
80  const btVector3 mi = node->volume.Center() - node->volume.Extents() * scl;
81  const btVector3 mx = node->volume.Center() + node->volume.Extents() * scl;
82  drawBox(idraw, mi, mx, node->isleaf() ? lcolor : ncolor);
83  }
84  }
85 }
86 
87 //
88 template <typename T>
89 static inline T sum(const btAlignedObjectArray<T>& items)
90 {
91  T v;
92  if (items.size())
93  {
94  v = items[0];
95  for (int i = 1, ni = items.size(); i < ni; ++i)
96  {
97  v += items[i];
98  }
99  }
100  return (v);
101 }
102 
103 //
104 template <typename T, typename Q>
105 static inline void add(btAlignedObjectArray<T>& items, const Q& value)
106 {
107  for (int i = 0, ni = items.size(); i < ni; ++i)
108  {
109  items[i] += value;
110  }
111 }
112 
113 //
114 template <typename T, typename Q>
115 static inline void mul(btAlignedObjectArray<T>& items, const Q& value)
116 {
117  for (int i = 0, ni = items.size(); i < ni; ++i)
118  {
119  items[i] *= value;
120  }
121 }
122 
123 //
124 template <typename T>
125 static inline T average(const btAlignedObjectArray<T>& items)
126 {
127  const btScalar n = (btScalar)(items.size() > 0 ? items.size() : 1);
128  return (sum(items) / n);
129 }
130 
131 #if 0
132 //
133  inline static btScalar tetravolume(const btVector3& x0,
134  const btVector3& x1,
135  const btVector3& x2,
136  const btVector3& x3)
137 {
138  const btVector3 a=x1-x0;
139  const btVector3 b=x2-x0;
140  const btVector3 c=x3-x0;
141  return(btDot(a,btCross(b,c)));
142 }
143 #endif
144 
145 //
146 #if 0
147 static btVector3 stresscolor(btScalar stress)
148 {
149  static const btVector3 spectrum[]= { btVector3(1,0,1),
150  btVector3(0,0,1),
151  btVector3(0,1,1),
152  btVector3(0,1,0),
153  btVector3(1,1,0),
154  btVector3(1,0,0),
155  btVector3(1,0,0)};
156  static const int ncolors=sizeof(spectrum)/sizeof(spectrum[0])-1;
157  static const btScalar one=1;
158  stress=btMax<btScalar>(0,btMin<btScalar>(1,stress))*ncolors;
159  const int sel=(int)stress;
160  const btScalar frc=stress-sel;
161  return(spectrum[sel]+(spectrum[sel+1]-spectrum[sel])*frc);
162 }
163 #endif
164 
165 //
167  btIDebugDraw* idraw,
168  int drawflags)
169 {
170  const btScalar scl = (btScalar)0.1;
171  const btScalar nscl = scl * 5;
172  const btVector3 lcolor = btVector3(0, 0, 0);
173  const btVector3 ncolor = btVector3(1, 1, 1);
174  const btVector3 ccolor = btVector3(1, 0, 0);
175  int i, j, nj;
176 
177  /* Clusters */
178  if (0 != (drawflags & fDrawFlags::Clusters))
179  {
180  srand(1806);
181  for (i = 0; i < psb->m_clusters.size(); ++i)
182  {
183  if (psb->m_clusters[i]->m_collide)
184  {
185  btVector3 color(rand() / (btScalar)RAND_MAX,
186  rand() / (btScalar)RAND_MAX,
187  rand() / (btScalar)RAND_MAX);
188  color = color.normalized() * 0.75;
190  vertices.resize(psb->m_clusters[i]->m_nodes.size());
191  for (j = 0, nj = vertices.size(); j < nj; ++j)
192  {
193  vertices[j] = psb->m_clusters[i]->m_nodes[j]->m_x;
194  }
195 #define USE_NEW_CONVEX_HULL_COMPUTER
196 #ifdef USE_NEW_CONVEX_HULL_COMPUTER
197  btConvexHullComputer computer;
198  int stride = sizeof(btVector3);
199  int count = vertices.size();
200  btScalar shrink = 0.f;
201  btScalar shrinkClamp = 0.f;
202  computer.compute(&vertices[0].getX(), stride, count, shrink, shrinkClamp);
203  for (int i = 0; i < computer.faces.size(); i++)
204  {
205  int face = computer.faces[i];
206  //printf("face=%d\n",face);
207  const btConvexHullComputer::Edge* firstEdge = &computer.edges[face];
208  const btConvexHullComputer::Edge* edge = firstEdge->getNextEdgeOfFace();
209 
210  int v0 = firstEdge->getSourceVertex();
211  int v1 = firstEdge->getTargetVertex();
212  while (edge != firstEdge)
213  {
214  int v2 = edge->getTargetVertex();
215  idraw->drawTriangle(computer.vertices[v0], computer.vertices[v1], computer.vertices[v2], color, 1);
216  edge = edge->getNextEdgeOfFace();
217  v0 = v1;
218  v1 = v2;
219  };
220  }
221 #else
222 
223  HullDesc hdsc(QF_TRIANGLES, vertices.size(), &vertices[0]);
224  HullResult hres;
225  HullLibrary hlib;
226  hdsc.mMaxVertices = vertices.size();
227  hlib.CreateConvexHull(hdsc, hres);
228  const btVector3 center = average(hres.m_OutputVertices);
229  add(hres.m_OutputVertices, -center);
230  mul(hres.m_OutputVertices, (btScalar)1);
231  add(hres.m_OutputVertices, center);
232  for (j = 0; j < (int)hres.mNumFaces; ++j)
233  {
234  const int idx[] = {hres.m_Indices[j * 3 + 0], hres.m_Indices[j * 3 + 1], hres.m_Indices[j * 3 + 2]};
235  idraw->drawTriangle(hres.m_OutputVertices[idx[0]],
236  hres.m_OutputVertices[idx[1]],
237  hres.m_OutputVertices[idx[2]],
238  color, 1);
239  }
240  hlib.ReleaseResult(hres);
241 #endif
242  }
243  /* Velocities */
244 #if 0
245  for(int j=0;j<psb->m_clusters[i].m_nodes.size();++j)
246  {
247  const btSoftBody::Cluster& c=psb->m_clusters[i];
248  const btVector3 r=c.m_nodes[j]->m_x-c.m_com;
249  const btVector3 v=c.m_lv+btCross(c.m_av,r);
250  idraw->drawLine(c.m_nodes[j]->m_x,c.m_nodes[j]->m_x+v,btVector3(1,0,0));
251  }
252 #endif
253  /* Frame */
254  // btSoftBody::Cluster& c=*psb->m_clusters[i];
255  // idraw->drawLine(c.m_com,c.m_framexform*btVector3(10,0,0),btVector3(1,0,0));
256  // idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,10,0),btVector3(0,1,0));
257  // idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,0,10),btVector3(0,0,1));
258  }
259  }
260  else
261  {
262  /* Nodes */
263  if (0 != (drawflags & fDrawFlags::Nodes))
264  {
265  for (i = 0; i < psb->m_nodes.size(); ++i)
266  {
267  const btSoftBody::Node& n = psb->m_nodes[i];
268  if (0 == (n.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue;
269  idraw->drawLine(n.m_x - btVector3(scl, 0, 0), n.m_x + btVector3(scl, 0, 0), btVector3(1, 0, 0));
270  idraw->drawLine(n.m_x - btVector3(0, scl, 0), n.m_x + btVector3(0, scl, 0), btVector3(0, 1, 0));
271  idraw->drawLine(n.m_x - btVector3(0, 0, scl), n.m_x + btVector3(0, 0, scl), btVector3(0, 0, 1));
272  }
273  }
274  /* Links */
275  if (0 != (drawflags & fDrawFlags::Links))
276  {
277  for (i = 0; i < psb->m_links.size(); ++i)
278  {
279  const btSoftBody::Link& l = psb->m_links[i];
280  if (0 == (l.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue;
281  idraw->drawLine(l.m_n[0]->m_x, l.m_n[1]->m_x, lcolor);
282  }
283  }
284  /* Normals */
285  if (0 != (drawflags & fDrawFlags::Normals))
286  {
287  for (i = 0; i < psb->m_nodes.size(); ++i)
288  {
289  const btSoftBody::Node& n = psb->m_nodes[i];
290  if (0 == (n.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue;
291  const btVector3 d = n.m_n * nscl;
292  idraw->drawLine(n.m_x, n.m_x + d, ncolor);
293  idraw->drawLine(n.m_x, n.m_x - d, ncolor * 0.5);
294  }
295  }
296  /* Contacts */
297  if (0 != (drawflags & fDrawFlags::Contacts))
298  {
299  static const btVector3 axis[] = {btVector3(1, 0, 0),
300  btVector3(0, 1, 0),
301  btVector3(0, 0, 1)};
302  for (i = 0; i < psb->m_rcontacts.size(); ++i)
303  {
304  const btSoftBody::RContact& c = psb->m_rcontacts[i];
305  const btVector3 o = c.m_node->m_x - c.m_cti.m_normal *
306  (btDot(c.m_node->m_x, c.m_cti.m_normal) + c.m_cti.m_offset);
307  const btVector3 x = btCross(c.m_cti.m_normal, axis[c.m_cti.m_normal.minAxis()]).normalized();
308  const btVector3 y = btCross(x, c.m_cti.m_normal).normalized();
309  idraw->drawLine(o - x * nscl, o + x * nscl, ccolor);
310  idraw->drawLine(o - y * nscl, o + y * nscl, ccolor);
311  idraw->drawLine(o, o + c.m_cti.m_normal * nscl * 3, btVector3(1, 1, 0));
312  }
313  }
314  /* Faces */
315  if (0 != (drawflags & fDrawFlags::Faces))
316  {
317  const btScalar scl = (btScalar)0.8;
318  const btScalar alp = (btScalar)1;
319  const btVector3 col(0, (btScalar)0.7, 0);
320  for (i = 0; i < psb->m_faces.size(); ++i)
321  {
322  const btSoftBody::Face& f = psb->m_faces[i];
323  if (0 == (f.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue;
324  const btVector3 x[] = {f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x};
325  const btVector3 c = (x[0] + x[1] + x[2]) / 3;
326  idraw->drawTriangle((x[0] - c) * scl + c,
327  (x[1] - c) * scl + c,
328  (x[2] - c) * scl + c,
329  col, alp);
330  }
331  }
332  /* Tetras */
333  if (0 != (drawflags & fDrawFlags::Tetras))
334  {
335  const btScalar scl = (btScalar)0.8;
336  const btScalar alp = (btScalar)1;
337  const btVector3 col((btScalar)0.3, (btScalar)0.3, (btScalar)0.7);
338  for (int i = 0; i < psb->m_tetras.size(); ++i)
339  {
340  const btSoftBody::Tetra& t = psb->m_tetras[i];
341  if (0 == (t.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue;
342  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};
343  const btVector3 c = (x[0] + x[1] + x[2] + x[3]) / 4;
344  idraw->drawTriangle((x[0] - c) * scl + c, (x[1] - c) * scl + c, (x[2] - c) * scl + c, col, alp);
345  idraw->drawTriangle((x[0] - c) * scl + c, (x[1] - c) * scl + c, (x[3] - c) * scl + c, col, alp);
346  idraw->drawTriangle((x[1] - c) * scl + c, (x[2] - c) * scl + c, (x[3] - c) * scl + c, col, alp);
347  idraw->drawTriangle((x[2] - c) * scl + c, (x[0] - c) * scl + c, (x[3] - c) * scl + c, col, alp);
348  }
349  }
350  }
351  /* Anchors */
352  if (0 != (drawflags & fDrawFlags::Anchors))
353  {
354  for (i = 0; i < psb->m_anchors.size(); ++i)
355  {
356  const btSoftBody::Anchor& a = psb->m_anchors[i];
357  const btVector3 q = a.m_body->getWorldTransform() * a.m_local;
358  drawVertex(idraw, a.m_node->m_x, 0.25, btVector3(1, 0, 0));
359  drawVertex(idraw, q, 0.25, btVector3(0, 1, 0));
360  idraw->drawLine(a.m_node->m_x, q, btVector3(1, 1, 1));
361  }
362  for (i = 0; i < psb->m_nodes.size(); ++i)
363  {
364  const btSoftBody::Node& n = psb->m_nodes[i];
365  if (0 == (n.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue;
366  if (n.m_im <= 0)
367  {
368  drawVertex(idraw, n.m_x, 0.25, btVector3(1, 0, 0));
369  }
370  }
371  }
372 
373  /* Notes */
374  if (0 != (drawflags & fDrawFlags::Notes))
375  {
376  for (i = 0; i < psb->m_notes.size(); ++i)
377  {
378  const btSoftBody::Note& n = psb->m_notes[i];
379  btVector3 p = n.m_offset;
380  for (int j = 0; j < n.m_rank; ++j)
381  {
382  p += n.m_nodes[j]->m_x * n.m_coords[j];
383  }
384  idraw->draw3dText(p, n.m_text);
385  }
386  }
387  /* Node tree */
388  if (0 != (drawflags & fDrawFlags::NodeTree)) DrawNodeTree(psb, idraw);
389  /* Face tree */
390  if (0 != (drawflags & fDrawFlags::FaceTree)) DrawFaceTree(psb, idraw);
391  /* Cluster tree */
392  if (0 != (drawflags & fDrawFlags::ClusterTree)) DrawClusterTree(psb, idraw);
393  /* Joints */
394  if (0 != (drawflags & fDrawFlags::Joints))
395  {
396  for (i = 0; i < psb->m_joints.size(); ++i)
397  {
398  const btSoftBody::Joint* pj = psb->m_joints[i];
399  switch (pj->Type())
400  {
402  {
403  const btSoftBody::LJoint* pjl = (const btSoftBody::LJoint*)pj;
404  const btVector3 a0 = pj->m_bodies[0].xform() * pjl->m_refs[0];
405  const btVector3 a1 = pj->m_bodies[1].xform() * pjl->m_refs[1];
406  idraw->drawLine(pj->m_bodies[0].xform().getOrigin(), a0, btVector3(1, 1, 0));
407  idraw->drawLine(pj->m_bodies[1].xform().getOrigin(), a1, btVector3(0, 1, 1));
408  drawVertex(idraw, a0, 0.25, btVector3(1, 1, 0));
409  drawVertex(idraw, a1, 0.25, btVector3(0, 1, 1));
410  }
411  break;
413  {
414  //const btSoftBody::AJoint* pja=(const btSoftBody::AJoint*)pj;
415  const btVector3 o0 = pj->m_bodies[0].xform().getOrigin();
416  const btVector3 o1 = pj->m_bodies[1].xform().getOrigin();
417  const btVector3 a0 = pj->m_bodies[0].xform().getBasis() * pj->m_refs[0];
418  const btVector3 a1 = pj->m_bodies[1].xform().getBasis() * pj->m_refs[1];
419  idraw->drawLine(o0, o0 + a0 * 10, btVector3(1, 1, 0));
420  idraw->drawLine(o0, o0 + a1 * 10, btVector3(1, 1, 0));
421  idraw->drawLine(o1, o1 + a0 * 10, btVector3(0, 1, 1));
422  idraw->drawLine(o1, o1 + a1 * 10, btVector3(0, 1, 1));
423  break;
424  }
425  default:
426  {
427  }
428  }
429  }
430  }
431 }
432 
433 //
435  btIDebugDraw* idraw,
436  bool masses,
437  bool areas,
438  bool /*stress*/)
439 {
440  for (int i = 0; i < psb->m_nodes.size(); ++i)
441  {
442  const btSoftBody::Node& n = psb->m_nodes[i];
443  char text[2048] = {0};
444  char buff[1024];
445  if (masses)
446  {
447  sprintf(buff, " M(%.2f)", 1 / n.m_im);
448  strcat(text, buff);
449  }
450  if (areas)
451  {
452  sprintf(buff, " A(%.2f)", n.m_area);
453  strcat(text, buff);
454  }
455  if (text[0]) idraw->draw3dText(n.m_x, text);
456  }
457 }
458 
459 //
461  btIDebugDraw* idraw,
462  int mindepth,
463  int maxdepth)
464 {
465  drawTree(idraw, psb->m_ndbvt.m_root, 0, btVector3(1, 0, 1), btVector3(1, 1, 1), mindepth, maxdepth);
466 }
467 
468 //
470  btIDebugDraw* idraw,
471  int mindepth,
472  int maxdepth)
473 {
474  drawTree(idraw, psb->m_fdbvt.m_root, 0, btVector3(0, 1, 0), btVector3(1, 0, 0), mindepth, maxdepth);
475 }
476 
477 //
479  btIDebugDraw* idraw,
480  int mindepth,
481  int maxdepth)
482 {
483  drawTree(idraw, psb->m_cdbvt.m_root, 0, btVector3(0, 1, 1), btVector3(1, 0, 0), mindepth, maxdepth);
484 }
485 
486 //The btSoftBody object from the BulletSDK includes an array of Nodes and Links. These links appear
487 // to be first set up to connect a node to between 5 and 6 of its neighbors [480 links],
488 //and then to the rest of the nodes after the execution of the Floyd-Warshall graph algorithm
489 //[another 930 links].
490 //The way the links are stored by default, we have a number of cases where adjacent links share a node in common
491 // - this leads to the creation of a data dependency through memory.
492 //The PSolve_Links() function reads and writes nodes as it iterates over each link.
493 //So, we now have the possibility of a data dependency between iteration X
494 //that processes link L with iteration X+1 that processes link L+1
495 //because L and L+1 have one node in common, and iteration X updates the positions of that node,
496 //and iteration X+1 reads in the position of that shared node.
497 //
498 //Such a memory dependency limits the ability of a modern CPU to speculate beyond
499 //a certain point because it has to respect a possible dependency
500 //- this prevents the CPU from making full use of its out-of-order resources.
501 //If we re-order the links such that we minimize the cases where a link L and L+1 share a common node,
502 //we create a temporal gap between when the node position is written,
503 //and when it is subsequently read. This in turn allows the CPU to continue execution without
504 //risking a dependency violation. Such a reordering would result in significant speedups on
505 //modern CPUs with lots of execution resources.
506 //In our testing, we see it have a tremendous impact not only on the A7,
507 //but also on all x86 cores that ship with modern Macs.
508 //The attached source file includes a single function (ReoptimizeLinkOrder) which can be called on a
509 //btSoftBody object in the solveConstraints() function before the actual solver is invoked,
510 //or right after generateBendingConstraints() once we have all 1410 links.
511 
512 //===================================================================
513 //
514 //
515 // This function takes in a list of interdependent Links and tries
516 // to maximize the distance between calculation
517 // of dependent links. This increases the amount of parallelism that can
518 // be exploited by out-of-order instruction processors with large but
519 // (inevitably) finite instruction windows.
520 //
521 //===================================================================
522 
523 // A small structure to track lists of dependent link calculations
525 {
526 public:
527  int value; // A link calculation that is dependent on this one
528  // Positive values = "input A" while negative values = "input B"
529  LinkDeps_t* next; // Next dependence in the list
530 };
532 
533 // Dependency list constants
534 #define REOP_NOT_DEPENDENT -1
535 #define REOP_NODE_COMPLETE -2 // Must be less than REOP_NOT_DEPENDENT
536 
537 void btSoftBodyHelpers::ReoptimizeLinkOrder(btSoftBody* psb /* This can be replaced by a btSoftBody pointer */)
538 {
539  int i, nLinks = psb->m_links.size(), nNodes = psb->m_nodes.size();
540  btSoftBody::Link* lr;
541  int ar, br;
542  btSoftBody::Node* node0 = &(psb->m_nodes[0]);
543  btSoftBody::Node* node1 = &(psb->m_nodes[1]);
544  LinkDepsPtr_t linkDep;
545  int readyListHead, readyListTail, linkNum, linkDepFrees, depLink;
546 
547  // Allocate temporary buffers
548  int* nodeWrittenAt = new int[nNodes + 1]; // What link calculation produced this node's current values?
549  int* linkDepA = new int[nLinks]; // Link calculation input is dependent upon prior calculation #N
550  int* linkDepB = new int[nLinks];
551  int* readyList = new int[nLinks]; // List of ready-to-process link calculations (# of links, maximum)
552  LinkDeps_t* linkDepFreeList = new LinkDeps_t[2 * nLinks]; // Dependent-on-me list elements (2x# of links, maximum)
553  LinkDepsPtr_t* linkDepListStarts = new LinkDepsPtr_t[nLinks]; // Start nodes of dependent-on-me lists, one for each link
554 
555  // Copy the original, unsorted links to a side buffer
556  btSoftBody::Link* linkBuffer = new btSoftBody::Link[nLinks];
557  memcpy(linkBuffer, &(psb->m_links[0]), sizeof(btSoftBody::Link) * nLinks);
558 
559  // Clear out the node setup and ready list
560  for (i = 0; i < nNodes + 1; i++)
561  {
562  nodeWrittenAt[i] = REOP_NOT_DEPENDENT;
563  }
564  for (i = 0; i < nLinks; i++)
565  {
566  linkDepListStarts[i] = NULL;
567  }
568  readyListHead = readyListTail = linkDepFrees = 0;
569 
570  // Initial link analysis to set up data structures
571  for (i = 0; i < nLinks; i++)
572  {
573  // Note which prior link calculations we are dependent upon & build up dependence lists
574  lr = &(psb->m_links[i]);
575  ar = (lr->m_n[0] - node0) / (node1 - node0);
576  br = (lr->m_n[1] - node0) / (node1 - node0);
577  if (nodeWrittenAt[ar] > REOP_NOT_DEPENDENT)
578  {
579  linkDepA[i] = nodeWrittenAt[ar];
580  linkDep = &linkDepFreeList[linkDepFrees++];
581  linkDep->value = i;
582  linkDep->next = linkDepListStarts[nodeWrittenAt[ar]];
583  linkDepListStarts[nodeWrittenAt[ar]] = linkDep;
584  }
585  else
586  {
587  linkDepA[i] = REOP_NOT_DEPENDENT;
588  }
589  if (nodeWrittenAt[br] > REOP_NOT_DEPENDENT)
590  {
591  linkDepB[i] = nodeWrittenAt[br];
592  linkDep = &linkDepFreeList[linkDepFrees++];
593  linkDep->value = -(i + 1);
594  linkDep->next = linkDepListStarts[nodeWrittenAt[br]];
595  linkDepListStarts[nodeWrittenAt[br]] = linkDep;
596  }
597  else
598  {
599  linkDepB[i] = REOP_NOT_DEPENDENT;
600  }
601 
602  // Add this link to the initial ready list, if it is not dependent on any other links
603  if ((linkDepA[i] == REOP_NOT_DEPENDENT) && (linkDepB[i] == REOP_NOT_DEPENDENT))
604  {
605  readyList[readyListTail++] = i;
606  linkDepA[i] = linkDepB[i] = REOP_NODE_COMPLETE; // Probably not needed now
607  }
608 
609  // Update the nodes to mark which ones are calculated by this link
610  nodeWrittenAt[ar] = nodeWrittenAt[br] = i;
611  }
612 
613  // Process the ready list and create the sorted list of links
614  // -- By treating the ready list as a queue, we maximize the distance between any
615  // inter-dependent node calculations
616  // -- All other (non-related) nodes in the ready list will automatically be inserted
617  // in between each set of inter-dependent link calculations by this loop
618  i = 0;
619  while (readyListHead != readyListTail)
620  {
621  // Use ready list to select the next link to process
622  linkNum = readyList[readyListHead++];
623  // Copy the next-to-calculate link back into the original link array
624  psb->m_links[i++] = linkBuffer[linkNum];
625 
626  // Free up any link inputs that are dependent on this one
627  linkDep = linkDepListStarts[linkNum];
628  while (linkDep)
629  {
630  depLink = linkDep->value;
631  if (depLink >= 0)
632  {
633  linkDepA[depLink] = REOP_NOT_DEPENDENT;
634  }
635  else
636  {
637  depLink = -depLink - 1;
638  linkDepB[depLink] = REOP_NOT_DEPENDENT;
639  }
640  // Add this dependent link calculation to the ready list if *both* inputs are clear
641  if ((linkDepA[depLink] == REOP_NOT_DEPENDENT) && (linkDepB[depLink] == REOP_NOT_DEPENDENT))
642  {
643  readyList[readyListTail++] = depLink;
644  linkDepA[depLink] = linkDepB[depLink] = REOP_NODE_COMPLETE; // Probably not needed now
645  }
646  linkDep = linkDep->next;
647  }
648  }
649 
650  // Delete the temporary buffers
651  delete[] nodeWrittenAt;
652  delete[] linkDepA;
653  delete[] linkDepB;
654  delete[] readyList;
655  delete[] linkDepFreeList;
656  delete[] linkDepListStarts;
657  delete[] linkBuffer;
658 }
659 
660 //
662  btIDebugDraw* idraw)
663 {
664  if (psb->m_pose.m_bframe)
665  {
666  static const btScalar ascl = 10;
667  static const btScalar nscl = (btScalar)0.1;
668  const btVector3 com = psb->m_pose.m_com;
669  const btMatrix3x3 trs = psb->m_pose.m_rot * psb->m_pose.m_scl;
670  const btVector3 Xaxis = (trs * btVector3(1, 0, 0)).normalized();
671  const btVector3 Yaxis = (trs * btVector3(0, 1, 0)).normalized();
672  const btVector3 Zaxis = (trs * btVector3(0, 0, 1)).normalized();
673  idraw->drawLine(com, com + Xaxis * ascl, btVector3(1, 0, 0));
674  idraw->drawLine(com, com + Yaxis * ascl, btVector3(0, 1, 0));
675  idraw->drawLine(com, com + Zaxis * ascl, btVector3(0, 0, 1));
676  for (int i = 0; i < psb->m_pose.m_pos.size(); ++i)
677  {
678  const btVector3 x = com + trs * psb->m_pose.m_pos[i];
679  drawVertex(idraw, x, nscl, btVector3(1, 0, 1));
680  }
681  }
682 }
683 
684 //
686  const btVector3& to,
687  int res,
688  int fixeds)
689 {
690  /* Create nodes */
691  const int r = res + 2;
692  btVector3* x = new btVector3[r];
693  btScalar* m = new btScalar[r];
694  int i;
695 
696  for (i = 0; i < r; ++i)
697  {
698  const btScalar t = i / (btScalar)(r - 1);
699  x[i] = lerp(from, to, t);
700  m[i] = 1;
701  }
702  btSoftBody* psb = new btSoftBody(&worldInfo, r, x, m);
703  if (fixeds & 1) psb->setMass(0, 0);
704  if (fixeds & 2) psb->setMass(r - 1, 0);
705  delete[] x;
706  delete[] m;
707  /* Create links */
708  for (i = 1; i < r; ++i)
709  {
710  psb->appendLink(i - 1, i);
711  }
712  /* Finished */
713  return (psb);
714 }
715 
716 //
718  const btVector3& corner10,
719  const btVector3& corner01,
720  const btVector3& corner11,
721  int resx,
722  int resy,
723  int fixeds,
724  bool gendiags)
725 {
726 #define IDX(_x_, _y_) ((_y_)*rx + (_x_))
727  /* Create nodes */
728  if ((resx < 2) || (resy < 2)) return (0);
729  const int rx = resx;
730  const int ry = resy;
731  const int tot = rx * ry;
732  btVector3* x = new btVector3[tot];
733  btScalar* m = new btScalar[tot];
734  int iy;
735 
736  for (iy = 0; iy < ry; ++iy)
737  {
738  const btScalar ty = iy / (btScalar)(ry - 1);
739  const btVector3 py0 = lerp(corner00, corner01, ty);
740  const btVector3 py1 = lerp(corner10, corner11, ty);
741  for (int ix = 0; ix < rx; ++ix)
742  {
743  const btScalar tx = ix / (btScalar)(rx - 1);
744  x[IDX(ix, iy)] = lerp(py0, py1, tx);
745  m[IDX(ix, iy)] = 1;
746  }
747  }
748  btSoftBody* psb = new btSoftBody(&worldInfo, tot, x, m);
749  if (fixeds & 1) psb->setMass(IDX(0, 0), 0);
750  if (fixeds & 2) psb->setMass(IDX(rx - 1, 0), 0);
751  if (fixeds & 4) psb->setMass(IDX(0, ry - 1), 0);
752  if (fixeds & 8) psb->setMass(IDX(rx - 1, ry - 1), 0);
753  delete[] x;
754  delete[] m;
755  /* Create links and faces */
756  for (iy = 0; iy < ry; ++iy)
757  {
758  for (int ix = 0; ix < rx; ++ix)
759  {
760  const int idx = IDX(ix, iy);
761  const bool mdx = (ix + 1) < rx;
762  const bool mdy = (iy + 1) < ry;
763  if (mdx) psb->appendLink(idx, IDX(ix + 1, iy));
764  if (mdy) psb->appendLink(idx, IDX(ix, iy + 1));
765  if (mdx && mdy)
766  {
767  if ((ix + iy) & 1)
768  {
769  psb->appendFace(IDX(ix, iy), IDX(ix + 1, iy), IDX(ix + 1, iy + 1));
770  psb->appendFace(IDX(ix, iy), IDX(ix + 1, iy + 1), IDX(ix, iy + 1));
771  if (gendiags)
772  {
773  psb->appendLink(IDX(ix, iy), IDX(ix + 1, iy + 1));
774  }
775  }
776  else
777  {
778  psb->appendFace(IDX(ix, iy + 1), IDX(ix, iy), IDX(ix + 1, iy));
779  psb->appendFace(IDX(ix, iy + 1), IDX(ix + 1, iy), IDX(ix + 1, iy + 1));
780  if (gendiags)
781  {
782  psb->appendLink(IDX(ix + 1, iy), IDX(ix, iy + 1));
783  }
784  }
785  }
786  }
787  }
788  /* Finished */
789 #undef IDX
790  return (psb);
791 }
792 
793 //
795  const btVector3& corner00,
796  const btVector3& corner10,
797  const btVector3& corner01,
798  const btVector3& corner11,
799  int resx,
800  int resy,
801  int fixeds,
802  bool gendiags,
803  float* tex_coords)
804 {
805  /*
806  *
807  * corners:
808  *
809  * [0][0] corner00 ------- corner01 [resx][0]
810  * | |
811  * | |
812  * [0][resy] corner10 -------- corner11 [resx][resy]
813  *
814  *
815  *
816  *
817  *
818  *
819  * "fixedgs" map:
820  *
821  * corner00 --> +1
822  * corner01 --> +2
823  * corner10 --> +4
824  * corner11 --> +8
825  * upper middle --> +16
826  * left middle --> +32
827  * right middle --> +64
828  * lower middle --> +128
829  * center --> +256
830  *
831  *
832  * tex_coords size (resx-1)*(resy-1)*12
833  *
834  *
835  *
836  * SINGLE QUAD INTERNALS
837  *
838  * 1) btSoftBody's nodes and links,
839  * diagonal link is optional ("gendiags")
840  *
841  *
842  * node00 ------ node01
843  * | .
844  * | .
845  * | .
846  * | .
847  * | .
848  * node10 node11
849  *
850  *
851  *
852  * 2) Faces:
853  * two triangles,
854  * UV Coordinates (hier example for single quad)
855  *
856  * (0,1) (0,1) (1,1)
857  * 1 |\ 3 \-----| 2
858  * | \ \ |
859  * | \ \ |
860  * | \ \ |
861  * | \ \ |
862  * 2 |-----\ 3 \| 1
863  * (0,0) (1,0) (1,0)
864  *
865  *
866  *
867  *
868  *
869  *
870  */
871 
872 #define IDX(_x_, _y_) ((_y_)*rx + (_x_))
873  /* Create nodes */
874  if ((resx < 2) || (resy < 2)) return (0);
875  const int rx = resx;
876  const int ry = resy;
877  const int tot = rx * ry;
878  btVector3* x = new btVector3[tot];
879  btScalar* m = new btScalar[tot];
880 
881  int iy;
882 
883  for (iy = 0; iy < ry; ++iy)
884  {
885  const btScalar ty = iy / (btScalar)(ry - 1);
886  const btVector3 py0 = lerp(corner00, corner01, ty);
887  const btVector3 py1 = lerp(corner10, corner11, ty);
888  for (int ix = 0; ix < rx; ++ix)
889  {
890  const btScalar tx = ix / (btScalar)(rx - 1);
891  x[IDX(ix, iy)] = lerp(py0, py1, tx);
892  m[IDX(ix, iy)] = 1;
893  }
894  }
895  btSoftBody* psb = new btSoftBody(&worldInfo, tot, x, m);
896  if (fixeds & 1) psb->setMass(IDX(0, 0), 0);
897  if (fixeds & 2) psb->setMass(IDX(rx - 1, 0), 0);
898  if (fixeds & 4) psb->setMass(IDX(0, ry - 1), 0);
899  if (fixeds & 8) psb->setMass(IDX(rx - 1, ry - 1), 0);
900  if (fixeds & 16) psb->setMass(IDX((rx - 1) / 2, 0), 0);
901  if (fixeds & 32) psb->setMass(IDX(0, (ry - 1) / 2), 0);
902  if (fixeds & 64) psb->setMass(IDX(rx - 1, (ry - 1) / 2), 0);
903  if (fixeds & 128) psb->setMass(IDX((rx - 1) / 2, ry - 1), 0);
904  if (fixeds & 256) psb->setMass(IDX((rx - 1) / 2, (ry - 1) / 2), 0);
905  delete[] x;
906  delete[] m;
907 
908  int z = 0;
909  /* Create links and faces */
910  for (iy = 0; iy < ry; ++iy)
911  {
912  for (int ix = 0; ix < rx; ++ix)
913  {
914  const bool mdx = (ix + 1) < rx;
915  const bool mdy = (iy + 1) < ry;
916 
917  int node00 = IDX(ix, iy);
918  int node01 = IDX(ix + 1, iy);
919  int node10 = IDX(ix, iy + 1);
920  int node11 = IDX(ix + 1, iy + 1);
921 
922  if (mdx) psb->appendLink(node00, node01);
923  if (mdy) psb->appendLink(node00, node10);
924  if (mdx && mdy)
925  {
926  psb->appendFace(node00, node10, node11);
927  if (tex_coords)
928  {
929  tex_coords[z + 0] = CalculateUV(resx, resy, ix, iy, 0);
930  tex_coords[z + 1] = CalculateUV(resx, resy, ix, iy, 1);
931  tex_coords[z + 2] = CalculateUV(resx, resy, ix, iy, 0);
932  tex_coords[z + 3] = CalculateUV(resx, resy, ix, iy, 2);
933  tex_coords[z + 4] = CalculateUV(resx, resy, ix, iy, 3);
934  tex_coords[z + 5] = CalculateUV(resx, resy, ix, iy, 2);
935  }
936  psb->appendFace(node11, node01, node00);
937  if (tex_coords)
938  {
939  tex_coords[z + 6] = CalculateUV(resx, resy, ix, iy, 3);
940  tex_coords[z + 7] = CalculateUV(resx, resy, ix, iy, 2);
941  tex_coords[z + 8] = CalculateUV(resx, resy, ix, iy, 3);
942  tex_coords[z + 9] = CalculateUV(resx, resy, ix, iy, 1);
943  tex_coords[z + 10] = CalculateUV(resx, resy, ix, iy, 0);
944  tex_coords[z + 11] = CalculateUV(resx, resy, ix, iy, 1);
945  }
946  if (gendiags) psb->appendLink(node00, node11);
947  z += 12;
948  }
949  }
950  }
951  /* Finished */
952 #undef IDX
953  return (psb);
954 }
955 
956 float btSoftBodyHelpers::CalculateUV(int resx, int resy, int ix, int iy, int id)
957 {
958  /*
959  *
960  *
961  * node00 --- node01
962  * | |
963  * node10 --- node11
964  *
965  *
966  * ID map:
967  *
968  * node00 s --> 0
969  * node00 t --> 1
970  *
971  * node01 s --> 3
972  * node01 t --> 1
973  *
974  * node10 s --> 0
975  * node10 t --> 2
976  *
977  * node11 s --> 3
978  * node11 t --> 2
979  *
980  *
981  */
982 
983  float tc = 0.0f;
984  if (id == 0)
985  {
986  tc = (1.0f / ((resx - 1)) * ix);
987  }
988  else if (id == 1)
989  {
990  tc = (1.0f / ((resy - 1)) * (resy - 1 - iy));
991  }
992  else if (id == 2)
993  {
994  tc = (1.0f / ((resy - 1)) * (resy - 1 - iy - 1));
995  }
996  else if (id == 3)
997  {
998  tc = (1.0f / ((resx - 1)) * (ix + 1));
999  }
1000  return tc;
1001 }
1002 //
1004  const btVector3& radius,
1005  int res)
1006 {
1007  struct Hammersley
1008  {
1009  static void Generate(btVector3* x, int n)
1010  {
1011  for (int i = 0; i < n; i++)
1012  {
1013  btScalar p = 0.5, t = 0;
1014  for (int j = i; j; p *= 0.5, j >>= 1)
1015  if (j & 1) t += p;
1016  btScalar w = 2 * t - 1;
1017  btScalar a = (SIMD_PI + 2 * i * SIMD_PI) / n;
1018  btScalar s = btSqrt(1 - w * w);
1019  *x++ = btVector3(s * btCos(a), s * btSin(a), w);
1020  }
1021  }
1022  };
1024  vtx.resize(3 + res);
1025  Hammersley::Generate(&vtx[0], vtx.size());
1026  for (int i = 0; i < vtx.size(); ++i)
1027  {
1028  vtx[i] = vtx[i] * radius + center;
1029  }
1030  return (CreateFromConvexHull(worldInfo, &vtx[0], vtx.size()));
1031 }
1032 
1033 //
1035  const int* triangles,
1036  int ntriangles, bool randomizeConstraints)
1037 {
1038  int maxidx = 0;
1039  int i, j, ni;
1040 
1041  for (i = 0, ni = ntriangles * 3; i < ni; ++i)
1042  {
1043  maxidx = btMax(triangles[i], maxidx);
1044  }
1045  ++maxidx;
1048  chks.resize(maxidx * maxidx, false);
1049  vtx.resize(maxidx);
1050  for (i = 0, j = 0, ni = maxidx * 3; i < ni; ++j, i += 3)
1051  {
1052  vtx[j] = btVector3(vertices[i], vertices[i + 1], vertices[i + 2]);
1053  }
1054  btSoftBody* psb = new btSoftBody(&worldInfo, vtx.size(), &vtx[0], 0);
1055  for (i = 0, ni = ntriangles * 3; i < ni; i += 3)
1056  {
1057  const int idx[] = {triangles[i], triangles[i + 1], triangles[i + 2]};
1058 #define IDX(_x_, _y_) ((_y_)*maxidx + (_x_))
1059  for (int j = 2, k = 0; k < 3; j = k++)
1060  {
1061  if (!chks[IDX(idx[j], idx[k])])
1062  {
1063  chks[IDX(idx[j], idx[k])] = true;
1064  chks[IDX(idx[k], idx[j])] = true;
1065  psb->appendLink(idx[j], idx[k]);
1066  }
1067  }
1068 #undef IDX
1069  psb->appendFace(idx[0], idx[1], idx[2]);
1070  }
1071 
1072  if (randomizeConstraints)
1073  {
1074  psb->randomizeConstraints();
1075  }
1076 
1077  return (psb);
1078 }
1079 
1080 //
1082  int nvertices, bool randomizeConstraints)
1083 {
1084  HullDesc hdsc(QF_TRIANGLES, nvertices, vertices);
1085  HullResult hres;
1086  HullLibrary hlib; /*??*/
1087  hdsc.mMaxVertices = nvertices;
1088  hlib.CreateConvexHull(hdsc, hres);
1089  btSoftBody* psb = new btSoftBody(&worldInfo, (int)hres.mNumOutputVertices,
1090  &hres.m_OutputVertices[0], 0);
1091  for (int i = 0; i < (int)hres.mNumFaces; ++i)
1092  {
1093  const int idx[] = {static_cast<int>(hres.m_Indices[i * 3 + 0]),
1094  static_cast<int>(hres.m_Indices[i * 3 + 1]),
1095  static_cast<int>(hres.m_Indices[i * 3 + 2])};
1096  if (idx[0] < idx[1]) psb->appendLink(idx[0], idx[1]);
1097  if (idx[1] < idx[2]) psb->appendLink(idx[1], idx[2]);
1098  if (idx[2] < idx[0]) psb->appendLink(idx[2], idx[0]);
1099  psb->appendFace(idx[0], idx[1], idx[2]);
1100  }
1101  hlib.ReleaseResult(hres);
1102  if (randomizeConstraints)
1103  {
1104  psb->randomizeConstraints();
1105  }
1106  return (psb);
1107 }
1108 
1109 static int nextLine(const char* buffer)
1110 {
1111  int numBytesRead = 0;
1112 
1113  while (*buffer != '\n')
1114  {
1115  buffer++;
1116  numBytesRead++;
1117  }
1118 
1119  if (buffer[0] == 0x0a)
1120  {
1121  buffer++;
1122  numBytesRead++;
1123  }
1124  return numBytesRead;
1125 }
1126 
1127 /* Create from TetGen .ele, .face, .node data */
1129  const char* ele,
1130  const char* face,
1131  const char* node,
1132  bool bfacelinks,
1133  bool btetralinks,
1134  bool bfacesfromtetras)
1135 {
1137  int nnode = 0;
1138  int ndims = 0;
1139  int nattrb = 0;
1140  int hasbounds = 0;
1141  int result = sscanf(node, "%d %d %d %d", &nnode, &ndims, &nattrb, &hasbounds);
1142  result = sscanf(node, "%d %d %d %d", &nnode, &ndims, &nattrb, &hasbounds);
1143  node += nextLine(node);
1144 
1145  pos.resize(nnode);
1146  for (int i = 0; i < pos.size(); ++i)
1147  {
1148  int index = 0;
1149  //int bound=0;
1150  float x, y, z;
1151  sscanf(node, "%d %f %f %f", &index, &x, &y, &z);
1152 
1153  // sn>>index;
1154  // sn>>x;sn>>y;sn>>z;
1155  node += nextLine(node);
1156 
1157  //for(int j=0;j<nattrb;++j)
1158  // sn>>a;
1159 
1160  //if(hasbounds)
1161  // sn>>bound;
1162 
1163  pos[index].setX(btScalar(x));
1164  pos[index].setY(btScalar(y));
1165  pos[index].setZ(btScalar(z));
1166  }
1167  btSoftBody* psb = new btSoftBody(&worldInfo, nnode, &pos[0], 0);
1168 #if 0
1169 if(face&&face[0])
1170  {
1171  int nface=0;
1172  sf>>nface;sf>>hasbounds;
1173  for(int i=0;i<nface;++i)
1174  {
1175  int index=0;
1176  int bound=0;
1177  int ni[3];
1178  sf>>index;
1179  sf>>ni[0];sf>>ni[1];sf>>ni[2];
1180  sf>>bound;
1181  psb->appendFace(ni[0],ni[1],ni[2]);
1182  if(btetralinks)
1183  {
1184  psb->appendLink(ni[0],ni[1],0,true);
1185  psb->appendLink(ni[1],ni[2],0,true);
1186  psb->appendLink(ni[2],ni[0],0,true);
1187  }
1188  }
1189  }
1190 #endif
1191 
1192  if (ele && ele[0])
1193  {
1194  int ntetra = 0;
1195  int ncorner = 0;
1196  int neattrb = 0;
1197  sscanf(ele, "%d %d %d", &ntetra, &ncorner, &neattrb);
1198  ele += nextLine(ele);
1199 
1200  //se>>ntetra;se>>ncorner;se>>neattrb;
1201  for (int i = 0; i < ntetra; ++i)
1202  {
1203  int index = 0;
1204  int ni[4];
1205 
1206  //se>>index;
1207  //se>>ni[0];se>>ni[1];se>>ni[2];se>>ni[3];
1208  sscanf(ele, "%d %d %d %d %d", &index, &ni[0], &ni[1], &ni[2], &ni[3]);
1209  ele += nextLine(ele);
1210  //for(int j=0;j<neattrb;++j)
1211  // se>>a;
1212  psb->appendTetra(ni[0], ni[1], ni[2], ni[3]);
1213  if (btetralinks)
1214  {
1215  psb->appendLink(ni[0], ni[1], 0, true);
1216  psb->appendLink(ni[1], ni[2], 0, true);
1217  psb->appendLink(ni[2], ni[0], 0, true);
1218  psb->appendLink(ni[0], ni[3], 0, true);
1219  psb->appendLink(ni[1], ni[3], 0, true);
1220  psb->appendLink(ni[2], ni[3], 0, true);
1221  }
1222  }
1223  }
1224  printf("Nodes: %u\r\n", psb->m_nodes.size());
1225  printf("Links: %u\r\n", psb->m_links.size());
1226  printf("Faces: %u\r\n", psb->m_faces.size());
1227  printf("Tetras: %u\r\n", psb->m_tetras.size());
1228  return (psb);
1229 }
HullResult::mNumFaces
unsigned int mNumFaces
Definition: btConvexHull.h:40
btConvexHullComputer::Edge::getNextEdgeOfFace
const Edge * getNextEdgeOfFace() const
Definition: btConvexHullComputer.h:55
btSoftBody::Cluster
Definition: btSoftBody.h:349
btSoftBody::Body::xform
const btTransform & xform() const
Definition: btSoftBody.h:437
btSoftBody::Joint::m_refs
btVector3 m_refs[2]
Definition: btSoftBody.h:530
btSoftBodyHelpers::DrawClusterTree
static void DrawClusterTree(btSoftBody *psb, btIDebugDraw *idraw, int mindepth=0, int maxdepth=-1)
Definition: btSoftBodyHelpers.cpp:478
REOP_NODE_COMPLETE
#define REOP_NODE_COMPLETE
Definition: btSoftBodyHelpers.cpp:535
HullLibrary::ReleaseResult
HullError ReleaseResult(HullResult &result)
Definition: btConvexHull.cpp:787
fDrawFlags::FaceTree
Definition: btSoftBodyHelpers.h:40
HullDesc::mMaxVertices
unsigned int mMaxVertices
Definition: btConvexHull.h:103
btSoftBody::appendLink
void appendLink(int model=-1, Material *mat=0)
Definition: btSoftBody.cpp:266
btSoftBody::Anchor::m_node
Node * m_node
Definition: btSoftBody.h:318
btSoftBody::m_links
tLinkArray m_links
Definition: btSoftBody.h:692
btIDebugDraw::drawTriangle
virtual void drawTriangle(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2, const btVector3 &, const btVector3 &, const btVector3 &, const btVector3 &color, btScalar alpha)
Definition: btIDebugDraw.h:114
btConvexHullComputer::vertices
btAlignedObjectArray< btVector3 > vertices
Definition: btConvexHullComputer.h:67
btSoftBody::m_tetras
tTetraArray m_tetras
Definition: btSoftBody.h:694
IDX
#define IDX(_x_, _y_)
btSoftBody::appendFace
void appendFace(int model=-1, Material *mat=0)
Definition: btSoftBody.cpp:306
btSoftBody::Cluster::m_com
btVector3 m_com
Definition: btSoftBody.h:359
btScalar
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:294
btSoftBody::Note::m_coords
btScalar m_coords[4]
Definition: btSoftBody.h:333
btSoftBody::Cluster::m_av
btVector3 m_av
Definition: btSoftBody.h:365
btSoftBody::Pose::m_com
btVector3 m_com
Definition: btSoftBody.h:343
btConvexHullComputer::Edge::getTargetVertex
int getTargetVertex() const
Definition: btConvexHullComputer.h:45
btSoftBody::Node::m_n
btVector3 m_n
Definition: btSoftBody.h:255
btSoftBody::Pose::m_bframe
bool m_bframe
Definition: btSoftBody.h:339
btConvexHullComputer::Edge::getSourceVertex
int getSourceVertex() const
Definition: btConvexHullComputer.h:40
btSoftBody::Joint::Type
virtual eType::_ Type() const =0
btSoftBodyHelpers::CreateFromTriMesh
static btSoftBody * CreateFromTriMesh(btSoftBodyWorldInfo &worldInfo, const btScalar *vertices, const int *triangles, int ntriangles, bool randomizeConstraints=true)
Definition: btSoftBodyHelpers.cpp:1034
btSoftBodyHelpers::DrawNodeTree
static void DrawNodeTree(btSoftBody *psb, btIDebugDraw *idraw, int mindepth=0, int maxdepth=-1)
Definition: btSoftBodyHelpers.cpp:460
btSoftBody::Note::m_offset
btVector3 m_offset
Definition: btSoftBody.h:330
btSoftBody::m_anchors
tAnchorArray m_anchors
Definition: btSoftBody.h:695
HullResult::m_OutputVertices
btAlignedObjectArray< btVector3 > m_OutputVertices
Definition: btConvexHull.h:39
btSoftBodyHelpers::CreatePatch
static btSoftBody * CreatePatch(btSoftBodyWorldInfo &worldInfo, const btVector3 &corner00, const btVector3 &corner10, const btVector3 &corner01, const btVector3 &corner11, int resx, int resy, int fixeds, bool gendiags)
Definition: btSoftBodyHelpers.cpp:717
btSoftBody::m_pose
Pose m_pose
Definition: btSoftBody.h:687
REOP_NOT_DEPENDENT
#define REOP_NOT_DEPENDENT
Definition: btSoftBodyHelpers.cpp:534
SIMD_PI
#define SIMD_PI
Definition: btScalar.h:506
btConvexHullComputer.h
btCross
btVector3 btCross(const btVector3 &v1, const btVector3 &v2)
Return the cross product of two vectors.
Definition: btVector3.h:918
btSoftBody::m_faces
tFaceArray m_faces
Definition: btSoftBody.h:693
btIDebugDraw::draw3dText
virtual void draw3dText(const btVector3 &location, const char *textString)=0
btSoftBodyHelpers::CreateRope
static btSoftBody * CreateRope(btSoftBodyWorldInfo &worldInfo, const btVector3 &from, const btVector3 &to, int res, int fixeds)
Definition: btSoftBodyHelpers.cpp:685
btSoftBody::Anchor
Definition: btSoftBody.h:316
btSoftBody::Pose::m_rot
btMatrix3x3 m_rot
Definition: btSoftBody.h:344
btConvexHullComputer::faces
btAlignedObjectArray< int > faces
Definition: btConvexHullComputer.h:73
LinkDepsPtr_t
LinkDeps_t * LinkDepsPtr_t
Definition: btSoftBodyHelpers.cpp:531
btSoftBodyHelpers::DrawFrame
static void DrawFrame(btSoftBody *psb, btIDebugDraw *idraw)
Definition: btSoftBodyHelpers.cpp:661
QF_TRIANGLES
Definition: btConvexHull.h:50
fDrawFlags::Notes
Definition: btSoftBodyHelpers.h:37
HullLibrary
The HullLibrary class can create a convex hull from a collection of vertices, using the ComputeHull m...
Definition: btConvexHull.h:182
add
static void add(btAlignedObjectArray< T > &items, const Q &value)
Definition: btSoftBodyHelpers.cpp:105
btSoftBody::fMaterial::DebugDraw
Definition: btSoftBody.h:178
btSoftBody::Note
Definition: btSoftBody.h:327
btSoftBody::m_notes
tNoteArray m_notes
Definition: btSoftBody.h:690
btSoftBody::m_cdbvt
btDbvt m_cdbvt
Definition: btSoftBody.h:705
btSoftBody::Node
Definition: btSoftBody.h:249
btSoftBodyWorldInfo
Definition: btSoftBody.h:43
btSoftBody::randomizeConstraints
void randomizeConstraints()
Definition: btSoftBody.cpp:1167
HullResult::mNumOutputVertices
unsigned int mNumOutputVertices
Definition: btConvexHull.h:38
btSoftBodyHelpers::CreatePatchUV
static btSoftBody * CreatePatchUV(btSoftBodyWorldInfo &worldInfo, const btVector3 &corner00, const btVector3 &corner10, const btVector3 &corner01, const btVector3 &corner11, int resx, int resy, int fixeds, bool gendiags, float *tex_coords=0)
Definition: btSoftBodyHelpers.cpp:794
btMax
const T & btMax(const T &a, const T &b)
Definition: btMinMax.h:27
btVector3::y
const btScalar & y() const
Return the y value.
Definition: btVector3.h:577
btSoftBody::Note::m_rank
int m_rank
Definition: btSoftBody.h:331
btSoftBody::Tetra
Definition: btSoftBody.h:284
fDrawFlags::Anchors
Definition: btSoftBodyHelpers.h:36
btCollisionObject::getWorldTransform
btTransform & getWorldTransform()
Definition: btCollisionObject.h:365
btSoftBody::RContact::m_node
Node * m_node
Definition: btSoftBody.h:297
btSoftBody::Cluster::m_nodes
btAlignedObjectArray< Node * > m_nodes
Definition: btSoftBody.h:352
btSin
btScalar btSin(btScalar x)
Definition: btScalar.h:479
HullLibrary::CreateConvexHull
HullError CreateConvexHull(const HullDesc &desc, HullResult &result)
Definition: btConvexHull.cpp:670
fDrawFlags::Links
Definition: btSoftBodyHelpers.h:31
btSoftBody::Anchor::m_body
btRigidBody * m_body
Definition: btSoftBody.h:320
btSoftBody::Node::m_x
btVector3 m_x
Definition: btSoftBody.h:251
btSoftBody::Joint::eType::Linear
Definition: btSoftBody.h:517
btSoftBodyHelpers::CreateEllipsoid
static btSoftBody * CreateEllipsoid(btSoftBodyWorldInfo &worldInfo, const btVector3 &center, const btVector3 &radius, int res)
Definition: btSoftBodyHelpers.cpp:1003
btIDebugDraw
The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations.
Definition: btIDebugDraw.h:26
drawBox
static void drawBox(btIDebugDraw *idraw, const btVector3 &mins, const btVector3 &maxs, const btVector3 &color)
Definition: btSoftBodyHelpers.cpp:34
btSoftBody::RContact
Definition: btSoftBody.h:294
LinkDeps_t::value
int value
Definition: btSoftBodyHelpers.cpp:527
btSoftBody::m_ndbvt
btDbvt m_ndbvt
Definition: btSoftBody.h:703
btAlignedObjectArray::resize
void resize(int newsize, const T &fillData=T())
Definition: btAlignedObjectArray.h:210
btSoftBody::Face
Definition: btSoftBody.h:276
btTransform::getBasis
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
Definition: btTransform.h:108
btSoftBodyHelpers::CreateFromTetGenData
static btSoftBody * CreateFromTetGenData(btSoftBodyWorldInfo &worldInfo, const char *ele, const char *face, const char *node, bool bfacelinks, bool btetralinks, bool bfacesfromtetras)
Definition: btSoftBodyHelpers.cpp:1128
btConvexHullComputer::edges
btAlignedObjectArray< Edge > edges
Definition: btConvexHullComputer.h:70
mul
static void mul(btAlignedObjectArray< T > &items, const Q &value)
Definition: btSoftBodyHelpers.cpp:115
fDrawFlags::Normals
Definition: btSoftBodyHelpers.h:34
fDrawFlags::Contacts
Definition: btSoftBodyHelpers.h:35
btDbvtNode::childs
btDbvtNode * childs[2]
Definition: btDbvt.h:187
btConvexHullComputer
Convex hull implementation based on Preparata and Hong See http://code.google.com/p/bullet/issues/det...
Definition: btConvexHullComputer.h:24
btCos
btScalar btCos(btScalar x)
Definition: btScalar.h:478
btMatrix3x3
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition: btMatrix3x3.h:46
btSoftBody::Cluster::m_lv
btVector3 m_lv
Definition: btSoftBody.h:364
fDrawFlags::Clusters
Definition: btSoftBodyHelpers.h:38
btSoftBody::Joint::m_bodies
Body m_bodies[2]
Definition: btSoftBody.h:529
fDrawFlags::Faces
Definition: btSoftBodyHelpers.h:32
fDrawFlags::Joints
Definition: btSoftBodyHelpers.h:42
HullDesc
Definition: btConvexHull.h:55
drawVertex
static void drawVertex(btIDebugDraw *idraw, const btVector3 &x, btScalar s, const btVector3 &c)
btSoftBodyHelpers.cpp by Nathanael Presson
Definition: btSoftBodyHelpers.cpp:25
btDbvtNode::volume
btDbvtVolume volume
Definition: btDbvt.h:182
btVector3
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:80
btSoftBody::sCti::m_normal
btVector3 m_normal
Definition: btSoftBody.h:216
btSoftBody::sCti::m_offset
btScalar m_offset
Definition: btSoftBody.h:217
btTransform::getOrigin
btVector3 & getOrigin()
Return the origin vector translation.
Definition: btTransform.h:113
btSoftBody::Anchor::m_local
btVector3 m_local
Definition: btSoftBody.h:319
btSoftBody::Node::m_area
btScalar m_area
Definition: btSoftBody.h:257
btDbvtAabbMm::Extents
DBVT_INLINE btVector3 Extents() const
Definition: btDbvt.h:136
btIDebugDraw::drawLine
virtual void drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color)=0
btAlignedObjectArray
The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods It...
Definition: btAlignedObjectArray.h:52
btSoftBodyHelpers::DrawInfos
static void DrawInfos(btSoftBody *psb, btIDebugDraw *idraw, bool masses, bool areas, bool stress)
Definition: btSoftBodyHelpers.cpp:434
btSoftBody::m_rcontacts
tRContactArray m_rcontacts
Definition: btSoftBody.h:696
btSoftBody::Joint::eType::Angular
Definition: btSoftBody.h:518
btDbvt::m_root
btDbvtNode * m_root
Definition: btDbvt.h:263
btSoftBody::Feature::m_material
Material * m_material
Definition: btSoftBody.h:246
btSoftBodyHelpers::ReoptimizeLinkOrder
static void ReoptimizeLinkOrder(btSoftBody *psb)
Sort the list of links to move link calculations that are dependent upon earlier ones as far as possi...
Definition: btSoftBodyHelpers.cpp:537
btDbvtNode::isinternal
DBVT_INLINE bool isinternal() const
Definition: btDbvt.h:185
btDot
btScalar btDot(const btVector3 &v1, const btVector3 &v2)
Return the dot product between two vectors.
Definition: btVector3.h:890
btSoftBody::RContact::m_cti
sCti m_cti
Definition: btSoftBody.h:296
btVector3::x
const btScalar & x() const
Return the x value.
Definition: btVector3.h:575
btSoftBody
The btSoftBody is an class to simulate cloth and volumetric soft bodies.
Definition: btSoftBody.h:70
btSoftBody::Tetra::m_n
Node * m_n[4]
Definition: btSoftBody.h:286
btSoftBodyHelpers.h
btSoftBody::appendTetra
void appendTetra(int model, Material *mat)
Definition: btSoftBody.cpp:346
btConvexHullComputer::Edge
Definition: btConvexHullComputer.h:30
HullResult
Definition: btConvexHull.h:27
lerp
btVector3 lerp(const btVector3 &v1, const btVector3 &v2, const btScalar &t)
Return the linear interpolation between two vectors.
Definition: btVector3.h:934
drawTree
static void drawTree(btIDebugDraw *idraw, const btDbvtNode *node, int depth, const btVector3 &ncolor, const btVector3 &lcolor, int mindepth, int maxdepth)
Definition: btSoftBodyHelpers.cpp:62
btDbvtNode::isleaf
DBVT_INLINE bool isleaf() const
Definition: btDbvt.h:184
fDrawFlags::NodeTree
Definition: btSoftBodyHelpers.h:39
btSoftBodyHelpers::Draw
static void Draw(btSoftBody *psb, btIDebugDraw *idraw, int drawflags=fDrawFlags::Std)
Definition: btSoftBodyHelpers.cpp:166
btSoftBodyInternals.h
btSoftBody::Pose::m_pos
tVector3Array m_pos
Definition: btSoftBody.h:341
fDrawFlags::ClusterTree
Definition: btSoftBodyHelpers.h:41
btSoftBody::Face::m_n
Node * m_n[3]
Definition: btSoftBody.h:278
btSoftBody::m_clusters
tClusterArray m_clusters
Definition: btSoftBody.h:706
HullResult::m_Indices
btAlignedObjectArray< unsigned int > m_Indices
Definition: btConvexHull.h:42
btVector3::minAxis
int minAxis() const
Return the axis with the smallest value Note return values are 0,1,2 for x, y, or z.
Definition: btVector3.h:470
btSoftBodyHelpers::CalculateUV
static float CalculateUV(int resx, int resy, int ix, int iy, int id)
Definition: btSoftBodyHelpers.cpp:956
btSoftBody::setMass
void setMass(int node, btScalar mass)
Definition: btSoftBody.cpp:687
btConvexHullComputer::compute
btScalar compute(const void *coords, bool doubleCoords, int stride, int count, btScalar shrink, btScalar shrinkClamp)
Definition: btConvexHullComputer.cpp:2653
btSoftBody::Pose::m_scl
btMatrix3x3 m_scl
Definition: btSoftBody.h:345
nextLine
static int nextLine(const char *buffer)
Definition: btSoftBodyHelpers.cpp:1109
btSoftBody::Material::m_flags
int m_flags
Definition: btSoftBody.h:240
btSoftBody::m_fdbvt
btDbvt m_fdbvt
Definition: btSoftBody.h:704
btSoftBody::Note::m_text
const char * m_text
Definition: btSoftBody.h:329
LinkDeps_t
Definition: btSoftBodyHelpers.cpp:524
btDbvtNode
Definition: btDbvt.h:180
btSoftBodyHelpers::DrawFaceTree
static void DrawFaceTree(btSoftBody *psb, btIDebugDraw *idraw, int mindepth=0, int maxdepth=-1)
Definition: btSoftBodyHelpers.cpp:469
btSqrt
btScalar btSqrt(btScalar y)
Definition: btScalar.h:446
btSoftBody::Node::m_im
btScalar m_im
Definition: btSoftBody.h:256
btSoftBody::Note::m_nodes
Node * m_nodes[4]
Definition: btSoftBody.h:332
average
static T average(const btAlignedObjectArray< T > &items)
Definition: btSoftBodyHelpers.cpp:125
btSoftBody::m_joints
tJointArray m_joints
Definition: btSoftBody.h:698
btDbvtAabbMm::Center
DBVT_INLINE btVector3 Center() const
Definition: btDbvt.h:134
btSoftBodyHelpers::CreateFromConvexHull
static btSoftBody * CreateFromConvexHull(btSoftBodyWorldInfo &worldInfo, const btVector3 *vertices, int nvertices, bool randomizeConstraints=true)
Definition: btSoftBodyHelpers.cpp:1081
btVector3::normalized
btVector3 normalized() const
Return a normalized version of this vector.
Definition: btVector3.h:949
LinkDeps_t::next
LinkDeps_t * next
Definition: btSoftBodyHelpers.cpp:529
fDrawFlags::Tetras
Definition: btSoftBodyHelpers.h:33
sum
static T sum(const btAlignedObjectArray< T > &items)
Definition: btSoftBodyHelpers.cpp:89
fDrawFlags::Nodes
Definition: btSoftBodyHelpers.h:30
btConvexHull.h
btVector3::z
const btScalar & z() const
Return the z value.
Definition: btVector3.h:579
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:149
btSoftBody::m_nodes
tNodeArray m_nodes
Definition: btSoftBody.h:691
btSoftBody::LJoint
Definition: btSoftBody.h:546
btSoftBody::Joint
Definition: btSoftBody.h:511