diff --git a/CHANGELOG.md b/CHANGELOG.md index 670d5c822..1f4c79d0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Generic Camera component to hold projection matrix (#1331, **@mkuritsu**) - Initial application debugging through Tesseratos (#1303, **@RiscadoA**). - Print stacktrace with *cpptrace* on calls to CUBOS_FAIL (#1172, **@RiscadoA**). +- OrthographicCamera component (#1182, **@mkuritsu**) ### Fixed diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 001549789..7dbebd6e5 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -127,6 +127,7 @@ set(CUBOS_ENGINE_SOURCE "src/render/depth/plugin.cpp" "src/render/depth/depth.cpp" "src/render/camera/plugin.cpp" + "src/render/camera/orthographic_camera.cpp" "src/render/camera/perspective_camera.cpp" "src/render/camera/draws_to.cpp" "src/render/camera/camera.cpp" diff --git a/engine/include/cubos/engine/render/camera/orthographic_camera.hpp b/engine/include/cubos/engine/render/camera/orthographic_camera.hpp new file mode 100644 index 000000000..7ba2bbd07 --- /dev/null +++ b/engine/include/cubos/engine/render/camera/orthographic_camera.hpp @@ -0,0 +1,31 @@ +/// @file +/// @brief Component @ref cubos::engine::OrthographicCamera +/// @ingroup render-camera-plugin + +#pragma once + +#include + +#include + +#include + +namespace cubos::engine +{ + /// @brief Component which defines parameters of a orthographic camera used to render the world. + /// @note Should be used with @ref LocalToWorld. + /// @ingroup render-camera-plugin + struct CUBOS_ENGINE_API OrthographicCamera + { + CUBOS_REFLECT; + + /// @brief Size multiplier for orthographic camera planes. + glm::vec2 size{1.0F, 1.0F}; + + /// @brief Near clipping plane. + float zNear{0.1F}; + + /// @brief Far clipping plane. + float zFar{1000.0F}; + }; +} // namespace cubos::engine diff --git a/engine/samples/render/main/assets/main.cubos b/engine/samples/render/main/assets/main.cubos index d71ed6420..43221064f 100644 --- a/engine/samples/render/main/assets/main.cubos +++ b/engine/samples/render/main/assets/main.cubos @@ -13,7 +13,12 @@ } }, "camera2": { - "cubos::engine::PerspectiveCamera": {}, + "cubos::engine::OrthographicCamera": { + "size": { + "x": 0.1, + "y": 0.1 + } + }, "cubos::engine::DrawsTo@render-target": {}, "cubos::engine::Position": { "x": 3, @@ -63,4 +68,4 @@ } } } -} \ No newline at end of file +} diff --git a/engine/src/render/camera/orthographic_camera.cpp b/engine/src/render/camera/orthographic_camera.cpp new file mode 100644 index 000000000..d65ea39d2 --- /dev/null +++ b/engine/src/render/camera/orthographic_camera.cpp @@ -0,0 +1,14 @@ +#include +#include +#include + +#include + +CUBOS_REFLECT_IMPL(cubos::engine::OrthographicCamera) +{ + return core::ecs::TypeBuilder("cubos::engine::OrthographicCamera") + .withField("size", &OrthographicCamera::size) + .withField("zNear", &OrthographicCamera::zNear) + .withField("zFar", &OrthographicCamera::zFar) + .build(); +} diff --git a/engine/src/render/camera/plugin.cpp b/engine/src/render/camera/plugin.cpp index 1aa4998c0..15614a992 100644 --- a/engine/src/render/camera/plugin.cpp +++ b/engine/src/render/camera/plugin.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -13,8 +14,9 @@ void cubos::engine::cameraPlugin(Cubos& cubos) { cubos.depends(renderTargetPlugin); - cubos.component(); cubos.component(); + cubos.component(); + cubos.component(); cubos.relation(); @@ -28,6 +30,16 @@ void cubos::engine::cameraPlugin(Cubos& cubos) } }); + cubos.observer("add Camera on add OrthographicCamera") + .onAdd() + .without() + .call([](Commands cmds, Query query) { + for (auto [ent] : query) + { + cmds.add(ent, Camera{}); + } + }); + cubos.system("update Camera projection by PerspectiveCamera") .call([](Query query) { for (auto [camera, perspective, drawsTo, target] : query) @@ -41,4 +53,18 @@ void cubos::engine::cameraPlugin(Cubos& cubos) } } }); + + cubos.system("update Camera projection by OrthographicCamera") + .call([](Query query) { + for (auto [camera, ortho, drawsTo, target] : query) + { + float width = static_cast(target.size.x) * drawsTo.viewportSize.x; + float height = static_cast(target.size.y) * drawsTo.viewportSize.y; + float left = (-width / 2.0F) * ortho.size.x; + float right = (width / 2.0F) * ortho.size.x; + float bottom = (-height / 2.0F) * ortho.size.y; + float top = (height / 2.0F) * ortho.size.y; + camera.projection = glm::ortho(left, right, bottom, top, ortho.zNear, ortho.zFar); + } + }); }