btSoftBodySolverData.h

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 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.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 #ifndef BT_SOFT_BODY_SOLVER_DATA_H
00017 #define BT_SOFT_BODY_SOLVER_DATA_H
00018 
00019 #include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
00020 #include "vectormath/vmInclude.h"
00021 
00022 
00023 class btSoftBodyLinkData
00024 {
00025 public:
00029         class LinkNodePair
00030         {
00031         public:
00032                 int vertex0;
00033                 int vertex1;
00034 
00035                 LinkNodePair()
00036                 {
00037                         vertex0 = 0;
00038                         vertex1 = 0;
00039                 }
00040 
00041                 LinkNodePair( int v0, int v1 )
00042                 {
00043                         vertex0 = v0;
00044                         vertex1 = v1;
00045                 }
00046         };
00047 
00051         class LinkDescription
00052         {
00053         protected:
00054                 int m_vertex0;
00055                 int m_vertex1;
00056                 float m_linkLinearStiffness;
00057                 float m_linkStrength;
00058 
00059         public:
00060 
00061                 LinkDescription()
00062                 {
00063                         m_vertex0 = 0;
00064                         m_vertex1 = 0;
00065                         m_linkLinearStiffness = 1.0;
00066                         m_linkStrength = 1.0;
00067                 }
00068 
00069                 LinkDescription( int newVertex0, int newVertex1, float linkLinearStiffness )
00070                 {
00071                         m_vertex0 = newVertex0;
00072                         m_vertex1 = newVertex1;
00073                         m_linkLinearStiffness = linkLinearStiffness;
00074                         m_linkStrength = 1.0;
00075                 }
00076 
00077                 LinkNodePair getVertexPair() const
00078                 {
00079                         LinkNodePair nodes;
00080                         nodes.vertex0 = m_vertex0;
00081                         nodes.vertex1 = m_vertex1;
00082                         return nodes;
00083                 }
00084 
00085                 void setVertex0( int vertex )
00086                 {
00087                         m_vertex0 = vertex;
00088                 }
00089 
00090                 void setVertex1( int vertex )
00091                 {
00092                         m_vertex1 = vertex;
00093                 }
00094 
00095                 void setLinkLinearStiffness( float linearStiffness )
00096                 {
00097                         m_linkLinearStiffness = linearStiffness;
00098                 }
00099 
00100                 void setLinkStrength( float strength )
00101                 {
00102                         m_linkStrength = strength;
00103                 }
00104 
00105                 int getVertex0() const
00106                 {
00107                         return m_vertex0;
00108                 }
00109 
00110                 int getVertex1() const
00111                 {
00112                         return m_vertex1;
00113                 }
00114 
00115                 float getLinkStrength() const
00116                 {
00117                         return m_linkStrength;
00118                 }
00119 
00120                 float getLinkLinearStiffness() const
00121                 {
00122                         return m_linkLinearStiffness;
00123                 }
00124         };
00125 
00126 
00127 protected:
00128         // NOTE:
00129         // Vertex reference data is stored relative to global array, not relative to individual cloth.
00130         // Values must be correct if being passed into single-cloth VBOs or when migrating from one solver
00131         // to another.
00132 
00133         btAlignedObjectArray< LinkNodePair > m_links; // Vertex pair for the link
00134         btAlignedObjectArray< float >                                                           m_linkStrength; // Strength of each link
00135         // (inverseMassA + inverseMassB)/ linear stiffness coefficient
00136         btAlignedObjectArray< float >                                                           m_linksMassLSC; 
00137         btAlignedObjectArray< float >                                                           m_linksRestLengthSquared; 
00138         // Current vector length of link
00139         btAlignedObjectArray< Vectormath::Aos::Vector3 >                        m_linksCLength;
00140         // 1/(current length * current length * massLSC)
00141         btAlignedObjectArray< float >                                                           m_linksLengthRatio; 
00142         btAlignedObjectArray< float >                                                           m_linksRestLength;
00143         btAlignedObjectArray< float >                                                           m_linksMaterialLinearStiffnessCoefficient;
00144 
00145 public:
00146         btSoftBodyLinkData()
00147         {
00148         }
00149 
00150         virtual ~btSoftBodyLinkData()
00151         {
00152         }
00153 
00154         virtual void clear()
00155         {
00156                 m_links.resize(0);
00157                 m_linkStrength.resize(0);
00158                 m_linksMassLSC.resize(0);
00159                 m_linksRestLengthSquared.resize(0);
00160                 m_linksLengthRatio.resize(0);
00161                 m_linksRestLength.resize(0);
00162                 m_linksMaterialLinearStiffnessCoefficient.resize(0);
00163         }
00164 
00165         int getNumLinks()
00166         {
00167                 return m_links.size();
00168         }
00169 
00171         virtual void createLinks( int numLinks )
00172         {
00173                 int previousSize = m_links.size();
00174                 int newSize = previousSize + numLinks;
00175 
00176                 // Resize all the arrays that store link data
00177                 m_links.resize( newSize );
00178                 m_linkStrength.resize( newSize );
00179                 m_linksMassLSC.resize( newSize );
00180                 m_linksRestLengthSquared.resize( newSize );
00181                 m_linksCLength.resize( newSize );
00182                 m_linksLengthRatio.resize( newSize );
00183                 m_linksRestLength.resize( newSize );
00184                 m_linksMaterialLinearStiffnessCoefficient.resize( newSize );
00185         }
00186         
00188         virtual void setLinkAt( const LinkDescription &link, int linkIndex )
00189         {
00190                 m_links[linkIndex] = link.getVertexPair();
00191                 m_linkStrength[linkIndex] = link.getLinkStrength();
00192                 m_linksMassLSC[linkIndex] = 0.f;
00193                 m_linksRestLengthSquared[linkIndex] = 0.f;
00194                 m_linksCLength[linkIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
00195                 m_linksLengthRatio[linkIndex] = 0.f;
00196                 m_linksRestLength[linkIndex] = 0.f;
00197                 m_linksMaterialLinearStiffnessCoefficient[linkIndex] = link.getLinkLinearStiffness();
00198         }
00199 
00200 
00206         virtual bool onAccelerator()
00207         {
00208                 return true;
00209         }
00210         
00215         virtual bool moveToAccelerator()
00216         {
00217                 return true;
00218         }
00219 
00224         virtual bool moveFromAccelerator()
00225         {
00226                 return true;
00227         }
00228 
00229 
00230 
00234         LinkNodePair &getVertexPair( int linkIndex )
00235         {
00236                 return m_links[linkIndex];
00237         }
00238 
00242         float &getStrength( int linkIndex )
00243         {
00244                 return m_linkStrength[linkIndex];
00245         }
00246 
00251         virtual float &getStrengthCorrected( int linkIndex )
00252         {
00253                 return getStrength( linkIndex );
00254         }
00255 
00259         float &getRestLength( int linkIndex )
00260         {
00261                 return m_linksRestLength[linkIndex];
00262         }
00263 
00267         float &getLinearStiffnessCoefficient( int linkIndex )
00268         {
00269                 return m_linksMaterialLinearStiffnessCoefficient[linkIndex];
00270         }
00271 
00275         float &getMassLSC( int linkIndex )
00276         {
00277                 return m_linksMassLSC[linkIndex];
00278         }
00279 
00283         float &getRestLengthSquared( int linkIndex )
00284         {
00285                 return m_linksRestLengthSquared[linkIndex];
00286         }
00287 
00291         Vectormath::Aos::Vector3 &getCurrentLength( int linkIndex )
00292         {
00293                 return m_linksCLength[linkIndex];
00294         }
00295 
00299          float &getLinkLengthRatio( int linkIndex )
00300          {
00301                  return m_linksLengthRatio[linkIndex];
00302          }
00303 };
00304 
00305 
00306 
00312 class btSoftBodyVertexData
00313 {
00314 public:
00318         class VertexDescription
00319         {
00320         private:
00321                 Vectormath::Aos::Point3 m_position;
00323                 float m_inverseMass;
00324 
00325         public:
00326                 VertexDescription()
00327                 {       
00328                         m_position = Vectormath::Aos::Point3( 0.f, 0.f, 0.f );
00329                         m_inverseMass = 0.f;
00330                 }
00331 
00332                 VertexDescription( const Vectormath::Aos::Point3 &position, float mass )
00333                 {
00334                         m_position = position;
00335                         if( mass > 0.f )
00336                                 m_inverseMass = 1.0f/mass;
00337                         else
00338                                 m_inverseMass = 0.f;
00339                 }
00340 
00341                 void setPosition( const Vectormath::Aos::Point3 &position )
00342                 {
00343                         m_position = position;
00344                 }
00345 
00346                 void setInverseMass( float inverseMass )
00347                 {
00348                         m_inverseMass = inverseMass;
00349                 }
00350 
00351                 void setMass( float mass )
00352                 {
00353                         if( mass > 0.f )
00354                                 m_inverseMass = 1.0f/mass;
00355                         else
00356                                 m_inverseMass = 0.f;
00357                 }
00358 
00359                 Vectormath::Aos::Point3 getPosition() const
00360                 {
00361                         return m_position;
00362                 }
00363 
00364                 float getInverseMass() const
00365                 {
00366                         return m_inverseMass;
00367                 }
00368 
00369                 float getMass() const
00370                 {
00371                         if( m_inverseMass == 0.f )
00372                                 return 0.f;
00373                         else
00374                                 return 1.0f/m_inverseMass;
00375                 }
00376         };
00377 protected:
00378 
00379         // identifier for the individual cloth
00380         // For the CPU we don't really need this as we can grab the cloths and iterate over only their vertices
00381         // For a parallel accelerator knowing on a per-vertex basis which cloth we're part of will help for obtaining
00382         // per-cloth data
00383         // For sorting etc it might also be helpful to be able to use in-array data such as this.
00384         btAlignedObjectArray< int >                                                     m_clothIdentifier;
00385         btAlignedObjectArray< Vectormath::Aos::Point3 >         m_vertexPosition;                       // vertex positions
00386         btAlignedObjectArray< Vectormath::Aos::Point3 >         m_vertexPreviousPosition;       // vertex positions
00387         btAlignedObjectArray< Vectormath::Aos::Vector3 >        m_vertexVelocity;                       // Velocity
00388         btAlignedObjectArray< Vectormath::Aos::Vector3 >        m_vertexForceAccumulator;       // Force accumulator
00389         btAlignedObjectArray< Vectormath::Aos::Vector3 >        m_vertexNormal;                         // Normals
00390         btAlignedObjectArray< float >                                           m_vertexInverseMass;            // Inverse mass
00391         btAlignedObjectArray< float >                                           m_vertexArea;                           // Area controlled by the vertex
00392         btAlignedObjectArray< int >                                                     m_vertexTriangleCount;          // Number of triangles touching this vertex
00393 
00394 public:
00395         btSoftBodyVertexData()
00396         {
00397         }
00398 
00399         virtual ~btSoftBodyVertexData()
00400         {
00401         }
00402 
00403         virtual void clear()
00404         {
00405                 m_clothIdentifier.resize(0);
00406                 m_vertexPosition.resize(0);
00407                 m_vertexPreviousPosition.resize(0);
00408                 m_vertexVelocity.resize(0);
00409                 m_vertexForceAccumulator.resize(0);
00410                 m_vertexNormal.resize(0);
00411                 m_vertexInverseMass.resize(0);
00412                 m_vertexArea.resize(0);
00413                 m_vertexTriangleCount.resize(0);
00414         }
00415 
00416         int getNumVertices()
00417         {
00418                 return m_vertexPosition.size();
00419         }
00420 
00421         int getClothIdentifier( int vertexIndex )
00422         {
00423                 return m_clothIdentifier[vertexIndex];
00424         }
00425 
00426         void setVertexAt( const VertexDescription &vertex, int vertexIndex )
00427         {
00428                 m_vertexPosition[vertexIndex] = vertex.getPosition();
00429                 m_vertexPreviousPosition[vertexIndex] = vertex.getPosition();
00430                 m_vertexVelocity[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
00431                 m_vertexForceAccumulator[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
00432                 m_vertexNormal[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
00433                 m_vertexInverseMass[vertexIndex] = vertex.getInverseMass();
00434                 m_vertexArea[vertexIndex] = 0.f;
00435                 m_vertexTriangleCount[vertexIndex] = 0;
00436         }
00437 
00442         void createVertices( int numVertices, int clothIdentifier, int maxVertices = 0 )
00443         {
00444                 int previousSize = m_vertexPosition.size();
00445                 if( maxVertices == 0 )
00446                         maxVertices = numVertices;
00447                 int newSize = previousSize + maxVertices;
00448 
00449                 // Resize all the arrays that store vertex data
00450                 m_clothIdentifier.resize( newSize );
00451                 m_vertexPosition.resize( newSize );
00452                 m_vertexPreviousPosition.resize( newSize );
00453                 m_vertexVelocity.resize( newSize );
00454                 m_vertexForceAccumulator.resize( newSize );
00455                 m_vertexNormal.resize( newSize );
00456                 m_vertexInverseMass.resize( newSize );
00457                 m_vertexArea.resize( newSize );
00458                 m_vertexTriangleCount.resize( newSize );
00459 
00460                 for( int vertexIndex = previousSize; vertexIndex < newSize; ++vertexIndex )
00461                         m_clothIdentifier[vertexIndex] = clothIdentifier;
00462                 for( int vertexIndex = (previousSize + numVertices); vertexIndex < newSize; ++vertexIndex )
00463                         m_clothIdentifier[vertexIndex] = -1;
00464         }
00465 
00466         // Get and set methods in header so they can be inlined
00467 
00471         Vectormath::Aos::Point3 &getPosition( int vertexIndex )
00472         {
00473                 return m_vertexPosition[vertexIndex];
00474         }
00475 
00476         Vectormath::Aos::Point3 getPosition( int vertexIndex ) const
00477         {
00478                 return m_vertexPosition[vertexIndex];
00479         }
00480 
00484         Vectormath::Aos::Point3 &getPreviousPosition( int vertexIndex )
00485         {
00486                 return m_vertexPreviousPosition[vertexIndex];
00487         }
00488 
00492         Vectormath::Aos::Vector3 &getVelocity( int vertexIndex )
00493         {
00494                 return m_vertexVelocity[vertexIndex];
00495         }
00496 
00500         Vectormath::Aos::Vector3 &getForceAccumulator( int vertexIndex )
00501         {
00502                 return m_vertexForceAccumulator[vertexIndex];
00503         }
00504 
00508         Vectormath::Aos::Vector3 &getNormal( int vertexIndex )
00509         {
00510                 return m_vertexNormal[vertexIndex];
00511         }
00512 
00513         Vectormath::Aos::Vector3 getNormal( int vertexIndex ) const
00514         {
00515                 return m_vertexNormal[vertexIndex];
00516         }
00517 
00521         float &getInverseMass( int vertexIndex )
00522         {
00523                 return m_vertexInverseMass[vertexIndex];
00524         }
00525 
00529         float &getArea( int vertexIndex )
00530         {
00531                 return m_vertexArea[vertexIndex];
00532         }
00533 
00537         int &getTriangleCount( int vertexIndex )
00538         {
00539                 return m_vertexTriangleCount[vertexIndex];
00540         }
00541 
00542 
00543 
00549         virtual bool onAccelerator()
00550         {
00551                 return true;
00552         }
00553         
00558         virtual bool moveToAccelerator()
00559         {
00560                 return true;
00561         }
00562 
00571         virtual bool moveFromAccelerator(bool bCopy = false, bool bCopyMinimum = true)
00572         {
00573                 return true;
00574         }
00575 
00576         btAlignedObjectArray< Vectormath::Aos::Point3 > &getVertexPositions()
00577         {
00578                 return m_vertexPosition;
00579         }
00580 };
00581 
00582 
00583 class btSoftBodyTriangleData
00584 {
00585 public:
00590         class TriangleNodeSet
00591         {
00592         public:
00593                 int vertex0;
00594                 int vertex1;
00595                 int vertex2;
00596                 int _padding;
00597 
00598                 TriangleNodeSet( )
00599                 {
00600                         vertex0 = 0;
00601                         vertex1 = 0;
00602                         vertex2 = 0;
00603                         _padding = -1;
00604                 }
00605 
00606                 TriangleNodeSet( int newVertex0, int newVertex1, int newVertex2 )
00607                 {
00608                         vertex0 = newVertex0;
00609                         vertex1 = newVertex1;
00610                         vertex2 = newVertex2;
00611                 }
00612         };
00613 
00614         class TriangleDescription
00615         {
00616         protected:
00617                 int m_vertex0;
00618                 int m_vertex1;
00619                 int m_vertex2;
00620 
00621         public:
00622                 TriangleDescription()
00623                 {
00624                         m_vertex0 = 0;
00625                         m_vertex1 = 0;
00626                         m_vertex2 = 0;
00627                 }
00628 
00629                 TriangleDescription( int newVertex0, int newVertex1, int newVertex2 )
00630                 {
00631                         m_vertex0 = newVertex0;
00632                         m_vertex1 = newVertex1;
00633                         m_vertex2 = newVertex2;
00634                 }
00635 
00636                 TriangleNodeSet getVertexSet() const
00637                 {
00638                         btSoftBodyTriangleData::TriangleNodeSet nodes;
00639                         nodes.vertex0 = m_vertex0;
00640                         nodes.vertex1 = m_vertex1;
00641                         nodes.vertex2 = m_vertex2;
00642                         return nodes;
00643                 }
00644         };
00645 
00646 protected:
00647         // NOTE:
00648         // Vertex reference data is stored relative to global array, not relative to individual cloth.
00649         // Values must be correct if being passed into single-cloth VBOs or when migrating from one solver
00650         // to another.
00651         btAlignedObjectArray< TriangleNodeSet > m_vertexIndices;
00652         btAlignedObjectArray< float > m_area;
00653         btAlignedObjectArray< Vectormath::Aos::Vector3 > m_normal;
00654 
00655 public:
00656         btSoftBodyTriangleData()
00657         {
00658         }
00659 
00660         virtual ~btSoftBodyTriangleData()
00661         {
00662 
00663         }
00664 
00665         virtual void clear()
00666         {
00667                 m_vertexIndices.resize(0);
00668                 m_area.resize(0);
00669                 m_normal.resize(0);
00670         }
00671 
00672         int getNumTriangles()
00673         {
00674                 return m_vertexIndices.size();
00675         }
00676 
00677         virtual void setTriangleAt( const TriangleDescription &triangle, int triangleIndex )
00678         {
00679                 m_vertexIndices[triangleIndex] = triangle.getVertexSet();
00680         }
00681 
00682         virtual void createTriangles( int numTriangles )                
00683         {
00684                 int previousSize = m_vertexIndices.size();
00685                 int newSize = previousSize + numTriangles;
00686 
00687                 // Resize all the arrays that store triangle data
00688                 m_vertexIndices.resize( newSize );
00689                 m_area.resize( newSize );
00690                 m_normal.resize( newSize );
00691         }
00692 
00696         const TriangleNodeSet &getVertexSet( int triangleIndex )
00697         {
00698                 return m_vertexIndices[triangleIndex];
00699         }
00700 
00704         float &getTriangleArea( int triangleIndex )
00705         {
00706                 return m_area[triangleIndex];
00707         }
00708 
00712         Vectormath::Aos::Vector3 &getNormal( int triangleIndex )
00713         {
00714                 return m_normal[triangleIndex];
00715         }
00716 
00722         virtual bool onAccelerator()
00723         {
00724                 return true;
00725         }
00726         
00731         virtual bool moveToAccelerator()
00732         {
00733                 return true;
00734         }
00735 
00740         virtual bool moveFromAccelerator()
00741         {
00742                 return true;
00743         }
00744 };
00745 
00746 
00747 #endif // #ifndef BT_SOFT_BODY_SOLVER_DATA_H
00748