Skip to content

Commit 7d04a5f

Browse files
authored
Check distance when no motion in CCD (#71)
1 parent 2ab3682 commit 7d04a5f

File tree

4 files changed

+72
-47
lines changed

4 files changed

+72
-47
lines changed

src/ipc/ccd/ccd.cpp

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,22 @@ namespace {
2626
assert(v.size() == 2 || v.size() == 3);
2727
return v.size() == 2 ? Eigen::Vector3d(v.x(), v.y(), 0) : v.head<3>();
2828
}
29+
30+
inline bool check_initial_distance(
31+
const double initial_distance, const double min_distance, double& toi)
32+
{
33+
if (initial_distance > min_distance) {
34+
return false;
35+
}
36+
37+
logger().warn(
38+
"Initial distance {} ≤ d_min={}, returning toi=0!",
39+
initial_distance, min_distance);
40+
41+
toi = 0; // Initially touching
42+
43+
return true;
44+
}
2945
} // namespace
3046

3147
/// @brief Scale the distance tolerance to be at most this fraction of the initial distance.
@@ -49,11 +65,7 @@ bool ccd_strategy(
4965
const double conservative_rescaling,
5066
double& toi)
5167
{
52-
if (initial_distance <= min_distance) {
53-
logger().warn(
54-
"Initial distance {} ≤ d_min={}, returning toi=0!",
55-
initial_distance, min_distance);
56-
toi = 0;
68+
if (check_initial_distance(initial_distance, min_distance, toi)) {
5769
return true;
5870
}
5971

@@ -111,12 +123,12 @@ bool point_point_ccd_3D(
111123
{
112124
assert(tmax >= 0 && tmax <= 1.0);
113125

114-
if (p0_t0 == p0_t1 && p1_t0 == p1_t1) {
115-
return false; // No motion
116-
}
117-
118126
const double initial_distance = sqrt(point_point_distance(p0_t0, p1_t0));
119127

128+
if (p0_t0 == p0_t1 && p1_t0 == p1_t1) { // No motion
129+
return check_initial_distance(initial_distance, min_distance, toi);
130+
}
131+
120132
const double adjusted_tolerance = std::min(
121133
INITIAL_DISTANCE_TOLERANCE_SCALE * initial_distance, tolerance);
122134

@@ -182,13 +194,13 @@ bool point_edge_ccd_3D(
182194
{
183195
assert(tmax >= 0 && tmax <= 1.0);
184196

185-
if (p_t0 == p_t1 && e0_t0 == e0_t1 && e1_t0 == e1_t1) {
186-
return false; // No motion
187-
}
188-
189197
const double initial_distance =
190198
sqrt(point_edge_distance(p_t0, e0_t0, e1_t0));
191199

200+
if (p_t0 == p_t1 && e0_t0 == e0_t1 && e1_t0 == e1_t1) { // No motion
201+
return check_initial_distance(initial_distance, min_distance, toi);
202+
}
203+
192204
const double adjusted_tolerance = std::min(
193205
INITIAL_DISTANCE_TOLERANCE_SCALE * initial_distance, tolerance);
194206

@@ -244,15 +256,6 @@ bool point_edge_ccd(
244256
assert(p_t1.size() == dim);
245257
assert(e0_t0.size() == dim && e1_t0.size() == dim);
246258
assert(e0_t1.size() == dim && e1_t1.size() == dim);
247-
248-
#ifndef IPC_TOOLKIT_WITH_CORRECT_CCD
249-
if (dim == 2) {
250-
return inexact_point_edge_ccd_2D(
251-
p_t0, e0_t0, e1_t0, p_t1, e0_t1, e1_t1, toi,
252-
conservative_rescaling);
253-
}
254-
#endif
255-
256259
return point_edge_ccd_3D(
257260
to_3D(p_t0), to_3D(e0_t0), to_3D(e1_t0), to_3D(p_t1), to_3D(e0_t1),
258261
to_3D(e1_t1), toi, min_distance, tmax, tolerance, max_iterations,
@@ -277,14 +280,14 @@ bool edge_edge_ccd(
277280
{
278281
assert(tmax >= 0 && tmax <= 1.0);
279282

280-
if (ea0_t0 == ea0_t1 && ea1_t0 == ea1_t1 && eb0_t0 == eb0_t1
281-
&& eb1_t0 == eb1_t1) {
282-
return false; // No motion
283-
}
284-
285283
const double initial_distance =
286284
sqrt(edge_edge_distance(ea0_t0, ea1_t0, eb0_t0, eb1_t0));
287285

286+
if (ea0_t0 == ea0_t1 && ea1_t0 == ea1_t1 && eb0_t0 == eb0_t1
287+
&& eb1_t0 == eb1_t1) { // No motion
288+
return check_initial_distance(initial_distance, min_distance, toi);
289+
}
290+
288291
const double adjusted_tolerance = std::min(
289292
INITIAL_DISTANCE_TOLERANCE_SCALE * initial_distance, tolerance);
290293

@@ -340,13 +343,14 @@ bool point_triangle_ccd(
340343
{
341344
assert(tmax >= 0 && tmax <= 1.0);
342345

343-
if (p_t0 == p_t1 && t0_t0 == t0_t1 && t1_t0 == t1_t1 && t2_t0 == t2_t1) {
344-
return false; // No motion
345-
}
346-
347346
const double initial_distance =
348347
sqrt(point_triangle_distance(p_t0, t0_t0, t1_t0, t2_t0));
349348

349+
if (p_t0 == p_t1 && t0_t0 == t0_t1 && t1_t0 == t1_t1 && t2_t0 == t2_t1) {
350+
// No motion
351+
return check_initial_distance(initial_distance, min_distance, toi);
352+
}
353+
350354
const double adjusted_tolerance = std::min(
351355
INITIAL_DISTANCE_TOLERANCE_SCALE * initial_distance, tolerance);
352356

src/ipc/ccd/inexact_point_edge.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
//
2+
// NOTE: This method is provided for reference comparison and is not utilized by
3+
// the high-level functionality. In compairson to Tight Inclusion CCD, this CCD
4+
// method is not provably conservative and so can potentially produce false
5+
// negatives (i.e., miss collisions) due to floating-point rounding error.
6+
//
7+
18
#include "inexact_point_edge.hpp"
29

310
#include <ipc/distance/distance_type.hpp>

src/ipc/ccd/inexact_point_edge.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
//
2+
// NOTE: This method is provided for reference comparison and is not utilized by
3+
// the high-level functionality. In compairson to Tight Inclusion CCD, this CCD
4+
// method is not provably conservative and so can potentially produce false
5+
// negatives (i.e., miss collisions) due to floating-point rounding error.
6+
//
7+
18
#pragma once
29

310
#include <Eigen/Core>

tests/src/tests/ccd/test_ccd_benchmark.cpp

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -256,30 +256,37 @@ TEST_CASE(
256256
// TEST_CASE("Failing Benchmark Cases", "[ccd]")
257257
// {
258258
// using Matrix8x3 = Eigen::Matrix<double, 8, 3, Eigen::RowMajor>;
259-
260-
// const static std::vector<std::string> paths;
261-
// const static std::vector<std::vector<int>> qids;
262-
259+
//
260+
// const static std::vector<std::filesystem::path> paths = { {
261+
// tests::NEW_CCD_BENCHMARK_DIR / "n-body-simulation/queries/42ee.csv",
262+
// } };
263+
// const static std::vector<std::vector<int>> qids { {
264+
// 2647,
265+
// 2648,
266+
// } };
267+
//
263268
// for (int i = 0; i < paths.size(); i++) {
264269
// const std::vector<ccd_io::CCDQuery> queries =
265270
// ccd_io::read_ccd_queries(
266-
// std::string(CCD_IO_SAMPLE_QUERIES_DIR) + paths[i]);
271+
// paths[i].string(),
272+
// paths[i].parent_path().parent_path() / "mma_bool"
273+
// / (paths[i].stem().string() + "_mma_bool.json"));
267274
// for (const auto& qi : qids[i]) {
268275
// Eigen::Map<const Matrix8x3> V(&queries[qi].vertices[0][0]);
269276
// const bool expected_result = queries[qi].ground_truth;
270-
277+
//
271278
// bool result;
272279
// double toi;
273-
// // if (subfolder == "edge-edge") {
274-
// // result = edge_edge_ccd(
275-
// // V.row(0), V.row(1), V.row(2), V.row(3), V.row(4),
276-
// // V.row(5), V.row(6), V.row(7), toi);
277-
// // } else {
278-
// result = additive_ccd::point_triangle_ccd(
279-
// V.row(0), V.row(1), V.row(2), V.row(3), V.row(4), V.row(5),
280-
// V.row(6), V.row(7), toi);
281-
// // }
282-
// CHECK(result || !expected_result); // false positive is ok
280+
// if (paths[i].stem().string().find("ee") != std::string::npos) {
281+
// result = edge_edge_ccd(
282+
// V.row(0), V.row(1), V.row(2), V.row(3), V.row(4),
283+
// V.row(5), V.row(6), V.row(7), toi);
284+
// } else {
285+
// result = point_triangle_ccd(
286+
// V.row(0), V.row(1), V.row(2), V.row(3), V.row(4),
287+
// V.row(5), V.row(6), V.row(7), toi);
288+
// }
289+
// CHECK((result || !expected_result)); // false positive is ok
283290
// }
284291
// }
285292
// }

0 commit comments

Comments
 (0)