refactoring with ECS
This commit is contained in:
parent
4078cdea8f
commit
e25625998c
20 changed files with 176 additions and 770 deletions
|
@ -70,7 +70,6 @@ struct matrix_ : matrixbase_<T, matrix_<R, C, T>>
|
|||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// //! get cell count
|
||||
// inline std::size_t coefficients() const { return this->size(); }
|
||||
|
||||
|
|
|
@ -116,121 +116,8 @@ struct matrixbase_ {
|
|||
inline const Derived operator - (const T& b) const { Derived r(derived()); for (auto & e : r) e -= b; return r; }
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
///**
|
||||
// * \brief base class for all matrix and vector operations
|
||||
// */
|
||||
//template <typename T> class matrixbase {
|
||||
//public:
|
||||
|
||||
// typedef T value_type;
|
||||
// typedef int offset_type;
|
||||
// typedef unsigned int size_type;
|
||||
|
||||
|
||||
// matrixbase() {}
|
||||
|
||||
// //! assignment constructor
|
||||
// explicit matrixbase(int rows, int cols,T* ptr,bool row_major,int data_offset = 0)
|
||||
// : _data(ptr)
|
||||
// , _data_offset(data_offset)
|
||||
// , _rows(rows)
|
||||
// , _cols(cols)
|
||||
// , _row_stride(row_major ? 1 : cols)
|
||||
// , _col_stride(row_major ? rows : 1)
|
||||
// {
|
||||
// }
|
||||
|
||||
// inline const T& get_element(int e) const { return this->at(e); }
|
||||
// inline void set_element(int e,const T &v) { this->at(e) = v; }
|
||||
|
||||
// //! return number of rows
|
||||
// inline unsigned int rows() const { return _rows; }
|
||||
// //! return number of columns
|
||||
// inline unsigned int cols() const { return _cols; }
|
||||
|
||||
// //! get cell count
|
||||
// inline unsigned int cells() const { return _rows * _cols; }
|
||||
|
||||
// //! get data
|
||||
// inline T* data() { return _data + _data_offset; }
|
||||
|
||||
// //! get data
|
||||
// inline const T* data() const { return _data + _data_offset; }
|
||||
|
||||
// //! get item at index
|
||||
// inline T& at(unsigned int idx) { return data()[idx]; }
|
||||
|
||||
// //! get item at index
|
||||
// inline const T& at(unsigned int idx) const { return data()[idx]; }
|
||||
|
||||
// //! get item at position
|
||||
// inline T& at(unsigned int r,unsigned int c) { return data()[r * _row_stride + c * _col_stride]; }
|
||||
|
||||
// //! get item at position
|
||||
// inline const T& at(unsigned int r,unsigned int c) const { return data()[r * _row_stride + c * _col_stride]; }
|
||||
|
||||
// //! fill data
|
||||
// inline matrixbase& fill(const T& val) {
|
||||
// for (unsigned int r = 0; r < this->rows(); r++)
|
||||
// for (unsigned int c = 0; c < this->cols(); c++)
|
||||
// this->at(r,c) = val;
|
||||
// return *this;
|
||||
// }
|
||||
|
||||
// //! set identity
|
||||
// inline matrixbase& set_identity() {
|
||||
// for (unsigned int r = 0;r < rows(); r++)
|
||||
// for (unsigned int c = 0; c < cols(); c++)
|
||||
// this->at(r,c) = (c == r) ? T(1) : T(0);
|
||||
// return *this;
|
||||
// }
|
||||
|
||||
// //! set strides for row and column
|
||||
// inline void set_stride(int row_stride,int col_stride) {
|
||||
// _row_stride = row_stride; _col_stride = col_stride;
|
||||
// }
|
||||
|
||||
// //! return row stride (elements between consequtive rows)
|
||||
// inline int row_stride() const { return _row_stride; }
|
||||
|
||||
// //! return column stride (elements between consequtive columns)
|
||||
// inline int col_stride() const { return _col_stride; }
|
||||
|
||||
// //! get row major
|
||||
// inline bool is_row_major() const { return row_stride() > col_stride(); }
|
||||
|
||||
// //! check if squared
|
||||
// inline bool is_square() const { return (_rows == _cols); }
|
||||
|
||||
// //! flip row/column order
|
||||
// inline void flip_order() { set_stride(col_stride(),row_stride()); }
|
||||
|
||||
// //! get the offset for data in the matrix
|
||||
// inline int get_data_offset(int r,int c) const { return (r * _row_stride + c * _col_stride) + _data_offset; }
|
||||
|
||||
//protected:
|
||||
|
||||
// T* _data;
|
||||
// int _data_offset;
|
||||
|
||||
// int _cols;
|
||||
// int _rows;
|
||||
|
||||
// int _row_stride;
|
||||
// int _col_stride;
|
||||
|
||||
//};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,33 +1,29 @@
|
|||
|
||||
set(hdrs
|
||||
include/pw/scene/entity.hpp
|
||||
include/pw/scene/projection.hpp
|
||||
include/pw/scene/component.hpp
|
||||
include/pw/scene/node.hpp
|
||||
include/pw/scene/scene.hpp
|
||||
include/pw/scene/transform.hpp
|
||||
include/pw/scene/traverser.hpp
|
||||
)
|
||||
|
||||
set(hdrs_components
|
||||
include/pw/scene/components/relationship.hpp
|
||||
include/pw/scene/components/transform.hpp
|
||||
include/pw/scene/components/projection.hpp
|
||||
)
|
||||
|
||||
set(srcs
|
||||
src/entity.cpp
|
||||
src/node.cpp
|
||||
src/projection.cpp
|
||||
src/component.cpp
|
||||
src/scene.cpp
|
||||
src/transform.cpp
|
||||
src/traverser.cpp
|
||||
)
|
||||
|
||||
add_library(pwscene
|
||||
STATIC
|
||||
${hdrs}
|
||||
${hdrs_components}
|
||||
${srcs}
|
||||
)
|
||||
|
||||
target_include_directories(
|
||||
pwscene
|
||||
|
||||
PUBLIC
|
||||
include
|
||||
)
|
||||
|
|
|
@ -22,51 +22,55 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PW_SCENE_COMPONENT_HPP
|
||||
#define PW_SCENE_COMPONENT_HPP
|
||||
#ifndef PW_SCENE_PROJECTION_HPP
|
||||
#define PW_SCENE_PROJECTION_HPP
|
||||
|
||||
#include <pw/core/globals.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <pw/core/matrix.hpp>
|
||||
|
||||
namespace pw {
|
||||
|
||||
class node;
|
||||
struct projection {
|
||||
|
||||
/**
|
||||
* @brief components represent attributes of the scene nodes
|
||||
*/
|
||||
void set_matrix(const matrix4x4 &projection)
|
||||
{
|
||||
this->projection_matrix = projection;
|
||||
|
||||
class component {
|
||||
public:
|
||||
// recompute the simplified parameters
|
||||
|
||||
friend class node;
|
||||
typedef std::vector<component> array;
|
||||
// auto near = _projection(3,4);
|
||||
// auto far = _projection(3,4);
|
||||
|
||||
component(node &host);
|
||||
component(const component& other);
|
||||
virtual ~component();
|
||||
// right = (1-m14) / m11
|
||||
|
||||
bool enabled() const;
|
||||
void set_enabled(bool enabled);
|
||||
// near = (1+m34)/m33;
|
||||
// far = -(1-m34)/m33;
|
||||
// bottom = (1-m24)/m22;
|
||||
// top = -(1+m24)/m22;
|
||||
// left = -(1+m14)/m11;
|
||||
// right = (1-m14)/m11;
|
||||
|
||||
uint32_t weight() const;
|
||||
void set_weight(const uint32_t &weight);
|
||||
// real_t fov_raw = float( atan (top / near_)) * * 2.0f;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T* cast() { return static_cast<T*>(this);}
|
||||
operator const matrix4x4&() const
|
||||
{
|
||||
return projection_matrix;
|
||||
}
|
||||
|
||||
protected:
|
||||
void set_frustum(real_t left,
|
||||
real_t right,
|
||||
real_t top,
|
||||
real_t bottom)
|
||||
{
|
||||
|
||||
uint32_t _weight = 1;
|
||||
}
|
||||
|
||||
node &_node;
|
||||
bool _enabled;
|
||||
|
||||
matrix4x4 projection_matrix;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1999-2017 Hartmut Seichter
|
||||
* Copyright (C) 1999-2020 Hartmut Seichter
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -22,40 +22,26 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PW_SCENE_PROJECTION_HPP
|
||||
#define PW_SCENE_PROJECTION_HPP
|
||||
#ifndef PW_SCENE_COMPONENTS_RELATIONSHIP_HPP
|
||||
#define PW_SCENE_COMPONENTS_RELATIONSHIP_HPP
|
||||
|
||||
|
||||
#include <pw/core/matrix.hpp>
|
||||
#include <pw/scene/component.hpp>
|
||||
#include <pw/scene/scene.hpp>
|
||||
|
||||
namespace pw {
|
||||
|
||||
class projection : public component {
|
||||
public:
|
||||
/**
|
||||
* @brief entity relations are hidden and managed by the entity itself
|
||||
*/
|
||||
struct relationship {
|
||||
relationship() = default;
|
||||
relationship(const relationship&) = default;
|
||||
|
||||
using component::component;
|
||||
|
||||
projection(node &host);
|
||||
|
||||
void set_matrix(const matrix4x4 &projection);
|
||||
const matrix4x4& matrix() const
|
||||
{
|
||||
return _m;
|
||||
}
|
||||
|
||||
void set_frustum(real_t left,
|
||||
real_t right,
|
||||
real_t top,
|
||||
real_t bottom);
|
||||
|
||||
private:
|
||||
|
||||
matrix4x4 _m;
|
||||
std::vector<entt::entity> children;
|
||||
entt::entity parent { entt::null };
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -7,18 +7,24 @@
|
|||
|
||||
namespace pw {
|
||||
|
||||
class node;
|
||||
|
||||
class transform {
|
||||
public:
|
||||
|
||||
transform(node &host);
|
||||
struct transform {
|
||||
|
||||
inline const matrix4x4& local() const { return _local; }
|
||||
void set_local(const matrix4x4 &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);
|
||||
void set_global(const matrix4x4 &global)
|
||||
{
|
||||
_global = global;
|
||||
_global_inverse = global.inverse();
|
||||
|
||||
update_local_from_global();
|
||||
}
|
||||
|
||||
inline const matrix4x4& global_inverse() const { return _global_inverse; }
|
||||
|
||||
|
@ -62,21 +68,13 @@ public:
|
|||
return scale(uniform_scale,uniform_scale,uniform_scale);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
matrix4x4 _local;
|
||||
matrix4x4 _global;
|
||||
|
||||
matrix4x4 _global_inverse;
|
||||
|
||||
private:
|
||||
|
||||
node &_node;
|
||||
|
||||
//! updates the global transform from parent globals and local transform
|
||||
void update_global_from_local();
|
||||
|
||||
//! updates the local transform from parent and new global
|
||||
void update_local_from_global();
|
||||
};
|
||||
|
|
@ -38,14 +38,14 @@ class entity {
|
|||
public:
|
||||
entity() = default;
|
||||
entity(const entity&) = default;
|
||||
entity(scene& s);
|
||||
entity(scene& s, const std::string &name = "");
|
||||
~entity();
|
||||
|
||||
/**
|
||||
* adds a component
|
||||
*/
|
||||
template <typename T,typename... Args>
|
||||
[[nodiscard]] T& add_component(Args&&... args) {
|
||||
T& add_component(Args&&... args) {
|
||||
return _registry->emplace<T>(this->_entity,std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ public:
|
|||
* returns a component
|
||||
*/
|
||||
template<typename T>
|
||||
[[nodiscard]] T& get_component() const {
|
||||
T& get_component() const {
|
||||
return _registry->get<T>(this->_entity);
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ public:
|
|||
* gets or creates a component
|
||||
*/
|
||||
template <typename T,typename... Args>
|
||||
[[nodiscard]] T& get_or_create_component(Args&&... args) {
|
||||
T& get_or_create_component(Args&&... args) {
|
||||
return _registry->get_or_emplace<T>(this->_entity,std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
|
@ -122,6 +122,17 @@ public:
|
|||
*/
|
||||
size_t child_count() const;
|
||||
|
||||
/**
|
||||
* @brief set the name
|
||||
* @param n name to be set
|
||||
*/
|
||||
void set_name(const std::string &n);
|
||||
|
||||
/**
|
||||
* @brief name
|
||||
* @return name of the entity
|
||||
*/
|
||||
std::string name();
|
||||
private:
|
||||
|
||||
std::shared_ptr<entt::registry> _registry;
|
||||
|
@ -130,4 +141,10 @@ private:
|
|||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include <pw/scene/components/relationship.hpp>
|
||||
#include <pw/scene/components/transform.hpp>
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,129 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 1999-2017 Hartmut Seichter
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef PW_SCENE_NODE_HPP
|
||||
#define PW_SCENE_NODE_HPP
|
||||
|
||||
#include <pw/core/globals.hpp>
|
||||
#include <pw/scene/component.hpp>
|
||||
#include <pw/scene/transform.hpp>
|
||||
|
||||
|
||||
namespace pw {
|
||||
|
||||
/**
|
||||
* @brief nodes represent the structure for the scene graph
|
||||
*
|
||||
* Unlike earlier designs the scenegraph here is not a DAG
|
||||
* but uses multiple references to components like Unity. This makes the
|
||||
* design of the scenegraph and traversal much more straight-forward.
|
||||
*/
|
||||
class node {
|
||||
public:
|
||||
|
||||
friend class component;
|
||||
|
||||
typedef shared_ptr<node> ref;
|
||||
typedef std::vector<ref> ref_array;
|
||||
|
||||
typedef node *ptr;
|
||||
typedef std::vector<ptr> ptr_array;
|
||||
|
||||
//! standard c'tor
|
||||
node();
|
||||
|
||||
//! copy c'tor
|
||||
node(const node& node);
|
||||
|
||||
//! d'tor
|
||||
~node();
|
||||
|
||||
//! cloning interface
|
||||
ref clone(const unsigned short& copymode) const;
|
||||
|
||||
std::string name() const; //!< get name
|
||||
void set_name(const std::string &name); //!< set name
|
||||
|
||||
//! return parent of this node
|
||||
inline ptr parent() const { return _path.back(); }
|
||||
|
||||
//! add a child node
|
||||
void add_child(ref child_node);
|
||||
|
||||
//! remove a child
|
||||
void remove_child(ref child_node);
|
||||
|
||||
//! get the list of children
|
||||
inline const ref_array& children() const { return _children; }
|
||||
|
||||
//! get number of children
|
||||
inline size_t child_count() const { return children().size(); }
|
||||
|
||||
//! check if this node is a leaf node
|
||||
inline bool is_leaf() const { return children().empty(); }
|
||||
|
||||
//! check if this is the root node
|
||||
inline bool is_root() const { return _path.empty(); }
|
||||
|
||||
//! list of components
|
||||
const component::array& components() const;
|
||||
|
||||
//! add a node component
|
||||
void add_component(component new_component);
|
||||
|
||||
template<typename T>
|
||||
void add_component_() {
|
||||
_components.push_back(T(*this));
|
||||
}
|
||||
|
||||
//! remove a node component
|
||||
void remove_component(component c);
|
||||
|
||||
//! paths to root
|
||||
const ptr_array& path() const;
|
||||
|
||||
void traversal();
|
||||
|
||||
// not sure about this
|
||||
const class transform& transform() const { return _transform; }
|
||||
class transform& transform() { return _transform; }
|
||||
|
||||
protected:
|
||||
|
||||
ref_array _children; //!< list of children
|
||||
ptr_array _path; //!< path to root
|
||||
|
||||
class transform _transform;
|
||||
|
||||
component::array _components; //<! components
|
||||
|
||||
std::string _name;
|
||||
|
||||
// change mask
|
||||
// layer mask
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -41,6 +41,8 @@ public:
|
|||
size_t count_all_enties() const;
|
||||
size_t count_alive_enties() const;
|
||||
|
||||
void update_transforms();
|
||||
|
||||
protected:
|
||||
|
||||
std::shared_ptr<entt::registry> _registry;
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
#ifndef PW_SCENE_TRAVERSER_HPP
|
||||
#define PW_SCENE_TRAVERSER_HPP
|
||||
|
||||
#include <pw/scene/node.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace pw {
|
||||
|
||||
class traverser {
|
||||
|
||||
public:
|
||||
|
||||
enum direction {
|
||||
up,
|
||||
down
|
||||
};
|
||||
|
||||
typedef std::function<void(node*)> edge_function;
|
||||
|
||||
direction _direction = direction::up;
|
||||
|
||||
edge_function on_enter,on_leave;
|
||||
|
||||
void visit(node* node);
|
||||
|
||||
void bfs(node::ref root);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // PW_SCENE_TRAVERSER_HPP
|
|
@ -1,71 +0,0 @@
|
|||
|
||||
#include "pw/scene/component.hpp"
|
||||
|
||||
#include <pw/core/vector.hpp>
|
||||
#include <pw/core/quaternion.hpp>
|
||||
#include "pw/scene/node.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace pw {
|
||||
|
||||
component::component(node &host)
|
||||
: _node(host)
|
||||
{
|
||||
}
|
||||
|
||||
component::component(const component &other)
|
||||
: _node(other._node)
|
||||
{
|
||||
}
|
||||
|
||||
component::~component()
|
||||
{
|
||||
}
|
||||
|
||||
bool component::enabled() const
|
||||
{
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
void component::set_enabled(bool enabled)
|
||||
{
|
||||
_enabled = enabled;
|
||||
}
|
||||
|
||||
uint32_t component::weight() const
|
||||
{
|
||||
return _weight;
|
||||
}
|
||||
|
||||
void component::set_weight(const uint32_t &weight)
|
||||
{
|
||||
_weight = weight;
|
||||
}
|
||||
|
||||
|
||||
class material_component {
|
||||
|
||||
enum shading_input {
|
||||
albedo,
|
||||
specular
|
||||
};
|
||||
|
||||
// std::map<shading_input,vector4> _colors;
|
||||
|
||||
|
||||
// std::shared_ptr<image> _albedo;
|
||||
};
|
||||
|
||||
|
||||
//class trs : public transform {
|
||||
|
||||
// vector3d _position;
|
||||
// vector3d _scale;
|
||||
// quaterniond _rotation;
|
||||
//};
|
||||
|
||||
|
||||
}
|
|
@ -7,21 +7,29 @@ namespace pw {
|
|||
|
||||
namespace detail {
|
||||
|
||||
// entity relationsships are hidden
|
||||
struct relationship {
|
||||
relationship() = default;
|
||||
relationship(const relationship&) = default;
|
||||
|
||||
std::vector<entt::entity> children;
|
||||
entt::entity parent { entt::null };
|
||||
// entity identiy is hidden
|
||||
|
||||
struct identity {
|
||||
identity() = default;
|
||||
identity(const std::string& name) : name(name) {}
|
||||
identity(const identity&) = default;
|
||||
|
||||
bool enabled = true;
|
||||
std::string name = "";
|
||||
std::vector<u_int32_t> tags = {};
|
||||
std::vector<uint32_t> layers = {};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
entity::entity(scene &s)
|
||||
entity::entity(scene &s,const std::string& name)
|
||||
: _registry(s._registry)
|
||||
, _entity(s._registry ? _registry->create() : entt::null)
|
||||
{
|
||||
if (s._registry) {
|
||||
this->add_component<detail::identity>(name);
|
||||
}
|
||||
}
|
||||
|
||||
bool entity::add_child(entity &child)
|
||||
|
@ -35,11 +43,11 @@ bool entity::add_child(entity &child)
|
|||
// TODO: check circular dependencies
|
||||
|
||||
// declare child relationship
|
||||
auto& r = get_or_create_component<detail::relationship>();
|
||||
auto& r = get_or_create_component<relationship>();
|
||||
r.children.push_back(child._entity);
|
||||
|
||||
// declare parent
|
||||
auto& p_r = child.get_or_create_component<detail::relationship>();
|
||||
auto& p_r = child.get_or_create_component<relationship>();
|
||||
p_r.parent = _entity;
|
||||
|
||||
return true;
|
||||
|
@ -54,18 +62,18 @@ bool entity::remove_child(entity& child)
|
|||
}
|
||||
|
||||
// both need to have a relationship component
|
||||
if (has_component<detail::relationship>() &&
|
||||
child.has_component<detail::relationship>())
|
||||
if (has_component<relationship>() &&
|
||||
child.has_component<relationship>())
|
||||
{
|
||||
// we need to check if the child is related to the parent
|
||||
auto r_p = child.get_component<detail::relationship>();
|
||||
auto r_p = child.get_component<relationship>();
|
||||
if (r_p.parent == _entity)
|
||||
{
|
||||
// now go ahead delete parent
|
||||
r_p.parent = entt::null;
|
||||
|
||||
// now remove all children
|
||||
auto& r = this->get_component<detail::relationship>();
|
||||
auto& r = this->get_component<relationship>();
|
||||
r.children.erase(std::remove(r.children.begin(),r.children.end(),child._entity));
|
||||
|
||||
// flag success
|
||||
|
@ -77,11 +85,26 @@ bool entity::remove_child(entity& child)
|
|||
|
||||
size_t entity::child_count() const
|
||||
{
|
||||
return has_component<detail::relationship>() ?
|
||||
get_component<detail::relationship>().children.size() :
|
||||
return has_component<relationship>() ?
|
||||
get_component<relationship>().children.size() :
|
||||
0;
|
||||
}
|
||||
|
||||
|
||||
void entity::set_name(const std::string& n)
|
||||
{
|
||||
auto &ident = get_or_create_component<detail::identity>();
|
||||
ident.name = n;
|
||||
}
|
||||
|
||||
std::string entity::name()
|
||||
{
|
||||
auto &ident = get_or_create_component<detail::identity>();
|
||||
return ident.name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
entity::~entity()
|
||||
{
|
||||
this->destroy();
|
||||
|
@ -89,8 +112,7 @@ entity::~entity()
|
|||
|
||||
void entity::destroy()
|
||||
{
|
||||
debug::d() << __PRETTY_FUNCTION__;
|
||||
if (valid()) _registry->destroy(_entity);
|
||||
_registry->destroy(_entity);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,109 +0,0 @@
|
|||
#include "pw/scene/transform.hpp"
|
||||
#include "pw/scene/node.hpp"
|
||||
|
||||
#include "pw/core/debug.hpp"
|
||||
|
||||
namespace pw {
|
||||
|
||||
node::node()
|
||||
: _transform(*this)
|
||||
{
|
||||
}
|
||||
|
||||
node::node(const node &node)
|
||||
: _children(node.children())
|
||||
, _components(node.components())
|
||||
, _name(node._name)
|
||||
, _transform(*this)
|
||||
{
|
||||
// _components.push_back(std::make_unique<transform>(*this));
|
||||
}
|
||||
|
||||
node::ref node::clone(const unsigned short ©mode) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string node::name() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
void node::set_name(const std::string &name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
void node::add_child(node::ref c)
|
||||
{
|
||||
// take parent nodepath ...
|
||||
c->_path = this->_path;
|
||||
|
||||
// add current node
|
||||
c->_path.push_back(this);
|
||||
|
||||
// add as child
|
||||
_children.push_back(c);
|
||||
}
|
||||
|
||||
void node::remove_child(ref child_node)
|
||||
{
|
||||
for (node::ref_array::iterator it = _children.begin();
|
||||
it != _children.end();
|
||||
it++)
|
||||
{
|
||||
if (child_node == *it) it = _children.erase(it);
|
||||
}
|
||||
// auto it = _children.end();
|
||||
|
||||
// while (it = std::find(_children.begin(),_children.end(),child_node) != _children.end()) {
|
||||
// it = _children.erase(it);
|
||||
// }
|
||||
}
|
||||
|
||||
node::~node()
|
||||
{
|
||||
_children.clear();
|
||||
}
|
||||
|
||||
//
|
||||
// components
|
||||
//
|
||||
void node::add_component(component new_component)
|
||||
{
|
||||
// assumption is that only transform is a "singular" node
|
||||
_components.push_back(new_component);
|
||||
}
|
||||
|
||||
void node::remove_component(component c)
|
||||
{
|
||||
// component::array::iterator it = _components.end();
|
||||
|
||||
for (component::array::iterator it = _components.begin();
|
||||
it != _components.end();
|
||||
it++)
|
||||
{
|
||||
// if (*it == c) it = _components.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
const node::ptr_array &node::path() const
|
||||
{
|
||||
return _path;
|
||||
}
|
||||
|
||||
void node::traversal()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
const component::array &node::components() const
|
||||
{
|
||||
return _components;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
#include "pw/scene/projection.hpp"
|
||||
#include "pw/core/matrix_transform.hpp"
|
||||
|
||||
namespace pw {
|
||||
|
||||
projection::projection(node &host)
|
||||
: component (host)
|
||||
{
|
||||
_m.set_identity();
|
||||
// set_matrix(matrix_transform<real_t>::perspective_projection(_fov,1,_near_plane,_far_plane));
|
||||
}
|
||||
|
||||
void projection::set_matrix(const matrix4x4 &projection)
|
||||
{
|
||||
this->_m = projection;
|
||||
|
||||
// recompute the simplified parameters
|
||||
|
||||
// auto near = _projection(3,4);
|
||||
// auto far = _projection(3,4);
|
||||
|
||||
// right = (1-m14) / m11
|
||||
|
||||
// near = (1+m34)/m33;
|
||||
// far = -(1-m34)/m33;
|
||||
// bottom = (1-m24)/m22;
|
||||
// top = -(1+m24)/m22;
|
||||
// left = -(1+m14)/m11;
|
||||
// right = (1-m14)/m11;
|
||||
|
||||
// real_t fov_raw = float( atan (top / near_)) * * 2.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void projection::set_frustum(real_t left, real_t right, real_t top, real_t bottom)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
#include "pw/scene/scene.hpp"
|
||||
#include "pw/scene/entity.hpp"
|
||||
|
||||
#include "pw/core/debug.hpp"
|
||||
|
||||
namespace pw {
|
||||
|
||||
scene::scene()
|
||||
|
@ -18,6 +20,46 @@ size_t scene::count_alive_enties() const
|
|||
return _registry->alive();
|
||||
}
|
||||
|
||||
void scene::update_transforms()
|
||||
{
|
||||
|
||||
#if 0
|
||||
|
||||
auto view = _registry->view<transform,relationship>();
|
||||
|
||||
for (auto entity : view)
|
||||
{
|
||||
auto [t,r] = view.get<transform,relationship>(entity);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
auto view = _registry->view<relationship>();
|
||||
|
||||
for (auto e : view) {
|
||||
|
||||
const auto& r = view.get<relationship>(e);
|
||||
|
||||
if (r.children.size() && r.parent == entt::null) {
|
||||
debug::d() << "root";
|
||||
}
|
||||
|
||||
// debug::d() << __PRETTY_FUNCTION__ << " " << view.get<relationship>(e).children.size();
|
||||
|
||||
// if
|
||||
}
|
||||
|
||||
// auto vr = _registry->view<relationship>();
|
||||
|
||||
// for (auto [rel] : vr) {
|
||||
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,50 +1,10 @@
|
|||
#include "pw/scene/transform.hpp"
|
||||
#include "pw/scene/node.hpp"
|
||||
|
||||
namespace pw {
|
||||
|
||||
transform::transform(node &host)
|
||||
: _node(host)
|
||||
{
|
||||
_local.set_identity();
|
||||
_global.set_identity();
|
||||
_global_inverse.set_identity();
|
||||
}
|
||||
|
||||
void transform::set_local(const matrix4x4 &local)
|
||||
{
|
||||
_local = local;
|
||||
update_global_from_local();
|
||||
// TODO need to rebuild the transforms: both -> global down and global up
|
||||
}
|
||||
|
||||
void transform::set_global(const matrix4x4 &global)
|
||||
{
|
||||
//TODO need to rebuild **_local** from parent
|
||||
_global = global;
|
||||
_global_inverse = global.inverse();
|
||||
|
||||
update_local_from_global();
|
||||
// TODO need to rebuild the transforms: both -> global down and global up
|
||||
}
|
||||
|
||||
void transform::update_global_from_local()
|
||||
{
|
||||
// update the global transform
|
||||
if (_node.is_root()) {
|
||||
this->_global = _local;
|
||||
} else
|
||||
{
|
||||
this->_global = _node.parent()->transform().global() * _local;
|
||||
}
|
||||
_global_inverse = _global.inverse();
|
||||
}
|
||||
|
||||
void transform::update_local_from_global()
|
||||
{
|
||||
_local = (_node.is_root()) ? _global :
|
||||
_node.parent()->transform().global_inverse() * _global;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
#include "pw/scene/traverser.hpp"
|
||||
#include "pw/scene/node.hpp"
|
||||
|
||||
#include <stack>
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
|
||||
namespace pw {
|
||||
|
||||
traverser t = traverser();
|
||||
|
||||
void traverser::visit(node *node)
|
||||
{
|
||||
// enter node
|
||||
on_enter(node);
|
||||
// visit
|
||||
if (direction::up == _direction)
|
||||
this->visit(node->parent());
|
||||
else
|
||||
for (auto c : node->children()) this->visit(c.get());
|
||||
|
||||
//leave node
|
||||
on_leave(node);
|
||||
}
|
||||
|
||||
void traverser::bfs(node::ref root)
|
||||
{
|
||||
std::stack<node::ref> q;
|
||||
q.push(root);
|
||||
|
||||
node::ref_array leafs;
|
||||
|
||||
while (!q.empty())
|
||||
{
|
||||
// get the top
|
||||
node::ref n = q.top();
|
||||
// remove from stack
|
||||
q.pop();
|
||||
|
||||
// std::cout << "d:" << q.size() << " l:" << n->is_leaf() << " n:" << n->name();
|
||||
|
||||
// add all children
|
||||
for(auto c : n->children()) q.push(c);
|
||||
|
||||
// std::cout << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,72 +1,13 @@
|
|||
#include <pw/core/vector.hpp>
|
||||
#include <pw/core/serialize.hpp>
|
||||
#include <pw/scene/node.hpp>
|
||||
#include <pw/scene/transform.hpp>
|
||||
//#include <pw/scene/transform.hpp>
|
||||
|
||||
#include <pw/core/serialize.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void print_node_path(pw::node::ref node) {
|
||||
|
||||
auto parents = node->path();
|
||||
|
||||
std::cout << node->name() << " - ";
|
||||
for (auto p : node->path()) {
|
||||
std::cout << " p:'" << p->name() << "'";
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
}
|
||||
|
||||
int main(int argc,char **argv) {
|
||||
|
||||
using namespace pw;
|
||||
|
||||
auto n = std::make_shared<node>();
|
||||
n->set_name("root-node");
|
||||
|
||||
|
||||
// add a child
|
||||
auto c = std::make_shared<node>();
|
||||
c->set_name("child-node");
|
||||
n->add_child(c);
|
||||
|
||||
std::cout << "n name: " << n->name() << std::endl;
|
||||
std::cout << "n leaf: " << n->is_leaf() << std::endl;
|
||||
std::cout << "n root: " << n->is_root() << std::endl;
|
||||
|
||||
std::cout << "s name: " << n->children().front()->name() << std::endl;
|
||||
std::cout << "s leaf: " << n->children().front()->is_leaf() << std::endl;
|
||||
std::cout << "s root: " << n->children().front()->is_root() << std::endl;
|
||||
|
||||
|
||||
// thats the only and most ugly way to register a component
|
||||
// new component(n.get());
|
||||
|
||||
|
||||
std::cout << "n components: " << n->components().size() << std::endl;
|
||||
|
||||
n->transform().set_translation(5,4,3);
|
||||
|
||||
std::cout << "c transform g " << serialize::matrix(n->transform().global()) << std::endl;
|
||||
std::cout << "c transform gi " << serialize::matrix(n->transform().global_inverse()) << std::endl;
|
||||
std::cout << "c transform l " << serialize::matrix(n->transform().local()) << std::endl;
|
||||
|
||||
|
||||
//n->add_component_<transform>();
|
||||
|
||||
print_node_path((n));
|
||||
|
||||
// auto t = n->transform();
|
||||
|
||||
// if (t)
|
||||
// std::cout << n->transform().local()(0,0) << std::endl;
|
||||
// else {
|
||||
// std::cerr << "no transform?" << std::endl;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
#include <pw/core/serialize.hpp>
|
||||
#include <pw/core/debug.hpp>
|
||||
|
||||
#include <pw/scene/node.hpp>
|
||||
#include <pw/scene/transform.hpp>
|
||||
#include <pw/scene/scene.hpp>
|
||||
#include <pw/scene/entity.hpp>
|
||||
|
||||
|
@ -42,9 +40,13 @@ void test_stack()
|
|||
e.add_child(e2);
|
||||
e.add_child(e3);
|
||||
|
||||
e2.add_component<pw::transform>();
|
||||
e3.add_component<pw::transform>();
|
||||
|
||||
std::cout << e.child_count() << std::endl;
|
||||
|
||||
s.update_transforms();
|
||||
|
||||
}
|
||||
|
||||
void test_heap()
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
#include <pw/core/vector.hpp>
|
||||
#include <pw/core/serialize.hpp>
|
||||
#include <pw/scene/node.hpp>
|
||||
#include <pw/scene/transform.hpp>
|
||||
#include <pw/scene/traverser.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
@ -23,25 +20,12 @@
|
|||
#include <iostream>
|
||||
|
||||
|
||||
|
||||
void print_node_path(pw::node::ref node) {
|
||||
|
||||
auto parents = node->path();
|
||||
|
||||
std::cout << node->name() << " - ";
|
||||
for (auto p : node->path()) {
|
||||
std::cout << " p:'" << p->name() << "'";
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
}
|
||||
int main(int argc,char **argv) {
|
||||
|
||||
using namespace pw;
|
||||
|
||||
node::ref root(std::make_shared<node>());
|
||||
root->set_name("root");
|
||||
// node::ref root(std::make_shared<node>());
|
||||
// root->set_name("root");
|
||||
// root->add_child()->set_name("sub-1");
|
||||
|
||||
// node::ref sub_2_1 = std::make_shared<node>("sub-2-1");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue