iMSTK
Interactive Medical Simulation Toolkit
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
imstkPointSetToSphereCD.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 "imstkPointSetToSphereCD.h"
8 #include "imstkCollisionData.h"
9 #include "imstkCollisionUtils.h"
10 #include "imstkParallelUtils.h"
11 #include "imstkPointSet.h"
12 #include "imstkSphere.h"
13 
14 namespace imstk
15 {
16 PointSetToSphereCD::PointSetToSphereCD()
17 {
18  setRequiredInputType<PointSet>(0);
19  setRequiredInputType<Sphere>(1);
20 }
21 
22 void
24  std::shared_ptr<Geometry> geomA,
25  std::shared_ptr<Geometry> geomB,
26  std::vector<CollisionElement>& elementsA,
27  std::vector<CollisionElement>& elementsB)
28 {
29  std::shared_ptr<PointSet> pointSet = std::dynamic_pointer_cast<PointSet>(geomA);
30  std::shared_ptr<Sphere> sphere = std::dynamic_pointer_cast<Sphere>(geomB);
31 
32  const Vec3d& spherePos = sphere->getPosition();
33  const double r = sphere->getRadius();
34 
35  std::shared_ptr<VecDataArray<double, 3>> vertexData = pointSet->getVertexPositions();
36  const VecDataArray<double, 3>& vertices = *vertexData;
38  ParallelUtils::parallelFor(vertices.size(),
39  [&](const int idx)
40  {
41  Vec3d sphereContactPt, sphereContactNormal;
42  double depth;
43 
44  if (CollisionUtils::testSphereToPoint(
45  spherePos, r, vertices[idx],
46  sphereContactPt, sphereContactNormal, depth))
47  {
49  elemA.dir = sphereContactNormal; // Direction to resolve pointset point
50  elemA.ptIndex = idx;
51  elemA.penetrationDepth = depth;
52 
54  elemB.dir = -sphereContactNormal; // Direction to resolve sphere
55  elemB.pt = sphereContactPt;
56  elemB.penetrationDepth = depth;
57 
58  lock.lock();
59  elementsA.push_back(elemA);
60  elementsB.push_back(elemB);
61  lock.unlock();
62  }
63  }, vertices.size() > 100);
64 }
65 
66 void
68  std::shared_ptr<Geometry> geomA,
69  std::shared_ptr<Geometry> geomB,
70  std::vector<CollisionElement>& elementsA)
71 {
72  std::shared_ptr<PointSet> pointSet = std::dynamic_pointer_cast<PointSet>(geomA);
73  std::shared_ptr<Sphere> sphere = std::dynamic_pointer_cast<Sphere>(geomB);
74 
75  const Vec3d& spherePos = sphere->getPosition();
76  const double r = sphere->getRadius();
77 
78  std::shared_ptr<VecDataArray<double, 3>> vertexData = pointSet->getVertexPositions();
79  const VecDataArray<double, 3>& vertices = *vertexData;
81  ParallelUtils::parallelFor(vertices.size(),
82  [&](const int idx)
83  {
84  Vec3d sphereContactPt, sphereContactNormal;
85  double depth;
86 
87  if (CollisionUtils::testSphereToPoint(
88  spherePos, r, vertices[idx],
89  sphereContactPt, sphereContactNormal, depth))
90  {
92  elemA.dir = sphereContactNormal; // Direction to resolve pointset point
93  elemA.ptIndex = idx;
94  elemA.penetrationDepth = depth;
95 
96  lock.lock();
97  elementsA.push_back(elemA);
98  lock.unlock();
99  }
100  }, vertices.size() > 100);
101 }
102 
103 void
105  std::shared_ptr<Geometry> geomA,
106  std::shared_ptr<Geometry> geomB,
107  std::vector<CollisionElement>& elementsB)
108 {
109  std::shared_ptr<PointSet> pointSet = std::dynamic_pointer_cast<PointSet>(geomA);
110  std::shared_ptr<Sphere> sphere = std::dynamic_pointer_cast<Sphere>(geomB);
111 
112  const Vec3d& spherePos = sphere->getPosition();
113  const double r = sphere->getRadius();
114 
115  std::shared_ptr<VecDataArray<double, 3>> vertexData = pointSet->getVertexPositions();
116  const VecDataArray<double, 3>& vertices = *vertexData;
118  ParallelUtils::parallelFor(vertices.size(),
119  [&](const int idx)
120  {
121  Vec3d sphereContactPt, sphereContactNormal;
122  double depth;
123 
124  if (CollisionUtils::testSphereToPoint(
125  spherePos, r, vertices[idx],
126  sphereContactPt, sphereContactNormal, depth))
127  {
128  PointDirectionElement elemB;
129  elemB.dir = -sphereContactNormal; // Direction to resolve sphere
130  elemB.pt = sphereContactPt;
131  elemB.penetrationDepth = depth;
132 
133  lock.lock();
134  elementsB.push_back(elemB);
135  lock.unlock();
136  }
137  }, vertices.size() > 100);
138 }
139 } // namespace imstk
The SpinLock class.
Definition: imstkSpinLock.h:20
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.
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
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 computeCollisionDataB(std::shared_ptr< Geometry > geomA, std::shared_ptr< Geometry > geomB, std::vector< CollisionElement > &elementsB) override
Compute collision data for side B.
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
Represents a sphere via its position & radius.
Definition: imstkSphere.h:19
Direclty gives a point-direction contact as its collision data, point given by index.
Direclty gives a point-direction contact as its collision data.