Rename 'geom' library to 'math'

This commit is contained in:
Nikita Lisitsa 2024-12-10 20:22:59 +03:00
parent 89cbbaeeef
commit c59b28e13f
274 changed files with 2986 additions and 2986 deletions

View file

@ -3,12 +3,12 @@
#include <psemek/gfx/painter.hpp>
#include <psemek/geom/camera.hpp>
#include <psemek/geom/gauss.hpp>
#include <psemek/geom/distance.hpp>
#include <psemek/geom/interval.hpp>
#include <psemek/geom/math.hpp>
#include <psemek/geom/rotation.hpp>
#include <psemek/math/camera.hpp>
#include <psemek/math/gauss.hpp>
#include <psemek/math/distance.hpp>
#include <psemek/math/interval.hpp>
#include <psemek/math/math.hpp>
#include <psemek/math/rotation.hpp>
#include <psemek/random/device.hpp>
#include <psemek/random/generator.hpp>
@ -35,9 +35,9 @@ namespace
struct bone
{
geom::point<float, 2> position;
geom::vector<float, 2> direction;
geom::vector<float, 2> velocity;
math::point<float, 2> position;
math::vector<float, 2> direction;
math::vector<float, 2> velocity;
float angular_velocity;
float length;
float width;
@ -51,16 +51,16 @@ struct joint
float s0, s1;
// angle range max should be in [0, 2*pi]
// angle range min should be less or equal to angle range max
std::optional<geom::interval<float>> angle_range = std::nullopt;
std::optional<math::interval<float>> angle_range = std::nullopt;
};
template <std::size_t Bones, std::size_t Constraints>
struct constraint
{
std::size_t bone[Bones];
geom::matrix<float, Constraints, 4 * Bones> jacobian;
geom::vector<float, Constraints> bias;
geom::interval<float> range = geom::interval<float>::full();
math::matrix<float, Constraints, 4 * Bones> jacobian;
math::vector<float, Constraints> bias;
math::interval<float> range = math::interval<float>::full();
};
struct system
@ -74,7 +74,7 @@ struct system
{
std::size_t index;
float pos;
geom::vector<float, 2> delta;
math::vector<float, 2> delta;
};
void advance(float time, std::optional<selection> sel, util::function<std::vector<float>(system const &)> torque_provider);
@ -105,7 +105,7 @@ void system::step(std::optional<selection> sel, util::function<std::vector<float
if (old_torque_.size() != joints.size())
old_torque_.assign(joints.size(), 0.f);
geom::vector<float, 2> const gravity { 0.f, -10.f };
math::vector<float, 2> const gravity { 0.f, -10.f };
for (std::size_t i = 0; i < bones.size(); ++i)
{
@ -138,7 +138,7 @@ void system::step(std::optional<selection> sel, util::function<std::vector<float
auto & b = bones[i];
b.position += b.velocity * dt;
b.direction = geom::normalized(b.direction + geom::ort(b.direction) * b.angular_velocity * dt);
b.direction = math::normalized(b.direction + math::ort(b.direction) * b.angular_velocity * dt);
}
std::vector<constraint<1, 1>> constraints_1_1;
@ -175,7 +175,7 @@ void system::step(std::optional<selection> sel, util::function<std::vector<float
float const bounce = 0.05f;
float const friction = 0.05f;
auto push_1 = [&](float depth, float s, geom::vector<float, 2> const & v){
auto push_1 = [&](float depth, float s, math::vector<float, 2> const & v){
constraint<1, 1> & c = constraints_1_1.emplace_back();
c.bone[0] = i;
@ -209,8 +209,8 @@ void system::step(std::optional<selection> sel, util::function<std::vector<float
auto p0 = b.position - b.direction * b.length / 2.f;
auto p1 = b.position + b.direction * b.length / 2.f;
auto v0 = b.velocity - geom::ort(b.direction) * b.angular_velocity * b.length / 2.f;
auto v1 = b.velocity + geom::ort(b.direction) * b.angular_velocity * b.length / 2.f;
auto v0 = b.velocity - math::ort(b.direction) * b.angular_velocity * b.length / 2.f;
auto v1 = b.velocity + math::ort(b.direction) * b.angular_velocity * b.length / 2.f;
if (p0[1] < b.width / 2.f)
{
@ -303,8 +303,8 @@ void system::step(std::optional<selection> sel, util::function<std::vector<float
if (j.angle_range)
{
float x = geom::dot(b0.direction, b1.direction);
float y = geom::det(b0.direction, b1.direction);
float x = math::dot(b0.direction, b1.direction);
float y = math::det(b0.direction, b1.direction);
// a \in [-pi, pi]
float a = std::atan2(y, x);
@ -314,10 +314,10 @@ void system::step(std::optional<selection> sel, util::function<std::vector<float
// j.angle_range->center() \in [-pi, 2*pi]
// delta \in [-3*pi, 2*pi]
float delta = a - j.angle_range->center();
if (delta > geom::pi)
delta -= 2.f * geom::pi;
if (delta < -geom::pi)
delta += 2.f * geom::pi;
if (delta > math::pi)
delta -= 2.f * math::pi;
if (delta < -math::pi)
delta += 2.f * math::pi;
// delta in [-pi, pi]
float const half_length = j.angle_range->length() / 2.f;
@ -380,7 +380,7 @@ void system::step(std::optional<selection> sel, util::function<std::vector<float
template <std::size_t B, std::size_t C>
void system::solve_constraint(constraint<B, C> const & c)
{
geom::vector<float, 4 * B> v;
math::vector<float, 4 * B> v;
auto j_inv_mass = c.jacobian;
for (std::size_t i = 0; i < B; ++i)
@ -401,11 +401,11 @@ void system::solve_constraint(constraint<B, C> const & c)
}
}
geom::vector<float, C> l = *geom::solve(j_inv_mass * geom::transpose(c.jacobian), - c.jacobian * v - c.bias);
math::vector<float, C> l = *math::solve(j_inv_mass * math::transpose(c.jacobian), - c.jacobian * v - c.bias);
for (std::size_t j = 0; j < C; ++j)
l[j] = geom::clamp(l[j], c.range);
l[j] = math::clamp(l[j], c.range);
auto p = geom::transpose(j_inv_mass) * l;
auto p = math::transpose(j_inv_mass) * l;
for (std::size_t i = 0; i < B; ++i)
{
@ -413,7 +413,7 @@ void system::solve_constraint(constraint<B, C> const & c)
b.velocity[0] += p[4 * i + 0];
b.velocity[1] += p[4 * i + 1];
b.angular_velocity += geom::det(b.direction, geom::vector{p[4 * i + 2], p[4 * i + 3]});
b.angular_velocity += math::det(b.direction, math::vector{p[4 * i + 2], p[4 * i + 3]});
}
}
@ -433,15 +433,15 @@ struct controller
static constexpr float max_output = 20.f;
geom::matrix<float, outputs, inputs> m1;
geom::vector<float, outputs> t1;
math::matrix<float, outputs, inputs> m1;
math::vector<float, outputs> t1;
// geom::matrix<float, layer1, inputs> m1;
// geom::vector<float, layer1> t1;
// geom::matrix<float, layer2, layer1> m2;
// geom::vector<float, layer2> t2;
// geom::matrix<float, layer3, layer2> m3;
// geom::vector<float, layer3> t3;
// math::matrix<float, layer1, inputs> m1;
// math::vector<float, layer1> t1;
// math::matrix<float, layer2, layer1> m2;
// math::vector<float, layer2> t2;
// math::matrix<float, layer3, layer2> m3;
// math::vector<float, layer3> t3;
//Eigen::VectorXf to_eigen() const;
//void from_eigen(Eigen::VectorXf const & v);
@ -456,7 +456,7 @@ struct controller
void reset();
geom::vector<float, outputs> apply(system const & s) const;
math::vector<float, outputs> apply(system const & s) const;
void read(std::istream & is);
void write(std::ostream & os) const;
@ -464,7 +464,7 @@ struct controller
static float activation(float x);
template <std::size_t N>
static geom::vector<float, N> activation(geom::vector<float, N> v);
static math::vector<float, N> activation(math::vector<float, N> v);
template <typename T>
static void read(std::istream & is, T & x);
@ -562,14 +562,14 @@ void controller::mutate(RNG && rng, float amplitude)
void controller::reset()
{}
geom::vector<float, controller::outputs> controller::apply(system const & sys) const
math::vector<float, controller::outputs> controller::apply(system const & sys) const
{
if (sys.bones.size() * 7 != inputs)
throw std::runtime_error(util::to_string("Wrong number of inputs: should be ", sys.bones.size() * 7));
if (sys.joints.size() != outputs)
throw std::runtime_error(util::to_string("Wrong number of outputs: should be ", sys.joints.size()));
geom::vector<float, inputs> input;
math::vector<float, inputs> input;
for (std::size_t i = 0; i < inputs / 7; ++i)
{
input[7 * i + 0] = sys.bones[i].position[0] - sys.bones[0].position[0];
@ -630,7 +630,7 @@ float controller::activation(float x)
}
template <std::size_t N>
geom::vector<float, N> controller::activation(geom::vector<float, N> v)
math::vector<float, N> controller::activation(math::vector<float, N> v)
{
for (std::size_t i = 0; i < N; ++i)
v[i] = activation(v[i]);
@ -640,12 +640,12 @@ geom::vector<float, N> controller::activation(geom::vector<float, N> v)
controller lerp(controller const & c1, controller const & c2, float t)
{
controller c;
c.m1 = geom::lerp(c1.m1, c2.m1, t);
// c.m2 = geom::lerp(c1.m2, c2.m2, t);
// c.m3 = geom::lerp(c1.m3, c2.m3, t);
c.t1 = geom::lerp(c1.t1, c2.t1, t);
// c.t2 = geom::lerp(c1.t2, c2.t2, t);
// c.t3 = geom::lerp(c1.t3, c2.t3, t);
c.m1 = math::lerp(c1.m1, c2.m1, t);
// c.m2 = math::lerp(c1.m2, c2.m2, t);
// c.m3 = math::lerp(c1.m3, c2.m3, t);
c.t1 = math::lerp(c1.t1, c2.t1, t);
// c.t2 = math::lerp(c1.t2, c2.t2, t);
// c.t3 = math::lerp(c1.t3, c2.t3, t);
c.generation = std::max(c1.generation, c2.generation) + 1;
return c;
}
@ -665,7 +665,7 @@ struct animation_2d_app
void update_camera();
geom::box<float, 2> view_bbox;
math::box<float, 2> view_bbox;
bool centered = false;
gfx::painter painter;
@ -700,7 +700,7 @@ struct animation_2d_app
std::size_t train_iterations = 0;
std::size_t const max_train_iterations = 1024*8;
float const initial_variance = 10.f;
static constexpr auto mutation_amplitude = [](float t){ return std::pow(10.f, 1.f + geom::lerp(0.f, -2.f, t)); };
static constexpr auto mutation_amplitude = [](float t){ return std::pow(10.f, 1.f + math::lerp(0.f, -2.f, t)); };
//Eigen::VectorXf mean;
//Eigen::MatrixXf covariance;
@ -765,7 +765,7 @@ void animation_2d_app::update_camera()
cx = ratio * view_bbox[1].length() / 2.f;
}
view_bbox[0] = geom::expand(geom::interval<float>::singleton(cx), ratio * view_bbox[1].length() / 2.f);
view_bbox[0] = math::expand(math::interval<float>::singleton(cx), ratio * view_bbox[1].length() / 2.f);
}
void animation_2d_app::on_event(app::key_event const & event)
@ -809,14 +809,14 @@ void animation_2d_app::on_event(app::key_event const & event)
float shiftx = random::uniform_distribution<float>{-1.f, 1.f}(rng) * position_variation_amplitude;
float shifty = random::uniform_distribution<float>{0.f, 1.f}(rng) * position_variation_amplitude;
float angle = random::uniform_distribution<float>{-1.f, 1.f}(rng) * geom::rad(angle_variation_amplitude);
float angle = random::uniform_distribution<float>{-1.f, 1.f}(rng) * math::rad(angle_variation_amplitude);
geom::plane_rotation<float, 2> rot{0, 1, angle};
math::plane_rotation<float, 2> rot{0, 1, angle};
float miny = 0.f;
for (auto & b : physics.bones)
{
b.position = rot(b.position) + geom::vector{shiftx, shifty};
b.position = rot(b.position) + math::vector{shiftx, shifty};
b.direction = rot(b.direction);
miny = std::min(miny, b.position[1] - std::abs(b.direction[1]) * b.length / 2.f - b.width / 2.f);
}
@ -871,8 +871,8 @@ void animation_2d_app::reset_state(system & sys) const
sys.bones.push_back(bone{{0.5f, 0.f}, {1.f, 0.f}, {0.f, 0.f}, 0.f, 1.f, 0.25f});
sys.bones.push_back(bone{{0.25f, 0.5f}, {0.5f, 1.f}, {0.f, 0.f}, 0.f, std::sqrt(1.25f), 0.25f});
sys.bones.push_back(bone{{0.75f, 1.5f}, {0.5f, 1.f}, {0.f, 0.f}, 0.f, std::sqrt(1.25f), 0.25f});
sys.joints.push_back(joint{0, 1, -1.f, -1.f, geom::interval<float>{geom::rad(60.f), geom::rad(120.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -1.f, geom::interval<float>{geom::rad(-30.f), geom::rad(30.f)}});
sys.joints.push_back(joint{0, 1, -1.f, -1.f, math::interval<float>{math::rad(60.f), math::rad(120.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -1.f, math::interval<float>{math::rad(-30.f), math::rad(30.f)}});
//*/
/*
@ -884,10 +884,10 @@ void animation_2d_app::reset_state(system & sys) const
sys.bones.push_back(bone{{ 0.f, h*2.f }, {1.f, 0.f}, {0.f, 0.f}, 0.f, 2.f, 0.25f});
sys.bones.push_back(bone{{ s, h*1.5f}, {0.f, -1.f}, {0.f, 0.f}, 0.f, h, 0.25f});
sys.bones.push_back(bone{{ s, h*0.5f}, {0.f, -1.f}, {0.f, 0.f}, 0.f, h, 0.25f});
sys.joints.push_back(joint{0, 1, 1.f, -1.f, geom::interval{geom::rad( 0.f), geom::rad(45.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -s, geom::interval{geom::rad(240.f), geom::rad(300.f)}});
sys.joints.push_back(joint{2, 3, s, -1.f, geom::interval{geom::rad(240.f), geom::rad(300.f)}});
sys.joints.push_back(joint{3, 4, 1.f, -1.f, geom::interval{geom::rad( 0.f), geom::rad(45.f)}});
sys.joints.push_back(joint{0, 1, 1.f, -1.f, math::interval{math::rad( 0.f), math::rad(45.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -s, math::interval{math::rad(240.f), math::rad(300.f)}});
sys.joints.push_back(joint{2, 3, s, -1.f, math::interval{math::rad(240.f), math::rad(300.f)}});
sys.joints.push_back(joint{3, 4, 1.f, -1.f, math::interval{math::rad( 0.f), math::rad(45.f)}});
//*/
/*
@ -896,10 +896,10 @@ void animation_2d_app::reset_state(system & sys) const
sys.bones.push_back(bone{{1.f, 0.5f}, {0.f, 1.f}, {0.f, 0.f}, 0.f, 1.f, 0.25f});
sys.bones.push_back(bone{{0.5f, 1.f}, {-1.f, 0.f}, {0.f, 0.f}, 0.f, 1.f, 0.25f});
sys.bones.push_back(bone{{0.f, 0.5f}, {0.f, -1.f}, {0.f, 0.f}, 0.f, 1.f, 0.25f});
sys.joints.push_back(joint{0, 1, 1.f, -1.f, geom::interval<float>{geom::rad(60.f), geom::rad(120.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -1.f, geom::interval<float>{geom::rad(60.f), geom::rad(120.f)}});
sys.joints.push_back(joint{2, 3, 1.f, -1.f, geom::interval<float>{geom::rad(60.f), geom::rad(120.f)}});
sys.joints.push_back(joint{3, 0, 1.f, -1.f, geom::interval<float>{geom::rad(60.f), geom::rad(120.f)}});
sys.joints.push_back(joint{0, 1, 1.f, -1.f, math::interval<float>{math::rad(60.f), math::rad(120.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -1.f, math::interval<float>{math::rad(60.f), math::rad(120.f)}});
sys.joints.push_back(joint{2, 3, 1.f, -1.f, math::interval<float>{math::rad(60.f), math::rad(120.f)}});
sys.joints.push_back(joint{3, 0, 1.f, -1.f, math::interval<float>{math::rad(60.f), math::rad(120.f)}});
//*/
/*
@ -908,10 +908,10 @@ void animation_2d_app::reset_state(system & sys) const
sys.bones.push_back(bone{{1.f, 0.5f}, {0.f, 1.f}, {0.f, 0.f}, 0.f, 1.f, 0.25f});
sys.bones.push_back(bone{{0.5f, 1.f}, {-1.f, 0.f}, {0.f, 0.f}, 0.f, 1.f, 0.25f});
sys.bones.push_back(bone{{0.f, 0.5f}, {0.f, -1.f}, {0.f, 0.f}, 0.f, 1.f, 0.25f});
sys.joints.push_back(joint{0, 1, 1.f, -1.f, geom::interval<float>{geom::rad(60.f), geom::rad(120.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -1.f, geom::interval<float>{geom::rad(60.f), geom::rad(120.f)}});
sys.joints.push_back(joint{2, 3, 1.f, -1.f, geom::interval<float>{geom::rad(60.f), geom::rad(120.f)}});
sys.joints.push_back(joint{3, 0, 1.f, -1.f, geom::interval<float>{geom::rad(60.f), geom::rad(120.f)}});
sys.joints.push_back(joint{0, 1, 1.f, -1.f, math::interval<float>{math::rad(60.f), math::rad(120.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -1.f, math::interval<float>{math::rad(60.f), math::rad(120.f)}});
sys.joints.push_back(joint{2, 3, 1.f, -1.f, math::interval<float>{math::rad(60.f), math::rad(120.f)}});
sys.joints.push_back(joint{3, 0, 1.f, -1.f, math::interval<float>{math::rad(60.f), math::rad(120.f)}});
//*/
/*
@ -927,7 +927,7 @@ void animation_2d_app::reset_state(system & sys) const
sys.bones.push_back(bone{{-0.25f, std::sqrt(3.f) * 0.25f}, {0.5f, -std::sqrt(3.f) * 0.5}, {0.f, 0.f}, 0.f, 1.f, 0.25f});
for (int i = 0; i < 2 * n + 4; ++i)
sys.joints.push_back(joint{i, (i + 1) % (2 * n + 4), 1.f, -1.f, geom::interval<float>{geom::rad(0.f), geom::rad(60.f)}});
sys.joints.push_back(joint{i, (i + 1) % (2 * n + 4), 1.f, -1.f, math::interval<float>{math::rad(0.f), math::rad(60.f)}});
//*/
/*
@ -936,7 +936,7 @@ void animation_2d_app::reset_state(system & sys) const
for (int i = 0; i < n; ++i)
sys.bones.push_back(bone{{i + 0.5f, 0.f}, {1.f, 0.f}, {0.f, 0.f}, 0.f, 1.f, 0.25f});
for (int i = 0; i + 1 < n; ++i)
sys.joints.push_back(joint{i, i + 1, 1.f, -1.f, geom::interval<float>{geom::rad(-30.f), geom::rad(30.f)}});
sys.joints.push_back(joint{i, i + 1, 1.f, -1.f, math::interval<float>{math::rad(-30.f), math::rad(30.f)}});
//*/
@ -951,11 +951,11 @@ void animation_2d_app::reset_state(system & sys) const
}
for (int i = 0; i + 1 < n; ++i)
sys.joints.push_back(joint{i, i + 1, 1.f, -1.f, geom::interval<float>{geom::rad(-30.f), geom::rad(30.f)}});
sys.joints.push_back(joint{i, i + 1, 1.f, -1.f, math::interval<float>{math::rad(-30.f), math::rad(30.f)}});
for (int i = 0; i < n; ++i)
{
sys.joints.push_back(joint{i, n + 2 * i + 0, -0.5f, -1.f, geom::interval<float>{geom::rad(240.f), geom::rad(300.f)}});
sys.joints.push_back(joint{i, n + 2 * i + 1, 0.5f, -1.f, geom::interval<float>{geom::rad(240.f), geom::rad(300.f)}});
sys.joints.push_back(joint{i, n + 2 * i + 0, -0.5f, -1.f, math::interval<float>{math::rad(240.f), math::rad(300.f)}});
sys.joints.push_back(joint{i, n + 2 * i + 1, 0.5f, -1.f, math::interval<float>{math::rad(240.f), math::rad(300.f)}});
}
//*/
@ -965,9 +965,9 @@ void animation_2d_app::reset_state(system & sys) const
sys.bones.push_back(bone{{0.5f, 1.f}, {1.f, 0.f}, {0.f, 0.f}, 0.f, 1.f, 0.25f});
sys.bones.push_back(bone{{1.5f, 1.f}, {1.f, 0.f}, {0.f, 0.f}, 0.f, 1.f, 0.25f});
sys.bones.push_back(bone{{2.f, 0.5f}, {0.f, -1.f}, {0.f, 0.f}, 0.f, 1.f, 0.25f});
sys.joints.push_back(joint{0, 1, 1.f, -1.f, geom::interval{geom::rad(240.f), geom::rad(300.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -1.f, geom::interval{geom::rad(-15.f), geom::rad( 15.f)}});
sys.joints.push_back(joint{2, 3, 1.f, -1.f, geom::interval{geom::rad(240.f), geom::rad(300.f)}});
sys.joints.push_back(joint{0, 1, 1.f, -1.f, math::interval{math::rad(240.f), math::rad(300.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -1.f, math::interval{math::rad(-15.f), math::rad( 15.f)}});
sys.joints.push_back(joint{2, 3, 1.f, -1.f, math::interval{math::rad(240.f), math::rad(300.f)}});
//*/
/*
@ -977,10 +977,10 @@ void animation_2d_app::reset_state(system & sys) const
sys.bones.push_back(bone{{ 0.f, 1.f }, {1.f, 0.f}, {0.f, 0.f}, 0.f, 2.f, 0.25f});
sys.bones.push_back(bone{{ 1.f, 0.75f}, {0.f, -1.f}, {0.f, 0.f}, 0.f, 0.5f, 0.25f});
sys.bones.push_back(bone{{ 1.f, 0.25f}, {0.f, -1.f}, {0.f, 0.f}, 0.f, 0.5f, 0.25f});
sys.joints.push_back(joint{0, 1, 1.f, -1.f, geom::interval{geom::rad( 0.f), geom::rad(45.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -1.f, geom::interval{geom::rad(240.f), geom::rad(300.f)}});
sys.joints.push_back(joint{2, 3, 1.f, -1.f, geom::interval{geom::rad(240.f), geom::rad(300.f)}});
sys.joints.push_back(joint{3, 4, 1.f, -1.f, geom::interval{geom::rad( 0.f), geom::rad(45.f)}});
sys.joints.push_back(joint{0, 1, 1.f, -1.f, math::interval{math::rad( 0.f), math::rad(45.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -1.f, math::interval{math::rad(240.f), math::rad(300.f)}});
sys.joints.push_back(joint{2, 3, 1.f, -1.f, math::interval{math::rad(240.f), math::rad(300.f)}});
sys.joints.push_back(joint{3, 4, 1.f, -1.f, math::interval{math::rad( 0.f), math::rad(45.f)}});
//*/
/*
@ -990,10 +990,10 @@ void animation_2d_app::reset_state(system & sys) const
sys.bones.push_back(bone{{ 0.f, 1.f }, {1.f, 0.f}, {0.f, 0.f}, 0.f, 2.f, 0.25f});
sys.bones.push_back(bone{{ 1.f, 0.75f}, {0.f, -1.f}, {0.f, 0.f}, 0.f, 0.5f, 0.25f});
sys.bones.push_back(bone{{ 1.f, 0.25f}, {0.f, -1.f}, {0.f, 0.f}, 0.f, 0.5f, 0.25f});
sys.joints.push_back(joint{0, 1, 1.f, -1.f, geom::interval{geom::rad(-45.f), geom::rad( 0.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -1.f, geom::interval{geom::rad(240.f), geom::rad(300.f)}});
sys.joints.push_back(joint{2, 3, 1.f, -1.f, geom::interval{geom::rad(240.f), geom::rad(300.f)}});
sys.joints.push_back(joint{3, 4, 1.f, -1.f, geom::interval{geom::rad(-45.f), geom::rad( 0.f)}});
sys.joints.push_back(joint{0, 1, 1.f, -1.f, math::interval{math::rad(-45.f), math::rad( 0.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -1.f, math::interval{math::rad(240.f), math::rad(300.f)}});
sys.joints.push_back(joint{2, 3, 1.f, -1.f, math::interval{math::rad(240.f), math::rad(300.f)}});
sys.joints.push_back(joint{3, 4, 1.f, -1.f, math::interval{math::rad(-45.f), math::rad( 0.f)}});
//*/
/*
@ -1003,10 +1003,10 @@ void animation_2d_app::reset_state(system & sys) const
sys.bones.push_back(bone{{ 0.f, 1.f }, {1.f, 0.f}, {0.f, 0.f}, 0.f, 2.f, 0.25f});
sys.bones.push_back(bone{{ 1.f, 0.75f}, {0.f, -1.f}, {0.f, 0.f}, 0.f, 0.5f, 0.25f});
sys.bones.push_back(bone{{ 1.f, 0.25f}, {0.f, -1.f}, {0.f, 0.f}, 0.f, 0.5f, 0.25f});
sys.joints.push_back(joint{0, 1, 1.f, -1.f, geom::interval{geom::rad(-45.f), geom::rad( 0.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -1.f, geom::interval{geom::rad(240.f), geom::rad(300.f)}});
sys.joints.push_back(joint{2, 3, 1.f, -1.f, geom::interval{geom::rad(240.f), geom::rad(300.f)}});
sys.joints.push_back(joint{3, 4, 1.f, -1.f, geom::interval{geom::rad( 0.f), geom::rad( 45.f)}});
sys.joints.push_back(joint{0, 1, 1.f, -1.f, math::interval{math::rad(-45.f), math::rad( 0.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -1.f, math::interval{math::rad(240.f), math::rad(300.f)}});
sys.joints.push_back(joint{2, 3, 1.f, -1.f, math::interval{math::rad(240.f), math::rad(300.f)}});
sys.joints.push_back(joint{3, 4, 1.f, -1.f, math::interval{math::rad( 0.f), math::rad( 45.f)}});
//*/
/*
@ -1016,17 +1016,17 @@ void animation_2d_app::reset_state(system & sys) const
sys.bones.push_back(bone{{ 0.f, 1.f }, {1.f, 0.f}, {0.f, 0.f}, 0.f, 2.f, 0.25f});
sys.bones.push_back(bone{{ 1.f, 0.75f}, {0.f, -1.f}, {0.f, 0.f}, 0.f, 0.5f, 0.25f});
sys.bones.push_back(bone{{ 1.f, 0.25f}, {0.f, -1.f}, {0.f, 0.f}, 0.f, 0.5f, 0.25f});
sys.joints.push_back(joint{0, 1, 1.f, -1.f, geom::interval{geom::rad( 0.f), geom::rad( 45.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -1.f, geom::interval{geom::rad(240.f), geom::rad(300.f)}});
sys.joints.push_back(joint{2, 3, 1.f, -1.f, geom::interval{geom::rad(240.f), geom::rad(300.f)}});
sys.joints.push_back(joint{3, 4, 1.f, -1.f, geom::interval{geom::rad(-45.f), geom::rad( 0.f)}});
sys.joints.push_back(joint{0, 1, 1.f, -1.f, math::interval{math::rad( 0.f), math::rad( 45.f)}});
sys.joints.push_back(joint{1, 2, 1.f, -1.f, math::interval{math::rad(240.f), math::rad(300.f)}});
sys.joints.push_back(joint{2, 3, 1.f, -1.f, math::interval{math::rad(240.f), math::rad(300.f)}});
sys.joints.push_back(joint{3, 4, 1.f, -1.f, math::interval{math::rad(-45.f), math::rad( 0.f)}});
//*/
float const bone_density = 1.f;
for (auto & b : sys.bones)
{
b.position[1] += 0.125f;
b.direction = geom::normalized(b.direction);
b.direction = math::normalized(b.direction);
b.mass = b.length * b.width * bone_density;
b.inertia = b.mass * (b.length * b.length + b.width * b.width) / 12.f;
}
@ -1045,14 +1045,14 @@ float animation_2d_app::eval_score(controller const & c, random::generator rng)
float shiftx = random::uniform_distribution<float>{-1.f, 1.f}(rng) * position_variation_amplitude;
float shifty = random::uniform_distribution<float>{0.f, 1.f}(rng) * position_variation_amplitude;
float angle = random::uniform_distribution<float>{-1.f, 1.f}(rng) * geom::rad(angle_variation_amplitude);
float angle = random::uniform_distribution<float>{-1.f, 1.f}(rng) * math::rad(angle_variation_amplitude);
geom::plane_rotation<float, 2> rot{0, 1, angle};
math::plane_rotation<float, 2> rot{0, 1, angle};
float miny = 0.f;
for (auto & b : physics.bones)
{
b.position = rot(b.position) + geom::vector{shiftx, shifty};
b.position = rot(b.position) + math::vector{shiftx, shifty};
b.direction = rot(b.direction);
miny = std::min(miny, b.position[1] - std::abs(b.direction[1]) * b.length / 2.f - b.width / 2.f);
}
@ -1100,7 +1100,7 @@ float animation_2d_app::eval_score(controller const & c, random::generator rng)
auto ctrl = c.apply(physics);
for (std::size_t i = 0; i < ctrl.dimension(); ++i)
torque[i] = ctrl[i];
energy += geom::length(ctrl) * dt;
energy += math::length(ctrl) * dt;
return torque;
});
@ -1119,12 +1119,12 @@ float animation_2d_app::eval_score(controller const & c, random::generator rng)
}
}
// penalty += geom::sqr((1.f - physics.bones[2].direction[0]) * dt);
// penalty += math::sqr((1.f - physics.bones[2].direction[0]) * dt);
// float const target_speed = 2.f;
// penalty += geom::sqr((physics.bones[2].velocity[0] - target_speed) / target_speed) * dt;
// penalty += math::sqr((physics.bones[2].velocity[0] - target_speed) / target_speed) * dt;
// penalty -= physics.bones[2].velocity[0] * dt / physics.bones;
auto cm_vel = geom::vector<float, 2>::zero();
auto cm_vel = math::vector<float, 2>::zero();
float mass = 0.f;
for (auto const & b : physics.bones)
{
@ -1360,7 +1360,7 @@ void animation_2d_app::do_train()
void animation_2d_app::do_test()
{
geom::point<float, 2> mouse = view_bbox.corner(state().mouse[0] * 1.f / state().size[0], 1.f - state().mouse[1] * 1.f / state().size[1]);
math::point<float, 2> mouse = view_bbox.corner(state().mouse[0] * 1.f / state().size[0], 1.f - state().mouse[1] * 1.f / state().size[1]);
if (state().mouse_button_down.contains(app::mouse_button::left))
{
@ -1379,18 +1379,18 @@ void animation_2d_app::do_test()
auto d = mouse - p0;
float t = geom::dot(d, r) / geom::dot(r, r);
float t = math::dot(d, r) / math::dot(r, r);
float distance;
if (0.f <= t && t <= 1.f)
{
distance = geom::length(d - r * t);
distance = math::length(d - r * t);
}
else
{
float d0 = geom::distance(p0, mouse);
float d1 = geom::distance(p1, mouse);
float d0 = math::distance(p0, mouse);
float d1 = math::distance(p1, mouse);
if (d0 < d1)
{
@ -1440,7 +1440,7 @@ void animation_2d_app::do_test()
}
{
auto cm_vel = geom::vector<float, 2>::zero();
auto cm_vel = math::vector<float, 2>::zero();
float mass = 0.f;
for (auto const & b : physics.bones)
{
@ -1491,7 +1491,7 @@ void animation_2d_app::present()
}
}
painter.render(geom::orthographic_camera{view_bbox}.transform());
painter.render(math::orthographic_camera{view_bbox}.transform());
float avg_speed = 0.f;
@ -1509,8 +1509,8 @@ void animation_2d_app::present()
for (std::size_t i = start; i + 1 < test_speeds.size(); ++i)
{
float const scale = 2.f;
geom::point p0{40.f + (i - start ) * step, 180.f - test_speeds[i ] * scale};
geom::point p1{40.f + (i - start + 1) * step, 180.f - test_speeds[i + 1] * scale};
math::point p0{40.f + (i - start ) * step, 180.f - test_speeds[i ] * scale};
math::point p1{40.f + (i - start + 1) * step, 180.f - test_speeds[i + 1] * scale};
painter.line(p0, p1, 2.f, gfx::red, false);
}
}
@ -1530,7 +1530,7 @@ void animation_2d_app::present()
// if (mode == mode::test && !test_speeds.empty()) painter.text({40.f, 136.f}, util::to_string("Speed: ", test_speeds.back()), opts);
}
painter.render(geom::window_camera{state().size[0], state().size[1]}.transform());
painter.render(math::window_camera{state().size[0], state().size[1]}.transform());
}
}

View file

@ -22,8 +22,8 @@
#include <psemek/gfx/painter.hpp>
#include <psemek/util/clock.hpp>
#include <psemek/util/to_string.hpp>
#include <psemek/geom/constants.hpp>
#include <psemek/geom/camera.hpp>
#include <psemek/math/constants.hpp>
#include <psemek/math/camera.hpp>
#include <psemek/prof/profiler.hpp>
#include <psemek/io/file_stream.hpp>
@ -68,7 +68,7 @@ static std::map<app::keycode, int> const key_to_midi
{app::keycode::RIGHTBRACKET, 91},
};
static geom::interval<int> const key_rows[3] = {
static math::interval<int> const key_rows[3] = {
{59, 68},
{69, 79},
{80, 91},
@ -204,7 +204,7 @@ struct audio_app
painter_.rect({{{x - s, x + s}, {r - w, r + w}}}, {0, 0, 255, 255});
}
painter_.render(geom::window_camera{state().size[0], state().size[1]}.transform());
painter_.render(math::window_camera{state().size[0], state().size[1]}.transform());
}
~audio_app() override

View file

@ -1,13 +1,13 @@
#include <psemek/app/application_base.hpp>
#include <psemek/app/default_application_factory.hpp>
#include <psemek/geom/box.hpp>
#include <psemek/geom/mesh.hpp>
#include <psemek/geom/intersection.hpp>
#include <psemek/geom/camera.hpp>
#include <psemek/geom/homogeneous.hpp>
#include <psemek/geom/constants.hpp>
#include <psemek/geom/math.hpp>
#include <psemek/geom/gradient.hpp>
#include <psemek/math/box.hpp>
#include <psemek/math/mesh.hpp>
#include <psemek/math/intersection.hpp>
#include <psemek/math/camera.hpp>
#include <psemek/math/homogeneous.hpp>
#include <psemek/math/constants.hpp>
#include <psemek/math/math.hpp>
#include <psemek/math/gradient.hpp>
#include <psemek/gfx/gl.hpp>
#include <psemek/gfx/mesh.hpp>
#include <psemek/gfx/renderer/simple.hpp>
@ -54,16 +54,16 @@ auto barycenter(Container const & c)
return barycenter(util::begin(c), util::end(c));
}
std::vector<geom::point<float, 3>> intersection(geom::vector<float, 4> const & f, std::vector<geom::point<float, 3>> const & vertices, std::vector<geom::segment<std::uint32_t>> const & edges)
std::vector<math::point<float, 3>> intersection(math::vector<float, 4> const & f, std::vector<math::point<float, 3>> const & vertices, std::vector<math::segment<std::uint32_t>> const & edges)
{
std::vector<geom::point<float, 3>> points;
std::vector<math::point<float, 3>> points;
for (auto e : edges)
{
auto p0 = vertices[e[0]];
auto p1 = vertices[e[1]];
auto f0 = dot(f, geom::homogeneous(p0));
auto f1 = dot(f, geom::homogeneous(p1));
auto f0 = dot(f, math::homogeneous(p0));
auto f1 = dot(f, math::homogeneous(p1));
if ((f0 >= 0.f) ^ (f1 >= 0.f))
{
@ -71,14 +71,14 @@ std::vector<geom::point<float, 3>> intersection(geom::vector<float, 4> const & f
}
}
geom::vector<float, 3> const n { f[0], f[1], f[2] };
math::vector<float, 3> const n { f[0], f[1], f[2] };
if (!points.empty())
{
auto const & p0 = points[0];
std::sort(points.begin() + 1, points.end(), [&](geom::point<float, 3> const & p1, geom::point<float, 3> const & p2){
return geom::dot(geom::cross(p1 - p0, p2 - p0), n) > 0.f;
std::sort(points.begin() + 1, points.end(), [&](math::point<float, 3> const & p1, math::point<float, 3> const & p2){
return math::dot(math::cross(p1 - p0, p2 - p0), n) > 0.f;
});
}
@ -89,9 +89,9 @@ template <typename Vertex, std::size_t N, typename Index = std::uint32_t>
struct mesh_builder
{
std::vector<Vertex> vertices;
std::vector<geom::simplex<Index, N>> indices;
std::vector<math::simplex<Index, N>> indices;
void add(std::vector<Vertex> const & v, std::vector<geom::simplex<Index, N>> const & i)
void add(std::vector<Vertex> const & v, std::vector<math::simplex<Index, N>> const & i)
{
Index const base = static_cast<Index>(vertices.size());
std::size_t begin = indices.size();
@ -164,25 +164,25 @@ void main()
struct cloud_app
: app::application_base
{
geom::spherical_camera camera;
math::spherical_camera camera;
float step;
float max_density = 2.f;
geom::interval<float> harmonic_range;
math::interval<float> harmonic_range;
util::clock<std::chrono::duration<float>> clock;
geom::box<float, 3> bbox;
std::vector<geom::point<float, 3>> bbox_vertices;
std::vector<geom::segment<std::uint32_t>> bbox_edges;
math::box<float, 3> bbox;
std::vector<math::point<float, 3>> bbox_vertices;
std::vector<math::segment<std::uint32_t>> bbox_edges;
gfx::mesh bbox_mesh;
gfx::mesh slice_mesh;
gfx::mesh light_mesh;
std::vector<geom::vector<float, 3>> dirs;
std::vector<math::vector<float, 3>> dirs;
gfx::simple_renderer renderer;
@ -193,12 +193,12 @@ struct cloud_app
cloud_app(std::size_t size)
{
geom::vector<int, 3> cloud_size{2 * size, size, size};
math::vector<int, 3> cloud_size{2 * size, size, size};
bbox = {{{-2.f, 2.f}, {-1.f, 1.f}, {-1.f, 1.f}}};
step = bbox[0].length() / cloud_size[0];
camera.fov_y = geom::rad(45.f);
camera.fov_y = math::rad(45.f);
camera.near_clip = 0.01f;
camera.far_clip = 100.f;
@ -207,15 +207,15 @@ struct cloud_app
camera.elevation_angle = 0.f;
camera.distance = 10.f;
bbox_vertices = geom::vertices(bbox);
bbox_edges = geom::edges(bbox);
bbox_vertices = math::vertices(bbox);
bbox_edges = math::edges(bbox);
bbox_mesh.setup<geom::point<float, 3>>();
bbox_mesh.setup<math::point<float, 3>>();
bbox_mesh.load(bbox_vertices, bbox_edges);
slice_mesh.setup<geom::point<float, 3>, geom::vector<float, 3>>();
slice_mesh.setup<math::point<float, 3>, math::vector<float, 3>>();
light_mesh.setup<geom::point<float, 3>>();
light_mesh.setup<math::point<float, 3>>();
{
async::threadpool bg("bg");
@ -223,7 +223,7 @@ struct cloud_app
random::generator rng(random::device{});
random::uniform_sphere_vector_distribution<float, 3> d;
std::vector<util::array<geom::vector<float, 3>, 3>> grad(4);
std::vector<util::array<math::vector<float, 3>, 3>> grad(4);
std::vector<float> weights(grad.size());
float weight_sum = 0.f;
@ -245,7 +245,7 @@ struct cloud_app
// can't use template argument deduction for first argument due to gcc bug
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89062
geom::gradient<float> g(std::make_pair(0.2f, 0.f), geom::easing_type::quadratic_out, std::pair{0.3f, max_density});
math::gradient<float> g(std::make_pair(0.2f, 0.f), math::easing_type::quadratic_out, std::pair{0.3f, max_density});
util::array<std::uint8_t, 3> cloud_data({cloud_size[0], cloud_size[1], cloud_size[2]});
@ -256,17 +256,17 @@ struct cloud_app
bg.post([&, z, y]{
for (std::size_t x = 0; x < cloud_data.width(); ++x)
{
geom::vector<float, 3> p;
math::vector<float, 3> p;
p[0] = (x * 1.f) / cloud_data.width();
p[1] = (y * 1.f) / cloud_data.height();
p[2] = (z * 1.f) / cloud_data.depth();
float v = perlin(p);
auto d = p - geom::vector{0.5f, 0.5f, 0.5f};
v *= std::max(0.f, 1.f - geom::length(d) / 0.5f);
auto d = p - math::vector{0.5f, 0.5f, 0.5f};
v *= std::max(0.f, 1.f - math::length(d) / 0.5f);
cloud_data(x, y, z) = geom::clamp(g(v) / max_density * 255.f, {0.f, 255.f});
cloud_data(x, y, z) = math::clamp(g(v) / max_density * 255.f, {0.f, 255.f});
}
});
}
@ -280,9 +280,9 @@ struct cloud_app
cloud_texture.linear_filter();
cloud_texture.generate_mipmap();
auto value_at = [this, &cloud_data](geom::point<float, 3> const & p)
auto value_at = [this, &cloud_data](math::point<float, 3> const & p)
{
geom::vector<float, 3> d;
math::vector<float, 3> d;
d[0] = (p[0] - bbox[0].min) / bbox[0].length() * cloud_data.width();
d[1] = (p[1] - bbox[1].min) / bbox[1].length() * cloud_data.height();
d[2] = (p[2] - bbox[2].min) / bbox[2].length() * cloud_data.depth();
@ -298,12 +298,12 @@ struct cloud_app
if (d[2] < 0.0f) return 0.f;
if (d[2] >= cloud_data.depth() - 1) return 0.f;
geom::vector<int, 3> i;
math::vector<int, 3> i;
i[0] = std::floor(d[0]);
i[1] = std::floor(d[1]);
i[2] = std::floor(d[2]);
geom::vector<float, 3> t;
math::vector<float, 3> t;
t[0] = d[0] - i[0];
t[1] = d[1] - i[1];
t[2] = d[2] - i[2];
@ -317,18 +317,18 @@ struct cloud_app
float v011 = cloud_data(i[0], i[1] + 1, i[2] + 1);
float v111 = cloud_data(i[0] + 1, i[1] + 1, i[2] + 1);
float v00 = geom::lerp(v000, v100, t[0]);
float v10 = geom::lerp(v010, v110, t[0]);
float v01 = geom::lerp(v001, v101, t[0]);
float v11 = geom::lerp(v011, v111, t[0]);
float v00 = math::lerp(v000, v100, t[0]);
float v10 = math::lerp(v010, v110, t[0]);
float v01 = math::lerp(v001, v101, t[0]);
float v11 = math::lerp(v011, v111, t[0]);
float v0 = geom::lerp(v00, v10, t[1]);
float v1 = geom::lerp(v01, v11, t[1]);
float v0 = math::lerp(v00, v10, t[1]);
float v1 = math::lerp(v01, v11, t[1]);
return geom::lerp(v0, v1, t[2]) / 255.f * max_density;
return math::lerp(v0, v1, t[2]) / 255.f * max_density;
};
util::array<geom::vector<float, 4>, 3> cloud_shadow_f(cloud_data.dims());
util::array<math::vector<float, 4>, 3> cloud_shadow_f(cloud_data.dims());
dirs.resize(32);
@ -336,7 +336,7 @@ struct cloud_app
float const phi = (1.f + std::sqrt(5.f)) / 2.f;
for (int i = 0; i < dirs.size(); ++i)
{
float a = 2.f * geom::pi * (i / phi);
float a = 2.f * math::pi * (i / phi);
float b = std::acos(1.f - (2.f * i) / dirs.size());
dirs[i][0] = std::cos(a) * std::sin(b);
@ -344,14 +344,14 @@ struct cloud_app
dirs[i][2] = std::cos(b);
}
float diag = std::sqrt(geom::sqr(bbox[0].length()) + geom::sqr(bbox[1].length()) + geom::sqr(bbox[2].length()));
float diag = std::sqrt(math::sqr(bbox[0].length()) + math::sqr(bbox[1].length()) + math::sqr(bbox[2].length()));
int steps = diag / step;
auto process = [&, this](auto const & idx)
{
float const step = bbox[0].length() / cloud_size[0];
geom::point<float, 3> o;
math::point<float, 3> o;
for (std::size_t i = 0; i < 3; ++i)
o[i] = bbox[i].min + bbox[i].length() * (idx[i] + 0.5f) / cloud_shadow_f.dim(i);
@ -364,7 +364,7 @@ struct cloud_app
{
float density = 0.f;
geom::point<float, 3> p = o + dir * (steps * step);
math::point<float, 3> p = o + dir * (steps * step);
for (int s = steps; s > 0; --s)
{
@ -374,10 +374,10 @@ struct cloud_app
p -= dir * step;
}
sum_0 += density * 2.f * std::sqrt(geom::pi);
sum_x += density * dir[0] * std::sqrt(12.f * geom::pi);
sum_y += density * dir[1] * std::sqrt(12.f * geom::pi);
sum_z += density * dir[2] * std::sqrt(12.f * geom::pi);
sum_0 += density * 2.f * std::sqrt(math::pi);
sum_x += density * dir[0] * std::sqrt(12.f * math::pi);
sum_y += density * dir[1] * std::sqrt(12.f * math::pi);
sum_z += density * dir[2] * std::sqrt(12.f * math::pi);
++count;
}
@ -414,8 +414,8 @@ struct cloud_app
log::info() << "Finished!";
geom::interval<float> range_0;
geom::interval<float> range_d;
math::interval<float> range_0;
math::interval<float> range_d;
for (auto const & v : cloud_shadow_f)
{
@ -448,14 +448,14 @@ struct cloud_app
}
}
util::array<geom::vector<std::uint8_t, 4>, 3> cloud_shadow(cloud_data.dims());
util::array<math::vector<std::uint8_t, 4>, 3> cloud_shadow(cloud_data.dims());
for (auto const & idx : cloud_shadow.indices())
{
for (std::size_t i = 0; i < 4; ++i)
{
float v = (cloud_shadow_f(idx)[i] - harmonic_range.min) / harmonic_range.length();
cloud_shadow(idx)[i] = geom::clamp(255.f * v, {0.f, 255.f});
cloud_shadow(idx)[i] = math::clamp(255.f * v, {0.f, 255.f});
}
}
@ -500,21 +500,21 @@ struct cloud_app
void update_slice_mesh()
{
auto n = -camera.direction();
geom::vector<float, 4> f {n[0], n[1], n[2], 0.f};
math::vector<float, 4> f {n[0], n[1], n[2], 0.f};
geom::interval<float> range;
math::interval<float> range;
for (auto p : bbox_vertices)
{
range |= geom::dot(f, geom::homogeneous(p));
range |= math::dot(f, math::homogeneous(p));
}
int count = std::ceil(range.length() / step);
struct vertex
{
geom::point<float, 3> pos;
geom::vector<float, 3> tc;
math::point<float, 3> pos;
math::vector<float, 3> tc;
};
mesh_builder<vertex, 2> builder;
@ -524,7 +524,7 @@ struct cloud_app
f[3] = - (range.max - (range.length() * s) / count);
auto slice_vertices = intersection(f, bbox_vertices, bbox_edges);
auto slice_indices = geom::triangulate_convex(slice_vertices);
auto slice_indices = math::triangulate_convex(slice_vertices);
std::vector<vertex> vertices;
for (auto p : slice_vertices)
@ -550,11 +550,11 @@ struct cloud_app
float t = clock.count();
geom::vector<float, 3> light_dir = geom::normalized(geom::vector{std::cos(t), std::sin(t), 0.5f});
math::vector<float, 3> light_dir = math::normalized(math::vector{std::cos(t), std::sin(t), 0.5f});
{
std::vector<geom::point<float, 3>> light_vertices;
auto o = geom::point<float, 3>::zero() + light_dir * 4.f;
std::vector<math::point<float, 3>> light_vertices;
auto o = math::point<float, 3>::zero() + light_dir * 4.f;
float s = 0.2f;
for (auto d : dirs)
{
@ -591,7 +591,7 @@ struct cloud_app
cloud_program["u_max_density"] = max_density;
cloud_program["u_min_harmonic"] = harmonic_range.min;
cloud_program["u_max_harmonic"] = harmonic_range.max;
cloud_program["u_light"] = geom::normalized(light_dir);
cloud_program["u_light"] = math::normalized(light_dir);
gl::ActiveTexture(gl::TEXTURE0);
cloud_texture.bind();
gl::ActiveTexture(gl::TEXTURE1);

View file

@ -6,12 +6,12 @@
#include <psemek/gfx/effect/fxaa.hpp>
#include <psemek/gfx/painter.hpp>
#include <psemek/geom/mesh.hpp>
#include <psemek/geom/camera.hpp>
#include <psemek/geom/math.hpp>
#include <psemek/geom/rotation.hpp>
#include <psemek/geom/translation.hpp>
#include <psemek/geom/scale.hpp>
#include <psemek/math/mesh.hpp>
#include <psemek/math/camera.hpp>
#include <psemek/math/math.hpp>
#include <psemek/math/rotation.hpp>
#include <psemek/math/translation.hpp>
#include <psemek/math/scale.hpp>
#include <psemek/util/clock.hpp>
#include <psemek/util/moving_average.hpp>
@ -44,7 +44,7 @@ struct deferred_app
gfx::texture_2d pre_fxaa_texture;
gfx::fxaa fxaa;
geom::spherical_camera camera;
math::spherical_camera camera;
gfx::mesh plane;
gfx::mesh cube;
@ -64,13 +64,13 @@ deferred_app::deferred_app(options const &, context const & context)
{
context.vsync(false);
camera.fov_y = geom::rad(45.f);
camera.fov_y = math::rad(45.f);
camera.near_clip = 0.1f;
camera.far_clip = 1000.f;
camera.target = {0.f, 0.f, 0.f};
camera.distance = 20.f;
camera.azimuthal_angle = 0.f;
camera.elevation_angle = geom::rad(30.f);
camera.elevation_angle = math::rad(30.f);
pre_gamma_texture.linear_filter();
pre_fxaa_texture.linear_filter();
@ -85,10 +85,10 @@ deferred_app::deferred_app(options const &, context const & context)
struct vertex
{
geom::point<float, 3> position;
math::point<float, 3> position;
gfx::color_rgba color;
geom::vector<float, 2> texcoord;
geom::vector<float, 3> normal;
math::vector<float, 2> texcoord;
math::vector<float, 3> normal;
static auto attribs()
{
@ -98,7 +98,7 @@ deferred_app::deferred_app(options const &, context const & context)
struct instance
{
geom::matrix<float, 3, 4> transform;
math::matrix<float, 3, 4> transform;
static auto attribs()
{
@ -115,7 +115,7 @@ deferred_app::deferred_app(options const &, context const & context)
vertices.push_back({{-1.f, 1.f, 0.f}, color, {0.f, 0.f}, {0.f, 0.f, 1.f}});
vertices.push_back({{ 1.f, 1.f, 0.f}, color, {0.f, 0.f}, {0.f, 0.f, 1.f}});
std::vector<geom::triangle<std::uint32_t>> indices;
std::vector<math::triangle<std::uint32_t>> indices;
indices.push_back({0, 1, 2});
indices.push_back({2, 1, 3});
@ -124,17 +124,17 @@ deferred_app::deferred_app(options const &, context const & context)
}
{
auto box = geom::box<float, 3>{{{-1.f, 1.f}, {-1.f, 1.f}, {-1.f, 1.f}}};
auto box = math::box<float, 3>{{{-1.f, 1.f}, {-1.f, 1.f}, {-1.f, 1.f}}};
auto triangles = geom::deindex(geom::vertices(box), geom::faces(box));
auto triangles = math::deindex(math::vertices(box), math::faces(box));
std::vector<geom::triangle<vertex>> vertices;
std::vector<math::triangle<vertex>> vertices;
for (auto const & t : triangles)
{
auto & r = vertices.emplace_back();
auto n = geom::normal(t[0], t[1], t[2]);
auto n = math::normal(t[0], t[1], t[2]);
std::size_t tcm = 0;
if (std::abs(n[1]) > std::abs(n[tcm])) tcm = 1;
@ -162,7 +162,7 @@ deferred_app::deferred_app(options const &, context const & context)
{
std::vector<vertex> vertices;
geom::point<float, 3> const origin {0.f, 0.f, 0.f};
math::point<float, 3> const origin {0.f, 0.f, 0.f};
float const radius = 1.f;
@ -174,19 +174,19 @@ deferred_app::deferred_app(options const &, context const & context)
{
for (int i = 0; i < 4 * N; ++i)
{
float a = (geom::pi * i) / (2 * N);
float b = (geom::pi * j) / (2 * N);
float a = (math::pi * i) / (2 * N);
float b = (math::pi * j) / (2 * N);
geom::vector n{std::cos(a) * std::cos(b), std::sin(a) * std::cos(b), std::sin(b)};
math::vector n{std::cos(a) * std::cos(b), std::sin(a) * std::cos(b), std::sin(b)};
vertices.push_back({origin + radius * n, c, {0.f, 0.f}, n});
}
}
vertices.push_back({origin + geom::vector{0.f, 0.f, -radius}, c, {0.f, 0.f}, {0.f, 0.f, -1.f}});
vertices.push_back({origin + geom::vector{0.f, 0.f, radius}, c, {0.f, 0.f}, {0.f, 0.f, 1.f}});
vertices.push_back({origin + math::vector{0.f, 0.f, -radius}, c, {0.f, 0.f}, {0.f, 0.f, -1.f}});
vertices.push_back({origin + math::vector{0.f, 0.f, radius}, c, {0.f, 0.f}, {0.f, 0.f, 1.f}});
std::vector<geom::triangle<std::uint32_t>> indices;
std::vector<math::triangle<std::uint32_t>> indices;
auto idx = [](int i, int j) -> std::uint32_t { return (i % (4 * N)) + 4 * N * (j + N - 1); };
@ -216,7 +216,7 @@ deferred_app::deferred_app(options const &, context const & context)
{
std::vector<vertex> vertices;
geom::point<float, 3> const position = {0.f, 0.f, 0.f};
math::point<float, 3> const position = {0.f, 0.f, 0.f};
float const radius1 = 0.8f;
float const radius2 = 0.2f;
@ -230,18 +230,18 @@ deferred_app::deferred_app(options const &, context const & context)
{
for (int i = 0; i < N; ++i)
{
float a = (2.f * geom::pi * i) / N;
float b = (2.f * geom::pi * j) / M;
float a = (2.f * math::pi * i) / N;
float b = (2.f * math::pi * j) / M;
geom::vector r{std::cos(a), std::sin(a), 0.f};
math::vector r{std::cos(a), std::sin(a), 0.f};
geom::vector n{std::cos(a) * std::cos(b), std::sin(a) * std::cos(b), std::sin(b)};
math::vector n{std::cos(a) * std::cos(b), std::sin(a) * std::cos(b), std::sin(b)};
vertices.push_back({position + radius1 * r + radius2 * n, color, {0.f, 0.f}, n});
}
}
std::vector<geom::triangle<std::uint32_t>> indices;
std::vector<math::triangle<std::uint32_t>> indices;
auto idx = [](int i, int j) -> std::uint32_t { return (i % N) + N * (j % M); };
@ -295,11 +295,11 @@ void deferred_app::on_event(app::resize_event const & event)
app::application_base::on_event(event);
camera.set_fov(camera.fov_y, static_cast<float>(event.size[0]) / event.size[1]);
pre_gamma_texture.load<geom::vector<std::uint16_t, 3>>(geom::cast<std::size_t>(event.size));
pre_gamma_texture.load<math::vector<std::uint16_t, 3>>(math::cast<std::size_t>(event.size));
pre_gamma_framebuffer.color(pre_gamma_texture);
pre_gamma_framebuffer.assert_complete();
pre_fxaa_texture.load<gfx::color_rgb>(geom::cast<std::size_t>(event.size));
pre_fxaa_texture.load<gfx::color_rgb>(math::cast<std::size_t>(event.size));
pre_fxaa_framebuffer.color(pre_fxaa_texture);
pre_fxaa_framebuffer.assert_complete();
}
@ -343,7 +343,7 @@ void deferred_app::present()
{
gfx::deferred_renderer::object obj;
obj.mesh = &plane;
obj.pre_transform = geom::scale<float, 3>(10.f).affine_matrix();
obj.pre_transform = math::scale<float, 3>(10.f).affine_matrix();
obj.bbox = {{{-10.f, 10.f}, {-10.f, 10.f}, {0.f, 0.f}}};
obj.mat = &plane_material;
objects.push_back(obj);
@ -358,7 +358,7 @@ void deferred_app::present()
{
gfx::deferred_renderer::object obj;
obj.mesh = &cube;
obj.pre_transform = geom::translation<float, 3>{geom::vector{x, y, 3.f}}.affine_matrix();
obj.pre_transform = math::translation<float, 3>{math::vector{x, y, 3.f}}.affine_matrix();
obj.bbox = {{{x - 1.f, x + 1.f}, {y - 1.f, y + 1.f}, {2.f, 4.f}}};
obj.mat = &cube_material;
objects.push_back(obj);
@ -374,7 +374,7 @@ void deferred_app::present()
{
gfx::deferred_renderer::object obj;
obj.mesh = &sphere;
obj.pre_transform = geom::translation<float, 3>{geom::vector{0.f, 0.f, z}}.affine_matrix();
obj.pre_transform = math::translation<float, 3>{math::vector{0.f, 0.f, z}}.affine_matrix();
obj.bbox = {{{-1.f, 1.f}, {-1.f, 1.f}, {z - 1.f, z + 1.f}}};
obj.mat = &sphere_material;
objects.push_back(obj);
@ -383,7 +383,7 @@ void deferred_app::present()
{
gfx::deferred_renderer::object obj;
obj.mesh = &torus;
obj.pre_transform = geom::translation<float, 3>{geom::vector{0.f, 0.f, 4.f}}.affine_matrix();
obj.pre_transform = math::translation<float, 3>{math::vector{0.f, 0.f, 4.f}}.affine_matrix();
obj.bbox = {{{-1.f, 1.f}, {-1.f, 1.f}, {4 - 0.2f, 4 + 0.2f}}};
obj.mat = &sphere_material;
objects.push_back(obj);
@ -392,7 +392,7 @@ void deferred_app::present()
gfx::deferred_renderer::options options;
options.camera = &camera;
options.clear_color = geom::vector{0.f, 0.f, 0.1f};
options.clear_color = math::vector{0.f, 0.f, 0.1f};
options.ambient = {1.f, 1.f, 1.f};
options.directional_lights.emplace_back();
@ -419,7 +419,7 @@ void deferred_app::present()
for (int i = 0; i < 24; ++i)
{
float a = (i * geom::pi) / 12.f;
float a = (i * math::pi) / 12.f;
auto & l = options.point_lights.emplace_back();
l.color = {15.f, 15.f, 15.f};
@ -437,9 +437,9 @@ void deferred_app::present()
float const s = 0.1f;
gfx::deferred_renderer::object obj;
obj.mesh = &sphere;
obj.pre_transform = (geom::translation<float, 3>{l.position - geom::point<float, 3>::zero()}.transform() * geom::scale<float, 3>(s).transform()).affine_matrix();
obj.pre_transform = (math::translation<float, 3>{l.position - math::point<float, 3>::zero()}.transform() * math::scale<float, 3>(s).transform()).affine_matrix();
obj.bbox = {{{l.position[0] - s, l.position[0] + s}, {l.position[1] - s, l.position[1] + s}, {l.position[2] - s, l.position[2] + s}}};
light_materials[i].color = geom::vector{l.color[0], l.color[1], l.color[2], 1.f};
light_materials[i].color = math::vector{l.color[0], l.color[1], l.color[2], 1.f};
light_materials[i].lit = false;
light_materials[i].casts_shadow = false;
obj.mat = &light_materials[i];
@ -495,7 +495,7 @@ void deferred_app::present()
gl::Enable(gl::BLEND);
gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
painter.render(geom::window_camera{state().size[0], state().size[1]}.transform());
painter.render(math::window_camera{state().size[0], state().size[1]}.transform());
}
namespace psemek::app

View file

@ -30,11 +30,11 @@
using namespace psemek;
std::vector<std::vector<geom::point<int, 2>>> fibonacci_cycles(int n)
std::vector<std::vector<math::point<int, 2>>> fibonacci_cycles(int n)
{
util::array<int, 2> cycle({n, n}, -1);
std::vector<std::vector<geom::point<int, 2>>> result;
std::vector<std::vector<math::point<int, 2>>> result;
for (int i = 0; i < n; ++i)
{
@ -46,14 +46,14 @@ std::vector<std::vector<geom::point<int, 2>>> fibonacci_cycles(int n)
int cycle_id = result.size();
auto & current = result.emplace_back();
geom::point p{i, j};
math::point p{i, j};
while (true)
{
current.push_back(p);
cycle(p[0], p[1]) = cycle_id;
p = {p[1], (p[0] + p[1]) % n};
if (p == geom::point{i, j})
if (p == math::point{i, j})
break;
}
}
@ -77,7 +77,7 @@ std::shared_ptr<audio::stream> note(int i, float duration)
return audio::fade_in(audio::fade_out(audio::karplus_strong(audio::midi_frequency(69 + i)), duration), duration / 16.f);
}
std::shared_ptr<audio::track> generate(std::vector<int> const & scale, std::vector<geom::point<int, 2>> const & cycle, float speed)
std::shared_ptr<audio::track> generate(std::vector<int> const & scale, std::vector<math::point<int, 2>> const & cycle, float speed)
{
auto mixer = audio::make_mixer();

View file

@ -3,13 +3,13 @@
#include <psemek/gfx/mesh.hpp>
#include <psemek/gfx/program.hpp>
#include <psemek/gfx/texture.hpp>
#include <psemek/geom/camera.hpp>
#include <psemek/geom/math.hpp>
#include <psemek/geom/rotation.hpp>
#include <psemek/geom/scale.hpp>
#include <psemek/geom/translation.hpp>
#include <psemek/geom/easing.hpp>
#include <psemek/geom/gradient.hpp>
#include <psemek/math/camera.hpp>
#include <psemek/math/math.hpp>
#include <psemek/math/rotation.hpp>
#include <psemek/math/scale.hpp>
#include <psemek/math/translation.hpp>
#include <psemek/math/easing.hpp>
#include <psemek/math/gradient.hpp>
#include <psemek/random/device.hpp>
#include <psemek/random/generator.hpp>
#include <psemek/random/uniform_sphere.hpp>
@ -81,17 +81,17 @@ struct candle_renderer
{
candle_renderer();
void add(geom::point<float, 3> const & pos, geom::vector<float, 3> const & dir, float size);
void add(math::point<float, 3> const & pos, math::vector<float, 3> const & dir, float size);
void render(geom::camera const & camera, float time);
void render(math::camera const & camera, float time);
private:
struct candle
{
geom::point<float, 3> pos;
geom::vector<float, 3> dir;
math::point<float, 3> pos;
math::vector<float, 3> dir;
float size;
geom::vector<float, 2> noise_offset;
math::vector<float, 2> noise_offset;
};
std::vector<candle> candles_;
@ -109,7 +109,7 @@ private:
candle_renderer::candle_renderer()
{
std::vector<geom::point<float, 3>> vertices;
std::vector<math::point<float, 3>> vertices;
vertices.push_back({-1.f, 0.f, -1.f});
vertices.push_back({ 1.f, 0.f, -1.f});
vertices.push_back({ 1.f, 0.f, 1.f});
@ -117,25 +117,25 @@ candle_renderer::candle_renderer()
vertices.push_back({ 1.f, 0.f, 1.f});
vertices.push_back({-1.f, 0.f, 1.f});
mesh_.setup<geom::point<float, 3>, gfx::instanced<geom::point<float, 3>>, gfx::instanced<geom::vector<float, 3>>, gfx::instanced<float>, gfx::instanced<geom::vector<float, 2>>>();
mesh_.setup<math::point<float, 3>, gfx::instanced<math::point<float, 3>>, gfx::instanced<math::vector<float, 3>>, gfx::instanced<float>, gfx::instanced<math::vector<float, 2>>>();
mesh_.load(vertices, gl::TRIANGLES);
geom::vector<float, 4> c0 {1.f, 0.99f, 0.98f, 1.f};
geom::vector<float, 4> c1 {1.f, 0.4f, 0.f, 0.75f};
geom::vector<float, 4> c2 {c1[0], c1[1], c1[2], 0.f};
math::vector<float, 4> c0 {1.f, 0.99f, 0.98f, 1.f};
math::vector<float, 4> c1 {1.f, 0.4f, 0.f, 0.75f};
math::vector<float, 4> c2 {c1[0], c1[1], c1[2], 0.f};
geom::gradient<float> gy{
math::gradient<float> gy{
std::make_pair(0.f, 0.f),
geom::easing_type::quadratic_in,
math::easing_type::quadratic_in,
std::make_pair(1.f, 2.f),
};
geom::gradient<float, geom::vector<float, 4>> gc
math::gradient<float, math::vector<float, 4>> gc
{
std::make_pair(0.1f, c0),
geom::easing_type::linear,
math::easing_type::linear,
std::pair{0.8f, c1},
geom::easing_type::cubic,
math::easing_type::cubic,
std::pair{1.2f, c2}
};
@ -172,7 +172,7 @@ candle_renderer::candle_renderer()
random::generator rng;
random::uniform_sphere_vector_distribution<float, 2> d;
util::array<geom::vector<float, 2>, 2> grad({16, 16});
util::array<math::vector<float, 2>, 2> grad({16, 16});
for (auto & v : grad) v = d(rng);
pcg::perlin<float, 2> perlinx(grad, pcg::seamless);
@ -180,13 +180,13 @@ candle_renderer::candle_renderer()
for (auto & v : grad) v = d(rng);
pcg::perlin<float, 2> perliny(grad, pcg::seamless);
gfx::basic_pixmap<geom::vector<std::uint8_t, 2>> pm({512, 512});
gfx::basic_pixmap<math::vector<std::uint8_t, 2>> pm({512, 512});
for (auto idx : pm.indices())
{
float x = (0.5f + idx[0]) / pm.width();
float y = (0.5f + idx[1]) / pm.height();
pm(idx) = gfx::to_coloru8(geom::vector{perlinx({x, y}), perliny({x, y})});
pm(idx) = gfx::to_coloru8(math::vector{perlinx({x, y}), perliny({x, y})});
}
noise_texture_.load(pm);
noise_texture_.linear_filter();
@ -196,11 +196,11 @@ candle_renderer::candle_renderer()
}
}
void candle_renderer::add(geom::point<float, 3> const & pos, geom::vector<float, 3> const & dir, float size)
void candle_renderer::add(math::point<float, 3> const & pos, math::vector<float, 3> const & dir, float size)
{
random::generator rng{random::device{}};
random::uniform_sphere_vector_distribution<float, 2> d;
geom::vector<float, 2> noise_offset;
math::vector<float, 2> noise_offset;
while (true)
{
noise_offset = d(rng);
@ -215,7 +215,7 @@ void candle_renderer::add(geom::point<float, 3> const & pos, geom::vector<float,
instances_need_update_ = true;
}
void candle_renderer::render(geom::camera const & camera, float time)
void candle_renderer::render(math::camera const & camera, float time)
{
if (instances_need_update_) update_instances();
@ -236,10 +236,10 @@ void candle_renderer::update_instances()
{
struct instance
{
geom::point<float, 3> pos;
geom::vector<float, 3> dir;
math::point<float, 3> pos;
math::vector<float, 3> dir;
float size;
geom::vector<float, 2> noise_offset;
math::vector<float, 2> noise_offset;
};
std::vector<instance> instances;
@ -256,7 +256,7 @@ void candle_renderer::update_instances()
struct fire_app
: app::application_base
{
geom::spherical_camera camera;
math::spherical_camera camera;
candle_renderer candles;
@ -265,7 +265,7 @@ struct fire_app
fire_app(options const &, context const &)
{
camera.fov_y = geom::rad(45.f);
camera.fov_y = math::rad(45.f);
camera.near_clip = 0.01f;
camera.far_clip = 1000.f;
camera.target = {0.f, 0.f, 0.f};

View file

@ -2,9 +2,9 @@
#include <psemek/app/default_application_factory.hpp>
#include <psemek/gfx/painter.hpp>
#include <psemek/gfx/gl.hpp>
#include <psemek/geom/scale.hpp>
#include <psemek/geom/camera.hpp>
#include <psemek/geom/constants.hpp>
#include <psemek/math/scale.hpp>
#include <psemek/math/camera.hpp>
#include <psemek/math/constants.hpp>
#include <psemek/util/clock.hpp>
#include <psemek/util/to_string.hpp>
#include <psemek/prof/profiler.hpp>
@ -49,8 +49,8 @@ using namespace psemek;
struct particle
{
geom::point<float, 2> pos;
geom::vector<float, 2> vel;
math::point<float, 2> pos;
math::vector<float, 2> vel;
float angle;
float angle_vel;
@ -59,12 +59,12 @@ struct particle
float mass;
float density;
geom::vector<float, 2> delta_pos{0.f, 0.f};
geom::vector<float, 2> delta_vel{0.f, 0.f};
math::vector<float, 2> delta_pos{0.f, 0.f};
math::vector<float, 2> delta_vel{0.f, 0.f};
geom::point<float, 2> old_pos{0.f, 0.f};
math::point<float, 2> old_pos{0.f, 0.f};
geom::vector<float, 2> acc{0.f, 0.f};
math::vector<float, 2> acc{0.f, 0.f};
float T = 0.f;
};
@ -78,7 +78,7 @@ float const FR = 0.99f;
float const dt = 0.01f;
float const world_size = 10000000.f;
geom::point world_center{0.f, 0.f};
math::point world_center{0.f, 0.f};
int const SOLVE_ITERATIONS = 16;
float const BIAS = 1.f / 8.f;
@ -96,7 +96,7 @@ struct myapp
std::uniform_real_distribution<float> d{-50.f, 50.f};
std::uniform_real_distribution<float> rr{0.5f, 2.f};
std::uniform_real_distribution<float> rden{0.25f, 1.f};
std::uniform_real_distribution<float> ra{0.f, 2.f * geom::pi};
std::uniform_real_distribution<float> ra{0.f, 2.f * math::pi};
float min_R = 0.f;
float max_R = 100.f;
@ -105,7 +105,7 @@ struct myapp
bool star = false;
if (star)
particles_.push_back({{0.f, 0.f}, {0.f, 0.f}, 0.f, 0.f, 10.f, geom::pi * 10000.f, 1.f});
particles_.push_back({{0.f, 0.f}, {0.f, 0.f}, 0.f, 0.f, 10.f, math::pi * 10000.f, 1.f});
// particles_.push_back({{-2.f, 0.f}, {0.f, 0.f}, 0.f, 0.f, 1.f, 1.f, 1.f});
// particles_.push_back({{ 2.f, 0.f}, {0.f, 0.f}, 0.f, 0.f, 1.f, 1.f, 1.f});
@ -113,14 +113,14 @@ struct myapp
// particles_.push_back({{ 0.f, -3.f}, {0.f, 0.f}, 0.f, 0.f, 1.f, 1.f, 1.f});
// float planet_R[] = {200.f, 300.f, 400.f};
// float planet_a[] = {0.f, geom::rad(120.f), geom::rad(240.f)};
// float planet_a[] = {0.f, math::rad(120.f), math::rad(240.f)};
// if(false)
for (int i = 0; i < 500; ++i)
{
geom::vector v{0.f, 0.f};
math::vector v{0.f, 0.f};
geom::point<float, 2> p;
math::point<float, 2> p;
float m;
float r;
float den;
@ -130,7 +130,7 @@ struct myapp
r = rr(rng_);
den = rden(rng_);
m = geom::pi * r * r * den;
m = math::pi * r * r * den;
auto a = ra(rng_);
float R = std::sqrt(rR(rng_)) * (max_R - min_R) + min_R;
@ -142,18 +142,18 @@ struct myapp
// R = planet_R[pl];
// R += std::uniform_real_distribution<float>(-10.f, 10.f)(rng_);
// a += geom::rad(std::uniform_real_distribution<float>(-2.f, 2.f)(rng_));
// a += math::rad(std::uniform_real_distribution<float>(-2.f, 2.f)(rng_));
p =
{
R * std::cos(a),
R * std::sin(a),
};
// p += geom::vector{((i % 2) ? -1000.f : 1000.f), 0.f};
// p += math::vector{((i % 2) ? -1000.f : 1000.f), 0.f};
// v[0] = {(i % 2) ? 100.f : -100.f};
if (std::all_of(particles_.begin(), particles_.end(), [&](particle const & q){ return geom::distance(q.pos, p) > q.radius + r; }))
if (std::all_of(particles_.begin(), particles_.end(), [&](particle const & q){ return math::distance(q.pos, p) > q.radius + r; }))
break;
}
particles_.push_back({p, v, 0.f, 0.f, r, m, den});
@ -168,10 +168,10 @@ struct myapp
if(false)
for (std::size_t i = star ? 1 : 0; i < particles_.size(); ++i)
{
auto r = particles_[i].pos - geom::point{0.f, 0.f};
auto R = geom::length(r);
auto r = particles_[i].pos - math::point{0.f, 0.f};
auto R = math::length(r);
float V = std::sqrt(G * total_M / R);
particles_[i].vel = geom::ort(r / R) * V;
particles_[i].vel = math::ort(r / R) * V;
(void)V;
}
@ -199,24 +199,24 @@ struct myapp
{
if (event.button == app::mouse_button::left && event.down)
{
geom::scale<float, 2> const flip_y({1.f, -1.f});
math::scale<float, 2> const flip_y({1.f, -1.f});
float const scale = camera_size_ / state().size[1];
geom::point<int, 2> const screen_center { state().size[0] / 2,state().size[1] / 2 };
auto target = camera_center_ + flip_y(geom::cast<float>(state().mouse - screen_center) * scale);
math::point<int, 2> const screen_center { state().size[0] / 2,state().size[1] / 2 };
auto target = camera_center_ + flip_y(math::cast<float>(state().mouse - screen_center) * scale);
force_target_ = target;
// geom::point<float, 2> pos{100.f, 0.f};
// math::point<float, 2> pos{100.f, 0.f};
// geom::vector<float, 2> vel = geom::normalized(target - pos) * 40.f;
// math::vector<float, 2> vel = math::normalized(target - pos) * 40.f;
// particles_.push_back({pos, vel, 1.f, 1.f});
// for (auto & p : particles_)
// {
// auto r = p.pos - target;
// p.vel += 4000.f * r / geom::length_sqr(r) / p.mass;
// p.vel += 4000.f * r / math::length_sqr(r) / p.mass;
// }
}
@ -242,20 +242,20 @@ struct myapp
if (camera_drag_)
{
geom::scale<float, 2> const flip_y({1.f, -1.f});
math::scale<float, 2> const flip_y({1.f, -1.f});
float const scale = camera_size_ / state().size[1];
camera_center_ += flip_y(geom::cast<float>(*camera_drag_ - event.position) * scale);
camera_center_ += flip_y(math::cast<float>(*camera_drag_ - event.position) * scale);
camera_drag_ = event.position;
}
if (force_target_)
{
geom::scale<float, 2> const flip_y({1.f, -1.f});
math::scale<float, 2> const flip_y({1.f, -1.f});
float const scale = camera_size_ / state().size[1];
geom::point<int, 2> const screen_center { state().size[0] / 2, state().size[1] / 2 };
auto target = camera_center_ + flip_y(geom::cast<float>(state().mouse - screen_center) * scale);
math::point<int, 2> const screen_center { state().size[0] / 2, state().size[1] / 2 };
auto target = camera_center_ + flip_y(math::cast<float>(state().mouse - screen_center) * scale);
force_target_ = target;
}
}
@ -290,18 +290,18 @@ struct myapp
p.acc = {0.f, 0.f};
for (auto & p : particles_)
p.acc += geom::vector{0.f, -GG};
p.acc += math::vector{0.f, -GG};
for (auto & p : particles_)
{
auto r = (p.pos - p.pos.zero());
p.acc -= GC * r / std::pow(1.f + geom::length(r), 3.f);
p.acc -= GC * r / std::pow(1.f + math::length(r), 3.f);
}
// for (std::size_t i = 0; i < particles_.size(); ++i)
// {
// log::info() << "Start: #" << i << " pos = " << std::setprecision(10) << particles_[i].pos << ", vel = " << particles_[i].vel
// << ", |vel| = " << geom::length(particles_[i].vel);
// << ", |vel| = " << math::length(particles_[i].vel);
// }
for (std::size_t i = 0; i < particles_.size(); ++i)
@ -348,7 +348,7 @@ struct myapp
// auto vij = particles_[i].vel - particles_[j].vel;
// auto vn = geom::dot(vij, n) * n;
// auto vn = math::dot(vij, n) * n;
// particles_[i].acc -= vn * particles_[j].mass / (particles_[i].mass + particles_[j].mass);
// particles_[j].acc += vn * particles_[i].mass / (particles_[i].mass + particles_[j].mass);
@ -374,7 +374,7 @@ struct myapp
for (auto & p : particles_)
{
auto r = p.pos - *force_target_;
p.acc += 100000.f * r / geom::length_sqr(r) / p.mass;
p.acc += 100000.f * r / math::length_sqr(r) / p.mass;
}
}
@ -420,14 +420,14 @@ struct myapp
// New iterative algorithm
if (false)
{
std::vector<geom::point<float, 2>> old_pos(particles_.size());
std::vector<math::point<float, 2>> old_pos(particles_.size());
for (std::size_t i = 0; i < particles_.size(); ++i)
old_pos[i] = particles_[i].pos;
struct collision
{
std::size_t i, j;
geom::vector<float, 2> n; // i -> j
math::vector<float, 2> n; // i -> j
};
std::vector<collision> collisions;
@ -452,7 +452,7 @@ struct myapp
{
auto const r = particles_[c.j].pos - particles_[c.i].pos;
auto const R = particles_[c.j].radius + particles_[c.i].radius;
auto const l = geom::dot(r, c.n);
auto const l = math::dot(r, c.n);
if (l < R)
{
@ -488,9 +488,9 @@ struct myapp
auto dv = particles_[i].vel - particles_[j].vel;
auto R = particles_[i].radius + particles_[j].radius;
float A = geom::dot(dv, dv);
float B = geom::dot(dp, dv);
float C = geom::dot(dp, dp) - geom::sqr(R);
float A = math::dot(dv, dv);
float B = math::dot(dp, dv);
float C = math::dot(dp, dp) - math::sqr(R);
if (B >= 0.f) return;
@ -522,7 +522,7 @@ struct myapp
// particle_time[i] = e.t;
// particle_time[j] = e.t;
auto n = geom::normalized(particles_[i].pos - particles_[j].pos);
auto n = math::normalized(particles_[i].pos - particles_[j].pos);
float S = 0.5f * (1.f / particles_[i].mass + 1.f / particles_[j].mass);
float T = dot(n, particles_[i].vel - particles_[j].vel);
@ -569,7 +569,7 @@ struct myapp
std::vector<float> particle_time(particles_.size(), 0.f);
std::unordered_map<geom::vector<int, 2>, std::vector<std::size_t>> cells;
std::unordered_map<math::vector<int, 2>, std::vector<std::size_t>> cells;
float time = 0.f;
@ -584,9 +584,9 @@ struct myapp
auto dv = particles_[i].vel - particles_[j].vel;
auto R = particles_[i].radius + particles_[j].radius;
float A = geom::dot(dv, dv);
float B = geom::dot(dp, dv);
float C = geom::dot(dp, dp) - geom::sqr(R);
float A = math::dot(dv, dv);
float B = math::dot(dp, dv);
float C = math::dot(dp, dp) - math::sqr(R);
// log::info() << "DV = " << dv;
// log::info() << "DP = " << dp;
@ -597,7 +597,7 @@ struct myapp
// if (B > 0.f) return;
// auto result = geom::solve_quadratic(A, B, C);
// auto result = math::solve_quadratic(A, B, C);
// if (!result) return;
// log::info() << result->first << " " << result->second;
@ -620,7 +620,7 @@ struct myapp
// if (!collision_time) return;
if (B >= -0.01f * geom::length(dv) * geom::length(dp)) return;
if (B >= -0.01f * math::length(dv) * math::length(dp)) return;
float collision_time;
@ -641,7 +641,7 @@ struct myapp
if (collision_time >= dt) return;
auto dpn = (particles_[i].pos + particles_[i].vel * (collision_time - particle_time[i])) - (particles_[j].pos + particles_[j].vel * (collision_time - particle_time[j]));
if (geom::dot(dv, dpn) >= -0.01f * geom::length(dv) * geom::length(dpn)) return;
if (math::dot(dv, dpn) >= -0.01f * math::length(dv) * math::length(dpn)) return;
auto insert_result = events.insert(collision_event{i, j, collision_time});
if (insert_result.second)
@ -670,15 +670,15 @@ struct myapp
auto foreach_cells = [&](std::size_t i, auto && callback)
{
geom::box<float, 2> bbox;
math::box<float, 2> bbox;
bbox |= particles_[i].pos - geom::vector{1.f, 1.f} * particles_[i].radius;
bbox |= particles_[i].pos + geom::vector{1.f, 1.f} * particles_[i].radius;
bbox |= particles_[i].pos - math::vector{1.f, 1.f} * particles_[i].radius;
bbox |= particles_[i].pos + math::vector{1.f, 1.f} * particles_[i].radius;
auto npos = particles_[i].pos + particles_[i].vel * dt;//(dt - particle_time[i]);
bbox |= npos - geom::vector{1.f, 1.f} * particles_[i].radius;
bbox |= npos + geom::vector{1.f, 1.f} * particles_[i].radius;
bbox |= npos - math::vector{1.f, 1.f} * particles_[i].radius;
bbox |= npos + math::vector{1.f, 1.f} * particles_[i].radius;
int xmin = std::floor(bbox[0].min);
int xmax = std::floor(bbox[0].max);
@ -724,17 +724,17 @@ struct myapp
particles_[e.i0].pos += particles_[e.i0].vel * (e.t - particle_time[e.i0]);
particles_[e.i1].pos += particles_[e.i1].vel * (e.t - particle_time[e.i1]);
// log::info() << "Collision " << e.i0 << " " << e.i1 << " " << geom::distance(particles_[e.i0].pos, particles_[e.i1].pos);
// log::info() << "Collision " << e.i0 << " " << e.i1 << " " << math::distance(particles_[e.i0].pos, particles_[e.i1].pos);
particle_time[e.i0] = e.t;
particle_time[e.i1] = e.t;
auto n = geom::normalized(particles_[e.i0].pos - particles_[e.i1].pos);
auto n = math::normalized(particles_[e.i0].pos - particles_[e.i1].pos);
float A = 0.5f * (1.f / particles_[e.i0].mass + 1.f / particles_[e.i1].mass);
float B = dot(n, particles_[e.i0].vel - particles_[e.i1].vel);
auto BB = B / geom::length(particles_[e.i0].vel - particles_[e.i1].vel);
auto BB = B / math::length(particles_[e.i0].vel - particles_[e.i1].vel);
(void)BB;
auto np = n * (- B / A);
@ -769,13 +769,13 @@ struct myapp
auto vij = particles_[i].vel - particles_[j].vel;
auto R = particles_[i].radius + particles_[j].radius;
float B = geom::dot(rij, vij);
float B = math::dot(rij, vij);
if (B >= 0.f) continue;
std::optional<collision_event> e;
float C = geom::dot(rij, rij) - geom::sqr(R);
float C = math::dot(rij, rij) - math::sqr(R);
if (C <= 0.f)
{
@ -783,7 +783,7 @@ struct myapp
}
else
{
float A = geom::dot(vij, vij);
float A = math::dot(vij, vij);
float D = B * B - A * C;
@ -868,26 +868,26 @@ struct myapp
for (auto & p : particles_)
{
auto r = p.pos - world_center;
auto l = geom::length(r);
auto l = math::length(r);
if (l + p.radius > world_size)
{
auto n = r / l;
auto t = geom::ort(n);
auto t = math::ort(n);
auto vn = n * geom::dot(p.vel, n);
auto vn = n * math::dot(p.vel, n);
auto vt = t * geom::dot(p.vel + t * p.angle_vel * p.radius, t);
auto vt = t * math::dot(p.vel + t * p.angle_vel * p.radius, t);
auto pt = - vt * (1.f - std::exp(- 10.f * dt));
float I = 0.5f * p.mass * geom::sqr(p.radius);
float I = 0.5f * p.mass * math::sqr(p.radius);
p.pos -= n * (l + p.radius - world_size);
p.vel -= 1.75f * vn;
p.vel += pt / p.mass;
p.angle_vel += geom::det(n * p.radius, pt) / I;
p.angle_vel += math::det(n * p.radius, pt) / I;
}
}
@ -912,14 +912,14 @@ struct myapp
auto const vij = particles_[i].vel - particles_[j].vel;
auto dp = - K * dt * n * dot(n, vij) * 2.f / (1.f / particles_[i].mass + 1.f / particles_[j].mass);
float Ei0 = geom::length_sqr(particles_[i].vel) * particles_[i].mass * 0.5f;
float Ei0 = math::length_sqr(particles_[i].vel) * particles_[i].mass * 0.5f;
particles_[i].vel += dp / particles_[i].mass;
float Ei1 = geom::length_sqr(particles_[i].vel) * particles_[i].mass * 0.5f;
float Ei1 = math::length_sqr(particles_[i].vel) * particles_[i].mass * 0.5f;
particles_[i].T += Ei0 - Ei1;
float Ej0 = geom::length_sqr(particles_[j].vel) * particles_[j].mass * 0.5f;
float Ej0 = math::length_sqr(particles_[j].vel) * particles_[j].mass * 0.5f;
particles_[j].vel -= dp / particles_[j].mass;
float Ej1 = geom::length_sqr(particles_[j].vel) * particles_[j].mass * 0.5f;
float Ej1 = math::length_sqr(particles_[j].vel) * particles_[j].mass * 0.5f;
particles_[j].T += Ej0 - Ej1;
float dT = particles_[i].T - particles_[j].T;
@ -939,8 +939,8 @@ struct myapp
p.pos = particles_[i].pos + (particles_[j].pos - particles_[i].pos) * particles_[j].mass / M;
p.vel = (particles_[i].vel * particles_[i].mass + particles_[j].vel * particles_[j].mass) / M;
p.mass = M;
p.radius = std::sqrt(geom::sqr(particles_[i].radius) + geom::sqr(particles_[j].radius));
p.density = p.mass / (geom::pi * geom::sqr(p.radius));
p.radius = std::sqrt(math::sqr(particles_[i].radius) + math::sqr(particles_[j].radius));
p.density = p.mass / (math::pi * math::sqr(p.radius));
particles_[i] = p;
particles_.erase(particles_.begin() + j);
@ -963,10 +963,10 @@ struct myapp
auto ri = p - particles_[i].pos;
auto rj = p - particles_[j].pos;
auto t = geom::ort(n);
auto t = math::ort(n);
auto vri = geom::dot(t, particles_[i].vel + geom::ort(ri) * particles_[i].angle_vel);
auto vrj = geom::dot(t, particles_[j].vel + geom::ort(rj) * particles_[j].angle_vel);
auto vri = math::dot(t, particles_[i].vel + math::ort(ri) * particles_[i].angle_vel);
auto vrj = math::dot(t, particles_[j].vel + math::ort(rj) * particles_[j].angle_vel);
auto vrij = vri - vrj;
@ -975,11 +975,11 @@ struct myapp
particles_[i].vel += (np + tp) / particles_[i].mass;
particles_[j].vel -= (np + tp) / particles_[j].mass;
float Ii = 0.5f * particles_[i].mass * geom::sqr(particles_[i].radius);
float Ij = 0.5f * particles_[j].mass * geom::sqr(particles_[j].radius);
float Ii = 0.5f * particles_[i].mass * math::sqr(particles_[i].radius);
float Ij = 0.5f * particles_[j].mass * math::sqr(particles_[j].radius);
auto ti = geom::det(ri, tp);
auto tj = geom::det(rj, -tp);
auto ti = math::det(ri, tp);
auto tj = math::det(rj, -tp);
particles_[i].angle_vel += ti / Ii;
particles_[j].angle_vel += tj / Ij;
@ -1020,7 +1020,7 @@ struct myapp
particles_[i].vel += dt * f / particles_[i].mass;
particles_[j].vel -= dt * f / particles_[j].mass;
auto vn = geom::dot(vij, n) * n;
auto vn = math::dot(vij, n) * n;
// vn *= 1.f - std::exp(- (1.f - l / R));
// vn *= 0.5f;
@ -1048,7 +1048,7 @@ struct myapp
float bias = 0.5f;
float constraint = l - R;
float reduced_mass = 1.f / (1.f / particles_[i].mass + 1.f / particles_[j].mass);
float lambda = (- geom::dot(n, particles_[i].vel - particles_[j].vel) - bias / dt * constraint) * reduced_mass;
float lambda = (- math::dot(n, particles_[i].vel - particles_[j].vel) - bias / dt * constraint) * reduced_mass;
auto impulse = lambda * n;
particles_[i].vel += impulse / particles_[i].mass;
@ -1080,7 +1080,7 @@ struct myapp
struct collision
{
std::size_t i, j;
geom::vector<float, 2> normal;
math::vector<float, 2> normal;
float value;
float impulse = 0.f;
};
@ -1114,7 +1114,7 @@ struct myapp
float reduced_mass = 1.f / (1.f / particles_[c.i].mass + 1.f / particles_[c.j].mass);
auto dv = geom::dot(c.normal, particles_[c.i].vel - particles_[c.j].vel);
auto dv = math::dot(c.normal, particles_[c.i].vel - particles_[c.j].vel);
float elasticity = 0.75f;
float lambda = (- dv - bias / dt * c.value - dv * elasticity) * reduced_mass;
@ -1139,7 +1139,7 @@ struct myapp
for (std::size_t i = 0; i < particles_.size(); ++i)
{
Ek += geom::length_sqr(particles_[i].vel) * particles_[i].mass / 2.f;
Ek += math::length_sqr(particles_[i].vel) * particles_[i].mass / 2.f;
for (std::size_t j = i + 1; j < particles_.size(); ++j)
{
@ -1150,7 +1150,7 @@ struct myapp
float omega = 0.f;
for (std::size_t i = 0; i < particles_.size(); ++i)
{
omega += geom::det(particles_[i].mass * particles_[i].vel, particles_[i].pos - geom::point{0.f, 0.f});
omega += math::det(particles_[i].mass * particles_[i].vel, particles_[i].pos - math::point{0.f, 0.f});
}
energy_ = Ek + Ep;
@ -1190,11 +1190,11 @@ struct myapp
float r = std::max(p.radius * s, 1.5f) / s;
painter_.circle(p.pos, r, {x, x, x, 191});
// painter_.line(p.pos, p.pos + r * geom::direction(p.angle), r / 16.f, {255, 0, 0, 255}, false);
// painter_.line(p.pos, p.pos + r * math::direction(p.angle), r / 16.f, {255, 0, 0, 255}, false);
// painter_.circle(p.pos, r * 0.75f, {255, 255, 255, 255});
}
geom::orthographic_camera camera;
math::orthographic_camera camera;
camera.box[0].min = camera_center_[0] - camera_size_ * camera_ratio_ / 2.f;
camera.box[0].max = camera_center_[0] + camera_size_ * camera_ratio_ / 2.f;
camera.box[1].min = camera_center_[1] - camera_size_ / 2.f;
@ -1206,7 +1206,7 @@ struct myapp
float rotation = 0.f;
for (auto const & p : particles_)
rotation += geom::det(p.pos - p.pos.zero(), p.vel) * p.mass;
rotation += math::det(p.pos - p.pos.zero(), p.vel) * p.mass;
rotation_.push(rotation);
{
@ -1216,11 +1216,11 @@ struct myapp
opts.x = gfx::painter::x_align::center;
opts.y = gfx::painter::y_align::top;
auto put = [&](geom::point<float, 2> const & pos, std::string const & str)
auto put = [&](math::point<float, 2> const & pos, std::string const & str)
{
return;
painter_.text(pos, str, opts);
painter_.text(pos + geom::vector{1.f, 0.f}, str, opts);
painter_.text(pos + math::vector{1.f, 0.f}, str, opts);
};
put({state().size[0] / 2.f, 30.f}, util::to_string("ITERATIONS: ", SOLVE_ITERATIONS));
@ -1231,7 +1231,7 @@ struct myapp
// painter_.text({10.f, 50.f}, util::to_string("Energy: ", energy_), opts);
}
painter_.render(geom::window_camera{state().size[0], state().size[1]}.transform());
painter_.render(math::window_camera{state().size[0], state().size[1]}.transform());
}
~myapp()
@ -1245,13 +1245,13 @@ struct myapp
private:
std::default_random_engine rng_;
std::optional<geom::point<float, 2>> force_target_;
std::optional<math::point<float, 2>> force_target_;
geom::point<float, 2> camera_center_ { 0.f, 0.f };
math::point<float, 2> camera_center_ { 0.f, 0.f };
float camera_size_ = 150.f;
float camera_ratio_ = 1.f;
std::optional<geom::point<int, 2>> camera_drag_;
std::optional<math::point<int, 2>> camera_drag_;
gfx::painter painter_;

View file

@ -4,13 +4,13 @@
#include <psemek/gfx/gl.hpp>
#include <psemek/gfx/painter.hpp>
#include <psemek/geom/point.hpp>
#include <psemek/geom/simplex.hpp>
#include <psemek/geom/orthographic.hpp>
#include <psemek/geom/rotation.hpp>
#include <psemek/geom/camera.hpp>
#include <psemek/geom/math.hpp>
#include <psemek/geom/distance.hpp>
#include <psemek/math/point.hpp>
#include <psemek/math/simplex.hpp>
#include <psemek/math/orthographic.hpp>
#include <psemek/math/rotation.hpp>
#include <psemek/math/camera.hpp>
#include <psemek/math/math.hpp>
#include <psemek/math/distance.hpp>
#include <psemek/util/clock.hpp>
#include <psemek/util/unused.hpp>
@ -50,11 +50,11 @@ namespace psemek::util
struct stick_model
{
std::vector<geom::point<float, 2>> points;
std::vector<geom::vector<float, 2>> vels;
std::vector<math::point<float, 2>> points;
std::vector<math::vector<float, 2>> vels;
std::vector<bool> movable;
std::vector<geom::segment<std::uint32_t>> sticks;
std::vector<math::segment<std::uint32_t>> sticks;
std::vector<float> stick_length;
std::vector<bool> stick_solid;
@ -64,7 +64,7 @@ struct stick_model
void stick_model::add_stick(std::size_t i, std::size_t j, bool solid)
{
sticks.push_back({i, j});
stick_length.push_back(geom::distance(points[i], points[j]));
stick_length.push_back(math::distance(points[i], points[j]));
stick_solid.push_back(solid);
}
@ -89,8 +89,8 @@ struct physics_demo_app
void update() override;
void present() override;
geom::point<float, 2> screen_to_world(geom::point<float, 2> const & p) const;
geom::point<float, 2> world_to_screen(geom::point<float, 2> const & p) const;
math::point<float, 2> screen_to_world(math::point<float, 2> const & p) const;
math::point<float, 2> world_to_screen(math::point<float, 2> const & p) const;
util::clock<std::chrono::duration<float>> frame_clock;
float update_time_left = 0.f;
@ -101,11 +101,11 @@ struct physics_demo_app
gfx::painter painter;
geom::box<float, 2> view_region;
math::box<float, 2> view_region;
std::optional<std::size_t> closest_point;
std::optional<std::size_t> closest_stick;
std::optional<geom::vector<float, 2>> drag_delta;
std::optional<math::vector<float, 2>> drag_delta;
std::optional<std::size_t> new_spring_start;
@ -165,7 +165,7 @@ physics_demo_app::physics_demo_app(options const &, context const &)
for (int i = 0; i < N; ++i)
{
float a = (2.f * geom::pi * i) / N;
float a = (2.f * math::pi * i) / N;
model.points.push_back({std::cos(a) * 0.5f, y + std::sin(a) * 0.5f});
}
@ -193,7 +193,7 @@ physics_demo_app::physics_demo_app(options const &, context const &)
model.add_stick(3, 4);
}
model.vels.assign(model.points.size(), geom::vector<float, 2>::zero());
model.vels.assign(model.points.size(), math::vector<float, 2>::zero());
model.movable.assign(model.points.size(), true);
}
@ -221,8 +221,8 @@ void physics_demo_app::on_event(app::mouse_button_event const & event)
if (event.button == app::mouse_button::left && event.down && closest_point)
{
drag_delta = world_to_screen(model.points[*closest_point]) - geom::cast<float>(state().mouse);
model.vels[*closest_point] = geom::vector<float, 2>::zero();
drag_delta = world_to_screen(model.points[*closest_point]) - math::cast<float>(state().mouse);
model.vels[*closest_point] = math::vector<float, 2>::zero();
}
if (event.button == app::mouse_button::left && !event.down)
@ -239,7 +239,7 @@ void physics_demo_app::on_event(app::mouse_button_event const & event)
else if (closest_point)
{
model.movable[*closest_point] = !model.movable[*closest_point];
model.vels[*closest_point] = geom::vector<float, 2>::zero();
model.vels[*closest_point] = math::vector<float, 2>::zero();
}
}
}
@ -254,14 +254,14 @@ void physics_demo_app::on_event(app::mouse_move_event const & event)
closest_stick = std::nullopt;
{
auto const m = geom::cast<float>(state().mouse);
auto const m = math::cast<float>(state().mouse);
std::size_t closest = 0;
float distance = std::numeric_limits<float>::infinity();
for (std::size_t i = 0; i < model.points.size(); ++i)
{
auto const d = geom::distance(m, world_to_screen(model.points[i]));
auto const d = math::distance(m, world_to_screen(model.points[i]));
if (d < distance)
{
distance = d;
@ -281,7 +281,7 @@ void physics_demo_app::on_event(app::mouse_move_event const & event)
for (std::size_t i = 0; i < model.sticks.size(); ++i)
{
auto const d = geom::distance(m, geom::simplex{world_to_screen(model.points[model.sticks[i][0]]), world_to_screen(model.points[model.sticks[i][1]])});
auto const d = math::distance(m, math::simplex{world_to_screen(model.points[model.sticks[i][0]]), world_to_screen(model.points[model.sticks[i][1]])});
if (d < distance)
{
distance = d;
@ -314,7 +314,7 @@ void physics_demo_app::on_event(app::key_event const & event)
model.vels.erase(model.vels.begin() + *closest_point);
model.movable.erase(model.movable.begin() + *closest_point);
std::vector<geom::segment<std::uint32_t>> new_sticks;
std::vector<math::segment<std::uint32_t>> new_sticks;
std::vector<float> new_stick_length;
std::vector<bool> new_stick_solid;
@ -359,8 +359,8 @@ void physics_demo_app::on_event(app::key_event const & event)
}
else if (new_spring_start)
{
model.points.push_back(screen_to_world(geom::cast<float>(state().mouse)));
model.vels.push_back(geom::vector<float, 2>::zero());
model.points.push_back(screen_to_world(math::cast<float>(state().mouse)));
model.vels.push_back(math::vector<float, 2>::zero());
model.movable.push_back(false);
model.add_stick(*new_spring_start, model.points.size() - 1);
new_spring_start = model.points.size() - 1;
@ -372,15 +372,15 @@ void physics_demo_app::on_event(app::key_event const & event)
}
else
{
model.points.push_back(screen_to_world(geom::cast<float>(state().mouse)));
model.vels.push_back(geom::vector<float, 2>::zero());
model.points.push_back(screen_to_world(math::cast<float>(state().mouse)));
model.vels.push_back(math::vector<float, 2>::zero());
model.movable.push_back(false);
}
}
else if (event.down && event.key == app::keycode::N)
{
model.points.push_back(screen_to_world(geom::cast<float>(state().mouse)));
model.vels.push_back(geom::vector<float, 2>::zero());
model.points.push_back(screen_to_world(math::cast<float>(state().mouse)));
model.vels.push_back(math::vector<float, 2>::zero());
model.movable.push_back(true);
}
else if (event.down && event.key == app::keycode::F)
@ -396,19 +396,19 @@ void physics_demo_app::on_event(app::key_event const & event)
int N = 12;
auto o = screen_to_world(geom::cast<float>(state().mouse));
auto o = screen_to_world(math::cast<float>(state().mouse));
model.points.push_back(o);
model.vels.push_back(geom::vector<float, 2>::zero());
model.vels.push_back(math::vector<float, 2>::zero());
model.movable.push_back(true);
float r = 0.5f;
for (int i = 0; i < N; ++i)
{
float a = (2.f * geom::pi * i) / N;
float a = (2.f * math::pi * i) / N;
model.points.push_back({o[0] + std::cos(a) * r, o[1] + std::sin(a) * r});
model.vels.push_back(geom::vector<float, 2>::zero());
model.vels.push_back(math::vector<float, 2>::zero());
model.movable.push_back(true);
}
@ -422,7 +422,7 @@ void physics_demo_app::on_event(app::key_event const & event)
{
std::uint32_t const base = model.points.size();
auto o = screen_to_world(geom::cast<float>(state().mouse));
auto o = screen_to_world(math::cast<float>(state().mouse));
float w = 0.25f;
@ -431,10 +431,10 @@ void physics_demo_app::on_event(app::key_event const & event)
model.points.push_back({o[0] - w, o[1] + w});
model.points.push_back({o[0] + w, o[1] + w});
model.vels.push_back(geom::vector<float, 2>::zero());
model.vels.push_back(geom::vector<float, 2>::zero());
model.vels.push_back(geom::vector<float, 2>::zero());
model.vels.push_back(geom::vector<float, 2>::zero());
model.vels.push_back(math::vector<float, 2>::zero());
model.vels.push_back(math::vector<float, 2>::zero());
model.vels.push_back(math::vector<float, 2>::zero());
model.vels.push_back(math::vector<float, 2>::zero());
model.movable.push_back(true);
model.movable.push_back(true);
model.movable.push_back(true);
@ -483,7 +483,7 @@ void physics_demo_app::update()
float const stick_friction = 500.f;
float const stick_bounce = 0.9f;
geom::vector<float, 2> const gravity {0.f, -10.f};
math::vector<float, 2> const gravity {0.f, -10.f};
update_time_left += frame_clock.restart().count();
@ -515,10 +515,10 @@ void physics_demo_app::update()
for (std::size_t i = 0; i < model.points.size(); ++i)
{
int x = std::floor(cells.width() * (model.points[i][0] - view_region[0].min) / view_region[0].length());
x = geom::clamp<int>(x, {0, cells.width() - 1});
x = math::clamp<int>(x, {0, cells.width() - 1});
int y = std::floor(cells.height() * (model.points[i][1] - view_region[1].min) / view_region[1].length());
y = geom::clamp<int>(y, {0, cells.height() - 1});
y = math::clamp<int>(y, {0, cells.height() - 1});
float cx = view_region[0].min + dx * x;
float cy = view_region[1].min + dy * y;
@ -579,7 +579,7 @@ void physics_demo_app::update()
if (closest_point && drag_delta)
{
auto target = screen_to_world(geom::cast<float>(state().mouse) + *drag_delta);
auto target = screen_to_world(math::cast<float>(state().mouse) + *drag_delta);
auto & point = model.points[*closest_point];
auto & vel = model.vels[*closest_point];
@ -591,7 +591,7 @@ void physics_demo_app::update()
fixed = closest_point;
}
std::vector<geom::vector<float, 2>> force(model.points.size(), geom::vector<float, 2>::zero());
std::vector<math::vector<float, 2>> force(model.points.size(), math::vector<float, 2>::zero());
for (std::size_t i = 0; i < model.points.size(); ++i)
{
@ -602,7 +602,7 @@ void physics_demo_app::update()
{
auto const & s = model.sticks[i];
auto d = model.points[s[1]] - model.points[s[0]];
auto l = geom::length(d);
auto l = math::length(d);
auto n = d / l;
auto f = - spring_constant * (l - model.stick_length[i]) * n / 2.f;
@ -620,17 +620,17 @@ void physics_demo_app::update()
model.vels[i] += dt * force[i];
}
std::vector<geom::vector<float, 2>> impulse(model.points.size(), geom::vector<float, 2>::zero());
std::vector<geom::vector<float, 2>> offset(model.points.size(), geom::vector<float, 2>::zero());
std::vector<math::vector<float, 2>> impulse(model.points.size(), math::vector<float, 2>::zero());
std::vector<math::vector<float, 2>> offset(model.points.size(), math::vector<float, 2>::zero());
for (std::size_t i = 0; i < model.sticks.size(); ++i)
{
auto const & s = model.sticks[i];
auto rel = model.vels[s[1]] - model.vels[s[0]];
auto n = geom::normalized(model.points[s[1]] - model.points[s[0]]);
auto n = math::normalized(model.points[s[1]] - model.points[s[0]]);
rel = n * geom::dot(rel, n);
rel = n * math::dot(rel, n);
impulse[s[0]] += rel / 2.f * spring_damping_constant * dt;
impulse[s[1]] -= rel / 2.f * spring_damping_constant * dt;
@ -639,7 +639,7 @@ void physics_demo_app::update()
for (std::size_t i = 0; i < model.points.size(); ++i)
{
bool collision = false;
geom::vector<float, 2> n;
math::vector<float, 2> n;
float d;
if (model.points[i][0] < view_region[0].min + ball_radius && model.vels[i][0] < 0.f)
@ -675,7 +675,7 @@ void physics_demo_app::update()
offset[i] += n * d;
(void)d;
auto nv = n * geom::dot(n, model.vels[i]);
auto nv = n * math::dot(n, model.vels[i]);
auto tv = model.vels[i] - nv;
auto jn = - (1.f + ground_bounce) * nv;
@ -684,9 +684,9 @@ void physics_demo_app::update()
unused(ground_mu);
// if (geom::length(jt) > ground_mu * geom::length(jn))
// if (math::length(jt) > ground_mu * math::length(jn))
// {
// jt = geom::normalized(jt) * ground_mu * geom::length(jn);
// jt = math::normalized(jt) * ground_mu * math::length(jn);
// }
impulse[i] += jn + jt;
@ -708,14 +708,14 @@ void physics_demo_app::update()
checked.push_back(j);
auto r = geom::distance(model.points[i], model.points[j]);
auto r = math::distance(model.points[i], model.points[j]);
if (r < ball_radius * 2.f)
{
auto n = (model.points[j] - model.points[i]) / r;
auto rel = model.vels[j] - model.vels[i];
auto d = geom::dot(rel, n);
auto d = math::dot(rel, n);
if (d < 0.f)
{
@ -745,23 +745,23 @@ void physics_demo_app::update()
if (i == s[0] || i == s[1]) continue;
auto d = geom::normalized(model.points[s[1]] - model.points[s[0]]);
auto d = math::normalized(model.points[s[1]] - model.points[s[0]]);
auto t = geom::dot(d, model.points[i] - model.points[s[0]]) / geom::distance(model.points[s[1]], model.points[s[0]]);
auto t = math::dot(d, model.points[i] - model.points[s[0]]) / math::distance(model.points[s[1]], model.points[s[0]]);
if (t < 0.f || t > 1.f) continue;
auto v = geom::lerp(model.vels[s[0]], model.vels[s[1]], t);
auto v = math::lerp(model.vels[s[0]], model.vels[s[1]], t);
auto rel = model.vels[i] - v;
auto n = geom::ort(d);
auto n = math::ort(d);
float r = geom::dot(n, model.points[i] - model.points[s[0]]);
float r = math::dot(n, model.points[i] - model.points[s[0]]);
if (geom::dot(rel, n) * r >= 0.f) continue;
if (math::dot(rel, n) * r >= 0.f) continue;
auto nv = n * geom::dot(rel, n);
auto nv = n * math::dot(rel, n);
auto tv = rel - nv;
unused(stick_friction);
@ -769,10 +769,10 @@ void physics_demo_app::update()
if (std::abs(r) >= ball_radius) continue;
geom::vector<float, 2> off = (r < 0.f ? -1.f : 1.f) * n * (ball_radius - std::abs(r));
math::vector<float, 2> off = (r < 0.f ? -1.f : 1.f) * n * (ball_radius - std::abs(r));
unused(off);
geom::vector<float, 2> imp = - nv * (1.f + stick_bounce) - tv * stick_friction * dt;
math::vector<float, 2> imp = - nv * (1.f + stick_bounce) - tv * stick_friction * dt;
offset[i] += off * 2.f / 3.f;
offset[s[0]] -= off / 3.f * (1.f - t);
@ -816,7 +816,7 @@ void physics_demo_app::present()
if (new_spring_start)
{
painter.line(model.points[*new_spring_start], screen_to_world(geom::cast<float>(state().mouse)), ball_radius / 2.f, gfx::red);
painter.line(model.points[*new_spring_start], screen_to_world(math::cast<float>(state().mouse)), ball_radius / 2.f, gfx::red);
}
if (closest_stick)
@ -834,7 +834,7 @@ void physics_demo_app::present()
painter.circle(model.points[*closest_point], ball_radius, gfx::red);
}
painter.render(geom::orthographic<float, 3>(geom::box<float, 3>{{view_region[0], view_region[1], {-1.f, 1.f}}}).homogeneous_matrix());
painter.render(math::orthographic<float, 3>(math::box<float, 3>{{view_region[0], view_region[1], {-1.f, 1.f}}}).homogeneous_matrix());
text = util::to_string("Balls: ", model.points.size(), "\n", text);
@ -865,17 +865,17 @@ void physics_demo_app::present()
text.clear();
painter.render(geom::window_camera{state().size[0], state().size[1]}.transform());
painter.render(math::window_camera{state().size[0], state().size[1]}.transform());
}
geom::point<float, 2> physics_demo_app::screen_to_world(geom::point<float, 2> const & p) const
math::point<float, 2> physics_demo_app::screen_to_world(math::point<float, 2> const & p) const
{
return geom::orthographic<float, 2>(view_region).inverse()(geom::point{2.f * p[0] / state().size[0] - 1.f, 1.f - 2.f * p[1] / state().size[1]});
return math::orthographic<float, 2>(view_region).inverse()(math::point{2.f * p[0] / state().size[0] - 1.f, 1.f - 2.f * p[1] / state().size[1]});
}
geom::point<float, 2> physics_demo_app::world_to_screen(geom::point<float, 2> const & p) const
math::point<float, 2> physics_demo_app::world_to_screen(math::point<float, 2> const & p) const
{
auto q = geom::orthographic<float, 2>(view_region)(p);
auto q = math::orthographic<float, 2>(view_region)(p);
return {(q[0] + 1.f) / 2.f * state().size[0], (1.f - q[1]) / 2.f * state().size[1]};
}

View file

@ -5,9 +5,9 @@
#include <psemek/gfx/painter.hpp>
#include <psemek/geom/box.hpp>
#include <psemek/geom/camera.hpp>
#include <psemek/geom/rotation.hpp>
#include <psemek/math/box.hpp>
#include <psemek/math/camera.hpp>
#include <psemek/math/rotation.hpp>
#include <psemek/util/clock.hpp>
#include <psemek/util/recursive.hpp>
@ -30,8 +30,8 @@ struct physics_2d_app
{
phys2d::engine physics;
geom::box<float, 2> view_box;
geom::box<float, 2> simulation_box;
math::box<float, 2> view_box;
math::box<float, 2> simulation_box;
gfx::painter painter;
@ -54,11 +54,11 @@ struct physics_2d_app
std::vector<float> radiuses;
std::optional<geom::point<float, 2>> mouse;
std::optional<math::point<float, 2>> mouse;
std::optional<std::size_t> selected_ball;
std::optional<geom::vector<float, 2>> drag_delta;
std::optional<math::vector<float, 2>> drag_delta;
std::size_t motor_id;
@ -104,7 +104,7 @@ struct physics_2d_app
{
for (int x = nx / 2 - ky / 2; x < nx / 2 - ky / 2 + (ky - y); ++x)
{
geom::point<float, 2> pos{simulation_box.corner((x + 0.5f * y + 0.5f) / nx, (y + 0.5f) / ny)};
math::point<float, 2> pos{simulation_box.corner((x + 0.5f * y + 0.5f) / nx, (y + 0.5f) / ny)};
physics.add_object(box_group, box_shape, material, {pos, 0.f}, {{0.f, 0.f}, 0.01f});
}
}
@ -118,19 +118,19 @@ struct physics_2d_app
{
if (chess && (y % 2))
{
geom::point<float, 2> pos{simulation_box.corner((0.25f) / nx, (y + 0.5f) / ny)};
math::point<float, 2> pos{simulation_box.corner((0.25f) / nx, (y + 0.5f) / ny)};
physics.add_object(box_group, small_box_shape, material, {pos, 0.f}, {{0.f, 0.f}, 0.01f});
}
for (int x = 0; x < nx - chess * (y % 2); ++x)
{
geom::point<float, 2> pos{simulation_box.corner((x + 0.5f + chess * 0.5f * (y % 2)) / nx, (y + 0.5f) / ny)};
math::point<float, 2> pos{simulation_box.corner((x + 0.5f + chess * 0.5f * (y % 2)) / nx, (y + 0.5f) / ny)};
physics.add_object(box_group, box_shape, material, {pos, 0.f}, {{0.f, 0.f}, 0.01f});
}
if (chess && (y % 2))
{
geom::point<float, 2> pos{simulation_box.corner((nx - 0.25f) / nx, (y + 0.5f) / ny)};
math::point<float, 2> pos{simulation_box.corner((nx - 0.25f) / nx, (y + 0.5f) / ny)};
physics.add_object(box_group, small_box_shape, material, {pos, 0.f}, {{0.f, 0.f}, 0.01f});
}
}
@ -146,9 +146,9 @@ struct physics_2d_app
if(false)
for (int i = 0; i < 15; ++i)
{
float a = geom::rad(360 * i / 15.f);
float r = ball_radius * 15.f / geom::pi;
geom::point<float, 2> pos{r * std::cos(a), r * std::sin(a)};
float a = math::rad(360 * i / 15.f);
float r = ball_radius * 15.f / math::pi;
math::point<float, 2> pos{r * std::cos(a), r * std::sin(a)};
physics.add_object(ball_group, ball_shape, material, {pos, 0.f}, {});
}
}
@ -169,12 +169,12 @@ struct physics_2d_app
physics.add_object(wall_group, wall_3_shape, wall_material, {}, {});
auto task = util::recursive([this, dx = box_width * 0.4f](auto && self) mutable -> void {
physics.add_object(box_group, box_shape, material, {simulation_box.corner(0.5f, 0.9f) + geom::vector{dx, 0.f}, 0.f}, {});
// physics.add_object(ball_group, ball_shape, material, {simulation_box.corner(0.5f, 0.9f) + geom::vector{dx, 0.f}, 0.f}, {});
physics.add_object(box_group, box_shape, material, {simulation_box.corner(0.5f, 0.9f) + math::vector{dx, 0.f}, 0.f}, {});
// physics.add_object(ball_group, ball_shape, material, {simulation_box.corner(0.5f, 0.9f) + math::vector{dx, 0.f}, 0.f}, {});
// float r = random::uniform_distribution<float>{0.05f, 0.5f}(gen);
// auto new_shape = physics.add_shape(phys2d::ball{r});
// physics.add_object(ball_group, new_shape, material, {simulation_box.corner(0.5f, 0.9f) + geom::vector{dx, 0.f}, 0.f}, {});
// physics.add_object(ball_group, new_shape, material, {simulation_box.corner(0.5f, 0.9f) + math::vector{dx, 0.f}, 0.f}, {});
// radiuses.push_back(r);
dx *= -1.f;
@ -224,7 +224,7 @@ struct physics_2d_app
{
auto const & s = physics.group_static_state(ball_group)[*selected_ball];
auto r = s.position - *mouse;
r = geom::plane_rotation<float, 2>(0, 1, -s.rotation)(r);
r = math::plane_rotation<float, 2>(0, 1, -s.rotation)(r);
drag_delta = r;
}
else if (mouse)
@ -286,13 +286,13 @@ struct physics_2d_app
{
auto r = -*drag_delta;
auto R = geom::plane_rotation<float, 2>(0, 1, s.rotation);
auto R = math::plane_rotation<float, 2>(0, 1, s.rotation);
geom::vector<float, 2> f;
math::vector<float, 2> f;
f[0] = s.position[0] + R(r)[0] - (*mouse)[0];
f[1] = s.position[1] + R(r)[1] - (*mouse)[1];
geom::matrix<float, 2, 3> J;
math::matrix<float, 2, 3> J;
J[0][0] = 1.f;
J[0][1] = 0.f;
J[0][2] = - std::sin(s.rotation) * r[0] + std::cos(s.rotation) * r[1];
@ -300,12 +300,12 @@ struct physics_2d_app
J[1][1] = 1.f;
J[1][2] = std::cos(s.rotation) * r[0] - std::sin(s.rotation) * r[1];
geom::vector<float, 3> v;
math::vector<float, 3> v;
v[0] = d.velocity[0];
v[1] = d.velocity[1];
v[2] = d.angular_velocity;
auto dv = geom::least_squares(J, -(1.f / 8.f) * f / dt - (J * v));
auto dv = math::least_squares(J, -(1.f / 8.f) * f / dt - (J * v));
if (dv)
{
d.velocity[0] += (*dv)[0] * lambda;
@ -323,24 +323,24 @@ struct physics_2d_app
auto & d1 = physics.group_dynamic_state(group)[j];
auto r = s1.position - s0.position;
float l = geom::length(r);
float l = math::length(r);
geom::vector<float, 1> f;
math::vector<float, 1> f;
f[0] = l - target;
geom::matrix<float, 1, 4> J;
math::matrix<float, 1, 4> J;
J[0][0] = -r[0] / l;
J[0][1] = -r[1] / l;
J[0][2] = r[0] / l;
J[0][3] = r[1] / l;
geom::vector<float, 4> v;
math::vector<float, 4> v;
v[0] = d0.velocity[0];
v[1] = d0.velocity[1];
v[2] = d1.velocity[0];
v[3] = d1.velocity[1];
auto dv = geom::least_squares(J, -(1.f / 8.f) * f / dt - (J * v));
auto dv = math::least_squares(J, -(1.f / 8.f) * f / dt - (J * v));
if (dv)
{
d0.velocity[0] += (*dv)[0] * lambda;
@ -413,7 +413,7 @@ struct physics_2d_app
for (std::size_t i = 0; i < physics.group_size(ball_group); ++i)
{
auto p = physics.group_static_state(ball_group)[i].position;
float d = geom::distance(p, *mouse);
float d = math::distance(p, *mouse);
if (d <= std::min(closest, ball_radius))
{
closest = d;
@ -441,8 +441,8 @@ struct physics_2d_app
painter.circle(p, r, gfx::black);
painter.circle(p, r - line_width, gfx::light(gfx::blue, selected ? 0.8f : 1.f).as_color_rgba());
geom::vector const n{std::cos(a), std::sin(a)};
geom::vector const m = geom::ort(n);
math::vector const n{std::cos(a), std::sin(a)};
math::vector const m = math::ort(n);
painter.line(p - n * ball_radius / 2.f, p + n * ball_radius / 2.f, line_width, gfx::black, false);
painter.line(p - m * ball_radius / 2.f, p + m * ball_radius / 2.f, line_width, gfx::black, false);
@ -458,13 +458,13 @@ struct physics_2d_app
float w = std::get<phys2d::box const *>(physics.get_shape(physics.get_object(box_group, i).shape))->width / 2.f;
float h = std::get<phys2d::box const *>(physics.get_shape(physics.get_object(box_group, i).shape))->height / 2.f;
geom::vector<float, 2> q[4];
math::vector<float, 2> q[4];
q[0] = {-w, -h};
q[1] = { w, -h};
q[2] = { w, h};
q[3] = {-w, h};
auto m = geom::plane_rotation<float, 2>(0, 1, a).linear_matrix();
auto m = math::plane_rotation<float, 2>(0, 1, a).linear_matrix();
for (std::size_t j = 0; j < 4; ++j)
q[j] = m * q[j];
@ -483,7 +483,7 @@ struct physics_2d_app
painter.line(simulation_box.corner(1, 1), simulation_box.corner(0, 1), line_width, gfx::black, false);
painter.line(simulation_box.corner(0, 1), simulation_box.corner(0, 0), line_width, gfx::black, false);
painter.render(geom::orthographic_camera{view_box}.transform());
painter.render(math::orthographic_camera{view_box}.transform());
}
};

View file

@ -9,11 +9,11 @@
#include <psemek/cg/body/icosahedron.hpp>
#include <psemek/cg/body/box.hpp>
#include <psemek/geom/camera.hpp>
#include <psemek/geom/mesh.hpp>
#include <psemek/geom/rotation.hpp>
#include <psemek/geom/translation.hpp>
#include <psemek/geom/scale.hpp>
#include <psemek/math/camera.hpp>
#include <psemek/math/mesh.hpp>
#include <psemek/math/rotation.hpp>
#include <psemek/math/translation.hpp>
#include <psemek/math/scale.hpp>
#include <psemek/random/device.hpp>
#include <psemek/random/generator.hpp>
@ -95,12 +95,12 @@ struct physics_3d_app
{
camera_.near_clip = 0.1f;
camera_.far_clip = 1000.f;
camera_.fov_y = geom::rad(90.f);
camera_.fov_y = math::rad(90.f);
camera_.fov_x = camera_.fov_y;
camera_.target = {0.f, 0.f, 0.f};
camera_.distance = 10.f;
camera_.elevation_angle = geom::rad(45.f);
camera_.azimuthal_angle = geom::rad(30.f);
camera_.elevation_angle = math::rad(45.f);
camera_.azimuthal_angle = math::rad(30.f);
camera_distance_tgt_ = camera_.distance;
camera_azimuthal_angle_tgt_ = camera_.azimuthal_angle;
@ -108,12 +108,12 @@ struct physics_3d_app
struct vertex
{
geom::point<float, 3> position;
geom::vector<float, 3> normal;
math::point<float, 3> position;
math::vector<float, 3> normal;
static void setup(gfx::mesh & m)
{
m.setup<geom::point<float, 3>, geom::vector<float, 3>>();
m.setup<math::point<float, 3>, math::vector<float, 3>>();
}
};
@ -136,21 +136,21 @@ struct physics_3d_app
auto const & body_vertices = cg::vertices(body);
auto const & body_triangles = cg::triangles(body);
std::vector<geom::point<float, 3>> positions;
std::vector<math::point<float, 3>> positions;
std::copy(body_vertices.begin(), body_vertices.end(), std::back_inserter(positions));
std::vector<geom::triangle<std::uint32_t>> triangles;
std::vector<math::triangle<std::uint32_t>> triangles;
for (auto const & t : body_triangles)
triangles.push_back({t[0], t[1], t[2]});
for (int iterations = 0; iterations < 2; ++iterations)
{
geom::subdivide(positions, triangles);
math::subdivide(positions, triangles);
for (auto & p : positions)
p = p.zero() + geom::normalized(p - p.zero());
p = p.zero() + math::normalized(p - p.zero());
}
auto normals = geom::smooth_normals(positions, triangles);
auto normals = math::smooth_normals(positions, triangles);
std::vector<vertex> vertices;
@ -167,19 +167,19 @@ struct physics_3d_app
auto const & body_vertices = cg::vertices(body);
auto const & body_triangles = cg::triangles(body);
std::vector<geom::point<float, 3>> positions;
std::vector<math::point<float, 3>> positions;
std::copy(body_vertices.begin(), body_vertices.end(), std::back_inserter(positions));
std::vector<geom::triangle<std::uint32_t>> triangles;
std::vector<math::triangle<std::uint32_t>> triangles;
for (auto const & t : body_triangles)
triangles.push_back({t[0], t[1], t[2]});
auto flat_positions = geom::deindex(positions, triangles);
auto flat_positions = math::deindex(positions, triangles);
std::vector<vertex> vertices;
for (auto const & t : flat_positions)
{
auto n = geom::normal(t[0], t[1], t[2]);
auto n = math::normal(t[0], t[1], t[2]);
vertices.push_back({t[0], n});
vertices.push_back({t[1], n});
vertices.push_back({t[2], n});
@ -286,7 +286,7 @@ struct physics_3d_app
auto w = engine_.get_object_state(h).angular_velocity;
auto H = engine_.get_object_state(h).position[2];
E += 0.5f * geom::length_sqr(v) * m + 0.5f * geom::dot(w, I * w) + m * 10.f * H;
E += 0.5f * math::length_sqr(v) * m + 0.5f * math::dot(w, I * w) + m * 10.f * H;
}
log::info() << "Energy: " << E;
}
@ -307,15 +307,15 @@ struct physics_3d_app
program_.bind();
program_["u_camera_transform"] = camera_.transform();
program_["u_light_direction"] = geom::normalized(geom::vector{1.f, 1.f, 1.f});
program_["u_light_color"] = geom::vector{1.f, 1.f, 1.f};
program_["u_light_direction"] = math::normalized(math::vector{1.f, 1.f, 1.f});
program_["u_light_color"] = math::vector{1.f, 1.f, 1.f};
program_["u_object_transform"] = geom::matrix<float, 4, 4>::identity();
program_["u_object_color"] = geom::vector{0.5f, 0.5f, 0.5f};
program_["u_object_transform"] = math::matrix<float, 4, 4>::identity();
program_["u_object_color"] = math::vector{0.5f, 0.5f, 0.5f};
program_["u_grid"] = 0;
plane_mesh_.draw();
program_["u_object_color"] = geom::vector{0.f, 0.f, 1.f};
program_["u_object_color"] = math::vector{0.f, 0.f, 1.f};
program_["u_grid"] = 1;
for (phys3d::engine::object_handle h = 0; h < engine_.object_count(); ++h)
{
@ -326,17 +326,17 @@ struct physics_3d_app
if (auto s = std::get_if<phys3d::ball const *>(&sh))
{
program_["u_object_transform"] =
geom::translation<float, 3>(engine_.get_object_state(h).position - geom::point<float, 3>::zero()).homogeneous_matrix() *
geom::quaternion_rotation<float>(engine_.get_object_state(h).rotation).homogeneous_matrix() *
geom::scale<float, 3>((*s)->radius).homogeneous_matrix();
math::translation<float, 3>(engine_.get_object_state(h).position - math::point<float, 3>::zero()).homogeneous_matrix() *
math::quaternion_rotation<float>(engine_.get_object_state(h).rotation).homogeneous_matrix() *
math::scale<float, 3>((*s)->radius).homogeneous_matrix();
sphere_mesh_.draw();
}
else if (auto s = std::get_if<phys3d::box const *>(&sh))
{
program_["u_object_transform"] =
geom::translation<float, 3>(engine_.get_object_state(h).position - geom::point<float, 3>::zero()).homogeneous_matrix() *
geom::quaternion_rotation<float>(engine_.get_object_state(h).rotation).homogeneous_matrix() *
geom::scale<float, 3>((*s)->dimensions / 2.f).homogeneous_matrix();
math::translation<float, 3>(engine_.get_object_state(h).position - math::point<float, 3>::zero()).homogeneous_matrix() *
math::quaternion_rotation<float>(engine_.get_object_state(h).rotation).homogeneous_matrix() *
math::scale<float, 3>((*s)->dimensions / 2.f).homogeneous_matrix();
box_mesh_.draw();
}
}
@ -345,7 +345,7 @@ struct physics_3d_app
private:
gfx::program program_;
geom::spherical_camera camera_;
math::spherical_camera camera_;
float camera_distance_tgt_;
float camera_azimuthal_angle_tgt_;
float camera_elevation_angle_tgt_;

View file

@ -2,10 +2,10 @@
#include <psemek/app/default_application_factory.hpp>
#include <psemek/gfx/painter.hpp>
#include <psemek/gfx/gl.hpp>
#include <psemek/geom/scale.hpp>
#include <psemek/geom/camera.hpp>
#include <psemek/geom/constants.hpp>
#include <psemek/geom/intersection.hpp>
#include <psemek/math/scale.hpp>
#include <psemek/math/camera.hpp>
#include <psemek/math/constants.hpp>
#include <psemek/math/intersection.hpp>
#include <psemek/random/generator.hpp>
#include <psemek/random/uniform.hpp>
#include <psemek/util/clock.hpp>
@ -15,30 +15,30 @@ using namespace psemek;
struct map
{
std::vector<geom::box<float, 2>> platforms;
std::vector<math::box<float, 2>> platforms;
};
struct player
{
geom::vector<float, 2> size;
geom::point<float, 2> position;
geom::vector<float, 2> velocity;
math::vector<float, 2> size;
math::point<float, 2> position;
math::vector<float, 2> velocity;
geom::point<float, 2> ghost_position;
geom::vector<float, 2> ghost_velocity;
math::point<float, 2> ghost_position;
math::vector<float, 2> ghost_velocity;
bool grounded = false;
geom::box<float, 2> bbox() const
math::box<float, 2> bbox() const
{
return geom::expand(geom::box<float, 2>::singleton(position), size);
return math::expand(math::box<float, 2>::singleton(position), size);
}
};
struct particle
{
geom::point<float, 2> position;
geom::vector<float, 2> velocity;
math::point<float, 2> position;
math::vector<float, 2> velocity;
float size;
float lifetime;
gfx::color_rgba color;
@ -73,8 +73,8 @@ struct platformer_app
float const friction = 25.f;
float const jump_speed = 15.f;
geom::vector const ghost_spring_force{200.f, 500.f};
geom::vector const ghost_spring_damping{10.f, 20.f};
math::vector const ghost_spring_force{200.f, 500.f};
math::vector const ghost_spring_damping{10.f, 20.f};
float const particle_grow_speed = 0.1f;
float const move_particle_spawn_period = 1.f / 32.f;
@ -89,7 +89,7 @@ struct platformer_app
{
auto v = (player_.position - player_.ghost_position);
player_.ghost_velocity += geom::pointwise_mult(v, ghost_spring_force) * dt;
player_.ghost_velocity += math::pointwise_mult(v, ghost_spring_force) * dt;
player_.ghost_velocity[0] *= std::exp(- ghost_spring_damping[0] * dt);
player_.ghost_velocity[1] *= std::exp(- ghost_spring_damping[1] * dt);
}
@ -142,8 +142,8 @@ struct platformer_app
move_particle_spawn_timer_ -= move_particle_spawn_period;
float s = state().key_down.contains(app::keycode::A) ? 1.f : -1.f;
auto position = player_.position + geom::vector{s * player_.size[0], -player_.size[1]};
auto velocity = geom::direction(random::uniform(rng_, geom::rad(60.f), geom::rad(120.f)));
auto position = player_.position + math::vector{s * player_.size[0], -player_.size[1]};
auto velocity = math::direction(random::uniform(rng_, math::rad(60.f), math::rad(120.f)));
auto size = random::uniform(rng_, 0.05f, 0.15f);
auto lifetime = random::uniform(rng_, 0.25f, 0.5f);
int c = random::uniform(rng_, 63, 191);
@ -161,8 +161,8 @@ struct platformer_app
{
float s = random::uniform(rng_, -1.f, 1.f);
auto position = player_.position + geom::vector{s * player_.size[0], -player_.size[1]};
auto velocity = (random::uniform<bool>(rng_) ? 1.f : -1.f) * geom::direction(random::uniform(rng_, geom::rad(-30.f), geom::rad(30.f))) * 3.f;
auto position = player_.position + math::vector{s * player_.size[0], -player_.size[1]};
auto velocity = (random::uniform<bool>(rng_) ? 1.f : -1.f) * math::direction(random::uniform(rng_, math::rad(-30.f), math::rad(30.f))) * 3.f;
auto size = random::uniform(rng_, 0.05f, 0.15f);
auto lifetime = random::uniform(rng_, 0.25f, 0.5f);
int c = random::uniform(rng_, 63, 191);
@ -178,8 +178,8 @@ struct platformer_app
{
float s = random::uniform(rng_, -1.f, 1.f);
auto position = player_.position + geom::vector{s * player_.size[0], -player_.size[1]};
auto velocity = geom::direction(random::uniform(rng_, geom::rad(0.f), geom::rad(180.f))) * (-velocity_before_collision[1]) * 0.2f;
auto position = player_.position + math::vector{s * player_.size[0], -player_.size[1]};
auto velocity = math::direction(random::uniform(rng_, math::rad(0.f), math::rad(180.f))) * (-velocity_before_collision[1]) * 0.2f;
auto size = random::uniform(rng_, 0.05f, 0.15f);
auto lifetime = random::uniform(rng_, 0.25f, 0.5f);
int c = random::uniform(rng_, 63, 191);
@ -211,10 +211,10 @@ struct platformer_app
painter_.rect(box, {0, 0, 0, 255});
{
geom::point bottom = player_.position - geom::vector{0.f, player_.size[1]};
geom::point top = player_.ghost_position + geom::vector{0.f, player_.size[1]};
math::point bottom = player_.position - math::vector{0.f, player_.size[1]};
math::point top = player_.ghost_position + math::vector{0.f, player_.size[1]};
auto d = geom::vector{player_.size[0], 0.f};
auto d = math::vector{player_.size[0], 0.f};
gfx::color_rgba color{255, 0, 0, 255};
painter_.triangle(bottom - d, bottom + d, top - d, color);
@ -230,9 +230,9 @@ struct platformer_app
float const aspect_ratio = state().size[0] * 1.f / state().size[1];
float const view_size = 5.f;
geom::box<float, 2> view_box{{{-view_size * aspect_ratio, view_size * aspect_ratio}, {-view_size, view_size}}};
math::box<float, 2> view_box{{{-view_size * aspect_ratio, view_size * aspect_ratio}, {-view_size, view_size}}};
painter_.render(geom::orthographic_camera{view_box}.transform());
painter_.render(math::orthographic_camera{view_box}.transform());
}
private:

View file

@ -9,11 +9,11 @@
#include <psemek/gfx/framebuffer.hpp>
#include <psemek/gfx/error.hpp>
#include <psemek/geom/camera.hpp>
#include <psemek/geom/math.hpp>
#include <psemek/geom/mesh.hpp>
#include <psemek/geom/homogeneous.hpp>
#include <psemek/geom/gram_schmidt.hpp>
#include <psemek/math/camera.hpp>
#include <psemek/math/math.hpp>
#include <psemek/math/mesh.hpp>
#include <psemek/math/homogeneous.hpp>
#include <psemek/math/gram_schmidt.hpp>
#include <psemek/util/clock.hpp>
@ -96,16 +96,16 @@ struct phong_renderer
struct light
{
geom::vector<float, 4> position;
math::vector<float, 4> position;
};
struct render_options
{
gfx::framebuffer const * framebuffer;
GLenum draw_buffer;
geom::box<int, 2> viewport;
geom::matrix<float, 4, 4> transform;
geom::point<float, 3> camera_position;
math::box<int, 2> viewport;
math::matrix<float, 4, 4> transform;
math::point<float, 3> camera_position;
struct light light;
};
@ -134,13 +134,13 @@ void phong_renderer::render(render_options const & options)
program_.bind();
program_["u_transform"] = options.transform;
program_["u_light_position"] = options.light.position;
program_["u_camera_position"] = geom::homogeneous(options.camera_position);
program_["u_camera_position"] = math::homogeneous(options.camera_position);
for (auto const & state : render_states_)
{
if (!state.mesh) continue;
program_["u_material"] = geom::vector{state.material.ambient, state.material.diffuse, state.material.specular, state.material.shininess};
program_["u_material"] = math::vector{state.material.ambient, state.material.diffuse, state.material.specular, state.material.shininess};
state.mesh->draw();
}
@ -177,12 +177,12 @@ struct shadow_map_builder
struct render_state
{
gfx::mesh const * mesh;
geom::box<float, 3> bbox;
math::box<float, 3> bbox;
};
struct render_options
{
geom::vector<float, 3> light;
math::vector<float, 3> light;
};
shadow_map_builder(std::size_t width, std::size_t height);
@ -191,7 +191,7 @@ struct shadow_map_builder
void build(render_options const & options);
geom::matrix<float, 4, 4> const & transform() const;
math::matrix<float, 4, 4> const & transform() const;
gfx::texture_2d const & texture() const;
@ -201,7 +201,7 @@ private:
gfx::framebuffer framebuffer_;
gfx::texture_2d depth_texture_;
geom::matrix<float, 4, 4> transform_;
math::matrix<float, 4, 4> transform_;
};
shadow_map_builder::shadow_map_builder(std::size_t width, std::size_t height)
@ -224,7 +224,7 @@ void shadow_map_builder::push(render_state const & state)
void shadow_map_builder::build(render_options const & options)
{
geom::vector<float, 3> light_axes[3];
math::vector<float, 3> light_axes[3];
light_axes[2] = -options.light;
light_axes[1] = {0.f, 0.f, 1.f};
@ -232,24 +232,24 @@ void shadow_map_builder::build(render_options const & options)
if (light_axes[2][2] > 0.5f)
light_axes[1] = {0.f, 1.f, 0.f};
geom::gram_schmidt(light_axes[2], light_axes[1]);
math::gram_schmidt(light_axes[2], light_axes[1]);
light_axes[0] = geom::cross(light_axes[2], light_axes[1]);
light_axes[0] = math::cross(light_axes[2], light_axes[1]);
geom::box<float, 3> light_bbox;
math::box<float, 3> light_bbox;
geom::point<float, 3> origin = geom::point<float, 3>::zero();
math::point<float, 3> origin = math::point<float, 3>::zero();
for (auto const & state : render_states_)
{
for (auto const & v : geom::vertices(state.bbox))
for (auto const & v : math::vertices(state.bbox))
{
for (std::size_t i = 0; i < 3; ++i)
light_bbox[i] |= geom::dot(light_axes[i], v - origin);
light_bbox[i] |= math::dot(light_axes[i], v - origin);
}
}
transform_ = geom::orthographic_camera{light_bbox}.projection() * geom::homogeneous(geom::by_rows(light_axes[0], light_axes[1], light_axes[2]));
transform_ = math::orthographic_camera{light_bbox}.projection() * math::homogeneous(math::by_rows(light_axes[0], light_axes[1], light_axes[2]));
framebuffer_.bind();
gl::DrawBuffer(gl::NONE);
@ -289,7 +289,7 @@ void shadow_map_builder::build(render_options const & options)
*/
}
geom::matrix<float, 4, 4> const & shadow_map_builder::transform() const
math::matrix<float, 4, 4> const & shadow_map_builder::transform() const
{
return transform_;
}
@ -399,21 +399,21 @@ struct shadow_renderer
struct material material;
gfx::mesh const * mesh;
bool casts_shadow;
std::optional<geom::box<float, 3>> bbox;
std::optional<math::box<float, 3>> bbox;
};
struct light
{
geom::vector<float, 4> position;
math::vector<float, 4> position;
};
struct render_options
{
gfx::framebuffer const * framebuffer;
GLenum draw_buffer;
geom::box<int, 2> viewport;
geom::matrix<float, 4, 4> transform;
geom::point<float, 3> camera_position;
math::box<int, 2> viewport;
math::matrix<float, 4, 4> transform;
math::point<float, 3> camera_position;
struct light light;
};
@ -460,7 +460,7 @@ void shadow_renderer::render(render_options const & options)
program_.bind();
program_["u_transform"] = options.transform;
program_["u_light_position"] = options.light.position;
program_["u_camera_position"] = geom::homogeneous(options.camera_position);
program_["u_camera_position"] = math::homogeneous(options.camera_position);
program_["u_shadow_transform"] = builder_.transform();
program_["u_shadow_map"] = 0;
@ -469,7 +469,7 @@ void shadow_renderer::render(render_options const & options)
for (auto const & state : render_states_)
{
program_["u_material"] = geom::vector{state.material.ambient, state.material.diffuse, state.material.specular, state.material.shininess};
program_["u_material"] = math::vector{state.material.ambient, state.material.diffuse, state.material.specular, state.material.shininess};
state.mesh->draw();
}
@ -478,15 +478,15 @@ void shadow_renderer::render(render_options const & options)
struct vertex
{
geom::point<float, 3> position;
geom::vector<float, 3> normal;
math::point<float, 3> position;
math::vector<float, 3> normal;
gfx::color_rgba color;
};
struct shadow_app
: app::application_base
{
geom::spherical_camera camera;
math::spherical_camera camera;
shadow_renderer renderer;
@ -495,15 +495,15 @@ struct shadow_app
gfx::mesh cube_mesh;
shadow_renderer::material cube_material;
geom::box<float, 3> cube_bbox;
math::box<float, 3> cube_bbox;
gfx::mesh sphere_mesh;
shadow_renderer::material sphere_material;
geom::box<float, 3> sphere_bbox;
math::box<float, 3> sphere_bbox;
gfx::mesh torus_mesh;
shadow_renderer::material torus_material;
geom::box<float, 3> torus_bbox;
math::box<float, 3> torus_bbox;
util::clock<std::chrono::duration<float>> clock;
float time = 0.f;
@ -529,10 +529,10 @@ shadow_app::shadow_app(options const &, context const & context)
camera.near_clip = 0.1f;
camera.far_clip = 1000.f;
camera.fov_y = geom::rad(45.f);
camera.fov_y = math::rad(45.f);
camera.azimuthal_angle = 0.f;
camera.elevation_angle = geom::rad(30.f);
camera.elevation_angle = math::rad(30.f);
camera.target = {0.f, 0.f, 0.f};
camera.distance = 10.f;
@ -547,7 +547,7 @@ shadow_app::shadow_app(options const &, context const & context)
vertices.push_back({{ 10.f, -10.f, 0.f}, {0.f, 0.f, 1.f}, {127, 127, 127, 255}});
vertices.push_back({{ 10.f, 10.f, 0.f}, {0.f, 0.f, 1.f}, {127, 127, 127, 255}});
plane_mesh.setup<geom::point<float, 3>, geom::vector<float, 3>, gfx::normalized<gfx::color_rgba>>();
plane_mesh.setup<math::point<float, 3>, math::vector<float, 3>, gfx::normalized<gfx::color_rgba>>();
plane_mesh.load(vertices, gl::TRIANGLES, gl::STATIC_DRAW);
plane_material.ambient = 0.2f;
@ -557,12 +557,12 @@ shadow_app::shadow_app(options const &, context const & context)
}
{
auto cube = geom::box<float, 3>{{{-1.f, 1.f}, {-1.f, 1.f}, {0.f, 5.f}}};
auto cube = math::box<float, 3>{{{-1.f, 1.f}, {-1.f, 1.f}, {0.f, 5.f}}};
auto vertices = geom::vertices(cube);
auto faces = geom::faces(cube);
auto normals = geom::flat_normals(vertices, faces);
auto flat_vertices = geom::deindex(vertices, faces);
auto vertices = math::vertices(cube);
auto faces = math::faces(cube);
auto normals = math::flat_normals(vertices, faces);
auto flat_vertices = math::deindex(vertices, faces);
std::vector<vertex> mesh_vertices;
@ -573,7 +573,7 @@ shadow_app::shadow_app(options const &, context const & context)
mesh_vertices.push_back({flat_vertices[i][2], normals[i], {255, 127, 127, 255}});
}
cube_mesh.setup<geom::point<float, 3>, geom::vector<float, 3>, gfx::normalized<gfx::color_rgba>>();
cube_mesh.setup<math::point<float, 3>, math::vector<float, 3>, gfx::normalized<gfx::color_rgba>>();
cube_mesh.load(mesh_vertices, gl::TRIANGLES, gl::STATIC_DRAW);
cube_material.ambient = 0.2f;
@ -587,7 +587,7 @@ shadow_app::shadow_app(options const &, context const & context)
{
std::vector<vertex> vertices;
geom::point<float, 3> const position = {3.f, 2.f, 3.f};
math::point<float, 3> const position = {3.f, 2.f, 3.f};
float const radius = 1.f;
@ -599,19 +599,19 @@ shadow_app::shadow_app(options const &, context const & context)
{
for (int i = 0; i < 4 * N; ++i)
{
float a = (geom::pi * i) / (2 * N);
float b = (geom::pi * j) / (2 * N);
float a = (math::pi * i) / (2 * N);
float b = (math::pi * j) / (2 * N);
geom::vector n{std::cos(a) * std::cos(b), std::sin(a) * std::cos(b), std::sin(b)};
math::vector n{std::cos(a) * std::cos(b), std::sin(a) * std::cos(b), std::sin(b)};
vertices.push_back({position + radius * n, n, color});
}
}
vertices.push_back({position + geom::vector{0.f, 0.f, -radius}, {0.f, 0.f, -1.f}, color});
vertices.push_back({position + geom::vector{0.f, 0.f, radius}, {0.f, 0.f, 1.f}, color});
vertices.push_back({position + math::vector{0.f, 0.f, -radius}, {0.f, 0.f, -1.f}, color});
vertices.push_back({position + math::vector{0.f, 0.f, radius}, {0.f, 0.f, 1.f}, color});
std::vector<geom::triangle<std::uint32_t>> indices;
std::vector<math::triangle<std::uint32_t>> indices;
auto idx = [](int i, int j) -> std::uint32_t { return (i % (4 * N)) + 4 * N * (j + N - 1); };
@ -634,7 +634,7 @@ shadow_app::shadow_app(options const &, context const & context)
indices.push_back({idx(i, N - 1), idx(i + 1, N - 1), (2 * N - 1) * (4 * N) + 1});
}
sphere_mesh.setup<geom::point<float, 3>, geom::vector<float, 3>, gfx::normalized<gfx::color_rgba>>();
sphere_mesh.setup<math::point<float, 3>, math::vector<float, 3>, gfx::normalized<gfx::color_rgba>>();
sphere_mesh.load(vertices, indices, gl::STATIC_DRAW);
sphere_material.ambient = 0.2f;
@ -650,7 +650,7 @@ shadow_app::shadow_app(options const &, context const & context)
{
std::vector<vertex> vertices;
geom::point<float, 3> const position = {-3.f, 2.f, 3.f};
math::point<float, 3> const position = {-3.f, 2.f, 3.f};
float const radius1 = 1.f;
float const radius2 = 0.2f;
@ -664,18 +664,18 @@ shadow_app::shadow_app(options const &, context const & context)
{
for (int i = 0; i < N; ++i)
{
float a = (2.f * geom::pi * i) / N;
float b = (2.f * geom::pi * j) / M;
float a = (2.f * math::pi * i) / N;
float b = (2.f * math::pi * j) / M;
geom::vector r{std::cos(a), std::sin(a), 0.f};
math::vector r{std::cos(a), std::sin(a), 0.f};
geom::vector n{std::cos(a) * std::cos(b), std::sin(a) * std::cos(b), std::sin(b)};
math::vector n{std::cos(a) * std::cos(b), std::sin(a) * std::cos(b), std::sin(b)};
vertices.push_back({position + radius1 * r + radius2 * n, n, color});
}
}
std::vector<geom::triangle<std::uint32_t>> indices;
std::vector<math::triangle<std::uint32_t>> indices;
auto idx = [](int i, int j) -> std::uint32_t { return (i % N) + N * (j % M); };
@ -688,7 +688,7 @@ shadow_app::shadow_app(options const &, context const & context)
}
}
torus_mesh.setup<geom::point<float, 3>, geom::vector<float, 3>, gfx::normalized<gfx::color_rgba>>();
torus_mesh.setup<math::point<float, 3>, math::vector<float, 3>, gfx::normalized<gfx::color_rgba>>();
torus_mesh.load(vertices, indices, gl::STATIC_DRAW);
torus_material.ambient = 0.2f;
@ -745,7 +745,7 @@ void shadow_app::present()
else
clock.restart();
geom::vector<float, 3> light_dir = {std::cos(time), std::sin(time), 0.5f};
math::vector<float, 3> light_dir = {std::cos(time), std::sin(time), 0.5f};
gfx::framebuffer::null().bind();
gl::DrawBuffer(gl::BACK);
@ -768,7 +768,7 @@ void shadow_app::present()
options.viewport = {{{0, state().size[0]}, {0, state().size[1]}}};
options.draw_buffer = gl::BACK;
options.transform = camera.transform();
options.light.position = geom::homogeneous(light_dir);
options.light.position = math::homogeneous(light_dir);
options.camera_position = camera.position();
renderer.render(options);

View file

@ -2,10 +2,10 @@
#include <psemek/app/default_application_factory.hpp>
#include <psemek/phys/engine_2d.hpp>
#include <psemek/gfx/painter.hpp>
#include <psemek/geom/simplex.hpp>
#include <psemek/geom/math.hpp>
#include <psemek/geom/camera.hpp>
#include <psemek/geom/scale.hpp>
#include <psemek/math/simplex.hpp>
#include <psemek/math/math.hpp>
#include <psemek/math/camera.hpp>
#include <psemek/math/scale.hpp>
#include <psemek/util/hash_table.hpp>
#include <psemek/util/clock.hpp>
#include <psemek/random/generator.hpp>
@ -28,8 +28,8 @@ static float const hills_friction = 100.f;
static float const spring_damping = 10.f;
static float const max_spring_force = 25000.f;
static geom::interval<float> const cell_size_range{1.f, 1.f};
static geom::interval<float> const cell_period_range{0.25f, 4.f};
static math::interval<float> const cell_size_range{1.f, 1.f};
static math::interval<float> const cell_period_range{0.25f, 4.f};
static float const muscle_expand_extent = 0.5f;
static int const population_size = 4 * 1024;
@ -70,7 +70,7 @@ float spring_force(cell_type type)
return 0.f;
}
static geom::vector<int, 2> const neighbours[4] =
static math::vector<int, 2> const neighbours[4] =
{
{-1, 0},
{ 1, 0},
@ -80,12 +80,12 @@ static geom::vector<int, 2> const neighbours[4] =
struct map
{
geom::vector<float, 2> ground_normal{0.f, 1.f};
math::vector<float, 2> ground_normal{0.f, 1.f};
std::vector<geom::point<float, 2>> ground_points;
std::vector<math::point<float, 2>> ground_points;
};
using creature_blueprint = std::unordered_map<geom::point<int, 2>, cell_info>;
using creature_blueprint = std::unordered_map<math::point<int, 2>, cell_info>;
struct creature
{
@ -99,16 +99,16 @@ struct creature
int generation = 0;
std::optional<float> score = std::nullopt;
std::vector<geom::point<float, 2>> positions;
std::vector<geom::vector<float, 2>> velocities;
std::vector<math::point<float, 2>> positions;
std::vector<math::vector<float, 2>> velocities;
std::vector<cell> cells;
std::vector<geom::segment<std::uint32_t>> outer_edges;
std::vector<math::segment<std::uint32_t>> outer_edges;
geom::point<float, 2> center() const;
geom::vector<float, 2> center_velocity() const;
void translate(geom::vector<float, 2> const & delta);
void push(geom::vector<float, 2> const & delta_velocity);
math::point<float, 2> center() const;
math::vector<float, 2> center_velocity() const;
void translate(math::vector<float, 2> const & delta);
void push(math::vector<float, 2> const & delta_velocity);
bool dead() const;
@ -118,9 +118,9 @@ struct creature
void compute_outer_edges();
};
geom::point<float, 2> creature::center() const
math::point<float, 2> creature::center() const
{
geom::vector<float, 2> sum{0.f, 0.f};
math::vector<float, 2> sum{0.f, 0.f};
for (int i = 1; i < positions.size(); ++i)
{
sum += positions[i] - positions[0];
@ -128,9 +128,9 @@ geom::point<float, 2> creature::center() const
return positions[0] + sum / (1.f * positions.size());
}
geom::vector<float, 2> creature::center_velocity() const
math::vector<float, 2> creature::center_velocity() const
{
geom::vector<float, 2> sum{0.f, 0.f};
math::vector<float, 2> sum{0.f, 0.f};
for (int i = 1; i < velocities.size(); ++i)
{
sum += velocities[i];
@ -138,13 +138,13 @@ geom::vector<float, 2> creature::center_velocity() const
return sum / (1.f * velocities.size());
}
void creature::translate(geom::vector<float, 2> const & delta)
void creature::translate(math::vector<float, 2> const & delta)
{
for (auto & pos : positions)
pos += delta;
}
void creature::push(geom::vector<float, 2> const & delta_velocity)
void creature::push(math::vector<float, 2> const & delta_velocity)
{
for (auto & vel : velocities)
vel += delta_velocity;
@ -165,14 +165,14 @@ void creature::update(float dt)
for (auto & vel : velocities)
{
auto v = geom::length(vel);
auto v = math::length(vel);
vel -= air_friction * v * vel * dt;
}
for (int i = 0; i < positions.size(); ++i)
positions[i] += velocities[i] * dt;
static geom::vector<float, 2> const deltas[4]
static math::vector<float, 2> const deltas[4]
{
{-0.5f, -0.5f},
{ 0.5f, -0.5f},
@ -189,13 +189,13 @@ void creature::update(float dt)
cell.info.phase += dt / cell.info.period;
while (cell.info.phase >= 1.f)
cell.info.phase -= 1.f;
size *= 1.f + muscle_expand_extent * std::sin(cell.info.phase * 2.f * geom::pi);
size *= 1.f + muscle_expand_extent * std::sin(cell.info.phase * 2.f * math::pi);
}
geom::point<float, 2> center{0.f, 0.f};
math::point<float, 2> center{0.f, 0.f};
for (auto idx : cell.indices)
{
center += (positions[idx] - geom::point{0.f, 0.f}) * 0.25f;
center += (positions[idx] - math::point{0.f, 0.f}) * 0.25f;
}
float A = 0.f;
@ -206,33 +206,33 @@ void creature::update(float dt)
auto const p = positions[cell.indices[i]] - center;
auto const q = deltas[i] * size;
A += geom::dot(p, q);
B += geom::det(p, q);
A += math::dot(p, q);
B += math::det(p, q);
}
float const angle = - std::atan2(B, A);
for (int i = 0; i < 4; ++i)
{
auto const target = center + geom::rotate(deltas[i] * size, angle);
auto const target = center + math::rotate(deltas[i] * size, angle);
auto force = spring_force(cell.info.type) * (target - positions[cell.indices[i]]);
if (auto f = geom::length(force); f > max_spring_force)
if (auto f = math::length(force); f > max_spring_force)
cell.info.type = cell_type::dead;
velocities[cell.indices[i]] += force * dt;
}
auto cmvel = geom::vector{0.f, 0.f};
auto cmvel = math::vector{0.f, 0.f};
auto rotation = 0.f;
for (auto idx : cell.indices)
{
cmvel += velocities[idx] * 0.25f;
rotation += geom::det(positions[idx] - center, velocities[idx]) * (0.25f / geom::length_sqr(positions[idx] - center));
rotation += math::det(positions[idx] - center, velocities[idx]) * (0.25f / math::length_sqr(positions[idx] - center));
}
for (auto idx : cell.indices)
{
auto target_vel = cmvel + geom::ort(positions[idx] - center) * rotation;
auto target_vel = cmvel + math::ort(positions[idx] - center) * rotation;
velocities[idx] += (target_vel - velocities[idx]) * (1.f - std::exp(- spring_damping * dt));
}
@ -243,15 +243,15 @@ void creature::collide(map const & map, float dt)
{
for (int i = 0; i < positions.size(); ++i)
{
auto delta = positions[i] - geom::point<float, 2>{0.f, 0.f};
auto dist = geom::dot(delta, map.ground_normal);
auto delta = positions[i] - math::point<float, 2>{0.f, 0.f};
auto dist = math::dot(delta, map.ground_normal);
if (dist < 0.f)
{
positions[i] -= dist * map.ground_normal;
auto tangent = geom::ort(map.ground_normal);
auto vn = geom::dot(velocities[i], map.ground_normal);
auto vt = geom::dot(velocities[i], tangent);
auto tangent = math::ort(map.ground_normal);
auto vn = math::dot(velocities[i], map.ground_normal);
auto vt = math::dot(velocities[i], tangent);
vn = std::max(0.f, vn);
vt *= std::exp(- dt * ground_friction);
@ -264,16 +264,16 @@ void creature::collide(map const & map, float dt)
{
auto j = (it - map.ground_points.begin()) - 1;
auto n = geom::normalized(geom::ort(map.ground_points[j + 1] - map.ground_points[j]));
float dist = geom::dot(positions[i] - map.ground_points[j], n);
auto n = math::normalized(math::ort(map.ground_points[j + 1] - map.ground_points[j]));
float dist = math::dot(positions[i] - map.ground_points[j], n);
if (dist < 0.f)
{
positions[i] -= dist * n;
auto tangent = geom::ort(n);
auto vn = geom::dot(velocities[i], n);
auto vt = geom::dot(velocities[i], tangent);
auto tangent = math::ort(n);
auto vn = math::dot(velocities[i], n);
auto vt = math::dot(velocities[i], tangent);
vn = std::max(0.f, vn);
vt *= std::exp(- dt * hills_friction);
@ -286,13 +286,13 @@ void creature::collide(map const & map, float dt)
void creature::compute_outer_edges()
{
util::hash_set<geom::segment<std::uint32_t>> edge_set;
util::hash_set<math::segment<std::uint32_t>> edge_set;
for (auto const & cell : cells)
{
for (int i = 0; i < 4; ++i)
{
geom::segment<std::uint32_t> segment;
math::segment<std::uint32_t> segment;
segment[0] = cell.indices[i];
segment[1] = cell.indices[(i + 1) % 4];
edge_set.insert(segment);
@ -330,14 +330,14 @@ void draw(gfx::painter & painter, creature const & creature)
{
for (auto const & cell : creature.cells)
{
geom::point<float, 2> center{0.f, 0.f};
math::point<float, 2> center{0.f, 0.f};
for (auto idx : cell.indices)
center += 0.25f * (creature.positions[idx] - geom::point{0.f, 0.f});
center += 0.25f * (creature.positions[idx] - math::point{0.f, 0.f});
gfx::color_rgba const color = cell_color(cell.info.type);
gfx::color_rgba const bgcolor = gfx::dark(color, 0.25f);
geom::point<float, 2> ps[4];
math::point<float, 2> ps[4];
for (int i = 0; i < 4; ++i)
ps[i] = creature.positions[cell.indices[i]];
@ -345,7 +345,7 @@ void draw(gfx::painter & painter, creature const & creature)
painter.triangle(ps[2], ps[0], ps[3], bgcolor);
for (int i = 0; i < 4; ++i)
ps[i] = geom::lerp(ps[i], center, 0.25f);
ps[i] = math::lerp(ps[i], center, 0.25f);
painter.triangle(ps[0], ps[1], ps[2], color);
painter.triangle(ps[2], ps[0], ps[3], color);
@ -367,19 +367,19 @@ struct creature_builder
: blueprint_(std::move(blueprint))
{}
void add(geom::point<int, 2> const position, cell_info const & info)
void add(math::point<int, 2> const position, cell_info const & info)
{
blueprint_[position] = info;
}
bool contains(geom::point<int, 2> const & position) const
bool contains(math::point<int, 2> const & position) const
{
return blueprint_.contains(position);
}
creature build(int generation)
{
static geom::vector<int, 2> const vertex_delta[4]
static math::vector<int, 2> const vertex_delta[4]
{
{0, 0},
{1, 0},
@ -390,7 +390,7 @@ struct creature_builder
creature result;
result.generation = generation;
util::hash_map<geom::point<int, 2>, std::uint32_t> vertex_id;
util::hash_map<math::point<int, 2>, std::uint32_t> vertex_id;
for (auto const & cell : blueprint_)
{
@ -398,7 +398,7 @@ struct creature_builder
cell_out.info = cell.second;
for (int i = 0; i < 4; ++i)
{
geom::point<int, 2> vertex = cell.first + vertex_delta[i];
math::point<int, 2> vertex = cell.first + vertex_delta[i];
if (auto it = vertex_id.find(vertex); it != vertex_id.end())
{
cell_out.indices[i] = it->second;
@ -406,8 +406,8 @@ struct creature_builder
else
{
cell_out.indices[i] = (vertex_id[vertex] = result.positions.size());
result.positions.push_back(geom::cast<float>(vertex));
result.velocities.push_back(geom::vector<float, 2>::zero());
result.positions.push_back(math::cast<float>(vertex));
result.velocities.push_back(math::vector<float, 2>::zero());
}
}
}
@ -422,9 +422,9 @@ struct creature_builder
if (blueprint_.empty())
return false;
util::hash_set<geom::point<int, 2>> visited;
util::hash_set<math::point<int, 2>> visited;
std::deque<geom::point<int, 2>> queue;
std::deque<math::point<int, 2>> queue;
queue.push_back(blueprint_.begin()->first);
visited.insert(queue.back());
@ -480,7 +480,7 @@ struct soft_creatures_2d_app
// map_.ground_points.push_back({5.f, 0.f});
// for (int x = 10; x <= 200; x += 1)
// map_.ground_points.push_back({x / 2.f, random::uniform(rng, 0.f, std::min(x, 200) / 200.f * 4.f)});
// map_.ground_points.push_back({x, std::min(2.f, geom::sqr(x - 10) * 0.25f)});
// map_.ground_points.push_back({x, std::min(2.f, math::sqr(x - 10) * 0.25f)});
// map_.ground_points.push_back({x, random::uniform(rng, 0.f, 4.f)});
for (int species = 0; species < population_size; ++species)
@ -560,7 +560,7 @@ struct soft_creatures_2d_app
float max_view_x = 0.f;
for (int c = 0; c < display_creatures_.size(); ++c)
for (auto const & p : display_creatures_[c].positions)
geom::make_max(max_view_x, p[0]);
math::make_max(max_view_x, p[0]);
max_view_x = std::max(max_view_x + 10.f, max_view_x_);
max_view_x_ += (max_view_x - max_view_x_) * (1.f - std::exp(- 4.f * frame_dt));
@ -574,14 +574,14 @@ struct soft_creatures_2d_app
for (int c = 0; c < display_creatures_.size(); ++c)
{
float aspect_ratio = state().size[0] * 1.f / state().size[1] * display_creatures_.size();
geom::box<float, 2> view_box = {{{0.f, 0.f}, {0.f, 0.f}}};
math::box<float, 2> view_box = {{{0.f, 0.f}, {0.f, 0.f}}};
view_box[0] = {max_view_x_ - display_width, max_view_x_};
view_box[1] = {0.f, view_box[0].length() / aspect_ratio};
view_box[1] -= 2.f;
geom::box<float, 2> ground_box;
ground_box[0] = geom::interval<float>::full();
ground_box[1] = {geom::limits<float>::min(), 0.f};
math::box<float, 2> ground_box;
ground_box[0] = math::interval<float>::full();
ground_box[1] = {math::limits<float>::min(), 0.f};
ground_box = ground_box & view_box;
gfx::color_rgba ground_color{127, 91, 65, 255};
painter_.rect(ground_box, ground_color);
@ -611,7 +611,7 @@ struct soft_creatures_2d_app
float scale = 2.f * view_box[0].length() / state().size[0];
painter_.line({x, 0.f}, {x, y}, 0.125f, {255, 255, 255, 255}, false);
painter_.text3d({x + 0.1f, -0.5f, 0.f}, util::to_string(r * 5), {.scale = scale, .x = gfx::painter::x_align::left, .c = {255, 255, 255, 127}}, geom::scale<float, 3>({1.f, -1.f, 1.f}).linear_matrix());
painter_.text3d({x + 0.1f, -0.5f, 0.f}, util::to_string(r * 5), {.scale = scale, .x = gfx::painter::x_align::left, .c = {255, 255, 255, 127}}, math::scale<float, 3>({1.f, -1.f, 1.f}).linear_matrix());
}
draw(painter_, display_creatures_[c]);
@ -619,7 +619,7 @@ struct soft_creatures_2d_app
float height = view_box[1].length();
view_box[1].max += c * height;
view_box[1].min = view_box[1].max - display_creatures_.size() * height;
painter_.render(geom::orthographic_camera(view_box).transform());
painter_.render(math::orthographic_camera(view_box).transform());
}
int text_row = 0;
@ -672,7 +672,7 @@ struct soft_creatures_2d_app
painter_.line({0.f, y}, {state().size[0], y}, 4.f, {0, 0, 0, 255}, false);
}
painter_.render(geom::window_camera(state().size[0], state().size[1]).transform());
painter_.render(math::window_camera(state().size[0], state().size[1]).transform());
}
private:
@ -726,12 +726,12 @@ private:
auto center = creature.center();
float radius = -std::numeric_limits<float>::infinity();
for (auto const & pos : creature.positions)
geom::make_max(radius, geom::distance(pos, center));
math::make_max(radius, math::distance(pos, center));
float angle = 0.f;
for (auto & pos : creature.positions)
pos = geom::vector{0.f, radius} + center + geom::rotate(pos - center, angle);
pos = math::vector{0.f, radius} + center + math::rotate(pos - center, angle);
}
}
}
@ -767,13 +767,13 @@ private:
auto center = sim_creature.center();
float radius = -std::numeric_limits<float>::infinity();
for (auto const & pos : sim_creature.positions)
geom::make_max(radius, geom::distance(pos, center));
math::make_max(radius, math::distance(pos, center));
auto angle = random::uniform<float>(rng, -1.f, 1.f) * geom::rad(30.f);
auto angle = random::uniform<float>(rng, -1.f, 1.f) * math::rad(30.f);
angle = 0.f;
for (auto & pos : sim_creature.positions)
pos = geom::vector{0.f, radius} + center + geom::rotate(pos - center, angle);
pos = math::vector{0.f, radius} + center + math::rotate(pos - center, angle);
auto start_pos = sim_creature.center();
float max_y = start_pos[1];
@ -784,7 +784,7 @@ private:
{
sim_creature.update(sim_dt);
sim_creature.collide(map_, sim_dt);
geom::make_max(max_y, sim_creature.center()[1]);
math::make_max(max_y, sim_creature.center()[1]);
auto speed = sim_creature.center_velocity();
sum_speed_x += speed[0];
@ -868,7 +868,7 @@ private:
blueprint[cell.first] = cell.second;
}
std::vector<geom::point<int, 2>> erase_cells;
std::vector<math::point<int, 2>> erase_cells;
for (auto const & cell : blueprint)
{
if (random::uniform<float>(rng) < erase_probability)
@ -878,7 +878,7 @@ private:
for (auto cell : erase_cells)
blueprint.erase(cell);
std::vector<std::pair<geom::point<int, 2>, cell_info>> grow_cells;
std::vector<std::pair<math::point<int, 2>, cell_info>> grow_cells;
for (auto const & cell : blueprint)
{
for (auto n : neighbours)
@ -921,9 +921,9 @@ private:
cell.info.phase += randn(rng) * 0.1f * mutation_boost;
cell.info.period += randn(rng) * 0.1f * mutation_boost;
cell.info.size = geom::clamp(cell.info.size, cell_size_range);
cell.info.size = math::clamp(cell.info.size, cell_size_range);
cell.info.phase = std::fmod(cell.info.phase, 1.f);
cell.info.period = geom::clamp(cell.info.period, cell_period_range);
cell.info.period = math::clamp(cell.info.period, cell_period_range);
new_creature.score = std::nullopt;
new_creature.generation = generation;

View file

@ -2,11 +2,11 @@
#include <psemek/app/default_application_factory.hpp>
#include <psemek/phys/engine_2d.hpp>
#include <psemek/gfx/painter.hpp>
#include <psemek/geom/simplex.hpp>
#include <psemek/geom/math.hpp>
#include <psemek/geom/camera.hpp>
#include <psemek/geom/scale.hpp>
#include <psemek/geom/quaternion.hpp>
#include <psemek/math/simplex.hpp>
#include <psemek/math/math.hpp>
#include <psemek/math/camera.hpp>
#include <psemek/math/scale.hpp>
#include <psemek/math/quaternion.hpp>
#include <psemek/util/hash_table.hpp>
#include <psemek/util/clock.hpp>
#include <psemek/util/overload.hpp>
@ -106,7 +106,7 @@ gfx::color_rgba cell_color(cell_data type)
), type);
}
static geom::vector<int, 2> const neighbours[4] =
static math::vector<int, 2> const neighbours[4] =
{
{-1, 0},
{ 1, 0},
@ -118,23 +118,23 @@ struct map
{
struct wall
{
geom::point<float, 2> origin;
geom::vector<float, 2> normal;
math::point<float, 2> origin;
math::vector<float, 2> normal;
bool contains(geom::point<float, 2> const & p) const
bool contains(math::point<float, 2> const & p) const
{
return geom::dot(p - origin, normal) <= 0.f;
return math::dot(p - origin, normal) <= 0.f;
}
};
std::vector<wall> walls;
std::vector<geom::point<float, 2>> ground_points;
std::vector<math::point<float, 2>> ground_points;
std::optional<float> radius;
};
using cell_map = std::unordered_map<geom::point<int, 2>, cell_data>;
using cell_map = std::unordered_map<math::point<int, 2>, cell_data>;
struct genome
{
@ -154,21 +154,21 @@ struct creature
struct genome genome;
int generation = 0;
std::vector<geom::point<float, 2>> positions;
std::vector<geom::vector<float, 2>> velocities;
std::vector<math::point<float, 2>> positions;
std::vector<math::vector<float, 2>> velocities;
std::vector<bool> collided;
std::vector<std::optional<geom::point<float, 2>>> fixed;
std::vector<std::optional<math::point<float, 2>>> fixed;
std::vector<cell> cells;
float energy = 0.f;
std::vector<geom::segment<std::uint32_t>> outer_edges;
std::vector<math::segment<std::uint32_t>> outer_edges;
geom::point<float, 2> center() const;
geom::point<float, 2> cell_center(cell const & cell) const;
geom::vector<float, 2> center_velocity() const;
void translate(geom::vector<float, 2> const & delta);
void push(geom::vector<float, 2> const & delta_velocity);
math::point<float, 2> center() const;
math::point<float, 2> cell_center(cell const & cell) const;
math::vector<float, 2> center_velocity() const;
void translate(math::vector<float, 2> const & delta);
void push(math::vector<float, 2> const & delta_velocity);
bool dead() const;
@ -179,9 +179,9 @@ struct creature
void finalize_creation();
};
geom::point<float, 2> creature::center() const
math::point<float, 2> creature::center() const
{
geom::vector<float, 2> sum{0.f, 0.f};
math::vector<float, 2> sum{0.f, 0.f};
for (int i = 1; i < positions.size(); ++i)
{
sum += positions[i] - positions[0];
@ -189,17 +189,17 @@ geom::point<float, 2> creature::center() const
return positions[0] + sum / (1.f * positions.size());
}
geom::point<float, 2> creature::cell_center(cell const & cell) const
math::point<float, 2> creature::cell_center(cell const & cell) const
{
geom::point<float, 2> center{0.f, 0.f};
math::point<float, 2> center{0.f, 0.f};
for (auto idx : cell.indices)
center += (positions[idx] - geom::point{0.f, 0.f}) * 0.25f;
center += (positions[idx] - math::point{0.f, 0.f}) * 0.25f;
return center;
}
geom::vector<float, 2> creature::center_velocity() const
math::vector<float, 2> creature::center_velocity() const
{
geom::vector<float, 2> sum{0.f, 0.f};
math::vector<float, 2> sum{0.f, 0.f};
for (int i = 1; i < velocities.size(); ++i)
{
sum += velocities[i];
@ -207,13 +207,13 @@ geom::vector<float, 2> creature::center_velocity() const
return sum / (1.f * velocities.size());
}
void creature::translate(geom::vector<float, 2> const & delta)
void creature::translate(math::vector<float, 2> const & delta)
{
for (auto & pos : positions)
pos += delta;
}
void creature::push(geom::vector<float, 2> const & delta_velocity)
void creature::push(math::vector<float, 2> const & delta_velocity)
{
for (auto & vel : velocities)
vel += delta_velocity;
@ -228,7 +228,7 @@ std::vector<creature> creature::update(float dt, random::generator & rng)
{
for (int i = 0; i < velocities.size(); ++i)
{
// velocities[i] -= gravity * dt * geom::normalized(positions[i] - geom::point{0.f, 0.f});
// velocities[i] -= gravity * dt * math::normalized(positions[i] - math::point{0.f, 0.f});
velocities[i][1] -= gravity * dt;
if (fixed[i])
velocities[i] += (*fixed[i] - positions[i]) * fixed_root_force * dt;
@ -236,7 +236,7 @@ std::vector<creature> creature::update(float dt, random::generator & rng)
for (auto & vel : velocities)
{
// auto v = geom::length(vel);
// auto v = math::length(vel);
// vel -= air_friction * v * vel * dt;
vel *= std::exp(- air_friction * dt);
}
@ -244,7 +244,7 @@ std::vector<creature> creature::update(float dt, random::generator & rng)
for (int i = 0; i < positions.size(); ++i)
positions[i] += velocities[i] * dt;
static geom::vector<float, 2> const deltas[4]
static math::vector<float, 2> const deltas[4]
{
{-0.5f, -0.5f},
{ 0.5f, -0.5f},
@ -329,33 +329,33 @@ std::vector<creature> creature::update(float dt, random::generator & rng)
auto const p = positions[cell.indices[i]] - center;
auto const q = deltas[i] * size;
A += geom::dot(p, q);
B += geom::det(p, q);
A += math::dot(p, q);
B += math::det(p, q);
}
float const angle = - std::atan2(B, A);
for (int i = 0; i < 4; ++i)
{
auto const target = center + geom::rotate(deltas[i] * size, angle);
auto const target = center + math::rotate(deltas[i] * size, angle);
auto force = spring_force(cell.data) * (target - positions[cell.indices[i]]);
// if (auto f = geom::length(force); f > max_spring_force)
// if (auto f = math::length(force); f > max_spring_force)
// ;
velocities[cell.indices[i]] += force * dt;
}
auto cmvel = geom::vector{0.f, 0.f};
auto cmvel = math::vector{0.f, 0.f};
auto rotation = 0.f;
for (auto idx : cell.indices)
{
cmvel += velocities[idx] * 0.25f;
rotation += geom::det(positions[idx] - center, velocities[idx]) * (0.25f / geom::length_sqr(positions[idx] - center));
rotation += math::det(positions[idx] - center, velocities[idx]) * (0.25f / math::length_sqr(positions[idx] - center));
}
for (auto idx : cell.indices)
{
auto target_vel = cmvel + geom::ort(positions[idx] - center) * rotation;
auto target_vel = cmvel + math::ort(positions[idx] - center) * rotation;
velocities[idx] += (target_vel - velocities[idx]) * (1.f - std::exp(- spring_damping * dt));
}
@ -372,8 +372,8 @@ void creature::collide(map const & map, float dt)
{
if (map.radius)
{
auto delta = positions[i] - geom::point{0.f, 0.f};
auto dist = geom::length(delta);
auto delta = positions[i] - math::point{0.f, 0.f};
auto dist = math::length(delta);
auto normal = delta / dist;
dist -= *map.radius;
@ -381,9 +381,9 @@ void creature::collide(map const & map, float dt)
{
positions[i] -= dist * normal;
auto tangent = geom::ort(normal);
auto vn = geom::dot(velocities[i], normal);
auto vt = geom::dot(velocities[i], tangent);
auto tangent = math::ort(normal);
auto vn = math::dot(velocities[i], normal);
auto vt = math::dot(velocities[i], tangent);
vn = std::max(0.f, vn);
vt *= std::exp(- dt * ground_friction);
@ -397,14 +397,14 @@ void creature::collide(map const & map, float dt)
for (auto const & wall : map.walls)
{
auto delta = positions[i] - wall.origin;
auto dist = geom::dot(delta, wall.normal);
auto dist = math::dot(delta, wall.normal);
if (dist < 0.f)
{
positions[i] -= dist * wall.normal;
auto tangent = geom::ort(wall.normal);
auto vn = geom::dot(velocities[i], wall.normal);
auto vt = geom::dot(velocities[i], tangent);
auto tangent = math::ort(wall.normal);
auto vn = math::dot(velocities[i], wall.normal);
auto vt = math::dot(velocities[i], tangent);
vn = std::max(0.f, vn);
vt *= std::exp(- dt * ground_friction);
@ -420,16 +420,16 @@ void creature::collide(map const & map, float dt)
{
auto j = (it - map.ground_points.begin()) - 1;
auto n = geom::normalized(geom::ort(map.ground_points[j + 1] - map.ground_points[j]));
float dist = geom::dot(positions[i] - map.ground_points[j], n);
auto n = math::normalized(math::ort(map.ground_points[j + 1] - map.ground_points[j]));
float dist = math::dot(positions[i] - map.ground_points[j], n);
if (dist < 0.f)
{
positions[i] -= dist * n;
auto tangent = geom::ort(n);
auto vn = geom::dot(velocities[i], n);
auto vt = geom::dot(velocities[i], tangent);
auto tangent = math::ort(n);
auto vn = math::dot(velocities[i], n);
auto vt = math::dot(velocities[i], tangent);
vn = std::max(0.f, vn);
vt *= std::exp(- dt * hills_friction);
@ -459,13 +459,13 @@ void creature::finalize_creation()
collided.assign(positions.size(), false);
fixed.assign(positions.size(), std::nullopt);
util::hash_set<geom::segment<std::uint32_t>> edge_set;
util::hash_set<math::segment<std::uint32_t>> edge_set;
for (auto const & cell : cells)
{
for (int i = 0; i < 4; ++i)
{
geom::segment<std::uint32_t> segment;
math::segment<std::uint32_t> segment;
segment[0] = cell.indices[i];
segment[1] = cell.indices[(i + 1) % 4];
edge_set.insert(segment);
@ -488,11 +488,11 @@ void collide(std::vector<creature> & creatures, float dt)
{
int creature;
int cell;
geom::point<float, 2> center;
math::point<float, 2> center;
float radius;
};
util::hash_map<geom::point<int, 2>, std::vector<cell_data>> bins;
util::hash_map<math::point<int, 2>, std::vector<cell_data>> bins;
float bin_size = 1.f;
for (int c = 0; c < creatures.size(); ++c)
@ -502,7 +502,7 @@ void collide(std::vector<creature> & creatures, float dt)
auto const & cell = creatures[c].cells[i];
cell_data data{c, i, creatures[c].cell_center(cell), size(cell.data)};
geom::point<int, 2> bin_id{std::floor(data.center[0] / bin_size), std::floor(data.center[1] / bin_size)};
math::point<int, 2> bin_id{std::floor(data.center[0] / bin_size), std::floor(data.center[1] / bin_size)};
bins[bin_id].push_back(data);
}
}
@ -510,7 +510,7 @@ void collide(std::vector<creature> & creatures, float dt)
auto collide_cells = [&](cell_data const & data1, cell_data const & data2)
{
auto delta = data2.center - data1.center;
auto distance = geom::length(delta);
auto distance = math::length(delta);
float min_distance = data1.radius + data2.radius;
@ -548,7 +548,7 @@ void collide(std::vector<creature> & creatures, float dt)
{
if (x == 0 && y == 0) continue;
auto nid = bin.first + geom::vector{x, y};
auto nid = bin.first + math::vector{x, y};
if (bin.first < nid) continue;
@ -567,7 +567,7 @@ void enlighten(std::vector<creature> & creatures)
{
int creature;
int cell;
geom::point<float, 2> center;
math::point<float, 2> center;
float radius;
};
@ -597,14 +597,14 @@ void enlighten(std::vector<creature> & creatures)
return std::tie(d1.center[1], d1.center[0]) < std::tie(d2.center[1], d2.center[0]);
});
geom::interval<float> bin_extent{bin.first * bin_size, (bin.first + 1) * bin_size};
math::interval<float> bin_extent{bin.first * bin_size, (bin.first + 1) * bin_size};
float received_light = 1.f;
for (int i = bin.second.size(); i --> 0;)
{
auto const & data = bin.second[i];
auto & cell = creatures[data.creature].cells[data.cell];
geom::interval cell_extent{data.center[0] - data.radius, data.center[0] + data.radius};
math::interval cell_extent{data.center[0] - data.radius, data.center[0] + data.radius};
auto portion = std::min(1.f, (cell_extent & bin_extent).length() / cell_extent.length());
@ -628,14 +628,14 @@ void draw(gfx::painter & painter, creature const & creature, float lag)
for (auto const & cell : creature.cells)
{
geom::point<float, 2> center{0.f, 0.f};
math::point<float, 2> center{0.f, 0.f};
for (auto idx : cell.indices)
center += 0.25f * (creature.positions[idx] - geom::point{0.f, 0.f});
center += 0.25f * (creature.positions[idx] - math::point{0.f, 0.f});
gfx::color_rgba const color = gfx::dark(cell_color(cell.data), 0.75f * (1.f - cell.received_light));
gfx::color_rgba const bgcolor = gfx::dark(color, 0.25f);
geom::point<float, 2> ps[4];
math::point<float, 2> ps[4];
for (int i = 0; i < 4; ++i)
ps[i] = point(cell.indices[i]);
@ -643,7 +643,7 @@ void draw(gfx::painter & painter, creature const & creature, float lag)
painter.triangle(ps[2], ps[0], ps[3], bgcolor);
for (int i = 0; i < 4; ++i)
ps[i] = geom::lerp(ps[i], center, 0.25f);
ps[i] = math::lerp(ps[i], center, 0.25f);
painter.triangle(ps[0], ps[1], ps[2], color);
painter.triangle(ps[2], ps[0], ps[3], color);
@ -665,19 +665,19 @@ struct creature_builder
: genome_(std::move(genome))
{}
void add(geom::point<int, 2> const position, cell_data const & data)
void add(math::point<int, 2> const position, cell_data const & data)
{
genome_.cells[position] = data;
}
bool contains(geom::point<int, 2> const & position) const
bool contains(math::point<int, 2> const & position) const
{
return genome_.cells.contains(position);
}
creature build(int generation)
{
static geom::vector<int, 2> const vertex_delta[4]
static math::vector<int, 2> const vertex_delta[4]
{
{0, 0},
{1, 0},
@ -688,7 +688,7 @@ struct creature_builder
creature result;
result.generation = generation;
util::hash_map<geom::point<int, 2>, std::uint32_t> vertex_id;
util::hash_map<math::point<int, 2>, std::uint32_t> vertex_id;
for (auto const & cell : genome_.cells)
{
@ -696,7 +696,7 @@ struct creature_builder
cell_out.data = cell.second;
for (int i = 0; i < 4; ++i)
{
geom::point<int, 2> vertex = cell.first + vertex_delta[i];
math::point<int, 2> vertex = cell.first + vertex_delta[i];
if (auto it = vertex_id.find(vertex); it != vertex_id.end())
{
cell_out.indices[i] = it->second;
@ -704,8 +704,8 @@ struct creature_builder
else
{
cell_out.indices[i] = (vertex_id[vertex] = result.positions.size());
result.positions.push_back(geom::cast<float>(vertex));
result.velocities.push_back(geom::vector<float, 2>::zero());
result.positions.push_back(math::cast<float>(vertex));
result.velocities.push_back(math::vector<float, 2>::zero());
}
}
}
@ -720,9 +720,9 @@ struct creature_builder
if (genome_.cells.empty())
return false;
util::hash_set<geom::point<int, 2>> visited;
util::hash_set<math::point<int, 2>> visited;
std::deque<geom::point<int, 2>> queue;
std::deque<math::point<int, 2>> queue;
queue.push_back(genome_.cells.begin()->first);
visited.insert(queue.back());
@ -773,7 +773,7 @@ void mutate(genome & genome, random::generator & rng)
if (random::uniform<float>(rng) < change_type_probability)
cell.second = random_cell(rng);
std::vector<geom::point<int, 2>> erase_cells;
std::vector<math::point<int, 2>> erase_cells;
for (auto const & cell : genome.cells)
if (random::uniform<float>(rng) < erase_probability)
erase_cells.push_back(cell.first);
@ -781,7 +781,7 @@ void mutate(genome & genome, random::generator & rng)
for (auto const & cell : erase_cells)
genome.cells.erase(cell);
std::vector<std::pair<geom::point<int, 2>, cell_data>> grow_cells;
std::vector<std::pair<math::point<int, 2>, cell_data>> grow_cells;
for (auto const & cell : genome.cells)
for (auto n : neighbours)
{
@ -808,7 +808,7 @@ std::optional<creature> creature::create_offspring(cell const & cell, random::ge
auto center = result.center();
auto angle = random::uniform_angle<float>(rng);
for (auto & position : result.positions)
position = center + geom::rotate(position - center, angle);
position = center + math::rotate(position - center, angle);
auto push = random::uniform_hemisphere_vector_distribution<float, 2>({0.f, 1.f})(rng);
result.translate(push * 1.f);
@ -826,14 +826,14 @@ struct soft_creatures_2d_app
// map_.ground_points.push_back({5.f, 0.f});
// for (int x = 10; x <= 200; x += 1)
// map_.ground_points.push_back({x / 2.f, random::uniform(rng, 0.f, std::min(x, 200) / 200.f * 4.f)});
// map_.ground_points.push_back({x, std::min(2.f, geom::sqr(x - 10) * 0.25f)});
// map_.ground_points.push_back({x, std::min(2.f, math::sqr(x - 10) * 0.25f)});
// map_.ground_points.push_back({x, random::uniform(rng, 0.f, 4.f)});
map_.walls.push_back({{0.f, 0.f}, {0.f, 1.f}});
// map_.walls.push_back({{-40.f, 0.f}, {1.f, 0.f}});
// map_.walls.push_back({{40.f, 0.f}, {-1.f, 0.f}});
map_.walls.push_back({{-20.f, 0.f}, geom::normalized(geom::vector{1.f, 1.f})});
map_.walls.push_back({{20.f, 0.f}, geom::normalized(geom::vector{-1.f, 1.f})});
map_.walls.push_back({{-20.f, 0.f}, math::normalized(math::vector{1.f, 1.f})});
map_.walls.push_back({{20.f, 0.f}, math::normalized(math::vector{-1.f, 1.f})});
// map_.radius = 30.f;
@ -946,7 +946,7 @@ struct soft_creatures_2d_app
gl::Clear(gl::COLOR_BUFFER_BIT);
float aspect_ratio = state().size[0] * 1.f / state().size[1];
geom::box<float, 2> view_box = {{{0.f, 0.f}, {0.f, 0.f}}};
math::box<float, 2> view_box = {{{0.f, 0.f}, {0.f, 0.f}}};
view_box[0] = {-50.f, 50.f};
view_box[1] = {0.f, view_box[0].length() / aspect_ratio};
view_box[1] -= view_box[1].length() / 2.f;
@ -960,7 +960,7 @@ struct soft_creatures_2d_app
for (auto const & wall : map_.walls)
{
std::vector<geom::point<float, 2>> points;
std::vector<math::point<float, 2>> points;
for (float x = 0; x <= 1; ++x)
{
for (float y = 0; y <= 1; ++y)
@ -980,11 +980,11 @@ struct soft_creatures_2d_app
// (p0 + t * dp - o) * n = 0
// t (dp*n) + (p0-o)*n = 0
float a = geom::dot(p1 - p0, wall.normal);
float a = math::dot(p1 - p0, wall.normal);
if (std::abs(a) < 1e-4f)
continue;
float t = - geom::dot(p0 - wall.origin, wall.normal) / a;
float t = - math::dot(p0 - wall.origin, wall.normal) / a;
if (t < 0.f || t > 1.f)
continue;
@ -993,7 +993,7 @@ struct soft_creatures_2d_app
}
}
std::vector<std::vector<geom::point<float, 2>>::iterator> hull;
std::vector<std::vector<math::point<float, 2>>::iterator> hull;
if (!points.empty())
cg::graham_convex_hull(points.begin(), points.end(), std::back_inserter(hull));
@ -1019,7 +1019,7 @@ struct soft_creatures_2d_app
for (auto const & creature : creatures_)
draw(painter_, creature, physics_lag_);
painter_.render(geom::orthographic_camera(view_box).transform());
painter_.render(math::orthographic_camera(view_box).transform());
int text_row = 0;
auto put_line = [&](std::string const & line)
@ -1038,7 +1038,7 @@ struct soft_creatures_2d_app
put_line(util::to_string("Cells: ", cells));
put_line(util::to_string("Cell/cr.: ", cells * 1.f / creatures_.size()));
painter_.render(geom::window_camera(state().size[0], state().size[1]).transform());
painter_.render(math::window_camera(state().size[0], state().size[1]).transform());
}
private:
@ -1046,8 +1046,8 @@ private:
util::clock<> frame_clock_;
geom::point<float, 2> view_center_{0.f, 20.f};
geom::point<float, 2> view_center_tgt_ = view_center_;
math::point<float, 2> view_center_{0.f, 20.f};
math::point<float, 2> view_center_tgt_ = view_center_;
random::generator rng_{random::device{}};

View file

@ -8,13 +8,13 @@
#include <psemek/gfx/renderer/simple.hpp>
#include <psemek/gfx/error.hpp>
#include <psemek/geom/camera.hpp>
#include <psemek/geom/math.hpp>
#include <psemek/geom/homogeneous.hpp>
#include <psemek/geom/gauss.hpp>
#include <psemek/geom/orientation.hpp>
#include <psemek/geom/intersection.hpp>
#include <psemek/geom/distance.hpp>
#include <psemek/math/camera.hpp>
#include <psemek/math/math.hpp>
#include <psemek/math/homogeneous.hpp>
#include <psemek/math/gauss.hpp>
#include <psemek/math/orientation.hpp>
#include <psemek/math/intersection.hpp>
#include <psemek/math/distance.hpp>
#include <psemek/cg/body/icosahedron.hpp>
#include <psemek/cg/body/box.hpp>
@ -83,7 +83,7 @@ static const float exaggeration = 1.f;
struct height_provider
{
float height_at(geom::vector<float, 3> const & v);
float height_at(math::vector<float, 3> const & v);
struct datum_id_hash
{
@ -100,13 +100,13 @@ struct height_provider
std::unordered_set<std::pair<int, int>, datum_id_hash> no_datums;
};
float height_provider::height_at(geom::vector<float, 3> const & v)
float height_provider::height_at(math::vector<float, 3> const & v)
{
static std::filesystem::path const data_path = "/home/lisyarus/data/srtm/dem";
float const lat = geom::deg(std::asin(v[2]));
float const lat = math::deg(std::asin(v[2]));
float const lon = geom::deg(std::atan2(v[0], -v[1]));
float const lon = math::deg(std::atan2(v[0], -v[1]));
int ilat = std::floor(lat);
int ilon = std::floor(lon);
@ -199,8 +199,8 @@ float height_provider::height_at(geom::vector<float, 3> const & v)
return (int)values[(3600 - lat) * 3601 + lon] - 32768;
};
int const tlat = geom::clamp<int>(std::floor((lat - ilat) * 3600), {0, 3600 - 1});
int const tlon = geom::clamp<int>(std::floor((lon - ilon) * 3600), {0, 3600 - 1});
int const tlat = math::clamp<int>(std::floor((lat - ilat) * 3600), {0, 3600 - 1});
int const tlon = math::clamp<int>(std::floor((lon - ilon) * 3600), {0, 3600 - 1});
float const mlat = (lat - ilat) * 3600.f - tlat;
float const mlon = (lon - ilon) * 3600.f - tlon;
@ -210,7 +210,7 @@ float height_provider::height_at(geom::vector<float, 3> const & v)
float h10 = at(tlat, tlon + 1);
float h11 = at(tlat + 1, tlon + 1);
return geom::lerp(geom::lerp(h00, h01, mlat), geom::lerp(h10, h11, mlat), mlon);
return math::lerp(math::lerp(h00, h01, mlat), math::lerp(h10, h11, mlat), mlon);
}
static constexpr int node_size_log2 = 8;
@ -256,8 +256,8 @@ void node_cache::store(std::size_t uid, std::vector<std::int16_t> const & data)
struct node
{
geom::vector<float, 3> v[3];
geom::interval<float> height_range;
math::vector<float, 3> v[3];
math::interval<float> height_range;
virtual bool draw(int level) = 0;
virtual node * child(int id) = 0;
@ -312,7 +312,7 @@ private:
};
node_controller::node_controller()
: icosahedron_{geom::point<float, 3>::zero(), 1.f}
: icosahedron_{math::point<float, 3>::zero(), 1.f}
{
std::vector<std::uint16_t> indices;
index_counts_[0] = 0;
@ -356,9 +356,9 @@ node * node_controller::root(int f)
n->uid = (1 << 5) | f;
auto face = cg::faces(icosahedron_)[f];
n->v[0] = icosahedron_.vertices[face[0]] - geom::point<float, 3>::zero();
n->v[1] = icosahedron_.vertices[face[1]] - geom::point<float, 3>::zero();
n->v[2] = icosahedron_.vertices[face[2]] - geom::point<float, 3>::zero();
n->v[0] = icosahedron_.vertices[face[0]] - math::point<float, 3>::zero();
n->v[1] = icosahedron_.vertices[face[1]] - math::point<float, 3>::zero();
n->v[2] = icosahedron_.vertices[face[2]] - math::point<float, 3>::zero();
roots_[f] = std::move(n);
}
@ -450,7 +450,7 @@ node * node_controller::node_impl::child(int id)
float t1 = (1.f * j) / (1.f * node_child_size);
float t2 = 1.f - t0 - t1;
return geom::normalized(v[0] * t0 + v[1] * t1 + v[2] * t2);
return math::normalized(v[0] * t0 + v[1] * t1 + v[2] * t2);
};
n->v[0] = at(i0, j0);
@ -487,7 +487,7 @@ void node_controller::node_impl::load_heights()
float t1 = (1.f * j) / (1.f * node_size);
float t2 = 1.f - t0 - t1;
return geom::normalized(v[0] * t0 + v[1] * t1 + v[2] * t2);
return math::normalized(v[0] * t0 + v[1] * t1 + v[2] * t2);
};
for (int i = 0; i <= node_size; ++i)
@ -612,8 +612,8 @@ struct srtm_app
void update() override;
void present() override;
geom::free_camera camera;
geom::matrix<float, 4, 4> camera_transform;
math::free_camera camera;
math::matrix<float, 4, 4> camera_transform;
bool camera_forward = false;
node_controller nodes;
@ -637,15 +637,15 @@ srtm_app::srtm_app(options const &, context const & context)
context.vsync(true);
context.show_cursor(false);
camera.fov_y = geom::rad(45.f);
camera.fov_y = math::rad(45.f);
camera.near_clip = 0.0001f;
camera.far_clip = 10.f;
camera.pos = {0.f, -10.f, 0.f};
camera.rotateYZ(geom::rad(-90.f));
camera.rotateYZ(math::rad(-90.f));
camera_transform = camera.transform();
selected_mesh.setup<geom::point<float, 3>>();
selected_mesh.setup<math::point<float, 3>>();
{
util::array<gfx::color_rgb, 1> colors({16});
@ -721,7 +721,7 @@ void srtm_app::update()
camera.rotateXY(4.f * dt);
}
float const camera_speed = std::min(5.f, geom::distance(camera.pos, geom::point<float, 3>::zero()) - 1.f);
float const camera_speed = std::min(5.f, math::distance(camera.pos, math::point<float, 3>::zero()) - 1.f);
auto const camera_forward = camera.direction();
auto const camera_up = camera.axis_y();
@ -783,11 +783,11 @@ std::ostream & operator << (std::ostream & os, std::vector<T> const & v)
void srtm_app::present()
{
cg::icosahedron<float> icosahedron{geom::point<float, 3>::zero(), 1.f};
cg::icosahedron<float> icosahedron{math::point<float, 3>::zero(), 1.f};
auto const & icosa_vertices = cg::vertices(icosahedron);
auto const & icosa_faces = cg::faces(icosahedron);
auto const icosa_side = geom::distance(icosa_vertices[icosa_faces[0][0]], icosa_vertices[icosa_faces[0][1]]);
auto const icosa_side = math::distance(icosa_vertices[icosa_faces[0][0]], icosa_vertices[icosa_faces[0][1]]);
std::vector<std::string> info;
@ -806,7 +806,7 @@ void srtm_app::present()
gl::PrimitiveRestartIndex(0xffffu);
{
auto d = geom::distance(camera.pos, geom::point<float, 3>::zero());
auto d = math::distance(camera.pos, math::point<float, 3>::zero());
camera.far_clip = std::sqrt(d * d + 1.f);
camera.near_clip = (d > 2.f) ? d - 2.f : 0.0001f;
}
@ -815,12 +815,12 @@ void srtm_app::present()
auto const camera_pos = camera.position();
auto const camera_direction = camera.direction();
info.push_back(util::to_string("Camera height: ", (geom::distance(camera_pos, geom::point<float, 3>::zero()) - 1.f) * 6400000.f, " m"));
info.push_back(util::to_string("Camera height: ", (math::distance(camera_pos, math::point<float, 3>::zero()) - 1.f) * 6400000.f, " m"));
auto const frustum = cg::frustum(camera_transform);
(void)frustum;
auto light = geom::normalized(geom::vector{camera_pos[0]-camera_pos[1], camera_pos[1]+camera_pos[0], 0.f});
auto light = math::normalized(math::vector{camera_pos[0]-camera_pos[1], camera_pos[1]+camera_pos[0], 0.f});
tile_close_program.bind();
tile_close_program["u_transform"] = camera_transform;
@ -846,20 +846,20 @@ void srtm_app::present()
info.push_back(util::to_string("Camera pos: ", camera_pos));
std::vector<geom::point<float, 3>> selected_vertices;
std::vector<math::point<float, 3>> selected_vertices;
std::size_t rendered_tiles = 0;
std::vector<std::size_t> id;
auto visit = util::recursive([&](auto & self, node * n, int level = 0) -> bool
{
auto const & v = n->v;
auto const o = geom::point<float, 3>::zero();
auto const o = math::point<float, 3>::zero();
{
bool culled = true;
for (std::size_t i = 0; i < 3; ++i)
{
if (geom::dot(v[i], geom::normalized(camera_pos - o)) >= 0.f)
if (math::dot(v[i], math::normalized(camera_pos - o)) >= 0.f)
{
culled = false;
break;
@ -873,34 +873,34 @@ void srtm_app::present()
bool const flat = n->height_range.max == n->height_range.min;
auto const m3 = (v[0] + v[1] + v[2]) / 3.f;
auto const m = geom::normalized(m3);
auto const m = math::normalized(m3);
auto const m0 = m * (n->height_range.empty() ? 0.f : n->height_range.min) / 6400000.f;
auto const m1 = m * (n->height_range.empty() ? 1.f : flat ? n->height_range.min + 1.f : n->height_range.max) / 6400000.f + (m - m3);
geom::triangle<geom::point<float, 3>> t{o + v[0] + m0, o + v[1] + m0, o + v[2] + m0};
math::triangle<math::point<float, 3>> t{o + v[0] + m0, o + v[1] + m0, o + v[2] + m0};
cg::triangular_prism<float> body{t, m1 - m0};
// if (cg::separation(body, frustum).second > 0.f)
// return true;
bool const selected = geom::intersect(geom::ray{camera_pos, camera_direction}, t);
bool const selected = math::intersect(math::ray{camera_pos, camera_direction}, t);
float on_screen_unit;
{
auto edge = [](auto const & v0, auto const & v1, auto const & u) -> std::optional<float>
{
auto const n = geom::normalized(geom::cross(v0, v1));
auto v = geom::normalized(u - n * dot(u, n));
if (geom::dot(geom::cross(v0, v), geom::cross(v, v1)) >= 0.f)
return geom::length(v - u);
auto const n = math::normalized(math::cross(v0, v1));
auto v = math::normalized(u - n * dot(u, n));
if (math::dot(math::cross(v0, v), math::cross(v, v1)) >= 0.f)
return math::length(v - u);
return std::nullopt;
};
float distance = std::numeric_limits<float>::infinity();
auto c = camera_pos - o;
if (geom::det(v[0], v[1], c) >= 0.f && geom::det(v[1], v[2], c) >= 0.f && geom::det(v[2], v[0], c) >= 0.f)
distance = std::min(distance, geom::length(c) - 1.f);
if (math::det(v[0], v[1], c) >= 0.f && math::det(v[1], v[2], c) >= 0.f && math::det(v[2], v[0], c) >= 0.f)
distance = std::min(distance, math::length(c) - 1.f);
else
{
if (auto d = edge(v[0], v[1], c); d)
@ -910,9 +910,9 @@ void srtm_app::present()
if (auto d = edge(v[2], v[0], c); d)
distance = std::min(distance, *d);
}
distance = std::min(distance, geom::length(c - v[0]));
distance = std::min(distance, geom::length(c - v[1]));
distance = std::min(distance, geom::length(c - v[2]));
distance = std::min(distance, math::length(c - v[0]));
distance = std::min(distance, math::length(c - v[1]));
distance = std::min(distance, math::length(c - v[2]));
on_screen_unit = state().size[0] / distance / std::tan(camera.fov_x / 2.f);
}
@ -948,7 +948,7 @@ void srtm_app::present()
if (!should_draw_children || !all_children_drawn)
{
tile_n = geom::clamp(tile_n, {0, node_size_log2});
tile_n = math::clamp(tile_n, {0, node_size_log2});
++rendered_tiles;
@ -1026,7 +1026,7 @@ void srtm_app::present()
gl::Enable(gl::BLEND);
gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
gl::Disable(gl::DEPTH_TEST);
painter.render(geom::window_camera{width, height}.transform());
painter.render(math::window_camera{width, height}.transform());
}
namespace psemek::app

View file

@ -2,9 +2,9 @@
#include <psemek/app/default_application_factory.hpp>
#include <psemek/gfx/painter.hpp>
#include <psemek/gfx/gl.hpp>
#include <psemek/geom/scale.hpp>
#include <psemek/geom/camera.hpp>
#include <psemek/geom/constants.hpp>
#include <psemek/math/scale.hpp>
#include <psemek/math/camera.hpp>
#include <psemek/math/constants.hpp>
#include <psemek/cg/bbox.hpp>
#include <psemek/cg/triangulation/ear_clipping.hpp>
#include <psemek/cg/triangulation/monotone.hpp>
@ -13,8 +13,8 @@
#include <psemek/prof/profiler.hpp>
#include <psemek/util/clock.hpp>
#include <psemek/util/to_string.hpp>
#include <psemek/geom/homogeneous.hpp>
#include <psemek/geom/swizzle.hpp>
#include <psemek/math/homogeneous.hpp>
#include <psemek/math/swizzle.hpp>
#include <psemek/random/generator.hpp>
#include <psemek/random/uniform.hpp>
@ -31,7 +31,7 @@ struct triangulation_app
while (true)
{
geom::point<float, 2> p;
math::point<float, 2> p;
in >> p[0] >> p[1];
if (!in)
break;
@ -63,8 +63,8 @@ struct triangulation_app
{
prof::profiler prof("triangulate");
// auto dcel = cg::ear_clipping<std::uint16_t>(geom::fast, points_.begin(), points_.end());
auto dcel = cg::monotone_triangulation<std::uint16_t>(geom::fast, points_.begin(), points_.end());
// auto dcel = cg::ear_clipping<std::uint16_t>(math::fast, points_.begin(), points_.end());
auto dcel = cg::monotone_triangulation<std::uint16_t>(math::fast, points_.begin(), points_.end());
edges_ = cg::edge_mesh(dcel);
triangles_ = cg::triangle_mesh(dcel);
}
@ -103,7 +103,7 @@ struct triangulation_app
{
auto delta = state().mouse - *drag_start_;
delta[1] *= -1;
camera_center_ -= geom::cast<float>(delta) * camera_size_ / (1.f * state().size[1]);
camera_center_ -= math::cast<float>(delta) * camera_size_ / (1.f * state().size[1]);
drag_start_ = state().mouse;
}
@ -116,7 +116,7 @@ struct triangulation_app
gl::Clear(gl::COLOR_BUFFER_BIT);
float aspect_ratio = (state().size[0] * 1.f) / state().size[1];
geom::box<float, 2> view_bbox = geom::expand(geom::box<float, 2>::singleton(camera_center_), geom::vector{camera_size_ * 0.5f * aspect_ratio, camera_size_ * 0.5f});
math::box<float, 2> view_bbox = math::expand(math::box<float, 2>::singleton(camera_center_), math::vector{camera_size_ * 0.5f * aspect_ratio, camera_size_ * 0.5f});
float line_width = 4.f * camera_size_ / state().size[1];
@ -144,17 +144,17 @@ struct triangulation_app
for (std::size_t i = 0; i < points_.size(); ++i)
edge(i, (i + 1) % points_.size(), gfx::black);
auto camera_transform = geom::orthographic_camera{view_bbox}.transform();
auto camera_transform = math::orthographic_camera{view_bbox}.transform();
painter_.render(camera_transform);
{
geom::point<float, 2> m_world;
m_world[0] = geom::lerp(view_bbox[0], state().mouse[0] * 1.f / state().size[0]);
m_world[1] = geom::lerp(view_bbox[1], 1.f - state().mouse[1] * 1.f / state().size[1]);
math::point<float, 2> m_world;
m_world[0] = math::lerp(view_bbox[0], state().mouse[0] * 1.f / state().size[0]);
m_world[1] = math::lerp(view_bbox[1], 1.f - state().mouse[1] * 1.f / state().size[1]);
auto compare = [&](auto i, auto j){
return geom::distance(points_[i], m_world) < geom::distance(points_[j], m_world);
return math::distance(points_[i], m_world) < math::distance(points_[j], m_world);
};
std::size_t const n_closest = 8;
@ -167,7 +167,7 @@ struct triangulation_app
{
auto i = closest_points_[j];
if (geom::distance(points_[i], m_world) > max_distance)
if (math::distance(points_[i], m_world) > max_distance)
break;
gfx::painter::text_options opts;
@ -175,26 +175,26 @@ struct triangulation_app
opts.x = gfx::painter::x_align::left;
opts.y = gfx::painter::y_align::bottom;
opts.scale = 2.f;
auto p = geom::swizzle<0, 1>(geom::as_point(camera_transform * geom::homogeneous(geom::swizzle<0, 1, -1>(points_[i]))));
auto p = math::swizzle<0, 1>(math::as_point(camera_transform * math::homogeneous(math::swizzle<0, 1, -1>(points_[i]))));
p[0] = std::round((p[0] * 0.5f + 0.5f) * state().size[0]);
p[1] = std::round((0.5f - p[1] * 0.5f) * state().size[1]);
painter_.text(p, util::to_string(i), opts);
}
}
painter_.render(geom::window_camera{state().size[0], state().size[1]}.transform());
painter_.render(math::window_camera{state().size[0], state().size[1]}.transform());
}
private:
std::vector<geom::point<float, 2>> points_;
std::vector<geom::segment<std::uint16_t>> edges_;
std::vector<geom::triangle<std::uint16_t>> triangles_;
geom::box<float, 2> bbox_;
geom::point<float, 2> camera_center_;
std::vector<math::point<float, 2>> points_;
std::vector<math::segment<std::uint16_t>> edges_;
std::vector<math::triangle<std::uint16_t>> triangles_;
math::box<float, 2> bbox_;
math::point<float, 2> camera_center_;
float camera_size_;
float camera_size_tgt_;
std::optional<geom::point<int, 2>> drag_start_;
std::optional<math::point<int, 2>> drag_start_;
std::vector<std::uint16_t> closest_points_;
gfx::painter painter_;

View file

@ -1,7 +1,7 @@
#include <psemek/app/application_base.hpp>
#include <psemek/app/default_application_factory.hpp>
#include <psemek/gfx/painter.hpp>
#include <psemek/geom/orthographic.hpp>
#include <psemek/math/orthographic.hpp>
#include <psemek/log/log.hpp>
using namespace psemek;
@ -16,7 +16,7 @@ struct water_1d_app
void on_event(app::resize_event const & event) override;
geom::box<float, 2> simulation_area;
math::box<float, 2> simulation_area;
float aspect_ratio;
std::size_t const N = 100;
@ -42,7 +42,7 @@ water_1d_app::water_1d_app(options const &, context const &)
{
bed[i] += (0.5f * (N - i)) / N;
bed[i] += (100.f / (N - i)) / N;
bed[i] += 0.125f * std::exp(- 1000.f * geom::sqr(i * 1.f / N - 0.5f));
bed[i] += 0.125f * std::exp(- 1000.f * math::sqr(i * 1.f / N - 0.5f));
// bed[i] += (0.25f * i) / N;
// height[i] += (0.3f * i) / N;
@ -138,7 +138,7 @@ void water_1d_app::present()
gl::ClearColor(0.8f, 0.8f, 0.8f, 0.8f);
gl::Clear(gl::COLOR_BUFFER_BIT);
geom::box<float, 3> view_area;
math::box<float, 3> view_area;
{
view_area[0] = simulation_area[0];
view_area[1] = simulation_area[1];
@ -152,7 +152,7 @@ void water_1d_app::present()
view_area[0].max += extra_x / 2.f;
}
geom::matrix<float, 4, 4> const transform = geom::orthographic{view_area}.homogeneous_matrix();
math::matrix<float, 4, 4> const transform = math::orthographic{view_area}.homogeneous_matrix();
painter.rect(simulation_area, {255, 255, 255, 255});
@ -161,14 +161,14 @@ void water_1d_app::present()
for (std::size_t i = 0; i + 1 < N; ++i)
{
geom::point p0{x(i + 0) * 0.5f + x(i + 1) * 0.5f, simulation_area[1].min};
geom::point p1{x(i + 1) * 0.5f + x(i + 2) * 0.5f, simulation_area[1].min};
math::point p0{x(i + 0) * 0.5f + x(i + 1) * 0.5f, simulation_area[1].min};
math::point p1{x(i + 1) * 0.5f + x(i + 2) * 0.5f, simulation_area[1].min};
geom::point q0{p0[0], simulation_area[1].min + bed[i]};
geom::point q1{p1[0], simulation_area[1].min + bed[i + 1]};
math::point q0{p0[0], simulation_area[1].min + bed[i]};
math::point q1{p1[0], simulation_area[1].min + bed[i + 1]};
geom::point w0{p0[0], simulation_area[1].min + bed[i] + height[i]};
geom::point w1{p1[0], simulation_area[1].min + bed[i + 1] + height[i + 1]};
math::point w0{p0[0], simulation_area[1].min + bed[i] + height[i]};
math::point w1{p1[0], simulation_area[1].min + bed[i + 1] + height[i + 1]};
painter.triangle(p0, p1, q0, earth_color);
painter.triangle(q0, p1, q1, earth_color);
@ -200,7 +200,7 @@ void water_1d_app::on_event(app::resize_event const & event)
float water_1d_app::x(std::size_t i) const
{
return geom::lerp(simulation_area[0], (1.f * i) / N);
return math::lerp(simulation_area[0], (1.f * i) / N);
}
namespace psemek::app

View file

@ -8,9 +8,9 @@ namespace psemek::app
struct event_state
{
geom::vector<int, 2> size = {0, 0};
math::vector<int, 2> size = {0, 0};
bool focus = true;
geom::point<int, 2> mouse = {0, 0};
math::point<int, 2> mouse = {0, 0};
int wheel = 0;
util::hash_set<mouse_button> mouse_button_down;
util::hash_set<keycode> key_down;

View file

@ -1,13 +1,13 @@
#pragma once
#include <psemek/geom/point.hpp>
#include <psemek/math/point.hpp>
namespace psemek::app
{
struct resize_event
{
geom::vector<int, 2> size;
math::vector<int, 2> size;
};
struct focus_event
@ -17,8 +17,8 @@ namespace psemek::app
struct mouse_move_event
{
geom::point<int, 2> position;
geom::vector<int, 2> relative;
math::point<int, 2> position;
math::vector<int, 2> relative;
};
struct mouse_wheel_event
@ -41,17 +41,17 @@ namespace psemek::app
struct touch_down_event
{
geom::point<int, 2> position;
math::point<int, 2> position;
};
struct touch_up_event
{
geom::point<int, 2> position;
math::point<int, 2> position;
};
struct touch_move_event
{
geom::point<int, 2> position;
math::point<int, 2> position;
};
enum class keycode

View file

@ -3,4 +3,4 @@ file(GLOB_RECURSE PSEMEK_AUDIO_SOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "s
psemek_add_library(psemek-audio ${PSEMEK_AUDIO_HEADERS} ${PSEMEK_AUDIO_SOURCES})
target_include_directories(psemek-audio PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(psemek-audio PUBLIC psemek-random psemek-geom psemek-util psemek-log psemek-prof)
target_link_libraries(psemek-audio PUBLIC psemek-random psemek-math psemek-util psemek-log psemek-prof)

View file

@ -1,7 +1,7 @@
#pragma once
#include <psemek/audio/constants.hpp>
#include <psemek/geom/constants.hpp>
#include <psemek/math/constants.hpp>
#include <complex>
@ -17,7 +17,7 @@ namespace psemek::audio
void frequency(float f)
{
m_ = std::exp(std::complex<float>{0.f, 2.f * geom::pi * f * inv_frequency});
m_ = std::exp(std::complex<float>{0.f, 2.f * math::pi * f * inv_frequency});
}
std::complex<float> phase() const

View file

@ -1,6 +1,6 @@
#include <psemek/audio/detail/resampler.hpp>
#include <psemek/audio/detail/smooth.hpp>
#include <psemek/geom/math.hpp>
#include <psemek/math/math.hpp>
#include <psemek/log/log.hpp>
@ -47,16 +47,16 @@ namespace psemek::audio
while (position_ < 0)
{
result_.push_back(geom::lerp(last_sample_[0], samples[0], position_frac_));
result_.push_back(geom::lerp(last_sample_[1], samples[1], position_frac_));
result_.push_back(math::lerp(last_sample_[0], samples[0], position_frac_));
result_.push_back(math::lerp(last_sample_[1], samples[1], position_frac_));
real_ratio_ += (ratio - real_ratio_) * smoothness_multiplier;
advance(1.f / real_ratio_);
}
while (2 * position_ + 3 < samples.size())
{
result_.push_back(geom::lerp(samples[2 * position_ + 0], samples[2 * position_ + 2], position_frac_));
result_.push_back(geom::lerp(samples[2 * position_ + 1], samples[2 * position_ + 3], position_frac_));
result_.push_back(math::lerp(samples[2 * position_ + 0], samples[2 * position_ + 2], position_frac_));
result_.push_back(math::lerp(samples[2 * position_ + 1], samples[2 * position_ + 3], position_frac_));
real_ratio_ += (ratio - real_ratio_) * smoothness_multiplier;
advance(1.f / real_ratio_);
}

View file

@ -1,8 +1,8 @@
#include <psemek/audio/effect/compressor.hpp>
#include <psemek/audio/detail/smooth.hpp>
#include <psemek/geom/math.hpp>
#include <psemek/geom/interval.hpp>
#include <psemek/geom/contains.hpp>
#include <psemek/math/math.hpp>
#include <psemek/math/interval.hpp>
#include <psemek/math/contains.hpp>
namespace psemek::audio
{
@ -19,7 +19,7 @@ namespace psemek::audio
, strength_(strength)
, envelope_attack_multiplier_(smoothness_to_multiplier(envelope_attack))
, envelope_release_multiplier_(smoothness_to_multiplier(envelope_release))
, knee_range_(geom::expand(geom::interval<float>::singleton(volume_threshold_log_), std::log(knee) * 0.5f))
, knee_range_(math::expand(math::interval<float>::singleton(volume_threshold_log_), std::log(knee) * 0.5f))
{}
std::optional<std::size_t> length() const override
@ -43,8 +43,8 @@ namespace psemek::audio
float envelope_log = std::log(envelope_);
if (geom::contains(knee_range_, envelope_log))
strength *= geom::unlerp(knee_range_, envelope_log);
if (math::contains(knee_range_, envelope_log))
strength *= math::unlerp(knee_range_, envelope_log);
float log_gain = strength * std::min(0.f, volume_threshold_log_ - envelope_log);
@ -68,7 +68,7 @@ namespace psemek::audio
float strength_;
float envelope_attack_multiplier_;
float envelope_release_multiplier_;
geom::interval<float> knee_range_;
math::interval<float> knee_range_;
float envelope_ = 0.f;
};

View file

@ -12,7 +12,7 @@ namespace psemek::audio
{
auto func = [o = oscillator{frequency}]() mutable {
auto z = o.next();
return (2.f / geom::pi) * (- std::atan2(z.real() + 1.f, z.imag()));
return (2.f / math::pi) * (- std::atan2(z.real() + 1.f, z.imag()));
};
return make_generator(func);

View file

@ -11,7 +11,7 @@ namespace psemek::audio
{
auto func = [o = oscillator{frequency}]() mutable {
auto const z = o.next();
float const t = 0.5f * std::atan2(z.imag(), z.real()) / (geom::pi) + 0.5f;
float const t = 0.5f * std::atan2(z.imag(), z.real()) / (math::pi) + 0.5f;
return 4.f * std::abs(t - std::floor(t + 0.5f)) - 1.f;
};

View file

@ -2,5 +2,5 @@ file(GLOB_RECURSE PSEMEK_CG_HEADERS "include/*.hpp")
psemek_add_library(psemek-cg ${PSEMEK_CG_HEADERS})
target_include_directories(psemek-cg PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(psemek-cg PUBLIC psemek-geom psemek-util)
target_link_libraries(psemek-cg PUBLIC psemek-math psemek-util)
set_target_properties(psemek-cg PROPERTIES LINKER_LANGUAGE CXX)

View file

@ -1,7 +1,7 @@
#pragma once
#include <psemek/geom/point.hpp>
#include <psemek/geom/vector.hpp>
#include <psemek/math/point.hpp>
#include <psemek/math/vector.hpp>
#include <iterator>
@ -19,7 +19,7 @@ namespace psemek::cg
for (auto it = begin, prev = std::ranges::prev(end); it != end; prev = it++)
{
result += geom::volume(origin, *prev, *it);
result += math::volume(origin, *prev, *it);
}
return result / scalar_type{2};

View file

@ -1,6 +1,6 @@
#pragma once
#include <psemek/geom/box.hpp>
#include <psemek/math/box.hpp>
#include <psemek/util/range.hpp>
namespace psemek::cg
@ -11,7 +11,7 @@ namespace psemek::cg
{
using point_type = std::decay_t<decltype(*begin)>;
geom::box<typename point_type::scalar_type, point_type::static_dimension> result;
math::box<typename point_type::scalar_type, point_type::static_dimension> result;
for (; begin != end; ++begin)
result |= *begin;
return result;

View file

@ -1,8 +1,8 @@
#pragma once
#include <psemek/geom/simplex.hpp>
#include <psemek/geom/vector.hpp>
#include <psemek/geom/point.hpp>
#include <psemek/math/simplex.hpp>
#include <psemek/math/vector.hpp>
#include <psemek/math/point.hpp>
#include <vector>
#include <array>
@ -95,12 +95,12 @@ namespace psemek::cg
using std::begin;
using std::end;
std::vector<geom::segment<index_type>> result;
std::vector<math::segment<index_type>> result;
for (auto const & f : fs)
{
for (auto it = begin(f), jt = std::prev(end(f)); it != end(f); jt = it++)
{
geom::segment<index_type> s{*jt, *it};
math::segment<index_type> s{*jt, *it};
if (s[0] > s[1]) std::swap(s[0], s[1]);
result.push_back(s);
}
@ -142,13 +142,13 @@ namespace psemek::cg
{
constexpr std::size_t faces_count = detail::static_size_v<faces_type>;
constexpr std::size_t face_size = detail::static_size_v<face_type>;
std::array<geom::triangle<index_type>, faces_count * (face_size - 2)> result;
std::array<math::triangle<index_type>, faces_count * (face_size - 2)> result;
impl(result.begin());
return result;
}
else
{
std::vector<geom::triangle<index_type>> result;
std::vector<math::triangle<index_type>> result;
if constexpr (detail::has_static_size_v<face_type>)
{
constexpr std::size_t face_size = detail::static_size_v<face_type>;
@ -176,7 +176,7 @@ namespace psemek::cg
{
for (auto const & e : es)
{
*out++ = geom::normalized(vs[e[1]] - vs[e[0]]);
*out++ = math::normalized(vs[e[1]] - vs[e[0]]);
}
};
@ -209,7 +209,7 @@ namespace psemek::cg
{
for (auto const & f : fs)
{
*out++ = geom::normal(vs[f[0]], vs[f[1]], vs[f[2]]);
*out++ = math::normal(vs[f[0]], vs[f[1]], vs[f[2]]);
}
};

View file

@ -2,7 +2,7 @@
#include <psemek/cg/body/body.hpp>
#include <psemek/geom/box.hpp>
#include <psemek/math/box.hpp>
namespace psemek::cg
{
@ -11,19 +11,19 @@ namespace psemek::cg
struct box;
template <typename T, std::size_t N>
box(geom::box<T, N>) -> box<T, N>;
box(math::box<T, N>) -> box<T, N>;
template <typename T>
struct box<T, 2>
{
box() = default;
box(geom::box<T, 2> const & b);
box(math::box<T, 2> const & b);
std::array<geom::point<T, 2>, 4> vertices;
std::array<math::point<T, 2>, 4> vertices;
};
template <typename T>
box<T, 2>::box(geom::box<T, 2> const & b)
box<T, 2>::box(math::box<T, 2> const & b)
{
for (std::size_t y = 0; y < 2; ++y)
{
@ -46,7 +46,7 @@ namespace psemek::cg
template <typename T>
auto const & edges(box<T, 2> const &)
{
static const std::array<geom::segment<std::uint8_t>, 12> result =
static const std::array<math::segment<std::uint8_t>, 12> result =
{{
{ 0b00, 0b01 },
{ 0b01, 0b11 },
@ -61,13 +61,13 @@ namespace psemek::cg
struct box<T, 3>
{
box() = default;
box(geom::box<T, 3> const & b);
box(math::box<T, 3> const & b);
std::array<geom::point<T, 3>, 8> vertices;
std::array<math::point<T, 3>, 8> vertices;
};
template <typename T>
box<T, 3>::box(geom::box<T, 3> const & b)
box<T, 3>::box(math::box<T, 3> const & b)
{
for (std::size_t z = 0; z < 2; ++z)
{
@ -94,7 +94,7 @@ namespace psemek::cg
template <typename T>
auto const & edges(box<T, 3> const &)
{
static const std::array<geom::segment<std::uint8_t>, 12> result =
static const std::array<math::segment<std::uint8_t>, 12> result =
{{
{ 0b000, 0b001 },
{ 0b010, 0b011 },
@ -134,7 +134,7 @@ namespace psemek::cg
template <typename T>
auto const & face_normals(box<T, 3> const &)
{
static const std::array<geom::vector<T, 3>, 6> result =
static const std::array<math::vector<T, 3>, 6> result =
{{
{-1, 0, 0},
{ 1, 0, 0},
@ -150,7 +150,7 @@ namespace psemek::cg
template <typename T>
auto const & edge_directions(box<T, 3> const &)
{
static const std::array<geom::vector<T, 3>, 3> result =
static const std::array<math::vector<T, 3>, 3> result =
{{
{ 1, 0, 0},
{ 0, 1, 0},

View file

@ -3,9 +3,9 @@
#include <psemek/cg/body/body.hpp>
#include <psemek/cg/body/box.hpp>
#include <psemek/geom/matrix.hpp>
#include <psemek/geom/gauss.hpp>
#include <psemek/geom/homogeneous.hpp>
#include <psemek/math/matrix.hpp>
#include <psemek/math/gauss.hpp>
#include <psemek/math/homogeneous.hpp>
namespace psemek::cg
{
@ -14,21 +14,21 @@ namespace psemek::cg
struct frustum;
template <typename T, std::size_t N>
frustum(geom::matrix<T, N, N>) -> frustum<T, N-1>;
frustum(math::matrix<T, N, N>) -> frustum<T, N-1>;
template <typename T>
struct frustum<T, 3>
{
frustum() = default;
frustum(geom::matrix<T, 4, 4> const & m);
frustum(math::matrix<T, 4, 4> const & m);
std::array<geom::point<T, 3>, 8> vertices;
std::array<math::point<T, 3>, 8> vertices;
};
template <typename T>
frustum<T, 3>::frustum(geom::matrix<T, 4, 4> const & m)
frustum<T, 3>::frustum(math::matrix<T, 4, 4> const & m)
{
bool flip = (geom::det(m) < 0);
bool flip = (math::det(m) < 0);
for (std::size_t z = 0; z < 2; ++z)
{
@ -38,15 +38,15 @@ namespace psemek::cg
{
std::size_t i = z * 4 + y * 2 + (flip ? 1 - x : x);
geom::vector<T, 4> p;
math::vector<T, 4> p;
p[0] = (x == 0) ? -1 : 1;
p[1] = (y == 0) ? -1 : 1;
p[2] = (z == 0) ? -1 : 1;
p[3] = 1;
geom::gauss(m, p);
math::gauss(m, p);
vertices[i] = geom::as_point(p);
vertices[i] = math::as_point(p);
}
}
}

View file

@ -11,33 +11,33 @@ namespace psemek::cg
struct icosahedron
{
icosahedron() = default;
icosahedron(geom::point<T, 3> const & origin, T radius);
icosahedron(math::point<T, 3> const & origin, T radius);
std::array<geom::point<T, 3>, 12> vertices;
std::array<math::point<T, 3>, 12> vertices;
};
template <typename T>
icosahedron<T>::icosahedron(geom::point<T, 3> const & origin, T radius)
icosahedron<T>::icosahedron(math::point<T, 3> const & origin, T radius)
{
static const T icosa_a = radius * 0.850650808; // radius * phi / sqrt(1 + phi^2)
static const T icosa_b = radius * 0.525731112; // radius / sqrt(1 + phi^2)
vertices =
{{
origin + geom::vector<T, 3>{-icosa_a, -icosa_b, 0}, // 0
origin + geom::vector<T, 3>{-icosa_a, icosa_b, 0}, // 1
origin + geom::vector<T, 3>{ icosa_a, -icosa_b, 0}, // 2
origin + geom::vector<T, 3>{ icosa_a, icosa_b, 0}, // 3
origin + math::vector<T, 3>{-icosa_a, -icosa_b, 0}, // 0
origin + math::vector<T, 3>{-icosa_a, icosa_b, 0}, // 1
origin + math::vector<T, 3>{ icosa_a, -icosa_b, 0}, // 2
origin + math::vector<T, 3>{ icosa_a, icosa_b, 0}, // 3
origin + geom::vector<T, 3>{0, -icosa_a, -icosa_b}, // 4
origin + geom::vector<T, 3>{0, -icosa_a, icosa_b}, // 5
origin + geom::vector<T, 3>{0, icosa_a, -icosa_b}, // 6
origin + geom::vector<T, 3>{0, icosa_a, icosa_b}, // 7
origin + math::vector<T, 3>{0, -icosa_a, -icosa_b}, // 4
origin + math::vector<T, 3>{0, -icosa_a, icosa_b}, // 5
origin + math::vector<T, 3>{0, icosa_a, -icosa_b}, // 6
origin + math::vector<T, 3>{0, icosa_a, icosa_b}, // 7
origin + geom::vector<T, 3>{-icosa_b, 0, -icosa_a}, // 8
origin + geom::vector<T, 3>{ icosa_b, 0, -icosa_a}, // 9
origin + geom::vector<T, 3>{-icosa_b, 0, icosa_a}, // 10
origin + geom::vector<T, 3>{ icosa_b, 0, icosa_a}, // 11
origin + math::vector<T, 3>{-icosa_b, 0, -icosa_a}, // 8
origin + math::vector<T, 3>{ icosa_b, 0, -icosa_a}, // 9
origin + math::vector<T, 3>{-icosa_b, 0, icosa_a}, // 10
origin + math::vector<T, 3>{ icosa_b, 0, icosa_a}, // 11
}};
}
@ -50,7 +50,7 @@ namespace psemek::cg
template <typename T>
auto const & triangles(icosahedron<T> const &)
{
static const std::array<geom::triangle<std::uint8_t>, 20> result =
static const std::array<math::triangle<std::uint8_t>, 20> result =
{{
{0, 1, 8,},
{0, 10, 1,},

View file

@ -1,6 +1,6 @@
#pragma once
#include <psemek/geom/simplex.hpp>
#include <psemek/math/simplex.hpp>
#include <psemek/cg/body/body.hpp>
#include <vector>
@ -11,14 +11,14 @@ namespace psemek::cg
template <typename T>
struct polygon
{
polygon(std::vector<geom::point<T, 2>> vertices);
polygon(std::vector<math::point<T, 2>> vertices);
std::vector<geom::point<T, 2>> vertices;
std::vector<geom::segment<std::size_t>> edges;
std::vector<math::point<T, 2>> vertices;
std::vector<math::segment<std::size_t>> edges;
};
template <typename T>
polygon<T>::polygon(std::vector<geom::point<T, 2>> vertices)
polygon<T>::polygon(std::vector<math::point<T, 2>> vertices)
: vertices(std::move(vertices))
{
edges.resize(vertices.size());

View file

@ -11,14 +11,14 @@ namespace psemek::cg
struct triangular_prism
{
triangular_prism() = default;
triangular_prism(geom::triangle<geom::point<T, 3>> const & t, geom::vector<T, 3> const & d);
triangular_prism(math::triangle<math::point<T, 3>> const & t, math::vector<T, 3> const & d);
std::array<geom::point<T, 3>, 6> vertices;
std::array<geom::vector<T, 3>, 4> edge_directions;
std::array<math::point<T, 3>, 6> vertices;
std::array<math::vector<T, 3>, 4> edge_directions;
};
template <typename T>
triangular_prism<T>::triangular_prism(geom::triangle<geom::point<T, 3>> const & t, geom::vector<T, 3> const & d)
triangular_prism<T>::triangular_prism(math::triangle<math::point<T, 3>> const & t, math::vector<T, 3> const & d)
{
for (std::size_t i = 0; i < 3; ++i)
{
@ -26,7 +26,7 @@ namespace psemek::cg
vertices[i + 3] = t[i] + d;
}
if (geom::dot(geom::normal(vertices[0], vertices[1], vertices[2]), d) < 0)
if (math::dot(math::normal(vertices[0], vertices[1], vertices[2]), d) < 0)
{
std::swap(vertices[1], vertices[2]);
std::swap(vertices[4], vertices[5]);
@ -34,9 +34,9 @@ namespace psemek::cg
for (std::size_t i = 0; i < 3; ++i)
{
edge_directions[i] = geom::normalized(vertices[(i + 1) % 3] - vertices[i]);
edge_directions[i] = math::normalized(vertices[(i + 1) % 3] - vertices[i]);
}
edge_directions[3] = geom::normalized(d);
edge_directions[3] = math::normalized(d);
}
template <typename T>
@ -48,7 +48,7 @@ namespace psemek::cg
template <typename T>
auto const & edges(triangular_prism<T> const &)
{
static const std::array<geom::segment<std::uint8_t>, 9> result =
static const std::array<math::segment<std::uint8_t>, 9> result =
{{
{ 0, 1 },
{ 1, 2 },
@ -90,14 +90,14 @@ namespace psemek::cg
struct irregular_triangular_prism
{
irregular_triangular_prism() = default;
irregular_triangular_prism(geom::triangle<geom::point<T, 3>> const & low_triangle, geom::triangle<geom::point<T, 3>> const & high_triangle);
irregular_triangular_prism(math::triangle<math::point<T, 3>> const & low_triangle, math::triangle<math::point<T, 3>> const & high_triangle);
std::array<geom::point<T, 3>, 6> vertices;
std::array<geom::vector<T, 3>, 9> edge_directions;
std::array<math::point<T, 3>, 6> vertices;
std::array<math::vector<T, 3>, 9> edge_directions;
};
template <typename T>
irregular_triangular_prism<T>::irregular_triangular_prism(geom::triangle<geom::point<T, 3>> const & low_triangle, geom::triangle<geom::point<T, 3>> const & high_triangle)
irregular_triangular_prism<T>::irregular_triangular_prism(math::triangle<math::point<T, 3>> const & low_triangle, math::triangle<math::point<T, 3>> const & high_triangle)
{
for (std::size_t i = 0; i < 3; ++i)
{
@ -107,9 +107,9 @@ namespace psemek::cg
for (std::size_t i = 0; i < 3; ++i)
{
edge_directions[i + 0] = geom::normalized(vertices[(i + 1) % 3] - vertices[i]);
edge_directions[i + 3] = geom::normalized(vertices[3 + ((i + 1) % 3)] - vertices[3 + i]);
edge_directions[i + 6] = geom::normalized(vertices[i + 3] - vertices[i]);
edge_directions[i + 0] = math::normalized(vertices[(i + 1) % 3] - vertices[i]);
edge_directions[i + 3] = math::normalized(vertices[3 + ((i + 1) % 3)] - vertices[3 + i]);
edge_directions[i + 6] = math::normalized(vertices[i + 3] - vertices[i]);
}
}

View file

@ -1,7 +1,7 @@
#pragma once
#include <psemek/cg/body/body.hpp>
#include <psemek/geom/simplex.hpp>
#include <psemek/math/simplex.hpp>
#include <vector>
#include <cstdint>
@ -12,16 +12,16 @@ namespace psemek::cg
struct triangle_mesh
{
triangle_mesh() = default;
triangle_mesh(std::vector<geom::point<T, 3>> vertices, std::vector<geom::triangle<Index>> triangles);
triangle_mesh(std::vector<math::point<T, 3>> vertices, std::vector<math::triangle<Index>> triangles);
std::vector<geom::point<T, 3>> vertices;
std::vector<geom::triangle<Index>> triangles;
std::vector<geom::segment<Index>> edges;
std::vector<geom::vector<T, 3>> edge_directions;
std::vector<math::point<T, 3>> vertices;
std::vector<math::triangle<Index>> triangles;
std::vector<math::segment<Index>> edges;
std::vector<math::vector<T, 3>> edge_directions;
};
template <typename T, typename Index>
triangle_mesh<T, Index>::triangle_mesh(std::vector<geom::point<T, 3>> vertices, std::vector<geom::triangle<Index>> triangles)
triangle_mesh<T, Index>::triangle_mesh(std::vector<math::point<T, 3>> vertices, std::vector<math::triangle<Index>> triangles)
: vertices(std::move(vertices))
, triangles(std::move(triangles))
{
@ -34,7 +34,7 @@ namespace psemek::cg
}
for (auto const & e : edges)
edge_directions.push_back(geom::normalized(this->vertices[e[1]] - this->vertices[e[0]]));
edge_directions.push_back(math::normalized(this->vertices[e[1]] - this->vertices[e[0]]));
}
template <typename T, typename Index>

View file

@ -1,7 +1,7 @@
#pragma once
#include <psemek/geom/vector.hpp>
#include <psemek/geom/point.hpp>
#include <psemek/math/vector.hpp>
#include <psemek/math/point.hpp>
#include <psemek/cg/dcel.hpp>
namespace psemek::cg
@ -9,7 +9,7 @@ namespace psemek::cg
// TODO: this was written for Voronoi and is known to fail in some cases
template <typename T, typename Edge, typename Face, typename Index>
void clip(dcel<geom::point<T, 2>, Edge, Face, Index> & dcel, geom::vector<T, 3> const & eq)
void clip(dcel<math::point<T, 2>, Edge, Face, Index> & dcel, math::vector<T, 3> const & eq)
{
auto outer_face = dcel.face(0);

View file

@ -1,8 +1,8 @@
#pragma once
#include <psemek/cg/body/body.hpp>
#include <psemek/geom/interval.hpp>
#include <psemek/geom/math.hpp>
#include <psemek/math/interval.hpp>
#include <psemek/math/math.hpp>
namespace psemek::cg
{
@ -11,32 +11,32 @@ namespace psemek::cg
{
template <typename Body, typename T>
T distance_fast_2d(Body const & b, geom::point<T, 2> const & p)
T distance_fast_2d(Body const & b, math::point<T, 2> const & p)
{
T result = geom::limits<T>::min();
T result = math::limits<T>::min();
auto const & vs = vertices(b);
for (auto const & e : edges(b))
{
auto n = geom::ort(geom::normalized(vs[e[0]] - vs[e[1]]));
geom::make_max(result, geom::dot(n, p - vs[e[0]]));
auto n = math::ort(math::normalized(vs[e[0]] - vs[e[1]]));
math::make_max(result, math::dot(n, p - vs[e[0]]));
}
return result;
}
template <typename Body, typename T>
T distance_fast_3d(Body const & b, geom::point<T, 3> const & p)
T distance_fast_3d(Body const & b, math::point<T, 3> const & p)
{
T result = geom::limits<T>::min();
T result = math::limits<T>::min();
auto const & vs = vertices(b);
for (auto const & f : faces(b))
{
auto n = geom::normal(vs[f[0]], vs[f[1]], vs[f[2]]);
geom::make_max(result, geom::dot(n, p - vs[f[0]]));
auto n = math::normal(vs[f[0]], vs[f[1]], vs[f[2]]);
math::make_max(result, math::dot(n, p - vs[f[0]]));
}
return result;

View file

@ -2,29 +2,29 @@
#include <psemek/cg/body/body.hpp>
#include <psemek/geom/orientation.hpp>
#include <psemek/math/orientation.hpp>
namespace psemek::cg
{
template <typename RobustTag, typename T, std::size_t N, typename Body>
bool inside(RobustTag robust_tag, geom::point<T, N> const & p, Body const & body)
bool inside(RobustTag robust_tag, math::point<T, N> const & p, Body const & body)
{
auto const & vs = vertices(body);
auto const & fs = faces(body);
for (auto const & f : fs)
{
if (geom::orientation(robust_tag, vs[f[0]], vs[f[1]], vs[f[2]], p) == geom::sign_t::negative)
if (math::orientation(robust_tag, vs[f[0]], vs[f[1]], vs[f[2]], p) == math::sign_t::negative)
return false;
}
return true;
}
template <typename T, std::size_t N, typename Body>
bool inside(geom::point<T, N> const & p, Body const & body)
bool inside(math::point<T, N> const & p, Body const & body)
{
return inside(geom::default_robust_tag, p, body);
return inside(math::default_robust_tag, p, body);
}
}

View file

@ -2,8 +2,8 @@
#include <psemek/cg/body/body.hpp>
#include <psemek/geom/interval.hpp>
#include <psemek/geom/homogeneous.hpp>
#include <psemek/math/interval.hpp>
#include <psemek/math/homogeneous.hpp>
namespace psemek::cg
{
@ -12,8 +12,8 @@ namespace psemek::cg
struct separation_info
{
T distance = -std::numeric_limits<T>::infinity();
geom::vector<T, N> direction = geom::vector<T, N>::zero();
geom::point<T, N> contact_point = geom::point<T, N>::zero();
math::vector<T, N> direction = math::vector<T, N>::zero();
math::point<T, N> contact_point = math::point<T, N>::zero();
int contact_point_body = 0;
separation_info & operator |= (separation_info const & i);
@ -57,13 +57,13 @@ namespace psemek::cg
for (auto const & e : es1)
{
result_type edge_result;
edge_result.direction = -geom::ort(geom::normalized(vs1[e[1]] - vs1[e[0]]));
edge_result.direction = -math::ort(math::normalized(vs1[e[1]] - vs1[e[0]]));
edge_result.distance = std::numeric_limits<scalar_type>::infinity();
for (auto const & v : vs2)
{
auto const d = geom::dot(geom::homogeneous(edge_result.direction), geom::homogeneous(v - vs1[e[0]]));
if (geom::make_min(edge_result.distance, d))
auto const d = math::dot(math::homogeneous(edge_result.direction), math::homogeneous(v - vs1[e[0]]));
if (math::make_min(edge_result.distance, d))
edge_result.contact_point = v;
}
@ -113,15 +113,15 @@ namespace psemek::cg
for (auto const & f : fs1)
{
result_type face_result;
face_result.direction = geom::normal(vs1[f[0]], vs1[f[1]], vs1[f[2]]);
face_result.direction = math::normal(vs1[f[0]], vs1[f[1]], vs1[f[2]]);
face_result.distance = std::numeric_limits<scalar_type>::infinity();
auto const face_p = vs1[f[0]];
for (auto const & v : vs2)
{
auto const d = geom::dot(face_result.direction, v - face_p);
if (geom::make_min(face_result.distance, d))
auto const d = math::dot(face_result.direction, v - face_p);
if (math::make_min(face_result.distance, d))
face_result.contact_point = v;
}
@ -145,21 +145,21 @@ namespace psemek::cg
for (auto const & ed2 : eds2)
{
result_type edge_result;
edge_result.direction = geom::cross(ed1, ed2);
auto l = geom::length(edge_result.direction);
edge_result.direction = math::cross(ed1, ed2);
auto l = math::length(edge_result.direction);
if (l == 0) continue;
edge_result.direction /= l;
geom::interval<scalar_type> i1, i2;
math::interval<scalar_type> i1, i2;
for (auto const & v : vs1)
{
i1 |= geom::dot(geom::homogeneous(v), geom::homogeneous(edge_result.direction));
i1 |= math::dot(math::homogeneous(v), math::homogeneous(edge_result.direction));
}
for (auto const & v : vs2)
{
i2 |= geom::dot(geom::homogeneous(v), geom::homogeneous(edge_result.direction));
i2 |= math::dot(math::homogeneous(v), math::homogeneous(edge_result.direction));
}
auto edge_d12 = i2.min - i1.max;
@ -194,7 +194,7 @@ namespace psemek::cg
return result;
auto edge_result = process_edges(vs1, eds1, vs2, eds2);
if (geom::make_max(result.distance, edge_result.distance))
if (math::make_max(result.distance, edge_result.distance))
{
result = edge_result;
@ -202,31 +202,31 @@ namespace psemek::cg
auto e2 = es2[0];
{
auto max_d = geom::limits<scalar_type>::min();
auto max_d = math::limits<scalar_type>::min();
for (auto const & e : es1)
{
auto d = geom::dot(geom::homogeneous(vs1[e[0]]), geom::homogeneous(result.direction)) + geom::dot(geom::homogeneous(vs1[e[1]]), geom::homogeneous(result.direction));
if (geom::make_max(max_d, d))
auto d = math::dot(math::homogeneous(vs1[e[0]]), math::homogeneous(result.direction)) + math::dot(math::homogeneous(vs1[e[1]]), math::homogeneous(result.direction));
if (math::make_max(max_d, d))
e1 = e;
}
}
{
auto min_d = geom::limits<scalar_type>::max();
auto min_d = math::limits<scalar_type>::max();
for (auto const & e : es2)
{
auto d = geom::dot(geom::homogeneous(vs2[e[0]]), geom::homogeneous(result.direction)) + geom::dot(geom::homogeneous(vs2[e[1]]), geom::homogeneous(result.direction));
if (geom::make_min(min_d, d))
auto d = math::dot(math::homogeneous(vs2[e[0]]), math::homogeneous(result.direction)) + math::dot(math::homogeneous(vs2[e[1]]), math::homogeneous(result.direction));
if (math::make_min(min_d, d))
e2 = e;
}
}
result.contact_point_body = 0;
auto m = geom::cross(result.direction, vs2[e2[1]] - vs2[e2[0]]);
auto v = geom::dot(geom::homogeneous(vs2[e2[0]]), geom::homogeneous(m));
auto t = (v - geom::dot(geom::homogeneous(vs1[e1[0]]), geom::homogeneous(m))) / geom::dot(geom::homogeneous(vs1[e1[1]] - vs1[e1[0]]), geom::homogeneous(m));
result.contact_point = geom::lerp(vs1[e1[0]], vs1[e1[1]], geom::clamp(t, geom::interval(scalar_type(0), scalar_type(1))));
auto m = math::cross(result.direction, vs2[e2[1]] - vs2[e2[0]]);
auto v = math::dot(math::homogeneous(vs2[e2[0]]), math::homogeneous(m));
auto t = (v - math::dot(math::homogeneous(vs1[e1[0]]), math::homogeneous(m))) / math::dot(math::homogeneous(vs1[e1[1]] - vs1[e1[0]]), math::homogeneous(m));
result.contact_point = math::lerp(vs1[e1[0]], vs1[e1[1]], math::clamp(t, math::interval(scalar_type(0), scalar_type(1))));
}
return result;

View file

@ -1,6 +1,6 @@
#pragma once
#include <psemek/geom/orientation.hpp>
#include <psemek/math/orientation.hpp>
#include <algorithm>
#include <numeric>
@ -25,7 +25,7 @@ namespace psemek::cg
// find lower half of the hull
for (auto it = its.begin() + 1; it != its.end(); ++it)
{
while (hull.size() >= 2 && orientation(robust_tag, **(hull.end() - 2), **(hull.end() - 1), **it) != geom::sign_t::positive)
while (hull.size() >= 2 && orientation(robust_tag, **(hull.end() - 2), **(hull.end() - 1), **it) != math::sign_t::positive)
hull.pop_back();
hull.push_back(*it);
@ -37,7 +37,7 @@ namespace psemek::cg
if (*it == *(hull.end() - 2))
continue;
while (hull.size() >= 2 && orientation(robust_tag, **(hull.end() - 2), **(hull.end() - 1), **it) != geom::sign_t::positive)
while (hull.size() >= 2 && orientation(robust_tag, **(hull.end() - 2), **(hull.end() - 1), **it) != math::sign_t::positive)
hull.pop_back();
hull.push_back(*it);
@ -53,7 +53,7 @@ namespace psemek::cg
template <typename InIterator, typename OutIterator>
OutIterator andrew_convex_hull(InIterator begin, InIterator end, OutIterator out)
{
return andrew_convex_hull(geom::default_robust_tag, begin, end, out);
return andrew_convex_hull(math::default_robust_tag, begin, end, out);
}
}

View file

@ -1,6 +1,6 @@
#pragma once
#include <psemek/geom/orientation.hpp>
#include <psemek/math/orientation.hpp>
#include <algorithm>
#include <numeric>
@ -27,9 +27,9 @@ namespace psemek::cg
auto o = orientation(robust_tag, *its.front(), *i1, *i2);
// carefully deal with parallel points
if (o == geom::sign_t::positive)
if (o == math::sign_t::positive)
return true;
else if (o == geom::sign_t::negative)
else if (o == math::sign_t::negative)
return false;
return *i1 < *i2;
@ -41,7 +41,7 @@ namespace psemek::cg
for (auto it = its.begin() + 1; it != its.end(); ++it)
{
while (hull_end - its.begin() >= 2 && orientation(robust_tag, **(hull_end - 2), **(hull_end - 1), **it) != geom::sign_t::positive)
while (hull_end - its.begin() >= 2 && orientation(robust_tag, **(hull_end - 2), **(hull_end - 1), **it) != math::sign_t::positive)
--hull_end;
*hull_end++ = *it;
@ -54,7 +54,7 @@ namespace psemek::cg
template <typename InIterator, typename OutIterator>
OutIterator graham_convex_hull(InIterator begin, InIterator end, OutIterator out)
{
return graham_convex_hull(geom::default_robust_tag, begin, end, out);
return graham_convex_hull(math::default_robust_tag, begin, end, out);
}
}

View file

@ -1,6 +1,6 @@
#pragma once
#include <psemek/geom/orientation.hpp>
#include <psemek/math/orientation.hpp>
namespace psemek::cg
{
@ -26,7 +26,7 @@ namespace psemek::cg
if (jt == it) continue;
if (jt == last_hull_point) continue;
if (orientation(robust_tag, *last_hull_point, *it, *jt) != geom::sign_t::positive)
if (orientation(robust_tag, *last_hull_point, *it, *jt) != math::sign_t::positive)
{
is_hull_edge = false;
break;
@ -51,7 +51,7 @@ namespace psemek::cg
template <typename InIterator, typename OutIterator>
OutIterator jarvis_convex_hull(InIterator begin, InIterator end, OutIterator out)
{
return jarvis_convex_hull(geom::default_robust_tag, begin, end, out);
return jarvis_convex_hull(math::default_robust_tag, begin, end, out);
}
}

View file

@ -1,6 +1,6 @@
#pragma once
#include <psemek/geom/orientation.hpp>
#include <psemek/math/orientation.hpp>
#include <algorithm>
#include <numeric>
@ -21,11 +21,11 @@ namespace psemek::cg
// find point in [begin, end) furthest from segment (p1,p2)
auto mid = *std::max_element(begin, end, [&](auto it1, auto it2){
// TODO: design a robust predicate
return orientation(robust_tag, *it2, (*it2) + ((*p2) - (*p1)), *it1) == geom::sign_t::positive;
return orientation(robust_tag, *it2, (*it2) + ((*p2) - (*p1)), *it1) == math::sign_t::positive;
});
auto end1 = std::partition(begin, end, [&](auto it){ return orientation(robust_tag, *p1, *it, *mid) == geom::sign_t::positive; });
auto end2 = std::partition(end1, end, [&](auto it){ return orientation(robust_tag, *mid, *it, *p2) == geom::sign_t::positive; });
auto end1 = std::partition(begin, end, [&](auto it){ return orientation(robust_tag, *p1, *it, *mid) == math::sign_t::positive; });
auto end2 = std::partition(end1, end, [&](auto it){ return orientation(robust_tag, *mid, *it, *p2) == math::sign_t::positive; });
out = quick_hull_recursive_helper(robust_tag, p1, mid, begin, end1, out);
out = quick_hull_recursive_helper(robust_tag, mid, p2, end1, end2, out);
@ -52,7 +52,7 @@ namespace psemek::cg
{
auto p = std::find_if(its.begin() + 1, its.end(), [&](auto it){
return std::all_of(its.begin() + 1, its.end(), [&](auto jt){
return it == jt || orientation(robust_tag, *its.front(), *it, *jt) == geom::sign_t::negative;
return it == jt || orientation(robust_tag, *its.front(), *it, *jt) == math::sign_t::negative;
});
});
std::iter_swap(its.begin() + 1, p);
@ -67,7 +67,7 @@ namespace psemek::cg
template <typename InIterator, typename OutIterator>
OutIterator quick_hull(InIterator begin, InIterator end, OutIterator out)
{
return quick_hull(geom::default_robust_tag, begin, end, out);
return quick_hull(math::default_robust_tag, begin, end, out);
}
}

View file

@ -1,10 +1,10 @@
#pragma once
#include <psemek/geom/vector.hpp>
#include <psemek/geom/point.hpp>
#include <psemek/geom/orientation.hpp>
#include <psemek/geom/simplex.hpp>
#include <psemek/geom/math.hpp>
#include <psemek/math/vector.hpp>
#include <psemek/math/point.hpp>
#include <psemek/math/orientation.hpp>
#include <psemek/math/simplex.hpp>
#include <psemek/math/math.hpp>
#include <vector>
#include <list>
@ -16,15 +16,15 @@ namespace psemek::cg
{
template <typename RobustTag, typename T, typename Index = std::size_t>
std::vector<geom::triangle<Index>> quickhull(RobustTag robust_tag, std::vector<geom::point<T, 3ul>> const & points)
std::vector<math::triangle<Index>> quickhull(RobustTag robust_tag, std::vector<math::point<T, 3ul>> const & points)
{
struct face;
using handle = typename std::list<face>::iterator;
using edge = geom::segment<Index>;
using triangle = geom::triangle<Index>;
using edge = math::segment<Index>;
using triangle = math::triangle<Index>;
using point = geom::point<T, 3ul>;
using point = math::point<T, 3ul>;
struct face
{
@ -52,10 +52,10 @@ namespace psemek::cg
return distance(points[i0], p1) < distance(points[i0], p2);
}) - points.begin();
auto n01 = geom::normalized(points[i1] - points[i0]);
auto n01 = math::normalized(points[i1] - points[i0]);
auto dist01 = [&](point const & p){
auto l = p - points[i0];
return geom::length_sqr(l) - geom::sqr(geom::dot(l, n01));
return math::length_sqr(l) - math::sqr(math::dot(l, n01));
};
// furthest from i0-i1 line
@ -64,7 +64,7 @@ namespace psemek::cg
}) - points.begin();
auto dist012 = [&](point const & p){
return std::abs(geom::volume(p, points[i0], points[i1], points[i2]));
return std::abs(math::volume(p, points[i0], points[i1], points[i2]));
};
// highest 'z'
@ -72,7 +72,7 @@ namespace psemek::cg
return dist012(p1) < dist012(p2);
}) - points.begin();
if (geom::orientation(robust_tag, points[i0], points[i1], points[i2], points[i3]) == geom::sign_t::negative)
if (math::orientation(robust_tag, points[i0], points[i1], points[i2], points[i3]) == math::sign_t::negative)
std::swap(i2, i3);
triangle t0 { i0, i1, i2 };
@ -89,13 +89,13 @@ namespace psemek::cg
if (i == i2) continue;
if (i == i3) continue;
if (geom::orientation(robust_tag, points[t0[0]], points[t0[1]], points[t0[2]], points[i]) == geom::sign_t::negative)
if (math::orientation(robust_tag, points[t0[0]], points[t0[1]], points[t0[2]], points[i]) == math::sign_t::negative)
out0.push_back(i);
else if (geom::orientation(robust_tag, points[t1[0]], points[t1[1]], points[t1[2]], points[i]) == geom::sign_t::negative)
else if (math::orientation(robust_tag, points[t1[0]], points[t1[1]], points[t1[2]], points[i]) == math::sign_t::negative)
out1.push_back(i);
else if (geom::orientation(robust_tag, points[t2[0]], points[t2[1]], points[t2[2]], points[i]) == geom::sign_t::negative)
else if (math::orientation(robust_tag, points[t2[0]], points[t2[1]], points[t2[2]], points[i]) == math::sign_t::negative)
out2.push_back(i);
else if (geom::orientation(robust_tag, points[t3[0]], points[t3[1]], points[t3[2]], points[i]) == geom::sign_t::negative)
else if (math::orientation(robust_tag, points[t3[0]], points[t3[1]], points[t3[2]], points[i]) == math::sign_t::negative)
out3.push_back(i);
}
@ -146,7 +146,7 @@ namespace psemek::cg
for (auto i : out_set)
{
float const d = geom::volume(points[t[0]], points[t[1]], points[t[2]], points[i]);
float const d = math::volume(points[t[0]], points[t[1]], points[t[2]], points[i]);
if (d < dist)
{
@ -171,7 +171,7 @@ namespace psemek::cg
{
handle it = h->neigh[i];
triangle const & t = it->tri;
if (it->valid && (geom::orientation(robust_tag, points[t[0]], points[t[1]], points[t[2]], points[max_i]) == geom::sign_t::negative))
if (it->valid && (math::orientation(robust_tag, points[t[0]], points[t[1]], points[t[2]], points[max_i]) == math::sign_t::negative))
{
it->valid = false;
visible_queue.push(it);
@ -222,7 +222,7 @@ namespace psemek::cg
triangle const t { h->tri[(i+1)%3], h->tri[i], max_i };
auto it = std::partition(unassigned.begin(), unassigned_end, [&](Index i){
return geom::orientation(robust_tag, points[t[0]], points[t[1]], points[t[2]], points[i]) == geom::sign_t::positive;
return math::orientation(robust_tag, points[t[0]], points[t[1]], points[t[2]], points[i]) == math::sign_t::positive;
});
std::vector<Index> out_set(it, unassigned_end);
@ -253,9 +253,9 @@ namespace psemek::cg
}
template <typename T, typename Index = std::size_t>
auto quickhull(std::vector<geom::point<T, 3ul>> const & points)
auto quickhull(std::vector<math::point<T, 3ul>> const & points)
{
return quickhull(geom::default_robust_tag, points);
return quickhull(math::default_robust_tag, points);
}
}

View file

@ -2,7 +2,7 @@
#include <psemek/util/empty.hpp>
#include <psemek/util/ebo.hpp>
#include <psemek/geom/simplex.hpp>
#include <psemek/math/simplex.hpp>
#include <cstddef>
#include <vector>
@ -661,7 +661,7 @@ namespace psemek::cg
auto h = dcel.edge(e);
*out++ = geom::segment<Index>{h.origin().index(), h.twin().origin().index()};
*out++ = math::segment<Index>{h.origin().index(), h.twin().origin().index()};
}
return out;
}
@ -669,7 +669,7 @@ namespace psemek::cg
template <typename Point, typename Edge, typename Face, typename Index>
auto edge_mesh(dcel<Point, Edge, Face, Index> const & dcel)
{
std::vector<geom::segment<Index>> result;
std::vector<math::segment<Index>> result;
edge_mesh(dcel, std::back_inserter(result));
return result;
}
@ -681,7 +681,7 @@ namespace psemek::cg
{
auto h = dcel.face(f).edge();
geom::triangle<Index> t;
math::triangle<Index> t;
t[0] = h.origin().index(); h = h.next();
t[1] = h.origin().index(); h = h.next();
t[2] = h.origin().index();
@ -694,7 +694,7 @@ namespace psemek::cg
template <typename Point, typename Edge, typename Face, typename Index>
auto triangle_mesh(dcel<Point, Edge, Face, Index> const & dcel)
{
std::vector<geom::triangle<Index>> result;
std::vector<math::triangle<Index>> result;
triangle_mesh(dcel, std::back_inserter(result));
return result;
}

View file

@ -1,8 +1,8 @@
#pragma once
#include <psemek/geom/point.hpp>
#include <psemek/geom/box.hpp>
#include <psemek/geom/contains.hpp>
#include <psemek/math/point.hpp>
#include <psemek/math/box.hpp>
#include <psemek/math/contains.hpp>
#include <memory>
#include <optional>
@ -23,8 +23,8 @@ namespace psemek::cg
struct ndtree
{
public:
using point_type = geom::point<T, N>;
using box_type = geom::box<T, N>;
using point_type = math::point<T, N>;
using box_type = math::box<T, N>;
struct value_type
{
@ -82,9 +82,9 @@ namespace psemek::cg
return {root.get(), true};
}
if (!geom::half_open_contains(root_bbox, point))
if (!math::half_open_contains(root_bbox, point))
{
while (!geom::half_open_contains(root_bbox, point))
while (!math::half_open_contains(root_bbox, point))
extend_root(point);
}
@ -158,7 +158,7 @@ namespace psemek::cg
private:
node_ptr root;
geom::box<T, N> root_bbox;
math::box<T, N> root_bbox;
void extend_root(point_type const & point)
{

View file

@ -1,6 +1,6 @@
#pragma once
#include <psemek/geom/intersection.hpp>
#include <psemek/math/intersection.hpp>
#include <cstddef>
#include <algorithm>

View file

@ -1,6 +1,6 @@
#pragma once
#include <psemek/geom/incircle.hpp>
#include <psemek/math/incircle.hpp>
#include <psemek/cg/triangulation/triangulation.hpp>
#include <queue>
@ -62,7 +62,7 @@ namespace psemek::cg
auto p3 = e.twin().next().next().origin();
// decide if a flip is needed
if (in_circle(robust_tag, at(p0.index()), at(p1.index()), at(p2.index()), at(p3.index())) != geom::sign_t::positive) continue;
if (in_circle(robust_tag, at(p0.index()), at(p1.index()), at(p2.index()), at(p3.index())) != math::sign_t::positive) continue;
flipped_set.insert(std::lower_bound(flipped_set.begin(), flipped_set.end(), e.index()), e.index());
@ -113,7 +113,7 @@ namespace psemek::cg
template <typename Index = std::size_t, typename InputIterator>
auto delaunay(InputIterator begin, InputIterator end)
{
return delaunay<Index>(geom::default_robust_tag, begin, end);
return delaunay<Index>(math::default_robust_tag, begin, end);
}
}

View file

@ -1,8 +1,8 @@
#pragma once
#include <psemek/geom/point.hpp>
#include <psemek/geom/orientation.hpp>
#include <psemek/geom/contains.hpp>
#include <psemek/math/point.hpp>
#include <psemek/math/orientation.hpp>
#include <psemek/math/contains.hpp>
#include <psemek/cg/dcel.hpp>
#include <vector>
@ -50,9 +50,9 @@ namespace psemek::cg
auto inside = [robust_tag](auto const & t, auto const & p)
{
return true
&& geom::orientation(robust_tag, t[0], t[1], p) == geom::sign_t::positive
&& geom::orientation(robust_tag, t[1], t[2], p) == geom::sign_t::positive
&& geom::orientation(robust_tag, t[2], t[0], p) == geom::sign_t::positive
&& math::orientation(robust_tag, t[0], t[1], p) == math::sign_t::positive
&& math::orientation(robust_tag, t[1], t[2], p) == math::sign_t::positive
&& math::orientation(robust_tag, t[2], t[0], p) == math::sign_t::positive
;
};
@ -66,9 +66,9 @@ namespace psemek::cg
auto next = edge.next();
auto nnext = next.next();
geom::simplex triangle{at(edge.origin().index()), at(next.origin().index()), at(nnext.origin().index())};
math::simplex triangle{at(edge.origin().index()), at(next.origin().index()), at(nnext.origin().index())};
if (geom::orientation(robust_tag, triangle[0], triangle[1], triangle[2]) == geom::sign_t::negative)
if (math::orientation(robust_tag, triangle[0], triangle[1], triangle[2]) == math::sign_t::negative)
continue;
for (auto k = nnext.next(); k != edge; k = k.next())
@ -119,7 +119,7 @@ namespace psemek::cg
template <typename IndexType = std::size_t, typename Iterator>
auto ear_clipping(Iterator begin, Iterator end)
{
return ear_clipping<IndexType>(geom::default_robust_tag, begin, end);
return ear_clipping<IndexType>(math::default_robust_tag, begin, end);
}
}

View file

@ -1,8 +1,8 @@
#pragma once
#include <psemek/geom/point.hpp>
#include <psemek/geom/orientation.hpp>
#include <psemek/geom/contains.hpp>
#include <psemek/math/point.hpp>
#include <psemek/math/orientation.hpp>
#include <psemek/math/contains.hpp>
#include <psemek/cg/dcel.hpp>
#include <vector>
@ -67,23 +67,23 @@ namespace psemek::cg
auto const j0 = at(j);
auto const j1 = at((j + 1) % count);
auto const oi0 = geom::orientation(RobustTag{}, i0, i1, j0);
auto const oi1 = geom::orientation(RobustTag{}, i0, i1, j1);
auto const oi0 = math::orientation(RobustTag{}, i0, i1, j0);
auto const oi1 = math::orientation(RobustTag{}, i0, i1, j1);
if (oi0 == oi1)
return oi0 == geom::sign_t::positive;
return oi0 == math::sign_t::positive;
return geom::orientation(RobustTag{}, j0, j1, i0) == geom::sign_t::negative;
return math::orientation(RobustTag{}, j0, j1, i0) == math::sign_t::negative;
}
bool operator()(IndexType e, point_handle v) const
{
return geom::orientation(RobustTag{}, at(e), at((e + 1) % count), at(v.index())) == geom::sign_t::positive;
return math::orientation(RobustTag{}, at(e), at((e + 1) % count), at(v.index())) == math::sign_t::positive;
}
bool operator()(point_handle v, IndexType e) const
{
return geom::orientation(RobustTag{}, at(e), at((e + 1) % count), at(v.index())) == geom::sign_t::negative;
return math::orientation(RobustTag{}, at(e), at((e + 1) % count), at(v.index())) == math::sign_t::negative;
}
};
@ -115,15 +115,15 @@ namespace psemek::cg
bool lp = at(p) < at(e);
bool ln = at(n) < at(e);
auto s = geom::orientation(robust_tag, at(p), at(e), at(n));
auto s = math::orientation(robust_tag, at(p), at(e), at(n));
if (!lp && !ln && s == geom::sign_t::positive)
if (!lp && !ln && s == math::sign_t::positive)
return event_type::start;
else if (lp && ln && s == geom::sign_t::positive)
else if (lp && ln && s == math::sign_t::positive)
return event_type::end;
else if (!lp && !ln && s == geom::sign_t::negative)
else if (!lp && !ln && s == math::sign_t::negative)
return event_type::split;
else if (lp && ln && s == geom::sign_t::negative)
else if (lp && ln && s == math::sign_t::negative)
return event_type::merge;
else
return event_type::regular;
@ -140,10 +140,10 @@ namespace psemek::cg
auto f = at(ni.next().origin().index());
auto p = at(ni.prev().origin().index());
bool contains;
if (geom::orientation(robust_tag, f, vi, p) == geom::sign_t::negative)
contains = geom::orientation(robust_tag, f, vi, vj) == geom::sign_t::negative && geom::orientation(robust_tag, vj, vi, p) == geom::sign_t::negative;
if (math::orientation(robust_tag, f, vi, p) == math::sign_t::negative)
contains = math::orientation(robust_tag, f, vi, vj) == math::sign_t::negative && math::orientation(robust_tag, vj, vi, p) == math::sign_t::negative;
else
contains = geom::orientation(robust_tag, f, vi, vj) == geom::sign_t::negative || geom::orientation(robust_tag, vj, vi, p) == geom::sign_t::negative;
contains = math::orientation(robust_tag, f, vi, vj) == math::sign_t::negative || math::orientation(robust_tag, vj, vi, p) == math::sign_t::negative;
if (contains)
break;
ni = ni.prev().twin();
@ -156,10 +156,10 @@ namespace psemek::cg
auto f = at(nj.next().origin().index());
auto p = at(nj.prev().origin().index());
bool contains;
if (geom::orientation(robust_tag, f, vj, p) == geom::sign_t::negative)
contains = geom::orientation(robust_tag, f, vj, vi) == geom::sign_t::negative && geom::orientation(robust_tag, vi, vj, p) == geom::sign_t::negative;
if (math::orientation(robust_tag, f, vj, p) == math::sign_t::negative)
contains = math::orientation(robust_tag, f, vj, vi) == math::sign_t::negative && math::orientation(robust_tag, vi, vj, p) == math::sign_t::negative;
else
contains = geom::orientation(robust_tag, f, vj, vi) == geom::sign_t::negative || geom::orientation(robust_tag, vi, vj, p) == geom::sign_t::negative;
contains = math::orientation(robust_tag, f, vj, vi) == math::sign_t::negative || math::orientation(robust_tag, vi, vj, p) == math::sign_t::negative;
if (contains)
break;
nj = nj.prev().twin();
@ -317,12 +317,12 @@ namespace psemek::cg
auto orientation = [&](auto e0, auto e1, auto e2)
{
auto point = [&](auto e){ return at(result.edge(e).origin().index()); };
return geom::orientation(robust_tag, point(e0), point(e1), point(e2));
return math::orientation(robust_tag, point(e0), point(e1), point(e2));
};
if (left && stack_left)
{
while (stack.size() >= 2 && orientation(ve.index(), stack.back(), stack[stack.size() - 2]) == geom::sign_t::negative)
while (stack.size() >= 2 && orientation(ve.index(), stack.back(), stack[stack.size() - 2]) == math::sign_t::negative)
{
auto new_edge = emit_triangle(stack[stack.size() - 2], stack.back());
stack.pop_back();
@ -334,7 +334,7 @@ namespace psemek::cg
else if (!left && !stack_left)
{
auto e = ve.index();
while (stack.size() >= 2 && orientation(ve.index(), stack.back(), stack[stack.size() - 2]) == geom::sign_t::positive)
while (stack.size() >= 2 && orientation(ve.index(), stack.back(), stack[stack.size() - 2]) == math::sign_t::positive)
{
e = emit_triangle(e, stack.back());
stack.pop_back();
@ -389,7 +389,7 @@ namespace psemek::cg
template <typename IndexType, typename Iterator>
auto monotone_triangulation(Iterator begin, Iterator end)
{
return monotone_triangulation<IndexType>(geom::default_robust_tag, begin, end);
return monotone_triangulation<IndexType>(math::default_robust_tag, begin, end);
}
}

View file

@ -1,7 +1,7 @@
#pragma once
#include <psemek/util/functional.hpp>
#include <psemek/geom/orientation.hpp>
#include <psemek/math/orientation.hpp>
#include <psemek/cg/dcel.hpp>
#include <algorithm>
@ -100,7 +100,7 @@ namespace psemek::cg
bool degenerate = false;
// find first hull edge visible from new point
while (orientation(robust_tag, at(*it), at(hp0.index()), at(hp1.index())) != geom::sign_t::positive)
while (orientation(robust_tag, at(*it), at(hp0.index()), at(hp1.index())) != math::sign_t::positive)
{
move_hull_edge();
if (cur_hull_edge == hull_start)
@ -183,7 +183,7 @@ namespace psemek::cg
}
// until current edge is visible
while (orientation(robust_tag, at(*it), at(hp0.index()), at(hp1.index())) == geom::sign_t::positive)
while (orientation(robust_tag, at(*it), at(hp0.index()), at(hp1.index())) == math::sign_t::positive)
{
// fill new triangle
@ -253,7 +253,7 @@ namespace psemek::cg
template <typename Index = std::size_t, typename InputIterator>
auto triangulate(InputIterator begin, InputIterator end)
{
return triangulate<Index>(geom::default_robust_tag, begin, end);
return triangulate<Index>(math::default_robust_tag, begin, end);
}
}

View file

@ -1,6 +1,6 @@
#pragma once
#include <psemek/geom/gauss.hpp>
#include <psemek/math/gauss.hpp>
#include <psemek/cg/triangulation/delaunay.hpp>
#include <psemek/cg/dual.hpp>
#include <psemek/cg/bbox.hpp>
@ -35,8 +35,8 @@ namespace psemek::cg
using T = typename point_type::scalar_type;
geom::matrix<T, 3, 3> m;
geom::vector<T, 3> b;
math::matrix<T, 3, 3> m;
math::vector<T, 3> b;
for (std::size_t i = 0; i < 3; ++i)
{
@ -47,7 +47,7 @@ namespace psemek::cg
b[i] = q[i][0] * q[i][0] + q[i][1] * q[i][1];
}
geom::gauss(m, b);
math::gauss(m, b);
auto newp = result.push_point(point_type{b[0] / 2, b[1] / 2});
newp.edge(result.edge(p.edge().index()));

View file

@ -10,7 +10,7 @@ endif()
psemek_add_library(psemek-fonts ${PSEMEK_FONTS_HEADERS} ${PSEMEK_FONTS_SOURCES})
target_include_directories(psemek-fonts PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ${FREETYPE_INCLUDE_DIRS})
target_link_libraries(psemek-fonts PUBLIC psemek-util psemek-geom psemek-gfx rapidjson ${FREETYPE_LIBRARY})
target_link_libraries(psemek-fonts PUBLIC psemek-util psemek-math psemek-gfx rapidjson ${FREETYPE_LIBRARY})
if(PSEMEK_GRAPHICS_API STREQUAL WEBGPU)
target_link_libraries(psemek-fonts PUBLIC psemek-wgpu)
endif()

View file

@ -1,6 +1,6 @@
#pragma once
#include <psemek/geom/vector.hpp>
#include <psemek/math/vector.hpp>
#include <psemek/util/hash_table.hpp>
#include <psemek/io/stream.hpp>
@ -23,7 +23,7 @@ namespace psemek::fonts
};
std::string name;
geom::vector<int, 2> size;
math::vector<int, 2> size;
int baseline;
util::hash_map<char32_t, glyph_data> glyphs;
float sdf_scale = 0.f;

View file

@ -1,7 +1,7 @@
#pragma once
#include <psemek/geom/vector.hpp>
#include <psemek/geom/box.hpp>
#include <psemek/math/vector.hpp>
#include <psemek/math/box.hpp>
#include <psemek/util/span.hpp>
#include <psemek/gfx/texture.hpp>
@ -28,7 +28,7 @@ namespace psemek::fonts
struct glyph
{
geom::box<float, 2> position;
math::box<float, 2> position;
char32_t character;
};
@ -53,25 +53,25 @@ namespace psemek::fonts
virtual std::string_view name() const = 0;
virtual geom::vector<int, 2> size() const = 0;
virtual math::vector<int, 2> size() const = 0;
virtual int baseline() const { return 0; }
virtual bool supports_character(char32_t c) const = 0;
virtual util::span<character_range const> supported_characters() const = 0;
virtual std::vector<glyph> shape(std::string_view str, shape_options const & options, geom::point<float, 2> & pen) const = 0;
virtual std::vector<glyph> shape(std::u32string_view str, shape_options const & options, geom::point<float, 2> & pen) const = 0;
virtual std::vector<glyph> shape(std::string_view str, shape_options const & options, math::point<float, 2> & pen) const = 0;
virtual std::vector<glyph> shape(std::u32string_view str, shape_options const & options, math::point<float, 2> & pen) const = 0;
virtual std::vector<glyph> shape(std::string_view str, shape_options const & options) const
{
geom::point<float, 2> pen{0.f, 0.f};
math::point<float, 2> pen{0.f, 0.f};
return shape(str, options, pen);
}
virtual std::vector<glyph> shape(std::u32string_view str, shape_options const & options) const
{
geom::point<float, 2> pen{0.f, 0.f};
math::point<float, 2> pen{0.f, 0.f};
return shape(str, options, pen);
}
@ -79,7 +79,7 @@ namespace psemek::fonts
virtual float sdf_scale() const { return 0.f; }
virtual std::optional<geom::box<float, 2>> texcoords(char32_t character) const = 0;
virtual std::optional<math::box<float, 2>> texcoords(char32_t character) const = 0;
virtual ~font() {}
};

View file

@ -1,7 +1,7 @@
#pragma once
#include <psemek/geom/vector.hpp>
#include <psemek/geom/box.hpp>
#include <psemek/math/vector.hpp>
#include <psemek/math/box.hpp>
#include <psemek/util/span.hpp>
#if defined(PSEMEK_GRAPHICS_API_OPENGL)
@ -37,8 +37,8 @@ namespace psemek::fonts
struct shaped_glyph
{
texture_type const * texture;
geom::box<float, 2> position;
geom::box<float, 2> texcoords;
math::box<float, 2> position;
math::box<float, 2> texcoords;
};
struct shape_options
@ -60,21 +60,21 @@ namespace psemek::fonts
virtual std::string_view name() const = 0;
virtual geom::vector<int, 2> size() const = 0;
virtual math::vector<int, 2> size() const = 0;
virtual int xheight() const = 0;
virtual std::vector<shaped_glyph> const & shape(std::string_view str, shape_options const & options, geom::point<float, 2> & pen) = 0;
virtual std::vector<shaped_glyph> const & shape(std::u32string_view str, shape_options const & options, geom::point<float, 2> & pen) = 0;
virtual std::vector<shaped_glyph> const & shape(std::string_view str, shape_options const & options, math::point<float, 2> & pen) = 0;
virtual std::vector<shaped_glyph> const & shape(std::u32string_view str, shape_options const & options, math::point<float, 2> & pen) = 0;
virtual std::vector<shaped_glyph> const & shape(std::string_view str, shape_options const & options)
{
geom::point<float, 2> pen{0.f, 0.f};
math::point<float, 2> pen{0.f, 0.f};
return shape(str, options, pen);
}
virtual std::vector<shaped_glyph> const & shape(std::u32string_view str, shape_options const & options)
{
geom::point<float, 2> pen{0.f, 0.f};
math::point<float, 2> pen{0.f, 0.f};
return shape(str, options, pen);
}

View file

@ -15,19 +15,19 @@ namespace psemek::fonts
std::string_view name() const override { return data_.name; }
geom::vector<int, 2> size() const override { return data_.size; }
math::vector<int, 2> size() const override { return data_.size; }
int baseline() const override { return data_.baseline; }
bool supports_character(char32_t c) const override;
util::span<character_range const> supported_characters() const override { return ranges_; }
std::vector<glyph> shape(std::string_view str, shape_options const & options, geom::point<float, 2> & pen) const override;
std::vector<glyph> shape(std::u32string_view str, shape_options const & options, geom::point<float, 2> & pen) const override;
std::vector<glyph> shape(std::string_view str, shape_options const & options, math::point<float, 2> & pen) const override;
std::vector<glyph> shape(std::u32string_view str, shape_options const & options, math::point<float, 2> & pen) const override;
gfx::texture_2d const & atlas() const override { return atlas_; };
std::optional<geom::box<float, 2>> texcoords(char32_t character) const override;
std::optional<math::box<float, 2>> texcoords(char32_t character) const override;
protected:
std::vector<character_range> ranges_;
@ -35,7 +35,7 @@ namespace psemek::fonts
gfx::texture_2d atlas_;
template <typename String>
std::vector<glyph> shape_impl(String const & str, shape_options const & options, geom::point<float, 2> & pen) const;
std::vector<glyph> shape_impl(String const & str, shape_options const & options, math::point<float, 2> & pen) const;
};
}

View file

@ -8,33 +8,33 @@ namespace psemek::fonts
struct monospace_font
: font
{
monospace_font(character_range range, std::string_view name, geom::vector<int, 2> size, gfx::texture_2d atlas, std::vector<geom::box<float, 2>> texcoords);
monospace_font(character_range range, std::string_view name, math::vector<int, 2> size, gfx::texture_2d atlas, std::vector<math::box<float, 2>> texcoords);
font_type type() const override { return font_type::bitmap; }
std::string_view name() const override { return name_; }
geom::vector<int, 2> size() const override { return size_; }
math::vector<int, 2> size() const override { return size_; }
bool supports_character(char32_t c) const override;
util::span<character_range const> supported_characters() const override { return {&range_, &range_ + 1}; }
std::vector<glyph> shape(std::string_view str, shape_options const & options, geom::point<float, 2> & pen) const override;
std::vector<glyph> shape(std::u32string_view str, shape_options const & options, geom::point<float, 2> & pen) const override;
std::vector<glyph> shape(std::string_view str, shape_options const & options, math::point<float, 2> & pen) const override;
std::vector<glyph> shape(std::u32string_view str, shape_options const & options, math::point<float, 2> & pen) const override;
gfx::texture_2d const & atlas() const override { return atlas_; };
std::optional<geom::box<float, 2>> texcoords(char32_t character) const override;
std::optional<math::box<float, 2>> texcoords(char32_t character) const override;
private:
character_range range_;
std::string_view name_;
geom::vector<int, 2> size_;
math::vector<int, 2> size_;
gfx::texture_2d atlas_;
std::vector<geom::box<float, 2>> texcoords_;
std::vector<math::box<float, 2>> texcoords_;
template <typename String>
std::vector<glyph> shape_impl(String const & str, shape_options const & options, geom::point<float, 2> & pen) const;
std::vector<glyph> shape_impl(String const & str, shape_options const & options, math::point<float, 2> & pen) const;
};
}

View file

@ -103,7 +103,7 @@ namespace psemek::fonts
return FT_Get_Postscript_Name(state_->face);
}
geom::vector<int, 2> size() const override
math::vector<int, 2> size() const override
{
return {size_, size_};
}
@ -113,12 +113,12 @@ namespace psemek::fonts
return xheight_;
}
std::vector<shaped_glyph> const & shape(std::string_view str, shape_options const & options, geom::point<float, 2> & pen) override
std::vector<shaped_glyph> const & shape(std::string_view str, shape_options const & options, math::point<float, 2> & pen) override
{
return shape_impl(util::utf8_range(str), options, pen);
}
std::vector<shaped_glyph> const & shape(std::u32string_view str, shape_options const & options, geom::point<float, 2> & pen) override
std::vector<shaped_glyph> const & shape(std::u32string_view str, shape_options const & options, math::point<float, 2> & pen) override
{
return shape_impl(str, options, pen);
}
@ -150,9 +150,9 @@ namespace psemek::fonts
struct glyph_data
{
int page;
geom::box<int, 2> part;
geom::vector<int, 2> offset;
geom::vector<int, 2> advance;
math::box<int, 2> part;
math::vector<int, 2> offset;
math::vector<int, 2> advance;
};
util::hash_map<char32_t, std::uint32_t> glyph_mapping_;
@ -161,7 +161,7 @@ namespace psemek::fonts
std::vector<shaped_glyph> shaped_text_;
template <typename String>
std::vector<shaped_glyph> const & shape_impl(String const & string, shape_options const & options, geom::point<float, 2> & pen)
std::vector<shaped_glyph> const & shape_impl(String const & string, shape_options const & options, math::point<float, 2> & pen)
{
(void)options; // TODO: support options
@ -270,7 +270,7 @@ namespace psemek::fonts
}
pages_.back().current_row_x += face->glyph->bitmap.width + 2 * padding;
geom::make_max<int>(pages_.back().current_row_height, face->glyph->bitmap.rows + 2 * padding);
math::make_max<int>(pages_.back().current_row_height, face->glyph->bitmap.rows + 2 * padding);
pages_.back().needs_update = true;
need_update_pages = true;
@ -288,7 +288,7 @@ namespace psemek::fonts
result.texcoords[1].min = static_cast<float>(data->part[1].min) / page_size;
result.texcoords[1].max = static_cast<float>(data->part[1].max) / page_size;
pen += geom::cast<float>(data->advance);
pen += math::cast<float>(data->advance);
}
if (need_update_pages)

View file

@ -29,7 +29,7 @@ namespace psemek::fonts
}
}
static geom::vector<float, 2> advance_dir(shape_options::direction_t direction)
static math::vector<float, 2> advance_dir(shape_options::direction_t direction)
{
switch (direction)
{
@ -47,21 +47,21 @@ namespace psemek::fonts
return data_.glyphs.contains(c);
}
std::vector<glyph> kerned_font::shape(std::string_view str, shape_options const & options, geom::point<float, 2> & pen) const
std::vector<glyph> kerned_font::shape(std::string_view str, shape_options const & options, math::point<float, 2> & pen) const
{
return shape_impl(util::utf8_range(str), options, pen);
}
std::vector<glyph> kerned_font::shape(std::u32string_view str, shape_options const & options, geom::point<float, 2> & pen) const
std::vector<glyph> kerned_font::shape(std::u32string_view str, shape_options const & options, math::point<float, 2> & pen) const
{
return shape_impl(str, options, pen);
}
template <typename String>
std::vector<glyph> kerned_font::shape_impl(String const & str, shape_options const & options, geom::point<float, 2> & pen) const
std::vector<glyph> kerned_font::shape_impl(String const & str, shape_options const & options, math::point<float, 2> & pen) const
{
char32_t const unknown = supports_character(options.unknown_character) ? options.unknown_character : '?';
geom::vector<float, 2> const advance_mask = advance_dir(options.direction);
math::vector<float, 2> const advance_mask = advance_dir(options.direction);
std::vector<glyph> result;
@ -80,21 +80,21 @@ namespace psemek::fonts
g.position[1].max = pen[1] - data.offset_y * options.scale;
result.push_back(g);
geom::vector<float, 2> advance{data.advance * options.scale, data_.size[1] * options.scale};
math::vector<float, 2> advance{data.advance * options.scale, data_.size[1] * options.scale};
pen += geom::pointwise_mult(advance_mask, advance);
pen += math::pointwise_mult(advance_mask, advance);
}
return result;
}
std::optional<geom::box<float, 2>> kerned_font::texcoords(char32_t c) const
std::optional<math::box<float, 2>> kerned_font::texcoords(char32_t c) const
{
auto it = data_.glyphs.find(c);
if (it == data_.glyphs.end())
return std::nullopt;
geom::box<float, 2> box;
math::box<float, 2> box;
box[0].min = it->second.start_x;
box[1].min = it->second.start_y;
box[0].max = box[0].min + it->second.size_x;

View file

@ -6,7 +6,7 @@
namespace psemek::fonts
{
monospace_font::monospace_font(character_range range, std::string_view name, geom::vector<int, 2> size, gfx::texture_2d atlas, std::vector<geom::box<float, 2>> texcoords)
monospace_font::monospace_font(character_range range, std::string_view name, math::vector<int, 2> size, gfx::texture_2d atlas, std::vector<math::box<float, 2>> texcoords)
: range_{range}
, name_{name}
, size_{size}
@ -20,7 +20,7 @@ namespace psemek::fonts
throw util::exception("Monospace font must support '?' character");
}
static geom::vector<float, 2> advance_dir(shape_options::direction_t direction)
static math::vector<float, 2> advance_dir(shape_options::direction_t direction)
{
switch (direction)
{
@ -38,22 +38,22 @@ namespace psemek::fonts
return std::isspace(c) || (c >= range_.begin && c < range_.end);
}
std::vector<glyph> monospace_font::shape(std::string_view str, shape_options const & options, geom::point<float, 2> & pen) const
std::vector<glyph> monospace_font::shape(std::string_view str, shape_options const & options, math::point<float, 2> & pen) const
{
return shape_impl(util::utf8_range(str), options, pen);
}
std::vector<glyph> monospace_font::shape(std::u32string_view str, shape_options const & options, geom::point<float, 2> & pen) const
std::vector<glyph> monospace_font::shape(std::u32string_view str, shape_options const & options, math::point<float, 2> & pen) const
{
return shape_impl(str, options, pen);
}
template <typename String>
std::vector<glyph> monospace_font::shape_impl(String const & str, shape_options const & options, geom::point<float, 2> & pen) const
std::vector<glyph> monospace_font::shape_impl(String const & str, shape_options const & options, math::point<float, 2> & pen) const
{
char32_t const unknown = supports_character(options.unknown_character) ? options.unknown_character : '?';
geom::vector<float, 2> const size = geom::cast<float>(this->size()) * options.scale;
geom::vector<float, 2> const advance = geom::pointwise_mult(advance_dir(options.direction), size);
math::vector<float, 2> const size = math::cast<float>(this->size()) * options.scale;
math::vector<float, 2> const advance = math::pointwise_mult(advance_dir(options.direction), size);
std::vector<glyph> result;
@ -77,7 +77,7 @@ namespace psemek::fonts
return result;
}
std::optional<geom::box<float, 2>> monospace_font::texcoords(char32_t c) const
std::optional<math::box<float, 2>> monospace_font::texcoords(char32_t c) const
{
if (!supports_character(c)) return std::nullopt;

View file

@ -1,18 +0,0 @@
option(PSEMEK_GEOM_ROBUST_PREDICATES "Use robust geometric predicates" OFF)
find_package(Boost REQUIRED)
if(PSEMEK_ROBUST_PREDICATES)
find_package(GMP REQUIRED)
endif()
file(GLOB_RECURSE PSEMEK_GEOM_HEADERS "include/*.hpp")
file(GLOB_RECURSE PSEMEK_GEOM_SOURCES "source/*.cpp")
psemek_add_library(psemek-geom ${PSEMEK_GEOM_HEADERS} ${PSEMEK_GEOM_SOURCES})
target_include_directories(psemek-geom PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(psemek-geom PUBLIC psemek-util psemek-group Boost::boost)
if(PSEMEK_ROBUST_PREDICATES)
target_link_libraries(psemek-geom PUBLIC gmp)
endif()
psemek_glob_tests(psemek-geom tests)

View file

@ -5,7 +5,7 @@ file(GLOB_RECURSE PSEMEK_GFX_SOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "sou
psemek_add_library(psemek-gfx ${PSEMEK_GFX_HEADERS} ${PSEMEK_GFX_SOURCES} "${CMAKE_CURRENT_SOURCE_DIR}/api/${PSEMEK_GL_API}/source/gl.cpp")
target_include_directories(psemek-gfx PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/api/${PSEMEK_GL_API}/include")
target_link_libraries(psemek-gfx PUBLIC psemek-util psemek-geom psemek-cg psemek-random psemek-io psemek-log ${PSEMEK_GL_LIBRARIES} rapidjson)
target_link_libraries(psemek-gfx PUBLIC psemek-util psemek-math psemek-cg psemek-random psemek-io psemek-log ${PSEMEK_GL_LIBRARIES} rapidjson)
if(NOT KHR_PLATFORM_FILE)
message(STATUS "KHR/khrplatform.h not found, using a substitute header")
target_include_directories(psemek-gfx PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/extra/khr/include")

View file

@ -1,11 +1,11 @@
#pragma once
#include <psemek/geom/vector.hpp>
#include <psemek/geom/point.hpp>
#include <psemek/geom/quaternion.hpp>
#include <psemek/geom/matrix.hpp>
#include <psemek/geom/affine_transform.hpp>
#include <psemek/geom/rotation.hpp>
#include <psemek/math/vector.hpp>
#include <psemek/math/point.hpp>
#include <psemek/math/quaternion.hpp>
#include <psemek/math/matrix.hpp>
#include <psemek/math/affine_transform.hpp>
#include <psemek/math/rotation.hpp>
#include <cstdint>
@ -17,54 +17,54 @@ namespace psemek::gfx
static constexpr std::uint32_t null = static_cast<std::uint32_t>(-1);
std::uint32_t parent = null;
geom::vector<float, 3> offset = geom::vector<float, 3>::zero();
geom::matrix<float, 3, 3> axes = geom::matrix<float, 3, 3>::identity();
math::vector<float, 3> offset = math::vector<float, 3>::zero();
math::matrix<float, 3, 3> axes = math::matrix<float, 3, 3>::identity();
};
template <typename T>
struct bone_transform
{
geom::quaternion<T> rotation;
math::quaternion<T> rotation;
T scale;
geom::vector<T, 3> translation;
math::vector<T, 3> translation;
static bone_transform identity();
static bone_transform from_rotation(geom::quaternion<T> const & rotation);
static bone_transform from_rotation(math::quaternion<T> const & rotation);
static bone_transform from_scale(T const & scale);
static bone_transform from_translation(geom::vector<T, 3> const & translation);
static bone_transform from_translation(math::vector<T, 3> const & translation);
geom::matrix<T, 3, 4> matrix() const;
math::matrix<T, 3, 4> matrix() const;
};
template <typename T>
bone_transform<T> bone_transform<T>::identity()
{
return {geom::quaternion<T>::identity(), static_cast<T>(1), geom::vector<T, 3>::zero()};
return {math::quaternion<T>::identity(), static_cast<T>(1), math::vector<T, 3>::zero()};
}
template <typename T>
bone_transform<T> bone_transform<T>::from_rotation(geom::quaternion<T> const & rotation)
bone_transform<T> bone_transform<T>::from_rotation(math::quaternion<T> const & rotation)
{
return {rotation, static_cast<T>(1), geom::vector<T, 3>::zero()};
return {rotation, static_cast<T>(1), math::vector<T, 3>::zero()};
}
template <typename T>
bone_transform<T> bone_transform<T>::from_scale(T const & scale)
{
return {geom::quaternion<T>::identity(), scale, geom::vector<T, 3>::zero()};
return {math::quaternion<T>::identity(), scale, math::vector<T, 3>::zero()};
}
template <typename T>
bone_transform<T> bone_transform<T>::from_translation(geom::vector<T, 3> const & translation)
bone_transform<T> bone_transform<T>::from_translation(math::vector<T, 3> const & translation)
{
return {geom::quaternion<T>::identity(), static_cast<T>(1), translation};
return {math::quaternion<T>::identity(), static_cast<T>(1), translation};
}
template <typename T>
geom::matrix<T, 3, 4> bone_transform<T>::matrix() const
math::matrix<T, 3, 4> bone_transform<T>::matrix() const
{
return geom::affine_transform<T, 3, 3>(scale * geom::quaternion_rotation<T>(geom::quaternion<T>(rotation.coords)).linear_matrix(), translation).affine_matrix();
return math::affine_transform<T, 3, 3>(scale * math::quaternion_rotation<T>(math::quaternion<T>(rotation.coords)).linear_matrix(), translation).affine_matrix();
}
template <typename T>
@ -76,7 +76,7 @@ namespace psemek::gfx
// (1, t1) * (1, S1 * R1 * t2) * (S1, 0) * (S2, 0) * (R1, 0) * (R2, 0) =
// (1, t1 + S1 * R1 * t2) * (S1 * S2, 0) * (R1 * R2, 0)
return bone_transform<T>{m1.rotation * m2.rotation, m1.scale * m2.scale, m1.translation + m1.scale * geom::rotate(m1.rotation, m2.translation)};
return bone_transform<T>{m1.rotation * m2.rotation, m1.scale * m2.scale, m1.translation + m1.scale * math::rotate(m1.rotation, m2.translation)};
}
template <typename T>
@ -85,24 +85,24 @@ namespace psemek::gfx
// [(1, T) * (S, 0) * (R, 0)]^-1 = (R^-1, 0) * (S^-1, 0) * (1, -T) =
// = (1, - R^-1 S^-1 T) * (S^-1, 0) * (R^-1, 0)
auto ir = geom::inverse(m.rotation);
return bone_transform<T>{ir, T{1} / m.scale, - geom::rotate(ir, m.translation) / m.scale};
auto ir = math::inverse(m.rotation);
return bone_transform<T>{ir, T{1} / m.scale, - math::rotate(ir, m.translation) / m.scale};
}
template <typename T>
bone_transform<T> lerp(bone_transform<T> const & m1, bone_transform<T> const & m2, T t)
{
return {geom::slerp(m1.rotation, m2.rotation, t), std::exp(geom::lerp(std::log(m1.scale), std::log(m2.scale), t)), geom::lerp(m1.translation, m2.translation, t)};
return {math::slerp(m1.rotation, m2.rotation, t), std::exp(math::lerp(std::log(m1.scale), std::log(m2.scale), t)), math::lerp(m1.translation, m2.translation, t)};
}
template <typename T>
geom::vector<T, 3> operator * (bone_transform<T> const & m, geom::vector<T, 3> const & v)
math::vector<T, 3> operator * (bone_transform<T> const & m, math::vector<T, 3> const & v)
{
return m.translation + m.scale * geom::rotate(m.rotation, v);
return m.translation + m.scale * math::rotate(m.rotation, v);
}
template <typename T>
geom::point<T, 3> operator * (bone_transform<T> const & m, geom::point<T, 3> const & p)
math::point<T, 3> operator * (bone_transform<T> const & m, math::point<T, 3> const & p)
{
return p.zero() + m * (p - p.zero());
}
@ -130,11 +130,11 @@ namespace psemek::gfx
for (std::size_t b = 0; b < bones.size(); ++b)
{
result[b] =
gfx::bone_transform<float>{geom::quaternion<float>::identity(), 1.f, bones[b].offset}
* gfx::bone_transform<float>{geom::quaternion<float>::rotation(bones[b].axes), 1.f, {0.f, 0.f, 0.f}}
gfx::bone_transform<float>{math::quaternion<float>::identity(), 1.f, bones[b].offset}
* gfx::bone_transform<float>{math::quaternion<float>::rotation(bones[b].axes), 1.f, {0.f, 0.f, 0.f}}
* local_pose[b]
* gfx::bone_transform<float>{geom::inverse(geom::quaternion<float>::rotation(bones[b].axes)), 1.f, {0.f, 0.f, 0.f}}
* gfx::bone_transform<float>{geom::quaternion<float>::identity(), 1.f, -bones[b].offset}
* gfx::bone_transform<float>{math::inverse(math::quaternion<float>::rotation(bones[b].axes)), 1.f, {0.f, 0.f, 0.f}}
* gfx::bone_transform<float>{math::quaternion<float>::identity(), 1.f, -bones[b].offset}
;
auto p = bones[b].parent;
@ -154,9 +154,9 @@ namespace psemek::gfx
for (std::size_t b = 0; b < bones.size(); ++b)
{
result[b] =
gfx::bone_transform<float>{geom::quaternion<float>::identity(), 1.f, bones[b].offset}
gfx::bone_transform<float>{math::quaternion<float>::identity(), 1.f, bones[b].offset}
* local_pose[b]
* gfx::bone_transform<float>{geom::quaternion<float>::identity(), 1.f, -bones[b].offset}
* gfx::bone_transform<float>{math::quaternion<float>::identity(), 1.f, -bones[b].offset}
;
auto p = bones[b].parent;

View file

@ -2,10 +2,10 @@
#include <psemek/gfx/gl.hpp>
#include <psemek/geom/vector.hpp>
#include <psemek/geom/point.hpp>
#include <psemek/geom/matrix.hpp>
#include <psemek/geom/quaternion.hpp>
#include <psemek/math/vector.hpp>
#include <psemek/math/point.hpp>
#include <psemek/math/matrix.hpp>
#include <psemek/math/quaternion.hpp>
#include <vector>
#include <optional>
@ -204,9 +204,9 @@ namespace psemek::gfx
};
template <typename T, std::size_t N>
struct attrib_traits<geom::vector<T, N>>
struct attrib_traits<math::vector<T, N>>
{
using attrib_type = geom::vector<T, N>;
using attrib_type = math::vector<T, N>;
static constexpr GLint size = N;
static constexpr GLenum type = attrib_traits<T>::type;
@ -215,9 +215,9 @@ namespace psemek::gfx
};
template <typename T, std::size_t N>
struct attrib_traits<geom::point<T, N>>
struct attrib_traits<math::point<T, N>>
{
using attrib_type = geom::point<T, N>;
using attrib_type = math::point<T, N>;
static constexpr GLint size = N;
static constexpr GLenum type = attrib_traits<T>::type;
@ -226,15 +226,15 @@ namespace psemek::gfx
};
template <typename T, std::size_t R, std::size_t C>
struct attrib_traits<geom::matrix<T, R, C>>
struct attrib_traits<math::matrix<T, R, C>>
{
using attrib_type = geom::matrix<T, R, C>;
using attrib_type = math::matrix<T, R, C>;
};
template <typename T>
struct attrib_traits<geom::quaternion<T>>
struct attrib_traits<math::quaternion<T>>
{
using attrib_type = geom::quaternion<T>;
using attrib_type = math::quaternion<T>;
static constexpr GLint size = 4;
static constexpr GLenum type = attrib_traits<T>::type;
@ -312,7 +312,7 @@ namespace psemek::gfx
{};
template <typename T, std::size_t R, std::size_t C>
struct is_matrix<geom::matrix<T, R, C>> : std::true_type
struct is_matrix<math::matrix<T, R, C>> : std::true_type
{};
template <typename Attr>
@ -383,7 +383,7 @@ namespace psemek::gfx
if constexpr (is_matrix<attr>::value)
{
using T = typename attr::scalar_type;
using traits = attrib_traits<geom::vector<T, attr::static_columns>>;
using traits = attrib_traits<math::vector<T, attr::static_columns>>;
for (std::size_t row = 0; row < attr::static_rows; ++row)
{
@ -464,55 +464,55 @@ namespace psemek::gfx
inline std::int8_t to_signed_8bit(float x)
{
return static_cast<std::int8_t>(geom::clamp((0.5f * x + 0.5f) * 255.f - 128.f, {-128.f, 127.f}));
return static_cast<std::int8_t>(math::clamp((0.5f * x + 0.5f) * 255.f - 128.f, {-128.f, 127.f}));
}
inline std::uint8_t to_unsigned_8bit(float x)
{
return static_cast<std::uint8_t>(geom::clamp(x * 255.f, {0.f, 255.f}));
return static_cast<std::uint8_t>(math::clamp(x * 255.f, {0.f, 255.f}));
}
inline std::int16_t to_signed_16bit(float x)
{
return static_cast<std::int16_t>(geom::clamp((0.5f * x + 0.5f) * 65535.f - 32768.f, {-32768.f, 32767.f}));
return static_cast<std::int16_t>(math::clamp((0.5f * x + 0.5f) * 65535.f - 32768.f, {-32768.f, 32767.f}));
}
inline std::uint16_t to_unsigned_16bit(float x)
{
return static_cast<std::uint16_t>(geom::clamp(x * 65535.f, {0.f, 65535.f}));
return static_cast<std::uint16_t>(math::clamp(x * 65535.f, {0.f, 65535.f}));
}
template <std::size_t D>
geom::vector<std::int8_t, D> to_signed_8bit(geom::vector<float, D> const & v)
math::vector<std::int8_t, D> to_signed_8bit(math::vector<float, D> const & v)
{
geom::vector<std::int8_t, D> result;
math::vector<std::int8_t, D> result;
for (std::size_t i = 0; i < D; ++i)
result[i] = to_signed_8bit(v[i]);
return result;
}
template <std::size_t D>
geom::vector<std::uint8_t, D> to_unsigned_8bit(geom::vector<float, D> const & v)
math::vector<std::uint8_t, D> to_unsigned_8bit(math::vector<float, D> const & v)
{
geom::vector<std::uint8_t, D> result;
math::vector<std::uint8_t, D> result;
for (std::size_t i = 0; i < D; ++i)
result[i] = to_unsigned_8bit(v[i]);
return result;
}
template <std::size_t D>
geom::vector<std::int16_t, D> to_signed_16bit(geom::vector<float, D> const & v)
math::vector<std::int16_t, D> to_signed_16bit(math::vector<float, D> const & v)
{
geom::vector<std::int16_t, D> result;
math::vector<std::int16_t, D> result;
for (std::size_t i = 0; i < D; ++i)
result[i] = to_signed_16bit(v[i]);
return result;
}
template <std::size_t D>
geom::vector<std::uint16_t, D> to_unsigned_16bit(geom::vector<float, D> const & v)
math::vector<std::uint16_t, D> to_unsigned_16bit(math::vector<float, D> const & v)
{
geom::vector<std::uint16_t, D> result;
math::vector<std::uint16_t, D> result;
for (std::size_t i = 0; i < D; ++i)
result[i] = to_unsigned_16bit(v[i]);
return result;

View file

@ -1,8 +1,8 @@
#pragma once
#include <psemek/geom/vector.hpp>
#include <psemek/geom/interval.hpp>
#include <psemek/geom/math.hpp>
#include <psemek/math/vector.hpp>
#include <psemek/math/interval.hpp>
#include <psemek/math/math.hpp>
#include <cstdint>
#include <string_view>
@ -11,111 +11,111 @@
namespace psemek::gfx
{
using color_3f = geom::vector<float, 3>;
using color_4f = geom::vector<float, 4>;
using color_3f = math::vector<float, 3>;
using color_4f = math::vector<float, 4>;
using color_rgb = geom::vector<std::uint8_t, 3>;
using color_rgba = geom::vector<std::uint8_t, 4>;
using color_rgb = math::vector<std::uint8_t, 3>;
using color_rgba = math::vector<std::uint8_t, 4>;
template <std::size_t N>
auto to_colorf(geom::vector<std::uint8_t, N> const & c)
auto to_colorf(math::vector<std::uint8_t, N> const & c)
{
geom::vector<float, N> r;
math::vector<float, N> r;
for (std::size_t i = 0; i < N; ++i)
r[i] = c[i] / 255.f;
return r;
}
template <std::size_t N>
auto to_colorf(geom::vector<std::uint16_t, N> const & c)
auto to_colorf(math::vector<std::uint16_t, N> const & c)
{
geom::vector<float, N> r;
math::vector<float, N> r;
for (std::size_t i = 0; i < N; ++i)
r[i] = c[i] / 65535.f;
return r;
}
template <std::size_t N>
auto to_coloru8(geom::vector<std::uint16_t, N> const & c)
auto to_coloru8(math::vector<std::uint16_t, N> const & c)
{
geom::vector<std::uint8_t, N> r;
math::vector<std::uint8_t, N> r;
for (std::size_t i = 0; i < N; ++i)
r[i] = (static_cast<std::uint32_t>(c[i]) * 255) / 65535;
return r;
}
template <std::size_t N>
auto to_coloru8(geom::vector<float, N> const & c)
auto to_coloru8(math::vector<float, N> const & c)
{
geom::vector<std::uint8_t, N> r;
math::vector<std::uint8_t, N> r;
for (std::size_t i = 0; i < N; ++i)
r[i] = static_cast<std::uint8_t>(std::round(geom::clamp(c[i] * 255.f, {0.f, 255.f})));
r[i] = static_cast<std::uint8_t>(std::round(math::clamp(c[i] * 255.f, {0.f, 255.f})));
return r;
}
template <std::size_t N>
auto to_coloru16(geom::vector<std::uint8_t, N> const & c)
auto to_coloru16(math::vector<std::uint8_t, N> const & c)
{
geom::vector<std::uint16_t, N> r;
math::vector<std::uint16_t, N> r;
for (std::size_t i = 0; i < N; ++i)
r[i] = (static_cast<std::uint32_t>(c[i]) * 65535) / 255;
return r;
}
template <std::size_t N>
auto to_coloru16(geom::vector<float, N> const & c)
auto to_coloru16(math::vector<float, N> const & c)
{
geom::vector<std::uint16_t, N> r;
math::vector<std::uint16_t, N> r;
for (std::size_t i = 0; i < N; ++i)
r[i] = static_cast<std::uint16_t>(std::round(geom::clamp(c[i] * 65535.f, {0.f, 65535.f})));
r[i] = static_cast<std::uint16_t>(std::round(math::clamp(c[i] * 65535.f, {0.f, 65535.f})));
return r;
}
template <std::size_t N>
auto lerp(geom::vector<float, N> const & c0, geom::vector<float, N> const & c1, float t)
auto lerp(math::vector<float, N> const & c0, math::vector<float, N> const & c1, float t)
{
return geom::lerp(c0, c1, t);
return math::lerp(c0, c1, t);
}
template <std::size_t N>
auto lerp(geom::vector<std::uint8_t, N> const & c0, geom::vector<std::uint8_t, N> const & c1, float t)
auto lerp(math::vector<std::uint8_t, N> const & c0, math::vector<std::uint8_t, N> const & c1, float t)
{
return to_coloru8(lerp(to_colorf(c0), to_colorf(c1), t));
}
template <std::size_t N>
auto to_srgb(geom::vector<float, N> const & c, float g = 1.f / 2.2f)
auto to_srgb(math::vector<float, N> const & c, float g = 1.f / 2.2f)
{
geom::vector<float, N> r = c;
math::vector<float, N> r = c;
for (std::size_t i = 0; i < std::min<std::size_t>(3, N); ++i)
r[i] = std::pow(r[i], g);
return r;
}
template <std::size_t N>
auto to_srgb(geom::vector<std::uint8_t, N> const & c, float g = 1.f / 2.2f)
auto to_srgb(math::vector<std::uint8_t, N> const & c, float g = 1.f / 2.2f)
{
return to_coloru8(to_srgb(to_colorf(c), g));
}
template <std::size_t N>
auto to_srgb(geom::vector<std::uint16_t, N> const & c, float g = 1.f / 2.2f)
auto to_srgb(math::vector<std::uint16_t, N> const & c, float g = 1.f / 2.2f)
{
return to_coloru16(to_srgb(to_colorf(c), g));
}
template <typename T, std::size_t N>
auto to_linear(geom::vector<T, N> const & c, float g = 1.f / 2.2f)
auto to_linear(math::vector<T, N> const & c, float g = 1.f / 2.2f)
{
return to_srgb(c, 1.f / g);
}
inline geom::vector<float, 4> premult(geom::vector<float, 4> const & c)
inline math::vector<float, 4> premult(math::vector<float, 4> const & c)
{
return {c[0] * c[3], c[1] * c[3], c[2] * c[3], c[3]};
}
inline geom::vector<std::uint8_t, 4> premult(geom::vector<std::uint8_t, 4> const & c)
inline math::vector<std::uint8_t, 4> premult(math::vector<std::uint8_t, 4> const & c)
{
return {
(static_cast<std::uint16_t>(c[0]) * c[3]) / 255,
@ -125,7 +125,7 @@ namespace psemek::gfx
};
}
inline geom::vector<std::uint16_t, 4> premult(geom::vector<std::uint16_t, 4> const & c)
inline math::vector<std::uint16_t, 4> premult(math::vector<std::uint16_t, 4> const & c)
{
return {
(static_cast<std::uint32_t>(c[0]) * c[3]) / 65535,
@ -135,18 +135,18 @@ namespace psemek::gfx
};
}
inline geom::vector<float, 4> unpremult(geom::vector<float, 4> const & c)
inline math::vector<float, 4> unpremult(math::vector<float, 4> const & c)
{
if (c[3] == 0.f)
return geom::vector<float, 4>::zero();
return math::vector<float, 4>::zero();
return {c[0] / c[3], c[1] / c[3], c[2] / c[3], c[3]};
}
inline geom::vector<std::uint8_t, 4> unpremult(geom::vector<std::uint8_t, 4> const & c)
inline math::vector<std::uint8_t, 4> unpremult(math::vector<std::uint8_t, 4> const & c)
{
if (c[3] == 0)
return geom::vector<std::uint8_t, 4>::zero();
return math::vector<std::uint8_t, 4>::zero();
return {
(static_cast<std::uint16_t>(c[0]) * 255) / c[3],
@ -156,10 +156,10 @@ namespace psemek::gfx
};
}
inline geom::vector<std::uint16_t, 4> unpremult(geom::vector<std::uint16_t, 4> const & c)
inline math::vector<std::uint16_t, 4> unpremult(math::vector<std::uint16_t, 4> const & c)
{
if (c[3] == 0)
return geom::vector<std::uint16_t, 4>::zero();
return math::vector<std::uint16_t, 4>::zero();
return {
(static_cast<std::uint32_t>(c[0]) * 65535) / c[3],
@ -182,7 +182,7 @@ namespace psemek::gfx
}
template <std::size_t N>
auto blend(geom::vector<std::uint8_t, N> const & c0, geom::vector<std::uint8_t, N> const & c1, float t)
auto blend(math::vector<std::uint8_t, N> const & c0, math::vector<std::uint8_t, N> const & c1, float t)
{
return to_coloru8(blend(to_colorf(c0), to_colorf(c1), t));
}
@ -190,9 +190,9 @@ namespace psemek::gfx
template <std::size_t N>
struct as_hex
{
geom::vector<std::uint8_t, N> color;
math::vector<std::uint8_t, N> color;
as_hex(geom::vector<std::uint8_t, N> const & color)
as_hex(math::vector<std::uint8_t, N> const & color)
: color{color}
{}
};
@ -220,7 +220,7 @@ namespace psemek::gfx
auto as_color_rgb() const
{
return to_coloru8(geom::vector{c[0], c[1], c[2]});
return to_coloru8(math::vector{c[0], c[1], c[2]});
}
auto as_color_rgba() const
@ -278,31 +278,31 @@ namespace psemek::gfx
static const generic_color gray {{0.50f, 0.50f, 0.50f, 1.f}};
template <std::size_t N>
geom::vector<float, N> light(geom::vector<float, N> c, float lightness = 0.5f)
math::vector<float, N> light(math::vector<float, N> c, float lightness = 0.5f)
{
static_assert(N == 3 || N == 4);
for (std::size_t i = 0; i < 3; ++i)
c[i] = geom::lerp(c[i], 1.f, lightness);
c[i] = math::lerp(c[i], 1.f, lightness);
return c;
}
template <std::size_t N>
geom::vector<float, N> dark(geom::vector<float, N> c, float darkness = 0.5f)
math::vector<float, N> dark(math::vector<float, N> c, float darkness = 0.5f)
{
static_assert(N == 3 || N == 4);
for (std::size_t i = 0; i < 3; ++i)
c[i] = geom::lerp(c[i], 0.f, darkness);
c[i] = math::lerp(c[i], 0.f, darkness);
return c;
}
template <std::size_t N>
geom::vector<std::uint8_t, N> light(geom::vector<std::uint8_t, N> c, float lightness = 0.5f)
math::vector<std::uint8_t, N> light(math::vector<std::uint8_t, N> c, float lightness = 0.5f)
{
return to_coloru8(light(to_colorf(c), lightness));
}
template <std::size_t N>
geom::vector<std::uint8_t, N> dark(geom::vector<std::uint8_t, N> c, float darkness = 0.5f)
math::vector<std::uint8_t, N> dark(math::vector<std::uint8_t, N> c, float darkness = 0.5f)
{
return to_coloru8(dark(to_colorf(c), darkness));
}

View file

@ -37,70 +37,70 @@ namespace psemek::gfx
{};
template <typename T, std::size_t N>
struct accessor_traits<geom::vector<T, N>>
struct accessor_traits<math::vector<T, N>>
{
static constexpr bool is_floating_point = accessor_traits<T>::is_floating_point;
static constexpr std::size_t components = N;
using component_type = T;
static auto pointer(geom::vector<T, N> & value)
static auto pointer(math::vector<T, N> & value)
{
return &value[0];
}
static void finalize(geom::vector<T, N> &)
static void finalize(math::vector<T, N> &)
{}
};
template <typename T, std::size_t N>
struct accessor_traits<geom::point<T, N>>
struct accessor_traits<math::point<T, N>>
{
static constexpr bool is_floating_point = accessor_traits<T>::is_floating_point;
static constexpr std::size_t components = N;
using component_type = T;
static auto pointer(geom::point<T, N> & value)
static auto pointer(math::point<T, N> & value)
{
return &value[0];
}
static void finalize(geom::point<T, N> &)
static void finalize(math::point<T, N> &)
{}
};
template <typename T>
struct accessor_traits<geom::quaternion<T>>
struct accessor_traits<math::quaternion<T>>
{
static constexpr bool is_floating_point = accessor_traits<T>::is_floating_point;
static constexpr std::size_t components = 4;
using component_type = T;
static auto pointer(geom::quaternion<T> & value)
static auto pointer(math::quaternion<T> & value)
{
return &value[0];
}
static void finalize(geom::quaternion<T> &)
static void finalize(math::quaternion<T> &)
{}
};
template <typename T, std::size_t R, std::size_t C>
struct accessor_traits<geom::matrix<T, R, C>>
struct accessor_traits<math::matrix<T, R, C>>
{
static constexpr bool is_floating_point = accessor_traits<T>::is_floating_point;
static constexpr std::size_t components = R * C;
using component_type = T;
static auto pointer(geom::matrix<T, R, C> & value)
static auto pointer(math::matrix<T, R, C> & value)
{
return &value[0][0];
}
static void finalize(geom::matrix<T, R, C> & value)
static void finalize(math::matrix<T, R, C> & value)
{
geom::matrix<T, C, R> temp;
math::matrix<T, C, R> temp;
std::copy(value.coords, value.coords + R * C, temp.coords);
value = geom::transpose(temp);
value = math::transpose(temp);
}
};

View file

@ -1,9 +1,9 @@
#pragma once
#include <psemek/gfx/gltf_parser.hpp>
#include <psemek/geom/scale.hpp>
#include <psemek/geom/rotation.hpp>
#include <psemek/geom/translation.hpp>
#include <psemek/math/scale.hpp>
#include <psemek/math/rotation.hpp>
#include <psemek/math/translation.hpp>
#include <psemek/util/exception.hpp>
#include <algorithm>
@ -20,7 +20,7 @@ namespace psemek::gfx
template <>
struct gltf_animation_traits<gltf_asset::animation::channel::scale>
{
using output_type = geom::vector<float, 3>;
using output_type = math::vector<float, 3>;
static output_type default_value()
{
@ -29,7 +29,7 @@ namespace psemek::gfx
static output_type lerp(output_type const & v1, output_type const & v2, float t)
{
return geom::lerp(v1, v2, t);
return math::lerp(v1, v2, t);
}
static output_type normalize(output_type const & v)
@ -37,14 +37,14 @@ namespace psemek::gfx
return v;
}
static void canonicalize(geom::easing_type, std::vector<output_type> &)
static void canonicalize(math::easing_type, std::vector<output_type> &)
{}
};
template <>
struct gltf_animation_traits<gltf_asset::animation::channel::rotation>
{
using output_type = geom::quaternion<float>;
using output_type = math::quaternion<float>;
static output_type default_value()
{
@ -53,21 +53,21 @@ namespace psemek::gfx
static output_type lerp(output_type const & v1, output_type const & v2, float t)
{
return geom::slerp(v1, v2, t);
return math::slerp(v1, v2, t);
}
static output_type normalize(output_type const & v)
{
return geom::normalized(v);
return math::normalized(v);
}
static void canonicalize(geom::easing_type interpolation, std::vector<output_type> & output);
static void canonicalize(math::easing_type interpolation, std::vector<output_type> & output);
};
template <>
struct gltf_animation_traits<gltf_asset::animation::channel::translation>
{
using output_type = geom::vector<float, 3>;
using output_type = math::vector<float, 3>;
static output_type default_value()
{
@ -76,7 +76,7 @@ namespace psemek::gfx
static output_type lerp(output_type const & v1, output_type const & v2, float t)
{
return geom::lerp(v1, v2, t);
return math::lerp(v1, v2, t);
}
static output_type normalize(output_type const & v)
@ -84,7 +84,7 @@ namespace psemek::gfx
return v;
}
static void canonicalize(geom::easing_type, std::vector<output_type> &)
static void canonicalize(math::easing_type, std::vector<output_type> &)
{}
};
@ -99,10 +99,10 @@ namespace psemek::gfx
gltf_animation_channel()
: input_{0.f}
, output_{traits::default_value()}
, interpolation_{geom::easing_type::constant_left}
, interpolation_{math::easing_type::constant_left}
{}
gltf_animation_channel(std::vector<float> input, std::vector<output_type> output, geom::easing_type interpolation)
gltf_animation_channel(std::vector<float> input, std::vector<output_type> output, math::easing_type interpolation)
: input_(std::move(input))
, output_(std::move(output))
, interpolation_(interpolation)
@ -114,7 +114,7 @@ namespace psemek::gfx
gltf_animation_channel & operator = (gltf_animation_channel &&) = default;
geom::interval<float> range() const
math::interval<float> range() const
{
return {input_.front(), input_.back()};
}
@ -124,7 +124,7 @@ namespace psemek::gfx
private:
std::vector<float> input_;
std::vector<output_type> output_;
geom::easing_type interpolation_;
math::easing_type interpolation_;
};
extern template struct gltf_animation_channel<gltf_asset::animation::channel::scale>;
@ -145,9 +145,9 @@ namespace psemek::gfx
, translation_(std::move(translation))
{}
geom::interval<float> range() const;
math::interval<float> range() const;
geom::affine_transform<float, 3, 3> operator()(float time) const;
math::affine_transform<float, 3, 3> operator()(float time) const;
gltf_scale_animation const & scale() const { return scale_; }
gltf_rotation_animation const & rotation() const { return rotation_; }

View file

@ -3,7 +3,7 @@
#include <psemek/gfx/gltf_parser.hpp>
#include <psemek/gfx/drawable.hpp>
#include <psemek/gfx/texture.hpp>
#include <psemek/geom/simplex.hpp>
#include <psemek/math/simplex.hpp>
#include <psemek/util/span.hpp>
#include <psemek/util/blob.hpp>
@ -19,8 +19,8 @@ namespace psemek::gfx
gfx::drawable * drawable;
std::optional<std::size_t> material;
util::span<geom::point<float, 3> const> vertices;
util::span<geom::triangle<std::uint32_t> const> triangles;
util::span<math::point<float, 3> const> vertices;
util::span<math::triangle<std::uint32_t> const> triangles;
};
virtual gltf_asset::material const & material(std::size_t index) const = 0;

View file

@ -2,10 +2,10 @@
#include <psemek/io/stream.hpp>
#include <psemek/gfx/color.hpp>
#include <psemek/geom/vector.hpp>
#include <psemek/geom/quaternion.hpp>
#include <psemek/geom/affine_transform.hpp>
#include <psemek/geom/easing.hpp>
#include <psemek/math/vector.hpp>
#include <psemek/math/quaternion.hpp>
#include <psemek/math/affine_transform.hpp>
#include <psemek/math/easing.hpp>
#include <psemek/util/hstring.hpp>
#include <psemek/util/hash_table.hpp>
@ -31,10 +31,10 @@ namespace psemek::gfx
std::vector<std::size_t> children;
std::optional<std::size_t> light; // KHR_lights_punctual
geom::vector<float, 3> translation;
geom::quaternion<float> rotation;
geom::vector<float, 3> scale;
geom::affine_transform<float, 3, 3> transform;
math::vector<float, 3> translation;
math::quaternion<float> rotation;
math::vector<float, 3> scale;
math::affine_transform<float, 3, 3> transform;
extras_map extras;
};
@ -103,7 +103,7 @@ namespace psemek::gfx
{
std::size_t input; // keyframes accessor
std::size_t output; // values accessor
geom::easing_type interpolation;
math::easing_type interpolation;
};
std::string name;
@ -168,7 +168,7 @@ namespace psemek::gfx
gfx::color_3f color;
float intensity;
float range;
geom::interval<float> cone_angle;
math::interval<float> cone_angle;
extras_map extras;
};

View file

@ -7,10 +7,10 @@
#include <psemek/gfx/attribs.hpp>
#include <psemek/gfx/armature.hpp>
#include <psemek/geom/vector.hpp>
#include <psemek/geom/point.hpp>
#include <psemek/geom/simplex.hpp>
#include <psemek/geom/matrix.hpp>
#include <psemek/math/vector.hpp>
#include <psemek/math/point.hpp>
#include <psemek/math/simplex.hpp>
#include <psemek/math/matrix.hpp>
#include <psemek/util/assert.hpp>
#include <psemek/util/span.hpp>
@ -135,10 +135,10 @@ namespace psemek::gfx
void load(std::vector<Vertex> const & vertices, GLenum primitive_type, GLenum usage = gl::STREAM_DRAW);
template <typename Vertex, std::size_t N>
void load(geom::simplex<Vertex, N> const * simplices, std::size_t count, GLenum usage = gl::STREAM_DRAW);
void load(math::simplex<Vertex, N> const * simplices, std::size_t count, GLenum usage = gl::STREAM_DRAW);
template <typename Vertex, std::size_t N>
void load(std::vector<geom::simplex<Vertex, N>> const & simplices, GLenum usage = gl::STREAM_DRAW);
void load(std::vector<math::simplex<Vertex, N>> const & simplices, GLenum usage = gl::STREAM_DRAW);
// Indexed vertex data
@ -153,10 +153,10 @@ namespace psemek::gfx
void load(std::vector<Vertex> const & vertices, std::vector<Index> const & indices, GLenum primitive_type, GLenum usage = gl::STREAM_DRAW);
template <typename Vertex, typename Index, std::size_t N>
void load(Vertex const * vertices, std::size_t vertex_count, geom::simplex<Index, N> const * simplices, std::size_t simplex_count, GLenum usage = gl::STREAM_DRAW);
void load(Vertex const * vertices, std::size_t vertex_count, math::simplex<Index, N> const * simplices, std::size_t simplex_count, GLenum usage = gl::STREAM_DRAW);
template <typename Vertex, typename Index, std::size_t N>
void load(std::vector<Vertex> const & vertices, std::vector<geom::simplex<Index, N>> const & simplices, GLenum usage = gl::STREAM_DRAW);
void load(std::vector<Vertex> const & vertices, std::vector<math::simplex<Index, N>> const & simplices, GLenum usage = gl::STREAM_DRAW);
void load_raw(imported_mesh const & m);
@ -169,10 +169,10 @@ namespace psemek::gfx
void load_index(std::vector<Index> const & indices, GLenum primitive_type, GLenum usage = gl::STREAM_DRAW);
template <typename Index, std::size_t N>
void load_index(geom::simplex<Index, N> const * simplices, std::size_t simplex_count, GLenum usage = gl::STREAM_DRAW);
void load_index(math::simplex<Index, N> const * simplices, std::size_t simplex_count, GLenum usage = gl::STREAM_DRAW);
template <typename Index, std::size_t N>
void load_index(std::vector<geom::simplex<Index, N>> const & simplices, GLenum usage = gl::STREAM_DRAW);
void load_index(std::vector<math::simplex<Index, N>> const & simplices, GLenum usage = gl::STREAM_DRAW);
// Instance data
@ -254,14 +254,14 @@ namespace psemek::gfx
}
template <typename Vertex, std::size_t N>
void mesh::load(geom::simplex<Vertex, N> const * simplices, std::size_t count, GLenum usage)
void mesh::load(math::simplex<Vertex, N> const * simplices, std::size_t count, GLenum usage)
{
static_assert(sizeof(Vertex) * (N + 1) == sizeof(simplices[0]));
load(reinterpret_cast<Vertex const *>(simplices), count * (N + 1), detail::get_primitive_type<N>(), usage);
}
template <typename Vertex, std::size_t N>
void mesh::load(std::vector<geom::simplex<Vertex, N>> const & simplices, GLenum usage)
void mesh::load(std::vector<math::simplex<Vertex, N>> const & simplices, GLenum usage)
{
load(simplices.data(), simplices.size(), usage);
}
@ -279,14 +279,14 @@ namespace psemek::gfx
}
template <typename Vertex, typename Index, std::size_t N>
void mesh::load(Vertex const * vertices, std::size_t vertex_count, geom::simplex<Index, N> const * simplices, std::size_t simplex_count, GLenum usage)
void mesh::load(Vertex const * vertices, std::size_t vertex_count, math::simplex<Index, N> const * simplices, std::size_t simplex_count, GLenum usage)
{
static_assert(sizeof(Index) * (N + 1) == sizeof(simplices[0]));
load(vertices, vertex_count, reinterpret_cast<Index const *>(simplices), (N + 1) * simplex_count, detail::get_primitive_type<N>(), usage);
}
template <typename Vertex, typename Index, std::size_t N>
void mesh::load(std::vector<Vertex> const & vertices, std::vector<geom::simplex<Index, N>> const & simplices, GLenum usage)
void mesh::load(std::vector<Vertex> const & vertices, std::vector<math::simplex<Index, N>> const & simplices, GLenum usage)
{
load(vertices.data(), vertices.size(), simplices.data(), simplices.size(), usage);
}
@ -317,14 +317,14 @@ namespace psemek::gfx
}
template <typename Index, std::size_t N>
void mesh::load_index(geom::simplex<Index, N> const * simplices, std::size_t simplex_count, GLenum usage)
void mesh::load_index(math::simplex<Index, N> const * simplices, std::size_t simplex_count, GLenum usage)
{
static_assert(sizeof(Index) * (N + 1) == sizeof(simplices[0]));
load_index(reinterpret_cast<Index const *>(simplices), simplex_count, detail::get_primitive_type<N>(), usage);
}
template <typename Index, std::size_t N>
void mesh::load_index(std::vector<geom::simplex<Index, N>> const & simplices, GLenum usage)
void mesh::load_index(std::vector<math::simplex<Index, N>> const & simplices, GLenum usage)
{
load_index(simplices.data(), simplices.size(), usage);
}

View file

@ -1,8 +1,8 @@
#pragma once
#include <psemek/geom/vector.hpp>
#include <psemek/geom/point.hpp>
#include <psemek/geom/simplex.hpp>
#include <psemek/math/vector.hpp>
#include <psemek/math/point.hpp>
#include <psemek/math/simplex.hpp>
#include <iostream>
#include <vector>
@ -14,12 +14,12 @@ namespace psemek::gfx
{
struct vertex
{
geom::point<float, 3> position;
geom::vector<float, 2> texcoord;
geom::vector<float, 3> normal;
math::point<float, 3> position;
math::vector<float, 2> texcoord;
math::vector<float, 3> normal;
};
std::vector<geom::triangle<vertex>> triangles;
std::vector<math::triangle<vertex>> triangles;
};
obj_data parse_obj(std::istream & is);

View file

@ -3,10 +3,10 @@
#include <psemek/gfx/color.hpp>
#include <psemek/gfx/texture.hpp>
#include <psemek/geom/vector.hpp>
#include <psemek/geom/point.hpp>
#include <psemek/geom/matrix.hpp>
#include <psemek/geom/box.hpp>
#include <psemek/math/vector.hpp>
#include <psemek/math/point.hpp>
#include <psemek/math/matrix.hpp>
#include <psemek/math/box.hpp>
#include <psemek/util/pimpl.hpp>
@ -42,7 +42,7 @@ namespace psemek::gfx
struct text_options
{
font f = font::font_9x12;
geom::vector<float, 2> scale = {1.f, 1.f};
math::vector<float, 2> scale = {1.f, 1.f};
x_align x = x_align::center;
y_align y = y_align::center;
color c = {255, 255, 255, 255};
@ -52,29 +52,29 @@ namespace psemek::gfx
~painter();
// 2D
void triangle(geom::point<float, 2> const & p0, geom::point<float, 2> const & p1, geom::point<float, 2> const & p2, color const & c);
void triangle(geom::point<float, 2> const & p0, geom::point<float, 2> const & p1, geom::point<float, 2> const & p2, color const & c0, color const & c1, color const & c2);
void rect(geom::box<float, 2> const & box, color const & c);
void circle(geom::point<float, 2> const & center, float radius, color const & c, int quality = 24);
void line(geom::point<float, 2> const & p0, geom::point<float, 2> const & p1, float width, color const & c, bool smooth = true);
void line(geom::point<float, 2> const & p0, geom::point<float, 2> const & p1, float w0, float w1, color const & c0, color const & c1, bool smooth = true);
void besier(geom::point<float, 2> const & p0, geom::point<float, 2> const & p1, geom::point<float, 2> const & p2, float width, color const & c, int quality = 8, bool smooth = true);
void polygon(util::span<geom::point<float, 2> const> points, color const & c);
void triangle(math::point<float, 2> const & p0, math::point<float, 2> const & p1, math::point<float, 2> const & p2, color const & c);
void triangle(math::point<float, 2> const & p0, math::point<float, 2> const & p1, math::point<float, 2> const & p2, color const & c0, color const & c1, color const & c2);
void rect(math::box<float, 2> const & box, color const & c);
void circle(math::point<float, 2> const & center, float radius, color const & c, int quality = 24);
void line(math::point<float, 2> const & p0, math::point<float, 2> const & p1, float width, color const & c, bool smooth = true);
void line(math::point<float, 2> const & p0, math::point<float, 2> const & p1, float w0, float w1, color const & c0, color const & c1, bool smooth = true);
void besier(math::point<float, 2> const & p0, math::point<float, 2> const & p1, math::point<float, 2> const & p2, float width, color const & c, int quality = 8, bool smooth = true);
void polygon(util::span<math::point<float, 2> const> points, color const & c);
// 2D text
geom::vector<float, 2> text_size(std::string_view str, font f = font::font_9x12);
void text(geom::point<float, 2> const & p, std::string_view str, text_options const & opts);
math::vector<float, 2> text_size(std::string_view str, font f = font::font_9x12);
void text(math::point<float, 2> const & p, std::string_view str, text_options const & opts);
void texture(texture_2d const & texture, geom::box<float, 2> const & box, color const & c = {0, 0, 0, 0});
void texture(texture_2d const & texture, math::box<float, 2> const & box, color const & c = {0, 0, 0, 0});
// 3D
void axes(geom::point<float, 3> const & p, float length, float width);
void sphere(geom::point<float, 3> const & p, float radius, color const & c, int quality = 6);
void line3d(geom::point<float, 3> const & p0, geom::point<float, 3> const & p1, float width, color const & c);
void text3d(geom::point<float, 3> const & p, std::string_view str, text_options const & opts, geom::matrix<float, 3, 3> const & transform);
void axes(math::point<float, 3> const & p, float length, float width);
void sphere(math::point<float, 3> const & p, float radius, color const & c, int quality = 6);
void line3d(math::point<float, 3> const & p0, math::point<float, 3> const & p1, float width, color const & c);
void text3d(math::point<float, 3> const & p, std::string_view str, text_options const & opts, math::matrix<float, 3, 3> const & transform);
// Should be called on each frame
void render(geom::matrix<float, 4, 4> const & transform);
void render(math::matrix<float, 4, 4> const & transform);
private:
psemek_declare_pimpl

View file

@ -55,7 +55,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<std::uint8_t, 2>>
struct pixel_traits<math::vector<std::uint8_t, 2>>
{
static constexpr GLenum internal_format = gl::RG8;
static constexpr GLenum format = gl::RG;
@ -63,7 +63,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<std::uint8_t, 3>>
struct pixel_traits<math::vector<std::uint8_t, 3>>
{
static constexpr GLenum internal_format = gl::RGB8;
static constexpr GLenum format = gl::RGB;
@ -71,7 +71,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<std::uint8_t, 4>>
struct pixel_traits<math::vector<std::uint8_t, 4>>
{
static constexpr GLenum internal_format = gl::RGBA8;
static constexpr GLenum format = gl::RGBA;
@ -81,7 +81,7 @@ namespace psemek::gfx
// Normalized 8-bit sRGB
template <>
struct pixel_traits<srgb<geom::vector<std::uint8_t, 3>>>
struct pixel_traits<srgb<math::vector<std::uint8_t, 3>>>
{
static constexpr GLenum internal_format = gl::SRGB8;
static constexpr GLenum format = gl::RGB;
@ -89,7 +89,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<srgb<geom::vector<std::uint8_t, 4>>>
struct pixel_traits<srgb<math::vector<std::uint8_t, 4>>>
{
static constexpr GLenum internal_format = gl::SRGB8_ALPHA8;
static constexpr GLenum format = gl::RGBA;
@ -100,7 +100,7 @@ namespace psemek::gfx
#ifndef PSEMEK_GLES
template <>
struct pixel_traits<geom::vector<uint10, 3>>
struct pixel_traits<math::vector<uint10, 3>>
{
static constexpr GLenum internal_format = gl::RGB10;
static constexpr GLenum format = gl::RGB;
@ -110,7 +110,7 @@ namespace psemek::gfx
// Normalized 12-bit
template <>
struct pixel_traits<geom::vector<uint12, 3>>
struct pixel_traits<math::vector<uint12, 3>>
{
static constexpr GLenum internal_format = gl::RGB12;
static constexpr GLenum format = gl::RGB;
@ -118,7 +118,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<uint12, 4>>
struct pixel_traits<math::vector<uint12, 4>>
{
static constexpr GLenum internal_format = gl::RGBA12;
static constexpr GLenum format = gl::RGBA;
@ -136,7 +136,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<std::uint16_t, 2>>
struct pixel_traits<math::vector<std::uint16_t, 2>>
{
static constexpr GLenum internal_format = gl::RG16;
static constexpr GLenum format = gl::RG;
@ -144,7 +144,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<std::uint16_t, 3>>
struct pixel_traits<math::vector<std::uint16_t, 3>>
{
static constexpr GLenum internal_format = gl::RGB16;
static constexpr GLenum format = gl::RGB;
@ -152,7 +152,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<std::uint16_t, 4>>
struct pixel_traits<math::vector<std::uint16_t, 4>>
{
static constexpr GLenum internal_format = gl::RGBA16;
static constexpr GLenum format = gl::RGBA;
@ -182,7 +182,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::uint8_t>, 2>>
struct pixel_traits<math::vector<integer<std::uint8_t>, 2>>
{
static constexpr GLenum internal_format = gl::RG8UI;
static constexpr GLenum format = gl::RG_INTEGER;
@ -190,7 +190,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::uint8_t>, 3>>
struct pixel_traits<math::vector<integer<std::uint8_t>, 3>>
{
static constexpr GLenum internal_format = gl::RGB8UI;
static constexpr GLenum format = gl::RGB_INTEGER;
@ -198,7 +198,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::uint8_t>, 4>>
struct pixel_traits<math::vector<integer<std::uint8_t>, 4>>
{
static constexpr GLenum internal_format = gl::RGBA8UI;
static constexpr GLenum format = gl::RGBA_INTEGER;
@ -216,7 +216,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::uint16_t>, 2>>
struct pixel_traits<math::vector<integer<std::uint16_t>, 2>>
{
static constexpr GLenum internal_format = gl::RG16UI;
static constexpr GLenum format = gl::RG_INTEGER;
@ -224,7 +224,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::uint16_t>, 3>>
struct pixel_traits<math::vector<integer<std::uint16_t>, 3>>
{
static constexpr GLenum internal_format = gl::RGB16UI;
static constexpr GLenum format = gl::RGB_INTEGER;
@ -232,7 +232,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::uint16_t>, 4>>
struct pixel_traits<math::vector<integer<std::uint16_t>, 4>>
{
static constexpr GLenum internal_format = gl::RGBA16UI;
static constexpr GLenum format = gl::RGBA_INTEGER;
@ -250,7 +250,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::uint32_t>, 2>>
struct pixel_traits<math::vector<integer<std::uint32_t>, 2>>
{
static constexpr GLenum internal_format = gl::RG32UI;
static constexpr GLenum format = gl::RG_INTEGER;
@ -258,7 +258,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::uint32_t>, 3>>
struct pixel_traits<math::vector<integer<std::uint32_t>, 3>>
{
static constexpr GLenum internal_format = gl::RGB32UI;
static constexpr GLenum format = gl::RGB_INTEGER;
@ -266,7 +266,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::uint32_t>, 4>>
struct pixel_traits<math::vector<integer<std::uint32_t>, 4>>
{
static constexpr GLenum internal_format = gl::RGBA32UI;
static constexpr GLenum format = gl::RGBA_INTEGER;
@ -284,7 +284,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::int8_t>, 2>>
struct pixel_traits<math::vector<integer<std::int8_t>, 2>>
{
static constexpr GLenum internal_format = gl::RG8I;
static constexpr GLenum format = gl::RG_INTEGER;
@ -292,7 +292,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::int8_t>, 3>>
struct pixel_traits<math::vector<integer<std::int8_t>, 3>>
{
static constexpr GLenum internal_format = gl::RGB8I;
static constexpr GLenum format = gl::RGB_INTEGER;
@ -300,7 +300,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::int8_t>, 4>>
struct pixel_traits<math::vector<integer<std::int8_t>, 4>>
{
static constexpr GLenum internal_format = gl::RGBA8I;
static constexpr GLenum format = gl::RGBA_INTEGER;
@ -318,7 +318,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::int16_t>, 2>>
struct pixel_traits<math::vector<integer<std::int16_t>, 2>>
{
static constexpr GLenum internal_format = gl::RG16I;
static constexpr GLenum format = gl::RG_INTEGER;
@ -326,7 +326,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::int16_t>, 3>>
struct pixel_traits<math::vector<integer<std::int16_t>, 3>>
{
static constexpr GLenum internal_format = gl::RGB16I;
static constexpr GLenum format = gl::RGB_INTEGER;
@ -334,7 +334,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::int16_t>, 4>>
struct pixel_traits<math::vector<integer<std::int16_t>, 4>>
{
static constexpr GLenum internal_format = gl::RGBA16I;
static constexpr GLenum format = gl::RGBA_INTEGER;
@ -352,7 +352,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::int32_t>, 2>>
struct pixel_traits<math::vector<integer<std::int32_t>, 2>>
{
static constexpr GLenum internal_format = gl::RG32I;
static constexpr GLenum format = gl::RG_INTEGER;
@ -360,7 +360,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::int32_t>, 3>>
struct pixel_traits<math::vector<integer<std::int32_t>, 3>>
{
static constexpr GLenum internal_format = gl::RGB32I;
static constexpr GLenum format = gl::RGB_INTEGER;
@ -368,7 +368,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<integer<std::int32_t>, 4>>
struct pixel_traits<math::vector<integer<std::int32_t>, 4>>
{
static constexpr GLenum internal_format = gl::RGBA32I;
static constexpr GLenum format = gl::RGBA_INTEGER;
@ -386,7 +386,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<float16, 2>>
struct pixel_traits<math::vector<float16, 2>>
{
static constexpr GLenum internal_format = gl::RG16F;
static constexpr GLenum format = gl::RG;
@ -394,7 +394,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<float16, 3>>
struct pixel_traits<math::vector<float16, 3>>
{
static constexpr GLenum internal_format = gl::RGB16F;
static constexpr GLenum format = gl::RGB;
@ -402,7 +402,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<float16, 4>>
struct pixel_traits<math::vector<float16, 4>>
{
static constexpr GLenum internal_format = gl::RGBA16F;
static constexpr GLenum format = gl::RGBA;
@ -420,7 +420,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<float, 2>>
struct pixel_traits<math::vector<float, 2>>
{
static constexpr GLenum internal_format = gl::RG32F;
static constexpr GLenum format = gl::RG;
@ -428,7 +428,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<float, 3>>
struct pixel_traits<math::vector<float, 3>>
{
static constexpr GLenum internal_format = gl::RGB32F;
static constexpr GLenum format = gl::RGB;
@ -436,7 +436,7 @@ namespace psemek::gfx
};
template <>
struct pixel_traits<geom::vector<float, 4>>
struct pixel_traits<math::vector<float, 4>>
{
static constexpr GLenum internal_format = gl::RGBA32F;
static constexpr GLenum format = gl::RGBA;

View file

@ -2,11 +2,11 @@
#include <psemek/gfx/gl.hpp>
#include <psemek/geom/vector.hpp>
#include <psemek/geom/point.hpp>
#include <psemek/geom/matrix.hpp>
#include <psemek/geom/interval.hpp>
#include <psemek/geom/quaternion.hpp>
#include <psemek/math/vector.hpp>
#include <psemek/math/point.hpp>
#include <psemek/math/matrix.hpp>
#include <psemek/math/interval.hpp>
#include <psemek/math/quaternion.hpp>
#include <boost/container/flat_map.hpp>
@ -53,60 +53,60 @@ namespace psemek::gfx
void operator = (unsigned int i);
void operator = (float f);
void operator = (geom::vector<int, 1> const & v);
void operator = (geom::vector<int, 2> const & v);
void operator = (geom::vector<int, 3> const & v);
void operator = (geom::vector<int, 4> const & v);
void operator = (math::vector<int, 1> const & v);
void operator = (math::vector<int, 2> const & v);
void operator = (math::vector<int, 3> const & v);
void operator = (math::vector<int, 4> const & v);
void operator = (geom::vector<unsigned int, 1> const & v);
void operator = (geom::vector<unsigned int, 2> const & v);
void operator = (geom::vector<unsigned int, 3> const & v);
void operator = (geom::vector<unsigned int, 4> const & v);
void operator = (math::vector<unsigned int, 1> const & v);
void operator = (math::vector<unsigned int, 2> const & v);
void operator = (math::vector<unsigned int, 3> const & v);
void operator = (math::vector<unsigned int, 4> const & v);
void operator = (geom::vector<float, 1> const & v);
void operator = (geom::vector<float, 2> const & v);
void operator = (geom::vector<float, 3> const & v);
void operator = (geom::vector<float, 4> const & v);
void operator = (math::vector<float, 1> const & v);
void operator = (math::vector<float, 2> const & v);
void operator = (math::vector<float, 3> const & v);
void operator = (math::vector<float, 4> const & v);
template <typename T, std::size_t D>
void operator = (geom::vector<T, D> const & v);
void operator = (math::vector<T, D> const & v);
void operator = (geom::point<int, 1> const & v);
void operator = (geom::point<int, 2> const & v);
void operator = (geom::point<int, 3> const & v);
void operator = (geom::point<int, 4> const & v);
void operator = (math::point<int, 1> const & v);
void operator = (math::point<int, 2> const & v);
void operator = (math::point<int, 3> const & v);
void operator = (math::point<int, 4> const & v);
void operator = (geom::point<unsigned int, 1> const & v);
void operator = (geom::point<unsigned int, 2> const & v);
void operator = (geom::point<unsigned int, 3> const & v);
void operator = (geom::point<unsigned int, 4> const & v);
void operator = (math::point<unsigned int, 1> const & v);
void operator = (math::point<unsigned int, 2> const & v);
void operator = (math::point<unsigned int, 3> const & v);
void operator = (math::point<unsigned int, 4> const & v);
void operator = (geom::point<float, 1> const & v);
void operator = (geom::point<float, 2> const & v);
void operator = (geom::point<float, 3> const & v);
void operator = (geom::point<float, 4> const & v);
void operator = (math::point<float, 1> const & v);
void operator = (math::point<float, 2> const & v);
void operator = (math::point<float, 3> const & v);
void operator = (math::point<float, 4> const & v);
template <typename T, std::size_t D>
void operator = (geom::point<T, D> const & v);
void operator = (math::point<T, D> const & v);
void operator = (geom::matrix<float, 2, 2> const & m);
void operator = (geom::matrix<float, 2, 3> const & m);
void operator = (geom::matrix<float, 2, 4> const & m);
void operator = (geom::matrix<float, 3, 2> const & m);
void operator = (geom::matrix<float, 3, 3> const & m);
void operator = (geom::matrix<float, 3, 4> const & m);
void operator = (geom::matrix<float, 4, 2> const & m);
void operator = (geom::matrix<float, 4, 3> const & m);
void operator = (geom::matrix<float, 4, 4> const & m);
void operator = (math::matrix<float, 2, 2> const & m);
void operator = (math::matrix<float, 2, 3> const & m);
void operator = (math::matrix<float, 2, 4> const & m);
void operator = (math::matrix<float, 3, 2> const & m);
void operator = (math::matrix<float, 3, 3> const & m);
void operator = (math::matrix<float, 3, 4> const & m);
void operator = (math::matrix<float, 4, 2> const & m);
void operator = (math::matrix<float, 4, 3> const & m);
void operator = (math::matrix<float, 4, 4> const & m);
void operator = (geom::interval<int> const & i);
void operator = (geom::interval<unsigned int> const & i);
void operator = (geom::interval<float> const & i);
void operator = (math::interval<int> const & i);
void operator = (math::interval<unsigned int> const & i);
void operator = (math::interval<float> const & i);
template <typename T>
void operator = (geom::interval<T> const & i);
void operator = (math::interval<T> const & i);
void operator = (geom::quaternion<float> const & q);
void operator = (math::quaternion<float> const & q);
private:
GLint location_;
@ -129,21 +129,21 @@ namespace psemek::gfx
};
template <typename T, std::size_t D>
void program::uniform_proxy::operator = (geom::vector<T, D> const & v)
void program::uniform_proxy::operator = (math::vector<T, D> const & v)
{
if constexpr (std::is_floating_point_v<T>)
{
(*this) = geom::cast<float>(v);
(*this) = math::cast<float>(v);
}
else if (std::is_integral_v<T>)
{
if constexpr (std::is_unsigned_v<T>)
{
(*this) = geom::cast<unsigned int>(v);
(*this) = math::cast<unsigned int>(v);
}
else
{
(*this) = geom::cast<int>(v);
(*this) = math::cast<int>(v);
}
}
else
@ -153,21 +153,21 @@ namespace psemek::gfx
}
template <typename T, std::size_t D>
void program::uniform_proxy::operator = (geom::point<T, D> const & p)
void program::uniform_proxy::operator = (math::point<T, D> const & p)
{
if constexpr (std::is_floating_point_v<T>)
{
(*this) = geom::cast<float>(p);
(*this) = math::cast<float>(p);
}
else if (std::is_integral_v<T>)
{
if constexpr (std::is_unsigned_v<T>)
{
(*this) = geom::cast<unsigned int>(p);
(*this) = math::cast<unsigned int>(p);
}
else
{
(*this) = geom::cast<int>(p);
(*this) = math::cast<int>(p);
}
}
else
@ -177,21 +177,21 @@ namespace psemek::gfx
}
template <typename T>
void program::uniform_proxy::operator = (geom::interval<T> const & i)
void program::uniform_proxy::operator = (math::interval<T> const & i)
{
if constexpr (std::is_floating_point_v<T>)
{
(*this) = geom::cast<float>(i);
(*this) = math::cast<float>(i);
}
else if (std::is_integral_v<T>)
{
if constexpr (std::is_unsigned_v<T>)
{
(*this) = geom::cast<unsigned int>(i);
(*this) = math::cast<unsigned int>(i);
}
else
{
(*this) = geom::cast<int>(i);
(*this) = math::cast<int>(i);
}
}
else

View file

@ -2,7 +2,7 @@
#include <psemek/gfx/framebuffer.hpp>
#include <psemek/geom/box.hpp>
#include <psemek/math/box.hpp>
#include <psemek/util/assert.hpp>
@ -13,7 +13,7 @@ namespace psemek::gfx
{
gfx::framebuffer const * framebuffer;
GLenum draw_buffer;
geom::box<int, 2> viewport;
math::box<int, 2> viewport;
void bind() const
{

View file

@ -2,7 +2,7 @@
#include <psemek/gfx/gl.hpp>
#include <psemek/gfx/pixel.hpp>
#include <psemek/geom/vector.hpp>
#include <psemek/math/vector.hpp>
#include <cstddef>
#include <optional>
@ -32,31 +32,31 @@ namespace psemek::gfx
void reset();
geom::vector<std::size_t, 2> size() const { return size_; }
math::vector<std::size_t, 2> size() const { return size_; }
std::size_t width() const { return size_[0]; }
std::size_t height() const { return size_[1]; }
std::optional<int> samples() const { return samples_; }
void storage(GLenum internal_format, geom::vector<std::size_t, 2> const & size);
void storage(GLenum internal_format, geom::vector<std::size_t, 2> const & size, int samples);
void storage(GLenum internal_format, math::vector<std::size_t, 2> const & size);
void storage(GLenum internal_format, math::vector<std::size_t, 2> const & size, int samples);
template <typename Pixel>
void storage(geom::vector<std::size_t, 2> const & size)
void storage(math::vector<std::size_t, 2> const & size)
{
storage(pixel_traits<Pixel>::internal_format, size);
}
template <typename Pixel>
void storage(geom::vector<std::size_t, 2> const & size, int samples)
void storage(math::vector<std::size_t, 2> const & size, int samples)
{
storage(pixel_traits<Pixel>::internal_format, size, samples);
}
private:
GLuint id_ = 0;
geom::vector<std::size_t, 2> size_ = {0, 0};
math::vector<std::size_t, 2> size_ = {0, 0};
std::optional<int> samples_ = std::nullopt;
explicit renderbuffer(std::nullptr_t);

View file

@ -6,8 +6,8 @@
#include <psemek/gfx/framebuffer.hpp>
#include <psemek/gfx/render_target.hpp>
#include <psemek/geom/camera.hpp>
#include <psemek/geom/box.hpp>
#include <psemek/math/camera.hpp>
#include <psemek/math/box.hpp>
#include <psemek/util/pimpl.hpp>
#include <psemek/util/function.hpp>
@ -63,19 +63,19 @@ namespace psemek::gfx
gfx::mesh const * mesh = nullptr;
material const * mat = nullptr;
geom::box<float, 3> bbox;
std::optional<geom::matrix<float, 3, 4>> pre_transform;
std::optional<geom::matrix<float, 3, 4>> post_transform;
math::box<float, 3> bbox;
std::optional<math::matrix<float, 3, 4>> pre_transform;
std::optional<math::matrix<float, 3, 4>> post_transform;
};
struct directional_light
{
color_3f color;
geom::vector<float, 3> direction;
math::vector<float, 3> direction;
bool shadowed = true;
std::size_t shadow_map_size = 1024;
std::size_t cascades = 4;
std::vector<geom::interval<float>> cascade_ranges;
std::vector<math::interval<float>> cascade_ranges;
};
struct point_light
@ -86,7 +86,7 @@ namespace psemek::gfx
struct {
float c0, c1, c2;
} attenuation;
geom::point<float, 3> position;
math::point<float, 3> position;
bool shadowed = true;
float min_shadow_distance;
std::size_t shadow_map_size = 1024;
@ -94,7 +94,7 @@ namespace psemek::gfx
struct options
{
geom::camera const * camera;
math::camera const * camera;
std::optional<color_3f> clear_color;
util::function<void()> background_generator;
@ -125,7 +125,7 @@ namespace psemek::gfx
std::optional<ssao_data> ssao;
geom::vector<std::size_t, 3> grid_size{1, 1, 1};
math::vector<std::size_t, 3> grid_size{1, 1, 1};
};
void render(std::vector<object> const & objects, render_target const & target, options const & opts);

View file

@ -4,7 +4,7 @@
#include <psemek/gfx/color.hpp>
#include <psemek/gfx/texture.hpp>
#include <psemek/geom/matrix.hpp>
#include <psemek/math/matrix.hpp>
#include <psemek/util/pimpl.hpp>
@ -37,7 +37,7 @@ namespace psemek::gfx
struct render_options
{
geom::matrix<float, 4, 4> transform;
math::matrix<float, 4, 4> transform;
};
simple_renderer();

View file

@ -4,7 +4,7 @@
#include <psemek/gfx/pixel.hpp>
#include <psemek/gfx/pixmap.hpp>
#include <psemek/gfx/buffer.hpp>
#include <psemek/geom/vector.hpp>
#include <psemek/math/vector.hpp>
#include <optional>
@ -39,19 +39,19 @@ namespace psemek::gfx
GLint internal_format() const { return format_; }
geom::vector<std::size_t, D> size() const { return size_; }
math::vector<std::size_t, D> size() const { return size_; }
std::size_t width() const;
std::size_t height() const;
std::size_t depth() const;
void load(GLint internal_format, geom::vector<std::size_t, D> const & size, GLenum format, GLenum type, const void * data);
void load(GLint internal_format, math::vector<std::size_t, D> const & size, GLenum format, GLenum type, const void * data);
template <typename Pixel>
void load(geom::vector<std::size_t, D> const & size, Pixel const * data = nullptr);
void load(math::vector<std::size_t, D> const & size, Pixel const * data = nullptr);
template <typename Pixel>
void load_srgb(geom::vector<std::size_t, D> const & size, Pixel const * data = nullptr);
void load_srgb(math::vector<std::size_t, D> const & size, Pixel const * data = nullptr);
template <typename Pixel>
void load(util::array<Pixel, D> const & p);
@ -69,7 +69,7 @@ namespace psemek::gfx
Pixmap pixels(int layer = 0) const;
#endif
static basic_texture from_data(GLint internal_format, geom::vector<std::size_t, D> const & size, GLenum format, GLenum type, const void * data);
static basic_texture from_data(GLint internal_format, math::vector<std::size_t, D> const & size, GLenum format, GLenum type, const void * data);
template <typename Pixmap>
static basic_texture from_pixmap(Pixmap const & p);
@ -89,7 +89,7 @@ namespace psemek::gfx
protected:
GLuint id_ = 0;
GLint format_ = 0;
geom::vector<std::size_t, D> size_ = geom::vector<std::size_t, D>::zero();
math::vector<std::size_t, D> size_ = math::vector<std::size_t, D>::zero();
bool uses_mipmaps_ = true;
explicit basic_texture(std::nullptr_t);
@ -132,10 +132,10 @@ namespace psemek::gfx
static GLenum face_to_gl(int f);
void load(int f, GLint internal_format, geom::vector<std::size_t, 2> const & size, GLenum format, GLenum type, const void * data);
void load(int f, GLint internal_format, math::vector<std::size_t, 2> const & size, GLenum format, GLenum type, const void * data);
template <typename Pixel>
void load(int f, geom::vector<std::size_t, 2> const & size, Pixel const * data = nullptr)
void load(int f, math::vector<std::size_t, 2> const & size, Pixel const * data = nullptr)
{
using traits = pixel_traits<Pixel>;
load(f, traits::internal_format, size, traits::format, traits::type, data);
@ -144,7 +144,7 @@ namespace psemek::gfx
template <typename Pixel>
void load(int f, util::array<Pixel, 2> const & p)
{
geom::vector<std::size_t, 2> size;
math::vector<std::size_t, 2> size;
for (std::size_t i = 0; i < 2; ++i) size[i] = p.dim(i);
load(f, size, p.data());
}
@ -194,21 +194,21 @@ namespace psemek::gfx
void bind() const;
void bind(int texture_unit) const;
geom::vector<std::size_t, 2> size() const { return size_; }
math::vector<std::size_t, 2> size() const { return size_; }
std::size_t width() const { return size_[0]; }
std::size_t height() const { return size_[1]; }
int samples() const { return samples_; }
void load(GLint internal_format, geom::vector<std::size_t, 2> const & size, int samples, bool fixed_sample_locations = true);
void load(GLint internal_format, math::vector<std::size_t, 2> const & size, int samples, bool fixed_sample_locations = true);
template <typename Pixel>
void load(geom::vector<std::size_t, 2> const & size, int samples, bool fixed_sample_locations = true);
void load(math::vector<std::size_t, 2> const & size, int samples, bool fixed_sample_locations = true);
protected:
GLuint id_ = 0;
geom::vector<std::size_t, 2> size_ = {0, 0};
math::vector<std::size_t, 2> size_ = {0, 0};
int samples_ = 0;
explicit texture_2d_multisample(std::nullptr_t);
@ -351,7 +351,7 @@ namespace psemek::gfx
}
template <std::size_t D, GLenum Target>
void basic_texture<D, Target>::load(GLint internal_format, geom::vector<std::size_t, D> const & size, GLenum format, GLenum type, const void * data)
void basic_texture<D, Target>::load(GLint internal_format, math::vector<std::size_t, D> const & size, GLenum format, GLenum type, const void * data)
{
bind();
@ -376,7 +376,7 @@ namespace psemek::gfx
template <std::size_t D, GLenum Target>
template <typename Pixel>
void basic_texture<D, Target>::load(geom::vector<std::size_t, D> const & size, Pixel const * data)
void basic_texture<D, Target>::load(math::vector<std::size_t, D> const & size, Pixel const * data)
{
using traits = pixel_traits<Pixel>;
load(traits::internal_format, size, traits::format, traits::type, data);
@ -384,7 +384,7 @@ namespace psemek::gfx
template <std::size_t D, GLenum Target>
template <typename Pixel>
void basic_texture<D, Target>::load_srgb(geom::vector<std::size_t, D> const & size, Pixel const * data)
void basic_texture<D, Target>::load_srgb(math::vector<std::size_t, D> const & size, Pixel const * data)
{
using traits = pixel_traits<srgb<Pixel>>;
load(traits::internal_format, size, traits::format, traits::type, data);
@ -394,7 +394,7 @@ namespace psemek::gfx
template <typename Pixel>
void basic_texture<D, Target>::load(util::array<Pixel, D> const & p)
{
geom::vector<std::size_t, D> size;
math::vector<std::size_t, D> size;
for (std::size_t i = 0; i < D; ++i) size[i] = p.dim(i);
load(size, p.data());
}
@ -403,7 +403,7 @@ namespace psemek::gfx
template <typename Pixel>
void basic_texture<D, Target>::load_srgb(util::array<Pixel, D> const & p)
{
geom::vector<std::size_t, D> size;
math::vector<std::size_t, D> size;
for (std::size_t i = 0; i < D; ++i) size[i] = p.dim(i);
load_srgb(size, p.data());
}
@ -439,7 +439,7 @@ namespace psemek::gfx
#endif
template <std::size_t D, GLenum Target>
basic_texture<D, Target> basic_texture<D, Target>::from_data(GLint internal_format, geom::vector<std::size_t, D> const & size, GLenum format, GLenum type, const void * data)
basic_texture<D, Target> basic_texture<D, Target>::from_data(GLint internal_format, math::vector<std::size_t, D> const & size, GLenum format, GLenum type, const void * data)
{
basic_texture result;
result.load(internal_format, size, format, type, data);
@ -537,7 +537,7 @@ namespace psemek::gfx
#ifndef PSEMEK_GLES
template <typename Pixel>
void texture_2d_multisample::load(geom::vector<std::size_t, 2> const & size, int samples, bool fixed_sample_locations)
void texture_2d_multisample::load(math::vector<std::size_t, 2> const & size, int samples, bool fixed_sample_locations)
{
load(pixel_traits<Pixel>::internal_format, size, samples, fixed_sample_locations);
}
@ -611,7 +611,7 @@ namespace psemek::gfx
{}
template <std::size_t D>
std::size_t mipmap_count(geom::vector<std::size_t, D> const & size)
std::size_t mipmap_count(math::vector<std::size_t, D> const & size)
{
std::size_t s = 0;
for (std::size_t i = 0; i < D; ++i)

View file

@ -1,7 +1,7 @@
#pragma once
#include <psemek/gfx/texture.hpp>
#include <psemek/geom/box.hpp>
#include <psemek/math/box.hpp>
#include <cstdint>
@ -12,12 +12,12 @@ namespace psemek::gfx
struct basic_texture_view
{
basic_texture<D, Target> const * texture = nullptr;
geom::box<float, D> part; // in pixels
math::box<float, D> part; // in pixels
basic_texture_view(basic_texture<D, Target> const * texture = nullptr);
basic_texture_view(basic_texture<D, Target> const * texture, geom::box<float, D> const & part);
basic_texture_view(basic_texture<D, Target> const * texture, math::box<float, D> const & part);
geom::vector<float, D> size() const { return part.dimensions(); }
math::vector<float, D> size() const { return part.dimensions(); }
float width() const
{
@ -49,13 +49,13 @@ namespace psemek::gfx
{
if (texture)
{
static const auto zero = geom::point<float, D>::zero();
part = geom::span(zero, zero + geom::cast<float>(texture->size()));
static const auto zero = math::point<float, D>::zero();
part = math::span(zero, zero + math::cast<float>(texture->size()));
}
}
template <std::size_t D, GLenum Target>
basic_texture_view<D, Target>::basic_texture_view(basic_texture<D, Target> const * texture, geom::box<float, D> const & part)
basic_texture_view<D, Target>::basic_texture_view(basic_texture<D, Target> const * texture, math::box<float, D> const & part)
: texture(texture)
, part(part)
{}

View file

@ -136,7 +136,7 @@ void main()
src.bind();
array.bind();
program.bind();
program["u_inv_texture_size"] = geom::vector{1.f / src.width(), 1.f / src.height()};
program["u_inv_texture_size"] = math::vector{1.f / src.width(), 1.f / src.height()};
gl::DrawArrays(gl::TRIANGLES, 0, 6);
}
};

View file

@ -231,7 +231,7 @@ void main()
src.bind();
impl().array.bind();
impl().program.bind();
impl().program["u_d"] = geom::vector{1.f / src.width(), 1.f / src.height()};
impl().program["u_d"] = math::vector{1.f / src.width(), 1.f / src.height()};
gl::DrawArrays(gl::TRIANGLES, 0, 6);
}

View file

@ -7,7 +7,7 @@ namespace psemek::gfx
{
mesh m;
std::vector<geom::point<float, 2>> vertices(4);
std::vector<math::point<float, 2>> vertices(4);
std::vector<std::uint8_t> indices(6);
vertices[0] = {-1.f, -1.f};
@ -22,7 +22,7 @@ namespace psemek::gfx
indices[4] = 1;
indices[5] = 3;
m.setup<geom::point<float, 2>>();
m.setup<math::point<float, 2>>();
m.load(vertices, indices, gl::STATIC_DRAW);
return m;

View file

@ -6,23 +6,23 @@ namespace psemek::gfx
namespace detail
{
void gltf_animation_traits<gltf_asset::animation::channel::rotation>::canonicalize(geom::easing_type interpolation, std::vector<output_type> & output)
void gltf_animation_traits<gltf_asset::animation::channel::rotation>::canonicalize(math::easing_type interpolation, std::vector<output_type> & output)
{
if (interpolation == geom::easing_type::linear)
if (interpolation == math::easing_type::linear)
{
for (std::size_t i = 1; i < output.size(); ++i)
{
if (geom::dot(output[i - 1].coords, output[i].coords) < 0.f)
if (math::dot(output[i - 1].coords, output[i].coords) < 0.f)
{
output[i] = - output[i];
}
}
}
else if (interpolation == geom::easing_type::cubic)
else if (interpolation == math::easing_type::cubic)
{
for (std::size_t i = 3; i < output.size(); i += 3)
{
if (geom::dot(output[(i - 3) + 1].coords, output[i + 1].coords) < 0.f)
if (math::dot(output[(i - 3) + 1].coords, output[i + 1].coords) < 0.f)
{
output[i + 0] = - output[i + 0];
output[i + 1] = - output[i + 1];
@ -40,14 +40,14 @@ namespace psemek::gfx
auto it = std::lower_bound(input_.begin(), input_.end(), time);
if (it == input_.begin())
{
if (interpolation_ == geom::easing_type::cubic)
if (interpolation_ == math::easing_type::cubic)
return output_[1];
else
return output_.front();
}
if (it == input_.end())
{
if (interpolation_ == geom::easing_type::cubic)
if (interpolation_ == math::easing_type::cubic)
return output_[output_.size() - 2];
else
return output_.back();
@ -60,11 +60,11 @@ namespace psemek::gfx
switch (interpolation_)
{
case geom::easing_type::constant_left:
case math::easing_type::constant_left:
return output_[i - 1];
case geom::easing_type::linear:
case math::easing_type::linear:
return traits::lerp(output_[i - 1], output_[i], t);
case geom::easing_type::cubic:
case math::easing_type::cubic:
{
// see https://github.khronos.org/glTF-Tutorials/gltfTutorial/gltfTutorial_007_Animations.html#cubic-spline-interpolation
float t2 = t * t;
@ -85,16 +85,16 @@ namespace psemek::gfx
template struct gltf_animation_channel<gltf_asset::animation::channel::rotation>;
template struct gltf_animation_channel<gltf_asset::animation::channel::translation>;
geom::interval<float> gltf_animation::range() const
math::interval<float> gltf_animation::range() const
{
return scale_.range() | rotation_.range() | translation_.range();
}
geom::affine_transform<float, 3, 3> gltf_animation::operator()(float time) const
math::affine_transform<float, 3, 3> gltf_animation::operator()(float time) const
{
return geom::translation(translation_(time)).transform()
* geom::quaternion_rotation(rotation_(time)).transform()
* geom::scale(scale_(time)).transform();
return math::translation(translation_(time)).transform()
* math::quaternion_rotation(rotation_(time)).transform()
* math::scale(scale_(time)).transform();
}
}

View file

@ -20,8 +20,8 @@ namespace psemek::gfx
std::size_t index_offset;
GLenum index_type;
std::vector<geom::point<float, 3>> vertices;
std::vector<geom::triangle<std::uint32_t>> triangles;
std::vector<math::point<float, 3>> vertices;
std::vector<math::triangle<std::uint32_t>> triangles;
void draw() const override
{
@ -65,8 +65,8 @@ namespace psemek::gfx
{
std::vector<primitive> primitives;
gltf_asset::extras_map extras;
std::vector<geom::point<float, 3>> vertices;
std::vector<geom::triangle<std::uint32_t>> triangles;
std::vector<math::point<float, 3>> vertices;
std::vector<math::triangle<std::uint32_t>> triangles;
};
std::vector<gltf_asset::material> materials_;
@ -170,7 +170,7 @@ namespace psemek::gfx
}
if (primitive.position)
for (auto const & p : accessor_range<geom::point<float, 3>>(asset, *primitive.position))
for (auto const & p : accessor_range<math::point<float, 3>>(asset, *primitive.position))
drawable.vertices.push_back(p);
target_mesh.primitives.push_back({&drawable, primitive.material, drawable.vertices, drawable.triangles});

View file

@ -1,7 +1,7 @@
#include <psemek/gfx/gltf_parser.hpp>
#include <psemek/geom/scale.hpp>
#include <psemek/geom/rotation.hpp>
#include <psemek/geom/translation.hpp>
#include <psemek/math/scale.hpp>
#include <psemek/math/rotation.hpp>
#include <psemek/math/translation.hpp>
#include <psemek/util/to_string.hpp>
#include <psemek/util/hash_table.hpp>
#include <psemek/util/exception.hpp>
@ -158,7 +158,7 @@ namespace psemek::gfx
target.translation[i] = translation[i].GetFloat();
}
target.rotation = geom::quaternion<float>::identity();
target.rotation = math::quaternion<float>::identity();
if (node.HasMember("rotation"))
{
auto const & rotation = node["rotation"].GetArray();
@ -174,9 +174,9 @@ namespace psemek::gfx
target.scale[i] = scale[i].GetFloat();
}
target.transform = geom::translation(target.translation).transform()
* geom::quaternion_rotation(target.rotation).transform()
* geom::scale(target.scale).transform();
target.transform = math::translation(target.translation).transform()
* math::quaternion_rotation(target.rotation).transform()
* math::scale(target.scale).transform();
if (node.HasMember("children"))
{
@ -346,11 +346,11 @@ namespace psemek::gfx
std::string interpolation{sampler["interpolation"].GetString()};
if (interpolation == "STEP")
sampler_target.interpolation = geom::easing_type::constant_left;
sampler_target.interpolation = math::easing_type::constant_left;
else if (interpolation == "LINEAR")
sampler_target.interpolation = geom::easing_type::linear;
sampler_target.interpolation = math::easing_type::linear;
else if (interpolation == "CUBICSPLINE")
sampler_target.interpolation = geom::easing_type::cubic;
sampler_target.interpolation = math::easing_type::cubic;
else
throw util::exception("Unknown glTF animation interpolation type: " + interpolation);
}
@ -403,7 +403,7 @@ namespace psemek::gfx
target.color = {1.f, 1.f, 1.f};
target.intensity = 1.f;
target.range = std::numeric_limits<float>::infinity();
target.cone_angle = {0.f, geom::pi / 4.f};
target.cone_angle = {0.f, math::pi / 4.f};
std::string type = light["type"].GetString();

View file

@ -243,27 +243,27 @@ namespace psemek::gfx
vertex_format = s.read<std::uint32_t>();
if (vertex_format & POSITION_MASK)
result.attribs += make_attribs_description<geom::point<float, 3>>();
result.attribs += make_attribs_description<math::point<float, 3>>();
else
result.attribs += make_attribs_description<gfx::skip>();
if (vertex_format & NORMALS_MASK)
result.attribs += make_attribs_description<geom::vector<float, 3>>();
result.attribs += make_attribs_description<math::vector<float, 3>>();
else
result.attribs += make_attribs_description<gfx::skip>();
if (vertex_format & COLORS_MASK)
result.attribs += make_attribs_description<gfx::normalized<geom::vector<std::uint8_t, 4>>>();
result.attribs += make_attribs_description<gfx::normalized<math::vector<std::uint8_t, 4>>>();
else
result.attribs += make_attribs_description<gfx::skip>();
if (vertex_format & TEXCOORDS_MASK)
result.attribs += make_attribs_description<geom::vector<float, 2>>();
result.attribs += make_attribs_description<math::vector<float, 2>>();
else
result.attribs += make_attribs_description<gfx::skip>();
if (vertex_format & WEIGHTS_MASK)
result.attribs += make_attribs_description<gfx::integer<geom::vector<std::uint8_t, 2>>, gfx::normalized<geom::vector<std::uint8_t, 2>>>();
result.attribs += make_attribs_description<gfx::integer<math::vector<std::uint8_t, 2>>, gfx::normalized<math::vector<std::uint8_t, 2>>>();
else
result.attribs += make_attribs_description<gfx::skip, gfx::skip>();

View file

@ -11,9 +11,9 @@ namespace psemek::gfx
obj_data parse_obj(std::istream & is)
{
std::vector<geom::point<float, 3>> positions;
std::vector<geom::vector<float, 2>> texcoords;
std::vector<geom::vector<float, 3>> normals;
std::vector<math::point<float, 3>> positions;
std::vector<math::vector<float, 2>> texcoords;
std::vector<math::vector<float, 3>> normals;
obj_data result;

View file

@ -4,7 +4,7 @@
#include <psemek/gfx/texture.hpp>
#include <psemek/gfx/resource/font_9x12_png.hpp>
#include <psemek/cg/triangulation/ear_clipping.hpp>
#include <psemek/geom/constants.hpp>
#include <psemek/math/constants.hpp>
#include <psemek/io/memory_stream.hpp>
#include <psemek/util/enum.hpp>
@ -113,21 +113,21 @@ namespace psemek::gfx
{
struct vertex
{
geom::point<float, 3> position;
math::point<float, 3> position;
color_rgba color;
};
struct text_vertex
{
geom::point<float, 3> position;
math::point<float, 3> position;
color_rgba color;
geom::point<std::uint16_t, 2> texcoord;
math::point<std::uint16_t, 2> texcoord;
};
struct texture_vertex
{
geom::point<float, 3> position;
geom::point<std::uint16_t, 2> texcoord;
math::point<float, 3> position;
math::point<std::uint16_t, 2> texcoord;
};
gfx::program program{shader_prefix + vertex_source, shader_prefix + fragment_source};
@ -157,9 +157,9 @@ namespace psemek::gfx
impl()
{
mesh.setup<geom::vector<float, 3>, gfx::normalized<color_rgba>>();
text_mesh.setup<geom::point<float, 3>, gfx::normalized<color_rgba>, geom::point<std::uint16_t, 2>>();
texture_mesh.setup<geom::point<float, 3>, gfx::normalized<geom::point<std::uint16_t, 2>>>();
mesh.setup<math::vector<float, 3>, gfx::normalized<color_rgba>>();
text_mesh.setup<math::point<float, 3>, gfx::normalized<color_rgba>, math::point<std::uint16_t, 2>>();
texture_mesh.setup<math::point<float, 3>, gfx::normalized<math::point<std::uint16_t, 2>>>();
font_texture.load(gfx::read_image<std::uint8_t>(io::memory_istream{resource::font_9x12_png.data}));
@ -180,12 +180,12 @@ namespace psemek::gfx
painter::~painter() = default;
void painter::triangle(geom::point<float, 2> const & p0, geom::point<float, 2> const & p1, geom::point<float, 2> const & p2, color const & c)
void painter::triangle(math::point<float, 2> const & p0, math::point<float, 2> const & p1, math::point<float, 2> const & p2, color const & c)
{
triangle(p0, p1, p2, c, c, c);
}
void painter::triangle(geom::point<float, 2> const & p0, geom::point<float, 2> const & p1, geom::point<float, 2> const & p2, color const & c0, color const & c1, color const & c2)
void painter::triangle(math::point<float, 2> const & p0, math::point<float, 2> const & p1, math::point<float, 2> const & p2, color const & c0, color const & c1, color const & c2)
{
std::uint32_t const base = impl().vertices.size();
@ -198,7 +198,7 @@ namespace psemek::gfx
impl().indices.push_back(base + 2);
}
void painter::rect(geom::box<float, 2> const & box, color const & c)
void painter::rect(math::box<float, 2> const & box, color const & c)
{
std::uint32_t const base = impl().vertices.size();
@ -215,14 +215,14 @@ namespace psemek::gfx
impl().indices.push_back(base + 2);
}
void painter::circle(geom::point<float, 2> const & p, float r, color const & c, int quality)
void painter::circle(math::point<float, 2> const & p, float r, color const & c, int quality)
{
std::uint32_t const base = impl().vertices.size();
impl().vertices.push_back({{p[0], p[1], 0.f}, c});
for (int i = 0; i < quality; ++i)
{
float const a = (geom::pi * 2.f * i) / quality;
float const a = (math::pi * 2.f * i) / quality;
impl().vertices.push_back({{p[0] + r * std::cos(a), p[1] + r * std::sin(a), 0.f}, c});
}
@ -234,19 +234,19 @@ namespace psemek::gfx
}
}
void painter::line(geom::point<float, 2> const & p0, geom::point<float, 2> const & p1, float width, color const & c, bool smooth)
void painter::line(math::point<float, 2> const & p0, math::point<float, 2> const & p1, float width, color const & c, bool smooth)
{
line(p0, p1, width, width, c, c, smooth);
}
void painter::line(geom::point<float, 2> const & p0, geom::point<float, 2> const & p1, float width0, float width1, color const & c0, color const & c1, bool smooth)
void painter::line(math::point<float, 2> const & p0, math::point<float, 2> const & p1, float width0, float width1, color const & c0, color const & c1, bool smooth)
{
std::uint32_t const base = impl().vertices.size();
float const r0 = width0 / 2.f;
float const r1 = width1 / 2.f;
auto const d = geom::normalized(p1 - p0);
geom::vector<float, 2> const o { -d[1], d[0] };
auto const d = math::normalized(p1 - p0);
math::vector<float, 2> const o { -d[1], d[0] };
impl().vertices.push_back({{p0[0] + r0 * o[0], p0[1] + r0 * o[1], 0.f}, c0});
impl().vertices.push_back({{p0[0] - r0 * o[0], p0[1] - r0 * o[1], 0.f}, c0});
@ -267,7 +267,7 @@ namespace psemek::gfx
}
}
void painter::besier(geom::point<float, 2> const & p0, geom::point<float, 2> const & p1, geom::point<float, 2> const & p2, float width, color const & c, int quality, bool smooth)
void painter::besier(math::point<float, 2> const & p0, math::point<float, 2> const & p1, math::point<float, 2> const & p2, float width, color const & c, int quality, bool smooth)
{
auto at = [&](float t)
{
@ -283,7 +283,7 @@ namespace psemek::gfx
}
}
void painter::polygon(util::span<geom::point<float, 2> const> points, color const & c)
void painter::polygon(util::span<math::point<float, 2> const> points, color const & c)
{
auto dcel = cg::ear_clipping<std::uint32_t>(points.begin(), points.end());
@ -298,10 +298,10 @@ namespace psemek::gfx
}
}
geom::vector<float, 2> painter::text_size(std::string_view str, font f)
math::vector<float, 2> painter::text_size(std::string_view str, font f)
{
// TODO: multiline text
geom::vector<float, 2> s;
math::vector<float, 2> s;
switch (f)
{
case font::font_9x12:
@ -315,12 +315,12 @@ namespace psemek::gfx
return s;
}
void painter::text(geom::point<float, 2> const & p, std::string_view str, text_options const & opts)
void painter::text(math::point<float, 2> const & p, std::string_view str, text_options const & opts)
{
text3d(geom::point{p[0], p[1], 0.f}, str, opts, geom::matrix<float, 3, 3>::identity());
text3d(math::point{p[0], p[1], 0.f}, str, opts, math::matrix<float, 3, 3>::identity());
}
void painter::texture(gfx::texture_2d const & texture, geom::box<float, 2> const & box, color const & c)
void painter::texture(gfx::texture_2d const & texture, math::box<float, 2> const & box, color const & c)
{
impl::texture_render_data data;
data.texture = &texture;
@ -339,9 +339,9 @@ namespace psemek::gfx
impl().textures.push_back(data);
}
void painter::axes(geom::point<float, 3> const & p, float length, float width)
void painter::axes(math::point<float, 3> const & p, float length, float width)
{
geom::vector<float, 3> const d[3]
math::vector<float, 3> const d[3]
{
{ 1.f, 0.f, 0.f },
{ 0.f, 1.f, 0.f },
@ -395,24 +395,24 @@ namespace psemek::gfx
impl().indices.push_back(base + 1);
}
void painter::sphere(geom::point<float, 3> const & p, float radius, color const & c, int quality)
void painter::sphere(math::point<float, 3> const & p, float radius, color const & c, int quality)
{
std::uint32_t const base = impl().vertices.size();
impl().vertices.push_back({p - geom::vector{0.f, 0.f, radius}, c});
impl().vertices.push_back({p + geom::vector{0.f, 0.f, radius}, c});
impl().vertices.push_back({p - math::vector{0.f, 0.f, radius}, c});
impl().vertices.push_back({p + math::vector{0.f, 0.f, radius}, c});
auto const ray = [](float ax, float ay)
{
return geom::vector{std::cos(ax) * std::cos(ay), std::sin(ax) * std::cos(ay), std::sin(ay)};
return math::vector{std::cos(ax) * std::cos(ay), std::sin(ax) * std::cos(ay), std::sin(ay)};
};
for (int y = - quality + 1; y < quality; ++y)
{
for (int x = 0; x < quality * 4; ++x)
{
float ax = (x * geom::pi) / quality / 2.f;
float ay = (y * geom::pi) / quality / 2.f;
float ax = (x * math::pi) / quality / 2.f;
float ay = (y * math::pi) / quality / 2.f;
impl().vertices.push_back({p + radius * ray(ax, ay), c});
}
@ -464,13 +464,13 @@ namespace psemek::gfx
}
}
void painter::line3d(geom::point<float, 3> const & p0, geom::point<float, 3> const & p1, float width, color const & c)
void painter::line3d(math::point<float, 3> const & p0, math::point<float, 3> const & p1, float width, color const & c)
{
std::uint32_t const base = impl().vertices.size();
float const r = width / 2.f;
auto const d = geom::normalized(p1 - p0);
geom::vector<float, 3> const o = geom::normalized(geom::vector{ -d[1], d[0], 0.f });
auto const d = math::normalized(p1 - p0);
math::vector<float, 3> const o = math::normalized(math::vector{ -d[1], d[0], 0.f });
impl().vertices.push_back({{p0[0] + r * o[0], p0[1] + r * o[1], p0[2]}, c});
impl().vertices.push_back({{p0[0] - r * o[0], p0[1] - r * o[1], p0[2]}, c});
@ -485,11 +485,11 @@ namespace psemek::gfx
impl().indices.push_back(base + 2);
}
void painter::text3d(geom::point<float, 3> const & p, std::string_view str, text_options const & opts, geom::matrix<float, 3, 3> const & t)
void painter::text3d(math::point<float, 3> const & p, std::string_view str, text_options const & opts, math::matrix<float, 3, 3> const & t)
{
auto const size = geom::pointwise_mult(text_size(str, opts.f), opts.scale);
auto const size = math::pointwise_mult(text_size(str, opts.f), opts.scale);
geom::vector<float, 3> pen { 0.f, 0.f, 0.f };
math::vector<float, 3> pen { 0.f, 0.f, 0.f };
switch (opts.x)
{
@ -519,12 +519,12 @@ namespace psemek::gfx
throw util::unknown_enum_value_exception(opts.y);
}
geom::vector<float, 3> const sx = {9.f * opts.scale[0], 0.f, 0.f};
geom::vector<float, 3> const sy = {0.f, 12.f * opts.scale[1], 0.f};
math::vector<float, 3> const sx = {9.f * opts.scale[0], 0.f, 0.f};
math::vector<float, 3> const sy = {0.f, 12.f * opts.scale[1], 0.f};
auto to_texcoord = [](int tx, int ty, int ix, int iy)
{
return geom::point<std::uint16_t, 2>{ tx * 11 + (ix == 0 ? 1 : 10), ty * 14 + (iy == 0 ? 1 : 13) };
return math::point<std::uint16_t, 2>{ tx * 11 + (ix == 0 ? 1 : 10), ty * 14 + (iy == 0 ? 1 : 13) };
};
for (char c : str)
@ -568,7 +568,7 @@ namespace psemek::gfx
}
}
void painter::render(geom::matrix<float, 4, 4> const & transform)
void painter::render(math::matrix<float, 4, 4> const & transform)
{
gl::ActiveTexture(gl::TEXTURE0);

View file

@ -31,187 +31,187 @@ namespace psemek::gfx
gl::Uniform1f(location_, f);
}
void program::uniform_proxy::operator = (geom::vector<int, 1> const & v)
void program::uniform_proxy::operator = (math::vector<int, 1> const & v)
{
gl::Uniform1i(location_, v[0]);
}
void program::uniform_proxy::operator = (geom::vector<int, 2> const & v)
void program::uniform_proxy::operator = (math::vector<int, 2> const & v)
{
gl::Uniform2i(location_, v[0], v[1]);
}
void program::uniform_proxy::operator = (geom::vector<int, 3> const & v)
void program::uniform_proxy::operator = (math::vector<int, 3> const & v)
{
gl::Uniform3i(location_, v[0], v[1], v[2]);
}
void program::uniform_proxy::operator = (geom::vector<int, 4> const & v)
void program::uniform_proxy::operator = (math::vector<int, 4> const & v)
{
gl::Uniform4i(location_, v[0], v[1], v[2], v[3]);
}
void program::uniform_proxy::operator = (geom::vector<unsigned int, 1> const & v)
void program::uniform_proxy::operator = (math::vector<unsigned int, 1> const & v)
{
gl::Uniform1ui(location_, v[0]);
}
void program::uniform_proxy::operator = (geom::vector<unsigned int, 2> const & v)
void program::uniform_proxy::operator = (math::vector<unsigned int, 2> const & v)
{
gl::Uniform2ui(location_, v[0], v[1]);
}
void program::uniform_proxy::operator = (geom::vector<unsigned int, 3> const & v)
void program::uniform_proxy::operator = (math::vector<unsigned int, 3> const & v)
{
gl::Uniform3ui(location_, v[0], v[1], v[2]);
}
void program::uniform_proxy::operator = (geom::vector<unsigned int, 4> const & v)
void program::uniform_proxy::operator = (math::vector<unsigned int, 4> const & v)
{
gl::Uniform4ui(location_, v[0], v[1], v[2], v[3]);
}
void program::uniform_proxy::operator = (geom::vector<float, 1> const & v)
void program::uniform_proxy::operator = (math::vector<float, 1> const & v)
{
gl::Uniform1f(location_, v[0]);
}
void program::uniform_proxy::operator = (geom::vector<float, 2> const & v)
void program::uniform_proxy::operator = (math::vector<float, 2> const & v)
{
gl::Uniform2f(location_, v[0], v[1]);
}
void program::uniform_proxy::operator = (geom::vector<float, 3> const & v)
void program::uniform_proxy::operator = (math::vector<float, 3> const & v)
{
gl::Uniform3f(location_, v[0], v[1], v[2]);
}
void program::uniform_proxy::operator = (geom::vector<float, 4> const & v)
void program::uniform_proxy::operator = (math::vector<float, 4> const & v)
{
gl::Uniform4f(location_, v[0], v[1], v[2], v[3]);
}
void program::uniform_proxy::operator = (geom::point<int, 1> const & v)
void program::uniform_proxy::operator = (math::point<int, 1> const & v)
{
gl::Uniform1i(location_, v[0]);
}
void program::uniform_proxy::operator = (geom::point<int, 2> const & v)
void program::uniform_proxy::operator = (math::point<int, 2> const & v)
{
gl::Uniform2i(location_, v[0], v[1]);
}
void program::uniform_proxy::operator = (geom::point<int, 3> const & v)
void program::uniform_proxy::operator = (math::point<int, 3> const & v)
{
gl::Uniform3i(location_, v[0], v[1], v[2]);
}
void program::uniform_proxy::operator = (geom::point<int, 4> const & v)
void program::uniform_proxy::operator = (math::point<int, 4> const & v)
{
gl::Uniform4i(location_, v[0], v[1], v[2], v[3]);
}
void program::uniform_proxy::operator = (geom::point<unsigned int, 1> const & v)
void program::uniform_proxy::operator = (math::point<unsigned int, 1> const & v)
{
gl::Uniform1ui(location_, v[0]);
}
void program::uniform_proxy::operator = (geom::point<unsigned int, 2> const & v)
void program::uniform_proxy::operator = (math::point<unsigned int, 2> const & v)
{
gl::Uniform2ui(location_, v[0], v[1]);
}
void program::uniform_proxy::operator = (geom::point<unsigned int, 3> const & v)
void program::uniform_proxy::operator = (math::point<unsigned int, 3> const & v)
{
gl::Uniform3ui(location_, v[0], v[1], v[2]);
}
void program::uniform_proxy::operator = (geom::point<unsigned int, 4> const & v)
void program::uniform_proxy::operator = (math::point<unsigned int, 4> const & v)
{
gl::Uniform4ui(location_, v[0], v[1], v[2], v[3]);
}
void program::uniform_proxy::operator = (geom::point<float, 1> const & v)
void program::uniform_proxy::operator = (math::point<float, 1> const & v)
{
gl::Uniform1f(location_, v[0]);
}
void program::uniform_proxy::operator = (geom::point<float, 2> const & v)
void program::uniform_proxy::operator = (math::point<float, 2> const & v)
{
gl::Uniform2f(location_, v[0], v[1]);
}
void program::uniform_proxy::operator = (geom::point<float, 3> const & v)
void program::uniform_proxy::operator = (math::point<float, 3> const & v)
{
gl::Uniform3f(location_, v[0], v[1], v[2]);
}
void program::uniform_proxy::operator = (geom::point<float, 4> const & v)
void program::uniform_proxy::operator = (math::point<float, 4> const & v)
{
gl::Uniform4f(location_, v[0], v[1], v[2], v[3]);
}
void program::uniform_proxy::operator = (geom::matrix<float, 2, 2> const & m)
void program::uniform_proxy::operator = (math::matrix<float, 2, 2> const & m)
{
gl::UniformMatrix2fv(location_, 1, gl::TRUE, m.coords);
}
void program::uniform_proxy::operator = (geom::matrix<float, 2, 3> const & m)
void program::uniform_proxy::operator = (math::matrix<float, 2, 3> const & m)
{
gl::UniformMatrix3x2fv(location_, 1, gl::TRUE, m.coords);
}
void program::uniform_proxy::operator = (geom::matrix<float, 2, 4> const & m)
void program::uniform_proxy::operator = (math::matrix<float, 2, 4> const & m)
{
gl::UniformMatrix4x2fv(location_, 1, gl::TRUE, m.coords);
}
void program::uniform_proxy::operator = (geom::matrix<float, 3, 2> const & m)
void program::uniform_proxy::operator = (math::matrix<float, 3, 2> const & m)
{
gl::UniformMatrix2x3fv(location_, 1, gl::TRUE, m.coords);
}
void program::uniform_proxy::operator = (geom::matrix<float, 3, 3> const & m)
void program::uniform_proxy::operator = (math::matrix<float, 3, 3> const & m)
{
gl::UniformMatrix3fv(location_, 1, gl::TRUE, m.coords);
}
void program::uniform_proxy::operator = (geom::matrix<float, 3, 4> const & m)
void program::uniform_proxy::operator = (math::matrix<float, 3, 4> const & m)
{
gl::UniformMatrix4x3fv(location_, 1, gl::TRUE, m.coords);
}
void program::uniform_proxy::operator = (geom::matrix<float, 4, 2> const & m)
void program::uniform_proxy::operator = (math::matrix<float, 4, 2> const & m)
{
gl::UniformMatrix2x4fv(location_, 1, gl::TRUE, m.coords);
}
void program::uniform_proxy::operator = (geom::matrix<float, 4, 3> const & m)
void program::uniform_proxy::operator = (math::matrix<float, 4, 3> const & m)
{
gl::UniformMatrix3x4fv(location_, 1, gl::TRUE, m.coords);
}
void program::uniform_proxy::operator = (geom::matrix<float, 4, 4> const & m)
void program::uniform_proxy::operator = (math::matrix<float, 4, 4> const & m)
{
gl::UniformMatrix4fv(location_, 1, gl::TRUE, m.coords);
}
void program::uniform_proxy::operator = (geom::interval<int> const & i)
void program::uniform_proxy::operator = (math::interval<int> const & i)
{
gl::Uniform2i(location_, i.min, i.max);
}
void program::uniform_proxy::operator = (geom::interval<unsigned int> const & i)
void program::uniform_proxy::operator = (math::interval<unsigned int> const & i)
{
gl::Uniform2ui(location_, i.min, i.max);
}
void program::uniform_proxy::operator = (geom::interval<float> const & i)
void program::uniform_proxy::operator = (math::interval<float> const & i)
{
gl::Uniform2f(location_, i.min, i.max);
}
void program::uniform_proxy::operator = (geom::quaternion<float> const & q)
void program::uniform_proxy::operator = (math::quaternion<float> const & q)
{
(*this) = q.coords;
}

View file

@ -47,7 +47,7 @@ namespace psemek::gfx
id_ = 0;
}
void renderbuffer::storage(GLenum internal_format, geom::vector<std::size_t, 2> const & size)
void renderbuffer::storage(GLenum internal_format, math::vector<std::size_t, 2> const & size)
{
bind();
gl::RenderbufferStorage(target, internal_format, size[0], size[1]);
@ -55,7 +55,7 @@ namespace psemek::gfx
samples_ = std::nullopt;
}
void renderbuffer::storage(GLenum internal_format, geom::vector<std::size_t, 2> const & size, int samples)
void renderbuffer::storage(GLenum internal_format, math::vector<std::size_t, 2> const & size, int samples)
{
bind();
gl::RenderbufferStorageMultisample(target, samples, internal_format, size[0], size[1]);

View file

@ -14,11 +14,11 @@
#include <psemek/random/uniform_hemiball.hpp>
#include <psemek/random/uniform_sphere.hpp>
#include <psemek/geom/homogeneous.hpp>
#include <psemek/geom/gram_schmidt.hpp>
#include <psemek/geom/translation.hpp>
#include <psemek/geom/mesh.hpp>
#include <psemek/geom/contains.hpp>
#include <psemek/math/homogeneous.hpp>
#include <psemek/math/gram_schmidt.hpp>
#include <psemek/math/translation.hpp>
#include <psemek/math/mesh.hpp>
#include <psemek/math/contains.hpp>
#include <psemek/cg/convex_hull_2d/graham.hpp>
#include <psemek/cg/body/frustum.hpp>
@ -758,9 +758,9 @@ R"(#version 330
void main(){}
)";
static std::size_t bbox_to_screen_fan(geom::matrix<float, 4, 4> const & camera_transform, geom::box<float, 3> const & b, geom::point<float, 2> * result)
static std::size_t bbox_to_screen_fan(math::matrix<float, 4, 4> const & camera_transform, math::box<float, 3> const & b, math::point<float, 2> * result)
{
geom::point<float, 2> bbox_corners_screen[8];
math::point<float, 2> bbox_corners_screen[8];
auto bbox_corners_screen_end = bbox_corners_screen;
bool need_clipping = false;
@ -770,12 +770,12 @@ void main(){}
{
for (int x = 0; x < 2; ++x)
{
geom::point<float, 3> p;
p[0] = geom::lerp<float>(b[0], x);
p[1] = geom::lerp<float>(b[1], y);
p[2] = geom::lerp<float>(b[2], z);
math::point<float, 3> p;
p[0] = math::lerp<float>(b[0], x);
p[1] = math::lerp<float>(b[1], y);
p[2] = math::lerp<float>(b[2], z);
auto q = camera_transform * geom::homogeneous(p);
auto q = camera_transform * math::homogeneous(p);
if (q[2] < -q[3] || q[2] > q[3])
{
@ -797,7 +797,7 @@ void main(){}
return 4;
}
geom::point<float, 2> * bbox_hull_screen_it[8];
math::point<float, 2> * bbox_hull_screen_it[8];
auto bbox_hull_size = cg::graham_convex_hull(bbox_corners_screen, bbox_corners_screen_end, bbox_hull_screen_it) - bbox_hull_screen_it;
for (std::size_t i = 0; i < bbox_hull_size; ++i)
@ -837,7 +837,7 @@ void main(){}
// Only albedo & depth attached
gfx::framebuffer transparent_framebuffer;
std::optional<geom::vector<std::size_t, 2>> g_buffer_size;
std::optional<math::vector<std::size_t, 2>> g_buffer_size;
gfx::framebuffer directional_shadow_framebuffer;
gfx::texture_2d_array directional_shadow_texture;
@ -849,7 +849,7 @@ void main(){}
std::map<std::pair<int, float>, vblur> vblur_container;
overlay bloom_overlay;
std::optional<geom::vector<std::size_t, 2>> bloom_size;
std::optional<math::vector<std::size_t, 2>> bloom_size;
std::optional<std::size_t> bloom_downsample;
// 0: original, unblurred bloom
@ -860,7 +860,7 @@ void main(){}
gfx::texture_2d ssao_rotation_texture;
std::optional<geom::vector<std::size_t, 2>> ssao_size;
std::optional<math::vector<std::size_t, 2>> ssao_size;
std::optional<std::size_t> ssao_downsample;
// 0: original, unblurred ssao
@ -876,7 +876,7 @@ void main(){}
std::vector<GLuint> queries;
gfx::array box_array;
std::optional<geom::matrix<float, 4, 4>> prev_transform;
std::optional<math::matrix<float, 4, 4>> prev_transform;
};
deferred_renderer::deferred_renderer()
@ -934,8 +934,8 @@ void main(){}
random::generator rng{0xaa8e8eabull, 0x44a700e7ull};
{
random::uniform_hemiball_vector_distribution<float, 3> d{geom::vector{0.f, 0.f, 1.f}};
std::vector<geom::vector<float, 3>> ssao_kernel(32);
random::uniform_hemiball_vector_distribution<float, 3> d{math::vector{0.f, 0.f, 1.f}};
std::vector<math::vector<float, 3>> ssao_kernel(32);
for (auto & v : ssao_kernel)
v = d(rng);
@ -949,7 +949,7 @@ void main(){}
{
random::uniform_sphere_vector_distribution<float, 2> d;
basic_pixmap<geom::vector<float, 2>> pm({8, 8});
basic_pixmap<math::vector<float, 2>> pm({8, 8});
for (auto & v : pm)
v = d(rng);
@ -975,7 +975,7 @@ void main(){}
impl().ssao_pass_program["u_g3"] = 3;
impl().ssao_pass_program["u_ssao_rotation"] = 4;
impl().screen_mesh.setup<geom::point<float, 2>>();
impl().screen_mesh.setup<math::point<float, 2>>();
}
deferred_renderer::~deferred_renderer() = default;
@ -1047,12 +1047,12 @@ void main(){}
struct bin
{
util::hash_map<std::tuple<std::uint32_t, material const *>, objects_bucket> buckets;
geom::box<float, 3> bbox;
math::box<float, 3> bbox;
bool contains_near_clip = false;
float camera_separation;
};
geom::box<float, 3> all_bbox;
math::box<float, 3> all_bbox;
std::vector<float> camera_distance(objects.size());
for (std::size_t i = 0; i < objects.size(); ++i)
@ -1071,8 +1071,8 @@ void main(){}
util::array<bin, 3> bins({opts.grid_size[0], opts.grid_size[1], opts.grid_size[2]});
geom::box<float, 3> lit_bbox;
geom::box<float, 3> casts_shadow_bbox;
math::box<float, 3> lit_bbox;
math::box<float, 3> casts_shadow_bbox;
for (std::size_t i = 0; i < objects.size(); ++i)
{
@ -1090,9 +1090,9 @@ void main(){}
auto c = o.bbox.center() - all_bbox.corner(0, 0, 0);
int bx = geom::clamp(std::floor(c[0] / all_bbox[0].length() * opts.grid_size[0]), {0, opts.grid_size[0] - 1});
int by = geom::clamp(std::floor(c[1] / all_bbox[1].length() * opts.grid_size[1]), {0, opts.grid_size[1] - 1});
int bz = geom::clamp(std::floor(c[2] / all_bbox[2].length() * opts.grid_size[2]), {0, opts.grid_size[2] - 1});
int bx = math::clamp(std::floor(c[0] / all_bbox[0].length() * opts.grid_size[0]), {0, opts.grid_size[0] - 1});
int by = math::clamp(std::floor(c[1] / all_bbox[1].length() * opts.grid_size[1]), {0, opts.grid_size[1] - 1});
int bz = math::clamp(std::floor(c[2] / all_bbox[2].length() * opts.grid_size[2]), {0, opts.grid_size[2] - 1});
bin & b = bins(bx, by, bz);
@ -1105,13 +1105,13 @@ void main(){}
for (auto & b : bins)
{
b.bbox = geom::expand(b.bbox, b.bbox.dimensions() / 64.f);
b.bbox = math::expand(b.bbox, b.bbox.dimensions() / 64.f);
b.camera_separation = cg::separation(camera_frustum, cg::box{b.bbox}).distance;
b.contains_near_clip = true;
for (int i = 0; i < 4; ++i)
b.contains_near_clip &= geom::contains(b.bbox, camera_frustum.vertices[i]);
b.contains_near_clip &= math::contains(b.bbox, camera_frustum.vertices[i]);
for (auto & p : b.buckets)
{
@ -1162,7 +1162,7 @@ void main(){}
mat->bump_map->bind();
}
program["u_material"] = geom::vector<float, 2>{mat->specular.intensity, mat->specular.shininess};
program["u_material"] = math::vector<float, 2>{mat->specular.intensity, mat->specular.shininess};
for (std::size_t i = clip_by_camera ? p.second.first_visible : 0; i < p.second.objects.size(); ++i)
{
@ -1187,20 +1187,20 @@ void main(){}
// Resize g-buffer if needed
auto const buffer_size = geom::cast<std::size_t>(target.viewport.dimensions());
auto const buffer_size = math::cast<std::size_t>(target.viewport.dimensions());
bool const buffer_size_changed = !impl().g_buffer_size || *impl().g_buffer_size != buffer_size;
if (buffer_size_changed || impl().position_mode_changed)
{
if (impl().position_mode == position_mode::float16)
impl().g_buffer_texture[0].load<geom::vector<gfx::float16, 3>>(buffer_size);
impl().g_buffer_texture[0].load<math::vector<gfx::float16, 3>>(buffer_size);
else if (impl().position_mode == position_mode::float32)
impl().g_buffer_texture[0].load<geom::vector<float, 3>>(buffer_size);
impl().g_buffer_texture[0].load<math::vector<float, 3>>(buffer_size);
if (buffer_size_changed)
{
impl().g_buffer_texture[1].load<geom::vector<std::uint16_t, 4>>(buffer_size);
impl().g_buffer_texture[1].load<math::vector<std::uint16_t, 4>>(buffer_size);
impl().g_buffer_texture[2].load<gfx::integer<std::uint32_t>>(buffer_size);
impl().g_buffer_texture[3].load<geom::vector<gfx::float16, 2>>(buffer_size);
impl().g_buffer_texture[3].load<math::vector<gfx::float16, 2>>(buffer_size);
impl().g_buffer_depth.load<gfx::depth24_pixel>(buffer_size);
}
@ -1309,8 +1309,8 @@ void main(){}
if (b.contains_near_clip) continue;
if (b.camera_separation > 0.f) continue;
impl().occlusion_pass_program["u_box_min"] = geom::vector{b.bbox[0].min, b.bbox[1].min, b.bbox[2].min};
impl().occlusion_pass_program["u_box_max"] = geom::vector{b.bbox[0].max, b.bbox[1].max, b.bbox[2].max};
impl().occlusion_pass_program["u_box_min"] = math::vector{b.bbox[0].min, b.bbox[1].min, b.bbox[2].min};
impl().occlusion_pass_program["u_box_max"] = math::vector{b.bbox[0].max, b.bbox[1].max, b.bbox[2].max};
gl::BeginQuery(gl::ANY_SAMPLES_PASSED, impl().queries[bi]);
gl::DrawArrays(gl::TRIANGLES, 0, 36);
@ -1484,7 +1484,7 @@ void main(){}
impl().ssao_pass_program.bind();
gl::ActiveTexture(gl::TEXTURE4);
impl().ssao_rotation_texture.bind();
impl().ssao_pass_program["u_ssao_rotation_step"] = geom::cast<float>(impl().ssao_texture[0].size()) / (1.f * impl().ssao_rotation_texture.width());
impl().ssao_pass_program["u_ssao_rotation_step"] = math::cast<float>(impl().ssao_texture[0].size()) / (1.f * impl().ssao_rotation_texture.width());
impl().ssao_pass_program["u_ssao_radius"] = opts.ssao->radius;
impl().ssao_pass_program["u_transform"] = camera_transform;
impl().ssao_pass_program["u_view"] = opts.camera->view();
@ -1554,7 +1554,7 @@ void main(){}
// Directional lights
geom::point<float, 2> bbox_hull_screen[8];
math::point<float, 2> bbox_hull_screen[8];
auto lit_bbox_hull_size = bbox_to_screen_fan(camera_transform, lit_bbox, bbox_hull_screen);
impl().screen_mesh.load(bbox_hull_screen, lit_bbox_hull_size, gl::TRIANGLE_FAN);
@ -1563,7 +1563,7 @@ void main(){}
for (auto const & l : opts.directional_lights)
{
std::vector<geom::matrix<float, 4, 4>> light_transform;
std::vector<math::matrix<float, 4, 4>> light_transform;
if (l.shadowed)
{
@ -1576,16 +1576,16 @@ void main(){}
// Compute cascade split points
auto dir = geom::as_vector(camera_clip_planes[4]);
std::vector<geom::interval<float>> cascade_splits(l.cascades);
auto dir = math::as_vector(camera_clip_planes[4]);
std::vector<math::interval<float>> cascade_splits(l.cascades);
{
float offset;
auto dir_length = geom::length(dir);
auto dir_length = math::length(dir);
float near = camera_clip_planes[4][3] / dir_length;
dir /= dir_length;
offset = geom::dot(camera_position - geom::point<float, 3>::zero(), dir);
offset = math::dot(camera_position - math::point<float, 3>::zero(), dir);
near += offset;
float far = -camera_clip_planes[5][3] / geom::length(geom::as_vector(camera_clip_planes[5])) - offset;
float far = -camera_clip_planes[5][3] / math::length(math::as_vector(camera_clip_planes[5])) - offset;
if (l.cascade_ranges.empty())
{
@ -1615,39 +1615,39 @@ void main(){}
impl().directional_shadow_texture.load<depth24_pixel>({l.shadow_map_size, l.shadow_map_size, l.cascades});
}
geom::vector<float, 3> light_axes[3];
math::vector<float, 3> light_axes[3];
light_axes[2] = -geom::normalized(l.direction);
light_axes[2] = -math::normalized(l.direction);
light_axes[1] = {0.f, 0.f, 1.f};
if (light_axes[2][2] > 0.5f)
light_axes[1] = {0.f, 1.f, 0.f};
geom::gram_schmidt(light_axes[2], light_axes[1]);
math::gram_schmidt(light_axes[2], light_axes[1]);
light_axes[0] = geom::cross(light_axes[2], light_axes[1]);
light_axes[0] = math::cross(light_axes[2], light_axes[1]);
for (int cascade = 0; cascade < l.cascades; ++cascade)
{
geom::box<float, 3> shadowed_bbox;
math::box<float, 3> shadowed_bbox;
geom::matrix<float, 4, 4> cascade_transform = camera_transform;
math::matrix<float, 4, 4> cascade_transform = camera_transform;
{
float near = cascade_splits[cascade].max;
float far = cascade_splits[cascade].min;
geom::vector<float, 2> b;
math::vector<float, 2> b;
b[0] = -2.f * cascade_transform[3][dir_max_index];
b[1] = -2.f * cascade_transform[3][3];
geom::matrix<float, 2, 2> m;
math::matrix<float, 2, 2> m;
m[0][0] = - dir[dir_max_index];
m[0][1] = dir[dir_max_index];
m[1][0] = -near;
m[1][1] = far;
geom::gauss(m, b);
math::gauss(m, b);
for (std::size_t i = 0; i < 3; ++i)
cascade_transform[2][i] = dir[i] * (b[0] + b[1]) / 2.f;
@ -1661,20 +1661,20 @@ void main(){}
shadowed_bbox &= casts_shadow_bbox;
static auto const origin = geom::point<float, 3>::zero();
static auto const origin = math::point<float, 3>::zero();
geom::box<float, 3> light_bbox;
math::box<float, 3> light_bbox;
for (auto const & v : geom::vertices(shadowed_bbox))
for (auto const & v : math::vertices(shadowed_bbox))
{
for (std::size_t i = 0; i < 3; ++i)
light_bbox[i] |= geom::dot(light_axes[i], v - origin);
light_bbox[i] |= math::dot(light_axes[i], v - origin);
}
for (auto const & v : geom::vertices(casts_shadow_bbox))
light_bbox[2] |= geom::dot(light_axes[2], v - origin);
for (auto const & v : math::vertices(casts_shadow_bbox))
light_bbox[2] |= math::dot(light_axes[2], v - origin);
light_transform[cascade] = geom::orthographic_camera{light_bbox}.projection() * geom::homogeneous(geom::by_rows(light_axes[0], light_axes[1], light_axes[2]));
light_transform[cascade] = math::orthographic_camera{light_bbox}.projection() * math::homogeneous(math::by_rows(light_axes[0], light_axes[1], light_axes[2]));
cg::frustum<float, 3> light_frustum{light_transform[cascade]};
@ -1747,7 +1747,7 @@ void main(){}
impl().directional_light_pass_program["u_camera_position"] = camera_position;
impl().directional_light_pass_program["u_max_intensity"] = opts.max_intensity;
impl().directional_light_pass_program["u_light_direction"] = geom::normalized(l.direction);
impl().directional_light_pass_program["u_light_direction"] = math::normalized(l.direction);
impl().directional_light_pass_program["u_light_color"] = l.color;
impl().directional_light_pass_program["u_shadowed"] = l.shadowed;
if (l.shadowed)
@ -1772,11 +1772,11 @@ void main(){}
for (auto const & l : opts.point_lights)
{
float I = std::max({l.color[0], l.color[1], l.color[2]});
auto r = geom::solve_quadratic(l.attenuation.c2, l.attenuation.c1, l.attenuation.c0 - I / min_intensity);
auto r = math::solve_quadratic(l.attenuation.c2, l.attenuation.c1, l.attenuation.c0 - I / min_intensity);
float near = l.min_shadow_distance;
geom::vector<float, 3> far_positive;
geom::vector<float, 3> far_negative;
math::vector<float, 3> far_positive;
math::vector<float, 3> far_negative;
for (std::size_t i = 0; i < 3; ++i)
{
@ -1795,12 +1795,12 @@ void main(){}
if (l.shadowed)
{
geom::matrix<float, 4, 4> transform[6];
math::matrix<float, 4, 4> transform[6];
// +X
{
float far = far_positive[0];
transform[0] = geom::matrix<float, 4, 4>::zero();
transform[0] = math::matrix<float, 4, 4>::zero();
transform[0][0][2] = -1.f;
transform[0][1][1] = -1.f;
@ -1813,7 +1813,7 @@ void main(){}
// -X
{
float far = far_negative[0];
transform[1] = geom::matrix<float, 4, 4>::zero();
transform[1] = math::matrix<float, 4, 4>::zero();
transform[1][0][2] = 1.f;
transform[1][1][1] = -1.f;
@ -1826,7 +1826,7 @@ void main(){}
// +Y
{
float far = far_positive[1];
transform[2] = geom::matrix<float, 4, 4>::zero();
transform[2] = math::matrix<float, 4, 4>::zero();
transform[2][0][0] = 1.f;
transform[2][1][2] = 1.f;
@ -1839,7 +1839,7 @@ void main(){}
// -Y
{
float far = far_negative[1];
transform[3] = geom::matrix<float, 4, 4>::zero();
transform[3] = math::matrix<float, 4, 4>::zero();
transform[3][0][0] = 1.f;
transform[3][1][2] = -1.f;
@ -1852,7 +1852,7 @@ void main(){}
// +Z
{
float far = far_positive[2];
transform[4] = geom::matrix<float, 4, 4>::zero();
transform[4] = math::matrix<float, 4, 4>::zero();
transform[4][0][0] = 1.f;
transform[4][1][1] = -1.f;
@ -1865,7 +1865,7 @@ void main(){}
// -Z
{
float far = far_negative[2];
transform[5] = geom::matrix<float, 4, 4>::zero();
transform[5] = math::matrix<float, 4, 4>::zero();
transform[5][0][0] = -1.f;
transform[5][1][1] = -1.f;
@ -1875,7 +1875,7 @@ void main(){}
transform[5][3][2] = - 1.f;
}
geom::matrix<float, 4, 4> const translate_by_light = geom::translation<float, 3>(geom::point<float, 3>::zero() - l.position).homogeneous_matrix();
math::matrix<float, 4, 4> const translate_by_light = math::translation<float, 3>(math::point<float, 3>::zero() - l.position).homogeneous_matrix();
impl().point_shadow_framebuffer.bind();
@ -1900,7 +1900,7 @@ void main(){}
gl::Disable(gl::BLEND);
impl().cubemap_shadow_builder_program.bind();
impl().cubemap_shadow_builder_program["u_light_transform"] = geom::matrix<float, 4, 4>::identity();
impl().cubemap_shadow_builder_program["u_light_transform"] = math::matrix<float, 4, 4>::identity();
impl().cubemap_shadow_builder_program["u_layer_transform[0]"] = transform[0] * translate_by_light;
impl().cubemap_shadow_builder_program["u_layer_transform[1]"] = transform[1] * translate_by_light;
@ -1931,7 +1931,7 @@ void main(){}
impl().point_light_pass_program["u_shadow_far_negative"] = far_negative;
}
geom::box<float, 3> light_bbox;
math::box<float, 3> light_bbox;
if (r)
{
float light_influence_radius = r->second;
@ -1951,7 +1951,7 @@ void main(){}
impl().point_light_pass_program["u_light_position"] = l.position;
impl().point_light_pass_program["u_light_color"] = l.color;
impl().point_light_pass_program["u_light_attenuation"] = geom::vector{l.attenuation.c0, l.attenuation.c1, l.attenuation.c2};
impl().point_light_pass_program["u_light_attenuation"] = math::vector{l.attenuation.c0, l.attenuation.c1, l.attenuation.c2};
impl().screen_mesh.draw();
}

View file

@ -36,7 +36,7 @@ namespace psemek::gfx
}
void texture_cubemap::load(int f, GLint internal_format, geom::vector<std::size_t, 2> const & size, GLenum format, GLenum type, const void * data)
void texture_cubemap::load(int f, GLint internal_format, math::vector<std::size_t, 2> const & size, GLenum format, GLenum type, const void * data)
{
bind();
gl::TexImage2D(face_to_gl(f), 0, internal_format, size[0], size[1], 0, format, type, data);
@ -115,7 +115,7 @@ namespace psemek::gfx
bind();
}
void texture_2d_multisample::load(GLint internal_format, geom::vector<std::size_t, 2> const & size, int samples, bool fixed_sample_locations)
void texture_2d_multisample::load(GLint internal_format, math::vector<std::size_t, 2> const & size, int samples, bool fixed_sample_locations)
{
bind();
gl::TexImage2DMultisample(target, samples, internal_format, size[0], size[1], fixed_sample_locations ? gl::TRUE : gl::FALSE);

18
libs/math/CMakeLists.txt Normal file
View file

@ -0,0 +1,18 @@
option(PSEMEK_ROBUST_PREDICATES "Use robust geometric predicates" OFF)
find_package(Boost REQUIRED)
if(PSEMEK_ROBUST_PREDICATES)
find_package(GMP REQUIRED)
endif()
file(GLOB_RECURSE PSEMEK_GEOM_HEADERS "include/*.hpp")
file(GLOB_RECURSE PSEMEK_GEOM_SOURCES "source/*.cpp")
psemek_add_library(psemek-math ${PSEMEK_GEOM_HEADERS} ${PSEMEK_GEOM_SOURCES})
target_include_directories(psemek-math PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(psemek-math PUBLIC psemek-util psemek-group Boost::boost)
if(PSEMEK_ROBUST_PREDICATES)
target_link_libraries(psemek-math PUBLIC gmp)
endif()
psemek_glob_tests(psemek-math tests)

View file

@ -1,11 +1,11 @@
#pragma once
#include <psemek/geom/vector.hpp>
#include <psemek/geom/point.hpp>
#include <psemek/geom/matrix.hpp>
#include <psemek/geom/gauss.hpp>
#include <psemek/math/vector.hpp>
#include <psemek/math/point.hpp>
#include <psemek/math/matrix.hpp>
#include <psemek/math/gauss.hpp>
namespace psemek::geom
namespace psemek::math
{
// Affine transformation from M-dimensional to N-dimensional affine space

View file

@ -1,12 +1,12 @@
#pragma once
#include <psemek/geom/point.hpp>
#include <psemek/math/point.hpp>
#include <psemek/util/exception.hpp>
#include <vector>
#include <stdexcept>
namespace psemek::geom
namespace psemek::math
{
// In-place de Casteljau's algorithm

View file

@ -1,12 +1,12 @@
#pragma once
#include <psemek/geom/detail/array.hpp>
#include <psemek/geom/interval.hpp>
#include <psemek/geom/point.hpp>
#include <psemek/math/detail/array.hpp>
#include <psemek/math/interval.hpp>
#include <psemek/math/point.hpp>
#include <iostream>
namespace psemek::geom
namespace psemek::math
{
template <typename T, std::size_t N>
@ -59,9 +59,9 @@ namespace psemek::geom
return result;
}
geom::vector<T, N> dimensions() const
math::vector<T, N> dimensions() const
{
geom::vector<T, N> result;
math::vector<T, N> result;
for (std::size_t i = 0; i < N; ++i)
result[i] = axes[i].length();
return result;

View file

@ -1,13 +1,13 @@
#pragma once
#include <psemek/geom/vector.hpp>
#include <psemek/geom/point.hpp>
#include <psemek/geom/matrix.hpp>
#include <psemek/geom/box.hpp>
#include <psemek/math/vector.hpp>
#include <psemek/math/point.hpp>
#include <psemek/math/matrix.hpp>
#include <psemek/math/box.hpp>
#include <array>
namespace psemek::geom
namespace psemek::math
{
struct camera
@ -55,18 +55,18 @@ namespace psemek::geom
struct orthographic_camera
: camera
{
geom::box<float, 3> box;
math::box<float, 3> box;
orthographic_camera() = default;
orthographic_camera(geom::box<float, 2> const & box)
orthographic_camera(math::box<float, 2> const & box)
{
this->box[0] = box[0];
this->box[1] = box[1];
this->box[2] = {-1.f, 1.f};
}
orthographic_camera(geom::box<float, 3> const & box)
orthographic_camera(math::box<float, 3> const & box)
: box{box}
{}

View file

@ -1,8 +1,8 @@
#pragma once
#include <psemek/geom/matrix.hpp>
#include <psemek/math/matrix.hpp>
namespace psemek::geom
namespace psemek::math
{
template <typename T, std::size_t N>

Some files were not shown because too many files have changed in this diff Show more