iMSTK
Interactive Medical Simulation Toolkit
imstkPointSetToOrientedBoxCD.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 "imstkPointSetToOrientedBoxCD.h"
8 #include "imstkCollisionData.h"
9 #include "imstkCollisionUtils.h"
10 #include "imstkOrientedBox.h"
11 #include "imstkParallelUtils.h"
12 #include "imstkPointSet.h"
13 #include "imstkVecDataArray.h"
14 
15 namespace imstk
16 {
17 PointSetToOrientedBoxCD::PointSetToOrientedBoxCD()
18 {
19  setRequiredInputType<PointSet>(0);
20  setRequiredInputType<OrientedBox>(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<OrientedBox> box = std::dynamic_pointer_cast<OrientedBox>(geomB);
32 
33  std::shared_ptr<VecDataArray<double, 3>> vertexData = pointSet->getVertexPositions();
34  const VecDataArray<double, 3>& vertices = *vertexData;
35 
36  const Vec3d boxPos = box->getPosition();
37  const Mat3d cubeRot = box->getOrientation().toRotationMatrix();
38  const Vec3d cubeExtents = box->getExtents();
40  ParallelUtils::parallelFor(vertices.size(),
41  [&](const int idx)
42  {
43  Vec3d cubeContactPt;
44  Vec3d pointContactNormal;
45  double depth;
46  if (CollisionUtils::testOBBToPoint(
47  boxPos, cubeRot, cubeExtents,
48  vertices[idx],
49  pointContactNormal, cubeContactPt, depth))
50  {
52  elemA.dir = pointContactNormal; // Direction to resolve pointset point
53  elemA.ptIndex = idx;
54  elemA.penetrationDepth = depth;
55 
57  elemB.dir = -pointContactNormal; // Direction to resolve cube
58  elemB.pt = cubeContactPt; // Contact point on surface of cube
59  elemB.penetrationDepth = depth;
60 
61  lock.lock();
62  elementsA.push_back(elemA);
63  elementsB.push_back(elemB);
64  lock.unlock();
65  }
66  }, vertices.size() > 100);
67 }
68 
69 void
71  std::shared_ptr<Geometry> geomA,
72  std::shared_ptr<Geometry> geomB,
73  std::vector<CollisionElement>& elementsA)
74 {
75  std::shared_ptr<PointSet> pointSet = std::dynamic_pointer_cast<PointSet>(geomA);
76  std::shared_ptr<OrientedBox> box = std::dynamic_pointer_cast<OrientedBox>(geomB);
77 
78  std::shared_ptr<VecDataArray<double, 3>> vertexData = pointSet->getVertexPositions();
79  const VecDataArray<double, 3>& vertices = *vertexData;
80 
81  const Vec3d boxPos = box->getPosition();
82  const Mat3d cubeRot = box->getOrientation().toRotationMatrix();
83  const Vec3d cubeExtents = box->getExtents();
85  ParallelUtils::parallelFor(vertices.size(),
86  [&](const int idx)
87  {
88  Vec3d cubeContactPt;
89  Vec3d pointContactNormal;
90  double depth;
91  if (CollisionUtils::testOBBToPoint(
92  boxPos, cubeRot, cubeExtents,
93  vertices[idx],
94  pointContactNormal, cubeContactPt, depth))
95  {
97  elemA.dir = pointContactNormal; // Direction to resolve pointset point
98  elemA.ptIndex = idx;
99  elemA.penetrationDepth = depth;
100 
101  lock.lock();
102  elementsA.push_back(elemA);
103  lock.unlock();
104  }
105  }, vertices.size() > 100);
106 }
107 
108 void
110  std::shared_ptr<Geometry> geomA,
111  std::shared_ptr<Geometry> geomB,
112  std::vector<CollisionElement>& elementsB)
113 {
114  std::shared_ptr<PointSet> pointSet = std::dynamic_pointer_cast<PointSet>(geomA);
115  std::shared_ptr<OrientedBox> box = std::dynamic_pointer_cast<OrientedBox>(geomB);
116 
117  std::shared_ptr<VecDataArray<double, 3>> vertexData = pointSet->getVertexPositions();
118  const VecDataArray<double, 3>& vertices = *vertexData;
119 
120  const Vec3d boxPos = box->getPosition();
121  const Mat3d cubeRot = box->getOrientation().toRotationMatrix();
122  const Vec3d cubeExtents = box->getExtents();
124  ParallelUtils::parallelFor(vertices.size(),
125  [&](const int idx)
126  {
127  Vec3d cubeContactPt;
128  Vec3d pointContactNormal;
129  double depth;
130  if (CollisionUtils::testOBBToPoint(
131  boxPos, cubeRot, cubeExtents,
132  vertices[idx],
133  pointContactNormal, cubeContactPt, depth))
134  {
135  PointDirectionElement elemB;
136  elemB.dir = -pointContactNormal; // Direction to resolve cube
137  elemB.pt = cubeContactPt; // Contact point on surface of cube
138  elemB.penetrationDepth = depth;
139 
140  lock.lock();
141  elementsB.push_back(elemB);
142  lock.unlock();
143  }
144  }, vertices.size() > 100);
145 }
146 } // namespace imstk
OrientedBox geometry, specified with extents (half lengths)
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.
Compound Geometry.
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
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.
Direclty gives a point-direction contact as its collision data, point given by index.
Direclty gives a point-direction contact as its collision data.