Imported Upstream version 2.81
[platform/upstream/libbullet.git] / src / BulletMultiThreaded / GpuSoftBodySolvers / OpenCL / btSoftBodySolver_OpenCL.h
1 /*\r
2 Bullet Continuous Collision Detection and Physics Library\r
3 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/\r
4 \r
5 This software is provided 'as-is', without any express or implied warranty.\r
6 In no event will the authors be held liable for any damages arising from the use of this software.\r
7 Permission is granted to anyone to use this software for any purpose, \r
8 including commercial applications, and to alter it and redistribute it freely, \r
9 subject to the following restrictions:\r
10 \r
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.\r
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\r
13 3. This notice may not be removed or altered from any source distribution.\r
14 */\r
15 \r
16 #ifndef BT_SOFT_BODY_SOLVER_OPENCL_H\r
17 #define BT_SOFT_BODY_SOLVER_OPENCL_H\r
18 \r
19 #include "stddef.h" //for size_t\r
20 #include "vectormath/vmInclude.h"\r
21 \r
22 #include "BulletSoftBody/btSoftBodySolvers.h"\r
23 #include "BulletSoftBody/btSoftBody.h"\r
24 #include "btSoftBodySolverBuffer_OpenCL.h"\r
25 #include "btSoftBodySolverLinkData_OpenCL.h"\r
26 #include "btSoftBodySolverVertexData_OpenCL.h"\r
27 #include "btSoftBodySolverTriangleData_OpenCL.h"\r
28 \r
29 class CLFunctions\r
30 {\r
31 protected:\r
32         cl_command_queue        m_cqCommandQue;\r
33         cl_context                      m_cxMainContext;\r
34 \r
35         int     m_kernelCompilationFailures;\r
36 \r
37 \r
38 public:\r
39         CLFunctions(cl_command_queue cqCommandQue, cl_context cxMainContext) :\r
40                 m_cqCommandQue( cqCommandQue ),\r
41                 m_cxMainContext( cxMainContext ),\r
42                 m_kernelCompilationFailures(0)\r
43         {\r
44         }\r
45 \r
46         int getKernelCompilationFailures() const\r
47         {\r
48                 return m_kernelCompilationFailures;\r
49         }\r
50 \r
51         /**\r
52          * Compile a compute shader kernel from a string and return the appropriate cl_kernel object.\r
53          */     \r
54         virtual cl_kernel compileCLKernelFromString( const char* kernelSource, const char* kernelName, const char* additionalMacros, const char* srcFileNameForCaching);\r
55 \r
56         void    clearKernelCompilationFailures()\r
57         {\r
58                 m_kernelCompilationFailures=0;\r
59         }\r
60 };\r
61 \r
62 /**\r
63  * Entry in the collision shape array.\r
64  * Specifies the shape type, the transform matrix and the necessary details of the collisionShape.\r
65  */\r
66 struct CollisionShapeDescription\r
67 {\r
68         Vectormath::Aos::Transform3 shapeTransform;\r
69         Vectormath::Aos::Vector3 linearVelocity;\r
70         Vectormath::Aos::Vector3 angularVelocity;\r
71 \r
72         int softBodyIdentifier;\r
73         int collisionShapeType;\r
74 \r
75         // Both needed for capsule\r
76         float radius;\r
77         float halfHeight;\r
78         int upAxis;\r
79         \r
80         float margin;\r
81         float friction;\r
82 \r
83         CollisionShapeDescription()\r
84         {\r
85                 collisionShapeType = 0;\r
86                 margin = 0;\r
87                 friction = 0;\r
88         }\r
89 };\r
90 \r
91 /**\r
92          * SoftBody class to maintain information about a soft body instance\r
93          * within a solver.\r
94          * This data addresses the main solver arrays.\r
95          */\r
96 class btOpenCLAcceleratedSoftBodyInterface\r
97 {\r
98 protected:\r
99         /** Current number of vertices that are part of this cloth */\r
100         int m_numVertices;\r
101         /** Maximum number of vertices allocated to be part of this cloth */\r
102         int m_maxVertices;\r
103         /** Current number of triangles that are part of this cloth */\r
104         int m_numTriangles;\r
105         /** Maximum number of triangles allocated to be part of this cloth */\r
106         int m_maxTriangles;\r
107         /** Index of first vertex in the world allocated to this cloth */\r
108         int m_firstVertex;\r
109         /** Index of first triangle in the world allocated to this cloth */\r
110         int m_firstTriangle;\r
111         /** Index of first link in the world allocated to this cloth */\r
112         int m_firstLink;\r
113         /** Maximum number of links allocated to this cloth */\r
114         int m_maxLinks;\r
115         /** Current number of links allocated to this cloth */\r
116         int m_numLinks;\r
117 \r
118         /** The actual soft body this data represents */\r
119         btSoftBody *m_softBody;\r
120 \r
121 \r
122 public:\r
123         btOpenCLAcceleratedSoftBodyInterface( btSoftBody *softBody ) :\r
124           m_softBody( softBody )\r
125         {\r
126                 m_numVertices = 0;\r
127                 m_maxVertices = 0;\r
128                 m_numTriangles = 0;\r
129                 m_maxTriangles = 0;\r
130                 m_firstVertex = 0;\r
131                 m_firstTriangle = 0;\r
132                 m_firstLink = 0;\r
133                 m_maxLinks = 0;\r
134                 m_numLinks = 0;\r
135         }\r
136         int getNumVertices()\r
137         {\r
138                 return m_numVertices;\r
139         }\r
140 \r
141         int getNumTriangles()\r
142         {\r
143                 return m_numTriangles;\r
144         }\r
145 \r
146         int getMaxVertices()\r
147         {\r
148                 return m_maxVertices;\r
149         }\r
150 \r
151         int getMaxTriangles()\r
152         {\r
153                 return m_maxTriangles;\r
154         }\r
155 \r
156         int getFirstVertex()\r
157         {\r
158                 return m_firstVertex;\r
159         }\r
160 \r
161         int getFirstTriangle()\r
162         {\r
163                 return m_firstTriangle;\r
164         }\r
165         \r
166         /**\r
167          * Update the bounds in the btSoftBody object\r
168          */\r
169         void updateBounds( const btVector3 &lowerBound, const btVector3 &upperBound );\r
170 \r
171         // TODO: All of these set functions will have to do checks and\r
172         // update the world because restructuring of the arrays will be necessary\r
173         // Reasonable use of "friend"?\r
174         void setNumVertices( int numVertices )\r
175         {\r
176                 m_numVertices = numVertices;\r
177         }       \r
178 \r
179         void setNumTriangles( int numTriangles )\r
180         {\r
181                 m_numTriangles = numTriangles;\r
182         }\r
183 \r
184         void setMaxVertices( int maxVertices )\r
185         {\r
186                 m_maxVertices = maxVertices;\r
187         }\r
188 \r
189         void setMaxTriangles( int maxTriangles )\r
190         {\r
191                 m_maxTriangles = maxTriangles;\r
192         }\r
193 \r
194         void setFirstVertex( int firstVertex )\r
195         {\r
196                 m_firstVertex = firstVertex;\r
197         }\r
198 \r
199         void setFirstTriangle( int firstTriangle )\r
200         {\r
201                 m_firstTriangle = firstTriangle;\r
202         }\r
203 \r
204         void setMaxLinks( int maxLinks )\r
205         {\r
206                 m_maxLinks = maxLinks;\r
207         }\r
208 \r
209         void setNumLinks( int numLinks )\r
210         {\r
211                 m_numLinks = numLinks;\r
212         }\r
213 \r
214         void setFirstLink( int firstLink )\r
215         {\r
216                 m_firstLink = firstLink;\r
217         }\r
218 \r
219         int getMaxLinks()\r
220         {\r
221                 return m_maxLinks;\r
222         }\r
223 \r
224         int getNumLinks()\r
225         {\r
226                 return m_numLinks;\r
227         }\r
228 \r
229         int getFirstLink()\r
230         {\r
231                 return m_firstLink;\r
232         }\r
233 \r
234         btSoftBody* getSoftBody()\r
235         {\r
236                 return m_softBody;\r
237         }\r
238 \r
239 };\r
240 \r
241 \r
242 \r
243 class btOpenCLSoftBodySolver : public btSoftBodySolver\r
244 {\r
245 public:\r
246         \r
247 \r
248         struct UIntVector3\r
249         {\r
250                 UIntVector3()\r
251                 {\r
252                         x = 0;\r
253                         y = 0;\r
254                         z = 0;\r
255                         _padding = 0;\r
256                 }\r
257                 \r
258                 UIntVector3( unsigned int x_, unsigned int y_, unsigned int z_ )\r
259                 {\r
260                         x = x_;\r
261                         y = y_;\r
262                         z = z_;\r
263                         _padding = 0;\r
264                 }\r
265                         \r
266                 unsigned int x;\r
267                 unsigned int y;\r
268                 unsigned int z;\r
269                 unsigned int _padding;\r
270         };\r
271 \r
272         struct CollisionObjectIndices\r
273         {\r
274                 CollisionObjectIndices( int f, int e )\r
275                 {\r
276                         firstObject = f;\r
277                         endObject = e;\r
278                 }\r
279 \r
280                 int firstObject;\r
281                 int endObject;\r
282         };\r
283 \r
284         btSoftBodyLinkDataOpenCL m_linkData;\r
285         btSoftBodyVertexDataOpenCL m_vertexData;\r
286         btSoftBodyTriangleDataOpenCL m_triangleData;\r
287 \r
288 protected:\r
289 \r
290         CLFunctions m_defaultCLFunctions;\r
291         CLFunctions* m_currentCLFunctions;\r
292 \r
293         /** Variable to define whether we need to update solver constants on the next iteration */\r
294         bool m_updateSolverConstants;\r
295 \r
296         bool m_shadersInitialized;\r
297 \r
298         /** \r
299          * Cloths owned by this solver.\r
300          * Only our cloths are in this array.\r
301          */\r
302         btAlignedObjectArray< btOpenCLAcceleratedSoftBodyInterface * > m_softBodySet;\r
303 \r
304         /** Acceleration value to be applied to all non-static vertices in the solver. \r
305          * Index n is cloth n, array sized by number of cloths in the world not the solver. \r
306          */\r
307         btAlignedObjectArray< Vectormath::Aos::Vector3 >        m_perClothAcceleration;\r
308         btOpenCLBuffer<Vectormath::Aos::Vector3>                        m_clPerClothAcceleration;\r
309 \r
310         /** Wind velocity to be applied normal to all non-static vertices in the solver. \r
311          * Index n is cloth n, array sized by number of cloths in the world not the solver. \r
312          */\r
313         btAlignedObjectArray< Vectormath::Aos::Vector3 >        m_perClothWindVelocity;\r
314         btOpenCLBuffer<Vectormath::Aos::Vector3>                        m_clPerClothWindVelocity;\r
315 \r
316         /** Velocity damping factor */\r
317         btAlignedObjectArray< float >                                           m_perClothDampingFactor;\r
318         btOpenCLBuffer<float>                                                           m_clPerClothDampingFactor;\r
319 \r
320         /** Velocity correction coefficient */\r
321         btAlignedObjectArray< float >                                           m_perClothVelocityCorrectionCoefficient;\r
322         btOpenCLBuffer<float>                                                           m_clPerClothVelocityCorrectionCoefficient;\r
323 \r
324         /** Lift parameter for wind effect on cloth. */\r
325         btAlignedObjectArray< float >                                           m_perClothLiftFactor;\r
326         btOpenCLBuffer<float>                                                           m_clPerClothLiftFactor;\r
327         \r
328         /** Drag parameter for wind effect on cloth. */\r
329         btAlignedObjectArray< float >                                           m_perClothDragFactor;\r
330         btOpenCLBuffer<float>                                                           m_clPerClothDragFactor;\r
331 \r
332         /** Density of the medium in which each cloth sits */\r
333         btAlignedObjectArray< float >                                           m_perClothMediumDensity;\r
334         btOpenCLBuffer<float>                                                           m_clPerClothMediumDensity;\r
335 \r
336         /** \r
337          * Collision shape details: pair of index of first collision shape for the cloth and number of collision objects.\r
338          */\r
339         btAlignedObjectArray< CollisionObjectIndices >          m_perClothCollisionObjects;\r
340         btOpenCLBuffer<CollisionObjectIndices>                          m_clPerClothCollisionObjects;\r
341 \r
342         /** \r
343          * Collision shapes being passed across to the cloths in this solver.\r
344          */\r
345         btAlignedObjectArray< CollisionShapeDescription >       m_collisionObjectDetails;\r
346         btOpenCLBuffer< CollisionShapeDescription >                     m_clCollisionObjectDetails;\r
347 \r
348 \r
349         \r
350         /** \r
351          * Friction coefficient for each cloth\r
352          */\r
353         btAlignedObjectArray< float >   m_perClothFriction;\r
354         btOpenCLBuffer< float >                 m_clPerClothFriction;\r
355 \r
356         // anchor node info\r
357         struct AnchorNodeInfoCL\r
358         {\r
359                 int clVertexIndex;\r
360                 btSoftBody::Node* pNode;\r
361         };\r
362 \r
363         btAlignedObjectArray<AnchorNodeInfoCL> m_anchorNodeInfoArray;\r
364         btAlignedObjectArray<Vectormath::Aos::Point3> m_anchorPosition;\r
365         btOpenCLBuffer<Vectormath::Aos::Point3>           m_clAnchorPosition;\r
366         btAlignedObjectArray<int> m_anchorIndex;\r
367         btOpenCLBuffer<int>               m_clAnchorIndex;\r
368 \r
369         bool m_bUpdateAnchoredNodePos;\r
370 \r
371         cl_kernel               m_prepareLinksKernel;\r
372         cl_kernel               m_solvePositionsFromLinksKernel;\r
373         cl_kernel               m_updateConstantsKernel;\r
374         cl_kernel               m_integrateKernel;\r
375         cl_kernel               m_addVelocityKernel;\r
376         cl_kernel               m_updatePositionsFromVelocitiesKernel;\r
377         cl_kernel               m_updateVelocitiesFromPositionsWithoutVelocitiesKernel;\r
378         cl_kernel               m_updateVelocitiesFromPositionsWithVelocitiesKernel;\r
379         cl_kernel               m_vSolveLinksKernel;\r
380         cl_kernel               m_solveCollisionsAndUpdateVelocitiesKernel;\r
381         cl_kernel               m_resetNormalsAndAreasKernel;\r
382         cl_kernel               m_normalizeNormalsAndAreasKernel;\r
383         cl_kernel               m_updateSoftBodiesKernel;\r
384 \r
385         cl_kernel               m_outputToVertexArrayKernel;\r
386         cl_kernel               m_applyForcesKernel;\r
387         cl_kernel       m_updateFixedVertexPositionsKernel;     \r
388 \r
389         cl_command_queue        m_cqCommandQue;\r
390         cl_context                      m_cxMainContext;\r
391         \r
392         size_t                          m_defaultWorkGroupSize;\r
393 \r
394 \r
395         virtual bool buildShaders();\r
396 \r
397         void resetNormalsAndAreas( int numVertices );\r
398 \r
399         void normalizeNormalsAndAreas( int numVertices );\r
400 \r
401         void executeUpdateSoftBodies( int firstTriangle, int numTriangles );\r
402 \r
403         void prepareCollisionConstraints();\r
404         \r
405         Vectormath::Aos::Vector3 ProjectOnAxis( const Vectormath::Aos::Vector3 &v, const Vectormath::Aos::Vector3 &a );\r
406 \r
407         void ApplyClampedForce( float solverdt, const Vectormath::Aos::Vector3 &force, const Vectormath::Aos::Vector3 &vertexVelocity, float inverseMass, Vectormath::Aos::Vector3 &vertexForce );\r
408         \r
409 \r
410         int findSoftBodyIndex( const btSoftBody* const softBody );\r
411 \r
412         virtual void applyForces( float solverdt );\r
413 \r
414         void updateFixedVertexPositions();\r
415 \r
416         /**\r
417          * Integrate motion on the solver.\r
418          */\r
419         virtual void integrate( float solverdt );\r
420 \r
421         virtual void updateConstants( float timeStep );\r
422 \r
423         float computeTriangleArea( \r
424                 const Vectormath::Aos::Point3 &vertex0,\r
425                 const Vectormath::Aos::Point3 &vertex1,\r
426                 const Vectormath::Aos::Point3 &vertex2 );\r
427 \r
428 \r
429         //////////////////////////////////////\r
430         // Kernel dispatches\r
431         void prepareLinks();\r
432 \r
433         void solveLinksForVelocity( int startLink, int numLinks, float kst );\r
434 \r
435         void updatePositionsFromVelocities( float solverdt );\r
436 \r
437         virtual void solveLinksForPosition( int startLink, int numLinks, float kst, float ti );\r
438         \r
439         void updateVelocitiesFromPositionsWithVelocities( float isolverdt );\r
440 \r
441         void updateVelocitiesFromPositionsWithoutVelocities( float isolverdt );\r
442         virtual void solveCollisionsAndUpdateVelocities( float isolverdt );\r
443 \r
444         // End kernel dispatches\r
445         /////////////////////////////////////\r
446         \r
447         void updateBounds();\r
448 \r
449         void releaseKernels();\r
450 \r
451 public:\r
452         btOpenCLSoftBodySolver(cl_command_queue queue,cl_context        ctx, bool bUpdateAchchoredNodePos = false);\r
453 \r
454         virtual ~btOpenCLSoftBodySolver();\r
455 \r
456 \r
457         \r
458         btOpenCLAcceleratedSoftBodyInterface *findSoftBodyInterface( const btSoftBody* const softBody );\r
459 \r
460         virtual btSoftBodyLinkData &getLinkData();\r
461 \r
462         virtual btSoftBodyVertexData &getVertexData();\r
463 \r
464         virtual btSoftBodyTriangleData &getTriangleData();\r
465 \r
466         virtual SolverTypes getSolverType() const\r
467         {\r
468                 return CL_SOLVER;\r
469         }\r
470 \r
471 \r
472         virtual bool checkInitialized();\r
473 \r
474         virtual void updateSoftBodies( );\r
475 \r
476         virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate=false);\r
477 \r
478         virtual void copyBackToSoftBodies(bool bMove = true);\r
479 \r
480         virtual void solveConstraints( float solverdt );\r
481 \r
482         virtual void predictMotion( float solverdt );\r
483 \r
484         virtual void processCollision( btSoftBody *, const btCollisionObjectWrapper* );\r
485 \r
486         virtual void processCollision( btSoftBody*, btSoftBody* );\r
487 \r
488         virtual void    setDefaultWorkgroupSize(size_t workGroupSize)\r
489         {\r
490                 m_defaultWorkGroupSize = workGroupSize;\r
491         }\r
492         virtual size_t  getDefaultWorkGroupSize() const\r
493         {\r
494                 return m_defaultWorkGroupSize;\r
495         }\r
496 \r
497         void    setCLFunctions(CLFunctions* funcs)\r
498         {\r
499                 if (funcs)\r
500                         m_currentCLFunctions = funcs;\r
501                 else\r
502                         m_currentCLFunctions  = &m_defaultCLFunctions;\r
503         }\r
504 \r
505 }; // btOpenCLSoftBodySolver\r
506 \r
507 \r
508 /** \r
509  * Class to manage movement of data from a solver to a given target.\r
510  * This version is the CL to CPU version.\r
511  */\r
512 class btSoftBodySolverOutputCLtoCPU : public btSoftBodySolverOutput\r
513 {\r
514 protected:\r
515 \r
516 public:\r
517         btSoftBodySolverOutputCLtoCPU()\r
518         {\r
519         }\r
520 \r
521         /** Output current computed vertex data to the vertex buffers for all cloths in the solver. */\r
522         virtual void copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer );\r
523 };\r
524 \r
525 \r
526 \r
527 #endif // #ifndef BT_SOFT_BODY_SOLVER_OPENCL_H\r