btSoftBodySolver_OpenCL.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_OPENCL_H
00017 #define BT_SOFT_BODY_SOLVER_OPENCL_H
00018 
00019 #include "stddef.h" //for size_t
00020 #include "vectormath/vmInclude.h"
00021 
00022 #include "BulletSoftBody/btSoftBodySolvers.h"
00023 #include "BulletSoftBody/btSoftBody.h"
00024 #include "btSoftBodySolverBuffer_OpenCL.h"
00025 #include "btSoftBodySolverLinkData_OpenCL.h"
00026 #include "btSoftBodySolverVertexData_OpenCL.h"
00027 #include "btSoftBodySolverTriangleData_OpenCL.h"
00028 
00029 class CLFunctions
00030 {
00031 protected:
00032         cl_command_queue        m_cqCommandQue;
00033         cl_context                      m_cxMainContext;
00034 
00035         int     m_kernelCompilationFailures;
00036 
00037 
00038 public:
00039         CLFunctions(cl_command_queue cqCommandQue, cl_context cxMainContext) :
00040                 m_cqCommandQue( cqCommandQue ),
00041                 m_cxMainContext( cxMainContext ),
00042                 m_kernelCompilationFailures(0)
00043         {
00044         }
00045 
00046         int getKernelCompilationFailures() const
00047         {
00048                 return m_kernelCompilationFailures;
00049         }
00050 
00054         virtual cl_kernel compileCLKernelFromString( const char* kernelSource, const char* kernelName, const char* additionalMacros, const char* srcFileNameForCaching);
00055 
00056         void    clearKernelCompilationFailures()
00057         {
00058                 m_kernelCompilationFailures=0;
00059         }
00060 };
00061 
00066 struct CollisionShapeDescription
00067 {
00068         Vectormath::Aos::Transform3 shapeTransform;
00069         Vectormath::Aos::Vector3 linearVelocity;
00070         Vectormath::Aos::Vector3 angularVelocity;
00071 
00072         int softBodyIdentifier;
00073         int collisionShapeType;
00074 
00075         // Both needed for capsule
00076         float radius;
00077         float halfHeight;
00078         int upAxis;
00079         
00080         float margin;
00081         float friction;
00082 
00083         CollisionShapeDescription()
00084         {
00085                 collisionShapeType = 0;
00086                 margin = 0;
00087                 friction = 0;
00088         }
00089 };
00090 
00096 class btOpenCLAcceleratedSoftBodyInterface
00097 {
00098 protected:
00100         int m_numVertices;
00102         int m_maxVertices;
00104         int m_numTriangles;
00106         int m_maxTriangles;
00108         int m_firstVertex;
00110         int m_firstTriangle;
00112         int m_firstLink;
00114         int m_maxLinks;
00116         int m_numLinks;
00117 
00119         btSoftBody *m_softBody;
00120 
00121 
00122 public:
00123         btOpenCLAcceleratedSoftBodyInterface( btSoftBody *softBody ) :
00124           m_softBody( softBody )
00125         {
00126                 m_numVertices = 0;
00127                 m_maxVertices = 0;
00128                 m_numTriangles = 0;
00129                 m_maxTriangles = 0;
00130                 m_firstVertex = 0;
00131                 m_firstTriangle = 0;
00132                 m_firstLink = 0;
00133                 m_maxLinks = 0;
00134                 m_numLinks = 0;
00135         }
00136         int getNumVertices()
00137         {
00138                 return m_numVertices;
00139         }
00140 
00141         int getNumTriangles()
00142         {
00143                 return m_numTriangles;
00144         }
00145 
00146         int getMaxVertices()
00147         {
00148                 return m_maxVertices;
00149         }
00150 
00151         int getMaxTriangles()
00152         {
00153                 return m_maxTriangles;
00154         }
00155 
00156         int getFirstVertex()
00157         {
00158                 return m_firstVertex;
00159         }
00160 
00161         int getFirstTriangle()
00162         {
00163                 return m_firstTriangle;
00164         }
00165         
00169         void updateBounds( const btVector3 &lowerBound, const btVector3 &upperBound );
00170 
00171         // TODO: All of these set functions will have to do checks and
00172         // update the world because restructuring of the arrays will be necessary
00173         // Reasonable use of "friend"?
00174         void setNumVertices( int numVertices )
00175         {
00176                 m_numVertices = numVertices;
00177         }       
00178 
00179         void setNumTriangles( int numTriangles )
00180         {
00181                 m_numTriangles = numTriangles;
00182         }
00183 
00184         void setMaxVertices( int maxVertices )
00185         {
00186                 m_maxVertices = maxVertices;
00187         }
00188 
00189         void setMaxTriangles( int maxTriangles )
00190         {
00191                 m_maxTriangles = maxTriangles;
00192         }
00193 
00194         void setFirstVertex( int firstVertex )
00195         {
00196                 m_firstVertex = firstVertex;
00197         }
00198 
00199         void setFirstTriangle( int firstTriangle )
00200         {
00201                 m_firstTriangle = firstTriangle;
00202         }
00203 
00204         void setMaxLinks( int maxLinks )
00205         {
00206                 m_maxLinks = maxLinks;
00207         }
00208 
00209         void setNumLinks( int numLinks )
00210         {
00211                 m_numLinks = numLinks;
00212         }
00213 
00214         void setFirstLink( int firstLink )
00215         {
00216                 m_firstLink = firstLink;
00217         }
00218 
00219         int getMaxLinks()
00220         {
00221                 return m_maxLinks;
00222         }
00223 
00224         int getNumLinks()
00225         {
00226                 return m_numLinks;
00227         }
00228 
00229         int getFirstLink()
00230         {
00231                 return m_firstLink;
00232         }
00233 
00234         btSoftBody* getSoftBody()
00235         {
00236                 return m_softBody;
00237         }
00238 
00239 };
00240 
00241 
00242 
00243 class btOpenCLSoftBodySolver : public btSoftBodySolver
00244 {
00245 public:
00246         
00247 
00248         struct UIntVector3
00249         {
00250                 UIntVector3()
00251                 {
00252                         x = 0;
00253                         y = 0;
00254                         z = 0;
00255                         _padding = 0;
00256                 }
00257                 
00258                 UIntVector3( unsigned int x_, unsigned int y_, unsigned int z_ )
00259                 {
00260                         x = x_;
00261                         y = y_;
00262                         z = z_;
00263                         _padding = 0;
00264                 }
00265                         
00266                 unsigned int x;
00267                 unsigned int y;
00268                 unsigned int z;
00269                 unsigned int _padding;
00270         };
00271 
00272         struct CollisionObjectIndices
00273         {
00274                 CollisionObjectIndices( int f, int e )
00275                 {
00276                         firstObject = f;
00277                         endObject = e;
00278                 }
00279 
00280                 int firstObject;
00281                 int endObject;
00282         };
00283 
00284         btSoftBodyLinkDataOpenCL m_linkData;
00285         btSoftBodyVertexDataOpenCL m_vertexData;
00286         btSoftBodyTriangleDataOpenCL m_triangleData;
00287 
00288 protected:
00289 
00290         CLFunctions m_defaultCLFunctions;
00291         CLFunctions* m_currentCLFunctions;
00292 
00294         bool m_updateSolverConstants;
00295 
00296         bool m_shadersInitialized;
00297 
00302         btAlignedObjectArray< btOpenCLAcceleratedSoftBodyInterface * > m_softBodySet;
00303 
00307         btAlignedObjectArray< Vectormath::Aos::Vector3 >        m_perClothAcceleration;
00308         btOpenCLBuffer<Vectormath::Aos::Vector3>                        m_clPerClothAcceleration;
00309 
00313         btAlignedObjectArray< Vectormath::Aos::Vector3 >        m_perClothWindVelocity;
00314         btOpenCLBuffer<Vectormath::Aos::Vector3>                        m_clPerClothWindVelocity;
00315 
00317         btAlignedObjectArray< float >                                           m_perClothDampingFactor;
00318         btOpenCLBuffer<float>                                                           m_clPerClothDampingFactor;
00319 
00321         btAlignedObjectArray< float >                                           m_perClothVelocityCorrectionCoefficient;
00322         btOpenCLBuffer<float>                                                           m_clPerClothVelocityCorrectionCoefficient;
00323 
00325         btAlignedObjectArray< float >                                           m_perClothLiftFactor;
00326         btOpenCLBuffer<float>                                                           m_clPerClothLiftFactor;
00327         
00329         btAlignedObjectArray< float >                                           m_perClothDragFactor;
00330         btOpenCLBuffer<float>                                                           m_clPerClothDragFactor;
00331 
00333         btAlignedObjectArray< float >                                           m_perClothMediumDensity;
00334         btOpenCLBuffer<float>                                                           m_clPerClothMediumDensity;
00335 
00339         btAlignedObjectArray< CollisionObjectIndices >          m_perClothCollisionObjects;
00340         btOpenCLBuffer<CollisionObjectIndices>                          m_clPerClothCollisionObjects;
00341 
00345         btAlignedObjectArray< CollisionShapeDescription >       m_collisionObjectDetails;
00346         btOpenCLBuffer< CollisionShapeDescription >                     m_clCollisionObjectDetails;
00347 
00348 
00349         
00353         btAlignedObjectArray< float >   m_perClothFriction;
00354         btOpenCLBuffer< float >                 m_clPerClothFriction;
00355 
00356         // anchor node info
00357         struct AnchorNodeInfoCL
00358         {
00359                 int clVertexIndex;
00360                 btSoftBody::Node* pNode;
00361         };
00362 
00363         btAlignedObjectArray<AnchorNodeInfoCL> m_anchorNodeInfoArray;
00364         btAlignedObjectArray<Vectormath::Aos::Point3> m_anchorPosition;
00365         btOpenCLBuffer<Vectormath::Aos::Point3>           m_clAnchorPosition;
00366         btAlignedObjectArray<int> m_anchorIndex;
00367         btOpenCLBuffer<int>               m_clAnchorIndex;
00368 
00369         bool m_bUpdateAnchoredNodePos;
00370 
00371         cl_kernel               m_prepareLinksKernel;
00372         cl_kernel               m_solvePositionsFromLinksKernel;
00373         cl_kernel               m_updateConstantsKernel;
00374         cl_kernel               m_integrateKernel;
00375         cl_kernel               m_addVelocityKernel;
00376         cl_kernel               m_updatePositionsFromVelocitiesKernel;
00377         cl_kernel               m_updateVelocitiesFromPositionsWithoutVelocitiesKernel;
00378         cl_kernel               m_updateVelocitiesFromPositionsWithVelocitiesKernel;
00379         cl_kernel               m_vSolveLinksKernel;
00380         cl_kernel               m_solveCollisionsAndUpdateVelocitiesKernel;
00381         cl_kernel               m_resetNormalsAndAreasKernel;
00382         cl_kernel               m_normalizeNormalsAndAreasKernel;
00383         cl_kernel               m_updateSoftBodiesKernel;
00384 
00385         cl_kernel               m_outputToVertexArrayKernel;
00386         cl_kernel               m_applyForcesKernel;
00387         cl_kernel       m_updateFixedVertexPositionsKernel;     
00388 
00389         cl_command_queue        m_cqCommandQue;
00390         cl_context                      m_cxMainContext;
00391         
00392         size_t                          m_defaultWorkGroupSize;
00393 
00394 
00395         virtual bool buildShaders();
00396 
00397         void resetNormalsAndAreas( int numVertices );
00398 
00399         void normalizeNormalsAndAreas( int numVertices );
00400 
00401         void executeUpdateSoftBodies( int firstTriangle, int numTriangles );
00402 
00403         void prepareCollisionConstraints();
00404         
00405         Vectormath::Aos::Vector3 ProjectOnAxis( const Vectormath::Aos::Vector3 &v, const Vectormath::Aos::Vector3 &a );
00406 
00407         void ApplyClampedForce( float solverdt, const Vectormath::Aos::Vector3 &force, const Vectormath::Aos::Vector3 &vertexVelocity, float inverseMass, Vectormath::Aos::Vector3 &vertexForce );
00408         
00409 
00410         int findSoftBodyIndex( const btSoftBody* const softBody );
00411 
00412         virtual void applyForces( float solverdt );
00413 
00414         void updateFixedVertexPositions();
00415 
00419         virtual void integrate( float solverdt );
00420 
00421         virtual void updateConstants( float timeStep );
00422 
00423         float computeTriangleArea( 
00424                 const Vectormath::Aos::Point3 &vertex0,
00425                 const Vectormath::Aos::Point3 &vertex1,
00426                 const Vectormath::Aos::Point3 &vertex2 );
00427 
00428 
00430         // Kernel dispatches
00431         void prepareLinks();
00432 
00433         void solveLinksForVelocity( int startLink, int numLinks, float kst );
00434 
00435         void updatePositionsFromVelocities( float solverdt );
00436 
00437         virtual void solveLinksForPosition( int startLink, int numLinks, float kst, float ti );
00438         
00439         void updateVelocitiesFromPositionsWithVelocities( float isolverdt );
00440 
00441         void updateVelocitiesFromPositionsWithoutVelocities( float isolverdt );
00442         virtual void solveCollisionsAndUpdateVelocities( float isolverdt );
00443 
00444         // End kernel dispatches
00446         
00447         void updateBounds();
00448 
00449         void releaseKernels();
00450 
00451 public:
00452         btOpenCLSoftBodySolver(cl_command_queue queue,cl_context        ctx, bool bUpdateAchchoredNodePos = false);
00453 
00454         virtual ~btOpenCLSoftBodySolver();
00455 
00456 
00457         
00458         btOpenCLAcceleratedSoftBodyInterface *findSoftBodyInterface( const btSoftBody* const softBody );
00459 
00460         virtual btSoftBodyLinkData &getLinkData();
00461 
00462         virtual btSoftBodyVertexData &getVertexData();
00463 
00464         virtual btSoftBodyTriangleData &getTriangleData();
00465 
00466         virtual SolverTypes getSolverType() const
00467         {
00468                 return CL_SOLVER;
00469         }
00470 
00471 
00472         virtual bool checkInitialized();
00473 
00474         virtual void updateSoftBodies( );
00475 
00476         virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate=false);
00477 
00478         virtual void copyBackToSoftBodies(bool bMove = true);
00479 
00480         virtual void solveConstraints( float solverdt );
00481 
00482         virtual void predictMotion( float solverdt );
00483 
00484         virtual void processCollision( btSoftBody *, const btCollisionObjectWrapper* );
00485 
00486         virtual void processCollision( btSoftBody*, btSoftBody* );
00487 
00488         virtual void    setDefaultWorkgroupSize(size_t workGroupSize)
00489         {
00490                 m_defaultWorkGroupSize = workGroupSize;
00491         }
00492         virtual size_t  getDefaultWorkGroupSize() const
00493         {
00494                 return m_defaultWorkGroupSize;
00495         }
00496 
00497         void    setCLFunctions(CLFunctions* funcs)
00498         {
00499                 if (funcs)
00500                         m_currentCLFunctions = funcs;
00501                 else
00502                         m_currentCLFunctions  = &m_defaultCLFunctions;
00503         }
00504 
00505 }; // btOpenCLSoftBodySolver
00506 
00507 
00512 class btSoftBodySolverOutputCLtoCPU : public btSoftBodySolverOutput
00513 {
00514 protected:
00515 
00516 public:
00517         btSoftBodySolverOutputCLtoCPU()
00518         {
00519         }
00520 
00522         virtual void copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer );
00523 };
00524 
00525 
00526 
00527 #endif // #ifndef BT_SOFT_BODY_SOLVER_OPENCL_H