Commit 3ba10c66 authored by Aaron Grabowy's avatar Aaron Grabowy
Browse files

Added intersects aabb for pyramids (incl. _boundary and _boundary_no_caps)

parent e1590f05
......@@ -17,7 +17,7 @@ template <int D, class ScalarT>
}
template <int D, class ScalarT>
[[nodiscard]] constexpr array<segment<2, ScalarT>, 4> edges_of(quad<D, ScalarT> const& q)
[[nodiscard]] constexpr array<segment<D, ScalarT>, 4> edges_of(quad<D, ScalarT> const& q)
{
return {{{q.pos00, q.pos10}, {q.pos10, q.pos11}, {q.pos11, q.pos01}, {q.pos01, q.pos00}}};
}
......@@ -79,12 +79,10 @@ template <class ScalarT, int DomainD, class TraitsT>
}};
}
template <class BaseT, class TraitsT>
template <class BaseT, class TraitsT, typename = std::enable_if_t<!std::is_same_v<BaseT, sphere<2, typename BaseT::scalar_t, 3>>>>
[[nodiscard]] constexpr auto edges_of(pyramid<BaseT, TraitsT> const& py)
{
using ScalarT = typename BaseT::scalar_t;
static_assert(!std::is_same_v<BaseT, sphere<2, ScalarT, 3>>, "not possible for cones");
const auto apex = apex_of(py);
const auto edgesBase = edges_of(py.base);
auto res = array<segment<3, ScalarT>, edgesBase.size() * 2>();
......
......@@ -62,12 +62,11 @@ template <class ScalarT, class TraitsT>
return {{faceX0, faceX1, faceY0, faceY1, faceZ0, faceZ1}};
}
template <class BaseT>
template <class BaseT, typename = std::enable_if_t<!std::is_same_v<BaseT, sphere<2, typename BaseT::scalar_t, 3>>>>
[[nodiscard]] constexpr auto faces_of(pyramid<BaseT, boundary_no_caps_tag> const& py)
{
using ScalarT = typename BaseT::scalar_t;
static_assert(is_floating_point<ScalarT>, "cannot be guaranteed for integers");
static_assert(!std::is_same_v<BaseT, sphere<2, ScalarT, 3>>, "not possible for cones");
const auto apex = apex_of(py);
const auto verts = vertices_of(py.base);
......@@ -77,7 +76,7 @@ template <class BaseT>
return triangles;
}
template <class BaseT, class TraitsT>
template <class BaseT, class TraitsT, typename = std::enable_if_t<!std::is_same_v<BaseT, sphere<2, typename BaseT::scalar_t, 3>>>>
[[nodiscard]] constexpr auto faces_of(pyramid<BaseT, TraitsT> const& py)
{
auto mantle = faces_of(boundary_no_caps_of(py));
......
......@@ -1211,6 +1211,20 @@ template <int ObjectD, class ScalarT, int DomainD>
return {c - e, c + e};
}
template <class BaseT>
[[nodiscard]] constexpr hit_interval<typename BaseT::scalar_t> shadow(pyramid<BaseT> const& p, vec<3, typename BaseT::scalar_t> const& axis)
{
using ScalarT = typename BaseT::scalar_t;
auto tMin = tg::max<ScalarT>();
auto tMax = tg::min<ScalarT>();
for (auto const& vertex : vertices_of(p))
{
auto const t = dot(vertex, axis);
tMin = tg::min(tMin, t);
tMax = tg::max(tMax, t);
}
return {tMin, tMax};
}
}
template <class ScalarT>
......@@ -1652,6 +1666,47 @@ template <int D, class ScalarT>
return false;
}
template <class BaseT>
[[nodiscard]] constexpr auto intersects(pyramid<BaseT> const& p, aabb<3, typename BaseT::scalar_t> const& b) -> decltype(faces_of(p), true)
{
// SAT: box faces
if (!intersects(aabb_of(p), b))
return false;
// SAT: pyramid faces
using vec_t = vec<3, typename BaseT::scalar_t>;
auto axes = std::vector<vec_t>();
auto const faces = faces_of(p);
axes.emplace_back(normal_of(faces.base));
for (auto const& face : faces.mantle)
axes.emplace_back(normal_of(face));
if (!detail::intersects_SAT(p, b, axes))
return false;
// SAT: cross product of edge pairs
axes.clear();
array<vec_t, 3> axisDirs = {vec_t::unit_x, vec_t::unit_y, vec_t::unit_z};
for (auto const& edge : edges_of(p))
{
vec_t d = direction(edge);
for (auto j = 0; j < 3; ++j)
axes.push_back(cross(d, axisDirs[j]));
}
return detail::intersects_SAT(p, b, axes);
}
template <class BaseT>
[[nodiscard]] constexpr auto intersects(pyramid_boundary_no_caps<BaseT> const& p, aabb<3, typename BaseT::scalar_t> const& b) -> decltype(faces_of(p), true)
{
// SAT: box faces
if (!intersects(aabb_of(p), b))
return false;
auto const faces = faces_of(p);
return detail::intersects_any_array(b, faces, std::make_index_sequence<faces.size()>{});
}
template <class ScalarT>
[[nodiscard]] constexpr bool intersects(triangle<2, ScalarT> const& a, aabb<2, ScalarT> const& b)
{
......
......@@ -135,12 +135,10 @@ template <class ScalarT, int DomainD, class TraitsT>
return {{p0000, p1000, p1100, p0100, p0010, p1010, p1110, p0110, p0001, p1001, p1101, p0101, p0011, p1011, p1111, p0111}};
}
template <class BaseT, class TraitsT>
template <class BaseT, class TraitsT, typename = std::enable_if_t<!std::is_same_v<BaseT, sphere<2, typename BaseT::scalar_t, 3>>>>
[[nodiscard]] constexpr auto vertices_of(pyramid<BaseT, TraitsT> const& py)
{
using ScalarT = typename BaseT::scalar_t;
static_assert(!std::is_same_v<BaseT, sphere<2, ScalarT, 3>>, "not possible for cones");
auto const vertsBase = vertices_of(py.base);
auto res = array<pos<3, ScalarT>, vertsBase.size() + 1>();
for (size_t i = 0; i < vertsBase.size(); ++i)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment