Commit bef5e83a authored by Philip Trettner's avatar Philip Trettner

Merge branch 'agrabowy' into 'develop'

aabb_of all remaining types

See merge request !78
parents 3bfbb704 8b8a9018
......@@ -39,11 +39,13 @@ template <int D, class ScalarT, class TraitsT>
return this->min + (this->max - this->min) * size(c);
}
/// Note that the box goes from -1 to 1 instead of the usual 0 to 1
template <int D, class ScalarT, class TraitsT>
[[nodiscard]] constexpr pos<D, ScalarT> box<D, ScalarT, D, TraitsT>::operator[](comp<D, ScalarT> const& c) const
{
return this->center + this->half_extents * vec(c);
}
/// Note that the box goes from -1 to 1 instead of the usual 0 to 1
template <class ScalarT, class TraitsT>
[[nodiscard]] constexpr pos<3, ScalarT> box<2, ScalarT, 3, TraitsT>::operator[](comp<2, ScalarT> const& c) const
{
......
......@@ -20,9 +20,16 @@ struct sum_of_pos
constexpr sum_of_pos() = default;
/* implicit */ constexpr sum_of_pos(pos_t const& p) : accum(p) {}
constexpr pos<D, div_t> operator/(div_t const& rhs) const { return accum / rhs; }
constexpr pos<D, div_t> operator*(div_t const& rhs) const { return accum * rhs; }
constexpr auto operator/(div_t const& rhs) const
{
using T = std::common_type_t<ScalarT, div_t>;
return pos<D, T>(accum) / T(rhs);
}
constexpr auto operator*(div_t const& rhs) const
{
using T = std::common_type_t<ScalarT, div_t>;
return pos<D, T>(accum) * T(rhs);
}
constexpr sum_of_pos operator+(sum_of_pos const& rhs) const { return accum + vec(rhs); }
constexpr sum_of_pos operator+(pos_t const& rhs) const { return accum + vec(rhs); }
......
......@@ -4,6 +4,9 @@
#include <typed-geometry/types/objects/aabb.hh>
#include <typed-geometry/types/objects/box.hh>
#include <typed-geometry/types/objects/capsule.hh>
#include <typed-geometry/types/objects/hemisphere.hh>
#include <typed-geometry/types/objects/pyramid.hh>
#include <typed-geometry/types/objects/quad.hh>
#include <typed-geometry/types/objects/segment.hh>
#include <typed-geometry/types/objects/sphere.hh>
......@@ -29,6 +32,34 @@ template <int D, class ScalarT, class TraitsT>
return {s.center - s.radius, s.center + s.radius};
}
template <class ScalarT, class TraitsT>
[[nodiscard]] constexpr aabb<3, ScalarT> aabb_of(sphere<2, ScalarT, 3, TraitsT> const& s)
{
// See http://www.iquilezles.org/www/articles/diskbbox/diskbbox.htm
const auto e = abs(s.radius) * sqrt(ScalarT(1) - comp(s.normal) * comp(s.normal));
return {s.center - e, s.center + e};
}
template <class ScalarT, class TraitsT>
[[nodiscard]] constexpr aabb<1, ScalarT> aabb_of(hemisphere<1, ScalarT, TraitsT> const& h)
{
return aabb_of(h.center, h.center + h.normal * h.radius);
}
template <class ScalarT, class TraitsT>
[[nodiscard]] constexpr aabb<2, ScalarT> aabb_of(hemisphere<2, ScalarT, TraitsT> const& h)
{
const auto baseVec = h.radius * perpendicular(h.normal);
const auto sphereCorner = h.center + h.radius * sign(vec(h.normal));
return aabb_of(h.center - baseVec, h.center + baseVec, sphereCorner);
}
template <class ScalarT, class TraitsT>
[[nodiscard]] constexpr aabb<3, ScalarT> aabb_of(hemisphere<3, ScalarT, TraitsT> const& h)
{
const auto disk = sphere<2, ScalarT, 3>(h.center, h.radius, h.normal);
const auto sphereCorner = h.center + h.radius * sign(vec(h.normal));
return aabb_of(disk, sphereCorner);
}
template <int D, class ScalarT>
[[nodiscard]] constexpr aabb<D, ScalarT> aabb_of(segment<D, ScalarT> const& s)
{
......@@ -42,9 +73,9 @@ template <int D, class ScalarT>
}
template <int D, class ScalarT>
[[nodiscard]] constexpr aabb<D, ScalarT> aabb_of(quad<D, ScalarT> const& t)
[[nodiscard]] constexpr aabb<D, ScalarT> aabb_of(quad<D, ScalarT> const& q)
{
return aabb_of(t.pos00, t.pos10, t.pos11, t.pos01);
return aabb_of(q.pos00, q.pos10, q.pos11, q.pos01);
}
template <int ObjectD, class ScalarT, int DomainD, class TraitsT>
......@@ -57,6 +88,26 @@ template <int ObjectD, class ScalarT, int DomainD, class TraitsT>
return {b.center - diag, b.center + diag};
}
template <int D, class ScalarT, class TraitsT>
[[nodiscard]] constexpr aabb<D, ScalarT> aabb_of(capsule<D, ScalarT, TraitsT> const& c)
{
return aabb_of(sphere<D, ScalarT>(c.axis.pos0, c.radius), sphere<D, ScalarT>(c.axis.pos1, c.radius));
}
template <int D, class ScalarT, class TraitsT>
[[nodiscard]] constexpr aabb<D, ScalarT> aabb_of(cylinder<D, ScalarT, TraitsT> const& c)
{
const auto n = normalize(c.axis.pos1 - c.axis.pos0);
return aabb_of(sphere<2, ScalarT, 3>(c.axis.pos0, c.radius, n), sphere<2, ScalarT, 3>(c.axis.pos1, c.radius, n));
}
template <class BaseT, class TraitsT, class ScalarT = typename BaseT::scalar_t>
[[nodiscard]] constexpr aabb<3, ScalarT> aabb_of(pyramid<BaseT, TraitsT> const& p)
{
const auto apex = centroid(p.base) + normal(p.base) * p.height;
return aabb_of(p.base, apex);
}
template <class PrimA, class PrimB, class... PrimsT>
[[nodiscard]] constexpr auto aabb_of(PrimA const& pa, PrimB const& pb, PrimsT const&... prims) -> decltype(aabb_of(pa))
{
......
#pragma once
#include <typed-geometry/detail/scalar_traits.hh>
#include <typed-geometry/detail/special_values.hh>
#include <typed-geometry/types/objects/aabb.hh>
#include <typed-geometry/types/objects/capsule.hh>
#include <typed-geometry/types/objects/cylinder.hh>
#include <typed-geometry/types/objects/quad.hh>
#include <typed-geometry/types/objects/segment.hh>
#include <typed-geometry/types/objects/sphere.hh>
#include <typed-geometry/types/objects/triangle.hh>
......@@ -12,8 +12,6 @@
#include <typed-geometry/detail/operators/ops_pos.hh>
#include <typed-geometry/detail/operators/ops_vec.hh>
#include <typed-geometry/functions/basic/mix.hh>
// returns the arithmetic mean of all points contained in an object
// has variadic versions
......@@ -26,38 +24,44 @@ template <int D, class ScalarT>
}
template <int D, class ScalarT>
[[nodiscard]] constexpr pos<D, ScalarT> centroid(pos<D, ScalarT> const& a, pos<D, ScalarT> const& b)
[[nodiscard]] constexpr pos<D, fractional_result<ScalarT>> centroid(pos<D, ScalarT> const& a, pos<D, ScalarT> const& b)
{
return mix(a, b, ScalarT(0.5));
return (a + b) * fractional_result<ScalarT>(0.5);
}
template <int D, class ScalarT>
[[nodiscard]] constexpr pos<D, ScalarT> centroid(box<D, ScalarT> const& b)
template <int ObjectD, class ScalarT, int DomainD>
[[nodiscard]] constexpr pos<DomainD, ScalarT> centroid(box<ObjectD, ScalarT, DomainD> const& b)
{
return b.center;
}
template <int D, class ScalarT>
[[nodiscard]] constexpr pos<D, fractional_result<ScalarT>> centroid(aabb<D, ScalarT> const& p)
[[nodiscard]] constexpr pos<D, fractional_result<ScalarT>> centroid(aabb<D, ScalarT> const& b)
{
return mix(p.min, p.max, ScalarT(0.5));
return (b.min + b.max) * fractional_result<ScalarT>(0.5);
}
template <int D, class ScalarT>
[[nodiscard]] constexpr pos<D, fractional_result<ScalarT>> centroid(triangle<D, ScalarT> const& p)
[[nodiscard]] constexpr pos<D, fractional_result<ScalarT>> centroid(segment<D, ScalarT> const& s)
{
auto z = tg::zero<pos<D, ScalarT>>();
return z + ((p.pos0 - z) + (p.pos1 - z) + (p.pos2 - z)) / ScalarT(3);
return (s.pos0 + s.pos1) * fractional_result<ScalarT>(0.5);
}
template <int D, class ScalarT>
[[nodiscard]] constexpr pos<D, fractional_result<ScalarT>> centroid(segment<D, ScalarT> const& p)
[[nodiscard]] constexpr pos<D, fractional_result<ScalarT>> centroid(triangle<D, ScalarT> const& t)
{
return mix(p.pos0, p.pos1, fractional_result<ScalarT>(0.5));
return (t.pos0 + t.pos1 + t.pos2) / ScalarT(3);
}
template <int D, class ScalarT>
[[nodiscard]] constexpr pos<D, ScalarT> centroid(sphere<D, ScalarT> const& p)
[[nodiscard]] constexpr pos<D, fractional_result<ScalarT>> centroid(quad<D, ScalarT> const& q)
{
// TODO: The average of the four corners is not the same as the average of all points in the quad
return (q.pos00 + q.pos01 + q.pos10 + q.pos11) * fractional_result<ScalarT>(0.25);
}
template <int ObjectD, class ScalarT, int DomainD>
[[nodiscard]] constexpr pos<DomainD, ScalarT> centroid(sphere<ObjectD, ScalarT, DomainD> const& p)
{
return p.center;
}
......
......@@ -286,7 +286,7 @@ template <class ScalarT>
auto apexToP = normalize_safe(p - apex);
if (apexToP == vec<3, ScalarT>::zero)
return true;
return angle_between(dir<3, ScalarT>(apexToP), c.opening_dir) <= c.opening_angle;
return angle_between(dir<3, ScalarT>(apexToP), c.opening_dir) <= ScalarT(0.5) * c.opening_angle; // opening_angle is between the cone surfaces
}
template <class ScalarT>
[[nodiscard]] constexpr bool contains(inf_cone_boundary<3, ScalarT> const& c, pos<3, ScalarT> const& p, dont_deduce<ScalarT> eps = ScalarT(0))
......@@ -297,8 +297,64 @@ template <class ScalarT>
auto apexInnerToP = normalize_safe(p - apexInner);
if (apexOuterToP == vec<3, ScalarT>::zero || apexInnerToP == vec<3, ScalarT>::zero)
return true;
return angle_between(dir<3, ScalarT>(apexOuterToP), c.opening_dir) <= c.opening_angle
&& angle_between(dir<3, ScalarT>(apexInnerToP), c.opening_dir) >= c.opening_angle;
return angle_between(dir<3, ScalarT>(apexOuterToP), c.opening_dir) <= ScalarT(0.5) * c.opening_angle
&& angle_between(dir<3, ScalarT>(apexInnerToP), c.opening_dir) >= ScalarT(0.5) * c.opening_angle;
}
template <class ScalarT>
[[nodiscard]] constexpr bool contains(pyramid<triangle<3, ScalarT>> const& py, pos<3, ScalarT> const& p, dont_deduce<ScalarT> eps = ScalarT(0))
{
const auto c = centroid(py.base);
auto n = normal(py.base);
if (dot(p - c + eps * n, n) < ScalarT(0))
return false; // Not inside if on the other side of the base
// Check if inside for each pyramid side
const auto apex = c + n * py.height;
n = normalize(cross(apex - py.base.pos0, py.base.pos1 - py.base.pos0));
if (dot(p - apex + eps * n, n) < ScalarT(0))
return false;
n = normalize(cross(apex - py.base.pos1, py.base.pos2 - py.base.pos1));
if (dot(p - apex + eps * n, n) < ScalarT(0))
return false;
n = normalize(cross(apex - py.base.pos2, py.base.pos0 - py.base.pos2));
if (dot(p - apex + eps * n, n) < ScalarT(0))
return false;
return true;
}
template <class ScalarT>
[[nodiscard]] constexpr bool contains(pyramid<box<2, ScalarT, 3>> const& py, pos<3, ScalarT> const& p, dont_deduce<ScalarT> eps = ScalarT(0))
{
const auto c = centroid(py.base);
auto n = normal(py.base);
if (dot(p - c + eps * n, n) < ScalarT(0))
return false; // Not inside if on the other side of the base
// Check if inside for each pyramid side
const auto apex = c + n * py.height;
const auto p0 = py.base[comp<2, ScalarT>(-1, -1)];
const auto p1 = py.base[comp<2, ScalarT>(1, -1)];
const auto p2 = py.base[comp<2, ScalarT>(1, 1)];
const auto p3 = py.base[comp<2, ScalarT>(-1, 1)];
n = normalize(cross(apex - p0, p1 - p0));
if (dot(p - apex + eps * n, n) < ScalarT(0))
return false;
n = normalize(cross(apex - p1, p2 - p1));
if (dot(p - apex + eps * n, n) < ScalarT(0))
return false;
n = normalize(cross(apex - p2, p3 - p2));
if (dot(p - apex + eps * n, n) < ScalarT(0))
return false;
n = normalize(cross(apex - p3, p0 - p3));
if (dot(p - apex + eps * n, n) < ScalarT(0))
return false;
return true;
}
} // namespace tg
......@@ -4,13 +4,17 @@
#include <typed-geometry/types/objects/halfspace.hh>
#include <typed-geometry/types/objects/line.hh>
#include <typed-geometry/types/objects/plane.hh>
#include <typed-geometry/types/objects/quad.hh>
#include <typed-geometry/types/objects/ray.hh>
#include <typed-geometry/types/objects/segment.hh>
#include <typed-geometry/types/objects/sphere.hh>
#include <typed-geometry/types/objects/triangle.hh>
#include <typed-geometry/functions/vector/normalize.hh>
#include <typed-geometry/functions/vector/perpendicular.hh>
#include "typed-geometry/functions/tests/vec_tests.hh"
// Computes the normal at the surface of an object
// Some objects have a fixed normal everywhere, some only at defined positions
// Evaluating the normal at other positions might be undefined or wrong
......@@ -29,6 +33,12 @@ template <int D, class ScalarT>
return h.normal;
}
template <class ScalarT>
[[nodiscard]] constexpr dir<3, ScalarT> normal(sphere<2, ScalarT, 3> const& d)
{
return d.normal;
}
template <class ScalarT>
[[nodiscard]] constexpr dir<2, ScalarT> normal(line<2, ScalarT> const& l)
{
......@@ -53,6 +63,15 @@ template <class ScalarT>
return normalize(cross(t.pos1 - t.pos0, t.pos2 - t.pos0));
}
template <class ScalarT>
[[nodiscard]] constexpr dir<3, fractional_result<ScalarT>> normal(quad<3, ScalarT> const& q)
{
// Assumes the quad is planar, as it is a requirement for pyramid<quad>
const auto res = normalize(cross(q.pos01 - q.pos00, q.pos10 - q.pos00));
TG_ASSERT(tg::are_orthogonal(q.pos11 - q.pos00, res)); // Checks that the four points are indeed coplanar
return res;
}
template <class ScalarT, class TraitsT>
[[nodiscard]] constexpr dir<3, fractional_result<ScalarT>> normal(box<2, ScalarT, 3, TraitsT> const& b)
{
......
......@@ -367,13 +367,22 @@ template <class ScalarT>
// ============== project to inf_cylinder ==============
template <class ScalarT>
[[nodiscard]] constexpr pos<3, ScalarT> project(pos<3, ScalarT> const& p, inf_cylinder<3, ScalarT> const& c)
{
if (contains(c, p))
return p;
return project(p, boundary_of(c));
}
template <int D, class ScalarT>
[[nodiscard]] constexpr pos<D, ScalarT> project(pos<D, ScalarT> const& p, inf_cylinder<D, ScalarT> const& itube)
[[nodiscard]] constexpr pos<D, ScalarT> project(pos<D, ScalarT> const& p, inf_cylinder_boundary<D, ScalarT> const& c)
{
auto vec = p - itube.axis.pos;
auto h = dot(vec, itube.axis.dir);
auto point_on_axis = itube.axis[h];
return point_on_axis + tg::normalize_safe(p - point_on_axis) * itube.radius;
auto vec = p - c.axis.pos;
auto h = dot(vec, c.axis.dir);
auto point_on_axis = c.axis[h];
return point_on_axis + tg::normalize_safe(p - point_on_axis) * c.radius;
}
......@@ -410,16 +419,16 @@ template <class ScalarT>
// ============== project to cone ==============
template <class ScalarT>
[[nodiscard]] constexpr pos<3, ScalarT> project(pos<3, ScalarT> const& p, cone<3, ScalarT> const& c)
{
template <class ScalarT, class TraitsT, class = enable_if<!std::is_same<TraitsT, boundary_no_caps_tag>::value>>
[[nodiscard]] constexpr pos<3, ScalarT> project(pos<3, ScalarT> const& p, cone<3, ScalarT, TraitsT> const& c)
{ // enable_if is not necessary as long as project(cone_boundary_no_caps) is defined separately. But it is kept to prevent misusing the function.
auto closestOnBase = project(p, c.base);
auto apex = c.base.center + c.height * c.base.normal;
if (dot(p - closestOnBase, closestOnBase - apex) >= ScalarT(0)) // Base is closer than any point on the cone can be
return closestOnBase;
// Return closer projection
auto closestOnCone = project(p, inf_cone(c));
auto closestOnCone = project(p, inf_cone<3, ScalarT, TraitsT>(c));
return length_sqr(p - closestOnCone) >= length_sqr(p - closestOnBase) ? closestOnBase : closestOnCone;
}
......
......@@ -453,6 +453,15 @@ template <int D, class ScalarT, class Rng>
return h.center - v;
}
template <class BaseT, class Rng, class ScalarT = typename BaseT::scalar_t>
[[nodiscard]] constexpr pos<3, ScalarT> uniform(Rng& rng, pyramid<BaseT> const& p)
{
const auto n = normal(p.base);
const auto h = tg::pow2(detail::uniform01<ScalarT>(rng));
const auto pBase = uniform(rng, p.base);
return mix(pBase, centroid(p.base), h) + h * p.height * n;
}
template <int D, class ScalarT, class Rng, class = enable_if<is_floating_point<ScalarT>>>
[[deprecated("potentially misleading operation. use uniform_vec(rng, tg::aabb3(..)) or uniform_vec(rng, tg::segment3(..)) depending on your intended "
"semantics")]] [[nodiscard]] constexpr vec<D, ScalarT>
......
......@@ -12,7 +12,7 @@
// Component-wise vectorized versions of scalar math
// TODO: make more generic with only one template, not repeat pos, size, vec, ...
// TODO: make more generic with only one template, not repeat pos, size, vec, comp, color, ...
namespace tg
{
......@@ -20,106 +20,133 @@ namespace tg
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, abs);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, abs);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, abs);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, abs);
// min
TG_IMPL_DEFINE_COMPWISE_FUNC_BINARY(pos, min);
TG_IMPL_DEFINE_COMPWISE_FUNC_BINARY(vec, min);
TG_IMPL_DEFINE_COMPWISE_FUNC_BINARY(size, min);
TG_IMPL_DEFINE_COMPWISE_FUNC_BINARY(comp, min);
// max
TG_IMPL_DEFINE_COMPWISE_FUNC_BINARY(pos, max);
TG_IMPL_DEFINE_COMPWISE_FUNC_BINARY(vec, max);
TG_IMPL_DEFINE_COMPWISE_FUNC_BINARY(size, max);
TG_IMPL_DEFINE_COMPWISE_FUNC_BINARY(comp, max);
// sin
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, sin);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, sin);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, sin);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, sin);
// cos
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, cos);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, cos);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, cos);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, cos);
// sqrt
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, sqrt);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, sqrt);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, sqrt);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, sqrt);
// cbrt
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, cbrt);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, cbrt);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, cbrt);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, cbrt);
// pow
TG_IMPL_DEFINE_COMPWISE_FUNC_BINARY(pos, pow);
TG_IMPL_DEFINE_COMPWISE_FUNC_BINARY(vec, pow);
TG_IMPL_DEFINE_COMPWISE_FUNC_BINARY(size, pow);
TG_IMPL_DEFINE_COMPWISE_FUNC_BINARY(comp, pow);
// pow2
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, pow2);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, pow2);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, pow2);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, pow2);
// pow3
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, pow3);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, pow3);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, pow3);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, pow3);
// pow4
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, pow4);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, pow4);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, pow4);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, pow4);
// pow5
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, pow5);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, pow5);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, pow5);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, pow5);
// round
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, round);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, round);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, round);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, round);
// iround
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, iround);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, iround);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, iround);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, iround);
// floor
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, floor);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, floor);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, floor);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, floor);
// ifloor
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, ifloor);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, ifloor);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, ifloor);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, ifloor);
// ceil
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, ceil);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, ceil);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, ceil);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, ceil);
// iceil
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, iceil);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, iceil);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, iceil);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, iceil);
// fract
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, fract);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, fract);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, fract);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, fract);
// sign
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, sign);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, sign);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, sign);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, sign);
// clamp
TG_IMPL_DEFINE_COMPWISE_FUNC_TERNARY(pos, clamp);
TG_IMPL_DEFINE_COMPWISE_FUNC_TERNARY(vec, clamp);
TG_IMPL_DEFINE_COMPWISE_FUNC_TERNARY(size, clamp);
TG_IMPL_DEFINE_COMPWISE_FUNC_TERNARY(comp, clamp);
// saturate
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(pos, saturate);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(vec, saturate);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(size, saturate);
TG_IMPL_DEFINE_COMPWISE_FUNC_UNARY(comp, saturate);
// tests
TG_IMPL_DEFINE_COMPWISE_UNARY_TO_COMP(pos, is_nan);
......
......@@ -76,6 +76,7 @@ struct box<D, ScalarT, D, TraitsT>
constexpr box(pos_t center, mat_t const& half_extents) : center(center), half_extents(half_extents) {}
constexpr box(aabb<D, ScalarT, TraitsT> const& b); // requires tg.hh
/// Note that the box goes from -1 to 1 instead of the usual 0 to 1
[[nodiscard]] constexpr pos_t operator[](comp<D, ScalarT> const& c) const;
[[nodiscard]] bool operator==(box const& rhs) const { return center == rhs.center && half_extents == rhs.half_extents; }
......@@ -97,6 +98,7 @@ struct box<2, ScalarT, 3, TraitsT>
constexpr box() = default;
constexpr box(pos_t center, mat_t const& half_extents) : center(center), half_extents(half_extents) {}
/// Note that the box goes from -1 to 1 instead of the usual 0 to 1
[[nodiscard]] constexpr pos_t operator[](comp<2, ScalarT> const& c) const;
[[nodiscard]] bool operator==(box const& rhs) const { return center == rhs.center && half_extents == rhs.half_extents; }
......
......@@ -39,6 +39,7 @@ using uquad4 = quad<4, u32>;
template <int D, class ScalarT>
struct quad
{
using scalar_t = ScalarT;
using vec_t = vec<D, ScalarT>;
using pos_t = pos<D, ScalarT>;
......
......@@ -39,6 +39,7 @@ using utriangle4 = triangle<4, u32>;
template <int D, class ScalarT>
struct triangle
{
using scalar_t = ScalarT;
using vec_t = vec<D, ScalarT>;
using pos_t = pos<D, ScalarT>;
......
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