From da9946dbe1518724bee8e98a8e0696414771f9ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Fonseca?= Date: Sun, 8 Oct 2023 22:28:18 +0100 Subject: [PATCH] feat(transform): unify components --- engine/CMakeLists.txt | 5 +- .../cubos/engine/transform/local_to_world.hpp | 31 -------- .../include/cubos/engine/transform/plugin.hpp | 24 +----- .../cubos/engine/transform/position.hpp | 22 ------ .../cubos/engine/transform/rotation.hpp | 22 ------ .../include/cubos/engine/transform/scale.hpp | 20 ----- .../cubos/engine/transform/transform.hpp | 68 +++++++++++++++++ .../cubos/engine/transform/local_to_world.cpp | 11 --- engine/src/cubos/engine/transform/plugin.cpp | 45 +---------- .../src/cubos/engine/transform/position.cpp | 11 --- .../src/cubos/engine/transform/rotation.cpp | 11 --- engine/src/cubos/engine/transform/scale.cpp | 9 --- .../src/cubos/engine/transform/transform.cpp | 74 +++++++++++++++++++ 13 files changed, 150 insertions(+), 203 deletions(-) delete mode 100644 engine/include/cubos/engine/transform/local_to_world.hpp delete mode 100644 engine/include/cubos/engine/transform/position.hpp delete mode 100644 engine/include/cubos/engine/transform/rotation.hpp delete mode 100644 engine/include/cubos/engine/transform/scale.hpp create mode 100644 engine/include/cubos/engine/transform/transform.hpp delete mode 100644 engine/src/cubos/engine/transform/local_to_world.cpp delete mode 100644 engine/src/cubos/engine/transform/position.cpp delete mode 100644 engine/src/cubos/engine/transform/rotation.cpp delete mode 100644 engine/src/cubos/engine/transform/scale.cpp create mode 100644 engine/src/cubos/engine/transform/transform.cpp diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index ae90b8b17..bd367dc5d 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -30,10 +30,7 @@ set(CUBOS_ENGINE_SOURCE "src/cubos/engine/tools/scene_editor/plugin.cpp" "src/cubos/engine/transform/plugin.cpp" - "src/cubos/engine/transform/local_to_world.cpp" - "src/cubos/engine/transform/position.cpp" - "src/cubos/engine/transform/rotation.cpp" - "src/cubos/engine/transform/scale.cpp" + "src/cubos/engine/transform/transform.cpp" "src/cubos/engine/assets/plugin.cpp" "src/cubos/engine/assets/assets.cpp" diff --git a/engine/include/cubos/engine/transform/local_to_world.hpp b/engine/include/cubos/engine/transform/local_to_world.hpp deleted file mode 100644 index 976c11236..000000000 --- a/engine/include/cubos/engine/transform/local_to_world.hpp +++ /dev/null @@ -1,31 +0,0 @@ -/// @file -/// @brief Component @ref cubos::engine::LocalToWorld. -/// @ingroup transform-plugin - -#pragma once - -#include - -#include - -namespace cubos::engine -{ - /// @brief Component which stores the transformation matrix of an entity, from local to world - /// space. - /// - /// @note This component is written to by the @ref transform-plugin "transform plugin", and - /// it only makes sense to modify it manually if its not accompanied by the other transform - /// components. - /// - /// @sa Position Applies a translation to this matrix. - /// @sa Rotation Applies a rotation to this matrix. - /// @sa Scale Applies a scaling to this matrix. - /// @ingroup transform-plugin - struct [[cubos::component("cubos/local_to_world", VecStorage)]] LocalToWorld - { - CUBOS_REFLECT; - - glm::mat4 mat = glm::mat4(1.0F); ///< Local to world space matrix. - }; - -} // namespace cubos::engine diff --git a/engine/include/cubos/engine/transform/plugin.hpp b/engine/include/cubos/engine/transform/plugin.hpp index 57103e671..565785937 100644 --- a/engine/include/cubos/engine/transform/plugin.hpp +++ b/engine/include/cubos/engine/transform/plugin.hpp @@ -8,34 +8,16 @@ #pragma once #include -#include -#include -#include -#include +#include namespace cubos::engine { /// @defgroup transform-plugin Transform /// @ingroup engine - /// @brief Adds transform components which assign positions, rotations and scaling to entities. - /// - /// This plugin operates on entities with a @ref LocalToWorld component and any combination of - /// the @ref Position, @ref Rotation and @ref Scale components. For example, if you have an - /// entity which doesn't need rotation, but has a position and a scale, you do not need to add - /// the @ref Rotation component, and its transform will still be updated. - /// - /// @note Any entity with either a @ref Position, @ref Rotation or @ref Scale component - /// automatically gets a @ref LocalToWorld component. + /// @brief Adds transform components. /// /// ## Components - /// - @ref LocalToWorld - holds the local to world transform matrix. - /// - @ref Position - holds the position of an entity. - /// - @ref Rotation - holds the rotation of an entity. - /// - @ref Scale - holds the scaling of an entity. - /// - /// ## Tags - /// - `cubos.transform.update` - the @ref LocalToWorld components are updated with the - /// information from the @ref Position, @ref Rotation and @ref Scale components. + /// - @ref Transform - Component which stores the transformation matrix of an entity. /// @brief Plugin entry function. /// @param cubos @b CUBOS. main class diff --git a/engine/include/cubos/engine/transform/position.hpp b/engine/include/cubos/engine/transform/position.hpp deleted file mode 100644 index b4742bdef..000000000 --- a/engine/include/cubos/engine/transform/position.hpp +++ /dev/null @@ -1,22 +0,0 @@ -/// @file -/// @brief Component @ref cubos::engine::Position. -/// @ingroup transform-plugin - -#pragma once - -#include - -#include - -namespace cubos::engine -{ - /// @brief Component which assigns a position to an entity. - /// @sa LocalToWorld Holds the resulting transform matrix. - /// @ingroup transform-plugin - struct [[cubos::component("cubos/position", VecStorage)]] Position - { - CUBOS_REFLECT; - - glm::vec3 vec = {0.0F, 0.0F, 0.0F}; ///< Position of the entity. - }; -} // namespace cubos::engine diff --git a/engine/include/cubos/engine/transform/rotation.hpp b/engine/include/cubos/engine/transform/rotation.hpp deleted file mode 100644 index 6f8337ddf..000000000 --- a/engine/include/cubos/engine/transform/rotation.hpp +++ /dev/null @@ -1,22 +0,0 @@ -/// @file -/// @brief Component @ref cubos::engine::Rotation. -/// @ingroup transform-plugin - -#pragma once - -#include - -#include - -namespace cubos::engine -{ - /// @brief Component which assigns a rotation to an entity. - /// @sa LocalToWorld Holds the resulting transform matrix. - /// @ingroup transform-plugin - struct [[cubos::component("cubos/rotation", VecStorage)]] Rotation - { - CUBOS_REFLECT; - - glm::quat quat = glm::quat(1.0F, 0.0F, 0.0F, 0.0F); ///< Rotation of the entity. - }; -} // namespace cubos::engine diff --git a/engine/include/cubos/engine/transform/scale.hpp b/engine/include/cubos/engine/transform/scale.hpp deleted file mode 100644 index 738cf13b9..000000000 --- a/engine/include/cubos/engine/transform/scale.hpp +++ /dev/null @@ -1,20 +0,0 @@ -/// @file -/// @brief Component @ref cubos::engine::Scale. -/// @ingroup transform-plugin - -#pragma once - -#include - -namespace cubos::engine -{ - /// @brief Component which assigns a uniform scale to an entity. - /// @sa LocalToWorld Holds the resulting transform matrix. - /// @ingroup transform-plugin - struct [[cubos::component("cubos/scale", VecStorage)]] Scale - { - CUBOS_REFLECT; - - float factor; ///< Uniform scale factor of the entity. - }; -} // namespace cubos::engine diff --git a/engine/include/cubos/engine/transform/transform.hpp b/engine/include/cubos/engine/transform/transform.hpp new file mode 100644 index 000000000..e9fb21ad0 --- /dev/null +++ b/engine/include/cubos/engine/transform/transform.hpp @@ -0,0 +1,68 @@ +/// @file +/// @brief Component @ref cubos::engine::Transform. +/// @ingroup transform-plugin + +#pragma once + +#include + +namespace cubos::engine +{ + /// @brief Component which stores the transformation matrix of an entity. + /// + /// @ingroup transform-plugin + struct [[cubos::component("cubos/transform", VecStorage)]] Transform + { + CUBOS_REFLECT; + + glm::mat4 mat = glm::mat4(1.0F); ///< Local to world space matrix. + + /// @brief Get the transformation matrix from local to world space. + /// @return The transformation matrix from local to world space. + glm::mat4 localToWorld() const; + + /// @brief Get the position of the transform. + /// @return The position of the transform. + glm::vec3 position() const; + + /// @brief Set the position of the transform. + /// @param pos The new position. + void position(const glm::vec3& pos); + + /// @brief Translate the transform. + /// @param delta The translation vector. + void translate(const glm::vec3& delta); + + /// @brief Get the rotation of the transform. + /// @return The rotation of the transform. + glm::quat rotation() const; + + /// @brief Get the rotation of the transform as euler angles. + /// @return The rotation of the transform as euler angles. + glm::vec3 eulerRotation() const; + + /// @brief Set the rotation of the transform. + /// @param rot The new rotation. + void rotation(const glm::quat& rot); + + /// @brief Set the rotation of the transform. + /// @param euler The new rotation as euler angles. + void rotation(const glm::vec3& euler); + + /// @brief Rotate the transform. + /// @param delta The rotation quaternion. + void rotate(const glm::quat& delta); + + /// @brief Rotate the transform. + /// @param eulerDelta The rotation as euler angles. + void rotate(const glm::vec3& eulerDelta); + + /// @brief Get the scale of the transform. + /// @return The scale of the transform. + float scale() const; + + /// @brief Set the scale of the transform. + /// @param scale The new scale. + void scale(float scale); + }; +} // namespace cubos::engine diff --git a/engine/src/cubos/engine/transform/local_to_world.cpp b/engine/src/cubos/engine/transform/local_to_world.cpp deleted file mode 100644 index c62f5099b..000000000 --- a/engine/src/cubos/engine/transform/local_to_world.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -#include - -CUBOS_REFLECT_IMPL(cubos::engine::LocalToWorld) -{ - return core::ecs::ComponentTypeBuilder("cubos::engine::LocalToWorld") - .withField("mat", &LocalToWorld::mat) - .build(); -} diff --git a/engine/src/cubos/engine/transform/plugin.cpp b/engine/src/cubos/engine/transform/plugin.cpp index edd895d3a..be5230d19 100644 --- a/engine/src/cubos/engine/transform/plugin.cpp +++ b/engine/src/cubos/engine/transform/plugin.cpp @@ -1,52 +1,15 @@ #include -using cubos::core::ecs::Commands; -using cubos::core::ecs::OptRead; -using cubos::core::ecs::Query; -using cubos::core::ecs::Write; using namespace cubos::engine; -static void autoLocalToWorld(Commands cmds, - Query, OptRead, OptRead, OptRead> query) +static void updateTransform() { - for (auto [entity, localToWorld, position, rotation, scale] : query) - { - if (!localToWorld && (position || rotation || scale)) - { - cmds.add(entity, LocalToWorld{}); - } - } -} - -static void applyTransform(Query, OptRead, OptRead, OptRead> query) -{ - for (auto [entity, localToWorld, position, rotation, scale] : query) - { - localToWorld->mat = glm::mat4(1.0F); - if (position) - { - localToWorld->mat = glm::translate(localToWorld->mat, position->vec); - } - - if (rotation) - { - localToWorld->mat *= glm::toMat4(rotation->quat); - } - - if (scale) - { - localToWorld->mat = glm::scale(localToWorld->mat, glm::vec3(scale->factor)); - } - } + // In the future, parent-child relationships will be handled here. } void cubos::engine::transformPlugin(Cubos& cubos) { - cubos.addComponent(); - cubos.addComponent(); - cubos.addComponent(); - cubos.addComponent(); + cubos.addComponent(); - cubos.system(autoLocalToWorld).before("cubos.transform.update"); - cubos.system(applyTransform).tagged("cubos.transform.update"); + cubos.system(updateTransform).tagged("cubos.transform.update"); } diff --git a/engine/src/cubos/engine/transform/position.cpp b/engine/src/cubos/engine/transform/position.cpp deleted file mode 100644 index 773c3f973..000000000 --- a/engine/src/cubos/engine/transform/position.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -#include - -CUBOS_REFLECT_IMPL(cubos::engine::Position) -{ - return core::ecs::ComponentTypeBuilder("cubos::engine::Position") - .withField("vec", &Position::vec) - .build(); -} diff --git a/engine/src/cubos/engine/transform/rotation.cpp b/engine/src/cubos/engine/transform/rotation.cpp deleted file mode 100644 index c1c4a87fd..000000000 --- a/engine/src/cubos/engine/transform/rotation.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -#include - -CUBOS_REFLECT_IMPL(cubos::engine::Rotation) -{ - return core::ecs::ComponentTypeBuilder("cubos::engine::Rotation") - .withField("quat", &Rotation::quat) - .build(); -} diff --git a/engine/src/cubos/engine/transform/scale.cpp b/engine/src/cubos/engine/transform/scale.cpp deleted file mode 100644 index b14d77dbb..000000000 --- a/engine/src/cubos/engine/transform/scale.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -#include - -CUBOS_REFLECT_IMPL(cubos::engine::Scale) -{ - return core::ecs::ComponentTypeBuilder("cubos::engine::Scale").withField("mat", &Scale::factor).build(); -} diff --git a/engine/src/cubos/engine/transform/transform.cpp b/engine/src/cubos/engine/transform/transform.cpp new file mode 100644 index 000000000..792547794 --- /dev/null +++ b/engine/src/cubos/engine/transform/transform.cpp @@ -0,0 +1,74 @@ +#include +#include +#include + +#include + +using namespace cubos::engine; + +glm::mat4 Transform::localToWorld() const +{ + return mat; +} + +glm::vec3 Transform::position() const +{ + return core::geom::position(mat); +} + +void Transform::position(const glm::vec3& pos) +{ + core::geom::position(mat, pos); +} + +void Transform::translate(const glm::vec3& delta) +{ + core::geom::translate(mat, delta); +} + +glm::quat Transform::rotation() const +{ + return core::geom::rotation(mat); +} + +glm::vec3 Transform::eulerRotation() const +{ + return core::geom::eulerRotation(mat); +} + +void Transform::rotation(const glm::quat& rot) +{ + core::geom::rotation(mat, rot); +} + +void Transform::rotation(const glm::vec3& euler) +{ + core::geom::rotation(mat, euler); +} + +void Transform::rotate(const glm::quat& delta) +{ + core::geom::rotate(mat, delta); +} + +void Transform::rotate(const glm::vec3& eulerDelta) +{ + core::geom::rotate(mat, eulerDelta); +} + +float Transform::scale() const +{ + return core::geom::scale(mat); +} + +void Transform::scale(float scale) +{ + core::geom::scale(mat, scale); +} + +CUBOS_REFLECT_IMPL(cubos::engine::Transform) +{ + return core::ecs::ComponentTypeBuilder("cubos::engine::Transform") + .withField("mat", &Transform::mat) + .build(); +}