Bullet Collision Detection & Physics Library
btSoftBodySolverData.h
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 */
15 
16 #ifndef BT_SOFT_BODY_SOLVER_DATA_H
17 #define BT_SOFT_BODY_SOLVER_DATA_H
18 
20 #include "vectormath/vmInclude.h"
21 
22 
24 {
25 public:
30  {
31  public:
32  int vertex0;
33  int vertex1;
34 
36  {
37  vertex0 = 0;
38  vertex1 = 0;
39  }
40 
41  LinkNodePair( int v0, int v1 )
42  {
43  vertex0 = v0;
44  vertex1 = v1;
45  }
46  };
47 
52  {
53  protected:
54  int m_vertex0;
55  int m_vertex1;
58 
59  public:
60 
62  {
63  m_vertex0 = 0;
64  m_vertex1 = 0;
66  m_linkStrength = 1.0;
67  }
68 
69  LinkDescription( int newVertex0, int newVertex1, float linkLinearStiffness )
70  {
71  m_vertex0 = newVertex0;
72  m_vertex1 = newVertex1;
73  m_linkLinearStiffness = linkLinearStiffness;
74  m_linkStrength = 1.0;
75  }
76 
78  {
79  LinkNodePair nodes;
80  nodes.vertex0 = m_vertex0;
81  nodes.vertex1 = m_vertex1;
82  return nodes;
83  }
84 
85  void setVertex0( int vertex )
86  {
87  m_vertex0 = vertex;
88  }
89 
90  void setVertex1( int vertex )
91  {
92  m_vertex1 = vertex;
93  }
94 
95  void setLinkLinearStiffness( float linearStiffness )
96  {
97  m_linkLinearStiffness = linearStiffness;
98  }
99 
100  void setLinkStrength( float strength )
101  {
102  m_linkStrength = strength;
103  }
104 
105  int getVertex0() const
106  {
107  return m_vertex0;
108  }
109 
110  int getVertex1() const
111  {
112  return m_vertex1;
113  }
114 
115  float getLinkStrength() const
116  {
117  return m_linkStrength;
118  }
119 
121  {
122  return m_linkLinearStiffness;
123  }
124  };
125 
126 
127 protected:
128  // NOTE:
129  // Vertex reference data is stored relative to global array, not relative to individual cloth.
130  // Values must be correct if being passed into single-cloth VBOs or when migrating from one solver
131  // to another.
132 
133  btAlignedObjectArray< LinkNodePair > m_links; // Vertex pair for the link
135  // (inverseMassA + inverseMassB)/ linear stiffness coefficient
138  // Current vector length of link
140  // 1/(current length * current length * massLSC)
144 
145 public:
147  {
148  }
149 
151  {
152  }
153 
154  virtual void clear()
155  {
156  m_links.resize(0);
163  }
164 
166  {
167  return m_links.size();
168  }
169 
171  virtual void createLinks( int numLinks )
172  {
173  int previousSize = m_links.size();
174  int newSize = previousSize + numLinks;
175 
176  // Resize all the arrays that store link data
177  m_links.resize( newSize );
178  m_linkStrength.resize( newSize );
179  m_linksMassLSC.resize( newSize );
180  m_linksRestLengthSquared.resize( newSize );
181  m_linksCLength.resize( newSize );
182  m_linksLengthRatio.resize( newSize );
183  m_linksRestLength.resize( newSize );
185  }
186 
188  virtual void setLinkAt( const LinkDescription &link, int linkIndex )
189  {
190  m_links[linkIndex] = link.getVertexPair();
191  m_linkStrength[linkIndex] = link.getLinkStrength();
192  m_linksMassLSC[linkIndex] = 0.f;
193  m_linksRestLengthSquared[linkIndex] = 0.f;
194  m_linksCLength[linkIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
195  m_linksLengthRatio[linkIndex] = 0.f;
196  m_linksRestLength[linkIndex] = 0.f;
198  }
199 
200 
206  virtual bool onAccelerator()
207  {
208  return true;
209  }
210 
215  virtual bool moveToAccelerator()
216  {
217  return true;
218  }
219 
224  virtual bool moveFromAccelerator()
225  {
226  return true;
227  }
228 
229 
230 
234  LinkNodePair &getVertexPair( int linkIndex )
235  {
236  return m_links[linkIndex];
237  }
238 
242  float &getStrength( int linkIndex )
243  {
244  return m_linkStrength[linkIndex];
245  }
246 
251  virtual float &getStrengthCorrected( int linkIndex )
252  {
253  return getStrength( linkIndex );
254  }
255 
259  float &getRestLength( int linkIndex )
260  {
261  return m_linksRestLength[linkIndex];
262  }
263 
267  float &getLinearStiffnessCoefficient( int linkIndex )
268  {
270  }
271 
275  float &getMassLSC( int linkIndex )
276  {
277  return m_linksMassLSC[linkIndex];
278  }
279 
283  float &getRestLengthSquared( int linkIndex )
284  {
285  return m_linksRestLengthSquared[linkIndex];
286  }
287 
292  {
293  return m_linksCLength[linkIndex];
294  }
295 
299  float &getLinkLengthRatio( int linkIndex )
300  {
301  return m_linksLengthRatio[linkIndex];
302  }
303 };
304 
305 
306 
313 {
314 public:
319  {
320  private:
324 
325  public:
327  {
328  m_position = Vectormath::Aos::Point3( 0.f, 0.f, 0.f );
329  m_inverseMass = 0.f;
330  }
331 
332  VertexDescription( const Vectormath::Aos::Point3 &position, float mass )
333  {
334  m_position = position;
335  if( mass > 0.f )
336  m_inverseMass = 1.0f/mass;
337  else
338  m_inverseMass = 0.f;
339  }
340 
341  void setPosition( const Vectormath::Aos::Point3 &position )
342  {
343  m_position = position;
344  }
345 
346  void setInverseMass( float inverseMass )
347  {
348  m_inverseMass = inverseMass;
349  }
350 
351  void setMass( float mass )
352  {
353  if( mass > 0.f )
354  m_inverseMass = 1.0f/mass;
355  else
356  m_inverseMass = 0.f;
357  }
358 
360  {
361  return m_position;
362  }
363 
364  float getInverseMass() const
365  {
366  return m_inverseMass;
367  }
368 
369  float getMass() const
370  {
371  if( m_inverseMass == 0.f )
372  return 0.f;
373  else
374  return 1.0f/m_inverseMass;
375  }
376  };
377 protected:
378 
379  // identifier for the individual cloth
380  // For the CPU we don't really need this as we can grab the cloths and iterate over only their vertices
381  // For a parallel accelerator knowing on a per-vertex basis which cloth we're part of will help for obtaining
382  // per-cloth data
383  // For sorting etc it might also be helpful to be able to use in-array data such as this.
391  btAlignedObjectArray< float > m_vertexArea; // Area controlled by the vertex
392  btAlignedObjectArray< int > m_vertexTriangleCount; // Number of triangles touching this vertex
393 
394 public:
396  {
397  }
398 
400  {
401  }
402 
403  virtual void clear()
404  {
412  m_vertexArea.resize(0);
414  }
415 
417  {
418  return m_vertexPosition.size();
419  }
420 
421  int getClothIdentifier( int vertexIndex )
422  {
423  return m_clothIdentifier[vertexIndex];
424  }
425 
426  void setVertexAt( const VertexDescription &vertex, int vertexIndex )
427  {
428  m_vertexPosition[vertexIndex] = vertex.getPosition();
429  m_vertexPreviousPosition[vertexIndex] = vertex.getPosition();
430  m_vertexVelocity[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
431  m_vertexForceAccumulator[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
432  m_vertexNormal[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
433  m_vertexInverseMass[vertexIndex] = vertex.getInverseMass();
434  m_vertexArea[vertexIndex] = 0.f;
435  m_vertexTriangleCount[vertexIndex] = 0;
436  }
437 
442  void createVertices( int numVertices, int clothIdentifier, int maxVertices = 0 )
443  {
444  int previousSize = m_vertexPosition.size();
445  if( maxVertices == 0 )
446  maxVertices = numVertices;
447  int newSize = previousSize + maxVertices;
448 
449  // Resize all the arrays that store vertex data
450  m_clothIdentifier.resize( newSize );
451  m_vertexPosition.resize( newSize );
452  m_vertexPreviousPosition.resize( newSize );
453  m_vertexVelocity.resize( newSize );
454  m_vertexForceAccumulator.resize( newSize );
455  m_vertexNormal.resize( newSize );
456  m_vertexInverseMass.resize( newSize );
457  m_vertexArea.resize( newSize );
458  m_vertexTriangleCount.resize( newSize );
459 
460  for( int vertexIndex = previousSize; vertexIndex < newSize; ++vertexIndex )
461  m_clothIdentifier[vertexIndex] = clothIdentifier;
462  for( int vertexIndex = (previousSize + numVertices); vertexIndex < newSize; ++vertexIndex )
463  m_clothIdentifier[vertexIndex] = -1;
464  }
465 
466  // Get and set methods in header so they can be inlined
467 
472  {
473  return m_vertexPosition[vertexIndex];
474  }
475 
476  Vectormath::Aos::Point3 getPosition( int vertexIndex ) const
477  {
478  return m_vertexPosition[vertexIndex];
479  }
480 
485  {
486  return m_vertexPreviousPosition[vertexIndex];
487  }
488 
493  {
494  return m_vertexVelocity[vertexIndex];
495  }
496 
501  {
502  return m_vertexForceAccumulator[vertexIndex];
503  }
504 
509  {
510  return m_vertexNormal[vertexIndex];
511  }
512 
513  Vectormath::Aos::Vector3 getNormal( int vertexIndex ) const
514  {
515  return m_vertexNormal[vertexIndex];
516  }
517 
521  float &getInverseMass( int vertexIndex )
522  {
523  return m_vertexInverseMass[vertexIndex];
524  }
525 
529  float &getArea( int vertexIndex )
530  {
531  return m_vertexArea[vertexIndex];
532  }
533 
537  int &getTriangleCount( int vertexIndex )
538  {
539  return m_vertexTriangleCount[vertexIndex];
540  }
541 
542 
543 
549  virtual bool onAccelerator()
550  {
551  return true;
552  }
553 
558  virtual bool moveToAccelerator()
559  {
560  return true;
561  }
562 
571  virtual bool moveFromAccelerator(bool bCopy = false, bool bCopyMinimum = true)
572  {
573  return true;
574  }
575 
577  {
578  return m_vertexPosition;
579  }
580 };
581 
582 
584 {
585 public:
591  {
592  public:
593  int vertex0;
594  int vertex1;
595  int vertex2;
596  int _padding;
597 
599  {
600  vertex0 = 0;
601  vertex1 = 0;
602  vertex2 = 0;
603  _padding = -1;
604  }
605 
606  TriangleNodeSet( int newVertex0, int newVertex1, int newVertex2 )
607  {
608  vertex0 = newVertex0;
609  vertex1 = newVertex1;
610  vertex2 = newVertex2;
611  }
612  };
613 
615  {
616  protected:
620 
621  public:
623  {
624  m_vertex0 = 0;
625  m_vertex1 = 0;
626  m_vertex2 = 0;
627  }
628 
629  TriangleDescription( int newVertex0, int newVertex1, int newVertex2 )
630  {
631  m_vertex0 = newVertex0;
632  m_vertex1 = newVertex1;
633  m_vertex2 = newVertex2;
634  }
635 
637  {
639  nodes.vertex0 = m_vertex0;
640  nodes.vertex1 = m_vertex1;
641  nodes.vertex2 = m_vertex2;
642  return nodes;
643  }
644  };
645 
646 protected:
647  // NOTE:
648  // Vertex reference data is stored relative to global array, not relative to individual cloth.
649  // Values must be correct if being passed into single-cloth VBOs or when migrating from one solver
650  // to another.
654 
655 public:
657  {
658  }
659 
661  {
662 
663  }
664 
665  virtual void clear()
666  {
667  m_vertexIndices.resize(0);
668  m_area.resize(0);
669  m_normal.resize(0);
670  }
671 
673  {
674  return m_vertexIndices.size();
675  }
676 
677  virtual void setTriangleAt( const TriangleDescription &triangle, int triangleIndex )
678  {
679  m_vertexIndices[triangleIndex] = triangle.getVertexSet();
680  }
681 
682  virtual void createTriangles( int numTriangles )
683  {
684  int previousSize = m_vertexIndices.size();
685  int newSize = previousSize + numTriangles;
686 
687  // Resize all the arrays that store triangle data
688  m_vertexIndices.resize( newSize );
689  m_area.resize( newSize );
690  m_normal.resize( newSize );
691  }
692 
696  const TriangleNodeSet &getVertexSet( int triangleIndex )
697  {
698  return m_vertexIndices[triangleIndex];
699  }
700 
704  float &getTriangleArea( int triangleIndex )
705  {
706  return m_area[triangleIndex];
707  }
708 
712  Vectormath::Aos::Vector3 &getNormal( int triangleIndex )
713  {
714  return m_normal[triangleIndex];
715  }
716 
722  virtual bool onAccelerator()
723  {
724  return true;
725  }
726 
731  virtual bool moveToAccelerator()
732  {
733  return true;
734  }
735 
740  virtual bool moveFromAccelerator()
741  {
742  return true;
743  }
744 };
745 
746 
747 #endif // #ifndef BT_SOFT_BODY_SOLVER_DATA_H
748 
virtual void setTriangleAt(const TriangleDescription &triangle, int triangleIndex)
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexForceAccumulator
void createVertices(int numVertices, int clothIdentifier, int maxVertices=0)
Create numVertices new vertices for cloth clothIdentifier maxVertices allows a buffer zone of extra v...
float & getLinkLengthRatio(int linkIndex)
Return the link length ratio from for link linkIndex as stored on the host.
int getClothIdentifier(int vertexIndex)
btAlignedObjectArray< Vectormath::Aos::Point3 > m_vertexPreviousPosition
virtual void createTriangles(int numTriangles)
Vectormath::Aos::Point3 getPosition() const
void setPosition(const Vectormath::Aos::Point3 &position)
virtual void setLinkAt(const LinkDescription &link, int linkIndex)
Insert the link described into the correct data structures assuming space has already been allocated ...
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_normal
virtual float & getStrengthCorrected(int linkIndex)
Return a reference to the strength of the link corrected for link sorting.
btAlignedObjectArray< TriangleNodeSet > m_vertexIndices
virtual bool onAccelerator()
Return true if data is on the accelerator.
btAlignedObjectArray< Vectormath::Aos::Point3 > m_vertexPosition
virtual bool moveFromAccelerator(bool bCopy=false, bool bCopyMinimum=true)
Move data to host memory from the accelerator if bCopy is false.
float & getRestLengthSquared(int linkIndex)
Return reference to rest length squared for link linkIndex as stored on the host. ...
VertexDescription(const Vectormath::Aos::Point3 &position, float mass)
int & getTriangleCount(int vertexIndex)
Get access to the array of how many triangles touch each vertex.
virtual bool moveToAccelerator()
Move data from host memory to the accelerator.
float & getLinearStiffnessCoefficient(int linkIndex)
Return reference to linear stiffness coefficient for link linkIndex as stored on the host...
LinkNodePair & getVertexPair(int linkIndex)
Return reference to the vertex index pair for link linkIndex as stored on the host.
virtual bool onAccelerator()
Return true if data is on the accelerator.
Class describing a vertex for input into the system.
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_linksCLength
float & getStrength(int linkIndex)
Return reference to strength of link linkIndex as stored on the host.
btAlignedObjectArray< float > m_vertexArea
btAlignedObjectArray< float > m_linkStrength
float & getMassLSC(int linkIndex)
Return reference to the MassLSC value for link linkIndex as stored on the host.
Vectormath::Aos::Vector3 & getNormal(int triangleIndex)
Get access to the normal vector for this triangle.
int size() const
return the number of elements in the array
TriangleNodeSet(int newVertex0, int newVertex1, int newVertex2)
btAlignedObjectArray< Vectormath::Aos::Point3 > & getVertexPositions()
btAlignedObjectArray< LinkNodePair > m_links
TriangleDescription(int newVertex0, int newVertex1, int newVertex2)
Class representing a link as a set of three indices into the vertex array.
LinkDescription(int newVertex0, int newVertex1, float linkLinearStiffness)
float & getArea(int vertexIndex)
Get access to the area controlled by this vertex.
float & getTriangleArea(int triangleIndex)
Get access to the triangle area.
float & getRestLength(int linkIndex)
Return reference to the rest length of link linkIndex as stored on the host.
btAlignedObjectArray< float > m_linksRestLengthSquared
btAlignedObjectArray< float > m_linksLengthRatio
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexNormal
btAlignedObjectArray< float > m_linksMaterialLinearStiffnessCoefficient
virtual bool onAccelerator()
Return true if data is on the accelerator.
Vectormath::Aos::Vector3 getNormal(int vertexIndex) const
Class describing a link for input into the system.
Wrapper for vertex data information.
virtual bool moveFromAccelerator()
Move data from host memory from the accelerator.
Vectormath::Aos::Vector3 & getNormal(int vertexIndex)
Return a reference to the normal of vertex vertexIndex as stored on the host.
void resize(int newsize, const T &fillData=T())
btAlignedObjectArray< float > m_linksMassLSC
float & getInverseMass(int vertexIndex)
Return a reference to the inverse mass of vertex vertexIndex as stored on the host.
Vectormath::Aos::Point3 & getPosition(int vertexIndex)
Return a reference to the position of vertex vertexIndex as stored on the host.
btAlignedObjectArray< float > m_area
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexVelocity
btAlignedObjectArray< int > m_clothIdentifier
Vectormath::Aos::Vector3 & getVelocity(int vertexIndex)
Return a reference to the velocity of vertex vertexIndex as stored on the host.
void setLinkLinearStiffness(float linearStiffness)
btAlignedObjectArray< int > m_vertexTriangleCount
btAlignedObjectArray< float > m_linksRestLength
Vectormath::Aos::Point3 & getPreviousPosition(int vertexIndex)
Return a reference to the previous position of vertex vertexIndex as stored on the host...
Vectormath::Aos::Vector3 & getForceAccumulator(int vertexIndex)
Return a reference to the force accumulator of vertex vertexIndex as stored on the host...
const TriangleNodeSet & getVertexSet(int triangleIndex)
Return the vertex index set for triangle triangleIndex as stored on the host.
Vectormath::Aos::Vector3 & getCurrentLength(int linkIndex)
Return reference to current length of link linkIndex as stored on the host.
virtual bool moveToAccelerator()
Move data from host memory to the accelerator.
virtual bool moveToAccelerator()
Move data from host memory to the accelerator.
void setVertexAt(const VertexDescription &vertex, int vertexIndex)
Vectormath::Aos::Point3 getPosition(int vertexIndex) const
btAlignedObjectArray< float > m_vertexInverseMass
Class representing a triangle as a set of three indices into the vertex array.
virtual bool moveFromAccelerator()
Move data from host memory from the accelerator.
virtual void createLinks(int numLinks)
Allocate enough space in all link-related arrays to fit numLinks links.