2
Bullet Continuous Collision Detection and Physics Library
3
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
5
This software is provided 'as-is', without any express or implied warranty.
6
In no event will the authors be held liable for any damages arising from the use of this software.
7
Permission is granted to anyone to use this software for any purpose,
8
including commercial applications, and to alter it and redistribute it freely,
9
subject to the following restrictions:
11
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13
3. This notice may not be removed or altered from any source distribution.
16
#ifndef BT_SOFT_BODY_SOLVER_DATA_H
17
#define BT_SOFT_BODY_SOLVER_DATA_H
19
#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
20
#include "vectormath/vmInclude.h"
23
class btSoftBodyLinkData
27
* Class representing a link as a set of three indices into the vertex array.
41
LinkNodePair( int v0, int v1 )
49
* Class describing a link for input into the system.
56
float m_linkLinearStiffness;
65
m_linkLinearStiffness = 1.0;
69
LinkDescription( int newVertex0, int newVertex1, float linkLinearStiffness )
71
m_vertex0 = newVertex0;
72
m_vertex1 = newVertex1;
73
m_linkLinearStiffness = linkLinearStiffness;
77
LinkNodePair getVertexPair() const
80
nodes.vertex0 = m_vertex0;
81
nodes.vertex1 = m_vertex1;
85
void setVertex0( int vertex )
90
void setVertex1( int vertex )
95
void setLinkLinearStiffness( float linearStiffness )
97
m_linkLinearStiffness = linearStiffness;
100
void setLinkStrength( float strength )
102
m_linkStrength = strength;
105
int getVertex0() const
110
int getVertex1() const
115
float getLinkStrength() const
117
return m_linkStrength;
120
float getLinkLinearStiffness() const
122
return m_linkLinearStiffness;
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
133
btAlignedObjectArray< LinkNodePair > m_links; // Vertex pair for the link
134
btAlignedObjectArray< float > m_linkStrength; // Strength of each link
135
// (inverseMassA + inverseMassB)/ linear stiffness coefficient
136
btAlignedObjectArray< float > m_linksMassLSC;
137
btAlignedObjectArray< float > m_linksRestLengthSquared;
138
// Current vector length of link
139
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_linksCLength;
140
// 1/(current length * current length * massLSC)
141
btAlignedObjectArray< float > m_linksLengthRatio;
142
btAlignedObjectArray< float > m_linksRestLength;
143
btAlignedObjectArray< float > m_linksMaterialLinearStiffnessCoefficient;
150
virtual ~btSoftBodyLinkData()
157
m_linkStrength.resize(0);
158
m_linksMassLSC.resize(0);
159
m_linksRestLengthSquared.resize(0);
160
m_linksLengthRatio.resize(0);
161
m_linksRestLength.resize(0);
162
m_linksMaterialLinearStiffnessCoefficient.resize(0);
167
return m_links.size();
170
/** Allocate enough space in all link-related arrays to fit numLinks links */
171
virtual void createLinks( int numLinks )
173
int previousSize = m_links.size();
174
int newSize = previousSize + numLinks;
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 );
184
m_linksMaterialLinearStiffnessCoefficient.resize( newSize );
187
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
188
virtual void setLinkAt( const LinkDescription &link, int linkIndex )
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;
197
m_linksMaterialLinearStiffnessCoefficient[linkIndex] = link.getLinkLinearStiffness();
202
* Return true if data is on the accelerator.
203
* The CPU version of this class will return true here because
204
* the CPU is the same as the accelerator.
206
virtual bool onAccelerator()
212
* Move data from host memory to the accelerator.
213
* The CPU version will always return that it has moved it.
215
virtual bool moveToAccelerator()
221
* Move data from host memory from the accelerator.
222
* The CPU version will always return that it has moved it.
224
virtual bool moveFromAccelerator()
232
* Return reference to the vertex index pair for link linkIndex as stored on the host.
234
LinkNodePair &getVertexPair( int linkIndex )
236
return m_links[linkIndex];
240
* Return reference to strength of link linkIndex as stored on the host.
242
float &getStrength( int linkIndex )
244
return m_linkStrength[linkIndex];
248
* Return a reference to the strength of the link corrected for link sorting.
249
* This is important if we are using data on an accelerator which has the data sorted in some fashion.
251
virtual float &getStrengthCorrected( int linkIndex )
253
return getStrength( linkIndex );
257
* Return reference to the rest length of link linkIndex as stored on the host.
259
float &getRestLength( int linkIndex )
261
return m_linksRestLength[linkIndex];
265
* Return reference to linear stiffness coefficient for link linkIndex as stored on the host.
267
float &getLinearStiffnessCoefficient( int linkIndex )
269
return m_linksMaterialLinearStiffnessCoefficient[linkIndex];
273
* Return reference to the MassLSC value for link linkIndex as stored on the host.
275
float &getMassLSC( int linkIndex )
277
return m_linksMassLSC[linkIndex];
281
* Return reference to rest length squared for link linkIndex as stored on the host.
283
float &getRestLengthSquared( int linkIndex )
285
return m_linksRestLengthSquared[linkIndex];
289
* Return reference to current length of link linkIndex as stored on the host.
291
Vectormath::Aos::Vector3 &getCurrentLength( int linkIndex )
293
return m_linksCLength[linkIndex];
297
* Return the link length ratio from for link linkIndex as stored on the host.
299
float &getLinkLengthRatio( int linkIndex )
301
return m_linksLengthRatio[linkIndex];
308
* Wrapper for vertex data information.
309
* By wrapping it like this we stand a good chance of being able to optimise for storage format easily.
310
* It should also help us make sure all the data structures remain consistent.
312
class btSoftBodyVertexData
316
* Class describing a vertex for input into the system.
318
class VertexDescription
321
Vectormath::Aos::Point3 m_position;
322
/** Inverse mass. If this is 0f then the mass was 0 because that simplifies calculations. */
328
m_position = Vectormath::Aos::Point3( 0.f, 0.f, 0.f );
332
VertexDescription( const Vectormath::Aos::Point3 &position, float mass )
334
m_position = position;
336
m_inverseMass = 1.0f/mass;
341
void setPosition( const Vectormath::Aos::Point3 &position )
343
m_position = position;
346
void setInverseMass( float inverseMass )
348
m_inverseMass = inverseMass;
351
void setMass( float mass )
354
m_inverseMass = 1.0f/mass;
359
Vectormath::Aos::Point3 getPosition() const
364
float getInverseMass() const
366
return m_inverseMass;
369
float getMass() const
371
if( m_inverseMass == 0.f )
374
return 1.0f/m_inverseMass;
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
383
// For sorting etc it might also be helpful to be able to use in-array data such as this.
384
btAlignedObjectArray< int > m_clothIdentifier;
385
btAlignedObjectArray< Vectormath::Aos::Point3 > m_vertexPosition; // vertex positions
386
btAlignedObjectArray< Vectormath::Aos::Point3 > m_vertexPreviousPosition; // vertex positions
387
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexVelocity; // Velocity
388
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexForceAccumulator; // Force accumulator
389
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexNormal; // Normals
390
btAlignedObjectArray< float > m_vertexInverseMass; // Inverse mass
391
btAlignedObjectArray< float > m_vertexArea; // Area controlled by the vertex
392
btAlignedObjectArray< int > m_vertexTriangleCount; // Number of triangles touching this vertex
395
btSoftBodyVertexData()
399
virtual ~btSoftBodyVertexData()
405
m_clothIdentifier.resize(0);
406
m_vertexPosition.resize(0);
407
m_vertexPreviousPosition.resize(0);
408
m_vertexVelocity.resize(0);
409
m_vertexForceAccumulator.resize(0);
410
m_vertexNormal.resize(0);
411
m_vertexInverseMass.resize(0);
412
m_vertexArea.resize(0);
413
m_vertexTriangleCount.resize(0);
418
return m_vertexPosition.size();
421
int getClothIdentifier( int vertexIndex )
423
return m_clothIdentifier[vertexIndex];
426
void setVertexAt( const VertexDescription &vertex, int vertexIndex )
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;
439
* Create numVertices new vertices for cloth clothIdentifier
440
* maxVertices allows a buffer zone of extra vertices for alignment or tearing reasons.
442
void createVertices( int numVertices, int clothIdentifier, int maxVertices = 0 )
444
int previousSize = m_vertexPosition.size();
445
if( maxVertices == 0 )
446
maxVertices = numVertices;
447
int newSize = previousSize + maxVertices;
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 );
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;
466
// Get and set methods in header so they can be inlined
469
* Return a reference to the position of vertex vertexIndex as stored on the host.
471
Vectormath::Aos::Point3 &getPosition( int vertexIndex )
473
return m_vertexPosition[vertexIndex];
476
Vectormath::Aos::Point3 getPosition( int vertexIndex ) const
478
return m_vertexPosition[vertexIndex];
482
* Return a reference to the previous position of vertex vertexIndex as stored on the host.
484
Vectormath::Aos::Point3 &getPreviousPosition( int vertexIndex )
486
return m_vertexPreviousPosition[vertexIndex];
490
* Return a reference to the velocity of vertex vertexIndex as stored on the host.
492
Vectormath::Aos::Vector3 &getVelocity( int vertexIndex )
494
return m_vertexVelocity[vertexIndex];
498
* Return a reference to the force accumulator of vertex vertexIndex as stored on the host.
500
Vectormath::Aos::Vector3 &getForceAccumulator( int vertexIndex )
502
return m_vertexForceAccumulator[vertexIndex];
506
* Return a reference to the normal of vertex vertexIndex as stored on the host.
508
Vectormath::Aos::Vector3 &getNormal( int vertexIndex )
510
return m_vertexNormal[vertexIndex];
513
Vectormath::Aos::Vector3 getNormal( int vertexIndex ) const
515
return m_vertexNormal[vertexIndex];
519
* Return a reference to the inverse mass of vertex vertexIndex as stored on the host.
521
float &getInverseMass( int vertexIndex )
523
return m_vertexInverseMass[vertexIndex];
527
* Get access to the area controlled by this vertex.
529
float &getArea( int vertexIndex )
531
return m_vertexArea[vertexIndex];
535
* Get access to the array of how many triangles touch each vertex.
537
int &getTriangleCount( int vertexIndex )
539
return m_vertexTriangleCount[vertexIndex];
545
* Return true if data is on the accelerator.
546
* The CPU version of this class will return true here because
547
* the CPU is the same as the accelerator.
549
virtual bool onAccelerator()
555
* Move data from host memory to the accelerator.
556
* The CPU version will always return that it has moved it.
558
virtual bool moveToAccelerator()
564
* Move data from host memory from the accelerator.
565
* The CPU version will always return that it has moved it.
567
virtual bool moveFromAccelerator()
572
btAlignedObjectArray< Vectormath::Aos::Point3 > &getVertexPositions()
574
return m_vertexPosition;
579
class btSoftBodyTriangleData
583
* Class representing a triangle as a set of three indices into the
586
class TriangleNodeSet
602
TriangleNodeSet( int newVertex0, int newVertex1, int newVertex2 )
604
vertex0 = newVertex0;
605
vertex1 = newVertex1;
606
vertex2 = newVertex2;
610
class TriangleDescription
618
TriangleDescription()
625
TriangleDescription( int newVertex0, int newVertex1, int newVertex2 )
627
m_vertex0 = newVertex0;
628
m_vertex1 = newVertex1;
629
m_vertex2 = newVertex2;
632
TriangleNodeSet getVertexSet() const
634
btSoftBodyTriangleData::TriangleNodeSet nodes;
635
nodes.vertex0 = m_vertex0;
636
nodes.vertex1 = m_vertex1;
637
nodes.vertex2 = m_vertex2;
644
// Vertex reference data is stored relative to global array, not relative to individual cloth.
645
// Values must be correct if being passed into single-cloth VBOs or when migrating from one solver
647
btAlignedObjectArray< TriangleNodeSet > m_vertexIndices;
648
btAlignedObjectArray< float > m_area;
649
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_normal;
652
btSoftBodyTriangleData()
656
virtual ~btSoftBodyTriangleData()
663
m_vertexIndices.resize(0);
668
int getNumTriangles()
670
return m_vertexIndices.size();
673
virtual void setTriangleAt( const TriangleDescription &triangle, int triangleIndex )
675
m_vertexIndices[triangleIndex] = triangle.getVertexSet();
678
virtual void createTriangles( int numTriangles )
680
int previousSize = m_vertexIndices.size();
681
int newSize = previousSize + numTriangles;
683
// Resize all the arrays that store triangle data
684
m_vertexIndices.resize( newSize );
685
m_area.resize( newSize );
686
m_normal.resize( newSize );
690
* Return the vertex index set for triangle triangleIndex as stored on the host.
692
const TriangleNodeSet &getVertexSet( int triangleIndex )
694
return m_vertexIndices[triangleIndex];
698
* Get access to the triangle area.
700
float &getTriangleArea( int triangleIndex )
702
return m_area[triangleIndex];
706
* Get access to the normal vector for this triangle.
708
Vectormath::Aos::Vector3 &getNormal( int triangleIndex )
710
return m_normal[triangleIndex];
714
* Return true if data is on the accelerator.
715
* The CPU version of this class will return true here because
716
* the CPU is the same as the accelerator.
718
virtual bool onAccelerator()
724
* Move data from host memory to the accelerator.
725
* The CPU version will always return that it has moved it.
727
virtual bool moveToAccelerator()
733
* Move data from host memory from the accelerator.
734
* The CPU version will always return that it has moved it.
736
virtual bool moveFromAccelerator()
743
#endif // #ifndef BT_SOFT_BODY_SOLVER_DATA_H