7 #include "NeedleRigidBodyCH.h" 8 #include "imstkArcNeedle.h" 9 #include "imstkPuncturable.h" 10 #include "imstkRbdContactConstraint.h" 11 #include "imstkRigidBodyModel2.h" 12 #include "imstkRigidObject2.h" 13 #include "RbdPointToArcConstraint.h" 17 const std::vector<CollisionElement>& elementsA,
18 const std::vector<CollisionElement>& elementsB)
21 RigidBodyCH::handle(elementsA, elementsB);
27 std::shared_ptr<CollidingObject> tissueObj = getInputObjectB();
28 auto puncturable = tissueObj->getComponent<
Puncturable>();
31 const Puncture::State state = needle->getState(punctureId);
33 if (elementsA.size() != 0)
35 if (state == Puncture::State::INSERTED)
37 const Mat3d& rot = needleObj->getRigidBody()->getOrientation().toRotationMatrix();
38 const Vec3d& pos = needleObj->getRigidBody()->getPosition();
40 const Mat3d& arcBasis = rot * needle->getArcBasis();
41 const Vec3d& arcCenter = pos + rot * needle->getArcCenter();
42 const double arcRadius = needle->getArcRadius();
43 const double arcBeginRad = needle->getBeginRad();
44 const double arcEndRad = needle->getEndRad();
47 auto pointToArcConstraint = std::make_shared<RbdPointToArcConstraint>(
48 needleObj->getRigidBody(),
50 arcBeginRad, arcEndRad,
55 pointToArcConstraint->compute(needleObj->getRigidBodyModel2()->getTimeStep());
56 needleObj->getRigidBodyModel2()->addConstraint(pointToArcConstraint);
61 if (state == Puncture::State::INSERTED || state == Puncture::State::TOUCHING)
63 if (state == Puncture::State::INSERTED)
65 LOG(INFO) <<
"Unpuncture!";
67 needle->setState(punctureId, Puncture::State::REMOVED);
74 std::shared_ptr<RigidObject2> rbdObj,
75 const Vec3d& contactPt,
const Vec3d& contactNormal,
76 const double contactDepth)
82 std::shared_ptr<CollidingObject> tissueObj = getInputObjectB();
83 auto puncturable = tissueObj->getComponent<
Puncturable>();
87 if (needle->getState(punctureId) == Puncture::State::REMOVED)
89 needle->setState(punctureId, Puncture::State::TOUCHING);
93 const Vec3d n = contactNormal.normalized();
94 if (needle->getState(punctureId) == Puncture::State::TOUCHING)
97 const double fN = std::max(-contactNormal.dot(rbdObj->getRigidBody()->getForce()), 0.0);
100 if (fN > m_forceThreshold)
102 LOG(INFO) <<
"Puncture!";
103 needle->setState(punctureId, Puncture::State::INSERTED);
104 puncturable->setPuncture(punctureId, needle->getPuncture(punctureId));
107 m_initOrientation = Quatd(rbdObj->getCollidingGeometry()->getRotation());
108 m_initContactPt = contactPt;
113 Puncture::State state = needle->getState(punctureId);
114 if (state == Puncture::State::TOUCHING)
116 auto contactConstraint = std::make_shared<RbdContactConstraint>(
117 rbdObj->getRigidBody(),
nullptr,
118 n, contactPt, contactDepth,
120 RbdConstraint::Side::A);
121 contactConstraint->compute(rbdObj->getRigidBodyModel2()->getTimeStep());
122 rbdObj->getRigidBodyModel2()->addConstraint(contactConstraint);
PunctureId getPunctureId(std::shared_ptr< Needle > needle, std::shared_ptr< Puncturable > puncturable, const int supportId)
Get puncture id between needle and puncturable.
Place this on an object to make it puncturable by a needle. This allows puncturables to know they've ...
std::shared_ptr< Component > getComponent(const unsigned int index) const
Get a component by index.
void handle(const std::vector< CollisionElement > &elementsA, const std::vector< CollisionElement > &elementsB) override
Handle the collision/contact data.
std::shared_ptr< CollidingObject > getInputObjectA() const
Get the input objects.
void addConstraint(std::shared_ptr< RigidObject2 > rbdObj, const Vec3d &contactPt, const Vec3d &contactNormal, const double contactDepth) override
Add constraint for the rigid body given contact.
Scene objects that are governed by rigid body dynamics under the RigidBodyModel2. ...
std::tuple< int, int, int > PunctureId
Punctures are identified via three ints. The needle id, the puncturable id, and a local id that allow...