iMSTK
Interactive Medical Simulation Toolkit
imstkPbdCollisionConstraint.cpp
1 /*
2 ** This file is part of the Interactive Medical Simulation Toolkit (iMSTK)
3 ** iMSTK is distributed under the Apache License, Version 2.0.
4 ** See accompanying NOTICE for details.
5 */
6 
7 #include "imstkPbdCollisionConstraint.h"
8 
9 namespace imstk
10 {
11 PbdCollisionConstraint::PbdCollisionConstraint(const int numParticlesA, const int numParticlesB) :
12  PbdConstraint(numParticlesA + numParticlesB)
13 {
14  m_bodiesSides.resize(numParticlesA + numParticlesB);
15  for (size_t i = 0; i < m_bodiesSides.size(); i++)
16  {
17  m_bodiesSides[i] = (i >= static_cast<size_t>(numParticlesA)); // false/0 for A, true/1 for B
18  }
19 }
20 
21 void
23 {
24  if (dt == 0.0)
25  {
26  return;
27  }
28 
29  double c = 0.0;
30  bool update = this->computeValueAndGradient(bodies, c, m_dcdx);
31  if (!update)
32  {
33  return;
34  }
35 
36  double lambda = 0.0;
37 
38  // Sum the mass (so we can weight displacements)
39  for (size_t i = 0; i < m_particles.size(); i++)
40  {
41  const double invMass = bodies.getInvMass(m_particles[i]);
42  if (invMass > 0.0)
43  {
44  lambda += invMass * m_dcdx[i].squaredNorm();
45  }
46  }
47 
48  if (lambda == 0.0)
49  {
50  return;
51  }
52 
53  lambda = c / lambda;
54 
55  for (size_t i = 0; i < m_particles.size(); i++)
56  {
57  const double invMass = bodies.getInvMass(m_particles[i]);
58  if (invMass > 0.0)
59  {
60  const Vec3d dx = invMass * lambda *
61  m_dcdx[i] * m_stiffness[m_bodiesSides[i]];
62  bodies.getPosition(m_particles[i]) += dx;
63  }
64  }
65 }
66 } // namespace imstk
Compound Geometry.
void projectConstraint(PbdState &bodies, const double dt, const SolverType &type) override
Performs the actual positional solve.
SolverType
Type of solvers.
Provides interface for accessing particles from a 2d array of PbdBody,Particles.
Definition: imstkPbdBody.h:229