Rename 'geom' library to 'math'
This commit is contained in:
parent
89cbbaeeef
commit
c59b28e13f
274 changed files with 2986 additions and 2986 deletions
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
|
||||
|
|
|
|||
|
|
@ -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]};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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{}};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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_);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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]]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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},
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,},
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/geom/intersection.hpp>
|
||||
#include <psemek/math/intersection.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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_; }
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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});
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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>();
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
18
libs/math/CMakeLists.txt
Normal 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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
@ -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}
|
||||
{}
|
||||
|
||||
|
|
@ -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
Loading…
Add table
Reference in a new issue