7 #include "imstkPbdDihedralConstraint.h" 13 const Vec3d& p0,
const Vec3d& p1,
const Vec3d& p2,
const Vec3d& p3,
25 const Vec3d n1 = (p2 - p0).cross(p3 - p0).normalized();
26 const Vec3d n2 = (p3 - p1).cross(p2 - p1).normalized();
28 m_restAngle = atan2(n1.cross(n2).dot(p3 - p2), (p3 - p2).norm() * n1.dot(n2));
33 double& c, std::vector<Vec3d>& dcdx)
35 const Vec3d& p0 = bodies.getPosition(
m_particles[0]);
36 const Vec3d& p1 = bodies.getPosition(
m_particles[1]);
37 const Vec3d& p2 = bodies.getPosition(
m_particles[2]);
38 const Vec3d& p3 = bodies.getPosition(
m_particles[3]);
40 const Vec3d e = p3 - p2;
41 const Vec3d e1 = p3 - p0;
42 const Vec3d e2 = p0 - p2;
43 const Vec3d e3 = p3 - p1;
44 const Vec3d e4 = p1 - p2;
46 Vec3d n1 = e1.cross(e);
47 Vec3d n2 = e.cross(e3);
48 const double A1 = n1.norm();
49 const double A2 = n2.norm();
53 const double l = e.norm();
59 dcdx[0] = -(l / A1) * n1;
60 dcdx[1] = -(l / A2) * n2;
61 dcdx[2] = (e.dot(e1) / (A1 * l)) * n1 + (e.dot(e3) / (A2 * l)) * n2;
62 dcdx[3] = (e.dot(e2) / (A1 * l)) * n1 + (e.dot(e4) / (A2 * l)) * n2;
64 c = atan2(n1.cross(n2).dot(e), l * n1.dot(n2)) -
m_restAngle;
std::pair< int, int > PbdParticleId
Index pair that refers to a particle in a PbdState. Index 0 is the body id, Index 1 is the particle i...
std::vector< PbdParticleId > m_particles
body, particle index
double m_restAngle
Rest angle.
void initConstraint(const Vec3d &p0, const Vec3d &p1, const Vec3d &p2, const Vec3d &p3, const PbdParticleId &pIdx0, const PbdParticleId &pIdx1, const PbdParticleId &pIdx2, const PbdParticleId &pIdx3, const double k)
initConstraint p3 / | \ / | \ p0 | p1 \ | / \ | / p2
Provides interface for accessing particles from a 2d array of PbdBody,Particles.
bool computeValueAndGradient(PbdState &bodies, double &c, std::vector< Vec3d > &dcdx) override
Compute value and gradient of the constraint.