Bullet Collision Detection & Physics Library
btDeformableContactConstraint.cpp
Go to the documentation of this file.
1/*
2 Written by Xuchen Han <xuchenhan2015@u.northwestern.edu>
3
4 Bullet Continuous Collision Detection and Physics Library
5 Copyright (c) 2019 Google Inc. http://bulletphysics.org
6 This software is provided 'as-is', without any express or implied warranty.
7 In no event will the authors be held liable for any damages arising from the use of this software.
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it freely,
10 subject to the following restrictions:
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15
17/* ================ Deformable Node Anchor =================== */
19 : m_anchor(&a), btDeformableContactConstraint(a.m_cti.m_normal, infoGlobal)
20{
21}
22
24 : m_anchor(other.m_anchor), btDeformableContactConstraint(other)
25{
26}
27
29{
30 const btSoftBody::sCti& cti = m_anchor->m_cti;
31 btVector3 va(0, 0, 0);
33 {
34 btRigidBody* rigidCol = 0;
35 btMultiBodyLinkCollider* multibodyLinkCol = 0;
36
37 // grab the velocity of the rigid body
39 {
41 va = rigidCol ? (rigidCol->getVelocityInLocalPoint(m_anchor->m_c1)) : btVector3(0, 0, 0);
42 }
44 {
46 if (multibodyLinkCol)
47 {
48 const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6;
52 const btScalar* local_v = multibodyLinkCol->m_multiBody->getVelocityVector();
53 const btScalar* local_dv = multibodyLinkCol->m_multiBody->getDeltaVelocityVector();
54 // add in the normal component of the va
55 btScalar vel = 0.0;
56 for (int k = 0; k < ndof; ++k)
57 {
58 vel += (local_v[k] + local_dv[k]) * J_n[k];
59 }
60 va = cti.m_normal * vel;
61 // add in the tangential components of the va
62 vel = 0.0;
63 for (int k = 0; k < ndof; ++k)
64 {
65 vel += (local_v[k] + local_dv[k]) * J_t1[k];
66 }
67 va += m_anchor->t1 * vel;
68 vel = 0.0;
69 for (int k = 0; k < ndof; ++k)
70 {
71 vel += (local_v[k] + local_dv[k]) * J_t2[k];
72 }
73 va += m_anchor->t2 * vel;
74 }
75 }
76 }
77 return va;
78}
79
81{
82 const btSoftBody::sCti& cti = m_anchor->m_cti;
83 btVector3 va = getVa();
84 btVector3 vb = getVb();
85 btVector3 vr = (vb - va);
86 // + (m_anchor->m_node->m_x - cti.m_colObj->getWorldTransform() * m_anchor->m_local) * 10.0
87 const btScalar dn = btDot(vr, vr);
88 // dn is the normal component of velocity diffrerence. Approximates the residual. // todo xuchenhan@: this prob needs to be scaled by dt
89 btScalar residualSquare = dn * dn;
90 btVector3 impulse = m_anchor->m_c0 * vr;
91 // apply impulse to deformable nodes involved and change their velocities
92 applyImpulse(impulse);
93
94 // apply impulse to the rigid/multibodies involved and change their velocities
96 {
97 btRigidBody* rigidCol = 0;
99 if (rigidCol)
100 {
101 rigidCol->applyImpulse(impulse, m_anchor->m_c1);
102 }
103 }
105 {
106 btMultiBodyLinkCollider* multibodyLinkCol = 0;
108 if (multibodyLinkCol)
109 {
111 // apply normal component of the impulse
112 multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof2(deltaV_normal, impulse.dot(cti.m_normal));
113 // apply tangential component of the impulse
115 multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof2(deltaV_t1, impulse.dot(m_anchor->t1));
117 multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof2(deltaV_t2, impulse.dot(m_anchor->t2));
118 }
119 }
120 return residualSquare;
121}
122
124{
125 return m_anchor->m_node->m_v;
126}
127
129{
130 btVector3 dv = impulse * m_anchor->m_c2;
131 m_anchor->m_node->m_v -= dv;
132}
133
134/* ================ Deformable vs. Rigid =================== */
136 : m_contact(&c), btDeformableContactConstraint(c.m_cti.m_normal, infoGlobal)
137{
140 // The magnitude of penetration is the depth of penetration.
143 m_binding = false;
144}
145
147 : m_contact(other.m_contact), btDeformableContactConstraint(other), m_penetration(other.m_penetration), m_total_split_impulse(other.m_total_split_impulse), m_binding(other.m_binding)
148{
151}
152
154{
155 const btSoftBody::sCti& cti = m_contact->m_cti;
156 btVector3 va(0, 0, 0);
157 if (cti.m_colObj->hasContactResponse())
158 {
159 btRigidBody* rigidCol = 0;
160 btMultiBodyLinkCollider* multibodyLinkCol = 0;
161
162 // grab the velocity of the rigid body
164 {
165 rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj);
166 va = rigidCol ? (rigidCol->getVelocityInLocalPoint(m_contact->m_c1)) : btVector3(0, 0, 0);
167 }
169 {
171 if (multibodyLinkCol)
172 {
173 const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6;
177 const btScalar* local_v = multibodyLinkCol->m_multiBody->getVelocityVector();
178 const btScalar* local_dv = multibodyLinkCol->m_multiBody->getDeltaVelocityVector();
179 // add in the normal component of the va
180 btScalar vel = 0.0;
181 for (int k = 0; k < ndof; ++k)
182 {
183 vel += (local_v[k] + local_dv[k]) * J_n[k];
184 }
185 va = cti.m_normal * vel;
186 // add in the tangential components of the va
187 vel = 0.0;
188 for (int k = 0; k < ndof; ++k)
189 {
190 vel += (local_v[k] + local_dv[k]) * J_t1[k];
191 }
192 va += m_contact->t1 * vel;
193 vel = 0.0;
194 for (int k = 0; k < ndof; ++k)
195 {
196 vel += (local_v[k] + local_dv[k]) * J_t2[k];
197 }
198 va += m_contact->t2 * vel;
199 }
200 }
201 }
202 return va;
203}
204
206{
207 const btSoftBody::sCti& cti = m_contact->m_cti;
208 btVector3 va(0, 0, 0);
209 if (cti.m_colObj->hasContactResponse())
210 {
211 btRigidBody* rigidCol = 0;
212 btMultiBodyLinkCollider* multibodyLinkCol = 0;
213
214 // grab the velocity of the rigid body
216 {
217 rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj);
218 va = rigidCol ? (rigidCol->getPushVelocityInLocalPoint(m_contact->m_c1)) : btVector3(0, 0, 0);
219 }
221 {
223 if (multibodyLinkCol)
224 {
225 const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6;
229 const btScalar* local_split_v = multibodyLinkCol->m_multiBody->getSplitVelocityVector();
230 // add in the normal component of the va
231 btScalar vel = 0.0;
232 for (int k = 0; k < ndof; ++k)
233 {
234 vel += local_split_v[k] * J_n[k];
235 }
236 va = cti.m_normal * vel;
237 // add in the tangential components of the va
238 vel = 0.0;
239 for (int k = 0; k < ndof; ++k)
240 {
241 vel += local_split_v[k] * J_t1[k];
242 }
243 va += m_contact->t1 * vel;
244 vel = 0.0;
245 for (int k = 0; k < ndof; ++k)
246 {
247 vel += local_split_v[k] * J_t2[k];
248 }
249 va += m_contact->t2 * vel;
250 }
251 }
252 }
253 return va;
254}
255
257{
258 const btSoftBody::sCti& cti = m_contact->m_cti;
259 btVector3 va = getVa();
260 btVector3 vb = getVb();
261 btVector3 vr = vb - va;
262 btScalar dn = btDot(vr, cti.m_normal) + m_total_normal_dv.dot(cti.m_normal) * infoGlobal.m_deformable_cfm;
263 if (m_penetration > 0)
264 {
265 dn += m_penetration / infoGlobal.m_timeStep;
266 }
267 if (!infoGlobal.m_splitImpulse)
268 {
269 dn += m_penetration * infoGlobal.m_deformable_erp / infoGlobal.m_timeStep;
270 }
271 // dn is the normal component of velocity difference. Approximates the residual. // todo xuchenhan@: this prob needs to be scaled by dt
272 btVector3 impulse = m_contact->m_c0 * (vr + m_total_normal_dv * infoGlobal.m_deformable_cfm + ((m_penetration > 0) ? m_penetration / infoGlobal.m_timeStep * cti.m_normal : btVector3(0, 0, 0)));
273 if (!infoGlobal.m_splitImpulse)
274 {
275 impulse += m_contact->m_c0 * (m_penetration * infoGlobal.m_deformable_erp / infoGlobal.m_timeStep * cti.m_normal);
276 }
277 btVector3 impulse_normal = m_contact->m_c0 * (cti.m_normal * dn);
278 btVector3 impulse_tangent = impulse - impulse_normal;
279 if (dn > 0)
280 {
281 return 0;
282 }
283 m_binding = true;
284 btScalar residualSquare = dn * dn;
285 btVector3 old_total_tangent_dv = m_total_tangent_dv;
286 // m_c5 is the inverse mass of the deformable node/face
287 m_total_normal_dv -= m_contact->m_c5 * impulse_normal;
288 m_total_tangent_dv -= m_contact->m_c5 * impulse_tangent;
289
290 if (m_total_normal_dv.dot(cti.m_normal) < 0)
291 {
292 // separating in the normal direction
293 m_binding = false;
294 m_static = false;
295 impulse_tangent.setZero();
296 }
297 else
298 {
300 {
301 // dynamic friction
302 // with dynamic friction, the impulse are still applied to the two objects colliding, however, it does not pose a constraint in the cg solve, hence the change to dv merely serves to update velocity in the contact iterations.
303 m_static = false;
305 {
306 m_total_tangent_dv = btVector3(0, 0, 0);
307 }
308 else
309 {
311 }
312 // impulse_tangent = -btScalar(1)/m_contact->m_c2 * (m_total_tangent_dv - old_total_tangent_dv);
313 impulse_tangent = m_contact->m_c5.inverse() * (old_total_tangent_dv - m_total_tangent_dv);
314 }
315 else
316 {
317 // static friction
318 m_static = true;
319 }
320 }
321 impulse = impulse_normal + impulse_tangent;
322 // apply impulse to deformable nodes involved and change their velocities
323 applyImpulse(impulse);
324 // apply impulse to the rigid/multibodies involved and change their velocities
326 {
327 btRigidBody* rigidCol = 0;
328 rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj);
329 if (rigidCol)
330 {
331 rigidCol->applyImpulse(impulse, m_contact->m_c1);
332 }
333 }
335 {
336 btMultiBodyLinkCollider* multibodyLinkCol = 0;
338 if (multibodyLinkCol)
339 {
341 // apply normal component of the impulse
342 multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof2(deltaV_normal, impulse.dot(cti.m_normal));
343 if (impulse_tangent.norm() > SIMD_EPSILON)
344 {
345 // apply tangential component of the impulse
347 multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof2(deltaV_t1, impulse.dot(m_contact->t1));
349 multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof2(deltaV_t2, impulse.dot(m_contact->t2));
350 }
351 }
352 }
353 return residualSquare;
354}
355
357{
358 btScalar MAX_PENETRATION_CORRECTION = infoGlobal.m_deformable_maxErrorReduction;
359 const btSoftBody::sCti& cti = m_contact->m_cti;
360 btVector3 vb = getSplitVb();
361 btVector3 va = getSplitVa();
363 if (p > 0)
364 {
365 return 0;
366 }
367 btVector3 vr = vb - va;
368 btScalar dn = btDot(vr, cti.m_normal) + p * infoGlobal.m_deformable_erp / infoGlobal.m_timeStep;
369 if (dn > 0)
370 {
371 return 0;
372 }
373 if (m_total_split_impulse + dn > MAX_PENETRATION_CORRECTION)
374 {
375 dn = MAX_PENETRATION_CORRECTION - m_total_split_impulse;
376 }
377 if (m_total_split_impulse + dn < -MAX_PENETRATION_CORRECTION)
378 {
379 dn = -MAX_PENETRATION_CORRECTION - m_total_split_impulse;
380 }
382
383 btScalar residualSquare = dn * dn;
384 const btVector3 impulse = m_contact->m_c0 * (cti.m_normal * dn);
385 applySplitImpulse(impulse);
386
387 // apply split impulse to the rigid/multibodies involved and change their velocities
389 {
390 btRigidBody* rigidCol = 0;
391 rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj);
392 if (rigidCol)
393 {
394 rigidCol->applyPushImpulse(impulse, m_contact->m_c1);
395 }
396 }
398 {
399 btMultiBodyLinkCollider* multibodyLinkCol = 0;
401 if (multibodyLinkCol)
402 {
404 // apply normal component of the impulse
405 multibodyLinkCol->m_multiBody->applyDeltaSplitVeeMultiDof(deltaV_normal, impulse.dot(cti.m_normal));
406 }
407 }
408 return residualSquare;
409}
410/* ================ Node vs. Rigid =================== */
412 : m_node(contact.m_node), btDeformableRigidContactConstraint(contact, infoGlobal)
413{
414}
415
417 : m_node(other.m_node), btDeformableRigidContactConstraint(other)
418{
419}
420
422{
423 return m_node->m_v;
424}
425
427{
428 return m_node->m_splitv;
429}
430
432{
434}
435
437{
439 btVector3 dv = contact->m_c5 * impulse;
440 contact->m_node->m_v -= dv;
441}
442
444{
446 btVector3 dv = contact->m_c5 * impulse;
447 contact->m_node->m_splitv -= dv;
448}
449
450/* ================ Face vs. Rigid =================== */
452 : m_face(contact.m_face), m_useStrainLimiting(useStrainLimiting), btDeformableRigidContactConstraint(contact, infoGlobal)
453{
454}
455
457 : m_face(other.m_face), m_useStrainLimiting(other.m_useStrainLimiting), btDeformableRigidContactConstraint(other)
458{
459}
460
462{
464 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];
465 return vb;
466}
467
469{
472 if (m_face->m_n[0] == node)
473 {
474 return face_dv * contact->m_weights[0];
475 }
476 if (m_face->m_n[1] == node)
477 {
478 return face_dv * contact->m_weights[1];
479 }
480 btAssert(node == m_face->m_n[2]);
481 return face_dv * contact->m_weights[2];
482}
483
485{
487 btVector3 dv = impulse * contact->m_c2;
488 btSoftBody::Face* face = contact->m_face;
489
490 // save applied impulse
491 contact->m_cti.m_impulse = impulse;
492
493 btVector3& v0 = face->m_n[0]->m_v;
494 btVector3& v1 = face->m_n[1]->m_v;
495 btVector3& v2 = face->m_n[2]->m_v;
496 const btScalar& im0 = face->m_n[0]->m_im;
497 const btScalar& im1 = face->m_n[1]->m_im;
498 const btScalar& im2 = face->m_n[2]->m_im;
499 if (im0 > 0)
500 v0 -= dv * contact->m_weights[0];
501 if (im1 > 0)
502 v1 -= dv * contact->m_weights[1];
503 if (im2 > 0)
504 v2 -= dv * contact->m_weights[2];
506 {
507 btScalar relaxation = 1. / btScalar(m_infoGlobal->m_numIterations);
508 btScalar m01 = (relaxation / (im0 + im1));
509 btScalar m02 = (relaxation / (im0 + im2));
510 btScalar m12 = (relaxation / (im1 + im2));
511#ifdef USE_STRAIN_RATE_LIMITING
512 // apply strain limiting to prevent the new velocity to change the current length of the edge by more than 1%.
513 btScalar p = 0.01;
514 btVector3& x0 = face->m_n[0]->m_x;
515 btVector3& x1 = face->m_n[1]->m_x;
516 btVector3& x2 = face->m_n[2]->m_x;
517 const btVector3 x_diff[3] = {x1 - x0, x2 - x0, x2 - x1};
518 const btVector3 v_diff[3] = {v1 - v0, v2 - v0, v2 - v1};
519 btVector3 u[3];
520 btScalar x_diff_dot_u, dn[3];
522 for (int i = 0; i < 3; ++i)
523 {
524 btScalar x_diff_norm = x_diff[i].safeNorm();
525 btScalar x_diff_norm_new = (x_diff[i] + v_diff[i] * dt).safeNorm();
526 btScalar strainRate = x_diff_norm_new / x_diff_norm;
527 u[i] = v_diff[i];
528 u[i].safeNormalize();
529 if (x_diff_norm == 0 || (1 - p <= strainRate && strainRate <= 1 + p))
530 {
531 dn[i] = 0;
532 continue;
533 }
534 x_diff_dot_u = btDot(x_diff[i], u[i]);
535 btScalar s;
536 if (1 - p > strainRate)
537 {
538 s = 1 / dt * (-x_diff_dot_u - btSqrt(x_diff_dot_u * x_diff_dot_u + (p * p - 2 * p) * x_diff_norm * x_diff_norm));
539 }
540 else
541 {
542 s = 1 / dt * (-x_diff_dot_u + btSqrt(x_diff_dot_u * x_diff_dot_u + (p * p + 2 * p) * x_diff_norm * x_diff_norm));
543 }
544 // x_diff_norm_new = (x_diff[i] + s * u[i] * dt).safeNorm();
545 // strainRate = x_diff_norm_new/x_diff_norm;
546 dn[i] = s - v_diff[i].safeNorm();
547 }
548 btVector3 dv0 = im0 * (m01 * u[0] * (-dn[0]) + m02 * u[1] * -(dn[1]));
549 btVector3 dv1 = im1 * (m01 * u[0] * (dn[0]) + m12 * u[2] * (-dn[2]));
550 btVector3 dv2 = im2 * (m12 * u[2] * (dn[2]) + m02 * u[1] * (dn[1]));
551#else
552 // apply strain limiting to prevent undamped modes
553 btVector3 dv0 = im0 * (m01 * (v1 - v0) + m02 * (v2 - v0));
554 btVector3 dv1 = im1 * (m01 * (v0 - v1) + m12 * (v2 - v1));
555 btVector3 dv2 = im2 * (m12 * (v1 - v2) + m02 * (v0 - v2));
556#endif
557 v0 += dv0;
558 v1 += dv1;
559 v2 += dv2;
560 }
561}
562
564{
566 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];
567 return vb;
568}
569
571{
573 btVector3 dv = impulse * contact->m_c2;
574 btSoftBody::Face* face = contact->m_face;
575 btVector3& v0 = face->m_n[0]->m_splitv;
576 btVector3& v1 = face->m_n[1]->m_splitv;
577 btVector3& v2 = face->m_n[2]->m_splitv;
578 const btScalar& im0 = face->m_n[0]->m_im;
579 const btScalar& im1 = face->m_n[1]->m_im;
580 const btScalar& im2 = face->m_n[2]->m_im;
581 if (im0 > 0)
582 {
583 v0 -= dv * contact->m_weights[0];
584 }
585 if (im1 > 0)
586 {
587 v1 -= dv * contact->m_weights[1];
588 }
589 if (im2 > 0)
590 {
591 v2 -= dv * contact->m_weights[2];
592 }
593}
594
595/* ================ Face vs. Node =================== */
597 : m_node(contact.m_node), m_face(contact.m_face), m_contact(&contact), btDeformableContactConstraint(contact.m_normal, infoGlobal)
598{
601}
602
604{
605 return m_node->m_v;
606}
607
609{
611 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];
612 return vb;
613}
614
616{
618 if (n == m_node)
619 return dv;
621 if (m_face->m_n[0] == n)
622 {
623 return dv * contact->m_weights[0];
624 }
625 if (m_face->m_n[1] == n)
626 {
627 return dv * contact->m_weights[1];
628 }
629 btAssert(n == m_face->m_n[2]);
630 return dv * contact->m_weights[2];
631}
632
634{
635 btVector3 va = getVa();
636 btVector3 vb = getVb();
637 btVector3 vr = vb - va;
638 const btScalar dn = btDot(vr, m_contact->m_normal);
639 // dn is the normal component of velocity diffrerence. Approximates the residual. // todo xuchenhan@: this prob needs to be scaled by dt
640 btScalar residualSquare = dn * dn;
641 btVector3 impulse = m_contact->m_c0 * vr;
642 const btVector3 impulse_normal = m_contact->m_c0 * (m_contact->m_normal * dn);
643 btVector3 impulse_tangent = impulse - impulse_normal;
644
645 btVector3 old_total_tangent_dv = m_total_tangent_dv;
646 // m_c2 is the inverse mass of the deformable node/face
647 if (m_node->m_im > 0)
648 {
649 m_total_normal_dv -= impulse_normal * m_node->m_im;
650 m_total_tangent_dv -= impulse_tangent * m_node->m_im;
651 }
652 else
653 {
654 m_total_normal_dv -= impulse_normal * m_contact->m_imf;
655 m_total_tangent_dv -= impulse_tangent * m_contact->m_imf;
656 }
657
659 {
660 // separating in the normal direction
661 m_static = false;
662 m_total_tangent_dv = btVector3(0, 0, 0);
663 impulse_tangent.setZero();
664 }
665 else
666 {
668 {
669 // dynamic friction
670 // with dynamic friction, the impulse are still applied to the two objects colliding, however, it does not pose a constraint in the cg solve, hence the change to dv merely serves to update velocity in the contact iterations.
671 m_static = false;
673 {
674 m_total_tangent_dv = btVector3(0, 0, 0);
675 }
676 else
677 {
679 }
680 impulse_tangent = -btScalar(1) / m_node->m_im * (m_total_tangent_dv - old_total_tangent_dv);
681 }
682 else
683 {
684 // static friction
685 m_static = true;
686 }
687 }
688 impulse = impulse_normal + impulse_tangent;
689 // apply impulse to deformable nodes involved and change their velocities
690 applyImpulse(impulse);
691 return residualSquare;
692}
693
695{
697 btVector3 dva = impulse * contact->m_node->m_im;
698 btVector3 dvb = impulse * contact->m_imf;
699 if (contact->m_node->m_im > 0)
700 {
701 contact->m_node->m_v += dva;
702 }
703
704 btSoftBody::Face* face = contact->m_face;
705 btVector3& v0 = face->m_n[0]->m_v;
706 btVector3& v1 = face->m_n[1]->m_v;
707 btVector3& v2 = face->m_n[2]->m_v;
708 const btScalar& im0 = face->m_n[0]->m_im;
709 const btScalar& im1 = face->m_n[1]->m_im;
710 const btScalar& im2 = face->m_n[2]->m_im;
711 if (im0 > 0)
712 {
713 v0 -= dvb * contact->m_weights[0];
714 }
715 if (im1 > 0)
716 {
717 v1 -= dvb * contact->m_weights[1];
718 }
719 if (im2 > 0)
720 {
721 v2 -= dvb * contact->m_weights[2];
722 }
723}
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
btScalar btSqrt(btScalar y)
Definition: btScalar.h:466
#define SIMD_EPSILON
Definition: btScalar.h:543
#define btAssert(x)
Definition: btScalar.h:153
btScalar btDot(const btVector3 &v1, const btVector3 &v2)
Return the dot product between two vectors.
Definition: btVector3.h:890
int getInternalType() const
reserved for Bullet internal usage
bool hasContactResponse() const
const btContactSolverInfo * m_infoGlobal
virtual btVector3 getVb() const =0
virtual void applyImpulse(const btVector3 &impulse)=0
virtual void applyImpulse(const btVector3 &impulse)
const btSoftBody::DeformableFaceNodeContact * m_contact
virtual btVector3 getDv(const btSoftBody::Node *) const
const btSoftBody::DeformableFaceNodeContact * getContact() const
virtual btScalar solveConstraint(const btContactSolverInfo &infoGlobal)
virtual void applySplitImpulse(const btVector3 &impulse)
const btSoftBody::DeformableFaceRigidContact * getContact() const
virtual btVector3 getDv(const btSoftBody::Node *) const
virtual void applyImpulse(const btVector3 &impulse)
virtual btScalar solveConstraint(const btContactSolverInfo &infoGlobal)
virtual void applyImpulse(const btVector3 &impulse)
const btSoftBody::DeformableNodeRigidAnchor * m_anchor
virtual void applySplitImpulse(const btVector3 &impulse)
virtual void applyImpulse(const btVector3 &impulse)
virtual btVector3 getDv(const btSoftBody::Node *) const
const btSoftBody::DeformableNodeRigidContact * getContact() const
virtual btScalar solveConstraint(const btContactSolverInfo &infoGlobal)
virtual btVector3 getSplitVb() const =0
btScalar solveSplitImpulse(const btContactSolverInfo &infoGlobal)
virtual void applySplitImpulse(const btVector3 &impulse)=0
const btSoftBody::DeformableRigidContact * m_contact
btMatrix3x3 inverse() const
Return the inverse of the matrix.
Definition: btMatrix3x3.h:1093
static btMultiBodyLinkCollider * upcast(btCollisionObject *colObj)
void applyDeltaSplitVeeMultiDof(const btScalar *delta_vee, btScalar multiplier)
Definition: btMultiBody.h:435
const btScalar * getDeltaVelocityVector() const
Definition: btMultiBody.h:307
int getNumDofs() const
Definition: btMultiBody.h:167
const btScalar * getSplitVelocityVector() const
Definition: btMultiBody.h:312
void applyDeltaVeeMultiDof2(const btScalar *delta_vee, btScalar multiplier)
Definition: btMultiBody.h:428
const btScalar * getVelocityVector() const
Definition: btMultiBody.h:302
The btRigidBody is the main class for rigid body objects.
Definition: btRigidBody.h:60
btVector3 getVelocityInLocalPoint(const btVector3 &rel_pos) const
Definition: btRigidBody.h:460
void applyImpulse(const btVector3 &impulse, const btVector3 &rel_pos)
Definition: btRigidBody.h:335
btVector3 getPushVelocityInLocalPoint(const btVector3 &rel_pos) const
Definition: btRigidBody.h:469
void applyPushImpulse(const btVector3 &impulse, const btVector3 &rel_pos)
Definition: btRigidBody.h:347
static const btRigidBody * upcast(const btCollisionObject *colObj)
to keep collision detection and dynamics separate we don't store a rigidbody pointer but a rigidbody ...
Definition: btRigidBody.h:189
btMultiBodyJacobianData jacobianData_t1
Definition: btSoftBody.h:374
btMultiBodyJacobianData jacobianData_normal
Definition: btSoftBody.h:373
btMultiBodyJacobianData jacobianData_t2
Definition: btSoftBody.h:375
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:82
btScalar safeNorm() const
Return the norm (length) of the vector.
Definition: btVector3.h:269
btVector3 & safeNormalize()
Definition: btVector3.h:286
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:229
btScalar norm() const
Return the norm (length) of the vector.
Definition: btVector3.h:263
btVector3 normalized() const
Return a normalized version of this vector.
Definition: btVector3.h:949
void setZero()
Definition: btVector3.h:671
btAlignedObjectArray< btScalar > m_deltaVelocitiesUnitImpulse
btAlignedObjectArray< btScalar > m_jacobians
Node * m_n[3]
Definition: btSoftBody.h:309
btVector3 m_x
Definition: btSoftBody.h:271
btVector3 m_splitv
Definition: btSoftBody.h:283
btVector3 m_v
Definition: btSoftBody.h:273
btVector3 m_impulse
Definition: btSoftBody.h:228
const btCollisionObject * m_colObj
Definition: btSoftBody.h:226
btScalar m_offset
Definition: btSoftBody.h:229
btVector3 m_normal
Definition: btSoftBody.h:227