refactoring with ECS

This commit is contained in:
Hartmut Seichter 2020-12-15 12:39:25 +01:00
parent 4078cdea8f
commit e25625998c
20 changed files with 176 additions and 770 deletions

View file

@ -70,7 +70,6 @@ struct matrix_ : matrixbase_<T, matrix_<R, C, T>>
return *this; return *this;
} }
// //! get cell count // //! get cell count
// inline std::size_t coefficients() const { return this->size(); } // inline std::size_t coefficients() const { return this->size(); }

View file

@ -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; } 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;
//};
} }

View file

@ -1,33 +1,29 @@
set(hdrs set(hdrs
include/pw/scene/entity.hpp 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/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 set(srcs
src/entity.cpp src/entity.cpp
src/node.cpp
src/projection.cpp
src/component.cpp
src/scene.cpp src/scene.cpp
src/transform.cpp
src/traverser.cpp
) )
add_library(pwscene add_library(pwscene
STATIC STATIC
${hdrs} ${hdrs}
${hdrs_components}
${srcs} ${srcs}
) )
target_include_directories( target_include_directories(
pwscene pwscene
PUBLIC PUBLIC
include include
) )

View file

@ -22,51 +22,55 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#ifndef PW_SCENE_COMPONENT_HPP #ifndef PW_SCENE_PROJECTION_HPP
#define PW_SCENE_COMPONENT_HPP #define PW_SCENE_PROJECTION_HPP
#include <pw/core/globals.hpp> #include <pw/core/matrix.hpp>
#include <string>
#include <vector>
#include <memory>
namespace pw { namespace pw {
class node; struct projection {
/** void set_matrix(const matrix4x4 &projection)
* @brief components represent attributes of the scene nodes {
*/ this->projection_matrix = projection;
class component { // recompute the simplified parameters
public:
friend class node; // auto near = _projection(3,4);
typedef std::vector<component> array; // auto far = _projection(3,4);
component(node &host); // right = (1-m14) / m11
component(const component& other);
virtual ~component();
bool enabled() const; // near = (1+m34)/m33;
void set_enabled(bool enabled); // far = -(1-m34)/m33;
// bottom = (1-m24)/m22;
// top = -(1+m24)/m22;
// left = -(1+m14)/m11;
// right = (1-m14)/m11;
uint32_t weight() const; // real_t fov_raw = float( atan (top / near_)) * * 2.0f;
void set_weight(const uint32_t &weight); }
template <typename T> operator const matrix4x4&() const
inline T* cast() { return static_cast<T*>(this);} {
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 #endif

View file

@ -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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#ifndef PW_SCENE_PROJECTION_HPP #ifndef PW_SCENE_COMPONENTS_RELATIONSHIP_HPP
#define PW_SCENE_PROJECTION_HPP #define PW_SCENE_COMPONENTS_RELATIONSHIP_HPP
#include <pw/core/matrix.hpp> #include <pw/scene/scene.hpp>
#include <pw/scene/component.hpp>
namespace pw { 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; std::vector<entt::entity> children;
entt::entity parent { entt::null };
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;
}; };
} }
#endif #endif

View file

@ -7,18 +7,24 @@
namespace pw { namespace pw {
class node; struct transform {
class transform {
public:
transform(node &host);
inline const matrix4x4& local() const { return _local; } 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; } 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; } inline const matrix4x4& global_inverse() const { return _global_inverse; }
@ -62,21 +68,13 @@ public:
return scale(uniform_scale,uniform_scale,uniform_scale); return scale(uniform_scale,uniform_scale,uniform_scale);
} }
protected:
matrix4x4 _local; matrix4x4 _local;
matrix4x4 _global; matrix4x4 _global;
matrix4x4 _global_inverse; matrix4x4 _global_inverse;
private:
node &_node;
//! updates the global transform from parent globals and local transform
void update_global_from_local(); void update_global_from_local();
//! updates the local transform from parent and new global
void update_local_from_global(); void update_local_from_global();
}; };

View file

@ -38,14 +38,14 @@ class entity {
public: public:
entity() = default; entity() = default;
entity(const entity&) = default; entity(const entity&) = default;
entity(scene& s); entity(scene& s, const std::string &name = "");
~entity(); ~entity();
/** /**
* adds a component * adds a component
*/ */
template <typename T,typename... Args> 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)...); return _registry->emplace<T>(this->_entity,std::forward<Args>(args)...);
} }
@ -62,7 +62,7 @@ public:
* returns a component * returns a component
*/ */
template<typename T> template<typename T>
[[nodiscard]] T& get_component() const { T& get_component() const {
return _registry->get<T>(this->_entity); return _registry->get<T>(this->_entity);
} }
@ -70,7 +70,7 @@ public:
* gets or creates a component * gets or creates a component
*/ */
template <typename T,typename... Args> 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)...); return _registry->get_or_emplace<T>(this->_entity,std::forward<Args>(args)...);
} }
@ -122,6 +122,17 @@ public:
*/ */
size_t child_count() const; 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: private:
std::shared_ptr<entt::registry> _registry; std::shared_ptr<entt::registry> _registry;
@ -130,4 +141,10 @@ private:
}; };
} }
#include <pw/scene/components/relationship.hpp>
#include <pw/scene/components/transform.hpp>
#endif #endif

View file

@ -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

View file

@ -41,6 +41,8 @@ public:
size_t count_all_enties() const; size_t count_all_enties() const;
size_t count_alive_enties() const; size_t count_alive_enties() const;
void update_transforms();
protected: protected:
std::shared_ptr<entt::registry> _registry; std::shared_ptr<entt::registry> _registry;

View file

@ -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

View file

@ -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;
//};
}

View file

@ -7,21 +7,29 @@ namespace pw {
namespace detail { namespace detail {
// entity relationsships are hidden
struct relationship {
relationship() = default;
relationship(const relationship&) = default;
std::vector<entt::entity> children; // entity identiy is hidden
entt::entity parent { entt::null };
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) : _registry(s._registry)
, _entity(s._registry ? _registry->create() : entt::null) , _entity(s._registry ? _registry->create() : entt::null)
{ {
if (s._registry) {
this->add_component<detail::identity>(name);
}
} }
bool entity::add_child(entity &child) bool entity::add_child(entity &child)
@ -35,11 +43,11 @@ bool entity::add_child(entity &child)
// TODO: check circular dependencies // TODO: check circular dependencies
// declare child relationship // declare child relationship
auto& r = get_or_create_component<detail::relationship>(); auto& r = get_or_create_component<relationship>();
r.children.push_back(child._entity); r.children.push_back(child._entity);
// declare parent // 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; p_r.parent = _entity;
return true; return true;
@ -54,18 +62,18 @@ bool entity::remove_child(entity& child)
} }
// both need to have a relationship component // both need to have a relationship component
if (has_component<detail::relationship>() && if (has_component<relationship>() &&
child.has_component<detail::relationship>()) child.has_component<relationship>())
{ {
// we need to check if the child is related to the parent // 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) if (r_p.parent == _entity)
{ {
// now go ahead delete parent // now go ahead delete parent
r_p.parent = entt::null; r_p.parent = entt::null;
// now remove all children // 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)); r.children.erase(std::remove(r.children.begin(),r.children.end(),child._entity));
// flag success // flag success
@ -77,11 +85,26 @@ bool entity::remove_child(entity& child)
size_t entity::child_count() const size_t entity::child_count() const
{ {
return has_component<detail::relationship>() ? return has_component<relationship>() ?
get_component<detail::relationship>().children.size() : get_component<relationship>().children.size() :
0; 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() entity::~entity()
{ {
this->destroy(); this->destroy();
@ -89,8 +112,7 @@ entity::~entity()
void entity::destroy() void entity::destroy()
{ {
debug::d() << __PRETTY_FUNCTION__; _registry->destroy(_entity);
if (valid()) _registry->destroy(_entity);
} }
} }

View file

@ -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 &copymode) 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;
}
}

View file

@ -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)
{
}
}

View file

@ -1,6 +1,8 @@
#include "pw/scene/scene.hpp" #include "pw/scene/scene.hpp"
#include "pw/scene/entity.hpp" #include "pw/scene/entity.hpp"
#include "pw/core/debug.hpp"
namespace pw { namespace pw {
scene::scene() scene::scene()
@ -18,6 +20,46 @@ size_t scene::count_alive_enties() const
return _registry->alive(); 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) {
// }
}

View file

@ -1,50 +1,10 @@
#include "pw/scene/transform.hpp" #include "pw/scene/transform.hpp"
#include "pw/scene/node.hpp"
namespace pw { 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;
}
} }

View file

@ -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;
}
}
}

View file

@ -1,72 +1,13 @@
#include <pw/core/vector.hpp> #include <pw/core/vector.hpp>
#include <pw/core/serialize.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 <pw/core/serialize.hpp>
#include <iostream> #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) { 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; return 0;

View file

@ -2,8 +2,6 @@
#include <pw/core/serialize.hpp> #include <pw/core/serialize.hpp>
#include <pw/core/debug.hpp> #include <pw/core/debug.hpp>
#include <pw/scene/node.hpp>
#include <pw/scene/transform.hpp>
#include <pw/scene/scene.hpp> #include <pw/scene/scene.hpp>
#include <pw/scene/entity.hpp> #include <pw/scene/entity.hpp>
@ -42,9 +40,13 @@ void test_stack()
e.add_child(e2); e.add_child(e2);
e.add_child(e3); e.add_child(e3);
e2.add_component<pw::transform>();
e3.add_component<pw::transform>();
std::cout << e.child_count() << std::endl; std::cout << e.child_count() << std::endl;
s.update_transforms();
} }
void test_heap() void test_heap()

View file

@ -1,8 +1,5 @@
#include <pw/core/vector.hpp> #include <pw/core/vector.hpp>
#include <pw/core/serialize.hpp> #include <pw/core/serialize.hpp>
#include <pw/scene/node.hpp>
#include <pw/scene/transform.hpp>
#include <pw/scene/traverser.hpp>
#include <iostream> #include <iostream>
@ -23,25 +20,12 @@
#include <iostream> #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) { int main(int argc,char **argv) {
using namespace pw; using namespace pw;
node::ref root(std::make_shared<node>()); // node::ref root(std::make_shared<node>());
root->set_name("root"); // root->set_name("root");
// root->add_child()->set_name("sub-1"); // root->add_child()->set_name("sub-1");
// node::ref sub_2_1 = std::make_shared<node>("sub-2-1"); // node::ref sub_2_1 = std::make_shared<node>("sub-2-1");