btSequentialImpulseConstraintSolverMt.cpp 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555
  1. /*
  2. Bullet Continuous Collision Detection and Physics Library
  3. Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
  4. This software is provided 'as-is', without any express or implied warranty.
  5. In no event will the authors be held liable for any damages arising from the use of this software.
  6. Permission is granted to anyone to use this software for any purpose,
  7. including commercial applications, and to alter it and redistribute it freely,
  8. subject to the following restrictions:
  9. 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.
  10. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  11. 3. This notice may not be removed or altered from any source distribution.
  12. */
  13. #include "btSequentialImpulseConstraintSolverMt.h"
  14. #include "LinearMath/btQuickprof.h"
  15. #include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
  16. #include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
  17. #include "BulletDynamics/Dynamics/btRigidBody.h"
  18. bool btSequentialImpulseConstraintSolverMt::s_allowNestedParallelForLoops = false; // some task schedulers don't like nested loops
  19. int btSequentialImpulseConstraintSolverMt::s_minimumContactManifoldsForBatching = 250;
  20. int btSequentialImpulseConstraintSolverMt::s_minBatchSize = 50;
  21. int btSequentialImpulseConstraintSolverMt::s_maxBatchSize = 100;
  22. btBatchedConstraints::BatchingMethod btSequentialImpulseConstraintSolverMt::s_contactBatchingMethod = btBatchedConstraints::BATCHING_METHOD_SPATIAL_GRID_2D;
  23. btBatchedConstraints::BatchingMethod btSequentialImpulseConstraintSolverMt::s_jointBatchingMethod = btBatchedConstraints::BATCHING_METHOD_SPATIAL_GRID_2D;
  24. btSequentialImpulseConstraintSolverMt::btSequentialImpulseConstraintSolverMt()
  25. {
  26. m_numFrictionDirections = 1;
  27. m_useBatching = false;
  28. m_useObsoleteJointConstraints = false;
  29. }
  30. btSequentialImpulseConstraintSolverMt::~btSequentialImpulseConstraintSolverMt()
  31. {
  32. }
  33. void btSequentialImpulseConstraintSolverMt::setupBatchedContactConstraints()
  34. {
  35. BT_PROFILE("setupBatchedContactConstraints");
  36. m_batchedContactConstraints.setup(&m_tmpSolverContactConstraintPool,
  37. m_tmpSolverBodyPool,
  38. s_contactBatchingMethod,
  39. s_minBatchSize,
  40. s_maxBatchSize,
  41. &m_scratchMemory);
  42. }
  43. void btSequentialImpulseConstraintSolverMt::setupBatchedJointConstraints()
  44. {
  45. BT_PROFILE("setupBatchedJointConstraints");
  46. m_batchedJointConstraints.setup(&m_tmpSolverNonContactConstraintPool,
  47. m_tmpSolverBodyPool,
  48. s_jointBatchingMethod,
  49. s_minBatchSize,
  50. s_maxBatchSize,
  51. &m_scratchMemory);
  52. }
  53. void btSequentialImpulseConstraintSolverMt::internalSetupContactConstraints(int iContactConstraint, const btContactSolverInfo& infoGlobal)
  54. {
  55. btSolverConstraint& contactConstraint = m_tmpSolverContactConstraintPool[iContactConstraint];
  56. btVector3 rel_pos1;
  57. btVector3 rel_pos2;
  58. btScalar relaxation;
  59. int solverBodyIdA = contactConstraint.m_solverBodyIdA;
  60. int solverBodyIdB = contactConstraint.m_solverBodyIdB;
  61. btSolverBody* solverBodyA = &m_tmpSolverBodyPool[solverBodyIdA];
  62. btSolverBody* solverBodyB = &m_tmpSolverBodyPool[solverBodyIdB];
  63. btRigidBody* colObj0 = solverBodyA->m_originalBody;
  64. btRigidBody* colObj1 = solverBodyB->m_originalBody;
  65. btManifoldPoint& cp = *static_cast<btManifoldPoint*>(contactConstraint.m_originalContactPoint);
  66. const btVector3& pos1 = cp.getPositionWorldOnA();
  67. const btVector3& pos2 = cp.getPositionWorldOnB();
  68. rel_pos1 = pos1 - solverBodyA->getWorldTransform().getOrigin();
  69. rel_pos2 = pos2 - solverBodyB->getWorldTransform().getOrigin();
  70. btVector3 vel1;
  71. btVector3 vel2;
  72. solverBodyA->getVelocityInLocalPointNoDelta(rel_pos1, vel1);
  73. solverBodyB->getVelocityInLocalPointNoDelta(rel_pos2, vel2);
  74. btVector3 vel = vel1 - vel2;
  75. btScalar rel_vel = cp.m_normalWorldOnB.dot(vel);
  76. setupContactConstraint(contactConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal, relaxation, rel_pos1, rel_pos2);
  77. // setup rolling friction constraints
  78. int rollingFrictionIndex = m_rollingFrictionIndexTable[iContactConstraint];
  79. if (rollingFrictionIndex >= 0)
  80. {
  81. btSolverConstraint& spinningFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[rollingFrictionIndex];
  82. btAssert(spinningFrictionConstraint.m_frictionIndex == iContactConstraint);
  83. setupTorsionalFrictionConstraint(spinningFrictionConstraint,
  84. cp.m_normalWorldOnB,
  85. solverBodyIdA,
  86. solverBodyIdB,
  87. cp,
  88. cp.m_combinedSpinningFriction,
  89. rel_pos1,
  90. rel_pos2,
  91. colObj0,
  92. colObj1,
  93. relaxation,
  94. 0.0f,
  95. 0.0f);
  96. btVector3 axis[2];
  97. btPlaneSpace1(cp.m_normalWorldOnB, axis[0], axis[1]);
  98. axis[0].normalize();
  99. axis[1].normalize();
  100. applyAnisotropicFriction(colObj0, axis[0], btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
  101. applyAnisotropicFriction(colObj1, axis[0], btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
  102. applyAnisotropicFriction(colObj0, axis[1], btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
  103. applyAnisotropicFriction(colObj1, axis[1], btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
  104. // put the largest axis first
  105. if (axis[1].length2() > axis[0].length2())
  106. {
  107. btSwap(axis[0], axis[1]);
  108. }
  109. const btScalar kRollingFrictionThreshold = 0.001f;
  110. for (int i = 0; i < 2; ++i)
  111. {
  112. int iRollingFric = rollingFrictionIndex + 1 + i;
  113. btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[iRollingFric];
  114. btAssert(rollingFrictionConstraint.m_frictionIndex == iContactConstraint);
  115. btVector3 dir = axis[i];
  116. if (dir.length() > kRollingFrictionThreshold)
  117. {
  118. setupTorsionalFrictionConstraint(rollingFrictionConstraint,
  119. dir,
  120. solverBodyIdA,
  121. solverBodyIdB,
  122. cp,
  123. cp.m_combinedRollingFriction,
  124. rel_pos1,
  125. rel_pos2,
  126. colObj0,
  127. colObj1,
  128. relaxation,
  129. 0.0f,
  130. 0.0f);
  131. }
  132. else
  133. {
  134. rollingFrictionConstraint.m_frictionIndex = -1; // disable constraint
  135. }
  136. }
  137. }
  138. // setup friction constraints
  139. // setupFrictionConstraint(solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, desiredVelocity, cfmSlip);
  140. {
  141. ///Bullet has several options to set the friction directions
  142. ///By default, each contact has only a single friction direction that is recomputed automatically very frame
  143. ///based on the relative linear velocity.
  144. ///If the relative velocity it zero, it will automatically compute a friction direction.
  145. ///You can also enable two friction directions, using the SOLVER_USE_2_FRICTION_DIRECTIONS.
  146. ///In that case, the second friction direction will be orthogonal to both contact normal and first friction direction.
  147. ///
  148. ///If you choose SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION, then the friction will be independent from the relative projected velocity.
  149. ///
  150. ///The user can manually override the friction directions for certain contacts using a contact callback,
  151. ///and set the cp.m_lateralFrictionInitialized to true
  152. ///In that case, you can set the target relative motion in each friction direction (cp.m_contactMotion1 and cp.m_contactMotion2)
  153. ///this will give a conveyor belt effect
  154. ///
  155. btSolverConstraint* frictionConstraint1 = &m_tmpSolverContactFrictionConstraintPool[contactConstraint.m_frictionIndex];
  156. btAssert(frictionConstraint1->m_frictionIndex == iContactConstraint);
  157. btSolverConstraint* frictionConstraint2 = NULL;
  158. if (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)
  159. {
  160. frictionConstraint2 = &m_tmpSolverContactFrictionConstraintPool[contactConstraint.m_frictionIndex + 1];
  161. btAssert(frictionConstraint2->m_frictionIndex == iContactConstraint);
  162. }
  163. if (!(infoGlobal.m_solverMode & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING) || !(cp.m_contactPointFlags & BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED))
  164. {
  165. cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel;
  166. btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2();
  167. if (!(infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION) && lat_rel_vel > SIMD_EPSILON)
  168. {
  169. cp.m_lateralFrictionDir1 *= 1.f / btSqrt(lat_rel_vel);
  170. applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION);
  171. applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION);
  172. setupFrictionConstraint(*frictionConstraint1, cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal);
  173. if (frictionConstraint2)
  174. {
  175. cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB);
  176. cp.m_lateralFrictionDir2.normalize(); //??
  177. applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION);
  178. applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION);
  179. setupFrictionConstraint(*frictionConstraint2, cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal);
  180. }
  181. }
  182. else
  183. {
  184. btPlaneSpace1(cp.m_normalWorldOnB, cp.m_lateralFrictionDir1, cp.m_lateralFrictionDir2);
  185. applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION);
  186. applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION);
  187. setupFrictionConstraint(*frictionConstraint1, cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal);
  188. if (frictionConstraint2)
  189. {
  190. applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION);
  191. applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION);
  192. setupFrictionConstraint(*frictionConstraint2, cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal);
  193. }
  194. if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) && (infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION))
  195. {
  196. cp.m_contactPointFlags |= BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED;
  197. }
  198. }
  199. }
  200. else
  201. {
  202. setupFrictionConstraint(*frictionConstraint1, cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, cp.m_contactMotion1, cp.m_frictionCFM);
  203. if (frictionConstraint2)
  204. {
  205. setupFrictionConstraint(*frictionConstraint2, cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, cp.m_contactMotion2, cp.m_frictionCFM);
  206. }
  207. }
  208. }
  209. setFrictionConstraintImpulse(contactConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal);
  210. }
  211. struct SetupContactConstraintsLoop : public btIParallelForBody
  212. {
  213. btSequentialImpulseConstraintSolverMt* m_solver;
  214. const btBatchedConstraints* m_bc;
  215. const btContactSolverInfo* m_infoGlobal;
  216. SetupContactConstraintsLoop(btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc, const btContactSolverInfo& infoGlobal)
  217. {
  218. m_solver = solver;
  219. m_bc = bc;
  220. m_infoGlobal = &infoGlobal;
  221. }
  222. void forLoop(int iBegin, int iEnd) const BT_OVERRIDE
  223. {
  224. BT_PROFILE("SetupContactConstraintsLoop");
  225. for (int iBatch = iBegin; iBatch < iEnd; ++iBatch)
  226. {
  227. const btBatchedConstraints::Range& batch = m_bc->m_batches[iBatch];
  228. for (int i = batch.begin; i < batch.end; ++i)
  229. {
  230. int iContact = m_bc->m_constraintIndices[i];
  231. m_solver->internalSetupContactConstraints(iContact, *m_infoGlobal);
  232. }
  233. }
  234. }
  235. };
  236. void btSequentialImpulseConstraintSolverMt::setupAllContactConstraints(const btContactSolverInfo& infoGlobal)
  237. {
  238. BT_PROFILE("setupAllContactConstraints");
  239. if (m_useBatching)
  240. {
  241. const btBatchedConstraints& batchedCons = m_batchedContactConstraints;
  242. SetupContactConstraintsLoop loop(this, &batchedCons, infoGlobal);
  243. for (int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase)
  244. {
  245. int iPhase = batchedCons.m_phaseOrder[iiPhase];
  246. const btBatchedConstraints::Range& phase = batchedCons.m_phases[iPhase];
  247. int grainSize = 1;
  248. btParallelFor(phase.begin, phase.end, grainSize, loop);
  249. }
  250. }
  251. else
  252. {
  253. for (int i = 0; i < m_tmpSolverContactConstraintPool.size(); ++i)
  254. {
  255. internalSetupContactConstraints(i, infoGlobal);
  256. }
  257. }
  258. }
  259. int btSequentialImpulseConstraintSolverMt::getOrInitSolverBodyThreadsafe(btCollisionObject& body, btScalar timeStep)
  260. {
  261. //
  262. // getOrInitSolverBody is threadsafe only for a single thread per solver (with potentially multiple solvers)
  263. //
  264. // getOrInitSolverBodyThreadsafe -- attempts to be fully threadsafe (however may affect determinism)
  265. //
  266. int solverBodyId = -1;
  267. bool isRigidBodyType = btRigidBody::upcast(&body) != NULL;
  268. if (isRigidBodyType && !body.isStaticOrKinematicObject())
  269. {
  270. // dynamic body
  271. // Dynamic bodies can only be in one island, so it's safe to write to the companionId
  272. solverBodyId = body.getCompanionId();
  273. if (solverBodyId < 0)
  274. {
  275. m_bodySolverArrayMutex.lock();
  276. // now that we have the lock, check again
  277. solverBodyId = body.getCompanionId();
  278. if (solverBodyId < 0)
  279. {
  280. solverBodyId = m_tmpSolverBodyPool.size();
  281. btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
  282. initSolverBody(&solverBody, &body, timeStep);
  283. body.setCompanionId(solverBodyId);
  284. }
  285. m_bodySolverArrayMutex.unlock();
  286. }
  287. }
  288. else if (isRigidBodyType && body.isKinematicObject())
  289. {
  290. //
  291. // NOTE: must test for kinematic before static because some kinematic objects also
  292. // identify as "static"
  293. //
  294. // Kinematic bodies can be in multiple islands at once, so it is a
  295. // race condition to write to them, so we use an alternate method
  296. // to record the solverBodyId
  297. int uniqueId = body.getWorldArrayIndex();
  298. const int INVALID_SOLVER_BODY_ID = -1;
  299. if (m_kinematicBodyUniqueIdToSolverBodyTable.size() <= uniqueId)
  300. {
  301. m_kinematicBodyUniqueIdToSolverBodyTableMutex.lock();
  302. // now that we have the lock, check again
  303. if (m_kinematicBodyUniqueIdToSolverBodyTable.size() <= uniqueId)
  304. {
  305. m_kinematicBodyUniqueIdToSolverBodyTable.resize(uniqueId + 1, INVALID_SOLVER_BODY_ID);
  306. }
  307. m_kinematicBodyUniqueIdToSolverBodyTableMutex.unlock();
  308. }
  309. solverBodyId = m_kinematicBodyUniqueIdToSolverBodyTable[uniqueId];
  310. // if no table entry yet,
  311. if (INVALID_SOLVER_BODY_ID == solverBodyId)
  312. {
  313. // need to acquire both locks
  314. m_kinematicBodyUniqueIdToSolverBodyTableMutex.lock();
  315. m_bodySolverArrayMutex.lock();
  316. // now that we have the lock, check again
  317. solverBodyId = m_kinematicBodyUniqueIdToSolverBodyTable[uniqueId];
  318. if (INVALID_SOLVER_BODY_ID == solverBodyId)
  319. {
  320. // create a table entry for this body
  321. solverBodyId = m_tmpSolverBodyPool.size();
  322. btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
  323. initSolverBody(&solverBody, &body, timeStep);
  324. m_kinematicBodyUniqueIdToSolverBodyTable[uniqueId] = solverBodyId;
  325. }
  326. m_bodySolverArrayMutex.unlock();
  327. m_kinematicBodyUniqueIdToSolverBodyTableMutex.unlock();
  328. }
  329. }
  330. else
  331. {
  332. // all fixed bodies (inf mass) get mapped to a single solver id
  333. if (m_fixedBodyId < 0)
  334. {
  335. m_bodySolverArrayMutex.lock();
  336. // now that we have the lock, check again
  337. if (m_fixedBodyId < 0)
  338. {
  339. m_fixedBodyId = m_tmpSolverBodyPool.size();
  340. btSolverBody& fixedBody = m_tmpSolverBodyPool.expand();
  341. initSolverBody(&fixedBody, 0, timeStep);
  342. }
  343. m_bodySolverArrayMutex.unlock();
  344. }
  345. solverBodyId = m_fixedBodyId;
  346. }
  347. btAssert(solverBodyId >= 0 && solverBodyId < m_tmpSolverBodyPool.size());
  348. return solverBodyId;
  349. }
  350. void btSequentialImpulseConstraintSolverMt::internalCollectContactManifoldCachedInfo(btContactManifoldCachedInfo* cachedInfoArray, btPersistentManifold** manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal)
  351. {
  352. BT_PROFILE("internalCollectContactManifoldCachedInfo");
  353. for (int i = 0; i < numManifolds; ++i)
  354. {
  355. btContactManifoldCachedInfo* cachedInfo = &cachedInfoArray[i];
  356. btPersistentManifold* manifold = manifoldPtr[i];
  357. btCollisionObject* colObj0 = (btCollisionObject*)manifold->getBody0();
  358. btCollisionObject* colObj1 = (btCollisionObject*)manifold->getBody1();
  359. int solverBodyIdA = getOrInitSolverBodyThreadsafe(*colObj0, infoGlobal.m_timeStep);
  360. int solverBodyIdB = getOrInitSolverBodyThreadsafe(*colObj1, infoGlobal.m_timeStep);
  361. cachedInfo->solverBodyIds[0] = solverBodyIdA;
  362. cachedInfo->solverBodyIds[1] = solverBodyIdB;
  363. cachedInfo->numTouchingContacts = 0;
  364. btSolverBody* solverBodyA = &m_tmpSolverBodyPool[solverBodyIdA];
  365. btSolverBody* solverBodyB = &m_tmpSolverBodyPool[solverBodyIdB];
  366. // A contact manifold between 2 static object should not exist!
  367. // check the collision flags of your objects if this assert fires.
  368. // Incorrectly set collision object flags can degrade performance in various ways.
  369. btAssert(!m_tmpSolverBodyPool[solverBodyIdA].m_invMass.isZero() || !m_tmpSolverBodyPool[solverBodyIdB].m_invMass.isZero());
  370. int iContact = 0;
  371. for (int j = 0; j < manifold->getNumContacts(); j++)
  372. {
  373. btManifoldPoint& cp = manifold->getContactPoint(j);
  374. if (cp.getDistance() <= manifold->getContactProcessingThreshold())
  375. {
  376. cachedInfo->contactPoints[iContact] = &cp;
  377. cachedInfo->contactHasRollingFriction[iContact] = (cp.m_combinedRollingFriction > 0.f);
  378. iContact++;
  379. }
  380. }
  381. cachedInfo->numTouchingContacts = iContact;
  382. }
  383. }
  384. struct CollectContactManifoldCachedInfoLoop : public btIParallelForBody
  385. {
  386. btSequentialImpulseConstraintSolverMt* m_solver;
  387. btSequentialImpulseConstraintSolverMt::btContactManifoldCachedInfo* m_cachedInfoArray;
  388. btPersistentManifold** m_manifoldPtr;
  389. const btContactSolverInfo* m_infoGlobal;
  390. CollectContactManifoldCachedInfoLoop(btSequentialImpulseConstraintSolverMt* solver, btSequentialImpulseConstraintSolverMt::btContactManifoldCachedInfo* cachedInfoArray, btPersistentManifold** manifoldPtr, const btContactSolverInfo& infoGlobal)
  391. {
  392. m_solver = solver;
  393. m_cachedInfoArray = cachedInfoArray;
  394. m_manifoldPtr = manifoldPtr;
  395. m_infoGlobal = &infoGlobal;
  396. }
  397. void forLoop(int iBegin, int iEnd) const BT_OVERRIDE
  398. {
  399. m_solver->internalCollectContactManifoldCachedInfo(m_cachedInfoArray + iBegin, m_manifoldPtr + iBegin, iEnd - iBegin, *m_infoGlobal);
  400. }
  401. };
  402. void btSequentialImpulseConstraintSolverMt::internalAllocContactConstraints(const btContactManifoldCachedInfo* cachedInfoArray, int numManifolds)
  403. {
  404. BT_PROFILE("internalAllocContactConstraints");
  405. // possibly parallel part
  406. for (int iManifold = 0; iManifold < numManifolds; ++iManifold)
  407. {
  408. const btContactManifoldCachedInfo& cachedInfo = cachedInfoArray[iManifold];
  409. int contactIndex = cachedInfo.contactIndex;
  410. int frictionIndex = contactIndex * m_numFrictionDirections;
  411. int rollingFrictionIndex = cachedInfo.rollingFrictionIndex;
  412. for (int i = 0; i < cachedInfo.numTouchingContacts; i++)
  413. {
  414. btSolverConstraint& contactConstraint = m_tmpSolverContactConstraintPool[contactIndex];
  415. contactConstraint.m_solverBodyIdA = cachedInfo.solverBodyIds[0];
  416. contactConstraint.m_solverBodyIdB = cachedInfo.solverBodyIds[1];
  417. contactConstraint.m_originalContactPoint = cachedInfo.contactPoints[i];
  418. // allocate the friction constraints
  419. contactConstraint.m_frictionIndex = frictionIndex;
  420. for (int iDir = 0; iDir < m_numFrictionDirections; ++iDir)
  421. {
  422. btSolverConstraint& frictionConstraint = m_tmpSolverContactFrictionConstraintPool[frictionIndex];
  423. frictionConstraint.m_frictionIndex = contactIndex;
  424. frictionIndex++;
  425. }
  426. // allocate rolling friction constraints
  427. if (cachedInfo.contactHasRollingFriction[i])
  428. {
  429. m_rollingFrictionIndexTable[contactIndex] = rollingFrictionIndex;
  430. // allocate 3 (although we may use only 2 sometimes)
  431. for (int i = 0; i < 3; i++)
  432. {
  433. m_tmpSolverContactRollingFrictionConstraintPool[rollingFrictionIndex].m_frictionIndex = contactIndex;
  434. rollingFrictionIndex++;
  435. }
  436. }
  437. else
  438. {
  439. // indicate there is no rolling friction for this contact point
  440. m_rollingFrictionIndexTable[contactIndex] = -1;
  441. }
  442. contactIndex++;
  443. }
  444. }
  445. }
  446. struct AllocContactConstraintsLoop : public btIParallelForBody
  447. {
  448. btSequentialImpulseConstraintSolverMt* m_solver;
  449. const btSequentialImpulseConstraintSolverMt::btContactManifoldCachedInfo* m_cachedInfoArray;
  450. AllocContactConstraintsLoop(btSequentialImpulseConstraintSolverMt* solver, btSequentialImpulseConstraintSolverMt::btContactManifoldCachedInfo* cachedInfoArray)
  451. {
  452. m_solver = solver;
  453. m_cachedInfoArray = cachedInfoArray;
  454. }
  455. void forLoop(int iBegin, int iEnd) const BT_OVERRIDE
  456. {
  457. m_solver->internalAllocContactConstraints(m_cachedInfoArray + iBegin, iEnd - iBegin);
  458. }
  459. };
  460. void btSequentialImpulseConstraintSolverMt::allocAllContactConstraints(btPersistentManifold** manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal)
  461. {
  462. BT_PROFILE("allocAllContactConstraints");
  463. btAlignedObjectArray<btContactManifoldCachedInfo> cachedInfoArray; // = m_manifoldCachedInfoArray;
  464. cachedInfoArray.resizeNoInitialize(numManifolds);
  465. if (/* DISABLES CODE */ (false))
  466. {
  467. // sequential
  468. internalCollectContactManifoldCachedInfo(&cachedInfoArray[0], manifoldPtr, numManifolds, infoGlobal);
  469. }
  470. else
  471. {
  472. // may alter ordering of bodies which affects determinism
  473. CollectContactManifoldCachedInfoLoop loop(this, &cachedInfoArray[0], manifoldPtr, infoGlobal);
  474. int grainSize = 200;
  475. btParallelFor(0, numManifolds, grainSize, loop);
  476. }
  477. {
  478. // serial part
  479. int numContacts = 0;
  480. int numRollingFrictionConstraints = 0;
  481. for (int iManifold = 0; iManifold < numManifolds; ++iManifold)
  482. {
  483. btContactManifoldCachedInfo& cachedInfo = cachedInfoArray[iManifold];
  484. cachedInfo.contactIndex = numContacts;
  485. cachedInfo.rollingFrictionIndex = numRollingFrictionConstraints;
  486. numContacts += cachedInfo.numTouchingContacts;
  487. for (int i = 0; i < cachedInfo.numTouchingContacts; ++i)
  488. {
  489. if (cachedInfo.contactHasRollingFriction[i])
  490. {
  491. numRollingFrictionConstraints += 3;
  492. }
  493. }
  494. }
  495. {
  496. BT_PROFILE("allocPools");
  497. if (m_tmpSolverContactConstraintPool.capacity() < numContacts)
  498. {
  499. // if we need to reallocate, reserve some extra so we don't have to reallocate again next frame
  500. int extraReserve = numContacts / 16;
  501. m_tmpSolverContactConstraintPool.reserve(numContacts + extraReserve);
  502. m_rollingFrictionIndexTable.reserve(numContacts + extraReserve);
  503. m_tmpSolverContactFrictionConstraintPool.reserve((numContacts + extraReserve) * m_numFrictionDirections);
  504. m_tmpSolverContactRollingFrictionConstraintPool.reserve(numRollingFrictionConstraints + extraReserve);
  505. }
  506. m_tmpSolverContactConstraintPool.resizeNoInitialize(numContacts);
  507. m_rollingFrictionIndexTable.resizeNoInitialize(numContacts);
  508. m_tmpSolverContactFrictionConstraintPool.resizeNoInitialize(numContacts * m_numFrictionDirections);
  509. m_tmpSolverContactRollingFrictionConstraintPool.resizeNoInitialize(numRollingFrictionConstraints);
  510. }
  511. }
  512. {
  513. AllocContactConstraintsLoop loop(this, &cachedInfoArray[0]);
  514. int grainSize = 200;
  515. btParallelFor(0, numManifolds, grainSize, loop);
  516. }
  517. }
  518. void btSequentialImpulseConstraintSolverMt::convertContacts(btPersistentManifold** manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal)
  519. {
  520. if (!m_useBatching)
  521. {
  522. btSequentialImpulseConstraintSolver::convertContacts(manifoldPtr, numManifolds, infoGlobal);
  523. return;
  524. }
  525. BT_PROFILE("convertContacts");
  526. if (numManifolds > 0)
  527. {
  528. if (m_fixedBodyId < 0)
  529. {
  530. m_fixedBodyId = m_tmpSolverBodyPool.size();
  531. btSolverBody& fixedBody = m_tmpSolverBodyPool.expand();
  532. initSolverBody(&fixedBody, 0, infoGlobal.m_timeStep);
  533. }
  534. allocAllContactConstraints(manifoldPtr, numManifolds, infoGlobal);
  535. if (m_useBatching)
  536. {
  537. setupBatchedContactConstraints();
  538. }
  539. setupAllContactConstraints(infoGlobal);
  540. }
  541. }
  542. void btSequentialImpulseConstraintSolverMt::internalInitMultipleJoints(btTypedConstraint** constraints, int iBegin, int iEnd)
  543. {
  544. BT_PROFILE("internalInitMultipleJoints");
  545. for (int i = iBegin; i < iEnd; i++)
  546. {
  547. btTypedConstraint* constraint = constraints[i];
  548. btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
  549. if (constraint->isEnabled())
  550. {
  551. constraint->buildJacobian();
  552. constraint->internalSetAppliedImpulse(0.0f);
  553. btJointFeedback* fb = constraint->getJointFeedback();
  554. if (fb)
  555. {
  556. fb->m_appliedForceBodyA.setZero();
  557. fb->m_appliedTorqueBodyA.setZero();
  558. fb->m_appliedForceBodyB.setZero();
  559. fb->m_appliedTorqueBodyB.setZero();
  560. }
  561. constraint->getInfo1(&info1);
  562. }
  563. else
  564. {
  565. info1.m_numConstraintRows = 0;
  566. info1.nub = 0;
  567. }
  568. }
  569. }
  570. struct InitJointsLoop : public btIParallelForBody
  571. {
  572. btSequentialImpulseConstraintSolverMt* m_solver;
  573. btTypedConstraint** m_constraints;
  574. InitJointsLoop(btSequentialImpulseConstraintSolverMt* solver, btTypedConstraint** constraints)
  575. {
  576. m_solver = solver;
  577. m_constraints = constraints;
  578. }
  579. void forLoop(int iBegin, int iEnd) const BT_OVERRIDE
  580. {
  581. m_solver->internalInitMultipleJoints(m_constraints, iBegin, iEnd);
  582. }
  583. };
  584. void btSequentialImpulseConstraintSolverMt::internalConvertMultipleJoints(const btAlignedObjectArray<JointParams>& jointParamsArray, btTypedConstraint** constraints, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal)
  585. {
  586. BT_PROFILE("internalConvertMultipleJoints");
  587. for (int i = iBegin; i < iEnd; ++i)
  588. {
  589. const JointParams& jointParams = jointParamsArray[i];
  590. int currentRow = jointParams.m_solverConstraint;
  591. if (currentRow != -1)
  592. {
  593. const btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
  594. btAssert(currentRow < m_tmpSolverNonContactConstraintPool.size());
  595. btAssert(info1.m_numConstraintRows > 0);
  596. btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow];
  597. btTypedConstraint* constraint = constraints[i];
  598. convertJoint(currentConstraintRow, constraint, info1, jointParams.m_solverBodyA, jointParams.m_solverBodyB, infoGlobal);
  599. }
  600. }
  601. }
  602. struct ConvertJointsLoop : public btIParallelForBody
  603. {
  604. btSequentialImpulseConstraintSolverMt* m_solver;
  605. const btAlignedObjectArray<btSequentialImpulseConstraintSolverMt::JointParams>& m_jointParamsArray;
  606. btTypedConstraint** m_srcConstraints;
  607. const btContactSolverInfo& m_infoGlobal;
  608. ConvertJointsLoop(btSequentialImpulseConstraintSolverMt* solver,
  609. const btAlignedObjectArray<btSequentialImpulseConstraintSolverMt::JointParams>& jointParamsArray,
  610. btTypedConstraint** srcConstraints,
  611. const btContactSolverInfo& infoGlobal) : m_jointParamsArray(jointParamsArray),
  612. m_infoGlobal(infoGlobal)
  613. {
  614. m_solver = solver;
  615. m_srcConstraints = srcConstraints;
  616. }
  617. void forLoop(int iBegin, int iEnd) const BT_OVERRIDE
  618. {
  619. m_solver->internalConvertMultipleJoints(m_jointParamsArray, m_srcConstraints, iBegin, iEnd, m_infoGlobal);
  620. }
  621. };
  622. void btSequentialImpulseConstraintSolverMt::convertJoints(btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal)
  623. {
  624. if (!m_useBatching)
  625. {
  626. btSequentialImpulseConstraintSolver::convertJoints(constraints, numConstraints, infoGlobal);
  627. return;
  628. }
  629. BT_PROFILE("convertJoints");
  630. bool parallelJointSetup = true;
  631. m_tmpConstraintSizesPool.resizeNoInitialize(numConstraints);
  632. if (parallelJointSetup)
  633. {
  634. InitJointsLoop loop(this, constraints);
  635. int grainSize = 40;
  636. btParallelFor(0, numConstraints, grainSize, loop);
  637. }
  638. else
  639. {
  640. internalInitMultipleJoints(constraints, 0, numConstraints);
  641. }
  642. int totalNumRows = 0;
  643. btAlignedObjectArray<JointParams> jointParamsArray;
  644. jointParamsArray.resizeNoInitialize(numConstraints);
  645. //calculate the total number of contraint rows
  646. for (int i = 0; i < numConstraints; i++)
  647. {
  648. btTypedConstraint* constraint = constraints[i];
  649. JointParams& params = jointParamsArray[i];
  650. const btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
  651. if (info1.m_numConstraintRows)
  652. {
  653. params.m_solverConstraint = totalNumRows;
  654. params.m_solverBodyA = getOrInitSolverBody(constraint->getRigidBodyA(), infoGlobal.m_timeStep);
  655. params.m_solverBodyB = getOrInitSolverBody(constraint->getRigidBodyB(), infoGlobal.m_timeStep);
  656. }
  657. else
  658. {
  659. params.m_solverConstraint = -1;
  660. }
  661. totalNumRows += info1.m_numConstraintRows;
  662. }
  663. m_tmpSolverNonContactConstraintPool.resizeNoInitialize(totalNumRows);
  664. ///setup the btSolverConstraints
  665. if (parallelJointSetup)
  666. {
  667. ConvertJointsLoop loop(this, jointParamsArray, constraints, infoGlobal);
  668. int grainSize = 20;
  669. btParallelFor(0, numConstraints, grainSize, loop);
  670. }
  671. else
  672. {
  673. internalConvertMultipleJoints(jointParamsArray, constraints, 0, numConstraints, infoGlobal);
  674. }
  675. setupBatchedJointConstraints();
  676. }
  677. void btSequentialImpulseConstraintSolverMt::internalConvertBodies(btCollisionObject** bodies, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal)
  678. {
  679. BT_PROFILE("internalConvertBodies");
  680. for (int i = iBegin; i < iEnd; i++)
  681. {
  682. btCollisionObject* obj = bodies[i];
  683. obj->setCompanionId(i);
  684. btSolverBody& solverBody = m_tmpSolverBodyPool[i];
  685. initSolverBody(&solverBody, obj, infoGlobal.m_timeStep);
  686. btRigidBody* body = btRigidBody::upcast(obj);
  687. if (body && body->getInvMass())
  688. {
  689. btVector3 gyroForce(0, 0, 0);
  690. if (body->getFlags() & BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT)
  691. {
  692. gyroForce = body->computeGyroscopicForceExplicit(infoGlobal.m_maxGyroscopicForce);
  693. solverBody.m_externalTorqueImpulse -= gyroForce * body->getInvInertiaTensorWorld() * infoGlobal.m_timeStep;
  694. }
  695. if (body->getFlags() & BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD)
  696. {
  697. gyroForce = body->computeGyroscopicImpulseImplicit_World(infoGlobal.m_timeStep);
  698. solverBody.m_externalTorqueImpulse += gyroForce;
  699. }
  700. if (body->getFlags() & BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY)
  701. {
  702. gyroForce = body->computeGyroscopicImpulseImplicit_Body(infoGlobal.m_timeStep);
  703. solverBody.m_externalTorqueImpulse += gyroForce;
  704. }
  705. }
  706. }
  707. }
  708. struct ConvertBodiesLoop : public btIParallelForBody
  709. {
  710. btSequentialImpulseConstraintSolverMt* m_solver;
  711. btCollisionObject** m_bodies;
  712. int m_numBodies;
  713. const btContactSolverInfo& m_infoGlobal;
  714. ConvertBodiesLoop(btSequentialImpulseConstraintSolverMt* solver,
  715. btCollisionObject** bodies,
  716. int numBodies,
  717. const btContactSolverInfo& infoGlobal) : m_infoGlobal(infoGlobal)
  718. {
  719. m_solver = solver;
  720. m_bodies = bodies;
  721. m_numBodies = numBodies;
  722. }
  723. void forLoop(int iBegin, int iEnd) const BT_OVERRIDE
  724. {
  725. m_solver->internalConvertBodies(m_bodies, iBegin, iEnd, m_infoGlobal);
  726. }
  727. };
  728. void btSequentialImpulseConstraintSolverMt::convertBodies(btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal)
  729. {
  730. BT_PROFILE("convertBodies");
  731. m_kinematicBodyUniqueIdToSolverBodyTable.resize(0);
  732. m_tmpSolverBodyPool.resizeNoInitialize(numBodies + 1);
  733. m_fixedBodyId = numBodies;
  734. {
  735. btSolverBody& fixedBody = m_tmpSolverBodyPool[m_fixedBodyId];
  736. initSolverBody(&fixedBody, NULL, infoGlobal.m_timeStep);
  737. }
  738. bool parallelBodySetup = true;
  739. if (parallelBodySetup)
  740. {
  741. ConvertBodiesLoop loop(this, bodies, numBodies, infoGlobal);
  742. int grainSize = 40;
  743. btParallelFor(0, numBodies, grainSize, loop);
  744. }
  745. else
  746. {
  747. internalConvertBodies(bodies, 0, numBodies, infoGlobal);
  748. }
  749. }
  750. btScalar btSequentialImpulseConstraintSolverMt::solveGroupCacheFriendlySetup(
  751. btCollisionObject** bodies,
  752. int numBodies,
  753. btPersistentManifold** manifoldPtr,
  754. int numManifolds,
  755. btTypedConstraint** constraints,
  756. int numConstraints,
  757. const btContactSolverInfo& infoGlobal,
  758. btIDebugDraw* debugDrawer)
  759. {
  760. m_numFrictionDirections = (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) ? 2 : 1;
  761. m_useBatching = false;
  762. if (numManifolds >= s_minimumContactManifoldsForBatching &&
  763. (s_allowNestedParallelForLoops || !btThreadsAreRunning()))
  764. {
  765. m_useBatching = true;
  766. m_batchedContactConstraints.m_debugDrawer = debugDrawer;
  767. m_batchedJointConstraints.m_debugDrawer = debugDrawer;
  768. }
  769. btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(bodies,
  770. numBodies,
  771. manifoldPtr,
  772. numManifolds,
  773. constraints,
  774. numConstraints,
  775. infoGlobal,
  776. debugDrawer);
  777. return 0.0f;
  778. }
  779. btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleContactSplitPenetrationImpulseConstraints(const btAlignedObjectArray<int>& consIndices, int batchBegin, int batchEnd)
  780. {
  781. btScalar leastSquaresResidual = 0.f;
  782. for (int iiCons = batchBegin; iiCons < batchEnd; ++iiCons)
  783. {
  784. int iCons = consIndices[iiCons];
  785. const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[iCons];
  786. btSolverBody& bodyA = m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA];
  787. btSolverBody& bodyB = m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB];
  788. btScalar residual = resolveSplitPenetrationImpulse(bodyA, bodyB, solveManifold);
  789. leastSquaresResidual += residual * residual;
  790. }
  791. return leastSquaresResidual;
  792. }
  793. struct ContactSplitPenetrationImpulseSolverLoop : public btIParallelSumBody
  794. {
  795. btSequentialImpulseConstraintSolverMt* m_solver;
  796. const btBatchedConstraints* m_bc;
  797. ContactSplitPenetrationImpulseSolverLoop(btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc)
  798. {
  799. m_solver = solver;
  800. m_bc = bc;
  801. }
  802. btScalar sumLoop(int iBegin, int iEnd) const BT_OVERRIDE
  803. {
  804. BT_PROFILE("ContactSplitPenetrationImpulseSolverLoop");
  805. btScalar sum = 0;
  806. for (int iBatch = iBegin; iBatch < iEnd; ++iBatch)
  807. {
  808. const btBatchedConstraints::Range& batch = m_bc->m_batches[iBatch];
  809. sum += m_solver->resolveMultipleContactSplitPenetrationImpulseConstraints(m_bc->m_constraintIndices, batch.begin, batch.end);
  810. }
  811. return sum;
  812. }
  813. };
  814. void btSequentialImpulseConstraintSolverMt::solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer)
  815. {
  816. BT_PROFILE("solveGroupCacheFriendlySplitImpulseIterations");
  817. if (infoGlobal.m_splitImpulse)
  818. {
  819. for (int iteration = 0; iteration < infoGlobal.m_numIterations; iteration++)
  820. {
  821. btScalar leastSquaresResidual = 0.f;
  822. if (m_useBatching)
  823. {
  824. const btBatchedConstraints& batchedCons = m_batchedContactConstraints;
  825. ContactSplitPenetrationImpulseSolverLoop loop(this, &batchedCons);
  826. btScalar leastSquaresResidual = 0.f;
  827. for (int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase)
  828. {
  829. int iPhase = batchedCons.m_phaseOrder[iiPhase];
  830. const btBatchedConstraints::Range& phase = batchedCons.m_phases[iPhase];
  831. int grainSize = batchedCons.m_phaseGrainSize[iPhase];
  832. leastSquaresResidual += btParallelSum(phase.begin, phase.end, grainSize, loop);
  833. }
  834. }
  835. else
  836. {
  837. // non-batched
  838. leastSquaresResidual = resolveMultipleContactSplitPenetrationImpulseConstraints(m_orderTmpConstraintPool, 0, m_tmpSolverContactConstraintPool.size());
  839. }
  840. if (leastSquaresResidual <= infoGlobal.m_leastSquaresResidualThreshold || iteration >= (infoGlobal.m_numIterations - 1))
  841. {
  842. #ifdef VERBOSE_RESIDUAL_PRINTF
  843. printf("residual = %f at iteration #%d\n", leastSquaresResidual, iteration);
  844. #endif
  845. break;
  846. }
  847. }
  848. }
  849. }
  850. btScalar btSequentialImpulseConstraintSolverMt::solveSingleIteration(int iteration, btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer)
  851. {
  852. if (!m_useBatching)
  853. {
  854. return btSequentialImpulseConstraintSolver::solveSingleIteration(iteration, bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer);
  855. }
  856. BT_PROFILE("solveSingleIterationMt");
  857. btScalar leastSquaresResidual = 0.f;
  858. if (infoGlobal.m_solverMode & SOLVER_RANDMIZE_ORDER)
  859. {
  860. if (1) // uncomment this for a bit less random ((iteration & 7) == 0)
  861. {
  862. randomizeConstraintOrdering(iteration, infoGlobal.m_numIterations);
  863. }
  864. }
  865. {
  866. ///solve all joint constraints
  867. leastSquaresResidual += resolveAllJointConstraints(iteration);
  868. if (iteration < infoGlobal.m_numIterations)
  869. {
  870. // this loop is only used for cone-twist constraints,
  871. // it would be nice to skip this loop if none of the constraints need it
  872. if (m_useObsoleteJointConstraints)
  873. {
  874. for (int j = 0; j < numConstraints; j++)
  875. {
  876. if (constraints[j]->isEnabled())
  877. {
  878. int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA(), infoGlobal.m_timeStep);
  879. int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB(), infoGlobal.m_timeStep);
  880. btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid];
  881. btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid];
  882. constraints[j]->solveConstraintObsolete(bodyA, bodyB, infoGlobal.m_timeStep);
  883. }
  884. }
  885. }
  886. if (infoGlobal.m_solverMode & SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS)
  887. {
  888. // solve all contact, contact-friction, and rolling friction constraints interleaved
  889. leastSquaresResidual += resolveAllContactConstraintsInterleaved();
  890. }
  891. else //SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS
  892. {
  893. // don't interleave them
  894. // solve all contact constraints
  895. leastSquaresResidual += resolveAllContactConstraints();
  896. // solve all contact friction constraints
  897. leastSquaresResidual += resolveAllContactFrictionConstraints();
  898. // solve all rolling friction constraints
  899. leastSquaresResidual += resolveAllRollingFrictionConstraints();
  900. }
  901. }
  902. }
  903. return leastSquaresResidual;
  904. }
  905. btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleJointConstraints(const btAlignedObjectArray<int>& consIndices, int batchBegin, int batchEnd, int iteration)
  906. {
  907. btScalar leastSquaresResidual = 0.f;
  908. for (int iiCons = batchBegin; iiCons < batchEnd; ++iiCons)
  909. {
  910. int iCons = consIndices[iiCons];
  911. const btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[iCons];
  912. if (iteration < constraint.m_overrideNumSolverIterations)
  913. {
  914. btSolverBody& bodyA = m_tmpSolverBodyPool[constraint.m_solverBodyIdA];
  915. btSolverBody& bodyB = m_tmpSolverBodyPool[constraint.m_solverBodyIdB];
  916. btScalar residual = resolveSingleConstraintRowGeneric(bodyA, bodyB, constraint);
  917. leastSquaresResidual += residual * residual;
  918. }
  919. }
  920. return leastSquaresResidual;
  921. }
  922. btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleContactConstraints(const btAlignedObjectArray<int>& consIndices, int batchBegin, int batchEnd)
  923. {
  924. btScalar leastSquaresResidual = 0.f;
  925. for (int iiCons = batchBegin; iiCons < batchEnd; ++iiCons)
  926. {
  927. int iCons = consIndices[iiCons];
  928. const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[iCons];
  929. btSolverBody& bodyA = m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA];
  930. btSolverBody& bodyB = m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB];
  931. btScalar residual = resolveSingleConstraintRowLowerLimit(bodyA, bodyB, solveManifold);
  932. leastSquaresResidual += residual * residual;
  933. }
  934. return leastSquaresResidual;
  935. }
  936. btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleContactFrictionConstraints(const btAlignedObjectArray<int>& consIndices, int batchBegin, int batchEnd)
  937. {
  938. btScalar leastSquaresResidual = 0.f;
  939. for (int iiCons = batchBegin; iiCons < batchEnd; ++iiCons)
  940. {
  941. int iContact = consIndices[iiCons];
  942. btScalar totalImpulse = m_tmpSolverContactConstraintPool[iContact].m_appliedImpulse;
  943. // apply sliding friction
  944. if (totalImpulse > 0.0f)
  945. {
  946. int iBegin = iContact * m_numFrictionDirections;
  947. int iEnd = iBegin + m_numFrictionDirections;
  948. for (int iFriction = iBegin; iFriction < iEnd; ++iFriction)
  949. {
  950. btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[iFriction++];
  951. btAssert(solveManifold.m_frictionIndex == iContact);
  952. solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse);
  953. solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse;
  954. btSolverBody& bodyA = m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA];
  955. btSolverBody& bodyB = m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB];
  956. btScalar residual = resolveSingleConstraintRowGeneric(bodyA, bodyB, solveManifold);
  957. leastSquaresResidual += residual * residual;
  958. }
  959. }
  960. }
  961. return leastSquaresResidual;
  962. }
  963. btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleContactRollingFrictionConstraints(const btAlignedObjectArray<int>& consIndices, int batchBegin, int batchEnd)
  964. {
  965. btScalar leastSquaresResidual = 0.f;
  966. for (int iiCons = batchBegin; iiCons < batchEnd; ++iiCons)
  967. {
  968. int iContact = consIndices[iiCons];
  969. int iFirstRollingFriction = m_rollingFrictionIndexTable[iContact];
  970. if (iFirstRollingFriction >= 0)
  971. {
  972. btScalar totalImpulse = m_tmpSolverContactConstraintPool[iContact].m_appliedImpulse;
  973. // apply rolling friction
  974. if (totalImpulse > 0.0f)
  975. {
  976. int iBegin = iFirstRollingFriction;
  977. int iEnd = iBegin + 3;
  978. for (int iRollingFric = iBegin; iRollingFric < iEnd; ++iRollingFric)
  979. {
  980. btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[iRollingFric];
  981. if (rollingFrictionConstraint.m_frictionIndex != iContact)
  982. {
  983. break;
  984. }
  985. btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction * totalImpulse;
  986. if (rollingFrictionMagnitude > rollingFrictionConstraint.m_friction)
  987. {
  988. rollingFrictionMagnitude = rollingFrictionConstraint.m_friction;
  989. }
  990. rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude;
  991. rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude;
  992. btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA], m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB], rollingFrictionConstraint);
  993. leastSquaresResidual += residual * residual;
  994. }
  995. }
  996. }
  997. }
  998. return leastSquaresResidual;
  999. }
  1000. btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleContactConstraintsInterleaved(const btAlignedObjectArray<int>& contactIndices,
  1001. int batchBegin,
  1002. int batchEnd)
  1003. {
  1004. btScalar leastSquaresResidual = 0.f;
  1005. int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
  1006. for (int iiCons = batchBegin; iiCons < batchEnd; iiCons++)
  1007. {
  1008. btScalar totalImpulse = 0;
  1009. int iContact = contactIndices[iiCons];
  1010. // apply penetration constraint
  1011. {
  1012. const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[iContact];
  1013. btScalar residual = resolveSingleConstraintRowLowerLimit(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold);
  1014. leastSquaresResidual += residual * residual;
  1015. totalImpulse = solveManifold.m_appliedImpulse;
  1016. }
  1017. // apply sliding friction
  1018. if (totalImpulse > 0.0f)
  1019. {
  1020. int iBegin = iContact * m_numFrictionDirections;
  1021. int iEnd = iBegin + m_numFrictionDirections;
  1022. for (int iFriction = iBegin; iFriction < iEnd; ++iFriction)
  1023. {
  1024. btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[iFriction];
  1025. btAssert(solveManifold.m_frictionIndex == iContact);
  1026. solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse);
  1027. solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse;
  1028. btSolverBody& bodyA = m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA];
  1029. btSolverBody& bodyB = m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB];
  1030. btScalar residual = resolveSingleConstraintRowGeneric(bodyA, bodyB, solveManifold);
  1031. leastSquaresResidual += residual * residual;
  1032. }
  1033. }
  1034. // apply rolling friction
  1035. int iFirstRollingFriction = m_rollingFrictionIndexTable[iContact];
  1036. if (totalImpulse > 0.0f && iFirstRollingFriction >= 0)
  1037. {
  1038. int iBegin = iFirstRollingFriction;
  1039. int iEnd = iBegin + 3;
  1040. for (int iRollingFric = iBegin; iRollingFric < iEnd; ++iRollingFric)
  1041. {
  1042. btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[iRollingFric];
  1043. if (rollingFrictionConstraint.m_frictionIndex != iContact)
  1044. {
  1045. break;
  1046. }
  1047. btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction * totalImpulse;
  1048. if (rollingFrictionMagnitude > rollingFrictionConstraint.m_friction)
  1049. {
  1050. rollingFrictionMagnitude = rollingFrictionConstraint.m_friction;
  1051. }
  1052. rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude;
  1053. rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude;
  1054. btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA], m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB], rollingFrictionConstraint);
  1055. leastSquaresResidual += residual * residual;
  1056. }
  1057. }
  1058. }
  1059. return leastSquaresResidual;
  1060. }
  1061. void btSequentialImpulseConstraintSolverMt::randomizeBatchedConstraintOrdering(btBatchedConstraints* batchedConstraints)
  1062. {
  1063. btBatchedConstraints& bc = *batchedConstraints;
  1064. // randomize ordering of phases
  1065. for (int ii = 1; ii < bc.m_phaseOrder.size(); ++ii)
  1066. {
  1067. int iSwap = btRandInt2(ii + 1);
  1068. bc.m_phaseOrder.swap(ii, iSwap);
  1069. }
  1070. // for each batch,
  1071. for (int iBatch = 0; iBatch < bc.m_batches.size(); ++iBatch)
  1072. {
  1073. // randomize ordering of constraints within the batch
  1074. const btBatchedConstraints::Range& batch = bc.m_batches[iBatch];
  1075. for (int iiCons = batch.begin; iiCons < batch.end; ++iiCons)
  1076. {
  1077. int iSwap = batch.begin + btRandInt2(iiCons - batch.begin + 1);
  1078. btAssert(iSwap >= batch.begin && iSwap < batch.end);
  1079. bc.m_constraintIndices.swap(iiCons, iSwap);
  1080. }
  1081. }
  1082. }
  1083. void btSequentialImpulseConstraintSolverMt::randomizeConstraintOrdering(int iteration, int numIterations)
  1084. {
  1085. // randomize ordering of joint constraints
  1086. randomizeBatchedConstraintOrdering(&m_batchedJointConstraints);
  1087. //contact/friction constraints are not solved more than numIterations
  1088. if (iteration < numIterations)
  1089. {
  1090. randomizeBatchedConstraintOrdering(&m_batchedContactConstraints);
  1091. }
  1092. }
  1093. struct JointSolverLoop : public btIParallelSumBody
  1094. {
  1095. btSequentialImpulseConstraintSolverMt* m_solver;
  1096. const btBatchedConstraints* m_bc;
  1097. int m_iteration;
  1098. JointSolverLoop(btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc, int iteration)
  1099. {
  1100. m_solver = solver;
  1101. m_bc = bc;
  1102. m_iteration = iteration;
  1103. }
  1104. btScalar sumLoop(int iBegin, int iEnd) const BT_OVERRIDE
  1105. {
  1106. BT_PROFILE("JointSolverLoop");
  1107. btScalar sum = 0;
  1108. for (int iBatch = iBegin; iBatch < iEnd; ++iBatch)
  1109. {
  1110. const btBatchedConstraints::Range& batch = m_bc->m_batches[iBatch];
  1111. sum += m_solver->resolveMultipleJointConstraints(m_bc->m_constraintIndices, batch.begin, batch.end, m_iteration);
  1112. }
  1113. return sum;
  1114. }
  1115. };
  1116. btScalar btSequentialImpulseConstraintSolverMt::resolveAllJointConstraints(int iteration)
  1117. {
  1118. BT_PROFILE("resolveAllJointConstraints");
  1119. const btBatchedConstraints& batchedCons = m_batchedJointConstraints;
  1120. JointSolverLoop loop(this, &batchedCons, iteration);
  1121. btScalar leastSquaresResidual = 0.f;
  1122. for (int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase)
  1123. {
  1124. int iPhase = batchedCons.m_phaseOrder[iiPhase];
  1125. const btBatchedConstraints::Range& phase = batchedCons.m_phases[iPhase];
  1126. int grainSize = 1;
  1127. leastSquaresResidual += btParallelSum(phase.begin, phase.end, grainSize, loop);
  1128. }
  1129. return leastSquaresResidual;
  1130. }
  1131. struct ContactSolverLoop : public btIParallelSumBody
  1132. {
  1133. btSequentialImpulseConstraintSolverMt* m_solver;
  1134. const btBatchedConstraints* m_bc;
  1135. ContactSolverLoop(btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc)
  1136. {
  1137. m_solver = solver;
  1138. m_bc = bc;
  1139. }
  1140. btScalar sumLoop(int iBegin, int iEnd) const BT_OVERRIDE
  1141. {
  1142. BT_PROFILE("ContactSolverLoop");
  1143. btScalar sum = 0;
  1144. for (int iBatch = iBegin; iBatch < iEnd; ++iBatch)
  1145. {
  1146. const btBatchedConstraints::Range& batch = m_bc->m_batches[iBatch];
  1147. sum += m_solver->resolveMultipleContactConstraints(m_bc->m_constraintIndices, batch.begin, batch.end);
  1148. }
  1149. return sum;
  1150. }
  1151. };
  1152. btScalar btSequentialImpulseConstraintSolverMt::resolveAllContactConstraints()
  1153. {
  1154. BT_PROFILE("resolveAllContactConstraints");
  1155. const btBatchedConstraints& batchedCons = m_batchedContactConstraints;
  1156. ContactSolverLoop loop(this, &batchedCons);
  1157. btScalar leastSquaresResidual = 0.f;
  1158. for (int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase)
  1159. {
  1160. int iPhase = batchedCons.m_phaseOrder[iiPhase];
  1161. const btBatchedConstraints::Range& phase = batchedCons.m_phases[iPhase];
  1162. int grainSize = batchedCons.m_phaseGrainSize[iPhase];
  1163. leastSquaresResidual += btParallelSum(phase.begin, phase.end, grainSize, loop);
  1164. }
  1165. return leastSquaresResidual;
  1166. }
  1167. struct ContactFrictionSolverLoop : public btIParallelSumBody
  1168. {
  1169. btSequentialImpulseConstraintSolverMt* m_solver;
  1170. const btBatchedConstraints* m_bc;
  1171. ContactFrictionSolverLoop(btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc)
  1172. {
  1173. m_solver = solver;
  1174. m_bc = bc;
  1175. }
  1176. btScalar sumLoop(int iBegin, int iEnd) const BT_OVERRIDE
  1177. {
  1178. BT_PROFILE("ContactFrictionSolverLoop");
  1179. btScalar sum = 0;
  1180. for (int iBatch = iBegin; iBatch < iEnd; ++iBatch)
  1181. {
  1182. const btBatchedConstraints::Range& batch = m_bc->m_batches[iBatch];
  1183. sum += m_solver->resolveMultipleContactFrictionConstraints(m_bc->m_constraintIndices, batch.begin, batch.end);
  1184. }
  1185. return sum;
  1186. }
  1187. };
  1188. btScalar btSequentialImpulseConstraintSolverMt::resolveAllContactFrictionConstraints()
  1189. {
  1190. BT_PROFILE("resolveAllContactFrictionConstraints");
  1191. const btBatchedConstraints& batchedCons = m_batchedContactConstraints;
  1192. ContactFrictionSolverLoop loop(this, &batchedCons);
  1193. btScalar leastSquaresResidual = 0.f;
  1194. for (int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase)
  1195. {
  1196. int iPhase = batchedCons.m_phaseOrder[iiPhase];
  1197. const btBatchedConstraints::Range& phase = batchedCons.m_phases[iPhase];
  1198. int grainSize = batchedCons.m_phaseGrainSize[iPhase];
  1199. leastSquaresResidual += btParallelSum(phase.begin, phase.end, grainSize, loop);
  1200. }
  1201. return leastSquaresResidual;
  1202. }
  1203. struct InterleavedContactSolverLoop : public btIParallelSumBody
  1204. {
  1205. btSequentialImpulseConstraintSolverMt* m_solver;
  1206. const btBatchedConstraints* m_bc;
  1207. InterleavedContactSolverLoop(btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc)
  1208. {
  1209. m_solver = solver;
  1210. m_bc = bc;
  1211. }
  1212. btScalar sumLoop(int iBegin, int iEnd) const BT_OVERRIDE
  1213. {
  1214. BT_PROFILE("InterleavedContactSolverLoop");
  1215. btScalar sum = 0;
  1216. for (int iBatch = iBegin; iBatch < iEnd; ++iBatch)
  1217. {
  1218. const btBatchedConstraints::Range& batch = m_bc->m_batches[iBatch];
  1219. sum += m_solver->resolveMultipleContactConstraintsInterleaved(m_bc->m_constraintIndices, batch.begin, batch.end);
  1220. }
  1221. return sum;
  1222. }
  1223. };
  1224. btScalar btSequentialImpulseConstraintSolverMt::resolveAllContactConstraintsInterleaved()
  1225. {
  1226. BT_PROFILE("resolveAllContactConstraintsInterleaved");
  1227. const btBatchedConstraints& batchedCons = m_batchedContactConstraints;
  1228. InterleavedContactSolverLoop loop(this, &batchedCons);
  1229. btScalar leastSquaresResidual = 0.f;
  1230. for (int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase)
  1231. {
  1232. int iPhase = batchedCons.m_phaseOrder[iiPhase];
  1233. const btBatchedConstraints::Range& phase = batchedCons.m_phases[iPhase];
  1234. int grainSize = 1;
  1235. leastSquaresResidual += btParallelSum(phase.begin, phase.end, grainSize, loop);
  1236. }
  1237. return leastSquaresResidual;
  1238. }
  1239. struct ContactRollingFrictionSolverLoop : public btIParallelSumBody
  1240. {
  1241. btSequentialImpulseConstraintSolverMt* m_solver;
  1242. const btBatchedConstraints* m_bc;
  1243. ContactRollingFrictionSolverLoop(btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc)
  1244. {
  1245. m_solver = solver;
  1246. m_bc = bc;
  1247. }
  1248. btScalar sumLoop(int iBegin, int iEnd) const BT_OVERRIDE
  1249. {
  1250. BT_PROFILE("ContactFrictionSolverLoop");
  1251. btScalar sum = 0;
  1252. for (int iBatch = iBegin; iBatch < iEnd; ++iBatch)
  1253. {
  1254. const btBatchedConstraints::Range& batch = m_bc->m_batches[iBatch];
  1255. sum += m_solver->resolveMultipleContactRollingFrictionConstraints(m_bc->m_constraintIndices, batch.begin, batch.end);
  1256. }
  1257. return sum;
  1258. }
  1259. };
  1260. btScalar btSequentialImpulseConstraintSolverMt::resolveAllRollingFrictionConstraints()
  1261. {
  1262. BT_PROFILE("resolveAllRollingFrictionConstraints");
  1263. btScalar leastSquaresResidual = 0.f;
  1264. //
  1265. // We do not generate batches for rolling friction constraints. We assume that
  1266. // one of two cases is true:
  1267. //
  1268. // 1. either most bodies in the simulation have rolling friction, in which case we can use the
  1269. // batches for contacts and use a lookup table to translate contact indices to rolling friction
  1270. // (ignoring any contact indices that don't map to a rolling friction constraint). As long as
  1271. // most contacts have a corresponding rolling friction constraint, this should parallelize well.
  1272. //
  1273. // -OR-
  1274. //
  1275. // 2. few bodies in the simulation have rolling friction, so it is not worth trying to use the
  1276. // batches from contacts as most of the contacts won't have corresponding rolling friction
  1277. // constraints and most threads would end up doing very little work. Most of the time would
  1278. // go to threading overhead, so we don't bother with threading.
  1279. //
  1280. int numRollingFrictionPoolConstraints = m_tmpSolverContactRollingFrictionConstraintPool.size();
  1281. if (numRollingFrictionPoolConstraints >= m_tmpSolverContactConstraintPool.size())
  1282. {
  1283. // use batching if there are many rolling friction constraints
  1284. const btBatchedConstraints& batchedCons = m_batchedContactConstraints;
  1285. ContactRollingFrictionSolverLoop loop(this, &batchedCons);
  1286. btScalar leastSquaresResidual = 0.f;
  1287. for (int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase)
  1288. {
  1289. int iPhase = batchedCons.m_phaseOrder[iiPhase];
  1290. const btBatchedConstraints::Range& phase = batchedCons.m_phases[iPhase];
  1291. int grainSize = 1;
  1292. leastSquaresResidual += btParallelSum(phase.begin, phase.end, grainSize, loop);
  1293. }
  1294. }
  1295. else
  1296. {
  1297. // no batching, also ignores SOLVER_RANDMIZE_ORDER
  1298. for (int j = 0; j < numRollingFrictionPoolConstraints; j++)
  1299. {
  1300. btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[j];
  1301. if (rollingFrictionConstraint.m_frictionIndex >= 0)
  1302. {
  1303. btScalar totalImpulse = m_tmpSolverContactConstraintPool[rollingFrictionConstraint.m_frictionIndex].m_appliedImpulse;
  1304. if (totalImpulse > 0.0f)
  1305. {
  1306. btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction * totalImpulse;
  1307. if (rollingFrictionMagnitude > rollingFrictionConstraint.m_friction)
  1308. rollingFrictionMagnitude = rollingFrictionConstraint.m_friction;
  1309. rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude;
  1310. rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude;
  1311. btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA], m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB], rollingFrictionConstraint);
  1312. leastSquaresResidual += residual * residual;
  1313. }
  1314. }
  1315. }
  1316. }
  1317. return leastSquaresResidual;
  1318. }
  1319. void btSequentialImpulseConstraintSolverMt::internalWriteBackContacts(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal)
  1320. {
  1321. BT_PROFILE("internalWriteBackContacts");
  1322. writeBackContacts(iBegin, iEnd, infoGlobal);
  1323. //for ( int iContact = iBegin; iContact < iEnd; ++iContact)
  1324. //{
  1325. // const btSolverConstraint& contactConstraint = m_tmpSolverContactConstraintPool[ iContact ];
  1326. // btManifoldPoint* pt = (btManifoldPoint*) contactConstraint.m_originalContactPoint;
  1327. // btAssert( pt );
  1328. // pt->m_appliedImpulse = contactConstraint.m_appliedImpulse;
  1329. // pt->m_appliedImpulseLateral1 = m_tmpSolverContactFrictionConstraintPool[ contactConstraint.m_frictionIndex ].m_appliedImpulse;
  1330. // if ( m_numFrictionDirections == 2 )
  1331. // {
  1332. // pt->m_appliedImpulseLateral2 = m_tmpSolverContactFrictionConstraintPool[ contactConstraint.m_frictionIndex + 1 ].m_appliedImpulse;
  1333. // }
  1334. //}
  1335. }
  1336. void btSequentialImpulseConstraintSolverMt::internalWriteBackJoints(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal)
  1337. {
  1338. BT_PROFILE("internalWriteBackJoints");
  1339. writeBackJoints(iBegin, iEnd, infoGlobal);
  1340. }
  1341. void btSequentialImpulseConstraintSolverMt::internalWriteBackBodies(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal)
  1342. {
  1343. BT_PROFILE("internalWriteBackBodies");
  1344. writeBackBodies(iBegin, iEnd, infoGlobal);
  1345. }
  1346. struct WriteContactPointsLoop : public btIParallelForBody
  1347. {
  1348. btSequentialImpulseConstraintSolverMt* m_solver;
  1349. const btContactSolverInfo* m_infoGlobal;
  1350. WriteContactPointsLoop(btSequentialImpulseConstraintSolverMt* solver, const btContactSolverInfo& infoGlobal)
  1351. {
  1352. m_solver = solver;
  1353. m_infoGlobal = &infoGlobal;
  1354. }
  1355. void forLoop(int iBegin, int iEnd) const BT_OVERRIDE
  1356. {
  1357. m_solver->internalWriteBackContacts(iBegin, iEnd, *m_infoGlobal);
  1358. }
  1359. };
  1360. struct WriteJointsLoop : public btIParallelForBody
  1361. {
  1362. btSequentialImpulseConstraintSolverMt* m_solver;
  1363. const btContactSolverInfo* m_infoGlobal;
  1364. WriteJointsLoop(btSequentialImpulseConstraintSolverMt* solver, const btContactSolverInfo& infoGlobal)
  1365. {
  1366. m_solver = solver;
  1367. m_infoGlobal = &infoGlobal;
  1368. }
  1369. void forLoop(int iBegin, int iEnd) const BT_OVERRIDE
  1370. {
  1371. m_solver->internalWriteBackJoints(iBegin, iEnd, *m_infoGlobal);
  1372. }
  1373. };
  1374. struct WriteBodiesLoop : public btIParallelForBody
  1375. {
  1376. btSequentialImpulseConstraintSolverMt* m_solver;
  1377. const btContactSolverInfo* m_infoGlobal;
  1378. WriteBodiesLoop(btSequentialImpulseConstraintSolverMt* solver, const btContactSolverInfo& infoGlobal)
  1379. {
  1380. m_solver = solver;
  1381. m_infoGlobal = &infoGlobal;
  1382. }
  1383. void forLoop(int iBegin, int iEnd) const BT_OVERRIDE
  1384. {
  1385. m_solver->internalWriteBackBodies(iBegin, iEnd, *m_infoGlobal);
  1386. }
  1387. };
  1388. btScalar btSequentialImpulseConstraintSolverMt::solveGroupCacheFriendlyFinish(btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal)
  1389. {
  1390. BT_PROFILE("solveGroupCacheFriendlyFinish");
  1391. if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
  1392. {
  1393. WriteContactPointsLoop loop(this, infoGlobal);
  1394. int grainSize = 500;
  1395. btParallelFor(0, m_tmpSolverContactConstraintPool.size(), grainSize, loop);
  1396. }
  1397. {
  1398. WriteJointsLoop loop(this, infoGlobal);
  1399. int grainSize = 400;
  1400. btParallelFor(0, m_tmpSolverNonContactConstraintPool.size(), grainSize, loop);
  1401. }
  1402. {
  1403. WriteBodiesLoop loop(this, infoGlobal);
  1404. int grainSize = 100;
  1405. btParallelFor(0, m_tmpSolverBodyPool.size(), grainSize, loop);
  1406. }
  1407. m_tmpSolverContactConstraintPool.resizeNoInitialize(0);
  1408. m_tmpSolverNonContactConstraintPool.resizeNoInitialize(0);
  1409. m_tmpSolverContactFrictionConstraintPool.resizeNoInitialize(0);
  1410. m_tmpSolverContactRollingFrictionConstraintPool.resizeNoInitialize(0);
  1411. m_tmpSolverBodyPool.resizeNoInitialize(0);
  1412. return 0.f;
  1413. }