btReducedDeformableContactConstraint.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. #include "btReducedDeformableContactConstraint.h"
  2. #include <iostream>
  3. // ================= static constraints ===================
  4. btReducedDeformableStaticConstraint::btReducedDeformableStaticConstraint(
  5. btReducedDeformableBody* rsb,
  6. btSoftBody::Node* node,
  7. const btVector3& ri,
  8. const btVector3& x0,
  9. const btVector3& dir,
  10. const btContactSolverInfo& infoGlobal,
  11. btScalar dt)
  12. : m_rsb(rsb), m_ri(ri), m_targetPos(x0), m_impulseDirection(dir), m_dt(dt), btDeformableStaticConstraint(node, infoGlobal)
  13. {
  14. m_erp = 0.2;
  15. m_appliedImpulse = 0;
  16. // get impulse factor
  17. m_impulseFactorMatrix = rsb->getImpulseFactor(m_node->index);
  18. m_impulseFactor = (m_impulseFactorMatrix * m_impulseDirection).dot(m_impulseDirection);
  19. btScalar vel_error = btDot(-m_node->m_v, m_impulseDirection);
  20. btScalar pos_error = btDot(m_targetPos - m_node->m_x, m_impulseDirection);
  21. m_rhs = (vel_error + m_erp * pos_error / m_dt) / m_impulseFactor;
  22. }
  23. btScalar btReducedDeformableStaticConstraint::solveConstraint(const btContactSolverInfo& infoGlobal)
  24. {
  25. // target velocity of fixed constraint is 0
  26. btVector3 deltaVa = getDeltaVa();
  27. btScalar deltaV_rel = btDot(deltaVa, m_impulseDirection);
  28. btScalar deltaImpulse = m_rhs - deltaV_rel / m_impulseFactor;
  29. m_appliedImpulse = m_appliedImpulse + deltaImpulse;
  30. btVector3 impulse = deltaImpulse * m_impulseDirection;
  31. applyImpulse(impulse);
  32. // calculate residual
  33. btScalar residualSquare = m_impulseFactor * deltaImpulse;
  34. residualSquare *= residualSquare;
  35. return residualSquare;
  36. }
  37. // this calls reduced deformable body's internalApplyFullSpaceImpulse
  38. void btReducedDeformableStaticConstraint::applyImpulse(const btVector3& impulse)
  39. {
  40. // apply full space impulse
  41. m_rsb->internalApplyFullSpaceImpulse(impulse, m_ri, m_node->index, m_dt);
  42. }
  43. btVector3 btReducedDeformableStaticConstraint::getDeltaVa() const
  44. {
  45. return m_rsb->internalComputeNodeDeltaVelocity(m_rsb->getInterpolationWorldTransform(), m_node->index);
  46. }
  47. // ================= base contact constraints ===================
  48. btReducedDeformableRigidContactConstraint::btReducedDeformableRigidContactConstraint(
  49. btReducedDeformableBody* rsb,
  50. const btSoftBody::DeformableRigidContact& c,
  51. const btContactSolverInfo& infoGlobal,
  52. btScalar dt)
  53. : m_rsb(rsb), m_dt(dt), btDeformableRigidContactConstraint(c, infoGlobal)
  54. {
  55. m_nodeQueryIndex = 0;
  56. m_appliedNormalImpulse = 0;
  57. m_appliedTangentImpulse = 0;
  58. m_rhs = 0;
  59. m_rhs_tangent = 0;
  60. m_cfm = infoGlobal.m_deformable_cfm;
  61. m_cfm_friction = 0;
  62. m_erp = infoGlobal.m_deformable_erp;
  63. m_erp_friction = infoGlobal.m_deformable_erp;
  64. m_friction = infoGlobal.m_friction;
  65. m_collideStatic = m_contact->m_cti.m_colObj->isStaticObject();
  66. m_collideMultibody = (m_contact->m_cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK);
  67. }
  68. void btReducedDeformableRigidContactConstraint::setSolverBody(const int bodyId, btSolverBody& solver_body)
  69. {
  70. if (!m_collideMultibody)
  71. {
  72. m_solverBodyId = bodyId;
  73. m_solverBody = &solver_body;
  74. m_linearComponentNormal = -m_contactNormalA * m_solverBody->internalGetInvMass();
  75. btVector3 torqueAxis = -m_relPosA.cross(m_contactNormalA);
  76. m_angularComponentNormal = m_solverBody->m_originalBody->getInvInertiaTensorWorld() * torqueAxis;
  77. m_linearComponentTangent = m_contactTangent * m_solverBody->internalGetInvMass();
  78. btVector3 torqueAxisTangent = m_relPosA.cross(m_contactTangent);
  79. m_angularComponentTangent = m_solverBody->m_originalBody->getInvInertiaTensorWorld() * torqueAxisTangent;
  80. }
  81. }
  82. btVector3 btReducedDeformableRigidContactConstraint::getVa() const
  83. {
  84. btVector3 Va(0, 0, 0);
  85. if (!m_collideStatic)
  86. {
  87. Va = btDeformableRigidContactConstraint::getVa();
  88. }
  89. return Va;
  90. }
  91. btScalar btReducedDeformableRigidContactConstraint::solveConstraint(const btContactSolverInfo& infoGlobal)
  92. {
  93. // btVector3 Va = getVa();
  94. // btVector3 deltaVa = Va - m_bufferVelocityA;
  95. // if (!m_collideStatic)
  96. // {
  97. // std::cout << "moving collision!!!\n";
  98. // std::cout << "relPosA: " << m_relPosA[0] << "\t" << m_relPosA[1] << "\t" << m_relPosA[2] << "\n";
  99. // std::cout << "moving rigid linear_vel: " << m_solverBody->m_originalBody->getLinearVelocity()[0] << '\t'
  100. // << m_solverBody->m_originalBody->getLinearVelocity()[1] << '\t'
  101. // << m_solverBody->m_originalBody->getLinearVelocity()[2] << '\n';
  102. // }
  103. btVector3 deltaVa = getDeltaVa();
  104. btVector3 deltaVb = getDeltaVb();
  105. // if (!m_collideStatic)
  106. // {
  107. // std::cout << "deltaVa: " << deltaVa[0] << '\t' << deltaVa[1] << '\t' << deltaVa[2] << '\n';
  108. // std::cout << "deltaVb: " << deltaVb[0] << '\t' << deltaVb[1] << '\t' << deltaVb[2] << '\n';
  109. // }
  110. // get delta relative velocity and magnitude (i.e., how much impulse has been applied?)
  111. btVector3 deltaV_rel = deltaVa - deltaVb;
  112. btScalar deltaV_rel_normal = -btDot(deltaV_rel, m_contactNormalA);
  113. // if (!m_collideStatic)
  114. // {
  115. // std::cout << "deltaV_rel: " << deltaV_rel[0] << '\t' << deltaV_rel[1] << '\t' << deltaV_rel[2] << "\n";
  116. // std::cout << "deltaV_rel_normal: " << deltaV_rel_normal << "\n";
  117. // std::cout << "normal_A: " << m_contactNormalA[0] << '\t' << m_contactNormalA[1] << '\t' << m_contactNormalA[2] << '\n';
  118. // }
  119. // get the normal impulse to be applied
  120. btScalar deltaImpulse = m_rhs - m_appliedNormalImpulse * m_cfm - deltaV_rel_normal / m_normalImpulseFactor;
  121. // if (!m_collideStatic)
  122. // {
  123. // std::cout << "m_rhs: " << m_rhs << '\t' << "m_appliedNormalImpulse: " << m_appliedNormalImpulse << "\n";
  124. // std::cout << "m_normalImpulseFactor: " << m_normalImpulseFactor << '\n';
  125. // }
  126. {
  127. // cumulative impulse that has been applied
  128. btScalar sum = m_appliedNormalImpulse + deltaImpulse;
  129. // if the cumulative impulse is pushing the object into the rigid body, set it zero
  130. if (sum < 0)
  131. {
  132. deltaImpulse = -m_appliedNormalImpulse;
  133. m_appliedNormalImpulse = 0;
  134. }
  135. else
  136. {
  137. m_appliedNormalImpulse = sum;
  138. }
  139. }
  140. // if (!m_collideStatic)
  141. // {
  142. // std::cout << "m_appliedNormalImpulse: " << m_appliedNormalImpulse << '\n';
  143. // std::cout << "deltaImpulse: " << deltaImpulse << '\n';
  144. // }
  145. // residual is the nodal normal velocity change in current iteration
  146. btScalar residualSquare = deltaImpulse * m_normalImpulseFactor; // get residual
  147. residualSquare *= residualSquare;
  148. // apply Coulomb friction (based on delta velocity, |dv_t| = |dv_n * friction|)
  149. btScalar deltaImpulse_tangent = 0;
  150. btScalar deltaImpulse_tangent2 = 0;
  151. {
  152. // calculate how much impulse is needed
  153. // btScalar deltaV_rel_tangent = btDot(deltaV_rel, m_contactTangent);
  154. // btScalar impulse_changed = deltaV_rel_tangent * m_tangentImpulseFactorInv;
  155. // deltaImpulse_tangent = m_rhs_tangent - impulse_changed;
  156. // btScalar sum = m_appliedTangentImpulse + deltaImpulse_tangent;
  157. btScalar lower_limit = - m_appliedNormalImpulse * m_friction;
  158. btScalar upper_limit = m_appliedNormalImpulse * m_friction;
  159. // if (sum > upper_limit)
  160. // {
  161. // deltaImpulse_tangent = upper_limit - m_appliedTangentImpulse;
  162. // m_appliedTangentImpulse = upper_limit;
  163. // }
  164. // else if (sum < lower_limit)
  165. // {
  166. // deltaImpulse_tangent = lower_limit - m_appliedTangentImpulse;
  167. // m_appliedTangentImpulse = lower_limit;
  168. // }
  169. // else
  170. // {
  171. // m_appliedTangentImpulse = sum;
  172. // }
  173. //
  174. calculateTangentialImpulse(deltaImpulse_tangent, m_appliedTangentImpulse, m_rhs_tangent,
  175. m_tangentImpulseFactorInv, m_contactTangent, lower_limit, upper_limit, deltaV_rel);
  176. if (m_collideMultibody)
  177. {
  178. calculateTangentialImpulse(deltaImpulse_tangent2, m_appliedTangentImpulse2, m_rhs_tangent2,
  179. m_tangentImpulseFactorInv2, m_contactTangent2, lower_limit, upper_limit, deltaV_rel);
  180. }
  181. if (!m_collideStatic)
  182. {
  183. // std::cout << "m_contactTangent: " << m_contactTangent[0] << "\t" << m_contactTangent[1] << "\t" << m_contactTangent[2] << "\n";
  184. // std::cout << "deltaV_rel_tangent: " << deltaV_rel_tangent << '\n';
  185. // std::cout << "deltaImpulseTangent: " << deltaImpulse_tangent << '\n';
  186. // std::cout << "m_appliedTangentImpulse: " << m_appliedTangentImpulse << '\n';
  187. }
  188. }
  189. // get the total impulse vector
  190. btVector3 impulse_normal = deltaImpulse * m_contactNormalA;
  191. btVector3 impulse_tangent = deltaImpulse_tangent * (-m_contactTangent);
  192. btVector3 impulse_tangent2 = deltaImpulse_tangent2 * (-m_contactTangent2);
  193. btVector3 impulse = impulse_normal + impulse_tangent + impulse_tangent2;
  194. applyImpulse(impulse);
  195. // apply impulse to the rigid/multibodies involved and change their velocities
  196. if (!m_collideStatic)
  197. {
  198. // std::cout << "linear_component: " << m_linearComponentNormal[0] << '\t'
  199. // << m_linearComponentNormal[1] << '\t'
  200. // << m_linearComponentNormal[2] << '\n';
  201. // std::cout << "angular_component: " << m_angularComponentNormal[0] << '\t'
  202. // << m_angularComponentNormal[1] << '\t'
  203. // << m_angularComponentNormal[2] << '\n';
  204. if (!m_collideMultibody) // collision with rigid body
  205. {
  206. // std::cout << "rigid impulse applied!!\n";
  207. // std::cout << "delta Linear: " << m_solverBody->getDeltaLinearVelocity()[0] << '\t'
  208. // << m_solverBody->getDeltaLinearVelocity()[1] << '\t'
  209. // << m_solverBody->getDeltaLinearVelocity()[2] << '\n';
  210. // std::cout << "delta Angular: " << m_solverBody->getDeltaAngularVelocity()[0] << '\t'
  211. // << m_solverBody->getDeltaAngularVelocity()[1] << '\t'
  212. // << m_solverBody->getDeltaAngularVelocity()[2] << '\n';
  213. m_solverBody->internalApplyImpulse(m_linearComponentNormal, m_angularComponentNormal, deltaImpulse);
  214. m_solverBody->internalApplyImpulse(m_linearComponentTangent, m_angularComponentTangent, deltaImpulse_tangent);
  215. // std::cout << "after\n";
  216. // std::cout << "rigid impulse applied!!\n";
  217. // std::cout << "delta Linear: " << m_solverBody->getDeltaLinearVelocity()[0] << '\t'
  218. // << m_solverBody->getDeltaLinearVelocity()[1] << '\t'
  219. // << m_solverBody->getDeltaLinearVelocity()[2] << '\n';
  220. // std::cout << "delta Angular: " << m_solverBody->getDeltaAngularVelocity()[0] << '\t'
  221. // << m_solverBody->getDeltaAngularVelocity()[1] << '\t'
  222. // << m_solverBody->getDeltaAngularVelocity()[2] << '\n';
  223. }
  224. else // collision with multibody
  225. {
  226. btMultiBodyLinkCollider* multibodyLinkCol = 0;
  227. multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(m_contact->m_cti.m_colObj);
  228. if (multibodyLinkCol)
  229. {
  230. const btScalar* deltaV_normal = &m_contact->jacobianData_normal.m_deltaVelocitiesUnitImpulse[0];
  231. // apply normal component of the impulse
  232. multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof2(deltaV_normal, -deltaImpulse);
  233. // const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6;
  234. // std::cout << "deltaV_normal: ";
  235. // for (int i = 0; i < ndof; ++i)
  236. // {
  237. // std::cout << i << "\t" << deltaV_normal[i] << '\n';
  238. // }
  239. if (impulse_tangent.norm() > SIMD_EPSILON)
  240. {
  241. // apply tangential component of the impulse
  242. const btScalar* deltaV_t1 = &m_contact->jacobianData_t1.m_deltaVelocitiesUnitImpulse[0];
  243. multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof2(deltaV_t1, deltaImpulse_tangent);
  244. const btScalar* deltaV_t2 = &m_contact->jacobianData_t2.m_deltaVelocitiesUnitImpulse[0];
  245. multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof2(deltaV_t2, deltaImpulse_tangent2);
  246. }
  247. }
  248. }
  249. }
  250. return residualSquare;
  251. }
  252. void btReducedDeformableRigidContactConstraint::calculateTangentialImpulse(btScalar& deltaImpulse_tangent,
  253. btScalar& appliedImpulse,
  254. const btScalar rhs_tangent,
  255. const btScalar tangentImpulseFactorInv,
  256. const btVector3& tangent,
  257. const btScalar lower_limit,
  258. const btScalar upper_limit,
  259. const btVector3& deltaV_rel)
  260. {
  261. btScalar deltaV_rel_tangent = btDot(deltaV_rel, tangent);
  262. btScalar impulse_changed = deltaV_rel_tangent * tangentImpulseFactorInv;
  263. deltaImpulse_tangent = rhs_tangent - m_cfm_friction * appliedImpulse - impulse_changed;
  264. btScalar sum = appliedImpulse + deltaImpulse_tangent;
  265. if (sum > upper_limit)
  266. {
  267. deltaImpulse_tangent = upper_limit - appliedImpulse;
  268. appliedImpulse = upper_limit;
  269. }
  270. else if (sum < lower_limit)
  271. {
  272. deltaImpulse_tangent = lower_limit - appliedImpulse;
  273. appliedImpulse = lower_limit;
  274. }
  275. else
  276. {
  277. appliedImpulse = sum;
  278. }
  279. }
  280. // ================= node vs rigid constraints ===================
  281. btReducedDeformableNodeRigidContactConstraint::btReducedDeformableNodeRigidContactConstraint(
  282. btReducedDeformableBody* rsb,
  283. const btSoftBody::DeformableNodeRigidContact& contact,
  284. const btContactSolverInfo& infoGlobal,
  285. btScalar dt)
  286. : m_node(contact.m_node), btReducedDeformableRigidContactConstraint(rsb, contact, infoGlobal, dt)
  287. {
  288. m_contactNormalA = contact.m_cti.m_normal;
  289. m_contactNormalB = -contact.m_cti.m_normal;
  290. if (contact.m_node->index < rsb->m_nodes.size())
  291. {
  292. m_nodeQueryIndex = contact.m_node->index;
  293. }
  294. else
  295. {
  296. m_nodeQueryIndex = m_node->index - rsb->m_nodeIndexOffset;
  297. }
  298. if (m_contact->m_cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY)
  299. {
  300. m_relPosA = contact.m_c1;
  301. }
  302. else
  303. {
  304. m_relPosA = btVector3(0,0,0);
  305. }
  306. m_relPosB = m_node->m_x - m_rsb->getRigidTransform().getOrigin();
  307. if (m_collideStatic) // colliding with static object, only consider reduced deformable body's impulse factor
  308. {
  309. m_impulseFactor = m_rsb->getImpulseFactor(m_nodeQueryIndex);
  310. }
  311. else // colliding with dynamic object, consider both reduced deformable and rigid body's impulse factors
  312. {
  313. m_impulseFactor = m_rsb->getImpulseFactor(m_nodeQueryIndex) + contact.m_c0;
  314. }
  315. m_normalImpulseFactor = (m_impulseFactor * m_contactNormalA).dot(m_contactNormalA);
  316. m_tangentImpulseFactor = 0;
  317. warmStarting();
  318. }
  319. void btReducedDeformableNodeRigidContactConstraint::warmStarting()
  320. {
  321. btVector3 va = getVa();
  322. btVector3 vb = getVb();
  323. m_bufferVelocityA = va;
  324. m_bufferVelocityB = vb;
  325. // we define the (+) direction of errors to be the outward surface normal of the rigid object
  326. btVector3 v_rel = vb - va;
  327. // get tangent direction of the relative velocity
  328. btVector3 v_tangent = v_rel - v_rel.dot(m_contactNormalA) * m_contactNormalA;
  329. if (v_tangent.norm() < SIMD_EPSILON)
  330. {
  331. m_contactTangent = btVector3(0, 0, 0);
  332. // tangent impulse factor
  333. m_tangentImpulseFactor = 0;
  334. m_tangentImpulseFactorInv = 0;
  335. }
  336. else
  337. {
  338. if (!m_collideMultibody)
  339. {
  340. m_contactTangent = v_tangent.normalized();
  341. m_contactTangent2.setZero();
  342. // tangent impulse factor 1
  343. m_tangentImpulseFactor = (m_impulseFactor * m_contactTangent).dot(m_contactTangent);
  344. m_tangentImpulseFactorInv = btScalar(1) / m_tangentImpulseFactor;
  345. // tangent impulse factor 2
  346. m_tangentImpulseFactor2 = 0;
  347. m_tangentImpulseFactorInv2 = 0;
  348. }
  349. else // multibody requires 2 contact directions
  350. {
  351. m_contactTangent = m_contact->t1;
  352. m_contactTangent2 = m_contact->t2;
  353. // tangent impulse factor 1
  354. m_tangentImpulseFactor = (m_impulseFactor * m_contactTangent).dot(m_contactTangent);
  355. m_tangentImpulseFactorInv = btScalar(1) / m_tangentImpulseFactor;
  356. // tangent impulse factor 2
  357. m_tangentImpulseFactor2 = (m_impulseFactor * m_contactTangent2).dot(m_contactTangent2);
  358. m_tangentImpulseFactorInv2 = btScalar(1) / m_tangentImpulseFactor2;
  359. }
  360. }
  361. // initial guess for normal impulse
  362. {
  363. btScalar velocity_error = btDot(v_rel, m_contactNormalA); // magnitude of relative velocity
  364. btScalar position_error = 0;
  365. if (m_penetration > 0)
  366. {
  367. velocity_error += m_penetration / m_dt;
  368. }
  369. else
  370. {
  371. // add penetration correction vel
  372. position_error = m_penetration * m_erp / m_dt;
  373. }
  374. // get the initial estimate of impulse magnitude to be applied
  375. m_rhs = -(velocity_error + position_error) / m_normalImpulseFactor;
  376. }
  377. // initial guess for tangential impulse
  378. {
  379. btScalar velocity_error = btDot(v_rel, m_contactTangent);
  380. m_rhs_tangent = velocity_error * m_tangentImpulseFactorInv;
  381. if (m_collideMultibody)
  382. {
  383. btScalar velocity_error2 = btDot(v_rel, m_contactTangent2);
  384. m_rhs_tangent2 = velocity_error2 * m_tangentImpulseFactorInv2;
  385. }
  386. }
  387. // warm starting
  388. // applyImpulse(m_rhs * m_contactNormalA);
  389. // if (!m_collideStatic)
  390. // {
  391. // const btSoftBody::sCti& cti = m_contact->m_cti;
  392. // if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY)
  393. // {
  394. // m_solverBody->internalApplyImpulse(m_linearComponentNormal, m_angularComponentNormal, -m_rhs);
  395. // }
  396. // }
  397. }
  398. btVector3 btReducedDeformableNodeRigidContactConstraint::getVb() const
  399. {
  400. return m_node->m_v;
  401. }
  402. btVector3 btReducedDeformableNodeRigidContactConstraint::getDeltaVa() const
  403. {
  404. btVector3 deltaVa(0, 0, 0);
  405. if (!m_collideStatic)
  406. {
  407. if (!m_collideMultibody) // for rigid body
  408. {
  409. deltaVa = m_solverBody->internalGetDeltaLinearVelocity() + m_solverBody->internalGetDeltaAngularVelocity().cross(m_relPosA);
  410. }
  411. else // for multibody
  412. {
  413. btMultiBodyLinkCollider* multibodyLinkCol = 0;
  414. multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(m_contact->m_cti.m_colObj);
  415. if (multibodyLinkCol)
  416. {
  417. const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6;
  418. const btScalar* J_n = &m_contact->jacobianData_normal.m_jacobians[0];
  419. const btScalar* J_t1 = &m_contact->jacobianData_t1.m_jacobians[0];
  420. const btScalar* J_t2 = &m_contact->jacobianData_t2.m_jacobians[0];
  421. const btScalar* local_dv = multibodyLinkCol->m_multiBody->getDeltaVelocityVector();
  422. // add in the normal component of the va
  423. btScalar vel = 0;
  424. for (int k = 0; k < ndof; ++k)
  425. {
  426. vel += local_dv[k] * J_n[k];
  427. }
  428. deltaVa = m_contact->m_cti.m_normal * vel;
  429. // add in the tangential components of the va
  430. vel = 0;
  431. for (int k = 0; k < ndof; ++k)
  432. {
  433. vel += local_dv[k] * J_t1[k];
  434. }
  435. deltaVa += m_contact->t1 * vel;
  436. vel = 0;
  437. for (int k = 0; k < ndof; ++k)
  438. {
  439. vel += local_dv[k] * J_t2[k];
  440. }
  441. deltaVa += m_contact->t2 * vel;
  442. }
  443. }
  444. }
  445. return deltaVa;
  446. }
  447. btVector3 btReducedDeformableNodeRigidContactConstraint::getDeltaVb() const
  448. {
  449. // std::cout << "node: " << m_node->index << '\n';
  450. return m_rsb->internalComputeNodeDeltaVelocity(m_rsb->getInterpolationWorldTransform(), m_nodeQueryIndex);
  451. }
  452. btVector3 btReducedDeformableNodeRigidContactConstraint::getSplitVb() const
  453. {
  454. return m_node->m_splitv;
  455. }
  456. btVector3 btReducedDeformableNodeRigidContactConstraint::getDv(const btSoftBody::Node* node) const
  457. {
  458. return m_total_normal_dv + m_total_tangent_dv;
  459. }
  460. void btReducedDeformableNodeRigidContactConstraint::applyImpulse(const btVector3& impulse)
  461. {
  462. m_rsb->internalApplyFullSpaceImpulse(impulse, m_relPosB, m_nodeQueryIndex, m_dt);
  463. // m_rsb->applyFullSpaceImpulse(impulse, m_relPosB, m_node->index, m_dt);
  464. // m_rsb->mapToFullVelocity(m_rsb->getInterpolationWorldTransform());
  465. // if (!m_collideStatic)
  466. // {
  467. // // std::cout << "impulse applied: " << impulse[0] << '\t' << impulse[1] << '\t' << impulse[2] << '\n';
  468. // // std::cout << "node: " << m_node->index << " vel: " << m_node->m_v[0] << '\t' << m_node->m_v[1] << '\t' << m_node->m_v[2] << '\n';
  469. // btVector3 v_after = getDeltaVb() + m_node->m_v;
  470. // // std::cout << "vel after: " << v_after[0] << '\t' << v_after[1] << '\t' << v_after[2] << '\n';
  471. // }
  472. // std::cout << "node: " << m_node->index << " pos: " << m_node->m_x[0] << '\t' << m_node->m_x[1] << '\t' << m_node->m_x[2] << '\n';
  473. }
  474. // ================= face vs rigid constraints ===================
  475. btReducedDeformableFaceRigidContactConstraint::btReducedDeformableFaceRigidContactConstraint(
  476. btReducedDeformableBody* rsb,
  477. const btSoftBody::DeformableFaceRigidContact& contact,
  478. const btContactSolverInfo& infoGlobal,
  479. btScalar dt,
  480. bool useStrainLimiting)
  481. : m_face(contact.m_face), m_useStrainLimiting(useStrainLimiting), btReducedDeformableRigidContactConstraint(rsb, contact, infoGlobal, dt)
  482. {}
  483. btVector3 btReducedDeformableFaceRigidContactConstraint::getVb() const
  484. {
  485. const btSoftBody::DeformableFaceRigidContact* contact = getContact();
  486. btVector3 vb = m_face->m_n[0]->m_v * contact->m_bary[0] + m_face->m_n[1]->m_v * contact->m_bary[1] + m_face->m_n[2]->m_v * contact->m_bary[2];
  487. return vb;
  488. }
  489. btVector3 btReducedDeformableFaceRigidContactConstraint::getSplitVb() const
  490. {
  491. const btSoftBody::DeformableFaceRigidContact* contact = getContact();
  492. btVector3 vb = (m_face->m_n[0]->m_splitv) * contact->m_bary[0] + (m_face->m_n[1]->m_splitv) * contact->m_bary[1] + (m_face->m_n[2]->m_splitv) * contact->m_bary[2];
  493. return vb;
  494. }
  495. btVector3 btReducedDeformableFaceRigidContactConstraint::getDv(const btSoftBody::Node* node) const
  496. {
  497. btVector3 face_dv = m_total_normal_dv + m_total_tangent_dv;
  498. const btSoftBody::DeformableFaceRigidContact* contact = getContact();
  499. if (m_face->m_n[0] == node)
  500. {
  501. return face_dv * contact->m_weights[0];
  502. }
  503. if (m_face->m_n[1] == node)
  504. {
  505. return face_dv * contact->m_weights[1];
  506. }
  507. btAssert(node == m_face->m_n[2]);
  508. return face_dv * contact->m_weights[2];
  509. }
  510. void btReducedDeformableFaceRigidContactConstraint::applyImpulse(const btVector3& impulse)
  511. {
  512. //
  513. }