diff --git a/headers/enduro2d/high/components/camera.hpp b/headers/enduro2d/high/components/camera.hpp index f22ccc3b..d7bdbe73 100644 --- a/headers/enduro2d/high/components/camera.hpp +++ b/headers/enduro2d/high/components/camera.hpp @@ -21,20 +21,23 @@ namespace e2d camera() = default; camera& depth(i32 value) noexcept; + camera& znear(f32 value) noexcept; + camera& zfar(f32 value) noexcept; camera& viewport(const b2f& value) noexcept; - camera& projection(const m4f& value) noexcept; camera& target(const render_target_ptr& value) noexcept; camera& background(const color& value) noexcept; [[nodiscard]] i32 depth() const noexcept; + [[nodiscard]] f32 znear() const noexcept; + [[nodiscard]] f32 zfar() const noexcept; [[nodiscard]] const b2f& viewport() const noexcept; - [[nodiscard]] const m4f& projection() const noexcept; [[nodiscard]] const render_target_ptr& target() const noexcept; [[nodiscard]] const color& background() const noexcept; private: i32 depth_ = 0; + f32 znear_ = 0.f; + f32 zfar_ = 1000.f; b2f viewport_ = b2f::unit(); - m4f projection_ = m4f::identity(); render_target_ptr target_ = nullptr; color background_ = color::clear(); }; @@ -89,13 +92,18 @@ namespace e2d return *this; } - inline camera& camera::viewport(const b2f& value) noexcept { - viewport_ = value; + inline camera& camera::znear(f32 value) noexcept { + znear_ = value; return *this; } - inline camera& camera::projection(const m4f& value) noexcept { - projection_ = value; + inline camera& camera::zfar(f32 value) noexcept { + zfar_ = value; + return *this; + } + + inline camera& camera::viewport(const b2f& value) noexcept { + viewport_ = value; return *this; } @@ -113,12 +121,16 @@ namespace e2d return depth_; } - inline const b2f& camera::viewport() const noexcept { - return viewport_; + inline f32 camera::znear() const noexcept { + return znear_; } - inline const m4f& camera::projection() const noexcept { - return projection_; + inline f32 camera::zfar() const noexcept { + return zfar_; + } + + inline const b2f& camera::viewport() const noexcept { + return viewport_; } inline const render_target_ptr& camera::target() const noexcept { @@ -129,3 +141,16 @@ namespace e2d return background_; } } + +namespace e2d::cameras +{ + inline m4f make_projection_matrix(const camera& camera, const window& window) noexcept { + const v2u target_size = camera.target() + ? camera.target()->size() + : window.real_size(); + return math::make_orthographic_lh_no_matrix4( + target_size.cast_to(), + camera.znear(), + math::max(camera.zfar(), camera.znear() + math::default_precision())); + } +} diff --git a/headers/enduro2d/math/mat4.hpp b/headers/enduro2d/math/mat4.hpp index 530ef866..d0587ed3 100644 --- a/headers/enduro2d/math/mat4.hpp +++ b/headers/enduro2d/math/mat4.hpp @@ -517,23 +517,23 @@ namespace e2d::math ax.x, ay.x, az.x, T(0), ax.y, ay.y, az.y, T(0), ax.z, ay.z, az.z, T(0), - dx, dy, dz, T(1)}; + -dx, -dy, -dz, T(1)}; } // - // make_orthogonal_lh_matrix4 + // make_orthographic_lh_zo_matrix4 // template < typename T > std::enable_if_t, mat4> - make_orthogonal_lh_matrix4(T width, T height, T znear, T zfar) noexcept { + make_orthographic_lh_zo_matrix4(T width, T height, T znear, T zfar) noexcept { E2D_ASSERT(!math::is_near_zero(width, T(0))); E2D_ASSERT(!math::is_near_zero(height, T(0))); E2D_ASSERT(!math::approximately(znear, zfar, T(0))); const T sx = T(2) / width; const T sy = T(2) / height; const T sz = T(1) / (zfar - znear); - const T tz = -znear * sz; + const T tz = -znear / (zfar - znear); return { sx, T(0), T(0), T(0), T(0), sy, T(0), T(0), @@ -543,24 +543,24 @@ namespace e2d::math template < typename T > std::enable_if_t, mat4> - make_orthogonal_lh_matrix4(const vec2& size, T znear, T zfar) { - return make_orthogonal_lh_matrix4(size.x, size.y, znear, zfar); + make_orthographic_lh_zo_matrix4(const vec2& size, T znear, T zfar) noexcept { + return make_orthographic_lh_zo_matrix4(size.x, size.y, znear, zfar); } // - // make_orthogonal_rh_matrix4 + // make_orthographic_lh_no_matrix4 // template < typename T > std::enable_if_t, mat4> - make_orthogonal_rh_matrix4(T width, T height, T znear, T zfar) noexcept { + make_orthographic_lh_no_matrix4(T width, T height, T znear, T zfar) noexcept { E2D_ASSERT(!math::is_near_zero(width, T(0))); E2D_ASSERT(!math::is_near_zero(height, T(0))); E2D_ASSERT(!math::approximately(znear, zfar, T(0))); const T sx = T(2) / width; const T sy = T(2) / height; - const T sz = T(1) / (znear - zfar); - const T tz = znear * sz; + const T sz = T(2) / (zfar - znear); + const T tz = -(zfar + znear) / (zfar - znear); return { sx, T(0), T(0), T(0), T(0), sy, T(0), T(0), @@ -570,24 +570,78 @@ namespace e2d::math template < typename T > std::enable_if_t, mat4> - make_orthogonal_rh_matrix4(const vec2& size, T znear, T zfar) { - return make_orthogonal_rh_matrix4(size.x, size.y, znear, zfar); + make_orthographic_lh_no_matrix4(const vec2& size, T znear, T zfar) noexcept { + return make_orthographic_lh_no_matrix4(size.x, size.y, znear, zfar); } // - // make_perspective_lh_matrix4 + // make_orthographic_rh_zo_matrix4 + // + + template < typename T > + std::enable_if_t, mat4> + make_orthographic_rh_zo_matrix4(T width, T height, T znear, T zfar) noexcept { + E2D_ASSERT(!math::is_near_zero(width, T(0))); + E2D_ASSERT(!math::is_near_zero(height, T(0))); + E2D_ASSERT(!math::approximately(znear, zfar, T(0))); + const T sx = T(2) / width; + const T sy = T(2) / height; + const T sz = T(-1) / (zfar - znear); + const T tz = -znear / (zfar - znear); + return { + sx, T(0), T(0), T(0), + T(0), sy, T(0), T(0), + T(0), T(0), sz, T(0), + T(0), T(0), tz, T(1)}; + } + + template < typename T > + std::enable_if_t, mat4> + make_orthographic_rh_zo_matrix4(const vec2& size, T znear, T zfar) noexcept { + return make_orthographic_rh_zo_matrix4(size.x, size.y, znear, zfar); + } + + // + // make_orthographic_rh_no_matrix4 + // + + template < typename T > + std::enable_if_t, mat4> + make_orthographic_rh_no_matrix4(T width, T height, T znear, T zfar) noexcept { + E2D_ASSERT(!math::is_near_zero(width, T(0))); + E2D_ASSERT(!math::is_near_zero(height, T(0))); + E2D_ASSERT(!math::approximately(znear, zfar, T(0))); + const T sx = T(2) / width; + const T sy = T(2) / height; + const T sz = T(-2) / (zfar - znear); + const T tz = -(zfar + znear) / (zfar - znear); + return { + sx, T(0), T(0), T(0), + T(0), sy, T(0), T(0), + T(0), T(0), sz, T(0), + T(0), T(0), tz, T(1)}; + } + + template < typename T > + std::enable_if_t, mat4> + make_orthographic_rh_no_matrix4(const vec2& size, T znear, T zfar) noexcept { + return make_orthographic_rh_no_matrix4(size.x, size.y, znear, zfar); + } + + // + // make_perspective_lh_zo_matrix4 // template < typename T, typename AngleTag > std::enable_if_t, mat4> - make_perspective_lh_matrix4(const unit& fov, T aspect, T znear, T zfar) noexcept { + make_perspective_lh_zo_matrix4(const unit& fov, T aspect, T znear, T zfar) noexcept { E2D_ASSERT(!math::is_near_zero(aspect, T(0))); E2D_ASSERT(!math::approximately(znear, zfar, T(0))); E2D_ASSERT(!math::approximately(fov, unit::zero(), T(0))); const T sy = T(1) / math::tan(fov * T(0.5)); const T sx = sy / aspect; const T sz = zfar / (zfar - znear); - const T tz = -znear * zfar / (zfar - znear); + const T tz = -(zfar * znear) / (zfar - znear); return { sx, T(0), T(0), T(0), T(0), sy, T(0), T(0), @@ -596,19 +650,61 @@ namespace e2d::math } // - // make_perspective_rh_matrix4 + // make_perspective_lh_no_matrix4 // template < typename T, typename AngleTag > std::enable_if_t, mat4> - make_perspective_rh_matrix4(const unit& fov, T aspect, T znear, T zfar) noexcept { + make_perspective_lh_no_matrix4(const unit& fov, T aspect, T znear, T zfar) noexcept { + E2D_ASSERT(!math::is_near_zero(aspect, T(0))); + E2D_ASSERT(!math::approximately(znear, zfar, T(0))); + E2D_ASSERT(!math::approximately(fov, unit::zero(), T(0))); + const T sy = T(1) / math::tan(fov * T(0.5)); + const T sx = sy / aspect; + const T sz = (zfar + znear) / (zfar - znear); + const T tz = -(T(2) * zfar * znear) / (zfar - znear); + return { + sx, T(0), T(0), T(0), + T(0), sy, T(0), T(0), + T(0), T(0), sz, T(1), + T(0), T(0), tz, T(0)}; + } + + // + // make_perspective_rh_zo_matrix4 + // + + template < typename T, typename AngleTag > + std::enable_if_t, mat4> + make_perspective_rh_zo_matrix4(const unit& fov, T aspect, T znear, T zfar) noexcept { E2D_ASSERT(!math::is_near_zero(aspect, T(0))); E2D_ASSERT(!math::approximately(znear, zfar, T(0))); E2D_ASSERT(!math::approximately(fov, unit::zero(), T(0))); const T sy = T(1) / math::tan(fov * T(0.5)); const T sx = sy / aspect; const T sz = zfar / (znear - zfar); - const T tz = znear * zfar / (znear - zfar); + const T tz = -(zfar * znear) / (zfar - znear); + return { + sx, T(0), T(0), T(0), + T(0), sy, T(0), T(0), + T(0), T(0), sz, T(-1), + T(0), T(0), tz, T(0)}; + } + + // + // make_perspective_rh_no_matrix4 + // + + template < typename T, typename AngleTag > + std::enable_if_t, mat4> + make_perspective_rh_no_matrix4(const unit& fov, T aspect, T znear, T zfar) noexcept { + E2D_ASSERT(!math::is_near_zero(aspect, T(0))); + E2D_ASSERT(!math::approximately(znear, zfar, T(0))); + E2D_ASSERT(!math::approximately(fov, unit::zero(), T(0))); + const T sy = T(1) / math::tan(fov * T(0.5)); + const T sx = sy / aspect; + const T sz = -(zfar + znear) / (zfar - znear); + const T tz = -(T(2) * zfar * znear) / (zfar - znear); return { sx, T(0), T(0), T(0), T(0), sy, T(0), T(0), diff --git a/samples/bin/library/prefabs/gnome_prefab.json b/samples/bin/library/prefabs/gnome_prefab.json index 238cb8a0..f839fe53 100644 --- a/samples/bin/library/prefabs/gnome_prefab.json +++ b/samples/bin/library/prefabs/gnome_prefab.json @@ -4,7 +4,10 @@ "renderer" : { "materials" : [ "../models/gnome/gnome_material.json" - ] + ], + "transform" : { + "translation" : [0,0,5] + } }, "model_renderer" : { "model" : "../models/gnome/gnome_model.json" diff --git a/samples/bin/library/scripts/emmy/components/camera.lua b/samples/bin/library/scripts/emmy/components/camera.lua index fb147ddc..297efb64 100644 --- a/samples/bin/library/scripts/emmy/components/camera.lua +++ b/samples/bin/library/scripts/emmy/components/camera.lua @@ -9,12 +9,15 @@ local camera = { ---@type integer depth = 0, + ---@type number + znear = 0.0, + + ---@type number + zfar = 1000.0, + ---@type rect viewport = rect.zero(), - ---@type m4f - projection = m4f.identity(), - ---@type color background = color.white() } diff --git a/samples/bin/library/scripts/emmy/math/m4f.lua b/samples/bin/library/scripts/emmy/math/m4f.lua index e67335d6..c4a1feb6 100644 --- a/samples/bin/library/scripts/emmy/math/m4f.lua +++ b/samples/bin/library/scripts/emmy/math/m4f.lua @@ -53,26 +53,50 @@ function m4f.make_look_at_rh(eye, at, up) end ---@overload fun(width: number, height: number, znear: number, zfar: number): m4f ---@overload fun(size: v2f, znear: number, zfar: number): m4f ---@return m4f -function m4f.make_orthogonal_lh(...) end +function m4f.make_orthographic_lh_zo(...) end ---@overload fun(width: number, height: number, znear: number, zfar: number): m4f ---@overload fun(size: v2f, znear: number, zfar: number): m4f ---@return m4f -function m4f.make_orthogonal_rh(...) end +function m4f.make_orthographic_lh_no(...) end + +---@overload fun(width: number, height: number, znear: number, zfar: number): m4f +---@overload fun(size: v2f, znear: number, zfar: number): m4f +---@return m4f +function m4f.make_orthographic_rh_zo(...) end + +---@overload fun(width: number, height: number, znear: number, zfar: number): m4f +---@overload fun(size: v2f, znear: number, zfar: number): m4f +---@return m4f +function m4f.make_orthographic_rh_no(...) end ---@param angle number ---@param aspect number ---@param znear number ---@param zfar number ---@return m4f -function m4f.make_perspective_lh(angle, aspect, znear, zfar) end +function m4f.make_perspective_lh_zo(angle, aspect, znear, zfar) end ---@param angle number ---@param aspect number ---@param znear number ---@param zfar number ---@return m4f -function m4f.make_perspective_rh(angle, aspect, znear, zfar) end +function m4f.make_perspective_lh_no(angle, aspect, znear, zfar) end + +---@param angle number +---@param aspect number +---@param znear number +---@param zfar number +---@return m4f +function m4f.make_perspective_rh_zo(angle, aspect, znear, zfar) end + +---@param angle number +---@param aspect number +---@param znear number +---@param zfar number +---@return m4f +function m4f.make_perspective_rh_no(angle, aspect, znear, zfar) end ---@param l m4f ---@param r m4f diff --git a/samples/sources/sample_00/sample_00.cpp b/samples/sources/sample_00/sample_00.cpp index d3471c52..b831d8e4 100644 --- a/samples/sources/sample_00/sample_00.cpp +++ b/samples/sources/sample_00/sample_00.cpp @@ -184,7 +184,7 @@ namespace void frame_render() final { const auto framebuffer_size = the().real_size().cast_to(); - const auto projection = math::make_orthogonal_lh_matrix4( + const auto projection = math::make_orthographic_lh_no_matrix4( framebuffer_size, 0.f, 1.f); material_.properties() diff --git a/samples/sources/sample_01/sample_01.cpp b/samples/sources/sample_01/sample_01.cpp index d3287d47..13ec8768 100644 --- a/samples/sources/sample_01/sample_01.cpp +++ b/samples/sources/sample_01/sample_01.cpp @@ -235,7 +235,7 @@ namespace void frame_render() final { const auto framebuffer_size = the().real_size().cast_to(); - const auto projection = math::make_perspective_lh_matrix4( + const auto projection = math::make_perspective_lh_no_matrix4( make_deg(45.f), framebuffer_size.x / framebuffer_size.y, 0.1f, diff --git a/samples/sources/sample_02/sample_02.cpp b/samples/sources/sample_02/sample_02.cpp index 65604ff0..fd2b894f 100644 --- a/samples/sources/sample_02/sample_02.cpp +++ b/samples/sources/sample_02/sample_02.cpp @@ -205,7 +205,7 @@ namespace void frame_render() final { const auto framebuffer_size = the().real_size().cast_to(); - const auto projection = math::make_perspective_lh_matrix4( + const auto projection = math::make_perspective_lh_no_matrix4( make_deg(45.f), framebuffer_size.x / framebuffer_size.y, 0.1f, diff --git a/samples/sources/sample_03/sample_03.cpp b/samples/sources/sample_03/sample_03.cpp index db0ce3c9..07864bc6 100644 --- a/samples/sources/sample_03/sample_03.cpp +++ b/samples/sources/sample_03/sample_03.cpp @@ -39,23 +39,6 @@ namespace } }; - class camera_system final : public systems::post_update_system { - public: - void process( - ecs::registry& owner, - const systems::post_update_event& event) override - { - E2D_UNUSED(event); - owner.for_joined_components( - [](const ecs::const_entity&, camera& cam){ - if ( !cam.target() ) { - cam.projection(math::make_orthogonal_lh_matrix4( - the().real_size().cast_to(), 0.f, 1000.f)); - } - }); - } - }; - class rotator_system final : public systems::update_system { public: void process( @@ -118,7 +101,9 @@ namespace .component(named() .name("gnome")) .component(v3f::unit_y()) - .component(renderer().materials({model_mat})) + .component(renderer() + .materials({model_mat}) + .translation({0.f, 0.f, 5.f})) .component(model_res); the().instantiate( @@ -189,8 +174,7 @@ namespace ecs::registry_filler(the().registry()) .feature(ecs::feature() .add_system() - .add_system() - .add_system()); + .add_system()); return true; } }; diff --git a/samples/sources/sample_04/sample_04.cpp b/samples/sources/sample_04/sample_04.cpp index 2de24d79..ebfb622f 100644 --- a/samples/sources/sample_04/sample_04.cpp +++ b/samples/sources/sample_04/sample_04.cpp @@ -32,23 +32,6 @@ namespace } }; - class camera_system final : public systems::post_update_system { - public: - void process( - ecs::registry& owner, - const systems::post_update_event& event) override - { - E2D_UNUSED(event); - owner.for_joined_components( - [](const ecs::const_entity&, camera& cam){ - if ( !cam.target() ) { - cam.projection(math::make_orthogonal_lh_matrix4( - the().real_size().cast_to(), 0.f, 1000.f)); - } - }); - } - }; - class game final : public starter::application { public: bool initialize() final { @@ -67,8 +50,7 @@ namespace bool create_systems() { ecs::registry_filler(the().registry()) .feature(ecs::feature() - .add_system() - .add_system()); + .add_system()); return true; } }; diff --git a/samples/sources/sample_06/sample_06.cpp b/samples/sources/sample_06/sample_06.cpp index 5ec4aae6..bb02995b 100644 --- a/samples/sources/sample_06/sample_06.cpp +++ b/samples/sources/sample_06/sample_06.cpp @@ -70,23 +70,6 @@ namespace } }; - class camera_system final : public systems::post_update_system { - public: - void process( - ecs::registry& owner, - const systems::post_update_event& event) override - { - E2D_UNUSED(event); - owner.for_joined_components( - [](const ecs::const_entity&, camera& cam){ - if ( !cam.target() ) { - cam.projection(math::make_orthogonal_lh_matrix4( - the().real_size().cast_to(), 0.f, 1000.f)); - } - }); - } - }; - class game final : public starter::application { public: bool initialize() final { @@ -105,8 +88,7 @@ namespace bool create_systems() { ecs::registry_filler(the().registry()) .feature(ecs::feature() - .add_system() - .add_system()); + .add_system()); return true; } }; diff --git a/samples/sources/sample_07/sample_07.cpp b/samples/sources/sample_07/sample_07.cpp index d246d4be..99458bde 100644 --- a/samples/sources/sample_07/sample_07.cpp +++ b/samples/sources/sample_07/sample_07.cpp @@ -32,23 +32,6 @@ namespace } }; - class camera_system final : public systems::post_update_system { - public: - void process( - ecs::registry& owner, - const systems::post_update_event& event) override - { - E2D_UNUSED(event); - owner.for_joined_components( - [](const ecs::const_entity&, camera& cam){ - if ( !cam.target() ) { - cam.projection(math::make_orthogonal_lh_matrix4( - the().real_size().cast_to(), 0.f, 1000.f)); - } - }); - } - }; - class game final : public starter::application { public: bool initialize() final { @@ -67,8 +50,7 @@ namespace bool create_systems() { ecs::registry_filler(the().registry()) .feature(ecs::feature() - .add_system() - .add_system()); + .add_system()); return true; } }; diff --git a/sources/enduro2d/core/dbgui.cpp b/sources/enduro2d/core/dbgui.cpp index ec93c67e..b3bf789f 100644 --- a/sources/enduro2d/core/dbgui.cpp +++ b/sources/enduro2d/core/dbgui.cpp @@ -129,8 +129,8 @@ namespace e2d const v2f framebuffer_size = display_size * v2f(draw_data->FramebufferScale); const m4f projection = - math::make_translation_matrix4(display_size * v2f(-0.5f, 0.5f)) * - math::make_orthogonal_lh_matrix4(display_size, 0.f, 1.f); + math::make_orthographic_lh_no_matrix4(display_size, 0.f, 1.f) * + math::make_translation_matrix4(-1.f, 1.f); for ( int i = 0; i < draw_data->CmdListsCount; ++i ) { const ImDrawList* cmd_list = draw_data->CmdLists[i]; diff --git a/sources/enduro2d/high/bindings/high_binds/components/camera_binds.cpp b/sources/enduro2d/high/bindings/high_binds/components/camera_binds.cpp index ba40cb70..a22f6332 100644 --- a/sources/enduro2d/high/bindings/high_binds/components/camera_binds.cpp +++ b/sources/enduro2d/high/bindings/high_binds/components/camera_binds.cpp @@ -58,6 +58,22 @@ namespace e2d::bindings::high c->depth(v); }), + "znear", sol::property( + [](const gcomponent& c) -> f32 { + return c->znear(); + }, + [](gcomponent& c, f32 v){ + c->znear(v); + }), + + "zfar", sol::property( + [](const gcomponent& c) -> f32 { + return c->zfar(); + }, + [](gcomponent& c, f32 v){ + c->zfar(v); + }), + "viewport", sol::property( [](const gcomponent& c) -> b2f { return c->viewport(); @@ -66,14 +82,6 @@ namespace e2d::bindings::high c->viewport(v); }), - "projection", sol::property( - [](const gcomponent& c) -> m4f { - return c->projection(); - }, - [](gcomponent& c, const m4f& v){ - c->projection(v); - }), - "background", sol::property( [](const gcomponent& c) -> color { return c->background(); diff --git a/sources/enduro2d/high/bindings/math_binds/mat4_binds.cpp b/sources/enduro2d/high/bindings/math_binds/mat4_binds.cpp index b8b567e7..5b59b56b 100644 --- a/sources/enduro2d/high/bindings/math_binds/mat4_binds.cpp +++ b/sources/enduro2d/high/bindings/math_binds/mat4_binds.cpp @@ -66,20 +66,36 @@ namespace "make_look_at_rh", sol::resolve< mat4(const vec3&,const vec3&,const vec3&)>(&math::make_look_at_rh_matrix4), - "make_orthogonal_lh", sol::overload( - sol::resolve(T,T,T,T)>(&math::make_orthogonal_lh_matrix4), - sol::resolve(const vec2&,T,T)>(&math::make_orthogonal_lh_matrix4)), + "make_orthographic_lh_zo", sol::overload( + sol::resolve(T,T,T,T)>(&math::make_orthographic_lh_zo_matrix4), + sol::resolve(const vec2&,T,T)>(&math::make_orthographic_lh_zo_matrix4)), - "make_orthogonal_rh", sol::overload( - sol::resolve(T,T,T,T)>(&math::make_orthogonal_rh_matrix4), - sol::resolve(const vec2&,T,T)>(&math::make_orthogonal_rh_matrix4)), + "make_orthographic_lh_no", sol::overload( + sol::resolve(T,T,T,T)>(&math::make_orthographic_lh_no_matrix4), + sol::resolve(const vec2&,T,T)>(&math::make_orthographic_lh_no_matrix4)), - "make_perspective_lh", [](T angle, T aspect, T znear, T zfar) -> mat4 { - return math::make_perspective_lh_matrix4(make_rad(angle), aspect, znear, zfar); + "make_orthographic_rh_zo", sol::overload( + sol::resolve(T,T,T,T)>(&math::make_orthographic_rh_zo_matrix4), + sol::resolve(const vec2&,T,T)>(&math::make_orthographic_rh_zo_matrix4)), + + "make_orthographic_rh_no", sol::overload( + sol::resolve(T,T,T,T)>(&math::make_orthographic_rh_no_matrix4), + sol::resolve(const vec2&,T,T)>(&math::make_orthographic_rh_no_matrix4)), + + "make_perspective_lh_zo", [](T angle, T aspect, T znear, T zfar) -> mat4 { + return math::make_perspective_lh_zo_matrix4(make_rad(angle), aspect, znear, zfar); }, - "make_perspective_rh", [](T angle, T aspect, T znear, T zfar) -> mat4 { - return math::make_perspective_rh_matrix4(make_rad(angle), aspect, znear, zfar); + "make_perspective_lh_no", [](T angle, T aspect, T znear, T zfar) -> mat4 { + return math::make_perspective_lh_no_matrix4(make_rad(angle), aspect, znear, zfar); + }, + + "make_perspective_rh_zo", [](T angle, T aspect, T znear, T zfar) -> mat4 { + return math::make_perspective_rh_zo_matrix4(make_rad(angle), aspect, znear, zfar); + }, + + "make_perspective_rh_no", [](T angle, T aspect, T znear, T zfar) -> mat4 { + return math::make_perspective_rh_no_matrix4(make_rad(angle), aspect, znear, zfar); }, "approximately", [](const mat4& l, const mat4& r) -> bool { diff --git a/sources/enduro2d/high/components/camera.cpp b/sources/enduro2d/high/components/camera.cpp index da1bf114..d0315de7 100644 --- a/sources/enduro2d/high/components/camera.cpp +++ b/sources/enduro2d/high/components/camera.cpp @@ -14,8 +14,9 @@ namespace e2d "additionalProperties" : false, "properties" : { "depth" : { "type" : "number" }, + "znear" : { "type" : "number" }, + "zfar" : { "type" : "number" }, "viewport" : { "$ref": "#/common_definitions/b2" }, - "projection" : { "$ref": "#/common_definitions/m4" }, "background" : { "$ref": "#/common_definitions/color" } } })json"; @@ -33,6 +34,24 @@ namespace e2d component.depth(depth); } + if ( ctx.root.HasMember("znear") ) { + f32 znear = component.znear(); + if ( !json_utils::try_parse_value(ctx.root["znear"], znear) ) { + the().error("CAMERA: Incorrect formatting of 'znear' property"); + return false; + } + component.znear(znear); + } + + if ( ctx.root.HasMember("zfar") ) { + f32 zfar = component.zfar(); + if ( !json_utils::try_parse_value(ctx.root["zfar"], zfar) ) { + the().error("CAMERA: Incorrect formatting of 'zfar' property"); + return false; + } + component.zfar(zfar); + } + if ( ctx.root.HasMember("viewport") ) { b2f viewport = component.viewport(); if ( !json_utils::try_parse_value(ctx.root["viewport"], viewport) ) { @@ -42,15 +61,6 @@ namespace e2d component.viewport(viewport); } - if ( ctx.root.HasMember("projection") ) { - m4f projection = component.projection(); - if ( !json_utils::try_parse_value(ctx.root["projection"], projection) ) { - the().error("CAMERA: Incorrect formatting of 'projection' property"); - return false; - } - component.projection(projection); - } - if ( ctx.root.HasMember("target") ) { //TODO(BlackMat): add 'target' property parsing } @@ -118,11 +128,29 @@ namespace e2d } if ( i32 depth = c->depth(); - ImGui::DragInt("depth", &depth) ) + ImGui::DragInt("depth", &depth, 1.f) ) { c->depth(depth); } + if ( ImGui::TreeNode("clipping") ) { + E2D_DEFER([](){ ImGui::TreePop(); }); + + if ( f32 znear = c->znear(); + ImGui::DragFloat("znear", &znear, 1.f) ) + { + c->znear(znear); + c->zfar(math::max(c->zfar(), c->znear())); + } + + if ( f32 zfar = c->zfar(); + ImGui::DragFloat("zfar", &zfar, 1.f) ) + { + c->zfar(zfar); + c->znear(math::min(c->znear(), c->zfar())); + } + } + if ( ImGui::TreeNode("viewport") ) { E2D_DEFER([](){ ImGui::TreePop(); }); @@ -133,13 +161,12 @@ namespace e2d } if ( b2f viewport = c->viewport(); - ImGui::DragFloat2("size", viewport.size.data(), 0.01f) ) + ImGui::DragFloat2("size", viewport.size.data(), 0.01f, 0.f, std::numeric_limits::max()) ) { c->viewport(viewport); } } - ///TODO(BlackMat): add 'projection' inspector ///TODO(BlackMat): add 'target' inspector if ( color background = c->background(); diff --git a/sources/enduro2d/high/components/renderer.cpp b/sources/enduro2d/high/components/renderer.cpp index a693ff22..aa8e2f1c 100644 --- a/sources/enduro2d/high/components/renderer.cpp +++ b/sources/enduro2d/high/components/renderer.cpp @@ -85,7 +85,7 @@ namespace e2d void component_inspector::operator()(gcomponent& c) const { if ( v3f translation = c->translation(); - ImGui::DragFloat3("translation", translation.data(), 1.f) ) + ImGui::DragFloat3("translation", translation.data(), 0.01f) ) { c->translation(translation); } diff --git a/sources/enduro2d/high/systems/gizmos_system.cpp b/sources/enduro2d/high/systems/gizmos_system.cpp index 0f7b86ed..fc5ea82a 100644 --- a/sources/enduro2d/high/systems/gizmos_system.cpp +++ b/sources/enduro2d/high/systems/gizmos_system.cpp @@ -22,8 +22,9 @@ namespace class imgui_gizmos_context final : public component_inspector<>::gizmos_context { public: - imgui_gizmos_context(editor& e, inspector& i) + imgui_gizmos_context(editor& e, window& w, inspector& i) : editor_(e) + , window_(w) , inspector_(i) {} bool setup_camera(const ecs::const_entity& cam_e) { @@ -41,7 +42,7 @@ namespace camera_vp_ = math::inversed(cam_n->world_matrix()).first * - cam.projection() * + cameras::make_projection_matrix(cam, window_) * math::make_scale_matrix4(0.5f, 0.5f) * math::make_translation_matrix4(0.5f, 0.5f) * math::make_scale_matrix4(cam.viewport().size) * @@ -185,6 +186,7 @@ namespace } private: editor& editor_; + window& window_; inspector& inspector_; m4f camera_vp_ = m4f::identity(); m4f go_matrix_ = m4f::identity(); @@ -227,9 +229,9 @@ namespace e2d class gizmos_system::internal_state final : private noncopyable { public: - internal_state(dbgui& d, editor& e, inspector& i) + internal_state(dbgui& d, window& w, editor& e, inspector& i) : dbgui_(d) - , gcontext_(e, i) {} + , gcontext_(e, w, i) {} ~internal_state() noexcept = default; void process_render(const ecs::const_entity& cam_e, ecs::registry& owner) { @@ -254,7 +256,7 @@ namespace e2d // gizmos_system::gizmos_system() - : state_(new internal_state(the(), the(), the())) {} + : state_(new internal_state(the(), the(), the(), the())) {} gizmos_system::~gizmos_system() noexcept = default; void gizmos_system::process( diff --git a/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.cpp b/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.cpp index e85d47ca..a986bbb0 100644 --- a/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.cpp +++ b/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.cpp @@ -58,7 +58,8 @@ namespace e2d::render_system_impl const m4f& m_v = cam_w_inv.second ? cam_w_inv.first : m4f::identity(); - const m4f& m_p = cam.projection(); + + const m4f& m_p = cameras::make_projection_matrix(cam, window); batcher_.flush() .property(screen_s_property_hash, cam.target() diff --git a/untests/sources/untests_math/mat4.cpp b/untests/sources/untests_math/mat4.cpp index ee4d6b5c..7206f8b7 100644 --- a/untests/sources/untests_math/mat4.cpp +++ b/untests/sources/untests_math/mat4.cpp @@ -35,8 +35,11 @@ TEST_CASE("mat4") { REQUIRE(math::make_rotation_matrix4(make_rad(1.f),1.f,1.f,1.f) == math::make_rotation_matrix4(make_rad(1.f), v3f::unit())); REQUIRE(math::make_rotation_matrix4(make_rad(1.f),v3f(1.f,1.f,1.f)) == math::make_rotation_matrix4(make_rad(1.f), v3f::unit())); - REQUIRE(math::make_orthogonal_lh_matrix4(640.f, 480.f, 0.f, 1.f) == math::make_orthogonal_lh_matrix4(v2f(640,480), 0.f, 1.f)); - REQUIRE(math::make_orthogonal_lh_matrix4(640.0, 480.0, 0.0, 1.0) == math::make_orthogonal_lh_matrix4(v2d(640,480), 0.0, 1.0)); + REQUIRE(math::make_orthographic_lh_no_matrix4(640.f, 480.f, 0.f, 1.f) == math::make_orthographic_lh_no_matrix4(v2f(640,480), 0.f, 1.f)); + REQUIRE(math::make_orthographic_lh_no_matrix4(640.0, 480.0, 0.0, 1.0) == math::make_orthographic_lh_no_matrix4(v2d(640,480), 0.0, 1.0)); + + REQUIRE(math::make_orthographic_lh_zo_matrix4(640.f, 480.f, 0.f, 1.f) == math::make_orthographic_lh_zo_matrix4(v2f(640,480), 0.f, 1.f)); + REQUIRE(math::make_orthographic_lh_zo_matrix4(640.0, 480.0, 0.0, 1.0) == math::make_orthographic_lh_zo_matrix4(v2d(640,480), 0.0, 1.0)); } { REQUIRE(m4f(m4f::identity()) == m4f::identity());