7 #include "imstkSurfaceMeshToSphereCD.h" 8 #include "imstkCollisionData.h" 9 #include "imstkCollisionUtils.h" 10 #include "imstkParallelUtils.h" 11 #include "imstkSphere.h" 12 #include "imstkSurfaceMesh.h" 16 SurfaceMeshToSphereCD::SurfaceMeshToSphereCD()
18 setRequiredInputType<SurfaceMesh>(0);
19 setRequiredInputType<Sphere>(1);
24 std::shared_ptr<Geometry> geomA,
25 std::shared_ptr<Geometry> geomB,
26 std::vector<CollisionElement>& elementsA,
27 std::vector<CollisionElement>& elementsB)
29 std::shared_ptr<SurfaceMesh> surfMesh = std::dynamic_pointer_cast<
SurfaceMesh>(geomA);
30 std::shared_ptr<Sphere> sphere = std::dynamic_pointer_cast<
Sphere>(geomB);
33 const double sphereRadius = sphere->getRadius();
35 std::shared_ptr<VecDataArray<int, 3>> indicesPtr = surfMesh->getCells();
37 std::shared_ptr<VecDataArray<double, 3>> verticesPtr = surfMesh->getVertexPositions();
42 ParallelUtils::parallelFor(indices.size(), [&](
int i)
44 const Vec3i& cell = indices[i];
45 const Vec3d& x1 = vertices[cell[0]];
46 const Vec3d& x2 = vertices[cell[1]];
47 const Vec3d& x3 = vertices[cell[2]];
51 const Vec3d centroid = (x1 + x2 + x3) / 3.0;
54 const double rSqr1 = (centroid - x1).squaredNorm();
55 const double rSqr2 = (centroid - x2).squaredNorm();
56 const double rSqr3 = (centroid - x3).squaredNorm();
57 const double triangleBoundingRadius = std::sqrt(std::max(rSqr1, std::max(rSqr2, rSqr3)));
59 const double distSqr = (centroid - spherePos).squaredNorm();
60 const double rSum = triangleBoundingRadius + sphereRadius;
61 if (distSqr < rSum * rSum)
63 Vec3d triangleContactPt;
66 int caseType = CollisionUtils::testSphereToTriangle(
67 spherePos, sphereRadius,
70 edgeContact, pointContact);
75 elemA.ids[0] = edgeContact[0];
76 elemA.ids[1] = edgeContact[1];
79 elemA.cellType = IMSTK_EDGE;
81 Vec3d contactNormal = (spherePos - triangleContactPt);
82 const double dist = contactNormal.norm();
83 const double penetrationDepth = sphereRadius - dist;
84 contactNormal /= dist;
87 elemB.dir = contactNormal;
88 elemB.pt = spherePos - sphereRadius * contactNormal;
89 elemB.penetrationDepth = penetrationDepth;
92 elementsA.push_back(elemA);
93 elementsB.push_back(elemB);
96 else if (caseType == 2)
100 elemA.ids[0] = cell[0];
101 elemA.ids[1] = cell[1];
102 elemA.ids[2] = cell[2];
105 elemA.cellType = IMSTK_TRIANGLE;
107 Vec3d contactNormal = (spherePos - triangleContactPt);
108 const double dist = contactNormal.norm();
109 const double penetrationDepth = sphereRadius - dist;
110 contactNormal /= dist;
113 elemB.dir = contactNormal;
114 elemB.pt = spherePos - sphereRadius * contactNormal;
115 elemB.penetrationDepth = penetrationDepth;
118 elementsA.push_back(elemA);
119 elementsB.push_back(elemB);
122 else if (caseType == 3)
124 Vec3d contactNormal = (spherePos - triangleContactPt);
125 const double dist = contactNormal.norm();
126 const double penetrationDepth = sphereRadius - dist;
127 contactNormal /= dist;
131 elemA.ptIndex = pointContact;
132 elemA.dir = -contactNormal;
133 elemA.penetrationDepth = penetrationDepth;
136 elemB.pt = spherePos - sphereRadius * contactNormal;
137 elemB.dir = contactNormal;
138 elemB.penetrationDepth = penetrationDepth;
141 elementsA.push_back(elemA);
142 elementsB.push_back(elemB);
void unlock()
End a thread-safe region.
Vec3d getPosition(DataType type=DataType::PostTransform)
Get the local or global position (post transformed)
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 lock()
Start a thread-safe region, where only one thread can execute at a time until a call to the unlock fu...
Represents a set of triangles & vertices via an array of Vec3d double vertices & Vec3i integer indice...
Represents a sphere via its position & radius.
Represents a cell by a single cell id OR by N vertex ids. Which case can be determined by the idCount...
Direclty gives a point-direction contact as its collision data, point given by index.
Direclty gives a point-direction contact as its collision data.