From a4f9308aa76270fd675897bf0f143854a1743e09 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Thu, 17 Dec 2020 23:23:08 +0100 Subject: [PATCH] WiP for proper support of ECS - figuring out how to use transformations in a ECS --- src/core/include/pw/core/debug.hpp | 1 + src/core/include/pw/core/matrix.hpp | 13 ++-- src/core/include/pw/core/matrixbase.hpp | 2 +- .../pw/scene/components/relationship.hpp | 18 +++-- .../include/pw/scene/components/transform.hpp | 30 +++------ src/scene/include/pw/scene/scene.hpp | 1 + src/scene/src/entity.cpp | 27 ++++---- src/scene/src/scene.cpp | 65 ++++++++++++++----- src/scene/tests/pwscene_test_scene.cpp | 6 ++ src/visual/src/texture.cpp | 4 ++ 10 files changed, 107 insertions(+), 60 deletions(-) diff --git a/src/core/include/pw/core/debug.hpp b/src/core/include/pw/core/debug.hpp index 601770b..d20ec0f 100644 --- a/src/core/include/pw/core/debug.hpp +++ b/src/core/include/pw/core/debug.hpp @@ -75,6 +75,7 @@ public: stream& operator << (const void *value); ///! pointer + protected: debug* _log; diff --git a/src/core/include/pw/core/matrix.hpp b/src/core/include/pw/core/matrix.hpp index 2a489ed..03e9685 100644 --- a/src/core/include/pw/core/matrix.hpp +++ b/src/core/include/pw/core/matrix.hpp @@ -70,9 +70,6 @@ struct matrix_ : matrixbase_> return *this; } -// //! get cell count -// inline std::size_t coefficients() const { return this->size(); } - inline size_t offset(size_t r,size_t c) const { return (RowMajor) ? r * C + c : c * R + r; } @@ -85,7 +82,7 @@ struct matrix_ : matrixbase_> return data[offset(r,c)]; } - inline const T* ptr() const { return &data[0]; } + inline const T *ptr() const { return &data[0]; } //! set identity inline matrix_& set_identity() @@ -201,6 +198,14 @@ struct matrix_ : matrixbase_> for (size_t i = 0; i < rows; i++) c[i] = (*this)(i,col_); return c; } + + static constexpr auto identity() { + matrix_ res; + for (std::size_t r = 0;r < rows; r++) + for (std::size_t c = 0; c < cols; c++) + res(r,c) = (c == r) ? T(1) : T(0); + return res; + } }; template <> inline diff --git a/src/core/include/pw/core/matrixbase.hpp b/src/core/include/pw/core/matrixbase.hpp index 39d245b..b2b46cb 100644 --- a/src/core/include/pw/core/matrixbase.hpp +++ b/src/core/include/pw/core/matrixbase.hpp @@ -39,7 +39,7 @@ namespace pw { template struct matrixbase_ { - typedef T value_type; + using value_type = T; Derived& derived() { return static_cast(*this); } const Derived& derived() const { return static_cast(*this); } diff --git a/src/scene/include/pw/scene/components/relationship.hpp b/src/scene/include/pw/scene/components/relationship.hpp index 7b23dcc..b00da04 100644 --- a/src/scene/include/pw/scene/components/relationship.hpp +++ b/src/scene/include/pw/scene/components/relationship.hpp @@ -33,12 +33,20 @@ namespace pw { /** * @brief entity relations are hidden and managed by the entity itself */ -struct relationship { - relationship() = default; - relationship(const relationship&) = default; +struct parent { + parent() = default; + parent(const parent&) = default; - std::vector children; - entt::entity parent { entt::null }; + entt::entity entity { entt::null }; + + operator bool() const { return entity != entt::null; } +}; + +struct children { + children() = default; + children(const children&) = default; + + std::vector entities; }; diff --git a/src/scene/include/pw/scene/components/transform.hpp b/src/scene/include/pw/scene/components/transform.hpp index 64c5b3e..4ec5a02 100644 --- a/src/scene/include/pw/scene/components/transform.hpp +++ b/src/scene/include/pw/scene/components/transform.hpp @@ -9,58 +9,52 @@ namespace pw { struct transform { + transform() = default; + transform(const transform&) = default; + inline const matrix4x4& local() const { return _local; } void set_local(const matrix4x4 &local) { _local = local; - update_global_from_local(); - // TODO need to rebuild the transforms: both -> global down and global up } inline const matrix4x4& global() const { return _global; } + void set_global(const matrix4x4 &global) { + matrix4x4 diff = _global.inverse() * global; + _local = _local * diff; + _global = global; - _global_inverse = global.inverse(); - - update_local_from_global(); } - inline const matrix4x4& global_inverse() const { return _global_inverse; } - inline transform& translate(const real_t &x, const real_t &y, const real_t &z) { _local(0,3) += x;_local(1,3) += y;_local(2,3) += z; - update_global_from_local(); return *this; } inline transform& set_translation(const real_t &x, const real_t &y, const real_t &z) { _local(0,3) = x;_local(1,3) = y;_local(2,3) = z; - update_global_from_local(); return *this; } inline transform& rotate(const quaternion& q) { _local = _local * q.to_matrix(); - update_global_from_local(); return *this; } inline transform& set_rotation(const quaternion& q) { _local = q.to_matrix(); - update_global_from_local(); return *this; } inline transform& scale(const real_t &sx, const real_t &sy, const real_t &sz) { _local(0,0) *= sx; _local(1,1) *= sy; _local(2,2) *= sz; - update_global_from_local(); return *this; } inline transform& set_scale(const real_t &sx, const real_t &sy, const real_t &sz) { _local(0,0) = sx; _local(1,1) = sy; _local(2,2) = sz; - update_global_from_local(); return *this; } @@ -68,14 +62,8 @@ struct transform { return scale(uniform_scale,uniform_scale,uniform_scale); } - matrix4x4 _local; - matrix4x4 _global; - - matrix4x4 _global_inverse; - - void update_global_from_local(); - - void update_local_from_global(); + matrix4x4 _local = matrix4x4::identity(); + matrix4x4 _global = matrix4x4::identity(); }; } diff --git a/src/scene/include/pw/scene/scene.hpp b/src/scene/include/pw/scene/scene.hpp index 722d8dd..50fa22c 100644 --- a/src/scene/include/pw/scene/scene.hpp +++ b/src/scene/include/pw/scene/scene.hpp @@ -28,6 +28,7 @@ #include #include + namespace pw { class entity; diff --git a/src/scene/src/entity.cpp b/src/scene/src/entity.cpp index a665978..5a914ae 100644 --- a/src/scene/src/entity.cpp +++ b/src/scene/src/entity.cpp @@ -43,12 +43,12 @@ bool entity::add_child(entity &child) // TODO: check circular dependencies // declare child relationship - auto& r = get_or_create_component(); - r.children.push_back(child._entity); + auto& c = this->get_or_create_component(); + c.entities.push_back(child._entity); // declare parent - auto& p_r = child.get_or_create_component(); - p_r.parent = _entity; + auto& p_r = child.get_or_create_component(); + p_r.entity = _entity; return true; } @@ -62,19 +62,19 @@ bool entity::remove_child(entity& child) } // both need to have a relationship component - if (has_component() && - child.has_component()) + if (child.has_component() && + this->has_component()) { // we need to check if the child is related to the parent - auto r_p = child.get_component(); - if (r_p.parent == _entity) + auto r_p = child.get_component(); + if (r_p.entity == _entity) { // now go ahead delete parent - r_p.parent = entt::null; + r_p.entity = entt::null; // now remove all children - auto& r = this->get_component(); - r.children.erase(std::remove(r.children.begin(),r.children.end(),child._entity)); + auto& c = this->get_component(); + c.entities.erase(std::remove(c.entities.begin(),c.entities.end(),child._entity)); // flag success return true; @@ -83,10 +83,11 @@ bool entity::remove_child(entity& child) return false; } + size_t entity::child_count() const { - return has_component() ? - get_component().children.size() : + return this->has_component() ? + get_component().entities.size() : 0; } diff --git a/src/scene/src/scene.cpp b/src/scene/src/scene.cpp index 8f5a1ee..498b4ee 100644 --- a/src/scene/src/scene.cpp +++ b/src/scene/src/scene.cpp @@ -2,6 +2,7 @@ #include "pw/scene/entity.hpp" #include "pw/core/debug.hpp" +#include "pw/core/serialize.hpp" namespace pw { @@ -23,35 +24,67 @@ size_t scene::count_alive_enties() const void scene::update_transforms() { -#if 0 +#if 1 - auto view = _registry->view(); + // search for nodes with parent and transform (only find leaf nodes) + auto view = _registry->view(entt::exclude); for (auto entity : view) { - auto [t,r] = view.get(entity); + debug::d() << "info for entity " << (int)entity; - } + //auto [t,r] = view.get(entity); - #endif + // collect node path + std::vector path; + while (_registry->has(entity)) { + if (_registry->has(entity)) { + path.push_back(_registry->get(entity)); + } - - auto view = _registry->view(); - - for (auto e : view) { - - const auto& r = view.get(e); - - if (r.children.size() && r.parent == entt::null) { - debug::d() << "root"; + entity = _registry->get(entity).entity; } -// debug::d() << __PRETTY_FUNCTION__ << " " << view.get(e).children.size(); -// if + debug::d() << "\tpath length " << path.size(); + + std::reverse(path.begin(),path.end()); + + auto m = pw::matrix4x4::identity(); + + for (auto& transform : path) { + transform._global = transform._local * m; + m = transform._global; + + debug::d() << pw::serialize::matrix(m); + } + + + +// r = _registry->view + } + +#else + +// auto view = _registry->view(); + +// for (auto e : view) { + +// const auto& r = view.get(e); + +// if (r.children.size() && r.parent == entt::null) { +// debug::d() << "root '" << (int)e << "'"; +// } + +//// debug::d() << __PRETTY_FUNCTION__ << " " << view.get(e).children.size(); + +//// if +// } +#endif + // auto vr = _registry->view(); // for (auto [rel] : vr) { diff --git a/src/scene/tests/pwscene_test_scene.cpp b/src/scene/tests/pwscene_test_scene.cpp index fa55ab6..7b3e426 100644 --- a/src/scene/tests/pwscene_test_scene.cpp +++ b/src/scene/tests/pwscene_test_scene.cpp @@ -43,6 +43,12 @@ void test_stack() e2.add_component(); e3.add_component(); + auto e22 = entity{s}; + e22.add_component().set_scale(.5,.5,.5); + e2.add_child(e22); + + e2.get_component().set_translation(10,20,40); + std::cout << e.child_count() << std::endl; s.update_transforms(); diff --git a/src/visual/src/texture.cpp b/src/visual/src/texture.cpp index 8c2982a..a184c44 100644 --- a/src/visual/src/texture.cpp +++ b/src/visual/src/texture.cpp @@ -26,6 +26,10 @@ struct texture::impl { case data_layout::shape_3d: return GL_TEXTURE_3D; } + + debug::e() << __PRETTY_FUNCTION__ << " unknown texture layout"; + + return 0; } void create()