btMultiBodyConstraintSolver.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  1. /*
  2. Bullet Continuous Collision Detection and Physics Library
  3. Copyright (c) 2013 Erwin Coumans http://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 "btMultiBodyConstraintSolver.h"
  14. #include "bullet/BulletCollision//NarrowPhaseCollision/btPersistentManifold.h"
  15. #include "btMultiBodyLinkCollider.h"
  16. #include "bullet/BulletDynamics/ConstraintSolver/btSolverBody.h"
  17. #include "btMultiBodyConstraint.h"
  18. #include "bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
  19. #include "bullet/LinearMath/btQuickprof.h"
  20. btScalar btMultiBodyConstraintSolver::solveSingleIteration(int iteration, btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
  21. {
  22. btScalar val = btSequentialImpulseConstraintSolver::solveSingleIteration(iteration, bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer);
  23. //solve featherstone non-contact constraints
  24. //printf("m_multiBodyNonContactConstraints = %d\n",m_multiBodyNonContactConstraints.size());
  25. for (int j=0;j<m_multiBodyNonContactConstraints.size();j++)
  26. {
  27. btMultiBodySolverConstraint& constraint = m_multiBodyNonContactConstraints[j];
  28. //if (iteration < constraint.m_overrideNumSolverIterations)
  29. //resolveSingleConstraintRowGenericMultiBody(constraint);
  30. resolveSingleConstraintRowGeneric(constraint);
  31. }
  32. //solve featherstone normal contact
  33. for (int j=0;j<m_multiBodyNormalContactConstraints.size();j++)
  34. {
  35. btMultiBodySolverConstraint& constraint = m_multiBodyNormalContactConstraints[j];
  36. if (iteration < infoGlobal.m_numIterations)
  37. resolveSingleConstraintRowGeneric(constraint);
  38. }
  39. //solve featherstone frictional contact
  40. for (int j=0;j<this->m_multiBodyFrictionContactConstraints.size();j++)
  41. {
  42. if (iteration < infoGlobal.m_numIterations)
  43. {
  44. btMultiBodySolverConstraint& frictionConstraint = m_multiBodyFrictionContactConstraints[j];
  45. btScalar totalImpulse = m_multiBodyNormalContactConstraints[frictionConstraint.m_frictionIndex].m_appliedImpulse;
  46. //adjust friction limits here
  47. if (totalImpulse>btScalar(0))
  48. {
  49. frictionConstraint.m_lowerLimit = -(frictionConstraint.m_friction*totalImpulse);
  50. frictionConstraint.m_upperLimit = frictionConstraint.m_friction*totalImpulse;
  51. resolveSingleConstraintRowGeneric(frictionConstraint);
  52. }
  53. }
  54. }
  55. return val;
  56. }
  57. btScalar btMultiBodyConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
  58. {
  59. m_multiBodyNonContactConstraints.resize(0);
  60. m_multiBodyNormalContactConstraints.resize(0);
  61. m_multiBodyFrictionContactConstraints.resize(0);
  62. m_data.m_jacobians.resize(0);
  63. m_data.m_deltaVelocitiesUnitImpulse.resize(0);
  64. m_data.m_deltaVelocities.resize(0);
  65. for (int i=0;i<numBodies;i++)
  66. {
  67. const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(bodies[i]);
  68. if (fcA)
  69. {
  70. fcA->m_multiBody->setCompanionId(-1);
  71. }
  72. }
  73. btScalar val = btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup( bodies,numBodies,manifoldPtr, numManifolds, constraints,numConstraints,infoGlobal,debugDrawer);
  74. return val;
  75. }
  76. void btMultiBodyConstraintSolver::applyDeltaVee(btScalar* delta_vee, btScalar impulse, int velocityIndex, int ndof)
  77. {
  78. for (int i = 0; i < ndof; ++i)
  79. m_data.m_deltaVelocities[velocityIndex+i] += delta_vee[i] * impulse;
  80. }
  81. void btMultiBodyConstraintSolver::resolveSingleConstraintRowGeneric(const btMultiBodySolverConstraint& c)
  82. {
  83. btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm;
  84. btScalar deltaVelADotn=0;
  85. btScalar deltaVelBDotn=0;
  86. btSolverBody* bodyA = 0;
  87. btSolverBody* bodyB = 0;
  88. int ndofA=0;
  89. int ndofB=0;
  90. if (c.m_multiBodyA)
  91. {
  92. ndofA = c.m_multiBodyA->getNumLinks() + 6;
  93. for (int i = 0; i < ndofA; ++i)
  94. deltaVelADotn += m_data.m_jacobians[c.m_jacAindex+i] * m_data.m_deltaVelocities[c.m_deltaVelAindex+i];
  95. } else
  96. {
  97. bodyA = &m_tmpSolverBodyPool[c.m_solverBodyIdA];
  98. deltaVelADotn += c.m_contactNormal1.dot(bodyA->internalGetDeltaLinearVelocity()) + c.m_relpos1CrossNormal.dot(bodyA->internalGetDeltaAngularVelocity());
  99. }
  100. if (c.m_multiBodyB)
  101. {
  102. ndofB = c.m_multiBodyB->getNumLinks() + 6;
  103. for (int i = 0; i < ndofB; ++i)
  104. deltaVelBDotn += m_data.m_jacobians[c.m_jacBindex+i] * m_data.m_deltaVelocities[c.m_deltaVelBindex+i];
  105. } else
  106. {
  107. bodyB = &m_tmpSolverBodyPool[c.m_solverBodyIdB];
  108. deltaVelBDotn += c.m_contactNormal2.dot(bodyB->internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(bodyB->internalGetDeltaAngularVelocity());
  109. }
  110. deltaImpulse -= deltaVelADotn*c.m_jacDiagABInv;//m_jacDiagABInv = 1./denom
  111. deltaImpulse -= deltaVelBDotn*c.m_jacDiagABInv;
  112. const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse;
  113. if (sum < c.m_lowerLimit)
  114. {
  115. deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse;
  116. c.m_appliedImpulse = c.m_lowerLimit;
  117. }
  118. else if (sum > c.m_upperLimit)
  119. {
  120. deltaImpulse = c.m_upperLimit-c.m_appliedImpulse;
  121. c.m_appliedImpulse = c.m_upperLimit;
  122. }
  123. else
  124. {
  125. c.m_appliedImpulse = sum;
  126. }
  127. if (c.m_multiBodyA)
  128. {
  129. applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacAindex],deltaImpulse,c.m_deltaVelAindex,ndofA);
  130. c.m_multiBodyA->applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacAindex],deltaImpulse);
  131. } else
  132. {
  133. bodyA->internalApplyImpulse(c.m_contactNormal1*bodyA->internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
  134. }
  135. if (c.m_multiBodyB)
  136. {
  137. applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacBindex],deltaImpulse,c.m_deltaVelBindex,ndofB);
  138. c.m_multiBodyB->applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacBindex],deltaImpulse);
  139. } else
  140. {
  141. bodyB->internalApplyImpulse(c.m_contactNormal2*bodyB->internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
  142. }
  143. }
  144. void btMultiBodyConstraintSolver::resolveSingleConstraintRowGenericMultiBody(const btMultiBodySolverConstraint& c)
  145. {
  146. btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm;
  147. btScalar deltaVelADotn=0;
  148. btScalar deltaVelBDotn=0;
  149. int ndofA=0;
  150. int ndofB=0;
  151. if (c.m_multiBodyA)
  152. {
  153. ndofA = c.m_multiBodyA->getNumLinks() + 6;
  154. for (int i = 0; i < ndofA; ++i)
  155. deltaVelADotn += m_data.m_jacobians[c.m_jacAindex+i] * m_data.m_deltaVelocities[c.m_deltaVelAindex+i];
  156. }
  157. if (c.m_multiBodyB)
  158. {
  159. ndofB = c.m_multiBodyB->getNumLinks() + 6;
  160. for (int i = 0; i < ndofB; ++i)
  161. deltaVelBDotn += m_data.m_jacobians[c.m_jacBindex+i] * m_data.m_deltaVelocities[c.m_deltaVelBindex+i];
  162. }
  163. deltaImpulse -= deltaVelADotn*c.m_jacDiagABInv;//m_jacDiagABInv = 1./denom
  164. deltaImpulse -= deltaVelBDotn*c.m_jacDiagABInv;
  165. const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse;
  166. if (sum < c.m_lowerLimit)
  167. {
  168. deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse;
  169. c.m_appliedImpulse = c.m_lowerLimit;
  170. }
  171. else if (sum > c.m_upperLimit)
  172. {
  173. deltaImpulse = c.m_upperLimit-c.m_appliedImpulse;
  174. c.m_appliedImpulse = c.m_upperLimit;
  175. }
  176. else
  177. {
  178. c.m_appliedImpulse = sum;
  179. }
  180. if (c.m_multiBodyA)
  181. {
  182. applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacAindex],deltaImpulse,c.m_deltaVelAindex,ndofA);
  183. c.m_multiBodyA->applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacAindex],deltaImpulse);
  184. }
  185. if (c.m_multiBodyB)
  186. {
  187. applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacBindex],deltaImpulse,c.m_deltaVelBindex,ndofB);
  188. c.m_multiBodyB->applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacBindex],deltaImpulse);
  189. }
  190. }
  191. void btMultiBodyConstraintSolver::setupMultiBodyContactConstraint(btMultiBodySolverConstraint& solverConstraint,
  192. const btVector3& contactNormal,
  193. btManifoldPoint& cp, const btContactSolverInfo& infoGlobal,
  194. btScalar& relaxation,
  195. bool isFriction, btScalar desiredVelocity, btScalar cfmSlip)
  196. {
  197. BT_PROFILE("setupMultiBodyContactConstraint");
  198. btVector3 rel_pos1;
  199. btVector3 rel_pos2;
  200. btMultiBody* multiBodyA = solverConstraint.m_multiBodyA;
  201. btMultiBody* multiBodyB = solverConstraint.m_multiBodyB;
  202. const btVector3& pos1 = cp.getPositionWorldOnA();
  203. const btVector3& pos2 = cp.getPositionWorldOnB();
  204. btSolverBody* bodyA = multiBodyA ? 0 : &m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA];
  205. btSolverBody* bodyB = multiBodyB ? 0 : &m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB];
  206. btRigidBody* rb0 = multiBodyA ? 0 : bodyA->m_originalBody;
  207. btRigidBody* rb1 = multiBodyB ? 0 : bodyB->m_originalBody;
  208. if (bodyA)
  209. rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin();
  210. if (bodyB)
  211. rel_pos2 = pos2 - bodyB->getWorldTransform().getOrigin();
  212. relaxation = 1.f;
  213. if (multiBodyA)
  214. {
  215. const int ndofA = multiBodyA->getNumLinks() + 6;
  216. solverConstraint.m_deltaVelAindex = multiBodyA->getCompanionId();
  217. if (solverConstraint.m_deltaVelAindex <0)
  218. {
  219. solverConstraint.m_deltaVelAindex = m_data.m_deltaVelocities.size();
  220. multiBodyA->setCompanionId(solverConstraint.m_deltaVelAindex);
  221. m_data.m_deltaVelocities.resize(m_data.m_deltaVelocities.size()+ndofA);
  222. } else
  223. {
  224. btAssert(m_data.m_deltaVelocities.size() >= solverConstraint.m_deltaVelAindex+ndofA);
  225. }
  226. solverConstraint.m_jacAindex = m_data.m_jacobians.size();
  227. m_data.m_jacobians.resize(m_data.m_jacobians.size()+ndofA);
  228. m_data.m_deltaVelocitiesUnitImpulse.resize(m_data.m_deltaVelocitiesUnitImpulse.size()+ndofA);
  229. btAssert(m_data.m_jacobians.size() == m_data.m_deltaVelocitiesUnitImpulse.size());
  230. btScalar* jac1=&m_data.m_jacobians[solverConstraint.m_jacAindex];
  231. multiBodyA->fillContactJacobian(solverConstraint.m_linkA, cp.getPositionWorldOnA(), contactNormal, jac1, m_data.scratch_r, m_data.scratch_v, m_data.scratch_m);
  232. btScalar* delta = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex];
  233. multiBodyA->calcAccelerationDeltas(&m_data.m_jacobians[solverConstraint.m_jacAindex],delta,m_data.scratch_r, m_data.scratch_v);
  234. } else
  235. {
  236. btVector3 torqueAxis0 = rel_pos1.cross(contactNormal);
  237. solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0*rb0->getAngularFactor() : btVector3(0,0,0);
  238. solverConstraint.m_relpos1CrossNormal = torqueAxis0;
  239. solverConstraint.m_contactNormal1 = contactNormal;
  240. }
  241. if (multiBodyB)
  242. {
  243. const int ndofB = multiBodyB->getNumLinks() + 6;
  244. solverConstraint.m_deltaVelBindex = multiBodyB->getCompanionId();
  245. if (solverConstraint.m_deltaVelBindex <0)
  246. {
  247. solverConstraint.m_deltaVelBindex = m_data.m_deltaVelocities.size();
  248. multiBodyB->setCompanionId(solverConstraint.m_deltaVelBindex);
  249. m_data.m_deltaVelocities.resize(m_data.m_deltaVelocities.size()+ndofB);
  250. }
  251. solverConstraint.m_jacBindex = m_data.m_jacobians.size();
  252. m_data.m_jacobians.resize(m_data.m_jacobians.size()+ndofB);
  253. m_data.m_deltaVelocitiesUnitImpulse.resize(m_data.m_deltaVelocitiesUnitImpulse.size()+ndofB);
  254. btAssert(m_data.m_jacobians.size() == m_data.m_deltaVelocitiesUnitImpulse.size());
  255. multiBodyB->fillContactJacobian(solverConstraint.m_linkB, cp.getPositionWorldOnB(), -contactNormal, &m_data.m_jacobians[solverConstraint.m_jacBindex], m_data.scratch_r, m_data.scratch_v, m_data.scratch_m);
  256. multiBodyB->calcAccelerationDeltas(&m_data.m_jacobians[solverConstraint.m_jacBindex],&m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex],m_data.scratch_r, m_data.scratch_v);
  257. } else
  258. {
  259. btVector3 torqueAxis1 = rel_pos2.cross(contactNormal);
  260. solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*-torqueAxis1*rb1->getAngularFactor() : btVector3(0,0,0);
  261. solverConstraint.m_relpos2CrossNormal = -torqueAxis1;
  262. solverConstraint.m_contactNormal2 = -contactNormal;
  263. }
  264. {
  265. btVector3 vec;
  266. btScalar denom0 = 0.f;
  267. btScalar denom1 = 0.f;
  268. btScalar* jacB = 0;
  269. btScalar* jacA = 0;
  270. btScalar* lambdaA =0;
  271. btScalar* lambdaB =0;
  272. int ndofA = 0;
  273. if (multiBodyA)
  274. {
  275. ndofA = multiBodyA->getNumLinks() + 6;
  276. jacA = &m_data.m_jacobians[solverConstraint.m_jacAindex];
  277. lambdaA = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex];
  278. for (int i = 0; i < ndofA; ++i)
  279. {
  280. btScalar j = jacA[i] ;
  281. btScalar l =lambdaA[i];
  282. denom0 += j*l;
  283. }
  284. } else
  285. {
  286. if (rb0)
  287. {
  288. vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1);
  289. denom0 = rb0->getInvMass() + contactNormal.dot(vec);
  290. }
  291. }
  292. if (multiBodyB)
  293. {
  294. const int ndofB = multiBodyB->getNumLinks() + 6;
  295. jacB = &m_data.m_jacobians[solverConstraint.m_jacBindex];
  296. lambdaB = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex];
  297. for (int i = 0; i < ndofB; ++i)
  298. {
  299. btScalar j = jacB[i] ;
  300. btScalar l =lambdaB[i];
  301. denom1 += j*l;
  302. }
  303. } else
  304. {
  305. if (rb1)
  306. {
  307. vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2);
  308. denom1 = rb1->getInvMass() + contactNormal.dot(vec);
  309. }
  310. }
  311. if (multiBodyA && (multiBodyA==multiBodyB))
  312. {
  313. // ndof1 == ndof2 in this case
  314. for (int i = 0; i < ndofA; ++i)
  315. {
  316. denom1 += jacB[i] * lambdaA[i];
  317. denom1 += jacA[i] * lambdaB[i];
  318. }
  319. }
  320. btScalar d = denom0+denom1;
  321. if (btFabs(d)>SIMD_EPSILON)
  322. {
  323. solverConstraint.m_jacDiagABInv = relaxation/(d);
  324. } else
  325. {
  326. solverConstraint.m_jacDiagABInv = 1.f;
  327. }
  328. }
  329. //compute rhs and remaining solverConstraint fields
  330. btScalar restitution = 0.f;
  331. btScalar penetration = isFriction? 0 : cp.getDistance()+infoGlobal.m_linearSlop;
  332. btScalar rel_vel = 0.f;
  333. int ndofA = 0;
  334. int ndofB = 0;
  335. {
  336. btVector3 vel1,vel2;
  337. if (multiBodyA)
  338. {
  339. ndofA = multiBodyA->getNumLinks() + 6;
  340. btScalar* jacA = &m_data.m_jacobians[solverConstraint.m_jacAindex];
  341. for (int i = 0; i < ndofA ; ++i)
  342. rel_vel += multiBodyA->getVelocityVector()[i] * jacA[i];
  343. } else
  344. {
  345. if (rb0)
  346. {
  347. rel_vel += rb0->getVelocityInLocalPoint(rel_pos1).dot(solverConstraint.m_contactNormal1);
  348. }
  349. }
  350. if (multiBodyB)
  351. {
  352. ndofB = multiBodyB->getNumLinks() + 6;
  353. btScalar* jacB = &m_data.m_jacobians[solverConstraint.m_jacBindex];
  354. for (int i = 0; i < ndofB ; ++i)
  355. rel_vel += multiBodyB->getVelocityVector()[i] * jacB[i];
  356. } else
  357. {
  358. if (rb1)
  359. {
  360. rel_vel += rb1->getVelocityInLocalPoint(rel_pos2).dot(solverConstraint.m_contactNormal2);
  361. }
  362. }
  363. solverConstraint.m_friction = cp.m_combinedFriction;
  364. restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution);
  365. if (restitution <= btScalar(0.))
  366. {
  367. restitution = 0.f;
  368. };
  369. }
  370. ///warm starting (or zero if disabled)
  371. if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
  372. {
  373. solverConstraint.m_appliedImpulse = isFriction ? 0 : cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor;
  374. if (solverConstraint.m_appliedImpulse)
  375. {
  376. if (multiBodyA)
  377. {
  378. btScalar impulse = solverConstraint.m_appliedImpulse;
  379. btScalar* deltaV = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex];
  380. multiBodyA->applyDeltaVee(deltaV,impulse);
  381. applyDeltaVee(deltaV,impulse,solverConstraint.m_deltaVelAindex,ndofA);
  382. } else
  383. {
  384. if (rb0)
  385. bodyA->internalApplyImpulse(solverConstraint.m_contactNormal1*bodyA->internalGetInvMass()*rb0->getLinearFactor(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse);
  386. }
  387. if (multiBodyB)
  388. {
  389. btScalar impulse = solverConstraint.m_appliedImpulse;
  390. btScalar* deltaV = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex];
  391. multiBodyB->applyDeltaVee(deltaV,impulse);
  392. applyDeltaVee(deltaV,impulse,solverConstraint.m_deltaVelBindex,ndofB);
  393. } else
  394. {
  395. if (rb1)
  396. bodyB->internalApplyImpulse(-solverConstraint.m_contactNormal2*bodyB->internalGetInvMass()*rb1->getLinearFactor(),-solverConstraint.m_angularComponentB,-(btScalar)solverConstraint.m_appliedImpulse);
  397. }
  398. }
  399. } else
  400. {
  401. solverConstraint.m_appliedImpulse = 0.f;
  402. }
  403. solverConstraint.m_appliedPushImpulse = 0.f;
  404. {
  405. btScalar positionalError = 0.f;
  406. btScalar velocityError = restitution - rel_vel;// * damping;
  407. btScalar erp = infoGlobal.m_erp2;
  408. if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold))
  409. {
  410. erp = infoGlobal.m_erp;
  411. }
  412. if (penetration>0)
  413. {
  414. positionalError = 0;
  415. velocityError = -penetration / infoGlobal.m_timeStep;
  416. } else
  417. {
  418. positionalError = -penetration * erp/infoGlobal.m_timeStep;
  419. }
  420. btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
  421. btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
  422. if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold))
  423. {
  424. //combine position and velocity into rhs
  425. solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;
  426. solverConstraint.m_rhsPenetration = 0.f;
  427. } else
  428. {
  429. //split position and velocity into rhs and m_rhsPenetration
  430. solverConstraint.m_rhs = velocityImpulse;
  431. solverConstraint.m_rhsPenetration = penetrationImpulse;
  432. }
  433. solverConstraint.m_cfm = 0.f;
  434. solverConstraint.m_lowerLimit = 0;
  435. solverConstraint.m_upperLimit = 1e10f;
  436. }
  437. }
  438. btMultiBodySolverConstraint& btMultiBodyConstraintSolver::addMultiBodyFrictionConstraint(const btVector3& normalAxis,btPersistentManifold* manifold,int frictionIndex,btManifoldPoint& cp,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip)
  439. {
  440. BT_PROFILE("addMultiBodyFrictionConstraint");
  441. btMultiBodySolverConstraint& solverConstraint = m_multiBodyFrictionContactConstraints.expandNonInitializing();
  442. solverConstraint.m_frictionIndex = frictionIndex;
  443. bool isFriction = true;
  444. const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0());
  445. const btMultiBodyLinkCollider* fcB = btMultiBodyLinkCollider::upcast(manifold->getBody1());
  446. btMultiBody* mbA = fcA? fcA->m_multiBody : 0;
  447. btMultiBody* mbB = fcB? fcB->m_multiBody : 0;
  448. int solverBodyIdA = mbA? -1 : getOrInitSolverBody(*colObj0,infoGlobal.m_timeStep);
  449. int solverBodyIdB = mbB ? -1 : getOrInitSolverBody(*colObj1,infoGlobal.m_timeStep);
  450. solverConstraint.m_solverBodyIdA = solverBodyIdA;
  451. solverConstraint.m_solverBodyIdB = solverBodyIdB;
  452. solverConstraint.m_multiBodyA = mbA;
  453. if (mbA)
  454. solverConstraint.m_linkA = fcA->m_link;
  455. solverConstraint.m_multiBodyB = mbB;
  456. if (mbB)
  457. solverConstraint.m_linkB = fcB->m_link;
  458. solverConstraint.m_originalContactPoint = &cp;
  459. setupMultiBodyContactConstraint(solverConstraint, normalAxis, cp, infoGlobal,relaxation,isFriction, desiredVelocity, cfmSlip);
  460. return solverConstraint;
  461. }
  462. void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal)
  463. {
  464. const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0());
  465. const btMultiBodyLinkCollider* fcB = btMultiBodyLinkCollider::upcast(manifold->getBody1());
  466. btMultiBody* mbA = fcA? fcA->m_multiBody : 0;
  467. btMultiBody* mbB = fcB? fcB->m_multiBody : 0;
  468. btCollisionObject* colObj0=0,*colObj1=0;
  469. colObj0 = (btCollisionObject*)manifold->getBody0();
  470. colObj1 = (btCollisionObject*)manifold->getBody1();
  471. int solverBodyIdA = mbA? -1 : getOrInitSolverBody(*colObj0,infoGlobal.m_timeStep);
  472. int solverBodyIdB = mbB ? -1 : getOrInitSolverBody(*colObj1,infoGlobal.m_timeStep);
  473. btSolverBody* solverBodyA = mbA ? 0 : &m_tmpSolverBodyPool[solverBodyIdA];
  474. btSolverBody* solverBodyB = mbB ? 0 : &m_tmpSolverBodyPool[solverBodyIdB];
  475. ///avoid collision response between two static objects
  476. // if (!solverBodyA || (solverBodyA->m_invMass.isZero() && (!solverBodyB || solverBodyB->m_invMass.isZero())))
  477. // return;
  478. int rollingFriction=1;
  479. for (int j=0;j<manifold->getNumContacts();j++)
  480. {
  481. btManifoldPoint& cp = manifold->getContactPoint(j);
  482. if (cp.getDistance() <= manifold->getContactProcessingThreshold())
  483. {
  484. btScalar relaxation;
  485. int frictionIndex = m_multiBodyNormalContactConstraints.size();
  486. btMultiBodySolverConstraint& solverConstraint = m_multiBodyNormalContactConstraints.expandNonInitializing();
  487. btRigidBody* rb0 = btRigidBody::upcast(colObj0);
  488. btRigidBody* rb1 = btRigidBody::upcast(colObj1);
  489. solverConstraint.m_solverBodyIdA = solverBodyIdA;
  490. solverConstraint.m_solverBodyIdB = solverBodyIdB;
  491. solverConstraint.m_multiBodyA = mbA;
  492. if (mbA)
  493. solverConstraint.m_linkA = fcA->m_link;
  494. solverConstraint.m_multiBodyB = mbB;
  495. if (mbB)
  496. solverConstraint.m_linkB = fcB->m_link;
  497. solverConstraint.m_originalContactPoint = &cp;
  498. bool isFriction = false;
  499. setupMultiBodyContactConstraint(solverConstraint, cp.m_normalWorldOnB,cp, infoGlobal, relaxation, isFriction);
  500. // const btVector3& pos1 = cp.getPositionWorldOnA();
  501. // const btVector3& pos2 = cp.getPositionWorldOnB();
  502. /////setup the friction constraints
  503. #define ENABLE_FRICTION
  504. #ifdef ENABLE_FRICTION
  505. solverConstraint.m_frictionIndex = frictionIndex;
  506. #if ROLLING_FRICTION
  507. btVector3 angVelA(0,0,0),angVelB(0,0,0);
  508. if (rb0)
  509. angVelA = rb0->getAngularVelocity();
  510. if (rb1)
  511. angVelB = rb1->getAngularVelocity();
  512. btVector3 relAngVel = angVelB-angVelA;
  513. if ((cp.m_combinedRollingFriction>0.f) && (rollingFriction>0))
  514. {
  515. //only a single rollingFriction per manifold
  516. rollingFriction--;
  517. if (relAngVel.length()>infoGlobal.m_singleAxisRollingFrictionThreshold)
  518. {
  519. relAngVel.normalize();
  520. applyAnisotropicFriction(colObj0,relAngVel,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
  521. applyAnisotropicFriction(colObj1,relAngVel,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
  522. if (relAngVel.length()>0.001)
  523. addRollingFrictionConstraint(relAngVel,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
  524. } else
  525. {
  526. addRollingFrictionConstraint(cp.m_normalWorldOnB,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
  527. btVector3 axis0,axis1;
  528. btPlaneSpace1(cp.m_normalWorldOnB,axis0,axis1);
  529. applyAnisotropicFriction(colObj0,axis0,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
  530. applyAnisotropicFriction(colObj1,axis0,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
  531. applyAnisotropicFriction(colObj0,axis1,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
  532. applyAnisotropicFriction(colObj1,axis1,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
  533. if (axis0.length()>0.001)
  534. addRollingFrictionConstraint(axis0,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
  535. if (axis1.length()>0.001)
  536. addRollingFrictionConstraint(axis1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
  537. }
  538. }
  539. #endif //ROLLING_FRICTION
  540. ///Bullet has several options to set the friction directions
  541. ///By default, each contact has only a single friction direction that is recomputed automatically very frame
  542. ///based on the relative linear velocity.
  543. ///If the relative velocity it zero, it will automatically compute a friction direction.
  544. ///You can also enable two friction directions, using the SOLVER_USE_2_FRICTION_DIRECTIONS.
  545. ///In that case, the second friction direction will be orthogonal to both contact normal and first friction direction.
  546. ///
  547. ///If you choose SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION, then the friction will be independent from the relative projected velocity.
  548. ///
  549. ///The user can manually override the friction directions for certain contacts using a contact callback,
  550. ///and set the cp.m_lateralFrictionInitialized to true
  551. ///In that case, you can set the target relative motion in each friction direction (cp.m_contactMotion1 and cp.m_contactMotion2)
  552. ///this will give a conveyor belt effect
  553. ///
  554. if (!(infoGlobal.m_solverMode & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING) || !cp.m_lateralFrictionInitialized)
  555. {/*
  556. cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel;
  557. btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2();
  558. if (!(infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION) && lat_rel_vel > SIMD_EPSILON)
  559. {
  560. cp.m_lateralFrictionDir1 *= 1.f/btSqrt(lat_rel_vel);
  561. if((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
  562. {
  563. cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB);
  564. cp.m_lateralFrictionDir2.normalize();//??
  565. applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
  566. applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
  567. addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
  568. }
  569. applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
  570. applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
  571. addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
  572. } else
  573. */
  574. {
  575. btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2);
  576. if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
  577. {
  578. applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
  579. applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
  580. addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir2,manifold,frictionIndex,cp,colObj0,colObj1, relaxation,infoGlobal);
  581. }
  582. applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
  583. applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
  584. addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir1,manifold,frictionIndex,cp,colObj0,colObj1, relaxation,infoGlobal);
  585. if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) && (infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION))
  586. {
  587. cp.m_lateralFrictionInitialized = true;
  588. }
  589. }
  590. } else
  591. {
  592. addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir1,manifold,frictionIndex,cp,colObj0,colObj1, relaxation,infoGlobal,cp.m_contactMotion1, cp.m_contactCFM1);
  593. if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
  594. addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir2,manifold,frictionIndex,cp,colObj0,colObj1, relaxation, infoGlobal,cp.m_contactMotion2, cp.m_contactCFM2);
  595. //setMultiBodyFrictionConstraintImpulse( solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal);
  596. //todo:
  597. solverConstraint.m_appliedImpulse = 0.f;
  598. solverConstraint.m_appliedPushImpulse = 0.f;
  599. }
  600. #endif //ENABLE_FRICTION
  601. }
  602. }
  603. }
  604. void btMultiBodyConstraintSolver::convertContacts(btPersistentManifold** manifoldPtr,int numManifolds, const btContactSolverInfo& infoGlobal)
  605. {
  606. btPersistentManifold* manifold = 0;
  607. for (int i=0;i<numManifolds;i++)
  608. {
  609. btPersistentManifold* manifold= manifoldPtr[i];
  610. const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0());
  611. const btMultiBodyLinkCollider* fcB = btMultiBodyLinkCollider::upcast(manifold->getBody1());
  612. if (!fcA && !fcB)
  613. {
  614. //the contact doesn't involve any Featherstone btMultiBody, so deal with the regular btRigidBody/btCollisionObject case
  615. convertContact(manifold,infoGlobal);
  616. } else
  617. {
  618. convertMultiBodyContact(manifold,infoGlobal);
  619. }
  620. }
  621. //also convert the multibody constraints, if any
  622. for (int i=0;i<m_tmpNumMultiBodyConstraints;i++)
  623. {
  624. btMultiBodyConstraint* c = m_tmpMultiBodyConstraints[i];
  625. m_data.m_solverBodyPool = &m_tmpSolverBodyPool;
  626. m_data.m_fixedBodyId = m_fixedBodyId;
  627. c->createConstraintRows(m_multiBodyNonContactConstraints,m_data, infoGlobal);
  628. }
  629. }
  630. btScalar btMultiBodyConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer,btDispatcher* dispatcher)
  631. {
  632. return btSequentialImpulseConstraintSolver::solveGroup(bodies,numBodies,manifold,numManifolds,constraints,numConstraints,info,debugDrawer,dispatcher);
  633. }
  634. void btMultiBodyConstraintSolver::solveMultiBodyGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,btMultiBodyConstraint** multiBodyConstraints, int numMultiBodyConstraints, const btContactSolverInfo& info, btIDebugDraw* debugDrawer,btDispatcher* dispatcher)
  635. {
  636. //printf("solveMultiBodyGroup start\n");
  637. m_tmpMultiBodyConstraints = multiBodyConstraints;
  638. m_tmpNumMultiBodyConstraints = numMultiBodyConstraints;
  639. btSequentialImpulseConstraintSolver::solveGroup(bodies,numBodies,manifold,numManifolds,constraints,numConstraints,info,debugDrawer,dispatcher);
  640. m_tmpMultiBodyConstraints = 0;
  641. m_tmpNumMultiBodyConstraints = 0;
  642. }