b3GpuJacobiContactSolver.cpp 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306
  1. #include "b3GpuJacobiContactSolver.h"
  2. #include "Bullet3Collision/NarrowPhaseCollision/b3Contact4.h"
  3. #include "Bullet3Common/b3AlignedObjectArray.h"
  4. #include "Bullet3OpenCL/ParallelPrimitives/b3FillCL.h" //b3Int2
  5. class b3Vector3;
  6. #include "Bullet3OpenCL/ParallelPrimitives/b3RadixSort32CL.h"
  7. #include "Bullet3OpenCL/ParallelPrimitives/b3PrefixScanCL.h"
  8. #include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h"
  9. #include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
  10. #include "Bullet3OpenCL/RigidBody/kernels/solverUtils.h"
  11. #include "Bullet3Common/b3Logging.h"
  12. #include "b3GpuConstraint4.h"
  13. #include "Bullet3Common/shared/b3Int2.h"
  14. #include "Bullet3Common/shared/b3Int4.h"
  15. #define SOLVER_UTILS_KERNEL_PATH "src/Bullet3OpenCL/RigidBody/kernels/solverUtils.cl"
  16. struct b3GpuJacobiSolverInternalData
  17. {
  18. //btRadixSort32CL* m_sort32;
  19. //btBoundSearchCL* m_search;
  20. b3PrefixScanCL* m_scan;
  21. b3OpenCLArray<unsigned int>* m_bodyCount;
  22. b3OpenCLArray<b3Int2>* m_contactConstraintOffsets;
  23. b3OpenCLArray<unsigned int>* m_offsetSplitBodies;
  24. b3OpenCLArray<b3Vector3>* m_deltaLinearVelocities;
  25. b3OpenCLArray<b3Vector3>* m_deltaAngularVelocities;
  26. b3AlignedObjectArray<b3Vector3> m_deltaLinearVelocitiesCPU;
  27. b3AlignedObjectArray<b3Vector3> m_deltaAngularVelocitiesCPU;
  28. b3OpenCLArray<b3GpuConstraint4>* m_contactConstraints;
  29. b3FillCL* m_filler;
  30. cl_kernel m_countBodiesKernel;
  31. cl_kernel m_contactToConstraintSplitKernel;
  32. cl_kernel m_clearVelocitiesKernel;
  33. cl_kernel m_averageVelocitiesKernel;
  34. cl_kernel m_updateBodyVelocitiesKernel;
  35. cl_kernel m_solveContactKernel;
  36. cl_kernel m_solveFrictionKernel;
  37. };
  38. b3GpuJacobiContactSolver::b3GpuJacobiContactSolver(cl_context ctx, cl_device_id device, cl_command_queue queue, int pairCapacity)
  39. : m_context(ctx),
  40. m_device(device),
  41. m_queue(queue)
  42. {
  43. m_data = new b3GpuJacobiSolverInternalData;
  44. m_data->m_scan = new b3PrefixScanCL(m_context, m_device, m_queue);
  45. m_data->m_bodyCount = new b3OpenCLArray<unsigned int>(m_context, m_queue);
  46. m_data->m_filler = new b3FillCL(m_context, m_device, m_queue);
  47. m_data->m_contactConstraintOffsets = new b3OpenCLArray<b3Int2>(m_context, m_queue);
  48. m_data->m_offsetSplitBodies = new b3OpenCLArray<unsigned int>(m_context, m_queue);
  49. m_data->m_contactConstraints = new b3OpenCLArray<b3GpuConstraint4>(m_context, m_queue);
  50. m_data->m_deltaLinearVelocities = new b3OpenCLArray<b3Vector3>(m_context, m_queue);
  51. m_data->m_deltaAngularVelocities = new b3OpenCLArray<b3Vector3>(m_context, m_queue);
  52. cl_int pErrNum;
  53. const char* additionalMacros = "";
  54. const char* solverUtilsSource = solverUtilsCL;
  55. {
  56. cl_program solverUtilsProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solverUtilsSource, &pErrNum, additionalMacros, SOLVER_UTILS_KERNEL_PATH);
  57. b3Assert(solverUtilsProg);
  58. m_data->m_countBodiesKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverUtilsSource, "CountBodiesKernel", &pErrNum, solverUtilsProg, additionalMacros);
  59. b3Assert(m_data->m_countBodiesKernel);
  60. m_data->m_contactToConstraintSplitKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverUtilsSource, "ContactToConstraintSplitKernel", &pErrNum, solverUtilsProg, additionalMacros);
  61. b3Assert(m_data->m_contactToConstraintSplitKernel);
  62. m_data->m_clearVelocitiesKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverUtilsSource, "ClearVelocitiesKernel", &pErrNum, solverUtilsProg, additionalMacros);
  63. b3Assert(m_data->m_clearVelocitiesKernel);
  64. m_data->m_averageVelocitiesKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverUtilsSource, "AverageVelocitiesKernel", &pErrNum, solverUtilsProg, additionalMacros);
  65. b3Assert(m_data->m_averageVelocitiesKernel);
  66. m_data->m_updateBodyVelocitiesKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverUtilsSource, "UpdateBodyVelocitiesKernel", &pErrNum, solverUtilsProg, additionalMacros);
  67. b3Assert(m_data->m_updateBodyVelocitiesKernel);
  68. m_data->m_solveContactKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverUtilsSource, "SolveContactJacobiKernel", &pErrNum, solverUtilsProg, additionalMacros);
  69. b3Assert(m_data->m_solveContactKernel);
  70. m_data->m_solveFrictionKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverUtilsSource, "SolveFrictionJacobiKernel", &pErrNum, solverUtilsProg, additionalMacros);
  71. b3Assert(m_data->m_solveFrictionKernel);
  72. }
  73. }
  74. b3GpuJacobiContactSolver::~b3GpuJacobiContactSolver()
  75. {
  76. clReleaseKernel(m_data->m_solveContactKernel);
  77. clReleaseKernel(m_data->m_solveFrictionKernel);
  78. clReleaseKernel(m_data->m_countBodiesKernel);
  79. clReleaseKernel(m_data->m_contactToConstraintSplitKernel);
  80. clReleaseKernel(m_data->m_averageVelocitiesKernel);
  81. clReleaseKernel(m_data->m_updateBodyVelocitiesKernel);
  82. clReleaseKernel(m_data->m_clearVelocitiesKernel);
  83. delete m_data->m_deltaLinearVelocities;
  84. delete m_data->m_deltaAngularVelocities;
  85. delete m_data->m_contactConstraints;
  86. delete m_data->m_offsetSplitBodies;
  87. delete m_data->m_contactConstraintOffsets;
  88. delete m_data->m_bodyCount;
  89. delete m_data->m_filler;
  90. delete m_data->m_scan;
  91. delete m_data;
  92. }
  93. b3Vector3 make_float4(float v)
  94. {
  95. return b3MakeVector3(v, v, v);
  96. }
  97. b3Vector4 make_float4(float x, float y, float z, float w)
  98. {
  99. return b3MakeVector4(x, y, z, w);
  100. }
  101. static inline float calcRelVel(const b3Vector3& l0, const b3Vector3& l1, const b3Vector3& a0, const b3Vector3& a1,
  102. const b3Vector3& linVel0, const b3Vector3& angVel0, const b3Vector3& linVel1, const b3Vector3& angVel1)
  103. {
  104. return b3Dot(l0, linVel0) + b3Dot(a0, angVel0) + b3Dot(l1, linVel1) + b3Dot(a1, angVel1);
  105. }
  106. static inline void setLinearAndAngular(const b3Vector3& n, const b3Vector3& r0, const b3Vector3& r1,
  107. b3Vector3& linear, b3Vector3& angular0, b3Vector3& angular1)
  108. {
  109. linear = n;
  110. angular0 = b3Cross(r0, n);
  111. angular1 = -b3Cross(r1, n);
  112. }
  113. static __inline void solveContact(b3GpuConstraint4& cs,
  114. const b3Vector3& posA, const b3Vector3& linVelARO, const b3Vector3& angVelARO, float invMassA, const b3Matrix3x3& invInertiaA,
  115. const b3Vector3& posB, const b3Vector3& linVelBRO, const b3Vector3& angVelBRO, float invMassB, const b3Matrix3x3& invInertiaB,
  116. float maxRambdaDt[4], float minRambdaDt[4], b3Vector3& dLinVelA, b3Vector3& dAngVelA, b3Vector3& dLinVelB, b3Vector3& dAngVelB)
  117. {
  118. for (int ic = 0; ic < 4; ic++)
  119. {
  120. // dont necessary because this makes change to 0
  121. if (cs.m_jacCoeffInv[ic] == 0.f) continue;
  122. {
  123. b3Vector3 angular0, angular1, linear;
  124. b3Vector3 r0 = cs.m_worldPos[ic] - (b3Vector3&)posA;
  125. b3Vector3 r1 = cs.m_worldPos[ic] - (b3Vector3&)posB;
  126. setLinearAndAngular((const b3Vector3&)cs.m_linear, (const b3Vector3&)r0, (const b3Vector3&)r1, linear, angular0, angular1);
  127. float rambdaDt = calcRelVel((const b3Vector3&)cs.m_linear, (const b3Vector3&)-cs.m_linear, angular0, angular1,
  128. linVelARO + dLinVelA, angVelARO + dAngVelA, linVelBRO + dLinVelB, angVelBRO + dAngVelB) +
  129. cs.m_b[ic];
  130. rambdaDt *= cs.m_jacCoeffInv[ic];
  131. {
  132. float prevSum = cs.m_appliedRambdaDt[ic];
  133. float updated = prevSum;
  134. updated += rambdaDt;
  135. updated = b3Max(updated, minRambdaDt[ic]);
  136. updated = b3Min(updated, maxRambdaDt[ic]);
  137. rambdaDt = updated - prevSum;
  138. cs.m_appliedRambdaDt[ic] = updated;
  139. }
  140. b3Vector3 linImp0 = invMassA * linear * rambdaDt;
  141. b3Vector3 linImp1 = invMassB * (-linear) * rambdaDt;
  142. b3Vector3 angImp0 = (invInertiaA * angular0) * rambdaDt;
  143. b3Vector3 angImp1 = (invInertiaB * angular1) * rambdaDt;
  144. #ifdef _WIN32
  145. b3Assert(_finite(linImp0.getX()));
  146. b3Assert(_finite(linImp1.getX()));
  147. #endif
  148. if (invMassA)
  149. {
  150. dLinVelA += linImp0;
  151. dAngVelA += angImp0;
  152. }
  153. if (invMassB)
  154. {
  155. dLinVelB += linImp1;
  156. dAngVelB += angImp1;
  157. }
  158. }
  159. }
  160. }
  161. void solveContact3(b3GpuConstraint4* cs,
  162. b3Vector3* posAPtr, b3Vector3* linVelA, b3Vector3* angVelA, float invMassA, const b3Matrix3x3& invInertiaA,
  163. b3Vector3* posBPtr, b3Vector3* linVelB, b3Vector3* angVelB, float invMassB, const b3Matrix3x3& invInertiaB,
  164. b3Vector3* dLinVelA, b3Vector3* dAngVelA, b3Vector3* dLinVelB, b3Vector3* dAngVelB)
  165. {
  166. float minRambdaDt = 0;
  167. float maxRambdaDt = FLT_MAX;
  168. for (int ic = 0; ic < 4; ic++)
  169. {
  170. if (cs->m_jacCoeffInv[ic] == 0.f) continue;
  171. b3Vector3 angular0, angular1, linear;
  172. b3Vector3 r0 = cs->m_worldPos[ic] - *posAPtr;
  173. b3Vector3 r1 = cs->m_worldPos[ic] - *posBPtr;
  174. setLinearAndAngular(cs->m_linear, r0, r1, linear, angular0, angular1);
  175. float rambdaDt = calcRelVel(cs->m_linear, -cs->m_linear, angular0, angular1,
  176. *linVelA + *dLinVelA, *angVelA + *dAngVelA, *linVelB + *dLinVelB, *angVelB + *dAngVelB) +
  177. cs->m_b[ic];
  178. rambdaDt *= cs->m_jacCoeffInv[ic];
  179. {
  180. float prevSum = cs->m_appliedRambdaDt[ic];
  181. float updated = prevSum;
  182. updated += rambdaDt;
  183. updated = b3Max(updated, minRambdaDt);
  184. updated = b3Min(updated, maxRambdaDt);
  185. rambdaDt = updated - prevSum;
  186. cs->m_appliedRambdaDt[ic] = updated;
  187. }
  188. b3Vector3 linImp0 = invMassA * linear * rambdaDt;
  189. b3Vector3 linImp1 = invMassB * (-linear) * rambdaDt;
  190. b3Vector3 angImp0 = (invInertiaA * angular0) * rambdaDt;
  191. b3Vector3 angImp1 = (invInertiaB * angular1) * rambdaDt;
  192. if (invMassA)
  193. {
  194. *dLinVelA += linImp0;
  195. *dAngVelA += angImp0;
  196. }
  197. if (invMassB)
  198. {
  199. *dLinVelB += linImp1;
  200. *dAngVelB += angImp1;
  201. }
  202. }
  203. }
  204. static inline void solveFriction(b3GpuConstraint4& cs,
  205. const b3Vector3& posA, const b3Vector3& linVelARO, const b3Vector3& angVelARO, float invMassA, const b3Matrix3x3& invInertiaA,
  206. const b3Vector3& posB, const b3Vector3& linVelBRO, const b3Vector3& angVelBRO, float invMassB, const b3Matrix3x3& invInertiaB,
  207. float maxRambdaDt[4], float minRambdaDt[4], b3Vector3& dLinVelA, b3Vector3& dAngVelA, b3Vector3& dLinVelB, b3Vector3& dAngVelB)
  208. {
  209. b3Vector3 linVelA = linVelARO + dLinVelA;
  210. b3Vector3 linVelB = linVelBRO + dLinVelB;
  211. b3Vector3 angVelA = angVelARO + dAngVelA;
  212. b3Vector3 angVelB = angVelBRO + dAngVelB;
  213. if (cs.m_fJacCoeffInv[0] == 0 && cs.m_fJacCoeffInv[0] == 0) return;
  214. const b3Vector3& center = (const b3Vector3&)cs.m_center;
  215. b3Vector3 n = -(const b3Vector3&)cs.m_linear;
  216. b3Vector3 tangent[2];
  217. #if 1
  218. b3PlaneSpace1(n, tangent[0], tangent[1]);
  219. #else
  220. b3Vector3 r = cs.m_worldPos[0] - center;
  221. tangent[0] = cross3(n, r);
  222. tangent[1] = cross3(tangent[0], n);
  223. tangent[0] = normalize3(tangent[0]);
  224. tangent[1] = normalize3(tangent[1]);
  225. #endif
  226. b3Vector3 angular0, angular1, linear;
  227. b3Vector3 r0 = center - posA;
  228. b3Vector3 r1 = center - posB;
  229. for (int i = 0; i < 2; i++)
  230. {
  231. setLinearAndAngular(tangent[i], r0, r1, linear, angular0, angular1);
  232. float rambdaDt = calcRelVel(linear, -linear, angular0, angular1,
  233. linVelA, angVelA, linVelB, angVelB);
  234. rambdaDt *= cs.m_fJacCoeffInv[i];
  235. {
  236. float prevSum = cs.m_fAppliedRambdaDt[i];
  237. float updated = prevSum;
  238. updated += rambdaDt;
  239. updated = b3Max(updated, minRambdaDt[i]);
  240. updated = b3Min(updated, maxRambdaDt[i]);
  241. rambdaDt = updated - prevSum;
  242. cs.m_fAppliedRambdaDt[i] = updated;
  243. }
  244. b3Vector3 linImp0 = invMassA * linear * rambdaDt;
  245. b3Vector3 linImp1 = invMassB * (-linear) * rambdaDt;
  246. b3Vector3 angImp0 = (invInertiaA * angular0) * rambdaDt;
  247. b3Vector3 angImp1 = (invInertiaB * angular1) * rambdaDt;
  248. #ifdef _WIN32
  249. b3Assert(_finite(linImp0.getX()));
  250. b3Assert(_finite(linImp1.getX()));
  251. #endif
  252. if (invMassA)
  253. {
  254. dLinVelA += linImp0;
  255. dAngVelA += angImp0;
  256. }
  257. if (invMassB)
  258. {
  259. dLinVelB += linImp1;
  260. dAngVelB += angImp1;
  261. }
  262. }
  263. { // angular damping for point constraint
  264. b3Vector3 ab = (posB - posA).normalized();
  265. b3Vector3 ac = (center - posA).normalized();
  266. if (b3Dot(ab, ac) > 0.95f || (invMassA == 0.f || invMassB == 0.f))
  267. {
  268. float angNA = b3Dot(n, angVelA);
  269. float angNB = b3Dot(n, angVelB);
  270. if (invMassA)
  271. dAngVelA -= (angNA * 0.1f) * n;
  272. if (invMassB)
  273. dAngVelB -= (angNB * 0.1f) * n;
  274. }
  275. }
  276. }
  277. float calcJacCoeff(const b3Vector3& linear0, const b3Vector3& linear1, const b3Vector3& angular0, const b3Vector3& angular1,
  278. float invMass0, const b3Matrix3x3* invInertia0, float invMass1, const b3Matrix3x3* invInertia1, float countA, float countB)
  279. {
  280. // linear0,1 are normlized
  281. float jmj0 = invMass0; //dot3F4(linear0, linear0)*invMass0;
  282. float jmj1 = b3Dot(mtMul3(angular0, *invInertia0), angular0);
  283. float jmj2 = invMass1; //dot3F4(linear1, linear1)*invMass1;
  284. float jmj3 = b3Dot(mtMul3(angular1, *invInertia1), angular1);
  285. return -1.f / ((jmj0 + jmj1) * countA + (jmj2 + jmj3) * countB);
  286. // return -1.f/((jmj0+jmj1)+(jmj2+jmj3));
  287. }
  288. void setConstraint4(const b3Vector3& posA, const b3Vector3& linVelA, const b3Vector3& angVelA, float invMassA, const b3Matrix3x3& invInertiaA,
  289. const b3Vector3& posB, const b3Vector3& linVelB, const b3Vector3& angVelB, float invMassB, const b3Matrix3x3& invInertiaB,
  290. b3Contact4* src, float dt, float positionDrift, float positionConstraintCoeff, float countA, float countB,
  291. b3GpuConstraint4* dstC)
  292. {
  293. dstC->m_bodyA = abs(src->m_bodyAPtrAndSignBit);
  294. dstC->m_bodyB = abs(src->m_bodyBPtrAndSignBit);
  295. float dtInv = 1.f / dt;
  296. for (int ic = 0; ic < 4; ic++)
  297. {
  298. dstC->m_appliedRambdaDt[ic] = 0.f;
  299. }
  300. dstC->m_fJacCoeffInv[0] = dstC->m_fJacCoeffInv[1] = 0.f;
  301. dstC->m_linear = src->m_worldNormalOnB;
  302. dstC->m_linear[3] = 0.7f; //src->getFrictionCoeff() );
  303. for (int ic = 0; ic < 4; ic++)
  304. {
  305. b3Vector3 r0 = src->m_worldPosB[ic] - posA;
  306. b3Vector3 r1 = src->m_worldPosB[ic] - posB;
  307. if (ic >= src->m_worldNormalOnB[3]) //npoints
  308. {
  309. dstC->m_jacCoeffInv[ic] = 0.f;
  310. continue;
  311. }
  312. float relVelN;
  313. {
  314. b3Vector3 linear, angular0, angular1;
  315. setLinearAndAngular(src->m_worldNormalOnB, r0, r1, linear, angular0, angular1);
  316. dstC->m_jacCoeffInv[ic] = calcJacCoeff(linear, -linear, angular0, angular1,
  317. invMassA, &invInertiaA, invMassB, &invInertiaB, countA, countB);
  318. relVelN = calcRelVel(linear, -linear, angular0, angular1,
  319. linVelA, angVelA, linVelB, angVelB);
  320. float e = 0.f; //src->getRestituitionCoeff();
  321. if (relVelN * relVelN < 0.004f)
  322. {
  323. e = 0.f;
  324. }
  325. dstC->m_b[ic] = e * relVelN;
  326. //float penetration = src->m_worldPos[ic].w;
  327. dstC->m_b[ic] += (src->m_worldPosB[ic][3] + positionDrift) * positionConstraintCoeff * dtInv;
  328. dstC->m_appliedRambdaDt[ic] = 0.f;
  329. }
  330. }
  331. if (src->m_worldNormalOnB[3] > 0) //npoints
  332. { // prepare friction
  333. b3Vector3 center = make_float4(0.f);
  334. for (int i = 0; i < src->m_worldNormalOnB[3]; i++)
  335. center += src->m_worldPosB[i];
  336. center /= (float)src->m_worldNormalOnB[3];
  337. b3Vector3 tangent[2];
  338. b3PlaneSpace1(src->m_worldNormalOnB, tangent[0], tangent[1]);
  339. b3Vector3 r[2];
  340. r[0] = center - posA;
  341. r[1] = center - posB;
  342. for (int i = 0; i < 2; i++)
  343. {
  344. b3Vector3 linear, angular0, angular1;
  345. setLinearAndAngular(tangent[i], r[0], r[1], linear, angular0, angular1);
  346. dstC->m_fJacCoeffInv[i] = calcJacCoeff(linear, -linear, angular0, angular1,
  347. invMassA, &invInertiaA, invMassB, &invInertiaB, countA, countB);
  348. dstC->m_fAppliedRambdaDt[i] = 0.f;
  349. }
  350. dstC->m_center = center;
  351. }
  352. for (int i = 0; i < 4; i++)
  353. {
  354. if (i < src->m_worldNormalOnB[3])
  355. {
  356. dstC->m_worldPos[i] = src->m_worldPosB[i];
  357. }
  358. else
  359. {
  360. dstC->m_worldPos[i] = make_float4(0.f);
  361. }
  362. }
  363. }
  364. void ContactToConstraintKernel(b3Contact4* gContact, b3RigidBodyData* gBodies, b3InertiaData* gShapes, b3GpuConstraint4* gConstraintOut, int nContacts,
  365. float dt,
  366. float positionDrift,
  367. float positionConstraintCoeff, int gIdx, b3AlignedObjectArray<unsigned int>& bodyCount)
  368. {
  369. //int gIdx = 0;//GET_GLOBAL_IDX;
  370. if (gIdx < nContacts)
  371. {
  372. int aIdx = abs(gContact[gIdx].m_bodyAPtrAndSignBit);
  373. int bIdx = abs(gContact[gIdx].m_bodyBPtrAndSignBit);
  374. b3Vector3 posA = gBodies[aIdx].m_pos;
  375. b3Vector3 linVelA = gBodies[aIdx].m_linVel;
  376. b3Vector3 angVelA = gBodies[aIdx].m_angVel;
  377. float invMassA = gBodies[aIdx].m_invMass;
  378. b3Matrix3x3 invInertiaA = gShapes[aIdx].m_invInertiaWorld; //.m_invInertia;
  379. b3Vector3 posB = gBodies[bIdx].m_pos;
  380. b3Vector3 linVelB = gBodies[bIdx].m_linVel;
  381. b3Vector3 angVelB = gBodies[bIdx].m_angVel;
  382. float invMassB = gBodies[bIdx].m_invMass;
  383. b3Matrix3x3 invInertiaB = gShapes[bIdx].m_invInertiaWorld; //m_invInertia;
  384. b3GpuConstraint4 cs;
  385. float countA = invMassA ? (float)(bodyCount[aIdx]) : 1;
  386. float countB = invMassB ? (float)(bodyCount[bIdx]) : 1;
  387. setConstraint4(posA, linVelA, angVelA, invMassA, invInertiaA, posB, linVelB, angVelB, invMassB, invInertiaB,
  388. &gContact[gIdx], dt, positionDrift, positionConstraintCoeff, countA, countB,
  389. &cs);
  390. cs.m_batchIdx = gContact[gIdx].m_batchIdx;
  391. gConstraintOut[gIdx] = cs;
  392. }
  393. }
  394. void b3GpuJacobiContactSolver::solveGroupHost(b3RigidBodyData* bodies, b3InertiaData* inertias, int numBodies, b3Contact4* manifoldPtr, int numManifolds, const b3JacobiSolverInfo& solverInfo)
  395. {
  396. B3_PROFILE("b3GpuJacobiContactSolver::solveGroup");
  397. b3AlignedObjectArray<unsigned int> bodyCount;
  398. bodyCount.resize(numBodies);
  399. for (int i = 0; i < numBodies; i++)
  400. bodyCount[i] = 0;
  401. b3AlignedObjectArray<b3Int2> contactConstraintOffsets;
  402. contactConstraintOffsets.resize(numManifolds);
  403. for (int i = 0; i < numManifolds; i++)
  404. {
  405. int pa = manifoldPtr[i].m_bodyAPtrAndSignBit;
  406. int pb = manifoldPtr[i].m_bodyBPtrAndSignBit;
  407. bool isFixedA = (pa < 0) || (pa == solverInfo.m_fixedBodyIndex);
  408. bool isFixedB = (pb < 0) || (pb == solverInfo.m_fixedBodyIndex);
  409. int bodyIndexA = manifoldPtr[i].getBodyA();
  410. int bodyIndexB = manifoldPtr[i].getBodyB();
  411. if (!isFixedA)
  412. {
  413. contactConstraintOffsets[i].x = bodyCount[bodyIndexA];
  414. bodyCount[bodyIndexA]++;
  415. }
  416. if (!isFixedB)
  417. {
  418. contactConstraintOffsets[i].y = bodyCount[bodyIndexB];
  419. bodyCount[bodyIndexB]++;
  420. }
  421. }
  422. b3AlignedObjectArray<unsigned int> offsetSplitBodies;
  423. offsetSplitBodies.resize(numBodies);
  424. unsigned int totalNumSplitBodies;
  425. m_data->m_scan->executeHost(bodyCount, offsetSplitBodies, numBodies, &totalNumSplitBodies);
  426. int numlastBody = bodyCount[numBodies - 1];
  427. totalNumSplitBodies += numlastBody;
  428. printf("totalNumSplitBodies = %d\n", totalNumSplitBodies);
  429. b3AlignedObjectArray<b3GpuConstraint4> contactConstraints;
  430. contactConstraints.resize(numManifolds);
  431. for (int i = 0; i < numManifolds; i++)
  432. {
  433. ContactToConstraintKernel(&manifoldPtr[0], bodies, inertias, &contactConstraints[0], numManifolds,
  434. solverInfo.m_deltaTime,
  435. solverInfo.m_positionDrift,
  436. solverInfo.m_positionConstraintCoeff,
  437. i, bodyCount);
  438. }
  439. int maxIter = solverInfo.m_numIterations;
  440. b3AlignedObjectArray<b3Vector3> deltaLinearVelocities;
  441. b3AlignedObjectArray<b3Vector3> deltaAngularVelocities;
  442. deltaLinearVelocities.resize(totalNumSplitBodies);
  443. deltaAngularVelocities.resize(totalNumSplitBodies);
  444. for (unsigned int i = 0; i < totalNumSplitBodies; i++)
  445. {
  446. deltaLinearVelocities[i].setZero();
  447. deltaAngularVelocities[i].setZero();
  448. }
  449. for (int iter = 0; iter < maxIter; iter++)
  450. {
  451. int i = 0;
  452. for (i = 0; i < numManifolds; i++)
  453. {
  454. //float frictionCoeff = contactConstraints[i].getFrictionCoeff();
  455. int aIdx = (int)contactConstraints[i].m_bodyA;
  456. int bIdx = (int)contactConstraints[i].m_bodyB;
  457. b3RigidBodyData& bodyA = bodies[aIdx];
  458. b3RigidBodyData& bodyB = bodies[bIdx];
  459. b3Vector3 zero = b3MakeVector3(0, 0, 0);
  460. b3Vector3* dlvAPtr = &zero;
  461. b3Vector3* davAPtr = &zero;
  462. b3Vector3* dlvBPtr = &zero;
  463. b3Vector3* davBPtr = &zero;
  464. if (bodyA.m_invMass)
  465. {
  466. int bodyOffsetA = offsetSplitBodies[aIdx];
  467. int constraintOffsetA = contactConstraintOffsets[i].x;
  468. int splitIndexA = bodyOffsetA + constraintOffsetA;
  469. dlvAPtr = &deltaLinearVelocities[splitIndexA];
  470. davAPtr = &deltaAngularVelocities[splitIndexA];
  471. }
  472. if (bodyB.m_invMass)
  473. {
  474. int bodyOffsetB = offsetSplitBodies[bIdx];
  475. int constraintOffsetB = contactConstraintOffsets[i].y;
  476. int splitIndexB = bodyOffsetB + constraintOffsetB;
  477. dlvBPtr = &deltaLinearVelocities[splitIndexB];
  478. davBPtr = &deltaAngularVelocities[splitIndexB];
  479. }
  480. {
  481. float maxRambdaDt[4] = {FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX};
  482. float minRambdaDt[4] = {0.f, 0.f, 0.f, 0.f};
  483. solveContact(contactConstraints[i], (b3Vector3&)bodyA.m_pos, (b3Vector3&)bodyA.m_linVel, (b3Vector3&)bodyA.m_angVel, bodyA.m_invMass, inertias[aIdx].m_invInertiaWorld,
  484. (b3Vector3&)bodyB.m_pos, (b3Vector3&)bodyB.m_linVel, (b3Vector3&)bodyB.m_angVel, bodyB.m_invMass, inertias[bIdx].m_invInertiaWorld,
  485. maxRambdaDt, minRambdaDt, *dlvAPtr, *davAPtr, *dlvBPtr, *davBPtr);
  486. }
  487. }
  488. //easy
  489. for (int i = 0; i < numBodies; i++)
  490. {
  491. if (bodies[i].m_invMass)
  492. {
  493. int bodyOffset = offsetSplitBodies[i];
  494. int count = bodyCount[i];
  495. float factor = 1.f / float(count);
  496. b3Vector3 averageLinVel;
  497. averageLinVel.setZero();
  498. b3Vector3 averageAngVel;
  499. averageAngVel.setZero();
  500. for (int j = 0; j < count; j++)
  501. {
  502. averageLinVel += deltaLinearVelocities[bodyOffset + j] * factor;
  503. averageAngVel += deltaAngularVelocities[bodyOffset + j] * factor;
  504. }
  505. for (int j = 0; j < count; j++)
  506. {
  507. deltaLinearVelocities[bodyOffset + j] = averageLinVel;
  508. deltaAngularVelocities[bodyOffset + j] = averageAngVel;
  509. }
  510. }
  511. }
  512. }
  513. for (int iter = 0; iter < maxIter; iter++)
  514. {
  515. //int i=0;
  516. //solve friction
  517. for (int i = 0; i < numManifolds; i++)
  518. {
  519. float maxRambdaDt[4] = {FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX};
  520. float minRambdaDt[4] = {0.f, 0.f, 0.f, 0.f};
  521. float sum = 0;
  522. for (int j = 0; j < 4; j++)
  523. {
  524. sum += contactConstraints[i].m_appliedRambdaDt[j];
  525. }
  526. float frictionCoeff = contactConstraints[i].getFrictionCoeff();
  527. int aIdx = (int)contactConstraints[i].m_bodyA;
  528. int bIdx = (int)contactConstraints[i].m_bodyB;
  529. b3RigidBodyData& bodyA = bodies[aIdx];
  530. b3RigidBodyData& bodyB = bodies[bIdx];
  531. b3Vector3 zero = b3MakeVector3(0, 0, 0);
  532. b3Vector3* dlvAPtr = &zero;
  533. b3Vector3* davAPtr = &zero;
  534. b3Vector3* dlvBPtr = &zero;
  535. b3Vector3* davBPtr = &zero;
  536. if (bodyA.m_invMass)
  537. {
  538. int bodyOffsetA = offsetSplitBodies[aIdx];
  539. int constraintOffsetA = contactConstraintOffsets[i].x;
  540. int splitIndexA = bodyOffsetA + constraintOffsetA;
  541. dlvAPtr = &deltaLinearVelocities[splitIndexA];
  542. davAPtr = &deltaAngularVelocities[splitIndexA];
  543. }
  544. if (bodyB.m_invMass)
  545. {
  546. int bodyOffsetB = offsetSplitBodies[bIdx];
  547. int constraintOffsetB = contactConstraintOffsets[i].y;
  548. int splitIndexB = bodyOffsetB + constraintOffsetB;
  549. dlvBPtr = &deltaLinearVelocities[splitIndexB];
  550. davBPtr = &deltaAngularVelocities[splitIndexB];
  551. }
  552. for (int j = 0; j < 4; j++)
  553. {
  554. maxRambdaDt[j] = frictionCoeff * sum;
  555. minRambdaDt[j] = -maxRambdaDt[j];
  556. }
  557. solveFriction(contactConstraints[i], (b3Vector3&)bodyA.m_pos, (b3Vector3&)bodyA.m_linVel, (b3Vector3&)bodyA.m_angVel, bodyA.m_invMass, inertias[aIdx].m_invInertiaWorld,
  558. (b3Vector3&)bodyB.m_pos, (b3Vector3&)bodyB.m_linVel, (b3Vector3&)bodyB.m_angVel, bodyB.m_invMass, inertias[bIdx].m_invInertiaWorld,
  559. maxRambdaDt, minRambdaDt, *dlvAPtr, *davAPtr, *dlvBPtr, *davBPtr);
  560. }
  561. //easy
  562. for (int i = 0; i < numBodies; i++)
  563. {
  564. if (bodies[i].m_invMass)
  565. {
  566. int bodyOffset = offsetSplitBodies[i];
  567. int count = bodyCount[i];
  568. float factor = 1.f / float(count);
  569. b3Vector3 averageLinVel;
  570. averageLinVel.setZero();
  571. b3Vector3 averageAngVel;
  572. averageAngVel.setZero();
  573. for (int j = 0; j < count; j++)
  574. {
  575. averageLinVel += deltaLinearVelocities[bodyOffset + j] * factor;
  576. averageAngVel += deltaAngularVelocities[bodyOffset + j] * factor;
  577. }
  578. for (int j = 0; j < count; j++)
  579. {
  580. deltaLinearVelocities[bodyOffset + j] = averageLinVel;
  581. deltaAngularVelocities[bodyOffset + j] = averageAngVel;
  582. }
  583. }
  584. }
  585. }
  586. //easy
  587. for (int i = 0; i < numBodies; i++)
  588. {
  589. if (bodies[i].m_invMass)
  590. {
  591. int bodyOffset = offsetSplitBodies[i];
  592. int count = bodyCount[i];
  593. if (count)
  594. {
  595. bodies[i].m_linVel += deltaLinearVelocities[bodyOffset];
  596. bodies[i].m_angVel += deltaAngularVelocities[bodyOffset];
  597. }
  598. }
  599. }
  600. }
  601. void b3GpuJacobiContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem inertiaBuf, int numContacts, cl_mem contactBuf, const struct b3Config& config, int static0Index)
  602. //
  603. //
  604. //void b3GpuJacobiContactSolver::solveGroup(b3OpenCLArray<b3RigidBodyData>* bodies,b3OpenCLArray<b3InertiaData>* inertias,b3OpenCLArray<b3Contact4>* manifoldPtr,const btJacobiSolverInfo& solverInfo)
  605. {
  606. b3JacobiSolverInfo solverInfo;
  607. solverInfo.m_fixedBodyIndex = static0Index;
  608. B3_PROFILE("b3GpuJacobiContactSolver::solveGroup");
  609. //int numBodies = bodies->size();
  610. int numManifolds = numContacts; //manifoldPtr->size();
  611. {
  612. B3_PROFILE("resize");
  613. m_data->m_bodyCount->resize(numBodies);
  614. }
  615. unsigned int val = 0;
  616. b3Int2 val2;
  617. val2.x = 0;
  618. val2.y = 0;
  619. {
  620. B3_PROFILE("m_filler");
  621. m_data->m_contactConstraintOffsets->resize(numManifolds);
  622. m_data->m_filler->execute(*m_data->m_bodyCount, val, numBodies);
  623. m_data->m_filler->execute(*m_data->m_contactConstraintOffsets, val2, numManifolds);
  624. }
  625. {
  626. B3_PROFILE("m_countBodiesKernel");
  627. b3LauncherCL launcher(this->m_queue, m_data->m_countBodiesKernel, "m_countBodiesKernel");
  628. launcher.setBuffer(contactBuf); //manifoldPtr->getBufferCL());
  629. launcher.setBuffer(m_data->m_bodyCount->getBufferCL());
  630. launcher.setBuffer(m_data->m_contactConstraintOffsets->getBufferCL());
  631. launcher.setConst(numManifolds);
  632. launcher.setConst(solverInfo.m_fixedBodyIndex);
  633. launcher.launch1D(numManifolds);
  634. }
  635. unsigned int totalNumSplitBodies = 0;
  636. {
  637. B3_PROFILE("m_scan->execute");
  638. m_data->m_offsetSplitBodies->resize(numBodies);
  639. m_data->m_scan->execute(*m_data->m_bodyCount, *m_data->m_offsetSplitBodies, numBodies, &totalNumSplitBodies);
  640. totalNumSplitBodies += m_data->m_bodyCount->at(numBodies - 1);
  641. }
  642. {
  643. B3_PROFILE("m_data->m_contactConstraints->resize");
  644. //int numContacts = manifoldPtr->size();
  645. m_data->m_contactConstraints->resize(numContacts);
  646. }
  647. {
  648. B3_PROFILE("contactToConstraintSplitKernel");
  649. b3LauncherCL launcher(m_queue, m_data->m_contactToConstraintSplitKernel, "m_contactToConstraintSplitKernel");
  650. launcher.setBuffer(contactBuf);
  651. launcher.setBuffer(bodyBuf);
  652. launcher.setBuffer(inertiaBuf);
  653. launcher.setBuffer(m_data->m_contactConstraints->getBufferCL());
  654. launcher.setBuffer(m_data->m_bodyCount->getBufferCL());
  655. launcher.setConst(numContacts);
  656. launcher.setConst(solverInfo.m_deltaTime);
  657. launcher.setConst(solverInfo.m_positionDrift);
  658. launcher.setConst(solverInfo.m_positionConstraintCoeff);
  659. launcher.launch1D(numContacts, 64);
  660. }
  661. {
  662. B3_PROFILE("m_data->m_deltaLinearVelocities->resize");
  663. m_data->m_deltaLinearVelocities->resize(totalNumSplitBodies);
  664. m_data->m_deltaAngularVelocities->resize(totalNumSplitBodies);
  665. }
  666. {
  667. B3_PROFILE("m_clearVelocitiesKernel");
  668. b3LauncherCL launch(m_queue, m_data->m_clearVelocitiesKernel, "m_clearVelocitiesKernel");
  669. launch.setBuffer(m_data->m_deltaAngularVelocities->getBufferCL());
  670. launch.setBuffer(m_data->m_deltaLinearVelocities->getBufferCL());
  671. launch.setConst(totalNumSplitBodies);
  672. launch.launch1D(totalNumSplitBodies);
  673. clFinish(m_queue);
  674. }
  675. int maxIter = solverInfo.m_numIterations;
  676. for (int iter = 0; iter < maxIter; iter++)
  677. {
  678. {
  679. B3_PROFILE("m_solveContactKernel");
  680. b3LauncherCL launcher(m_queue, m_data->m_solveContactKernel, "m_solveContactKernel");
  681. launcher.setBuffer(m_data->m_contactConstraints->getBufferCL());
  682. launcher.setBuffer(bodyBuf);
  683. launcher.setBuffer(inertiaBuf);
  684. launcher.setBuffer(m_data->m_contactConstraintOffsets->getBufferCL());
  685. launcher.setBuffer(m_data->m_offsetSplitBodies->getBufferCL());
  686. launcher.setBuffer(m_data->m_deltaLinearVelocities->getBufferCL());
  687. launcher.setBuffer(m_data->m_deltaAngularVelocities->getBufferCL());
  688. launcher.setConst(solverInfo.m_deltaTime);
  689. launcher.setConst(solverInfo.m_positionDrift);
  690. launcher.setConst(solverInfo.m_positionConstraintCoeff);
  691. launcher.setConst(solverInfo.m_fixedBodyIndex);
  692. launcher.setConst(numManifolds);
  693. launcher.launch1D(numManifolds);
  694. clFinish(m_queue);
  695. }
  696. {
  697. B3_PROFILE("average velocities");
  698. b3LauncherCL launcher(m_queue, m_data->m_averageVelocitiesKernel, "m_averageVelocitiesKernel");
  699. launcher.setBuffer(bodyBuf);
  700. launcher.setBuffer(m_data->m_offsetSplitBodies->getBufferCL());
  701. launcher.setBuffer(m_data->m_bodyCount->getBufferCL());
  702. launcher.setBuffer(m_data->m_deltaLinearVelocities->getBufferCL());
  703. launcher.setBuffer(m_data->m_deltaAngularVelocities->getBufferCL());
  704. launcher.setConst(numBodies);
  705. launcher.launch1D(numBodies);
  706. clFinish(m_queue);
  707. }
  708. {
  709. B3_PROFILE("m_solveFrictionKernel");
  710. b3LauncherCL launcher(m_queue, m_data->m_solveFrictionKernel, "m_solveFrictionKernel");
  711. launcher.setBuffer(m_data->m_contactConstraints->getBufferCL());
  712. launcher.setBuffer(bodyBuf);
  713. launcher.setBuffer(inertiaBuf);
  714. launcher.setBuffer(m_data->m_contactConstraintOffsets->getBufferCL());
  715. launcher.setBuffer(m_data->m_offsetSplitBodies->getBufferCL());
  716. launcher.setBuffer(m_data->m_deltaLinearVelocities->getBufferCL());
  717. launcher.setBuffer(m_data->m_deltaAngularVelocities->getBufferCL());
  718. launcher.setConst(solverInfo.m_deltaTime);
  719. launcher.setConst(solverInfo.m_positionDrift);
  720. launcher.setConst(solverInfo.m_positionConstraintCoeff);
  721. launcher.setConst(solverInfo.m_fixedBodyIndex);
  722. launcher.setConst(numManifolds);
  723. launcher.launch1D(numManifolds);
  724. clFinish(m_queue);
  725. }
  726. {
  727. B3_PROFILE("average velocities");
  728. b3LauncherCL launcher(m_queue, m_data->m_averageVelocitiesKernel, "m_averageVelocitiesKernel");
  729. launcher.setBuffer(bodyBuf);
  730. launcher.setBuffer(m_data->m_offsetSplitBodies->getBufferCL());
  731. launcher.setBuffer(m_data->m_bodyCount->getBufferCL());
  732. launcher.setBuffer(m_data->m_deltaLinearVelocities->getBufferCL());
  733. launcher.setBuffer(m_data->m_deltaAngularVelocities->getBufferCL());
  734. launcher.setConst(numBodies);
  735. launcher.launch1D(numBodies);
  736. clFinish(m_queue);
  737. }
  738. }
  739. {
  740. B3_PROFILE("update body velocities");
  741. b3LauncherCL launcher(m_queue, m_data->m_updateBodyVelocitiesKernel, "m_updateBodyVelocitiesKernel");
  742. launcher.setBuffer(bodyBuf);
  743. launcher.setBuffer(m_data->m_offsetSplitBodies->getBufferCL());
  744. launcher.setBuffer(m_data->m_bodyCount->getBufferCL());
  745. launcher.setBuffer(m_data->m_deltaLinearVelocities->getBufferCL());
  746. launcher.setBuffer(m_data->m_deltaAngularVelocities->getBufferCL());
  747. launcher.setConst(numBodies);
  748. launcher.launch1D(numBodies);
  749. clFinish(m_queue);
  750. }
  751. }
  752. #if 0
  753. void b3GpuJacobiContactSolver::solveGroupMixed(b3OpenCLArray<b3RigidBodyData>* bodiesGPU,b3OpenCLArray<b3InertiaData>* inertiasGPU,b3OpenCLArray<b3Contact4>* manifoldPtrGPU,const btJacobiSolverInfo& solverInfo)
  754. {
  755. b3AlignedObjectArray<b3RigidBodyData> bodiesCPU;
  756. bodiesGPU->copyToHost(bodiesCPU);
  757. b3AlignedObjectArray<b3InertiaData> inertiasCPU;
  758. inertiasGPU->copyToHost(inertiasCPU);
  759. b3AlignedObjectArray<b3Contact4> manifoldPtrCPU;
  760. manifoldPtrGPU->copyToHost(manifoldPtrCPU);
  761. int numBodiesCPU = bodiesGPU->size();
  762. int numManifoldsCPU = manifoldPtrGPU->size();
  763. B3_PROFILE("b3GpuJacobiContactSolver::solveGroupMixed");
  764. b3AlignedObjectArray<unsigned int> bodyCount;
  765. bodyCount.resize(numBodiesCPU);
  766. for (int i=0;i<numBodiesCPU;i++)
  767. bodyCount[i] = 0;
  768. b3AlignedObjectArray<b3Int2> contactConstraintOffsets;
  769. contactConstraintOffsets.resize(numManifoldsCPU);
  770. for (int i=0;i<numManifoldsCPU;i++)
  771. {
  772. int pa = manifoldPtrCPU[i].m_bodyAPtrAndSignBit;
  773. int pb = manifoldPtrCPU[i].m_bodyBPtrAndSignBit;
  774. bool isFixedA = (pa <0) || (pa == solverInfo.m_fixedBodyIndex);
  775. bool isFixedB = (pb <0) || (pb == solverInfo.m_fixedBodyIndex);
  776. int bodyIndexA = manifoldPtrCPU[i].getBodyA();
  777. int bodyIndexB = manifoldPtrCPU[i].getBodyB();
  778. if (!isFixedA)
  779. {
  780. contactConstraintOffsets[i].x = bodyCount[bodyIndexA];
  781. bodyCount[bodyIndexA]++;
  782. }
  783. if (!isFixedB)
  784. {
  785. contactConstraintOffsets[i].y = bodyCount[bodyIndexB];
  786. bodyCount[bodyIndexB]++;
  787. }
  788. }
  789. b3AlignedObjectArray<unsigned int> offsetSplitBodies;
  790. offsetSplitBodies.resize(numBodiesCPU);
  791. unsigned int totalNumSplitBodiesCPU;
  792. m_data->m_scan->executeHost(bodyCount,offsetSplitBodies,numBodiesCPU,&totalNumSplitBodiesCPU);
  793. int numlastBody = bodyCount[numBodiesCPU-1];
  794. totalNumSplitBodiesCPU += numlastBody;
  795. int numBodies = bodiesGPU->size();
  796. int numManifolds = manifoldPtrGPU->size();
  797. m_data->m_bodyCount->resize(numBodies);
  798. unsigned int val=0;
  799. b3Int2 val2;
  800. val2.x=0;
  801. val2.y=0;
  802. {
  803. B3_PROFILE("m_filler");
  804. m_data->m_contactConstraintOffsets->resize(numManifolds);
  805. m_data->m_filler->execute(*m_data->m_bodyCount,val,numBodies);
  806. m_data->m_filler->execute(*m_data->m_contactConstraintOffsets,val2,numManifolds);
  807. }
  808. {
  809. B3_PROFILE("m_countBodiesKernel");
  810. b3LauncherCL launcher(this->m_queue,m_data->m_countBodiesKernel);
  811. launcher.setBuffer(manifoldPtrGPU->getBufferCL());
  812. launcher.setBuffer(m_data->m_bodyCount->getBufferCL());
  813. launcher.setBuffer(m_data->m_contactConstraintOffsets->getBufferCL());
  814. launcher.setConst(numManifolds);
  815. launcher.setConst(solverInfo.m_fixedBodyIndex);
  816. launcher.launch1D(numManifolds);
  817. }
  818. unsigned int totalNumSplitBodies=0;
  819. m_data->m_offsetSplitBodies->resize(numBodies);
  820. m_data->m_scan->execute(*m_data->m_bodyCount,*m_data->m_offsetSplitBodies,numBodies,&totalNumSplitBodies);
  821. totalNumSplitBodies+=m_data->m_bodyCount->at(numBodies-1);
  822. if (totalNumSplitBodies != totalNumSplitBodiesCPU)
  823. {
  824. printf("error in totalNumSplitBodies!\n");
  825. }
  826. int numContacts = manifoldPtrGPU->size();
  827. m_data->m_contactConstraints->resize(numContacts);
  828. {
  829. B3_PROFILE("contactToConstraintSplitKernel");
  830. b3LauncherCL launcher( m_queue, m_data->m_contactToConstraintSplitKernel);
  831. launcher.setBuffer(manifoldPtrGPU->getBufferCL());
  832. launcher.setBuffer(bodiesGPU->getBufferCL());
  833. launcher.setBuffer(inertiasGPU->getBufferCL());
  834. launcher.setBuffer(m_data->m_contactConstraints->getBufferCL());
  835. launcher.setBuffer(m_data->m_bodyCount->getBufferCL());
  836. launcher.setConst(numContacts);
  837. launcher.setConst(solverInfo.m_deltaTime);
  838. launcher.setConst(solverInfo.m_positionDrift);
  839. launcher.setConst(solverInfo.m_positionConstraintCoeff);
  840. launcher.launch1D( numContacts, 64 );
  841. clFinish(m_queue);
  842. }
  843. b3AlignedObjectArray<b3GpuConstraint4> contactConstraints;
  844. contactConstraints.resize(numManifoldsCPU);
  845. for (int i=0;i<numManifoldsCPU;i++)
  846. {
  847. ContactToConstraintKernel(&manifoldPtrCPU[0],&bodiesCPU[0],&inertiasCPU[0],&contactConstraints[0],numManifoldsCPU,
  848. solverInfo.m_deltaTime,
  849. solverInfo.m_positionDrift,
  850. solverInfo.m_positionConstraintCoeff,
  851. i, bodyCount);
  852. }
  853. int maxIter = solverInfo.m_numIterations;
  854. b3AlignedObjectArray<b3Vector3> deltaLinearVelocities;
  855. b3AlignedObjectArray<b3Vector3> deltaAngularVelocities;
  856. deltaLinearVelocities.resize(totalNumSplitBodiesCPU);
  857. deltaAngularVelocities.resize(totalNumSplitBodiesCPU);
  858. for (int i=0;i<totalNumSplitBodiesCPU;i++)
  859. {
  860. deltaLinearVelocities[i].setZero();
  861. deltaAngularVelocities[i].setZero();
  862. }
  863. m_data->m_deltaLinearVelocities->resize(totalNumSplitBodies);
  864. m_data->m_deltaAngularVelocities->resize(totalNumSplitBodies);
  865. {
  866. B3_PROFILE("m_clearVelocitiesKernel");
  867. b3LauncherCL launch(m_queue,m_data->m_clearVelocitiesKernel);
  868. launch.setBuffer(m_data->m_deltaAngularVelocities->getBufferCL());
  869. launch.setBuffer(m_data->m_deltaLinearVelocities->getBufferCL());
  870. launch.setConst(totalNumSplitBodies);
  871. launch.launch1D(totalNumSplitBodies);
  872. }
  873. ///!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  874. m_data->m_contactConstraints->copyToHost(contactConstraints);
  875. m_data->m_offsetSplitBodies->copyToHost(offsetSplitBodies);
  876. m_data->m_contactConstraintOffsets->copyToHost(contactConstraintOffsets);
  877. m_data->m_deltaLinearVelocities->copyToHost(deltaLinearVelocities);
  878. m_data->m_deltaAngularVelocities->copyToHost(deltaAngularVelocities);
  879. for (int iter = 0;iter<maxIter;iter++)
  880. {
  881. {
  882. B3_PROFILE("m_solveContactKernel");
  883. b3LauncherCL launcher( m_queue, m_data->m_solveContactKernel );
  884. launcher.setBuffer(m_data->m_contactConstraints->getBufferCL());
  885. launcher.setBuffer(bodiesGPU->getBufferCL());
  886. launcher.setBuffer(inertiasGPU->getBufferCL());
  887. launcher.setBuffer(m_data->m_contactConstraintOffsets->getBufferCL());
  888. launcher.setBuffer(m_data->m_offsetSplitBodies->getBufferCL());
  889. launcher.setBuffer(m_data->m_deltaLinearVelocities->getBufferCL());
  890. launcher.setBuffer(m_data->m_deltaAngularVelocities->getBufferCL());
  891. launcher.setConst(solverInfo.m_deltaTime);
  892. launcher.setConst(solverInfo.m_positionDrift);
  893. launcher.setConst(solverInfo.m_positionConstraintCoeff);
  894. launcher.setConst(solverInfo.m_fixedBodyIndex);
  895. launcher.setConst(numManifolds);
  896. launcher.launch1D(numManifolds);
  897. clFinish(m_queue);
  898. }
  899. int i=0;
  900. for( i=0; i<numManifoldsCPU; i++)
  901. {
  902. float frictionCoeff = contactConstraints[i].getFrictionCoeff();
  903. int aIdx = (int)contactConstraints[i].m_bodyA;
  904. int bIdx = (int)contactConstraints[i].m_bodyB;
  905. b3RigidBodyData& bodyA = bodiesCPU[aIdx];
  906. b3RigidBodyData& bodyB = bodiesCPU[bIdx];
  907. b3Vector3 zero(0,0,0);
  908. b3Vector3* dlvAPtr=&zero;
  909. b3Vector3* davAPtr=&zero;
  910. b3Vector3* dlvBPtr=&zero;
  911. b3Vector3* davBPtr=&zero;
  912. if (bodyA.m_invMass)
  913. {
  914. int bodyOffsetA = offsetSplitBodies[aIdx];
  915. int constraintOffsetA = contactConstraintOffsets[i].x;
  916. int splitIndexA = bodyOffsetA+constraintOffsetA;
  917. dlvAPtr = &deltaLinearVelocities[splitIndexA];
  918. davAPtr = &deltaAngularVelocities[splitIndexA];
  919. }
  920. if (bodyB.m_invMass)
  921. {
  922. int bodyOffsetB = offsetSplitBodies[bIdx];
  923. int constraintOffsetB = contactConstraintOffsets[i].y;
  924. int splitIndexB= bodyOffsetB+constraintOffsetB;
  925. dlvBPtr =&deltaLinearVelocities[splitIndexB];
  926. davBPtr = &deltaAngularVelocities[splitIndexB];
  927. }
  928. {
  929. float maxRambdaDt[4] = {FLT_MAX,FLT_MAX,FLT_MAX,FLT_MAX};
  930. float minRambdaDt[4] = {0.f,0.f,0.f,0.f};
  931. solveContact( contactConstraints[i], (b3Vector3&)bodyA.m_pos, (b3Vector3&)bodyA.m_linVel, (b3Vector3&)bodyA.m_angVel, bodyA.m_invMass, inertiasCPU[aIdx].m_invInertiaWorld,
  932. (b3Vector3&)bodyB.m_pos, (b3Vector3&)bodyB.m_linVel, (b3Vector3&)bodyB.m_angVel, bodyB.m_invMass, inertiasCPU[bIdx].m_invInertiaWorld,
  933. maxRambdaDt, minRambdaDt , *dlvAPtr,*davAPtr,*dlvBPtr,*davBPtr );
  934. }
  935. }
  936. {
  937. B3_PROFILE("average velocities");
  938. b3LauncherCL launcher( m_queue, m_data->m_averageVelocitiesKernel);
  939. launcher.setBuffer(bodiesGPU->getBufferCL());
  940. launcher.setBuffer(m_data->m_offsetSplitBodies->getBufferCL());
  941. launcher.setBuffer(m_data->m_bodyCount->getBufferCL());
  942. launcher.setBuffer(m_data->m_deltaLinearVelocities->getBufferCL());
  943. launcher.setBuffer(m_data->m_deltaAngularVelocities->getBufferCL());
  944. launcher.setConst(numBodies);
  945. launcher.launch1D(numBodies);
  946. clFinish(m_queue);
  947. }
  948. //easy
  949. for (int i=0;i<numBodiesCPU;i++)
  950. {
  951. if (bodiesCPU[i].m_invMass)
  952. {
  953. int bodyOffset = offsetSplitBodies[i];
  954. int count = bodyCount[i];
  955. float factor = 1.f/float(count);
  956. b3Vector3 averageLinVel;
  957. averageLinVel.setZero();
  958. b3Vector3 averageAngVel;
  959. averageAngVel.setZero();
  960. for (int j=0;j<count;j++)
  961. {
  962. averageLinVel += deltaLinearVelocities[bodyOffset+j]*factor;
  963. averageAngVel += deltaAngularVelocities[bodyOffset+j]*factor;
  964. }
  965. for (int j=0;j<count;j++)
  966. {
  967. deltaLinearVelocities[bodyOffset+j] = averageLinVel;
  968. deltaAngularVelocities[bodyOffset+j] = averageAngVel;
  969. }
  970. }
  971. }
  972. // m_data->m_deltaAngularVelocities->copyFromHost(deltaAngularVelocities);
  973. //m_data->m_deltaLinearVelocities->copyFromHost(deltaLinearVelocities);
  974. m_data->m_deltaAngularVelocities->copyToHost(deltaAngularVelocities);
  975. m_data->m_deltaLinearVelocities->copyToHost(deltaLinearVelocities);
  976. #if 0
  977. {
  978. B3_PROFILE("m_solveFrictionKernel");
  979. b3LauncherCL launcher( m_queue, m_data->m_solveFrictionKernel);
  980. launcher.setBuffer(m_data->m_contactConstraints->getBufferCL());
  981. launcher.setBuffer(bodiesGPU->getBufferCL());
  982. launcher.setBuffer(inertiasGPU->getBufferCL());
  983. launcher.setBuffer(m_data->m_contactConstraintOffsets->getBufferCL());
  984. launcher.setBuffer(m_data->m_offsetSplitBodies->getBufferCL());
  985. launcher.setBuffer(m_data->m_deltaLinearVelocities->getBufferCL());
  986. launcher.setBuffer(m_data->m_deltaAngularVelocities->getBufferCL());
  987. launcher.setConst(solverInfo.m_deltaTime);
  988. launcher.setConst(solverInfo.m_positionDrift);
  989. launcher.setConst(solverInfo.m_positionConstraintCoeff);
  990. launcher.setConst(solverInfo.m_fixedBodyIndex);
  991. launcher.setConst(numManifolds);
  992. launcher.launch1D(numManifolds);
  993. clFinish(m_queue);
  994. }
  995. //solve friction
  996. for(int i=0; i<numManifoldsCPU; i++)
  997. {
  998. float maxRambdaDt[4] = {FLT_MAX,FLT_MAX,FLT_MAX,FLT_MAX};
  999. float minRambdaDt[4] = {0.f,0.f,0.f,0.f};
  1000. float sum = 0;
  1001. for(int j=0; j<4; j++)
  1002. {
  1003. sum +=contactConstraints[i].m_appliedRambdaDt[j];
  1004. }
  1005. float frictionCoeff = contactConstraints[i].getFrictionCoeff();
  1006. int aIdx = (int)contactConstraints[i].m_bodyA;
  1007. int bIdx = (int)contactConstraints[i].m_bodyB;
  1008. b3RigidBodyData& bodyA = bodiesCPU[aIdx];
  1009. b3RigidBodyData& bodyB = bodiesCPU[bIdx];
  1010. b3Vector3 zero(0,0,0);
  1011. b3Vector3* dlvAPtr=&zero;
  1012. b3Vector3* davAPtr=&zero;
  1013. b3Vector3* dlvBPtr=&zero;
  1014. b3Vector3* davBPtr=&zero;
  1015. if (bodyA.m_invMass)
  1016. {
  1017. int bodyOffsetA = offsetSplitBodies[aIdx];
  1018. int constraintOffsetA = contactConstraintOffsets[i].x;
  1019. int splitIndexA = bodyOffsetA+constraintOffsetA;
  1020. dlvAPtr = &deltaLinearVelocities[splitIndexA];
  1021. davAPtr = &deltaAngularVelocities[splitIndexA];
  1022. }
  1023. if (bodyB.m_invMass)
  1024. {
  1025. int bodyOffsetB = offsetSplitBodies[bIdx];
  1026. int constraintOffsetB = contactConstraintOffsets[i].y;
  1027. int splitIndexB= bodyOffsetB+constraintOffsetB;
  1028. dlvBPtr =&deltaLinearVelocities[splitIndexB];
  1029. davBPtr = &deltaAngularVelocities[splitIndexB];
  1030. }
  1031. for(int j=0; j<4; j++)
  1032. {
  1033. maxRambdaDt[j] = frictionCoeff*sum;
  1034. minRambdaDt[j] = -maxRambdaDt[j];
  1035. }
  1036. solveFriction( contactConstraints[i], (b3Vector3&)bodyA.m_pos, (b3Vector3&)bodyA.m_linVel, (b3Vector3&)bodyA.m_angVel, bodyA.m_invMass,inertiasCPU[aIdx].m_invInertiaWorld,
  1037. (b3Vector3&)bodyB.m_pos, (b3Vector3&)bodyB.m_linVel, (b3Vector3&)bodyB.m_angVel, bodyB.m_invMass, inertiasCPU[bIdx].m_invInertiaWorld,
  1038. maxRambdaDt, minRambdaDt , *dlvAPtr,*davAPtr,*dlvBPtr,*davBPtr);
  1039. }
  1040. {
  1041. B3_PROFILE("average velocities");
  1042. b3LauncherCL launcher( m_queue, m_data->m_averageVelocitiesKernel);
  1043. launcher.setBuffer(bodiesGPU->getBufferCL());
  1044. launcher.setBuffer(m_data->m_offsetSplitBodies->getBufferCL());
  1045. launcher.setBuffer(m_data->m_bodyCount->getBufferCL());
  1046. launcher.setBuffer(m_data->m_deltaLinearVelocities->getBufferCL());
  1047. launcher.setBuffer(m_data->m_deltaAngularVelocities->getBufferCL());
  1048. launcher.setConst(numBodies);
  1049. launcher.launch1D(numBodies);
  1050. clFinish(m_queue);
  1051. }
  1052. //easy
  1053. for (int i=0;i<numBodiesCPU;i++)
  1054. {
  1055. if (bodiesCPU[i].m_invMass)
  1056. {
  1057. int bodyOffset = offsetSplitBodies[i];
  1058. int count = bodyCount[i];
  1059. float factor = 1.f/float(count);
  1060. b3Vector3 averageLinVel;
  1061. averageLinVel.setZero();
  1062. b3Vector3 averageAngVel;
  1063. averageAngVel.setZero();
  1064. for (int j=0;j<count;j++)
  1065. {
  1066. averageLinVel += deltaLinearVelocities[bodyOffset+j]*factor;
  1067. averageAngVel += deltaAngularVelocities[bodyOffset+j]*factor;
  1068. }
  1069. for (int j=0;j<count;j++)
  1070. {
  1071. deltaLinearVelocities[bodyOffset+j] = averageLinVel;
  1072. deltaAngularVelocities[bodyOffset+j] = averageAngVel;
  1073. }
  1074. }
  1075. }
  1076. #endif
  1077. }
  1078. {
  1079. B3_PROFILE("update body velocities");
  1080. b3LauncherCL launcher( m_queue, m_data->m_updateBodyVelocitiesKernel);
  1081. launcher.setBuffer(bodiesGPU->getBufferCL());
  1082. launcher.setBuffer(m_data->m_offsetSplitBodies->getBufferCL());
  1083. launcher.setBuffer(m_data->m_bodyCount->getBufferCL());
  1084. launcher.setBuffer(m_data->m_deltaLinearVelocities->getBufferCL());
  1085. launcher.setBuffer(m_data->m_deltaAngularVelocities->getBufferCL());
  1086. launcher.setConst(numBodies);
  1087. launcher.launch1D(numBodies);
  1088. clFinish(m_queue);
  1089. }
  1090. //easy
  1091. for (int i=0;i<numBodiesCPU;i++)
  1092. {
  1093. if (bodiesCPU[i].m_invMass)
  1094. {
  1095. int bodyOffset = offsetSplitBodies[i];
  1096. int count = bodyCount[i];
  1097. if (count)
  1098. {
  1099. bodiesCPU[i].m_linVel += deltaLinearVelocities[bodyOffset];
  1100. bodiesCPU[i].m_angVel += deltaAngularVelocities[bodyOffset];
  1101. }
  1102. }
  1103. }
  1104. // bodiesGPU->copyFromHost(bodiesCPU);
  1105. }
  1106. #endif