Browse Source

Improve matrix and vector functions. Add more matrix operators.

master
C. J. Howard 1 year ago
parent
commit
d344db6297
18 changed files with 797 additions and 919 deletions
  1. +1
    -1
      src/entity/commands.cpp
  2. +2
    -0
      src/game/state/splash.cpp
  3. +18
    -18
      src/game/system/astronomy.cpp
  4. +3
    -3
      src/game/system/atmosphere.cpp
  5. +1
    -1
      src/geom/plane.hpp
  6. +448
    -588
      src/math/matrix.hpp
  7. +99
    -0
      src/math/projection.hpp
  8. +1
    -1
      src/math/se3.hpp
  9. +1
    -1
      src/math/transform-functions.hpp
  10. +208
    -294
      src/math/vector.hpp
  11. +1
    -1
      src/render/passes/ground-pass.cpp
  12. +3
    -2
      src/render/passes/material-pass.cpp
  13. +1
    -0
      src/render/passes/shadow-map-pass.cpp
  14. +3
    -3
      src/render/passes/sky-pass.cpp
  15. +2
    -2
      src/render/renderer.cpp
  16. +1
    -1
      src/render/renderer.hpp
  17. +3
    -2
      src/scene/camera.cpp
  18. +1
    -1
      src/scene/text.cpp

+ 1
- 1
src/entity/commands.cpp View File

@ -157,7 +157,7 @@ void place(entity::registry& registry, entity::id eid, entity::id celestial_body
}
game::component::transform& transform = registry.get<game::component::transform>(eid);
transform.local.translation = math::type_cast<float>(double3{x, y, z});
transform.local.translation = math::vector<float, 3>(double3{x, y, z});
transform.warp = true;
}
*/

+ 2
- 0
src/game/state/splash.cpp View File

@ -29,6 +29,8 @@
#include "debug/logger.hpp"
#include "resources/resource-manager.hpp"
#include "render/material-flags.hpp"
#include "math/matrix.hpp"
#include <iostream>
namespace game {
namespace state {

+ 18
- 18
src/game/system/astronomy.cpp View File

@ -157,7 +157,7 @@ void astronomy::update(double t, double dt)
// Update local transform
if (orbit.parent != entt::null)
{
transform.local.translation = math::normalize(math::type_cast<float>(r_eus));
transform.local.translation = math::normalize(float3(r_eus));
transform.local.rotation = math::type_cast<float>(rotation_eus);
transform.local.scale = {1.0f, 1.0f, 1.0f};
}
@ -206,12 +206,12 @@ void astronomy::update(double t, double dt)
(
math::look_rotation
(
math::type_cast<float>(-observer_blackbody_direction_eus),
math::type_cast<float>(blackbody_up_eus)
float3(-observer_blackbody_direction_eus),
float3(blackbody_up_eus)
)
);
sun_light->set_color(math::type_cast<float>(observer_blackbody_transmitted_illuminance));
sun_light->set_color(float3(observer_blackbody_transmitted_illuminance));
// Bounce sun light
bounce_illuminance += std::max(0.0, math::dot(bounce_normal, -observer_blackbody_direction_eus)) * observer_blackbody_transmitted_illuminance * bounce_albedo;
@ -231,7 +231,7 @@ void astronomy::update(double t, double dt)
sky_light_illuminance += starlight_illuminance;
// Update sky light
sky_light->set_color(math::type_cast<float>(sky_light_illuminance));
sky_light->set_color(float3(sky_light_illuminance));
// Bounce sky light
bounce_illuminance += sky_light_illuminance * bounce_albedo;
@ -240,9 +240,9 @@ void astronomy::update(double t, double dt)
// Upload blackbody params to sky pass
if (this->sky_pass)
{
this->sky_pass->set_sun_position(math::type_cast<float>(blackbody_position_eus));
this->sky_pass->set_sun_luminance(math::type_cast<float>(blackbody.luminance));
this->sky_pass->set_sun_illuminance(math::type_cast<float>(observer_blackbody_illuminance), math::type_cast<float>(observer_blackbody_transmitted_illuminance));
this->sky_pass->set_sun_position(float3(blackbody_position_eus));
this->sky_pass->set_sun_luminance(float3(blackbody.luminance));
this->sky_pass->set_sun_illuminance(float3(observer_blackbody_illuminance), float3(observer_blackbody_transmitted_illuminance));
this->sky_pass->set_sun_angular_radius(static_cast<float>(observer_blackbody_angular_radius));
}
@ -308,23 +308,23 @@ void astronomy::update(double t, double dt)
this->sky_pass->set_moon_position(transform.local.translation);
this->sky_pass->set_moon_rotation(transform.local.rotation);
this->sky_pass->set_moon_angular_radius(static_cast<float>(observer_reflector_angular_radius));
this->sky_pass->set_moon_sunlight_direction(math::type_cast<float>(-reflector_blackbody_direction_eus));
this->sky_pass->set_moon_sunlight_illuminance(math::type_cast<float>(reflector_blackbody_illuminance * observer_reflector_transmittance));
this->sky_pass->set_moon_planetlight_direction(math::type_cast<float>(observer_reflector_direction_eus));
this->sky_pass->set_moon_planetlight_illuminance(math::type_cast<float>(reflector_observer_illuminance * observer_reflector_transmittance));
this->sky_pass->set_moon_illuminance(math::type_cast<float>(observer_reflector_illuminance / observer_reflector_transmittance), math::type_cast<float>(observer_reflector_illuminance));
this->sky_pass->set_moon_sunlight_direction(float3(-reflector_blackbody_direction_eus));
this->sky_pass->set_moon_sunlight_illuminance(float3(reflector_blackbody_illuminance * observer_reflector_transmittance));
this->sky_pass->set_moon_planetlight_direction(float3(observer_reflector_direction_eus));
this->sky_pass->set_moon_planetlight_illuminance(float3(reflector_observer_illuminance * observer_reflector_transmittance));
this->sky_pass->set_moon_illuminance(float3(observer_reflector_illuminance / observer_reflector_transmittance), float3(observer_reflector_illuminance));
}
if (this->moon_light)
{
const float3 reflector_up_eus = math::type_cast<float>(icrf_to_eus.r * double3{0, 0, 1});
const float3 reflector_up_eus = float3(icrf_to_eus.r * double3{0, 0, 1});
this->moon_light->set_color(math::type_cast<float>(observer_reflector_illuminance));
this->moon_light->set_color(float3(observer_reflector_illuminance));
this->moon_light->set_rotation
(
math::look_rotation
(
math::type_cast<float>(-observer_reflector_direction_eus),
float3(-observer_reflector_direction_eus),
reflector_up_eus
)
);
@ -337,7 +337,7 @@ void astronomy::update(double t, double dt)
if (bounce_light)
{
bounce_light->set_color(math::type_cast<float>(bounce_illuminance));
bounce_light->set_color(float3(bounce_illuminance));
}
}
@ -580,7 +580,7 @@ void astronomy::update_icrf_to_eus(const game::component::celestial_body& body,
(
math::transformation::se3<float>
{
math::type_cast<float>(icrf_to_eus.t),
float3(icrf_to_eus.t),
math::type_cast<float>(icrf_to_eus.r)
}
);

+ 3
- 3
src/game/system/atmosphere.cpp View File

@ -143,10 +143,10 @@ void atmosphere::update_sky_pass()
return;
sky_pass->set_atmosphere_upper_limit(static_cast<float>(component->upper_limit));
sky_pass->set_rayleigh_parameters(static_cast<float>(component->rayleigh_scale_height), math::type_cast<float>(component->rayleigh_scattering));
sky_pass->set_rayleigh_parameters(static_cast<float>(component->rayleigh_scale_height), math::vector<float, 3>(component->rayleigh_scattering));
sky_pass->set_mie_parameters(static_cast<float>(component->mie_scale_height), static_cast<float>(component->mie_scattering), static_cast<float>(component->mie_extinction), static_cast<float>(component->mie_anisotropy));
sky_pass->set_ozone_parameters(static_cast<float>(component->ozone_lower_limit), static_cast<float>(component->ozone_upper_limit), static_cast<float>(component->ozone_mode), math::type_cast<float>(component->ozone_absorption));
sky_pass->set_airglow_illuminance(math::type_cast<float>(component->airglow_illuminance));
sky_pass->set_ozone_parameters(static_cast<float>(component->ozone_lower_limit), static_cast<float>(component->ozone_upper_limit), static_cast<float>(component->ozone_mode), math::vector<float, 3>(component->ozone_absorption));
sky_pass->set_airglow_illuminance(math::vector<float, 3>(component->airglow_illuminance));
}
void atmosphere::on_atmosphere_construct(entity::registry& registry, entity::id entity_id)

+ 1
- 1
src/geom/plane.hpp View File

@ -99,7 +99,7 @@ plane::plane(const vector_type& a, const vector_type& b, const vector_type& c
template <class T>
plane<T>::plane(const math::vector<T, 4>& coefficients)
{
const vector_type abc = math::resize<3>(coefficients);
const vector_type abc = math::vector<T, 3>(coefficients);
const float inverse_length = T(1) / math::length(abc);
normal = abc * inverse_length;

+ 448
- 588
src/math/matrix.hpp
File diff suppressed because it is too large
View File


+ 99
- 0
src/math/projection.hpp View File

@ -20,6 +20,7 @@
#ifndef ANTKEEPER_MATH_PROJECTION_HPP
#define ANTKEEPER_MATH_PROJECTION_HPP
#include "math/matrix.hpp"
#include <cmath>
namespace math {
@ -56,6 +57,104 @@ T vertical_fov(T h, T r)
return T{2} * std::atan(std::tan(h * T{0.5}) / r);
}
/**
* Creates an orthographic projection matrix which will transform the near and far clipping planes to `[-1, 1]`, respectively.
*
* @param left Signed distance to the left clipping plane.
* @param right Signed distance to the right clipping plane.
* @param bottom Signed distance to the bottom clipping plane.
* @param top Signed distance to the top clipping plane.
* @param z_near Signed distance to the near clipping plane.
* @param z_far Signed distance to the far clipping plane.
*
* @return Orthographic projection matrix.
*/
template <class T>
constexpr matrix<T, 4, 4> ortho(T left, T right, T bottom, T top, T z_near, T z_far) noexcept
{
return
{{
{T(2) / (right - left), T(0), T(0), T(0)},
{T(0), T(2) / (top - bottom), T(0), T(0)},
{T(0), T(0), T(-2) / (z_far - z_near), T(0)},
{-((right + left) / (right - left)), -((top + bottom) / (top - bottom)), -((z_far + z_near) / (z_far - z_near)), T(1)}
}};
}
/**
* Creates an orthographic projection matrix which will transform the near and far clipping planes to `[0, 1]`, respectively.
*
* @param left Signed distance to the left clipping plane.
* @param right Signed distance to the right clipping plane.
* @param bottom Signed distance to the bottom clipping plane.
* @param top Signed distance to the top clipping plane.
* @param z_near Signed distance to the near clipping plane.
* @param z_far Signed distance to the far clipping plane.
*
* @return Orthographic projection matrix.
*/
template <class T>
constexpr matrix<T, 4, 4> ortho_half_z(T left, T right, T bottom, T top, T z_near, T z_far) noexcept
{
return
{{
{T(2) / (right - left), T(0), T(0), T(0)},
{T(0), T(2) / (top - bottom), T(0), T(0)},
{T(0), T(0), T(-1) / (z_far - z_near), T(0)},
{-((right + left) / (right - left)), -((top + bottom) / (top - bottom)), -z_near / (z_far - z_near), T(1)}
}};
}
/**
* Creates a perspective projection matrix which will transform the near and far clipping planes to `[-1, 1]`, respectively.
*
* @param vertical_fov Vertical field of view angle, in radians.
* @param aspect_ratio Aspect ratio which determines the horizontal field of view.
* @param z_near Distance to the near clipping plane.
* @param z_far Distance to the far clipping plane.
*
* @return Perspective projection matrix.
*/
template <class T>
matrix<T, 4, 4> perspective(T vertical_fov, T aspect_ratio, T z_near, T z_far)
{
T half_fov = vertical_fov * T(0.5);
T f = std::cos(half_fov) / std::sin(half_fov);
return
{{
{f / aspect_ratio, T(0), T(0), T(0)},
{T(0), f, T(0), T(0)},
{T(0), T(0), (z_far + z_near) / (z_near - z_far), T(-1)},
{T(0), T(0), (T(2) * z_far * z_near) / (z_near - z_far), T(0)}
}};
}
/**
* Creates a perspective projection matrix which will transform the near and far clipping planes to `[0, 1]`, respectively.
*
* @param vertical_fov Vertical field of view angle, in radians.
* @param aspect_ratio Aspect ratio which determines the horizontal field of view.
* @param z_near Distance to the near clipping plane.
* @param z_far Distance to the far clipping plane.
*
* @return Perspective projection matrix.
*/
template <class T>
matrix<T, 4, 4> perspective_half_z(T vertical_fov, T aspect_ratio, T z_near, T z_far)
{
T half_fov = vertical_fov * T(0.5);
T f = std::cos(half_fov) / std::sin(half_fov);
return
{{
{f / aspect_ratio, T(0), T(0), T(0)},
{T(0), f, T(0), T(0)},
{T(0), T(0), z_far / (z_near - z_far), T(-1)},
{T(0), T(0), -(z_far * z_near) / (z_far - z_near), T(0)}
}};
}
} // namespace math
#endif // ANTKEEPER_MATH_PROJECTION_HPP

+ 1
- 1
src/math/se3.hpp View File

@ -95,7 +95,7 @@ se3 se3::inverse() const
template <class T>
typename se3<T>::matrix_type se3<T>::matrix() const
{
matrix_type m = math::resize<4, 4>(math::matrix_cast<T>(r));
matrix_type m = math::matrix<T, 4, 4>(math::matrix_cast<T>(r));
m[3].x() = t.x();
m[3].y() = t.y();

+ 1
- 1
src/math/transform-functions.hpp View File

@ -75,7 +75,7 @@ transform inverse(const transform& t)
template <class T>
matrix<T, 4, 4> matrix_cast(const transform<T>& t)
{
matrix<T, 4, 4> transformation = resize<4, 4>(matrix_cast(t.rotation));
matrix<T, 4, 4> transformation = matrix<T, 4, 4>(matrix_cast(t.rotation));
transformation[3] = {t.translation[0], t.translation[1], t.translation[2], T(1)};
return scale(transformation, t.scale);
}

+ 208
- 294
src/math/vector.hpp
File diff suppressed because it is too large
View File


+ 1
- 1
src/render/passes/ground-pass.cpp View File

@ -86,7 +86,7 @@ void ground_pass::render(const render::context& ctx, render::queue& queue) const
float clip_far = camera.get_clip_far_tween().interpolate(ctx.alpha);
float3 model_scale = float3{1.0f, 1.0f, 1.0f} * (clip_near + clip_far) * 0.5f;
float4x4 model = math::scale(math::matrix4<float>::identity(), model_scale);
float4x4 view = math::resize<4, 4>(math::resize<3, 3>(ctx.view));
float4x4 view = float4x4(float3x3(ctx.view));
float4x4 model_view = view * model;
const float4x4& projection = ctx.projection;
const float4x4& view_projection = ctx.view_projection;

+ 3
- 2
src/render/passes/material-pass.cpp View File

@ -43,6 +43,7 @@
#include "scene/spot-light.hpp"
#include "config.hpp"
#include "math/quaternion-operators.hpp"
#include "math/projection.hpp"
#include <cmath>
#include <glad/glad.h>
@ -504,8 +505,8 @@ void material_pass::render(const render::context& ctx, render::queue& queue) con
model = operation.transform;
model_view_projection = view_projection * model;
model_view = view * model;
normal_model = math::transpose(math::inverse(math::resize<3, 3>(model)));
normal_model_view = math::transpose(math::inverse(math::resize<3, 3>(model_view)));
normal_model = math::transpose(math::inverse(math::matrix<float, 3, 3>(model)));
normal_model_view = math::transpose(math::inverse(math::matrix<float, 3, 3>(model_view)));
// Skinning palette
if (operation.bone_count && parameters->skinning_palette)

+ 1
- 0
src/render/passes/shadow-map-pass.cpp View File

@ -35,6 +35,7 @@
#include "math/vector.hpp"
#include "math/matrix.hpp"
#include "math/quaternion-operators.hpp"
#include "math/projection.hpp"
#include <cmath>
#include <glad/glad.h>

+ 3
- 3
src/render/passes/sky-pass.cpp View File

@ -194,7 +194,7 @@ void sky_pass::render(const render::context& ctx, render::queue& queue) const
float clip_far = camera.get_clip_far_tween().interpolate(ctx.alpha);
float3 model_scale = float3{1.0f, 1.0f, 1.0f} * (clip_near + clip_far) * 0.5f;
float4x4 model = math::scale(math::matrix4<float>::identity(), model_scale);
float4x4 view = math::resize<4, 4>(math::resize<3, 3>(ctx.view));
float4x4 view = float4x4(float3x3(ctx.view));
float4x4 model_view = view * model;
const float4x4& projection = ctx.projection;
float4x4 view_projection = projection * view;
@ -300,7 +300,7 @@ void sky_pass::render(const render::context& ctx, render::queue& queue) const
{
float star_distance = (clip_near + clip_far) * 0.5f;
model = math::resize<4, 4>(math::matrix_cast<float>(icrf_to_eus.r));
model = float4x4(math::matrix_cast<float>(icrf_to_eus.r));
model = math::scale(model, {star_distance, star_distance, star_distance});
model_view = view * model;
@ -332,7 +332,7 @@ void sky_pass::render(const render::context& ctx, render::queue& queue) const
moon_transform.scale = {moon_radius, moon_radius, moon_radius};
model = math::matrix_cast(moon_transform);
float3x3 normal_model = math::transpose(math::inverse(math::resize<3, 3>(model)));
float3x3 normal_model = math::transpose(math::inverse(float3x3(model)));
rasterizer->use_program(*moon_shader_program);
if (moon_model_input)

+ 2
- 2
src/render/renderer.cpp View File

@ -176,7 +176,7 @@ void renderer::process_model_instance(const render::context& ctx, render::queue&
render::operation operation;
operation.transform = math::matrix_cast(model_instance->get_transform_tween().interpolate(ctx.alpha));
operation.depth = ctx.clip_near.signed_distance(math::resize<3>(operation.transform[3]));
operation.depth = ctx.clip_near.signed_distance(float3(operation.transform[3]));
operation.vertex_array = model->get_vertex_array();
operation.instance_count = model_instance->get_instance_count();
@ -223,7 +223,7 @@ void renderer::process_billboard(const render::context& ctx, render::queue& queu
math::transform<float> billboard_transform = billboard->get_transform_tween().interpolate(ctx.alpha);
billboard_op.material = billboard->get_material();
billboard_op.depth = ctx.clip_near.signed_distance(math::resize<3>(billboard_transform.translation));
billboard_op.depth = ctx.clip_near.signed_distance(float3(billboard_transform.translation));
// Align billboard
if (billboard->get_billboard_type() == scene::billboard_type::spherical)

+ 1
- 1
src/render/renderer.hpp View File

@ -52,7 +52,7 @@ public:
* @param t Current time, in seconds.
* @param dt Timestep, in seconds.
* @param alpha Subframe interpolation factor.
* @parma collection Collection of scene objects to render.
* @param collection Collection of scene objects to render.
*/
void render(float t, float dt, float alpha, const scene::collection& collection) const;

+ 3
- 2
src/scene/camera.cpp View File

@ -22,6 +22,7 @@
#include "math/constants.hpp"
#include "math/interpolation.hpp"
#include "math/quaternion-operators.hpp"
#include "math/projection.hpp"
namespace scene {
@ -101,7 +102,7 @@ float3 camera::project(const float3& object, const float4& viewport) const
result[0] = result[0] * viewport[2] + viewport[0];
result[1] = result[1] * viewport[3] + viewport[1];
return math::resize<3>(result);
return math::vector<float, 3>(result);
}
float3 camera::unproject(const float3& window, const float4& viewport) const
@ -116,7 +117,7 @@ float3 camera::unproject(const float3& window, const float4& viewport) const
result = math::inverse(view_projection[1]) * result;
return math::resize<3>(result) * (1.0f / result[3]);
return math::vector<float, 3>(result) * (1.0f / result[3]);
}
void camera::set_perspective(float fov, float aspect_ratio, float clip_near, float clip_far)

+ 1
- 1
src/scene/text.cpp View File

@ -104,7 +104,7 @@ void text::render(const render::context& ctx, render::queue& queue) const
return;
render_op.transform = math::matrix_cast(get_transform_tween().interpolate(ctx.alpha));
render_op.depth = ctx.clip_near.signed_distance(math::resize<3>(render_op.transform[3]));
render_op.depth = ctx.clip_near.signed_distance(math::vector<float, 3>(render_op.transform[3]));
queue.push_back(render_op);
}

Loading…
Cancel
Save