working ECS base
This commit is contained in:
parent
f3c17f6d03
commit
4078cdea8f
8 changed files with 104 additions and 23 deletions
34
README.md
34
README.md
|
@ -1,6 +1,34 @@
|
|||
pixwerx
|
||||
-------
|
||||
# pixwerx
|
||||
|
||||
pixwerx is an opinionated, academic approach to a 3D engine. It tries to mix
|
||||
modern andproven methods to build a fast and portable engine beyond pure 3D.
|
||||
|
||||
## Design Principles
|
||||
|
||||
Dogdooding: pixwerx is built on the principle of dogfooding. The engine is a
|
||||
full-stack system that tries to implement all necessary functions. The engine
|
||||
editor is just a UI build with the engine.
|
||||
|
||||
Reasonable dependencies: like many engines pixwerx tries to include as much 3rd-
|
||||
party code as possible and implements some of the core systems itself.
|
||||
|
||||
No premature optimization: pixwerx implements only very few systems with machine
|
||||
code. It tries to utilize the power of the compiler as much as possible.
|
||||
|
||||
Computer graphics 101: pixwerx does implement graphics components and systems in
|
||||
a way that makes code portable and not over-parameterized. Usability is
|
||||
achieved through layers on top of the core components.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
pixwerx is licenced under the terms of the MIT License. Please consult the
|
||||
LICENSE file.
|
||||
|
||||
## Authors
|
||||
|
||||
© 1999-2020 Hartmut Seichter
|
||||
|
||||
|
||||
an academic approach to a 3D engine
|
||||
|
||||
|
||||
|
|
|
@ -121,6 +121,8 @@ void register_core_function(sol::state& lua,sol::table& ns)
|
|||
// , "line_strip", geometry::topology_type::line_strip
|
||||
// );
|
||||
|
||||
|
||||
|
||||
ns.new_usertype<image>("image"
|
||||
, sol::constructors<image()>()
|
||||
,"create",&image::create
|
||||
|
|
|
@ -26,6 +26,7 @@ void register_scene_function(sol::state&,sol::table &ns)
|
|||
ns.new_usertype<entity>("entity"
|
||||
,sol::constructors<entity(),entity(const entity&),entity(scene&)>()
|
||||
,"add_child",&entity::add_child
|
||||
,"remove_child",&entity::remove_child
|
||||
,"child_count",sol::readonly_property(&entity::child_count)
|
||||
);
|
||||
|
||||
|
|
|
@ -32,8 +32,6 @@
|
|||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
namespace pw {
|
||||
|
||||
class entity {
|
||||
|
@ -43,46 +41,85 @@ public:
|
|||
entity(scene& s);
|
||||
~entity();
|
||||
|
||||
/**
|
||||
* adds a component
|
||||
*/
|
||||
template <typename T,typename... Args>
|
||||
[[nodiscard]] T& add_component(Args&&... args) {
|
||||
return _registry->emplace<T>(this->_entity,std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/**
|
||||
* removes a component
|
||||
*/
|
||||
template <typename T>
|
||||
void remove_component() {
|
||||
_registry->remove<T>(_entity);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns a component
|
||||
*/
|
||||
template<typename T>
|
||||
[[nodiscard]] T& get_component() const {
|
||||
return _registry->get<T>(this->_entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* gets or creates a component
|
||||
*/
|
||||
template <typename T,typename... Args>
|
||||
T& get_or_create_component(Args&&... args) {
|
||||
[[nodiscard]] T& get_or_create_component(Args&&... args) {
|
||||
return _registry->get_or_emplace<T>(this->_entity,std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if this entity contains a component
|
||||
*/
|
||||
template<typename T>
|
||||
bool has_component() const { return _registry->has<T>(_entity);}
|
||||
|
||||
/**
|
||||
* @brief destroy
|
||||
*/
|
||||
void destroy();
|
||||
|
||||
operator bool() const { return _registry && _entity != entt::null; }
|
||||
|
||||
/**
|
||||
* @brief conversion to an entt entity
|
||||
*/
|
||||
operator std::uint32_t() const { return static_cast<std::uint32_t>(_entity); }
|
||||
|
||||
/**
|
||||
* @brief checks if this entity is valid
|
||||
* @return true of it belongs to a scene already
|
||||
*/
|
||||
bool valid() const { return _registry && _registry->valid(_entity); }
|
||||
|
||||
|
||||
|
||||
operator bool() const { return _registry && _entity != entt::null; }
|
||||
|
||||
|
||||
/**
|
||||
* @brief adds another child entity to this entity -> establishing a
|
||||
* @param child
|
||||
* @return true if the given child could be added to the hierarchy
|
||||
*/
|
||||
bool add_child(entity &child);
|
||||
|
||||
void remove_child(entity &child);
|
||||
/**
|
||||
* @brief remove child entity from this parent
|
||||
* @param child
|
||||
* @return true if the given child could be remove from the hierarchy
|
||||
*/
|
||||
bool remove_child(entity &child);
|
||||
|
||||
/**
|
||||
* @brief returns the number of children on this entity
|
||||
* @return number of children
|
||||
*/
|
||||
size_t child_count() const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -39,7 +39,10 @@ public:
|
|||
projection(node &host);
|
||||
|
||||
void set_matrix(const matrix4x4 &projection);
|
||||
const matrix4x4& matrix() const;
|
||||
const matrix4x4& matrix() const
|
||||
{
|
||||
return _m;
|
||||
}
|
||||
|
||||
void set_frustum(real_t left,
|
||||
real_t right,
|
||||
|
|
|
@ -7,7 +7,6 @@ namespace pw {
|
|||
|
||||
namespace detail {
|
||||
|
||||
|
||||
// entity relationsships are hidden
|
||||
struct relationship {
|
||||
relationship() = default;
|
||||
|
@ -25,7 +24,7 @@ entity::entity(scene &s)
|
|||
{
|
||||
}
|
||||
|
||||
bool entity::add_child(entity& child)
|
||||
bool entity::add_child(entity &child)
|
||||
{
|
||||
// not mixing scenes (yet)
|
||||
if (child._registry != this->_registry) {
|
||||
|
@ -46,12 +45,12 @@ bool entity::add_child(entity& child)
|
|||
return true;
|
||||
}
|
||||
|
||||
void entity::remove_child(entity& child)
|
||||
bool entity::remove_child(entity& child)
|
||||
{
|
||||
// not mixing scenes (yet)
|
||||
if (child._registry != this->_registry) {
|
||||
debug::e() << "Cannot mix entities from different scenes";
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// both need to have a relationship component
|
||||
|
@ -62,13 +61,18 @@ void entity::remove_child(entity& child)
|
|||
auto r_p = child.get_component<detail::relationship>();
|
||||
if (r_p.parent == _entity)
|
||||
{
|
||||
// now go ahead
|
||||
// now go ahead delete parent
|
||||
r_p.parent = entt::null;
|
||||
|
||||
auto r = get_component<detail::relationship>();
|
||||
std::remove(r.children.begin(),r.children.end(),child._entity);
|
||||
// now remove all children
|
||||
auto& r = this->get_component<detail::relationship>();
|
||||
r.children.erase(std::remove(r.children.begin(),r.children.end(),child._entity));
|
||||
|
||||
// flag success
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t entity::child_count() const
|
||||
|
|
|
@ -31,10 +31,7 @@ void projection::set_matrix(const matrix4x4 &projection)
|
|||
// real_t fov_raw = float( atan (top / near_)) * * 2.0f;
|
||||
}
|
||||
|
||||
const matrix4x4 &projection::matrix() const
|
||||
{
|
||||
return _m;
|
||||
}
|
||||
|
||||
|
||||
void projection::set_frustum(real_t left, real_t right, real_t top, real_t bottom)
|
||||
{
|
||||
|
|
|
@ -11,17 +11,26 @@ local s = pw.scene.new()
|
|||
print(s)
|
||||
|
||||
local e = pw.entity.new(s)
|
||||
c = pw.entity.new(s)
|
||||
local c = pw.entity.new(s)
|
||||
|
||||
print(e)
|
||||
print(c)
|
||||
print(e.child_count)
|
||||
|
||||
-- add child
|
||||
e.add_child(c)
|
||||
|
||||
e:add_child(c)
|
||||
|
||||
print(e.child_count)
|
||||
|
||||
if e:remove_child(c) then
|
||||
print("remove_child success")
|
||||
else
|
||||
print("remove_child fail")
|
||||
end
|
||||
|
||||
print(e.child_count)
|
||||
|
||||
|
||||
print("bye, bye pixwerx!")
|
||||
|
||||
return 1
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue