Commit 46773cda authored by Philip Trettner's avatar Philip Trettner
Browse files

Merge branch 'develop' of...

Merge branch 'develop' of https://www.graphics.rwth-aachen.de:9000/ptrettner/typed-geometry into develop
parents 8945424b 7258860c
......@@ -28,6 +28,8 @@
#include "functions/scaling.hh"
#include "functions/submatrix.hh"
#include "functions/subvector.hh"
#include "functions/tangent.hh"
#include "functions/translation.hh"
#include "functions/uniform.hh"
#include "functions/volume.hh"
#include "functions/intersection.hh"
......@@ -79,4 +79,33 @@ constexpr bool contains(triangle<2, ScalarT> const& t, pos<2, ScalarT> const& p,
return ((A0 >= -eps) == (A1 >= -eps)) && ((A1 >= -eps) == (A2 >= -eps));
}
template <class ScalarT>
constexpr bool contains(triangle<3, ScalarT> const& t, pos<3, ScalarT> const& p)
{
// TODO
// use eps?
// does this also work for triangles where vertices are not ordered cc? should it?
auto n = normal(t);
// checking whether point lies on right side of any edge
auto e = t.v1 - t.v0;
auto C = cross(e, p - t.v0);
if (dot(n, C) < 0)
return false;
e = t.v2 - t.v1;
C = cross(e, p - t.v1);
if (dot(n, C) < 0)
return false;
e = t.v0 - t.v2;
C = cross(e, p - t.v2);
if (dot(n, C) < 0)
return false;
// point always on left side
return true;
}
} // namespace tg
......@@ -30,7 +30,24 @@ constexpr array<ScalarT, 3> coordinates(triangle<2, ScalarT> const& t, pos<2, Sc
auto A2 = cross(pv0, pv1);
auto A_inv = ScalarT(1) / A;
return {A0 * A_inv, A1 * A_inv, A2 * A_inv};
return {{A0 * A_inv, A1 * A_inv, A2 * A_inv}};
}
template <class ScalarT>
constexpr array<ScalarT, 3> coordinates(triangle<3, ScalarT> const& t, pos<3, ScalarT> const& p)
{
auto pv0 = t.v0 - p;
auto pv1 = t.v1 - p;
auto pv2 = t.v2 - p;
auto n = cross(t.v1 - t.v0, t.v2 - t.v0);
auto A = length(n);
n /= A;
auto A0 = dot(cross(pv1, pv2), n);
auto A1 = dot(cross(pv2, pv0), n);
auto A2 = dot(cross(pv0, pv1), n);
auto A_inv = ScalarT(1) / A;
return {{A0 * A_inv, A1 * A_inv, A2 * A_inv}};
}
template <int D, class ScalarT>
......
#pragma once
#include "../../types/objects/ray.hh"
#include "../../types/objects/triangle.hh"
#include "../../types/objects/hyperplane.hh"
#include "contains.hh"
#include "dot.hh"
#include "normal.hh"
namespace tg
{
template <class A, class B>
struct intersection_result;
template <int D, class ScalarT>
struct intersection_result<ray<3, ScalarT>, hyperplane<D, ScalarT>>
{
bool empty;
pos<D, ScalarT> pos;
};
template <class ScalarT>
struct intersection_result<ray<3, ScalarT>, triangle<3, ScalarT>>
{
bool empty;
pos<3, ScalarT> pos;
};
// returns whether two objects intersect
template <class A, class B>
constexpr auto intersects(A const& a, B const& b) -> decltype(!intersection(a, b).empty)
{
return !intersection(a, b).empty;
}
// returns intersection point of ray and hyperplane
template <int D, class ScalarT>
constexpr auto intersection(ray<3, ScalarT> const& r, hyperplane<D, ScalarT> const& p)
-> intersection_result<ray<3, ScalarT>, hyperplane<D, ScalarT>>
{
// if plane normal and raydirection are parallel there is no intersection
auto dotND = dot(p.n, r.dir);
if (dotND == 0)
return {true, {}};
auto t = -(dot(p.n, vec3(r.pos)) + p.d) / dotND;
// check whether plane lies behind ray
if (t < 0)
return {true, {}};
auto result = r.pos + r.dir * t;
// non-empty intersection
return {false, result};
}
// returns intersection point of ray and triangle
template <class ScalarT>
constexpr auto intersection(ray<3, ScalarT> const& r, triangle<3, ScalarT> const& t)
-> intersection_result<tg::ray<3, ScalarT>, tg::triangle<3, ScalarT>>
{
auto p = hyperplane<3, ScalarT>(normal(t), t.v0);
auto result = intersection(r, p);
// check whether potential intersection point indeed lies on the triangle
if (!contains(t, result.pos))
return {true, {}};
// non-empty intersection
return result;
}
} // namespace tg
......@@ -31,9 +31,15 @@ constexpr pos<D, ScalarT> project(pos<D, ScalarT> const& p, segment<D, ScalarT>
return mix(s.a, s.b, t);
}
template <class ScalarT>
constexpr pos<3, ScalarT> project(pos<3, ScalarT> const& p, plane const& pl)
template <int D, class ScalarT>
constexpr pos<D, ScalarT> project(pos<D, ScalarT> const& p, hyperplane<D, ScalarT> const& pl)
{
return p - pl.n * (dot(p - zero<pos<D, ScalarT>>(), pl.n) - pl.d);
}
template <int D, class ScalarT>
constexpr vec<D, ScalarT> project(vec<D, ScalarT> const& v, hyperplane<D, ScalarT> const& pl)
{
return p - pl.n * (dot(p - zero<pos<3, ScalarT>>(), pl.n) - pl.d);
return v - pl.n * dot(v, pl.n);
}
} // namespace tg
......@@ -3,6 +3,7 @@
#include "../../types/angle.hh"
#include "../../types/mat.hh"
#include "../../types/vec.hh"
#include "translation.hh"
// TODO: rotation(axis, angle) or angle/axis?
......@@ -47,4 +48,23 @@ constexpr mat<4, 4, T> rotation_z(angle<T> a)
m[1][1] = ca;
return m;
}
template <class ScalarT>
constexpr mat<3, 3, ScalarT> rotation_around(pos<2, ScalarT> p, angle<ScalarT> a)
{
auto origin_to_p = p - pos<2, ScalarT>::zero;
auto ca = cos(a);
auto sa = sin(a);
auto r = mat<3, 3, ScalarT>::identity;
r[2][2] = 1.0f;
r[0][0] = ca;
r[1][0] = -sa;
r[0][1] = sa;
r[1][1] = ca;
return translation(origin_to_p) * r * translation(-origin_to_p);
}
} // namespace tg
#pragma once
#include "../../types/mat.hh"
#include "../../types/objects/triangle.hh"
#include "cross.hh"
#include "normal.hh"
namespace tg
{
// For a given triangle with 3D positions pos and 2D tex coords uv,
// return the world space tangent of the triangle
template <class ScalarT>
constexpr vec<3, ScalarT> tangent(triangle<3, ScalarT> const& pos, triangle<2, ScalarT> const& uv)
{
auto p10 = pos.v1 - pos.v0;
auto p20 = pos.v2 - pos.v0;
auto uv10 = uv.v1 - uv.v0;
auto uv20 = uv.v2 - uv.v0;
auto u10 = uv10.x;
auto u20 = uv20.x;
auto v10 = uv10.y;
auto v20 = uv20.y;
auto dir = u20 * v10 - u10 * v20;
auto tangent = dir * (p20 * v10 - p10 * v20);
return normalize_safe(tangent);
}
// Returns the TBN matrix, i.e. the tangent frame for the given triangle position and uv coords (not necessarily orthogonal)
template <class ScalarT>
constexpr mat<3, 3, ScalarT> tbn_matrix(triangle<3, ScalarT> const& pos, triangle<2, ScalarT> const& uv)
{
auto p10 = pos.v1 - pos.v0;
auto p20 = pos.v2 - pos.v0;
auto uv10 = uv.v1 - uv.v0;
auto uv20 = uv.v2 - uv.v0;
auto u10 = uv10.x;
auto u20 = uv20.x;
auto v10 = uv10.y;
auto v20 = uv20.y;
auto dir = u20 * v10 - u10 * v20;
auto t = dir * (p20 * v10 - p10 * v20);
auto b = dir * (p10 * u20 - p20 * u10);
t = normalize_safe(t);
b = normalize_safe(b);
auto n = normalize_safe(cross(t, b));
return {{t, b, n}};
}
}
......@@ -5,6 +5,12 @@
namespace tg
{
template <class A>
constexpr angle<A> operator-(angle<A> const& a)
{
return radians(-a.radians());
}
template <class A, class B, class R = promoted_scalar<A, B>>
constexpr angle<R> operator+(angle<A> a, angle<B> b)
{
......
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