Commit f8a5e563 authored by Philip Trettner's avatar Philip Trettner
Browse files

barycoords and tritri transformations

parent 41065333
......@@ -23,5 +23,6 @@
#include <typed-geometry/functions/objects/rasterize.hh>
#include <typed-geometry/functions/objects/size.hh>
#include <typed-geometry/functions/objects/tangent.hh>
#include <typed-geometry/functions/objects/triangle.hh>
#include <typed-geometry/functions/objects/vertices.hh>
#include <typed-geometry/functions/objects/volume.hh>
#pragma once
#include <typed-geometry/functions/matrix/inverse.hh>
#include <typed-geometry/functions/objects/distance.hh>
#include <typed-geometry/functions/objects/normal.hh>
#include <typed-geometry/types/objects/sphere.hh>
#include <typed-geometry/types/objects/triangle.hh>
......@@ -32,4 +34,58 @@ template <class ObjectT>
{
return circumcircle_of(o);
}
/// given a 2D triangle, returns a 3x3 matrix M such that
/// M * (a, b, c) = (p, 1)
/// where a,b,c are barycentric coordinates for p
template <class ScalarT>
[[nodiscard]] mat<3, 3, ScalarT> from_barycoord_matrix_of(triangle<2, ScalarT> const& t)
{
return mat<3, 3, ScalarT>::from_cols(vec<3, ScalarT>(t.pos0, 1.f), //
vec<3, ScalarT>(t.pos1, 1.f), //
vec<3, ScalarT>(t.pos2, 1.f));
}
/// given a 3D triangle, returns a 4x4 matrix M such that
/// M * (a, b, c, d) = (p + normal * d, 1)
/// where a,b,c are barycentric coordinates for p
/// and d is the signed distance in normal direction
template <class ScalarT>
[[nodiscard]] mat<4, 4, ScalarT> from_barycoord_matrix_of(triangle<3, ScalarT> const& t)
{
auto const n = normal_of(t);
return mat<4, 4, ScalarT>::from_cols(vec<4, ScalarT>(t.pos0, 1.f), //
vec<4, ScalarT>(t.pos1, 1.f), //
vec<4, ScalarT>(t.pos2, 1.f), //
vec<4, ScalarT>(n, 0.f));
}
/// given a 2D triangle, returns a 3x3 matrix M such that
/// M * (p, 1) = (a, b, c)
/// where a,b,c are barycentric coordinates for p
template <class ScalarT>
[[nodiscard]] mat<3, 3, ScalarT> to_barycoord_matrix_of(triangle<2, ScalarT> const& t)
{
return inverse(from_barycoord_matrix_of(t));
}
/// given a 3D triangle, returns a 4x4 matrix M such that
/// M * (p, 1) = (a, b, c, d)
/// where a,b,c are barycentric coordinates for p
/// and d is the signed distance in normal direction
template <class ScalarT>
[[nodiscard]] mat<4, 4, ScalarT> to_barycoord_matrix_of(triangle<3, ScalarT> const& t)
{
return inverse(from_barycoord_matrix_of(t));
}
/// returns a transformation matrix M such that
/// M * p = p'
/// where p is a point in "from" and p' in "to" with the same barycentric coordinates
/// (i.e. it's the matrix transforming the first triangle into the second)
template <int D, class ScalarT>
[[nodiscard]] mat<D + 1, D + 1, ScalarT> transformation_from_to(triangle<D, ScalarT> const& from, triangle<D, ScalarT> const& to)
{
return from_barycoord_matrix_of(to) * to_barycoord_matrix_of(from);
}
}
......@@ -748,6 +748,20 @@ template <class Rng, class... Args>
return uniform(rng, args...) - decltype(uniform(rng, args...))::zero;
}
/// returns uniformly sampled barycentric coordinates
/// i.e. uniform(rng, triangle) has the same distribution as
/// triangle[uniform_barycoords(rng)]
template <class ScalarT = float, class Rng>
[[nodiscard]] constexpr comp<3, ScalarT> uniform_barycoords(Rng& rng)
{
auto const a = detail::uniform01<ScalarT>(rng);
auto const b = detail::uniform01<ScalarT>(rng);
if (a + b <= ScalarT(1))
return {a, b, 1 - a - b};
else
return {1 - a, 1 - b, a + b - 1};
}
namespace detail
{
......
Supports Markdown
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