Blender  V3.3
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>
20 #include <iostream>
21 #include <sstream>
22 #include <string.h>
23 #include <algorithm>
24 #include "btSoftBodyHelpers.h"
27 #include <map>
28 #include <vector>
29 
30 static void drawVertex(btIDebugDraw* idraw,
31  const btVector3& x, btScalar s, const btVector3& c)
32 {
33  idraw->drawLine(x - btVector3(s, 0, 0), x + btVector3(s, 0, 0), c);
34  idraw->drawLine(x - btVector3(0, s, 0), x + btVector3(0, s, 0), c);
35  idraw->drawLine(x - btVector3(0, 0, s), x + btVector3(0, 0, s), c);
36 }
37 
38 //
39 static void drawBox(btIDebugDraw* idraw,
40  const btVector3& mins,
41  const btVector3& maxs,
42  const btVector3& color)
43 {
44  const btVector3 c[] = {btVector3(mins.x(), mins.y(), mins.z()),
45  btVector3(maxs.x(), mins.y(), mins.z()),
46  btVector3(maxs.x(), maxs.y(), mins.z()),
47  btVector3(mins.x(), maxs.y(), mins.z()),
48  btVector3(mins.x(), mins.y(), maxs.z()),
49  btVector3(maxs.x(), mins.y(), maxs.z()),
50  btVector3(maxs.x(), maxs.y(), maxs.z()),
51  btVector3(mins.x(), maxs.y(), maxs.z())};
52  idraw->drawLine(c[0], c[1], color);
53  idraw->drawLine(c[1], c[2], color);
54  idraw->drawLine(c[2], c[3], color);
55  idraw->drawLine(c[3], c[0], color);
56  idraw->drawLine(c[4], c[5], color);
57  idraw->drawLine(c[5], c[6], color);
58  idraw->drawLine(c[6], c[7], color);
59  idraw->drawLine(c[7], c[4], color);
60  idraw->drawLine(c[0], c[4], color);
61  idraw->drawLine(c[1], c[5], color);
62  idraw->drawLine(c[2], c[6], color);
63  idraw->drawLine(c[3], c[7], color);
64 }
65 
66 //
67 static void drawTree(btIDebugDraw* idraw,
68  const btDbvtNode* node,
69  int depth,
70  const btVector3& ncolor,
71  const btVector3& lcolor,
72  int mindepth,
73  int maxdepth)
74 {
75  if (node)
76  {
77  if (node->isinternal() && ((depth < maxdepth) || (maxdepth < 0)))
78  {
79  drawTree(idraw, node->childs[0], depth + 1, ncolor, lcolor, mindepth, maxdepth);
80  drawTree(idraw, node->childs[1], depth + 1, ncolor, lcolor, mindepth, maxdepth);
81  }
82  if (depth >= mindepth)
83  {
84  const btScalar scl = (btScalar)(node->isinternal() ? 1 : 1);
85  const btVector3 mi = node->volume.Center() - node->volume.Extents() * scl;
86  const btVector3 mx = node->volume.Center() + node->volume.Extents() * scl;
87  drawBox(idraw, mi, mx, node->isleaf() ? lcolor : ncolor);
88  }
89  }
90 }
91 
92 //
93 template <typename T>
94 static inline T sum(const btAlignedObjectArray<T>& items)
95 {
96  T v;
97  if (items.size())
98  {
99  v = items[0];
100  for (int i = 1, ni = items.size(); i < ni; ++i)
101  {
102  v += items[i];
103  }
104  }
105  return (v);
106 }
107 
108 //
109 template <typename T, typename Q>
110 static inline void add(btAlignedObjectArray<T>& items, const Q& value)
111 {
112  for (int i = 0, ni = items.size(); i < ni; ++i)
113  {
114  items[i] += value;
115  }
116 }
117 
118 //
119 template <typename T, typename Q>
120 static inline void mul(btAlignedObjectArray<T>& items, const Q& value)
121 {
122  for (int i = 0, ni = items.size(); i < ni; ++i)
123  {
124  items[i] *= value;
125  }
126 }
127 
128 //
129 template <typename T>
130 static inline T average(const btAlignedObjectArray<T>& items)
131 {
132  const btScalar n = (btScalar)(items.size() > 0 ? items.size() : 1);
133  return (sum(items) / n);
134 }
135 
136 #if 0
137 //
138  inline static btScalar tetravolume(const btVector3& x0,
139  const btVector3& x1,
140  const btVector3& x2,
141  const btVector3& x3)
142 {
143  const btVector3 a=x1-x0;
144  const btVector3 b=x2-x0;
145  const btVector3 c=x3-x0;
146  return(btDot(a,btCross(b,c)));
147 }
148 #endif
149 
150 //
151 #if 0
152 static btVector3 stresscolor(btScalar stress)
153 {
154  static const btVector3 spectrum[]= { btVector3(1,0,1),
155  btVector3(0,0,1),
156  btVector3(0,1,1),
157  btVector3(0,1,0),
158  btVector3(1,1,0),
159  btVector3(1,0,0),
160  btVector3(1,0,0)};
161  static const int ncolors=sizeof(spectrum)/sizeof(spectrum[0])-1;
162  static const btScalar one=1;
163  stress=btMax<btScalar>(0,btMin<btScalar>(1,stress))*ncolors;
164  const int sel=(int)stress;
165  const btScalar frc=stress-sel;
166  return(spectrum[sel]+(spectrum[sel+1]-spectrum[sel])*frc);
167 }
168 #endif
169 
170 //
172  btIDebugDraw* idraw,
173  int drawflags)
174 {
175  const btScalar scl = (btScalar)0.1;
176  const btScalar nscl = scl * 5;
177  const btVector3 lcolor = btVector3(0, 0, 0);
178  const btVector3 ncolor = btVector3(1, 1, 1);
179  const btVector3 ccolor = btVector3(1, 0, 0);
180  int i, j, nj;
181 
182  /* Clusters */
183  if (0 != (drawflags & fDrawFlags::Clusters))
184  {
185  srand(1806);
186  for (i = 0; i < psb->m_clusters.size(); ++i)
187  {
188  if (psb->m_clusters[i]->m_collide)
189  {
190  btVector3 color(rand() / (btScalar)RAND_MAX,
191  rand() / (btScalar)RAND_MAX,
192  rand() / (btScalar)RAND_MAX);
193  color = color.normalized() * 0.75;
195  vertices.resize(psb->m_clusters[i]->m_nodes.size());
196  for (j = 0, nj = vertices.size(); j < nj; ++j)
197  {
198  vertices[j] = psb->m_clusters[i]->m_nodes[j]->m_x;
199  }
200 #define USE_NEW_CONVEX_HULL_COMPUTER
201 #ifdef USE_NEW_CONVEX_HULL_COMPUTER
202  btConvexHullComputer computer;
203  int stride = sizeof(btVector3);
204  int count = vertices.size();
205  btScalar shrink = 0.f;
206  btScalar shrinkClamp = 0.f;
207  computer.compute(&vertices[0].getX(), stride, count, shrink, shrinkClamp);
208  for (int i = 0; i < computer.faces.size(); i++)
209  {
210  int face = computer.faces[i];
211  //printf("face=%d\n",face);
212  const btConvexHullComputer::Edge* firstEdge = &computer.edges[face];
213  const btConvexHullComputer::Edge* edge = firstEdge->getNextEdgeOfFace();
214 
215  int v0 = firstEdge->getSourceVertex();
216  int v1 = firstEdge->getTargetVertex();
217  while (edge != firstEdge)
218  {
219  int v2 = edge->getTargetVertex();
220  idraw->drawTriangle(computer.vertices[v0], computer.vertices[v1], computer.vertices[v2], color, 1);
221  edge = edge->getNextEdgeOfFace();
222  v0 = v1;
223  v1 = v2;
224  };
225  }
226 #else
227 
228  HullDesc hdsc(QF_TRIANGLES, vertices.size(), &vertices[0]);
229  HullResult hres;
230  HullLibrary hlib;
231  hdsc.mMaxVertices = vertices.size();
232  hlib.CreateConvexHull(hdsc, hres);
234  add(hres.m_OutputVertices, -center);
235  mul(hres.m_OutputVertices, (btScalar)1);
236  add(hres.m_OutputVertices, center);
237  for (j = 0; j < (int)hres.mNumFaces; ++j)
238  {
239  const int idx[] = {hres.m_Indices[j * 3 + 0], hres.m_Indices[j * 3 + 1], hres.m_Indices[j * 3 + 2]};
240  idraw->drawTriangle(hres.m_OutputVertices[idx[0]],
241  hres.m_OutputVertices[idx[1]],
242  hres.m_OutputVertices[idx[2]],
243  color, 1);
244  }
245  hlib.ReleaseResult(hres);
246 #endif
247  }
248  /* Velocities */
249 #if 0
250  for(int j=0;j<psb->m_clusters[i].m_nodes.size();++j)
251  {
252  const btSoftBody::Cluster& c=psb->m_clusters[i];
253  const btVector3 r=c.m_nodes[j]->m_x-c.m_com;
254  const btVector3 v=c.m_lv+btCross(c.m_av,r);
255  idraw->drawLine(c.m_nodes[j]->m_x,c.m_nodes[j]->m_x+v,btVector3(1,0,0));
256  }
257 #endif
258  /* Frame */
259  // btSoftBody::Cluster& c=*psb->m_clusters[i];
260  // idraw->drawLine(c.m_com,c.m_framexform*btVector3(10,0,0),btVector3(1,0,0));
261  // idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,10,0),btVector3(0,1,0));
262  // idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,0,10),btVector3(0,0,1));
263  }
264  }
265  else
266  {
267  /* Nodes */
268  if (0 != (drawflags & fDrawFlags::Nodes))
269  {
270  for (i = 0; i < psb->m_nodes.size(); ++i)
271  {
272  const btSoftBody::Node& n = psb->m_nodes[i];
273  if (0 == (n.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue;
274  idraw->drawLine(n.m_x - btVector3(scl, 0, 0), n.m_x + btVector3(scl, 0, 0), btVector3(1, 0, 0));
275  idraw->drawLine(n.m_x - btVector3(0, scl, 0), n.m_x + btVector3(0, scl, 0), btVector3(0, 1, 0));
276  idraw->drawLine(n.m_x - btVector3(0, 0, scl), n.m_x + btVector3(0, 0, scl), btVector3(0, 0, 1));
277  }
278  }
279  /* Links */
280  if (0 != (drawflags & fDrawFlags::Links))
281  {
282  for (i = 0; i < psb->m_links.size(); ++i)
283  {
284  const btSoftBody::Link& l = psb->m_links[i];
285  if (0 == (l.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue;
286  idraw->drawLine(l.m_n[0]->m_x, l.m_n[1]->m_x, lcolor);
287  }
288  }
289  /* Normals */
290  if (0 != (drawflags & fDrawFlags::Normals))
291  {
292  for (i = 0; i < psb->m_nodes.size(); ++i)
293  {
294  const btSoftBody::Node& n = psb->m_nodes[i];
295  if (0 == (n.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue;
296  const btVector3 d = n.m_n * nscl;
297  idraw->drawLine(n.m_x, n.m_x + d, ncolor);
298  idraw->drawLine(n.m_x, n.m_x - d, ncolor * 0.5);
299  }
300  }
301  /* Contacts */
302  if (0 != (drawflags & fDrawFlags::Contacts))
303  {
304  static const btVector3 axis[] = {btVector3(1, 0, 0),
305  btVector3(0, 1, 0),
306  btVector3(0, 0, 1)};
307  for (i = 0; i < psb->m_rcontacts.size(); ++i)
308  {
309  const btSoftBody::RContact& c = psb->m_rcontacts[i];
310  const btVector3 o = c.m_node->m_x - c.m_cti.m_normal *
311  (btDot(c.m_node->m_x, c.m_cti.m_normal) + c.m_cti.m_offset);
312  const btVector3 x = btCross(c.m_cti.m_normal, axis[c.m_cti.m_normal.minAxis()]).normalized();
313  const btVector3 y = btCross(x, c.m_cti.m_normal).normalized();
314  idraw->drawLine(o - x * nscl, o + x * nscl, ccolor);
315  idraw->drawLine(o - y * nscl, o + y * nscl, ccolor);
316  idraw->drawLine(o, o + c.m_cti.m_normal * nscl * 3, btVector3(1, 1, 0));
317  }
318  }
319  /* Faces */
320  if (0 != (drawflags & fDrawFlags::Faces))
321  {
322  const btScalar scl = (btScalar)0.8;
323  const btScalar alp = (btScalar)1;
324  const btVector3 col(0, (btScalar)0.7, 0);
325  for (i = 0; i < psb->m_faces.size(); ++i)
326  {
327  const btSoftBody::Face& f = psb->m_faces[i];
328  if (0 == (f.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue;
329  const btVector3 x[] = {f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x};
330  const btVector3 c = (x[0] + x[1] + x[2]) / 3;
331  idraw->drawTriangle((x[0] - c) * scl + c,
332  (x[1] - c) * scl + c,
333  (x[2] - c) * scl + c,
334  col, alp);
335  }
336  }
337  /* Tetras */
338  if (0 != (drawflags & fDrawFlags::Tetras))
339  {
340  const btScalar scl = (btScalar)0.8;
341  const btScalar alp = (btScalar)1;
342  const btVector3 col((btScalar)0.3, (btScalar)0.3, (btScalar)0.7);
343  for (int i = 0; i < psb->m_tetras.size(); ++i)
344  {
345  const btSoftBody::Tetra& t = psb->m_tetras[i];
346  if (0 == (t.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue;
347  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};
348  const btVector3 c = (x[0] + x[1] + x[2] + x[3]) / 4;
349  idraw->drawTriangle((x[0] - c) * scl + c, (x[1] - c) * scl + c, (x[2] - c) * scl + c, col, alp);
350  idraw->drawTriangle((x[0] - c) * scl + c, (x[1] - c) * scl + c, (x[3] - c) * scl + c, col, alp);
351  idraw->drawTriangle((x[1] - c) * scl + c, (x[2] - c) * scl + c, (x[3] - c) * scl + c, col, alp);
352  idraw->drawTriangle((x[2] - c) * scl + c, (x[0] - c) * scl + c, (x[3] - c) * scl + c, col, alp);
353  }
354  }
355  }
356  /* Anchors */
357  if (0 != (drawflags & fDrawFlags::Anchors))
358  {
359  for (i = 0; i < psb->m_anchors.size(); ++i)
360  {
361  const btSoftBody::Anchor& a = psb->m_anchors[i];
362  const btVector3 q = a.m_body->getWorldTransform() * a.m_local;
363  drawVertex(idraw, a.m_node->m_x, 0.25, btVector3(1, 0, 0));
364  drawVertex(idraw, q, 0.25, btVector3(0, 1, 0));
365  idraw->drawLine(a.m_node->m_x, q, btVector3(1, 1, 1));
366  }
367  for (i = 0; i < psb->m_nodes.size(); ++i)
368  {
369  const btSoftBody::Node& n = psb->m_nodes[i];
370  if (0 == (n.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue;
371  if (n.m_im <= 0)
372  {
373  drawVertex(idraw, n.m_x, 0.25, btVector3(1, 0, 0));
374  }
375  }
376  }
377 
378  /* Notes */
379  if (0 != (drawflags & fDrawFlags::Notes))
380  {
381  for (i = 0; i < psb->m_notes.size(); ++i)
382  {
383  const btSoftBody::Note& n = psb->m_notes[i];
384  btVector3 p = n.m_offset;
385  for (int j = 0; j < n.m_rank; ++j)
386  {
387  p += n.m_nodes[j]->m_x * n.m_coords[j];
388  }
389  idraw->draw3dText(p, n.m_text);
390  }
391  }
392  /* Node tree */
393  if (0 != (drawflags & fDrawFlags::NodeTree)) DrawNodeTree(psb, idraw);
394  /* Face tree */
395  if (0 != (drawflags & fDrawFlags::FaceTree)) DrawFaceTree(psb, idraw);
396  /* Cluster tree */
397  if (0 != (drawflags & fDrawFlags::ClusterTree)) DrawClusterTree(psb, idraw);
398  /* Joints */
399  if (0 != (drawflags & fDrawFlags::Joints))
400  {
401  for (i = 0; i < psb->m_joints.size(); ++i)
402  {
403  const btSoftBody::Joint* pj = psb->m_joints[i];
404  switch (pj->Type())
405  {
407  {
408  const btSoftBody::LJoint* pjl = (const btSoftBody::LJoint*)pj;
409  const btVector3 a0 = pj->m_bodies[0].xform() * pjl->m_refs[0];
410  const btVector3 a1 = pj->m_bodies[1].xform() * pjl->m_refs[1];
411  idraw->drawLine(pj->m_bodies[0].xform().getOrigin(), a0, btVector3(1, 1, 0));
412  idraw->drawLine(pj->m_bodies[1].xform().getOrigin(), a1, btVector3(0, 1, 1));
413  drawVertex(idraw, a0, 0.25, btVector3(1, 1, 0));
414  drawVertex(idraw, a1, 0.25, btVector3(0, 1, 1));
415  }
416  break;
418  {
419  //const btSoftBody::AJoint* pja=(const btSoftBody::AJoint*)pj;
420  const btVector3 o0 = pj->m_bodies[0].xform().getOrigin();
421  const btVector3 o1 = pj->m_bodies[1].xform().getOrigin();
422  const btVector3 a0 = pj->m_bodies[0].xform().getBasis() * pj->m_refs[0];
423  const btVector3 a1 = pj->m_bodies[1].xform().getBasis() * pj->m_refs[1];
424  idraw->drawLine(o0, o0 + a0 * 10, btVector3(1, 1, 0));
425  idraw->drawLine(o0, o0 + a1 * 10, btVector3(1, 1, 0));
426  idraw->drawLine(o1, o1 + a0 * 10, btVector3(0, 1, 1));
427  idraw->drawLine(o1, o1 + a1 * 10, btVector3(0, 1, 1));
428  break;
429  }
430  default:
431  {
432  }
433  }
434  }
435  }
436 }
437 
438 //
440  btIDebugDraw* idraw,
441  bool masses,
442  bool areas,
443  bool /*stress*/)
444 {
445  for (int i = 0; i < psb->m_nodes.size(); ++i)
446  {
447  const btSoftBody::Node& n = psb->m_nodes[i];
448  char text[2048] = {0};
449  char buff[1024];
450  if (masses)
451  {
452  sprintf(buff, " M(%.2f)", 1 / n.m_im);
453  strcat(text, buff);
454  }
455  if (areas)
456  {
457  sprintf(buff, " A(%.2f)", n.m_area);
458  strcat(text, buff);
459  }
460  if (text[0]) idraw->draw3dText(n.m_x, text);
461  }
462 }
463 
464 //
466  btIDebugDraw* idraw,
467  int mindepth,
468  int maxdepth)
469 {
470  drawTree(idraw, psb->m_ndbvt.m_root, 0, btVector3(1, 0, 1), btVector3(1, 1, 1), mindepth, maxdepth);
471 }
472 
473 //
475  btIDebugDraw* idraw,
476  int mindepth,
477  int maxdepth)
478 {
479  drawTree(idraw, psb->m_fdbvt.m_root, 0, btVector3(0, 1, 0), btVector3(1, 0, 0), mindepth, maxdepth);
480 }
481 
482 //
484  btIDebugDraw* idraw,
485  int mindepth,
486  int maxdepth)
487 {
488  drawTree(idraw, psb->m_cdbvt.m_root, 0, btVector3(0, 1, 1), btVector3(1, 0, 0), mindepth, maxdepth);
489 }
490 
491 //The btSoftBody object from the BulletSDK includes an array of Nodes and Links. These links appear
492 // to be first set up to connect a node to between 5 and 6 of its neighbors [480 links],
493 //and then to the rest of the nodes after the execution of the Floyd-Warshall graph algorithm
494 //[another 930 links].
495 //The way the links are stored by default, we have a number of cases where adjacent links share a node in common
496 // - this leads to the creation of a data dependency through memory.
497 //The PSolve_Links() function reads and writes nodes as it iterates over each link.
498 //So, we now have the possibility of a data dependency between iteration X
499 //that processes link L with iteration X+1 that processes link L+1
500 //because L and L+1 have one node in common, and iteration X updates the positions of that node,
501 //and iteration X+1 reads in the position of that shared node.
502 //
503 //Such a memory dependency limits the ability of a modern CPU to speculate beyond
504 //a certain point because it has to respect a possible dependency
505 //- this prevents the CPU from making full use of its out-of-order resources.
506 //If we re-order the links such that we minimize the cases where a link L and L+1 share a common node,
507 //we create a temporal gap between when the node position is written,
508 //and when it is subsequently read. This in turn allows the CPU to continue execution without
509 //risking a dependency violation. Such a reordering would result in significant speedups on
510 //modern CPUs with lots of execution resources.
511 //In our testing, we see it have a tremendous impact not only on the A7,
512 //but also on all x86 cores that ship with modern Macs.
513 //The attached source file includes a single function (ReoptimizeLinkOrder) which can be called on a
514 //btSoftBody object in the solveConstraints() function before the actual solver is invoked,
515 //or right after generateBendingConstraints() once we have all 1410 links.
516 
517 //===================================================================
518 //
519 //
520 // This function takes in a list of interdependent Links and tries
521 // to maximize the distance between calculation
522 // of dependent links. This increases the amount of parallelism that can
523 // be exploited by out-of-order instruction processors with large but
524 // (inevitably) finite instruction windows.
525 //
526 //===================================================================
527 
528 // A small structure to track lists of dependent link calculations
530 {
531 public:
532  int value; // A link calculation that is dependent on this one
533  // Positive values = "input A" while negative values = "input B"
534  LinkDeps_t* next; // Next dependence in the list
535 };
537 
538 // Dependency list constants
539 #define REOP_NOT_DEPENDENT -1
540 #define REOP_NODE_COMPLETE -2 // Must be less than REOP_NOT_DEPENDENT
541 
542 void btSoftBodyHelpers::ReoptimizeLinkOrder(btSoftBody* psb /* This can be replaced by a btSoftBody pointer */)
543 {
544  int i, nLinks = psb->m_links.size(), nNodes = psb->m_nodes.size();
545  btSoftBody::Link* lr;
546  int ar, br;
547  btSoftBody::Node* node0 = &(psb->m_nodes[0]);
548  btSoftBody::Node* node1 = &(psb->m_nodes[1]);
549  LinkDepsPtr_t linkDep;
550  int readyListHead, readyListTail, linkNum, linkDepFrees, depLink;
551 
552  // Allocate temporary buffers
553  int* nodeWrittenAt = new int[nNodes + 1]; // What link calculation produced this node's current values?
554  int* linkDepA = new int[nLinks]; // Link calculation input is dependent upon prior calculation #N
555  int* linkDepB = new int[nLinks];
556  int* readyList = new int[nLinks]; // List of ready-to-process link calculations (# of links, maximum)
557  LinkDeps_t* linkDepFreeList = new LinkDeps_t[2 * nLinks]; // Dependent-on-me list elements (2x# of links, maximum)
558  LinkDepsPtr_t* linkDepListStarts = new LinkDepsPtr_t[nLinks]; // Start nodes of dependent-on-me lists, one for each link
559 
560  // Copy the original, unsorted links to a side buffer
561  btSoftBody::Link* linkBuffer = new btSoftBody::Link[nLinks];
562  memcpy(linkBuffer, &(psb->m_links[0]), sizeof(btSoftBody::Link) * nLinks);
563 
564  // Clear out the node setup and ready list
565  for (i = 0; i < nNodes + 1; i++)
566  {
567  nodeWrittenAt[i] = REOP_NOT_DEPENDENT;
568  }
569  for (i = 0; i < nLinks; i++)
570  {
571  linkDepListStarts[i] = NULL;
572  }
573  readyListHead = readyListTail = linkDepFrees = 0;
574 
575  // Initial link analysis to set up data structures
576  for (i = 0; i < nLinks; i++)
577  {
578  // Note which prior link calculations we are dependent upon & build up dependence lists
579  lr = &(psb->m_links[i]);
580  ar = (lr->m_n[0] - node0) / (node1 - node0);
581  br = (lr->m_n[1] - node0) / (node1 - node0);
582  if (nodeWrittenAt[ar] > REOP_NOT_DEPENDENT)
583  {
584  linkDepA[i] = nodeWrittenAt[ar];
585  linkDep = &linkDepFreeList[linkDepFrees++];
586  linkDep->value = i;
587  linkDep->next = linkDepListStarts[nodeWrittenAt[ar]];
588  linkDepListStarts[nodeWrittenAt[ar]] = linkDep;
589  }
590  else
591  {
592  linkDepA[i] = REOP_NOT_DEPENDENT;
593  }
594  if (nodeWrittenAt[br] > REOP_NOT_DEPENDENT)
595  {
596  linkDepB[i] = nodeWrittenAt[br];
597  linkDep = &linkDepFreeList[linkDepFrees++];
598  linkDep->value = -(i + 1);
599  linkDep->next = linkDepListStarts[nodeWrittenAt[br]];
600  linkDepListStarts[nodeWrittenAt[br]] = linkDep;
601  }
602  else
603  {
604  linkDepB[i] = REOP_NOT_DEPENDENT;
605  }
606 
607  // Add this link to the initial ready list, if it is not dependent on any other links
608  if ((linkDepA[i] == REOP_NOT_DEPENDENT) && (linkDepB[i] == REOP_NOT_DEPENDENT))
609  {
610  readyList[readyListTail++] = i;
611  linkDepA[i] = linkDepB[i] = REOP_NODE_COMPLETE; // Probably not needed now
612  }
613 
614  // Update the nodes to mark which ones are calculated by this link
615  nodeWrittenAt[ar] = nodeWrittenAt[br] = i;
616  }
617 
618  // Process the ready list and create the sorted list of links
619  // -- By treating the ready list as a queue, we maximize the distance between any
620  // inter-dependent node calculations
621  // -- All other (non-related) nodes in the ready list will automatically be inserted
622  // in between each set of inter-dependent link calculations by this loop
623  i = 0;
624  while (readyListHead != readyListTail)
625  {
626  // Use ready list to select the next link to process
627  linkNum = readyList[readyListHead++];
628  // Copy the next-to-calculate link back into the original link array
629  psb->m_links[i++] = linkBuffer[linkNum];
630 
631  // Free up any link inputs that are dependent on this one
632  linkDep = linkDepListStarts[linkNum];
633  while (linkDep)
634  {
635  depLink = linkDep->value;
636  if (depLink >= 0)
637  {
638  linkDepA[depLink] = REOP_NOT_DEPENDENT;
639  }
640  else
641  {
642  depLink = -depLink - 1;
643  linkDepB[depLink] = REOP_NOT_DEPENDENT;
644  }
645  // Add this dependent link calculation to the ready list if *both* inputs are clear
646  if ((linkDepA[depLink] == REOP_NOT_DEPENDENT) && (linkDepB[depLink] == REOP_NOT_DEPENDENT))
647  {
648  readyList[readyListTail++] = depLink;
649  linkDepA[depLink] = linkDepB[depLink] = REOP_NODE_COMPLETE; // Probably not needed now
650  }
651  linkDep = linkDep->next;
652  }
653  }
654 
655  // Delete the temporary buffers
656  delete[] nodeWrittenAt;
657  delete[] linkDepA;
658  delete[] linkDepB;
659  delete[] readyList;
660  delete[] linkDepFreeList;
661  delete[] linkDepListStarts;
662  delete[] linkBuffer;
663 }
664 
665 //
667  btIDebugDraw* idraw)
668 {
669  if (psb->m_pose.m_bframe)
670  {
671  static const btScalar ascl = 10;
672  static const btScalar nscl = (btScalar)0.1;
673  const btVector3 com = psb->m_pose.m_com;
674  const btMatrix3x3 trs = psb->m_pose.m_rot * psb->m_pose.m_scl;
675  const btVector3 Xaxis = (trs * btVector3(1, 0, 0)).normalized();
676  const btVector3 Yaxis = (trs * btVector3(0, 1, 0)).normalized();
677  const btVector3 Zaxis = (trs * btVector3(0, 0, 1)).normalized();
678  idraw->drawLine(com, com + Xaxis * ascl, btVector3(1, 0, 0));
679  idraw->drawLine(com, com + Yaxis * ascl, btVector3(0, 1, 0));
680  idraw->drawLine(com, com + Zaxis * ascl, btVector3(0, 0, 1));
681  for (int i = 0; i < psb->m_pose.m_pos.size(); ++i)
682  {
683  const btVector3 x = com + trs * psb->m_pose.m_pos[i];
684  drawVertex(idraw, x, nscl, btVector3(1, 0, 1));
685  }
686  }
687 }
688 
689 //
691  const btVector3& to,
692  int res,
693  int fixeds)
694 {
695  /* Create nodes */
696  const int r = res + 2;
697  btVector3* x = new btVector3[r];
698  btScalar* m = new btScalar[r];
699  int i;
700 
701  for (i = 0; i < r; ++i)
702  {
703  const btScalar t = i / (btScalar)(r - 1);
704  x[i] = lerp(from, to, t);
705  m[i] = 1;
706  }
707  btSoftBody* psb = new btSoftBody(&worldInfo, r, x, m);
708  if (fixeds & 1) psb->setMass(0, 0);
709  if (fixeds & 2) psb->setMass(r - 1, 0);
710  delete[] x;
711  delete[] m;
712  /* Create links */
713  for (i = 1; i < r; ++i)
714  {
715  psb->appendLink(i - 1, i);
716  }
717  /* Finished */
718  return (psb);
719 }
720 
721 //
723  const btVector3& corner10,
724  const btVector3& corner01,
725  const btVector3& corner11,
726  int resx,
727  int resy,
728  int fixeds,
729  bool gendiags,
730  btScalar perturbation)
731 {
732 #define IDX(_x_, _y_) ((_y_)*rx + (_x_))
733  /* Create nodes */
734  if ((resx < 2) || (resy < 2)) return (0);
735  const int rx = resx;
736  const int ry = resy;
737  const int tot = rx * ry;
738  btVector3* x = new btVector3[tot];
739  btScalar* m = new btScalar[tot];
740  int iy;
741 
742  for (iy = 0; iy < ry; ++iy)
743  {
744  const btScalar ty = iy / (btScalar)(ry - 1);
745  const btVector3 py0 = lerp(corner00, corner01, ty);
746  const btVector3 py1 = lerp(corner10, corner11, ty);
747  for (int ix = 0; ix < rx; ++ix)
748  {
749  const btScalar tx = ix / (btScalar)(rx - 1);
750  btScalar pert = perturbation * btScalar(rand()) / RAND_MAX;
751  btVector3 temp1 = py1;
752  temp1.setY(py1.getY() + pert);
753  btVector3 temp = py0;
754  pert = perturbation * btScalar(rand()) / RAND_MAX;
755  temp.setY(py0.getY() + pert);
756  x[IDX(ix, iy)] = lerp(temp, temp1, tx);
757  m[IDX(ix, iy)] = 1;
758  }
759  }
760  btSoftBody* psb = new btSoftBody(&worldInfo, tot, x, m);
761  if (fixeds & 1) psb->setMass(IDX(0, 0), 0);
762  if (fixeds & 2) psb->setMass(IDX(rx - 1, 0), 0);
763  if (fixeds & 4) psb->setMass(IDX(0, ry - 1), 0);
764  if (fixeds & 8) psb->setMass(IDX(rx - 1, ry - 1), 0);
765  delete[] x;
766  delete[] m;
767  /* Create links and faces */
768  for (iy = 0; iy < ry; ++iy)
769  {
770  for (int ix = 0; ix < rx; ++ix)
771  {
772  const int idx = IDX(ix, iy);
773  const bool mdx = (ix + 1) < rx;
774  const bool mdy = (iy + 1) < ry;
775  if (mdx) psb->appendLink(idx, IDX(ix + 1, iy));
776  if (mdy) psb->appendLink(idx, IDX(ix, iy + 1));
777  if (mdx && mdy)
778  {
779  if ((ix + iy) & 1)
780  {
781  psb->appendFace(IDX(ix, iy), IDX(ix + 1, iy), IDX(ix + 1, iy + 1));
782  psb->appendFace(IDX(ix, iy), IDX(ix + 1, iy + 1), IDX(ix, iy + 1));
783  if (gendiags)
784  {
785  psb->appendLink(IDX(ix, iy), IDX(ix + 1, iy + 1));
786  }
787  }
788  else
789  {
790  psb->appendFace(IDX(ix, iy + 1), IDX(ix, iy), IDX(ix + 1, iy));
791  psb->appendFace(IDX(ix, iy + 1), IDX(ix + 1, iy), IDX(ix + 1, iy + 1));
792  if (gendiags)
793  {
794  psb->appendLink(IDX(ix + 1, iy), IDX(ix, iy + 1));
795  }
796  }
797  }
798  }
799  }
800  /* Finished */
801 #undef IDX
802  return (psb);
803 }
804 
805 //
807  const btVector3& corner00,
808  const btVector3& corner10,
809  const btVector3& corner01,
810  const btVector3& corner11,
811  int resx,
812  int resy,
813  int fixeds,
814  bool gendiags,
815  float* tex_coords)
816 {
817  /*
818  *
819  * corners:
820  *
821  * [0][0] corner00 ------- corner01 [resx][0]
822  * | |
823  * | |
824  * [0][resy] corner10 -------- corner11 [resx][resy]
825  *
826  *
827  *
828  *
829  *
830  *
831  * "fixedgs" map:
832  *
833  * corner00 --> +1
834  * corner01 --> +2
835  * corner10 --> +4
836  * corner11 --> +8
837  * upper middle --> +16
838  * left middle --> +32
839  * right middle --> +64
840  * lower middle --> +128
841  * center --> +256
842  *
843  *
844  * tex_coords size (resx-1)*(resy-1)*12
845  *
846  *
847  *
848  * SINGLE QUAD INTERNALS
849  *
850  * 1) btSoftBody's nodes and links,
851  * diagonal link is optional ("gendiags")
852  *
853  *
854  * node00 ------ node01
855  * | .
856  * | .
857  * | .
858  * | .
859  * | .
860  * node10 node11
861  *
862  *
863  *
864  * 2) Faces:
865  * two triangles,
866  * UV Coordinates (hier example for single quad)
867  *
868  * (0,1) (0,1) (1,1)
869  * 1 |\ 3 \-----| 2
870  * | \ \ |
871  * | \ \ |
872  * | \ \ |
873  * | \ \ |
874  * 2 |-----\ 3 \| 1
875  * (0,0) (1,0) (1,0)
876  *
877  *
878  *
879  *
880  *
881  *
882  */
883 
884 #define IDX(_x_, _y_) ((_y_)*rx + (_x_))
885  /* Create nodes */
886  if ((resx < 2) || (resy < 2)) return (0);
887  const int rx = resx;
888  const int ry = resy;
889  const int tot = rx * ry;
890  btVector3* x = new btVector3[tot];
891  btScalar* m = new btScalar[tot];
892 
893  int iy;
894 
895  for (iy = 0; iy < ry; ++iy)
896  {
897  const btScalar ty = iy / (btScalar)(ry - 1);
898  const btVector3 py0 = lerp(corner00, corner01, ty);
899  const btVector3 py1 = lerp(corner10, corner11, ty);
900  for (int ix = 0; ix < rx; ++ix)
901  {
902  const btScalar tx = ix / (btScalar)(rx - 1);
903  x[IDX(ix, iy)] = lerp(py0, py1, tx);
904  m[IDX(ix, iy)] = 1;
905  }
906  }
907  btSoftBody* psb = new btSoftBody(&worldInfo, tot, x, m);
908  if (fixeds & 1) psb->setMass(IDX(0, 0), 0);
909  if (fixeds & 2) psb->setMass(IDX(rx - 1, 0), 0);
910  if (fixeds & 4) psb->setMass(IDX(0, ry - 1), 0);
911  if (fixeds & 8) psb->setMass(IDX(rx - 1, ry - 1), 0);
912  if (fixeds & 16) psb->setMass(IDX((rx - 1) / 2, 0), 0);
913  if (fixeds & 32) psb->setMass(IDX(0, (ry - 1) / 2), 0);
914  if (fixeds & 64) psb->setMass(IDX(rx - 1, (ry - 1) / 2), 0);
915  if (fixeds & 128) psb->setMass(IDX((rx - 1) / 2, ry - 1), 0);
916  if (fixeds & 256) psb->setMass(IDX((rx - 1) / 2, (ry - 1) / 2), 0);
917  delete[] x;
918  delete[] m;
919 
920  int z = 0;
921  /* Create links and faces */
922  for (iy = 0; iy < ry; ++iy)
923  {
924  for (int ix = 0; ix < rx; ++ix)
925  {
926  const bool mdx = (ix + 1) < rx;
927  const bool mdy = (iy + 1) < ry;
928 
929  int node00 = IDX(ix, iy);
930  int node01 = IDX(ix + 1, iy);
931  int node10 = IDX(ix, iy + 1);
932  int node11 = IDX(ix + 1, iy + 1);
933 
934  if (mdx) psb->appendLink(node00, node01);
935  if (mdy) psb->appendLink(node00, node10);
936  if (mdx && mdy)
937  {
938  psb->appendFace(node00, node10, node11);
939  if (tex_coords)
940  {
941  tex_coords[z + 0] = CalculateUV(resx, resy, ix, iy, 0);
942  tex_coords[z + 1] = CalculateUV(resx, resy, ix, iy, 1);
943  tex_coords[z + 2] = CalculateUV(resx, resy, ix, iy, 0);
944  tex_coords[z + 3] = CalculateUV(resx, resy, ix, iy, 2);
945  tex_coords[z + 4] = CalculateUV(resx, resy, ix, iy, 3);
946  tex_coords[z + 5] = CalculateUV(resx, resy, ix, iy, 2);
947  }
948  psb->appendFace(node11, node01, node00);
949  if (tex_coords)
950  {
951  tex_coords[z + 6] = CalculateUV(resx, resy, ix, iy, 3);
952  tex_coords[z + 7] = CalculateUV(resx, resy, ix, iy, 2);
953  tex_coords[z + 8] = CalculateUV(resx, resy, ix, iy, 3);
954  tex_coords[z + 9] = CalculateUV(resx, resy, ix, iy, 1);
955  tex_coords[z + 10] = CalculateUV(resx, resy, ix, iy, 0);
956  tex_coords[z + 11] = CalculateUV(resx, resy, ix, iy, 1);
957  }
958  if (gendiags) psb->appendLink(node00, node11);
959  z += 12;
960  }
961  }
962  }
963  /* Finished */
964 #undef IDX
965  return (psb);
966 }
967 
968 float btSoftBodyHelpers::CalculateUV(int resx, int resy, int ix, int iy, int id)
969 {
970  /*
971  *
972  *
973  * node00 --- node01
974  * | |
975  * node10 --- node11
976  *
977  *
978  * ID map:
979  *
980  * node00 s --> 0
981  * node00 t --> 1
982  *
983  * node01 s --> 3
984  * node01 t --> 1
985  *
986  * node10 s --> 0
987  * node10 t --> 2
988  *
989  * node11 s --> 3
990  * node11 t --> 2
991  *
992  *
993  */
994 
995  float tc = 0.0f;
996  if (id == 0)
997  {
998  tc = (1.0f / ((resx - 1)) * ix);
999  }
1000  else if (id == 1)
1001  {
1002  tc = (1.0f / ((resy - 1)) * (resy - 1 - iy));
1003  }
1004  else if (id == 2)
1005  {
1006  tc = (1.0f / ((resy - 1)) * (resy - 1 - iy - 1));
1007  }
1008  else if (id == 3)
1009  {
1010  tc = (1.0f / ((resx - 1)) * (ix + 1));
1011  }
1012  return tc;
1013 }
1014 //
1016  const btVector3& radius,
1017  int res)
1018 {
1019  struct Hammersley
1020  {
1021  static void Generate(btVector3* x, int n)
1022  {
1023  for (int i = 0; i < n; i++)
1024  {
1025  btScalar p = 0.5, t = 0;
1026  for (int j = i; j; p *= 0.5, j >>= 1)
1027  if (j & 1) t += p;
1028  btScalar w = 2 * t - 1;
1029  btScalar a = (SIMD_PI + 2 * i * SIMD_PI) / n;
1030  btScalar s = btSqrt(1 - w * w);
1031  *x++ = btVector3(s * btCos(a), s * btSin(a), w);
1032  }
1033  }
1034  };
1036  vtx.resize(3 + res);
1037  Hammersley::Generate(&vtx[0], vtx.size());
1038  for (int i = 0; i < vtx.size(); ++i)
1039  {
1040  vtx[i] = vtx[i] * radius + center;
1041  }
1042  return (CreateFromConvexHull(worldInfo, &vtx[0], vtx.size()));
1043 }
1044 
1045 //
1047  const int* triangles,
1048  int ntriangles, bool randomizeConstraints)
1049 {
1050  int maxidx = 0;
1051  int i, j, ni;
1052 
1053  for (i = 0, ni = ntriangles * 3; i < ni; ++i)
1054  {
1055  maxidx = btMax(triangles[i], maxidx);
1056  }
1057  ++maxidx;
1060  chks.resize(maxidx * maxidx, false);
1061  vtx.resize(maxidx);
1062  for (i = 0, j = 0, ni = maxidx * 3; i < ni; ++j, i += 3)
1063  {
1064  vtx[j] = btVector3(vertices[i], vertices[i + 1], vertices[i + 2]);
1065  }
1066  btSoftBody* psb = new btSoftBody(&worldInfo, vtx.size(), &vtx[0], 0);
1067  for (i = 0, ni = ntriangles * 3; i < ni; i += 3)
1068  {
1069  const int idx[] = {triangles[i], triangles[i + 1], triangles[i + 2]};
1070 #define IDX(_x_, _y_) ((_y_)*maxidx + (_x_))
1071  for (int j = 2, k = 0; k < 3; j = k++)
1072  {
1073  if (!chks[IDX(idx[j], idx[k])])
1074  {
1075  chks[IDX(idx[j], idx[k])] = true;
1076  chks[IDX(idx[k], idx[j])] = true;
1077  psb->appendLink(idx[j], idx[k]);
1078  }
1079  }
1080 #undef IDX
1081  psb->appendFace(idx[0], idx[1], idx[2]);
1082  }
1083 
1084  if (randomizeConstraints)
1085  {
1086  psb->randomizeConstraints();
1087  }
1088 
1089  return (psb);
1090 }
1091 
1092 //
1094  int nvertices, bool randomizeConstraints)
1095 {
1096  HullDesc hdsc(QF_TRIANGLES, nvertices, vertices);
1097  HullResult hres;
1098  HullLibrary hlib; /*??*/
1099  hdsc.mMaxVertices = nvertices;
1100  hlib.CreateConvexHull(hdsc, hres);
1101  btSoftBody* psb = new btSoftBody(&worldInfo, (int)hres.mNumOutputVertices,
1102  &hres.m_OutputVertices[0], 0);
1103  for (int i = 0; i < (int)hres.mNumFaces; ++i)
1104  {
1105  const int idx[] = {static_cast<int>(hres.m_Indices[i * 3 + 0]),
1106  static_cast<int>(hres.m_Indices[i * 3 + 1]),
1107  static_cast<int>(hres.m_Indices[i * 3 + 2])};
1108  if (idx[0] < idx[1]) psb->appendLink(idx[0], idx[1]);
1109  if (idx[1] < idx[2]) psb->appendLink(idx[1], idx[2]);
1110  if (idx[2] < idx[0]) psb->appendLink(idx[2], idx[0]);
1111  psb->appendFace(idx[0], idx[1], idx[2]);
1112  }
1113  hlib.ReleaseResult(hres);
1114  if (randomizeConstraints)
1115  {
1116  psb->randomizeConstraints();
1117  }
1118  return (psb);
1119 }
1120 
1121 static int nextLine(const char* buffer)
1122 {
1123  int numBytesRead = 0;
1124 
1125  while (*buffer != '\n')
1126  {
1127  buffer++;
1128  numBytesRead++;
1129  }
1130 
1131  if (buffer[0] == 0x0a)
1132  {
1133  buffer++;
1134  numBytesRead++;
1135  }
1136  return numBytesRead;
1137 }
1138 
1139 /* Create from TetGen .ele, .face, .node data */
1141  const char* ele,
1142  const char* face,
1143  const char* node,
1144  bool bfacelinks,
1145  bool btetralinks,
1146  bool bfacesfromtetras)
1147 {
1149  int nnode = 0;
1150  int ndims = 0;
1151  int nattrb = 0;
1152  int hasbounds = 0;
1153  int result = sscanf(node, "%d %d %d %d", &nnode, &ndims, &nattrb, &hasbounds);
1154  result = sscanf(node, "%d %d %d %d", &nnode, &ndims, &nattrb, &hasbounds);
1155  node += nextLine(node);
1156 
1157  pos.resize(nnode);
1158  for (int i = 0; i < pos.size(); ++i)
1159  {
1160  int index = 0;
1161  //int bound=0;
1162  float x, y, z;
1163  sscanf(node, "%d %f %f %f", &index, &x, &y, &z);
1164 
1165  // sn>>index;
1166  // sn>>x;sn>>y;sn>>z;
1167  node += nextLine(node);
1168 
1169  //for(int j=0;j<nattrb;++j)
1170  // sn>>a;
1171 
1172  //if(hasbounds)
1173  // sn>>bound;
1174 
1175  pos[index].setX(btScalar(x));
1176  pos[index].setY(btScalar(y));
1177  pos[index].setZ(btScalar(z));
1178  }
1179  btSoftBody* psb = new btSoftBody(&worldInfo, nnode, &pos[0], 0);
1180 #if 0
1181 if(face&&face[0])
1182  {
1183  int nface=0;
1184  sf>>nface;sf>>hasbounds;
1185  for(int i=0;i<nface;++i)
1186  {
1187  int index=0;
1188  int bound=0;
1189  int ni[3];
1190  sf>>index;
1191  sf>>ni[0];sf>>ni[1];sf>>ni[2];
1192  sf>>bound;
1193  psb->appendFace(ni[0],ni[1],ni[2]);
1194  if(btetralinks)
1195  {
1196  psb->appendLink(ni[0],ni[1],0,true);
1197  psb->appendLink(ni[1],ni[2],0,true);
1198  psb->appendLink(ni[2],ni[0],0,true);
1199  }
1200  }
1201  }
1202 #endif
1203 
1204  if (ele && ele[0])
1205  {
1206  int ntetra = 0;
1207  int ncorner = 0;
1208  int neattrb = 0;
1209  sscanf(ele, "%d %d %d", &ntetra, &ncorner, &neattrb);
1210  ele += nextLine(ele);
1211 
1212  //se>>ntetra;se>>ncorner;se>>neattrb;
1213  for (int i = 0; i < ntetra; ++i)
1214  {
1215  int index = 0;
1216  int ni[4];
1217 
1218  //se>>index;
1219  //se>>ni[0];se>>ni[1];se>>ni[2];se>>ni[3];
1220  sscanf(ele, "%d %d %d %d %d", &index, &ni[0], &ni[1], &ni[2], &ni[3]);
1221  ele += nextLine(ele);
1222  //for(int j=0;j<neattrb;++j)
1223  // se>>a;
1224  psb->appendTetra(ni[0], ni[1], ni[2], ni[3]);
1225  if (btetralinks)
1226  {
1227  psb->appendLink(ni[0], ni[1], 0, true);
1228  psb->appendLink(ni[1], ni[2], 0, true);
1229  psb->appendLink(ni[2], ni[0], 0, true);
1230  psb->appendLink(ni[0], ni[3], 0, true);
1231  psb->appendLink(ni[1], ni[3], 0, true);
1232  psb->appendLink(ni[2], ni[3], 0, true);
1233  }
1234  }
1235  }
1236  psb->initializeDmInverse();
1237  psb->m_tetraScratches.resize(psb->m_tetras.size());
1238  psb->m_tetraScratchesTn.resize(psb->m_tetras.size());
1239  printf("Nodes: %u\r\n", psb->m_nodes.size());
1240  printf("Links: %u\r\n", psb->m_links.size());
1241  printf("Faces: %u\r\n", psb->m_faces.size());
1242  printf("Tetras: %u\r\n", psb->m_tetras.size());
1243  return (psb);
1244 }
1245 
1247 {
1248  std::ifstream fs;
1249  fs.open(vtk_file);
1250  btAssert(fs);
1251 
1252  typedef btAlignedObjectArray<int> Index;
1253  std::string line;
1255  btVector3 position;
1257  bool reading_points = false;
1258  bool reading_tets = false;
1259  size_t n_points = 0;
1260  size_t n_tets = 0;
1261  size_t x_count = 0;
1262  size_t indices_count = 0;
1263  while (std::getline(fs, line))
1264  {
1265  std::stringstream ss(line);
1266  if (line.size() == (size_t)(0))
1267  {
1268  }
1269  else if (line.substr(0, 6) == "POINTS")
1270  {
1271  reading_points = true;
1272  reading_tets = false;
1273  ss.ignore(128, ' '); // ignore "POINTS"
1274  ss >> n_points;
1275  X.resize(n_points);
1276  }
1277  else if (line.substr(0, 5) == "CELLS")
1278  {
1279  reading_points = false;
1280  reading_tets = true;
1281  ss.ignore(128, ' '); // ignore "CELLS"
1282  ss >> n_tets;
1283  indices.resize(n_tets);
1284  }
1285  else if (line.substr(0, 10) == "CELL_TYPES")
1286  {
1287  reading_points = false;
1288  reading_tets = false;
1289  }
1290  else if (reading_points)
1291  {
1292  btScalar p;
1293  ss >> p;
1294  position.setX(p);
1295  ss >> p;
1296  position.setY(p);
1297  ss >> p;
1298  position.setZ(p);
1299  X[x_count++] = position;
1300  }
1301  else if (reading_tets)
1302  {
1303  int d;
1304  ss >> d;
1305  if (d != 4)
1306  {
1307  printf("Load deformable failed: Only Tetrahedra are supported in VTK file.\n");
1308  fs.close();
1309  return 0;
1310  }
1311  ss.ignore(128, ' '); // ignore "4"
1312  Index tet;
1313  tet.resize(4);
1314  for (size_t i = 0; i < 4; i++)
1315  {
1316  ss >> tet[i];
1317  printf("%d ", tet[i]);
1318  }
1319  printf("\n");
1320  indices[indices_count++] = tet;
1321  }
1322  }
1323  btSoftBody* psb = new btSoftBody(&worldInfo, n_points, &X[0], 0);
1324 
1325  for (int i = 0; i < n_tets; ++i)
1326  {
1327  const Index& ni = indices[i];
1328  psb->appendTetra(ni[0], ni[1], ni[2], ni[3]);
1329  {
1330  psb->appendLink(ni[0], ni[1], 0, true);
1331  psb->appendLink(ni[1], ni[2], 0, true);
1332  psb->appendLink(ni[2], ni[0], 0, true);
1333  psb->appendLink(ni[0], ni[3], 0, true);
1334  psb->appendLink(ni[1], ni[3], 0, true);
1335  psb->appendLink(ni[2], ni[3], 0, true);
1336  }
1337  }
1338 
1339  generateBoundaryFaces(psb);
1340  psb->initializeDmInverse();
1341  psb->m_tetraScratches.resize(psb->m_tetras.size());
1342  psb->m_tetraScratchesTn.resize(psb->m_tetras.size());
1343  printf("Nodes: %u\r\n", psb->m_nodes.size());
1344  printf("Links: %u\r\n", psb->m_links.size());
1345  printf("Faces: %u\r\n", psb->m_faces.size());
1346  printf("Tetras: %u\r\n", psb->m_tetras.size());
1347 
1348  fs.close();
1349  return psb;
1350 }
1351 
1353 {
1354  int counter = 0;
1355  for (int i = 0; i < psb->m_nodes.size(); ++i)
1356  {
1357  psb->m_nodes[i].index = counter++;
1358  }
1359  typedef btAlignedObjectArray<int> Index;
1361  indices.resize(psb->m_tetras.size());
1362  for (int i = 0; i < indices.size(); ++i)
1363  {
1364  Index index;
1365  index.push_back(psb->m_tetras[i].m_n[0]->index);
1366  index.push_back(psb->m_tetras[i].m_n[1]->index);
1367  index.push_back(psb->m_tetras[i].m_n[2]->index);
1368  index.push_back(psb->m_tetras[i].m_n[3]->index);
1369  indices[i] = index;
1370  }
1371 
1372  std::map<std::vector<int>, std::vector<int> > dict;
1373  for (int i = 0; i < indices.size(); ++i)
1374  {
1375  for (int j = 0; j < 4; ++j)
1376  {
1377  std::vector<int> f;
1378  if (j == 0)
1379  {
1380  f.push_back(indices[i][1]);
1381  f.push_back(indices[i][0]);
1382  f.push_back(indices[i][2]);
1383  }
1384  if (j == 1)
1385  {
1386  f.push_back(indices[i][3]);
1387  f.push_back(indices[i][0]);
1388  f.push_back(indices[i][1]);
1389  }
1390  if (j == 2)
1391  {
1392  f.push_back(indices[i][3]);
1393  f.push_back(indices[i][1]);
1394  f.push_back(indices[i][2]);
1395  }
1396  if (j == 3)
1397  {
1398  f.push_back(indices[i][2]);
1399  f.push_back(indices[i][0]);
1400  f.push_back(indices[i][3]);
1401  }
1402  std::vector<int> f_sorted = f;
1403  std::sort(f_sorted.begin(), f_sorted.end());
1404  if (dict.find(f_sorted) != dict.end())
1405  {
1406  dict.erase(f_sorted);
1407  }
1408  else
1409  {
1410  dict.insert(std::make_pair(f_sorted, f));
1411  }
1412  }
1413  }
1414 
1415  for (std::map<std::vector<int>, std::vector<int> >::iterator it = dict.begin(); it != dict.end(); ++it)
1416  {
1417  std::vector<int> f = it->second;
1418  psb->appendFace(f[0], f[1], f[2]);
1419  }
1420 }
1421 
1422 //Write the surface mesh to an obj file.
1423 void btSoftBodyHelpers::writeObj(const char* filename, const btSoftBody* psb)
1424 {
1425  std::ofstream fs;
1426  fs.open(filename);
1427  btAssert(fs);
1428 
1429  if (psb->m_tetras.size() > 0)
1430  {
1431  // For tetrahedron mesh, we need to re-index the surface mesh for it to be in obj file/
1432  std::map<int, int> dict;
1433  for (int i = 0; i < psb->m_faces.size(); i++)
1434  {
1435  for (int d = 0; d < 3; d++)
1436  {
1437  int index = psb->m_faces[i].m_n[d]->index;
1438  if (dict.find(index) == dict.end())
1439  {
1440  int dict_size = dict.size();
1441  dict[index] = dict_size;
1442  fs << "v";
1443  for (int k = 0; k < 3; k++)
1444  {
1445  fs << " " << psb->m_nodes[index].m_x[k];
1446  }
1447  fs << "\n";
1448  }
1449  }
1450  }
1451  // Write surface mesh.
1452  for (int i = 0; i < psb->m_faces.size(); ++i)
1453  {
1454  fs << "f";
1455  for (int n = 0; n < 3; n++)
1456  {
1457  fs << " " << dict[psb->m_faces[i].m_n[n]->index] + 1;
1458  }
1459  fs << "\n";
1460  }
1461  }
1462  else
1463  {
1464  // For trimesh, directly write out all the nodes and faces.xs
1465  for (int i = 0; i < psb->m_nodes.size(); ++i)
1466  {
1467  fs << "v";
1468  for (int d = 0; d < 3; d++)
1469  {
1470  fs << " " << psb->m_nodes[i].m_x[d];
1471  }
1472  fs << "\n";
1473  }
1474 
1475  for (int i = 0; i < psb->m_faces.size(); ++i)
1476  {
1477  fs << "f";
1478  for (int n = 0; n < 3; n++)
1479  {
1480  fs << " " << psb->m_faces[i].m_n[n]->index + 1;
1481  }
1482  fs << "\n";
1483  }
1484  }
1485  fs.close();
1486 }
1487 
1488 void btSoftBodyHelpers::duplicateFaces(const char* filename, const btSoftBody* psb)
1489 {
1490  std::ifstream fs_read;
1491  fs_read.open(filename);
1492  std::string line;
1493  btVector3 pos;
1495  while (std::getline(fs_read, line))
1496  {
1497  std::stringstream ss(line);
1498  if (line[0] == 'v')
1499  {
1500  }
1501  else if (line[0] == 'f')
1502  {
1503  ss.ignore();
1504  int id0, id1, id2;
1505  ss >> id0;
1506  ss >> id1;
1507  ss >> id2;
1508  btAlignedObjectArray<int> new_face;
1509  new_face.push_back(id1);
1510  new_face.push_back(id0);
1511  new_face.push_back(id2);
1512  additional_faces.push_back(new_face);
1513  }
1514  }
1515  fs_read.close();
1516 
1517  std::ofstream fs_write;
1518  fs_write.open(filename, std::ios_base::app);
1519  for (int i = 0; i < additional_faces.size(); ++i)
1520  {
1521  fs_write << "f";
1522  for (int n = 0; n < 3; n++)
1523  {
1524  fs_write << " " << additional_faces[i][n];
1525  }
1526  fs_write << "\n";
1527  }
1528  fs_write.close();
1529 }
1530 
1531 // Given a simplex with vertices a,b,c,d, find the barycentric weights of p in this simplex
1533 {
1534  btVector3 vap = p - a;
1535  btVector3 vbp = p - b;
1536 
1537  btVector3 vab = b - a;
1538  btVector3 vac = c - a;
1539  btVector3 vad = d - a;
1540 
1541  btVector3 vbc = c - b;
1542  btVector3 vbd = d - b;
1543  btScalar va6 = (vbp.cross(vbd)).dot(vbc);
1544  btScalar vb6 = (vap.cross(vac)).dot(vad);
1545  btScalar vc6 = (vap.cross(vad)).dot(vab);
1546  btScalar vd6 = (vap.cross(vab)).dot(vac);
1547  btScalar v6 = btScalar(1) / (vab.cross(vac).dot(vad));
1548  bary = btVector4(va6 * v6, vb6 * v6, vc6 * v6, vd6 * v6);
1549 }
1550 
1551 // Given a simplex with vertices a,b,c, find the barycentric weights of p in this simplex. bary[3] = 0.
1553 {
1554  btVector3 v0 = b - a, v1 = c - a, v2 = p - a;
1555  btScalar d00 = btDot(v0, v0);
1556  btScalar d01 = btDot(v0, v1);
1557  btScalar d11 = btDot(v1, v1);
1558  btScalar d20 = btDot(v2, v0);
1559  btScalar d21 = btDot(v2, v1);
1560  btScalar invDenom = 1.0 / (d00 * d11 - d01 * d01);
1561  bary[1] = (d11 * d20 - d01 * d21) * invDenom;
1562  bary[2] = (d00 * d21 - d01 * d20) * invDenom;
1563  bary[0] = 1.0 - bary[1] - bary[2];
1564  bary[3] = 0;
1565 }
1566 
1567 // Iterate through all render nodes to find the simulation tetrahedron that contains the render node and record the barycentric weights
1568 // If the node is not inside any tetrahedron, assign it to the tetrahedron in which the node has the least negative barycentric weight
1570 {
1571  psb->m_z.resize(0);
1574  for (int i = 0; i < psb->m_renderNodes.size(); ++i)
1575  {
1576  const btVector3& p = psb->m_renderNodes[i].m_x;
1577  btVector4 bary;
1578  btVector4 optimal_bary;
1579  btScalar min_bary_weight = -1e3;
1581  for (int j = 0; j < psb->m_tetras.size(); ++j)
1582  {
1583  const btSoftBody::Tetra& t = psb->m_tetras[j];
1584  getBarycentricWeights(t.m_n[0]->m_x, t.m_n[1]->m_x, t.m_n[2]->m_x, t.m_n[3]->m_x, p, bary);
1585  btScalar new_min_bary_weight = bary[0];
1586  for (int k = 1; k < 4; ++k)
1587  {
1588  new_min_bary_weight = btMin(new_min_bary_weight, bary[k]);
1589  }
1590  if (new_min_bary_weight > min_bary_weight)
1591  {
1593  parents.push_back(t.m_n[0]);
1594  parents.push_back(t.m_n[1]);
1595  parents.push_back(t.m_n[2]);
1596  parents.push_back(t.m_n[3]);
1597  optimal_parents = parents;
1598  optimal_bary = bary;
1599  min_bary_weight = new_min_bary_weight;
1600  // stop searching if p is inside the tetrahedron at hand
1601  if (bary[0] >= 0. && bary[1] >= 0. && bary[2] >= 0. && bary[3] >= 0.)
1602  {
1603  break;
1604  }
1605  }
1606  }
1607  psb->m_renderNodesInterpolationWeights[i] = optimal_bary;
1608  psb->m_renderNodesParents[i] = optimal_parents;
1609  }
1610 }
1611 
1612 // Iterate through all render nodes to find the simulation triangle that's closest to the node in the barycentric sense.
1614 {
1617  psb->m_z.resize(psb->m_renderNodes.size());
1618  for (int i = 0; i < psb->m_renderNodes.size(); ++i)
1619  {
1620  const btVector3& p = psb->m_renderNodes[i].m_x;
1621  btVector4 bary;
1622  btVector4 optimal_bary;
1623  btScalar min_bary_weight = -SIMD_INFINITY;
1625  btScalar dist = 0, optimal_dist = 0;
1626  for (int j = 0; j < psb->m_faces.size(); ++j)
1627  {
1628  const btSoftBody::Face& f = psb->m_faces[j];
1629  btVector3 n = btCross(f.m_n[1]->m_x - f.m_n[0]->m_x, f.m_n[2]->m_x - f.m_n[0]->m_x);
1630  btVector3 unit_n = n.normalized();
1631  dist = (p - f.m_n[0]->m_x).dot(unit_n);
1632  btVector3 proj_p = p - dist * unit_n;
1633  getBarycentricWeights(f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, proj_p, bary);
1634  btScalar new_min_bary_weight = bary[0];
1635  for (int k = 1; k < 3; ++k)
1636  {
1637  new_min_bary_weight = btMin(new_min_bary_weight, bary[k]);
1638  }
1639 
1640  // p is out of the current best triangle, we found a traingle that's better
1641  bool better_than_closest_outisde = (new_min_bary_weight > min_bary_weight && min_bary_weight < 0.);
1642  // p is inside of the current best triangle, we found a triangle that's better
1643  bool better_than_best_inside = (new_min_bary_weight >= 0 && min_bary_weight >= 0 && btFabs(dist) < btFabs(optimal_dist));
1644 
1645  if (better_than_closest_outisde || better_than_best_inside)
1646  {
1648  parents.push_back(f.m_n[0]);
1649  parents.push_back(f.m_n[1]);
1650  parents.push_back(f.m_n[2]);
1651  optimal_parents = parents;
1652  optimal_bary = bary;
1653  optimal_dist = dist;
1654  min_bary_weight = new_min_bary_weight;
1655  }
1656  }
1657  psb->m_renderNodesInterpolationWeights[i] = optimal_bary;
1658  psb->m_renderNodesParents[i] = optimal_parents;
1659  psb->m_z[i] = optimal_dist;
1660  }
1661 }
struct Link Link
NSNotificationCenter * center
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble x2
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei stride
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color or the default fallback if none is specified Separate Split a vector into its X
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
@ QF_TRIANGLES
Definition: btConvexHull.h:50
void sort(btMatrix3x3 &U, btVector3 &sigma, btMatrix3x3 &V, int t)
Helper function of 3X3 SVD for sorting singular values.
btMatrix3x3
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition: btMatrix3x3.h:50
SIMD_FORCE_INLINE const T & btMin(const T &a, const T &b)
Definition: btMinMax.h:21
SIMD_FORCE_INLINE const T & btMax(const T &a, const T &b)
Definition: btMinMax.h:27
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
SIMD_FORCE_INLINE const btScalar & getX() const
Return the x value.
Definition: btQuadWord.h:99
SIMD_FORCE_INLINE btScalar btCos(btScalar x)
Definition: btScalar.h:498
#define SIMD_PI
Definition: btScalar.h:526
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
SIMD_FORCE_INLINE btScalar btSin(btScalar x)
Definition: btScalar.h:499
SIMD_FORCE_INLINE btScalar btFabs(btScalar x)
Definition: btScalar.h:497
SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
Definition: btScalar.h:466
#define SIMD_INFINITY
Definition: btScalar.h:544
#define btAssert(x)
Definition: btScalar.h:295
static T average(const btAlignedObjectArray< T > &items)
#define REOP_NODE_COMPLETE
static void drawTree(btIDebugDraw *idraw, const btDbvtNode *node, int depth, const btVector3 &ncolor, const btVector3 &lcolor, int mindepth, int maxdepth)
static void mul(btAlignedObjectArray< T > &items, const Q &value)
static int nextLine(const char *buffer)
static void add(btAlignedObjectArray< T > &items, const Q &value)
#define IDX(_x_, _y_)
static T sum(const btAlignedObjectArray< T > &items)
static void drawBox(btIDebugDraw *idraw, const btVector3 &mins, const btVector3 &maxs, const btVector3 &color)
#define REOP_NOT_DEPENDENT
static void drawVertex(btIDebugDraw *idraw, const btVector3 &x, btScalar s, const btVector3 &c)
btSoftBodyHelpers.cpp by Nathanael Presson
LinkDeps_t * LinkDepsPtr_t
SIMD_FORCE_INLINE btScalar btDot(const btVector3 &v1, const btVector3 &v2)
Return the dot product between two vectors.
Definition: btVector3.h:890
btVector3
btVector3 can be used to represent 3D points and vectors. It has an un-used w component to suit 16-by...
Definition: btVector3.h:82
SIMD_FORCE_INLINE btVector3 normalized() const
Return a normalized version of this vector.
SIMD_FORCE_INLINE btVector3 btCross(const btVector3 &v1, const btVector3 &v2)
Return the cross product of two vectors.
Definition: btVector3.h:918
unsigned int mMaxVertices
Definition: btConvexHull.h:103
HullError ReleaseResult(HullResult &result)
HullError CreateConvexHull(const HullDesc &desc, HullResult &result)
btAlignedObjectArray< btVector3 > m_OutputVertices
Definition: btConvexHull.h:39
btAlignedObjectArray< unsigned int > m_Indices
Definition: btConvexHull.h:42
unsigned int mNumOutputVertices
Definition: btConvexHull.h:38
unsigned int mNumFaces
Definition: btConvexHull.h:40
LinkDeps_t * next
SIMD_FORCE_INLINE int size() const
return the number of elements in the array
SIMD_FORCE_INLINE void resize(int newsize, const T &fillData=T())
SIMD_FORCE_INLINE void push_back(const T &_Val)
const Edge * getNextEdgeOfFace() const
btAlignedObjectArray< btVector3 > vertices
btAlignedObjectArray< int > faces
btAlignedObjectArray< Edge > edges
virtual void drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color)=0
virtual void draw3dText(const btVector3 &location, const char *textString)=0
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
btDbvt m_cdbvt
Definition: btSoftBody.h:822
void appendFace(int model=-1, Material *mat=0)
Definition: btSoftBody.cpp:428
void setMass(int node, btScalar mass)
Definition: btSoftBody.cpp:919
tJointArray m_joints
Definition: btSoftBody.h:814
btAlignedObjectArray< TetraScratch > m_tetraScratchesTn
Definition: btSoftBody.h:806
Pose m_pose
Definition: btSoftBody.h:795
void appendTetra(int model, Material *mat)
Definition: btSoftBody.cpp:468
tTetraArray m_tetras
Definition: btSoftBody.h:804
btAlignedObjectArray< TetraScratch > m_tetraScratches
Definition: btSoftBody.h:805
btAlignedObjectArray< btVector4 > m_renderNodesInterpolationWeights
Definition: btSoftBody.h:832
tFaceArray m_faces
Definition: btSoftBody.h:802
btAlignedObjectArray< btScalar > m_z
Definition: btSoftBody.h:834
tRContactArray m_rcontacts
Definition: btSoftBody.h:809
tClusterArray m_clusters
Definition: btSoftBody.h:823
btAlignedObjectArray< btAlignedObjectArray< const btSoftBody::Node * > > m_renderNodesParents
Definition: btSoftBody.h:833
tNoteArray m_notes
Definition: btSoftBody.h:798
btDbvt m_fdbvt
Definition: btSoftBody.h:820
tLinkArray m_links
Definition: btSoftBody.h:801
tAnchorArray m_anchors
Definition: btSoftBody.h:807
void randomizeConstraints()
tNodeArray m_nodes
Definition: btSoftBody.h:799
void appendLink(int model=-1, Material *mat=0)
Definition: btSoftBody.cpp:388
void initializeDmInverse()
tNodeArray m_renderNodes
Definition: btSoftBody.h:800
btDbvt m_ndbvt
Definition: btSoftBody.h:819
OperationNode * node
StackEntry * from
uint pos
uint col
int count
ccl_global float * buffer
ccl_gpu_kernel_postfix ccl_global int * counter
ccl_gpu_kernel_postfix int ccl_global int * indices
#define T
static float lerp(float t, float a, float b)
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
T dot(const vec_base< T, Size > &a, const vec_base< T, Size > &b)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
SocketIndexByIdentifierMap * map
btDbvtNode * m_root
Definition: btDbvt.h:302
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)
static void writeObj(const char *file, const btSoftBody *psb)
static btSoftBody * CreateFromTriMesh(btSoftBodyWorldInfo &worldInfo, const btScalar *vertices, const int *triangles, int ntriangles, bool randomizeConstraints=true)
static void extrapolateBarycentricWeights(btSoftBody *psb)
static void DrawNodeTree(btSoftBody *psb, btIDebugDraw *idraw, int mindepth=0, int maxdepth=-1)
static void getBarycentricWeights(const btVector3 &a, const btVector3 &b, const btVector3 &c, const btVector3 &d, const btVector3 &p, btVector4 &bary)
static btSoftBody * CreateFromTetGenData(btSoftBodyWorldInfo &worldInfo, const char *ele, const char *face, const char *node, bool bfacelinks, bool btetralinks, bool bfacesfromtetras)
static btSoftBody * CreateFromConvexHull(btSoftBodyWorldInfo &worldInfo, const btVector3 *vertices, int nvertices, bool randomizeConstraints=true)
static btSoftBody * CreateFromVtkFile(btSoftBodyWorldInfo &worldInfo, const char *vtk_file)
static void ReoptimizeLinkOrder(btSoftBody *psb)
static void DrawFaceTree(btSoftBody *psb, btIDebugDraw *idraw, int mindepth=0, int maxdepth=-1)
static void DrawInfos(btSoftBody *psb, btIDebugDraw *idraw, bool masses, bool areas, bool stress)
static btSoftBody * CreateEllipsoid(btSoftBodyWorldInfo &worldInfo, const btVector3 &center, const btVector3 &radius, int res)
static void DrawClusterTree(btSoftBody *psb, btIDebugDraw *idraw, int mindepth=0, int maxdepth=-1)
static float CalculateUV(int resx, int resy, int ix, int iy, int id)
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, btScalar perturbation=0.)
static void generateBoundaryFaces(btSoftBody *psb)
static void Draw(btSoftBody *psb, btIDebugDraw *idraw, int drawflags=fDrawFlags::Std)
static void duplicateFaces(const char *filename, const btSoftBody *psb)
static void DrawFrame(btSoftBody *psb, btIDebugDraw *idraw)
static btSoftBody * CreateRope(btSoftBodyWorldInfo &worldInfo, const btVector3 &from, const btVector3 &to, int res, int fixeds)
static void interpolateBarycentricWeights(btSoftBody *psb)
const btTransform & xform() const
Definition: btSoftBody.h:534
Node * m_n[3]
Definition: btSoftBody.h:296
Material * m_material
Definition: btSoftBody.h:258
btVector3 m_refs[2]
Definition: btSoftBody.h:627
virtual eType::_ Type() const =0
btScalar m_area
Definition: btSoftBody.h:270
btVector3 m_x
Definition: btSoftBody.h:263
btVector3 m_n
Definition: btSoftBody.h:268
btScalar m_coords[4]
Definition: btSoftBody.h:430
btVector3 m_offset
Definition: btSoftBody.h:427
Node * m_nodes[4]
Definition: btSoftBody.h:429
const char * m_text
Definition: btSoftBody.h:426
btMatrix3x3 m_scl
Definition: btSoftBody.h:442
btVector3 m_com
Definition: btSoftBody.h:440
tVector3Array m_pos
Definition: btSoftBody.h:438
btMatrix3x3 m_rot
Definition: btSoftBody.h:441