iMSTK
Interactive Medical Simulation Toolkit
imstkPointSetToCapsuleCD.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 "imstkPointSetToCapsuleCD.h"
8 #include "imstkCapsule.h"
9 #include "imstkCollisionData.h"
10 #include "imstkCollisionUtils.h"
11 #include "imstkParallelUtils.h"
12 #include "imstkPointSet.h"
13 #include "imstkVecDataArray.h"
14 
15 namespace imstk
16 {
17 PointSetToCapsuleCD::PointSetToCapsuleCD()
18 {
19  setRequiredInputType<PointSet>(0);
20  setRequiredInputType<Capsule>(1);
21 }
22 
23 void
25  std::shared_ptr<Geometry> geomA,
26  std::shared_ptr<Geometry> geomB,
27  std::vector<CollisionElement>& elementsA,
28  std::vector<CollisionElement>& elementsB)
29 {
30  std::shared_ptr<PointSet> pointSet = std::dynamic_pointer_cast<PointSet>(geomA);
31  std::shared_ptr<Capsule> capsule = std::dynamic_pointer_cast<Capsule>(geomB);
32 
33  const Vec3d capsulePos = capsule->getPosition();
34  const Vec3d capsuleAxis = capsule->getOrientation().toRotationMatrix().col(1);
35  const double capsuleLength = capsule->getLength();
36  const double capsuleRadius = capsule->getRadius();
37 
38  std::shared_ptr<VecDataArray<double, 3>> vertexData = pointSet->getVertexPositions();
39  const VecDataArray<double, 3>& vertices = *vertexData;
41  ParallelUtils::parallelFor(vertices.size(),
42  [&](const int idx)
43  {
44  Vec3d capsuleContactPt;
45  Vec3d capsuleContactNormal, pointContactNormal;
46  double depth;
47  if (CollisionUtils::testCapsuleToPoint(
48  capsulePos, capsuleAxis, capsuleLength, capsuleRadius,
49  vertices[idx],
50  capsuleContactPt, capsuleContactNormal, pointContactNormal, depth))
51  {
53  elemA.dir = pointContactNormal; // Direction to resolve pointset point
54  elemA.ptIndex = idx;
55  elemA.penetrationDepth = depth;
56 
58  elemB.dir = capsuleContactNormal; // Direction to resolve capsule
59  elemB.pt = capsuleContactPt; // Contact point on surface of capsule
60  elemB.penetrationDepth = depth;
61 
62  lock.lock();
63  elementsA.push_back(elemA);
64  elementsB.push_back(elemB);
65  lock.unlock();
66  }
67  }, vertices.size() > 100);
68 }
69 
70 void
72  std::shared_ptr<Geometry> geomA,
73  std::shared_ptr<Geometry> geomB,
74  std::vector<CollisionElement>& elementsA)
75 {
76  std::shared_ptr<PointSet> pointSet = std::dynamic_pointer_cast<PointSet>(geomA);
77  std::shared_ptr<Capsule> capsule = std::dynamic_pointer_cast<Capsule>(geomB);
78 
79  const Vec3d capsulePos = capsule->getPosition();
80  const Vec3d capsuleAxis = capsule->getOrientation().toRotationMatrix().col(1);
81  const double capsuleLength = capsule->getLength();
82  const double capsuleRadius = capsule->getRadius();
83 
84  std::shared_ptr<VecDataArray<double, 3>> vertexData = pointSet->getVertexPositions();
85  const VecDataArray<double, 3>& vertices = *vertexData;
87  ParallelUtils::parallelFor(vertices.size(),
88  [&](const int idx)
89  {
90  Vec3d capsuleContactPt;
91  Vec3d capsuleContactNormal, pointContactNormal;
92  double depth;
93  if (CollisionUtils::testCapsuleToPoint(
94  capsulePos, capsuleAxis, capsuleLength, capsuleRadius,
95  vertices[idx],
96  capsuleContactPt, capsuleContactNormal, pointContactNormal, depth))
97  {
99  elemA.dir = pointContactNormal; // Direction to resolve pointset point
100  elemA.ptIndex = idx;
101  elemA.penetrationDepth = depth;
102 
103  lock.lock();
104  elementsA.push_back(elemA);
105  lock.unlock();
106  }
107  }, vertices.size() > 100);
108 }
109 
110 void
112  std::shared_ptr<Geometry> geomA,
113  std::shared_ptr<Geometry> geomB,
114  std::vector<CollisionElement>& elementsB)
115 {
116  std::shared_ptr<PointSet> pointSet = std::dynamic_pointer_cast<PointSet>(geomA);
117  std::shared_ptr<Capsule> capsule = std::dynamic_pointer_cast<Capsule>(geomB);
118 
119  const Vec3d capsulePos = capsule->getPosition();
120  const Vec3d capsuleAxis = capsule->getOrientation().toRotationMatrix().col(1);
121  const double capsuleLength = capsule->getLength();
122  const double capsuleRadius = capsule->getRadius();
123 
124  std::shared_ptr<VecDataArray<double, 3>> vertexData = pointSet->getVertexPositions();
125  const VecDataArray<double, 3>& vertices = *vertexData;
127  ParallelUtils::parallelFor(vertices.size(),
128  [&](const int idx)
129  {
130  Vec3d capsuleContactPt;
131  Vec3d capsuleContactNormal, pointContactNormal;
132  double depth;
133  if (CollisionUtils::testCapsuleToPoint(
134  capsulePos, capsuleAxis, capsuleLength, capsuleRadius,
135  vertices[idx],
136  capsuleContactPt, capsuleContactNormal, pointContactNormal, depth))
137  {
138  PointDirectionElement elemB;
139  elemB.dir = capsuleContactNormal; // Direction to resolve capsule
140  elemB.pt = capsuleContactPt; // Contact point on surface of capsule
141  elemB.penetrationDepth = depth;
142 
143  lock.lock();
144  elementsB.push_back(elemB);
145  lock.unlock();
146  }
147  }, vertices.size() > 100);
148 }
149 } // namespace imstk
The SpinLock class.
Definition: imstkSpinLock.h:20
void unlock()
End a thread-safe region.
Definition: imstkSpinLock.h:53
Base class for all geometries represented by discrete points and elements The pointsets follow a pipe...
Definition: imstkPointSet.h:25
void computeCollisionDataAB(std::shared_ptr< Geometry > geomA, std::shared_ptr< Geometry > geomB, std::vector< CollisionElement > &elementsA, std::vector< CollisionElement > &elementsB) override
Compute collision data for AB simultaneously.
Vec3d getPosition(DataType type=DataType::PostTransform)
Get the local or global position (post transformed)
Compound Geometry.
void computeCollisionDataA(std::shared_ptr< Geometry > geomA, std::shared_ptr< Geometry > geomB, std::vector< CollisionElement > &elementsA) override
Compute collision data for side A.
void lock()
Start a thread-safe region, where only one thread can execute at a time until a call to the unlock fu...
Definition: imstkSpinLock.h:45
Direclty gives a point-direction contact as its collision data, point given by index.
Capsule geometry, default configuration is centered at origin with length running up and down the y a...
Definition: imstkCapsule.h:21
Direclty gives a point-direction contact as its collision data.
void computeCollisionDataB(std::shared_ptr< Geometry > geomA, std::shared_ptr< Geometry > geomB, std::vector< CollisionElement > &elementsB) override
Compute collision data for side B.