Support early exit in cg::separation for intersection tests

This commit is contained in:
Nikita Lisitsa 2022-06-29 12:12:51 +03:00
parent 63662124d5
commit fa27ef4d79

View file

@ -34,7 +34,7 @@ namespace psemek::cg
namespace detail
{
template <typename Body1, typename Body2>
template <bool EarlyExit, typename Body1, typename Body2>
auto separation_2d(Body1 const & b1, Body2 const & b2)
{
auto const & vs1 = vertices(b1);
@ -64,6 +64,8 @@ namespace psemek::cg
}
result |= edge_result;
if (EarlyExit && result.distance > 0)
break;
}
return result;
@ -71,11 +73,13 @@ namespace psemek::cg
result_type result;
result |= process_edges(vs1, es1, vs2);
if (EarlyExit && result.distance > 0)
return result;
result |= process_edges(vs2, es2, vs1);
return result;
}
template <typename Body1, typename Body2>
template <bool EarlyExit, typename Body1, typename Body2>
auto separation_3d(Body1 const & b1, Body2 const & b2)
{
auto const & vs1 = vertices(b1);
@ -110,6 +114,8 @@ namespace psemek::cg
}
result |= face_result;
if (EarlyExit && result.distance > 0)
break;
}
return result;
@ -155,6 +161,9 @@ namespace psemek::cg
}
result |= edge_result;
if (EarlyExit && result.distance > 0)
return result;
}
}
@ -163,7 +172,11 @@ namespace psemek::cg
result_type result;
result |= process_faces(vs1, fs1, vs2);
if (EarlyExit && result.distance > 0)
return result;
result |= process_faces(vs2, fs2, vs1);
if (EarlyExit && result.distance > 0)
return result;
result |= process_edges(vs1, eds1, vs2, eds2);
return result;
}
@ -181,11 +194,34 @@ namespace psemek::cg
if constexpr (dim1 == 2)
{
return detail::separation_2d(b1, b2);
return detail::separation_2d<false>(b1, b2);
}
else if constexpr (dim1 == 3)
{
return detail::separation_3d(b1, b2);
return detail::separation_3d<false>(b1, b2);
}
else
{
return;
}
}
template <typename Body1, typename Body2>
auto intersect(Body1 const & b1, Body2 const & b2)
{
constexpr auto dim1 = dimension<Body1>;
constexpr auto dim2 = dimension<Body2>;
static_assert(dim1 == dim2);
static_assert(dim1 == 2 || dim1 == 3);
if constexpr (dim1 == 2)
{
return detail::separation_2d<true>(b1, b2).distance <= 0;
}
else if constexpr (dim1 == 3)
{
return detail::separation_3d<true>(b1, b2).distance <= 0;
}
else
{