7 #include "imstkCollisionData.h" 8 #include "imstkEdgeEdgeCCDState.h" 9 #include "imstkLineMesh.h" 10 #include "imstkLineMeshToLineMeshCCD.h" 14 LineMeshToLineMeshCCD::LineMeshToLineMeshCCD()
16 setRequiredInputType<LineMesh>(0);
17 setRequiredInputType<LineMesh>(1);
19 m_prevA = std::make_shared<LineMesh>();
20 m_prevB = std::make_shared<LineMesh>();
24 m_prevA->setVertexAttribute(
"Velocities", std::make_shared<VecDataArray<double, 3>>());
25 m_prevB->setVertexAttribute(
"Velocities", std::make_shared<VecDataArray<double, 3>>());
26 m_prevA->setVertexAttribute(
"InvMass", std::make_shared<VecDataArray<double, 3>>());
27 m_prevB->setVertexAttribute(
"InvMass", std::make_shared<VecDataArray<double, 3>>());
37 copyPointSetGeometry(
const Geometry* source, PointSet& dest)
41 if (
auto sourceLineMeshPtr = dynamic_cast<const PointSet*>(source))
44 if (
auto srcPointsPtr = sourceLineMeshPtr->getVertexPositions())
46 *dest.getVertexPositions() = *srcPointsPtr;
56 std::shared_ptr<const Geometry> geomA,
57 std::shared_ptr<const Geometry> geomB)
59 bool success = copyPointSetGeometry(geomA.get(), *m_prevA);
60 success = success && copyPointSetGeometry(geomB.get(), *m_prevB);
63 LOG(WARNING) <<
"Failed to make a copy of previous geometries.";
68 LineMeshToLineMeshCCD::internalComputeCollision(
69 std::shared_ptr<Geometry> geomA,
70 std::shared_ptr<Geometry> geomB,
71 std::vector<CollisionElement>* elementsA,
72 std::vector<CollisionElement>* elementsB)
75 if (!geomA || !geomB || (!elementsA && !elementsB))
77 LOG(WARNING) <<
"Incomplete inputs: one of more of geomA, geomB, elementsA, or elementsB" 78 " are nullptr when they shouldn't be." 79 "\n Self-collision requries geomA == geomB.";
83 if (!m_prevA || !m_prevB)
85 LOG(WARNING) <<
"Invalid cache. Null pointers encountered.";
95 const auto& prevA = *m_prevA->getVertexPositions().get();
96 const auto& prevB = *m_prevB->getVertexPositions().get();
98 auto meshA = std::dynamic_pointer_cast<
const LineMesh>(geomA);
99 auto meshB = std::dynamic_pointer_cast<
const LineMesh>(geomB);
101 if (meshA->getNumVertices() != prevA.size() || meshB->getNumVertices() != prevB.size())
103 LOG(WARNING) <<
"Invalid cache. Size of arrays do not match input.";
108 const bool selfCollision = (meshA == meshB);
111 std::shared_ptr<const VecDataArray<double, 3>> verticesPtrA = meshA->getVertexPositions();
112 std::shared_ptr<const VecDataArray<double, 3>> verticesPtrB = meshB->getVertexPositions();
114 if (!verticesPtrA || !verticesPtrB)
123 std::shared_ptr<VecDataArray<int, 2>> linesAPtr = meshA->getCells();
125 std::shared_ptr<VecDataArray<int, 2>> linesBPtr = meshB->getCells();
127 for (
size_t i = 0; i < static_cast<size_t>(meshA->getNumCells()); ++i)
129 const Vec2i& cellA = linesA[i];
130 size_t j = selfCollision ? i + 2 : 0;
131 for (; j < static_cast<size_t>(meshB->getNumCells()); ++j)
134 if (selfCollision && (std::max(i, j) - std::min(i, j) <= 1))
138 const Vec2i& cellB = linesB[j];
140 EdgeEdgeCCDState currState(verticesA[cellA(0)], verticesA[cellA(1)], verticesB[cellB(0)], verticesB[cellB(1)]);
141 EdgeEdgeCCDState prevState(prevA[cellA(0)], prevA[cellA(1)], prevB[cellB(0)], prevB[cellB(1)]);
144 double relativeTimeOfImpact = 0.0;
146 if (collisionCase != 0)
151 elemA.cellType = IMSTK_EDGE;
153 elemA.parentId =
static_cast<int>(i);
154 elemA.ids[0] = cellA(0);
155 elemA.ids[1] = cellA(1);
158 elementsA->push_back(e);
163 elemB.cellType = IMSTK_EDGE;
165 elemB.parentId =
static_cast<int>(j);
166 elemB.ids[0] = cellB(0);
167 elemB.ids[1] = cellB(1);
170 elementsB->push_back(e);
179 std::shared_ptr<Geometry> geomA,
180 std::shared_ptr<Geometry> geomB,
181 std::vector<CollisionElement>& elementsA,
182 std::vector<CollisionElement>& elementsB)
184 internalComputeCollision(geomA, geomB, &elementsA, &elementsB);
189 std::shared_ptr<Geometry> geomA,
190 std::shared_ptr<Geometry> geomB,
191 std::vector<CollisionElement>& elementsA)
193 internalComputeCollision(geomA, geomB, &elementsA,
nullptr);
198 std::shared_ptr<Geometry> geomA,
199 std::shared_ptr<Geometry> geomB,
200 std::vector<CollisionElement>& elementsB)
202 internalComputeCollision(geomA, geomB,
nullptr, &elementsB);
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 computeCollisionDataA(std::shared_ptr< Geometry > geomA, std::shared_ptr< Geometry > geomB, std::vector< CollisionElement > &elementsA) override
Compute collision data for side A.
const std::shared_ptr< CollisionData > getCollisionData() const
Returns output 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.
static int testCollision(const EdgeEdgeCCDState &prev, EdgeEdgeCCDState &curr, double &relativeTimeOfImpact)
Performs a collision test based on two given timesteps that store the state of two lines each...
Union of collision elements. We use a union to avoid polymorphism. There may be many elements and acc...
Base class for all volume mesh types.
Represents a cell by a single cell id OR by N vertex ids. Which case can be determined by the idCount...
void updatePreviousTimestepGeometry(std::shared_ptr< const Geometry > geomA, std::shared_ptr< const Geometry > geomB) override
Copy LineMesh geometry information (points only), as previous timestep information. These are used with current geometries that are received in computeCollisionDataXX functions for computing the continuous collision detection.