1#ifndef PBAT_SIM_CONTACT_MESHVERTEXTETRAHEDRONDCD_H
2#define PBAT_SIM_CONTACT_MESHVERTEXTETRAHEDRONDCD_H
4#include "MultibodyTetrahedralMeshSystem.h"
5#include "PhysicsBasedAnimationToolkitExport.h"
8#include "pbat/geometry/AabbRadixTreeHierarchy.h"
10#include "pbat/geometry/HierarchicalHashGrid.h"
12#include "pbat/math/linalg/mini/Eigen.h"
15#include <unordered_map>
45 Eigen::Ref<Eigen::Matrix<ScalarType, kDims, Eigen::Dynamic>> X,
46 Eigen::Ref<Eigen::Matrix<IndexType, 4, Eigen::Dynamic>> T);
54 Eigen::Ref<Eigen::Matrix<ScalarType, kDims, Eigen::Dynamic>
const>
const& X,
55 Eigen::Ref<Eigen::Matrix<IndexType, 4, Eigen::Dynamic>
const>
const& T);
64 template <
class FOnVertexTriangleContactPair>
67 FOnVertexTriangleContactPair fOnVertexTriangleContactPair)
const;
79 template <
class TDerivedX>
89 template <
class TDerivedX,
class TDerivedT>
92 Eigen::DenseBase<TDerivedX>
const& X,
93 Eigen::DenseBase<TDerivedT>
const& T);
118 template <
class FOnBodyPair>
129 template <
class TDerivedX,
class TDerivedT>
133 Eigen::DenseBase<TDerivedX>
const& X,
134 Eigen::DenseBase<TDerivedT>
const& T);
143 template <
class TDerivedX>
147 Eigen::DenseBase<TDerivedX>
const& X);
153 Eigen::Matrix<ScalarType, 2 * kDims, Eigen::Dynamic>
157 Eigen::Matrix<ScalarType, 2 * kDims, Eigen::Dynamic>
162 Eigen::Matrix<ScalarType, 2 * kDims, Eigen::Dynamic>
166 std::vector<geometry::AabbKdTreeHierarchy<kDims>>
168 std::vector<geometry::HierarchicalHashGrid<kDims, ScalarType, IndexType>>
169 mTetrahedronMeshHashGrids;
173 Eigen::Vector<bool, Eigen::Dynamic>
174 mIsTetrahedronMeshHashGridDirty;
178 std::vector<std::unordered_map<IndexType, IndexType>>
179 mBodyVertexToOtherBodiesValence;
183 Eigen::Matrix<IndexType, kMaxVertexTriangleContacts, Eigen::Dynamic>
189template <
class FOnVertexTriangleContactPair>
192 FOnVertexTriangleContactPair fOnVertexTriangleContactPair)
const
199 fOnVertexTriangleContactPair(f, k);
203template <
class TDerivedX>
206 PBAT_PROFILE_NAMED_SCOPE(
"pbat.sim.contact.MeshVertexTetrahedronDcd.ComputeTriangleAabbs");
207 auto const nTriangles = mMultibodySystem.NumContactTriangles();
208 for (
auto f = 0; f < nTriangles; ++f)
211 XF = X(Eigen::placeholders::all, mMultibodySystem.F.col(f)).template block<kDims, 3>(0, 0);
212 auto L = mTriangleAabbs.col(f).head<
kDims>();
213 auto U = mTriangleAabbs.col(f).tail<
kDims>();
214 L = XF.rowwise().minCoeff();
215 U = XF.rowwise().maxCoeff();
219template <
class TDerivedX,
class TDerivedT>
222 Eigen::DenseBase<TDerivedX>
const& X,
223 Eigen::DenseBase<TDerivedT>
const& T)
225 PBAT_PROFILE_NAMED_SCOPE(
226 "pbat.sim.contact.MeshVertexTetrahedronDcd.ComputeTetrahedronMeshAabbs");
227 auto const [tbegin, tend] = mMultibodySystem.TetrahedraRangeFor(o);
228 auto TB = mTetrahedronAabbs(Eigen::placeholders::all, Eigen::seq(tbegin, tend - 1));
229 for (
auto t = tbegin; t < tend; ++t)
231 Matrix<kDims, 4> XT = X(Eigen::placeholders::all, T.col(t)).template block<kDims, 4>(0, 0);
232 auto L = TB.col(t - tbegin).template head<kDims>();
233 auto U = TB.col(t - tbegin).template tail<kDims>();
234 L = XT.rowwise().minCoeff();
235 U = XT.rowwise().maxCoeff();
239template <
class FOnBodyPair>
242 PBAT_PROFILE_NAMED_SCOPE(
"pbat.sim.contact.MeshVertexTetrahedronDcd.ForEachBodyPair");
243 mBodiesBvh.SelfOverlaps(
247 throw std::runtime_error(
248 "MeshVertexTetrahedronDcd::UpdateActiveSet: oi == oj, which is not allowed.");
250 auto L1 = mBodyAabbs.col(oi).template head<kDims>();
251 auto U1 = mBodyAabbs.col(oi).template tail<kDims>();
252 auto L2 = mBodyAabbs.col(oj).template head<kDims>();
253 auto U2 = mBodyAabbs.col(oj).template tail<kDims>();
254 using math::linalg::mini::FromEigen;
261 [fOnBodyPair = std::forward<FOnBodyPair>(
267template <
class TDerivedX,
class TDerivedT>
271 Eigen::DenseBase<TDerivedX>
const& X,
272 Eigen::DenseBase<TDerivedT>
const& T)
274 PBAT_PROFILE_NAMED_SCOPE(
"pbat.sim.contact.MeshVertexTetrahedronDcd.MarkPenetratingVertices");
275 auto const Vov = mMultibodySystem.ContactVerticesOf(ov);
276 auto Xv = X(Eigen::placeholders::all, Vov);
277 auto const [tbegin, tend] = mMultibodySystem.TetrahedraRangeFor(ot);
279 mTetrahedronAabbs(Eigen::placeholders::all, Eigen::seq(tbegin, tend - 1)).topRows<
kDims>();
280 auto Ut = mTetrahedronAabbs(Eigen::placeholders::all, Eigen::seq(tbegin, tend - 1))
281 .bottomRows<
kDims>();
282 std::unordered_map<IndexType, IndexType>& mBodyVertexToOtherBodiesValenceMap =
283 mBodyVertexToOtherBodiesValence[
static_cast<std::size_t
>(ov)];
284 mTetrahedronMeshHashGrids[
static_cast<std::size_t
>(ot)]
286 auto const i = Vov(vq);
287 auto const XT = X(Eigen::placeholders::all, T.col(tbegin + tp));
288 using math::linalg::mini::FromEigen;
290 FromEigen(X.col(i).template head<kDims>()),
291 FromEigen(XT.col(0).template head<kDims>()),
292 FromEigen(XT.col(1).template head<kDims>()),
293 FromEigen(XT.col(2).template head<kDims>()),
294 FromEigen(XT.col(3).template head<kDims>())))
296 auto it = mBodyVertexToOtherBodiesValenceMap.find(vq);
297 auto end = mBodyVertexToOtherBodiesValenceMap.end();
300 mBodyVertexToOtherBodiesValenceMap.insert({vq,
IndexType(1)});
304 auto& valence = it->second;
311template <
class TDerivedX>
315 Eigen::DenseBase<TDerivedX>
const& X)
317 PBAT_PROFILE_NAMED_SCOPE(
318 "pbat.sim.contact.MeshVertexTetrahedronDcd.FindNearestTrianglesToPenetratingVertices");
319 IndexType const vbegin = mMultibodySystem.ContactVerticesRangeFor(ov).first;
320 auto const fbegin = mMultibodySystem.ContactTrianglesRangeFor(of).first;
321 std::unordered_map<IndexType, IndexType>& mBodyVertexToOtherBodiesValenceMap =
322 mBodyVertexToOtherBodiesValence[
static_cast<std::size_t
>(ov)];
323 for (
auto& [vq, valence] : mBodyVertexToOtherBodiesValenceMap)
327 auto const v = vbegin + vq;
328 auto const i = mMultibodySystem.V(v);
329 auto const P = X.col(i).template head<kDims>();
330 using math::linalg::mini::FromEigen;
331 mTriangleMeshBvhs[
static_cast<std::size_t
>(of)].NearestNeighbours(
332 [&]<
class TL,
class TU>(TL
const& L, TU
const& U) {
339 auto const f = fbegin + fq;
340 auto const iF = mMultibodySystem.F.col(f);
341 auto const XT = X(Eigen::placeholders::all, iF);
344 FromEigen(XT.col(0).template head<kDims>()),
345 FromEigen(XT.col(1).template head<kDims>()),
346 FromEigen(XT.col(2).template head<kDims>()));
351 mVFC(k, v) = fbegin + fq;
356 std::erase_if(mBodyVertexToOtherBodiesValenceMap, [](
auto const& keyValuePair) {
357 auto const& valence = keyValuePair.second;
358 assert(valence >= 0);
BVH over axis-aligned bounding boxes using a k-D tree.
This file contains functions to answer distance queries.
This file contains functions to answer overlap queries.
Axis-aligned radix tree hierarchy of axis-aligned bounding boxes.
Definition AabbRadixTreeHierarchy.h:35
PBAT_HOST_DEVICE auto PointTriangle(TMatrixP const &P, TMatrixA const &A, TMatrixB const &B, TMatrixC const &C) -> typename TMatrixP::ScalarType
Obtain squared distance between point P and triangle ABC.
Definition DistanceQueries.h:217
PBAT_HOST_DEVICE auto PointAxisAlignedBoundingBox(TMatrixP const &P, TMatrixL const &L, TMatrixU const &U) -> typename TMatrixP::ScalarType
Obtain squared distance between point P and axis-aligned box (L,U)
Definition DistanceQueries.h:199
PBAT_HOST_DEVICE bool AxisAlignedBoundingBoxes(TMatrixL1 const &L1, TMatrixU1 const &U1, TMatrixL2 const &L2, TMatrixU2 const &U2)
Tests for overlap between axis-aligned bounding box (L1,U1) and axis-aligned bounding box (L2,...
Definition OverlapQueries.h:608
PBAT_HOST_DEVICE bool PointTetrahedron3D(TMatrixP const &P, TMatrixA const &A, TMatrixB const &B, TMatrixC const &C, TMatrixD const &D)
Checks if point P is contained in tetrahedron ABCD, in at least 3D.
Definition OverlapQueries.h:562
std::ptrdiff_t Index
Index type.
Definition Aliases.h:17
double Scalar
Scalar type.
Definition Aliases.h:18
Eigen::Matrix< Scalar, Rows, Cols > Matrix
Fixed-size matrix type.
Definition Aliases.h:31
Multibody Tetrahedral Mesh System.
Definition MultibodyTetrahedralMeshSystem.h:26