nodes: new helper functions

This commit is contained in:
2020-01-18 15:03:51 +07:00
parent aed8b98db7
commit 6a765cb782
5 changed files with 131 additions and 0 deletions

View File

@@ -59,6 +59,9 @@ namespace e2d
const m4f& local_matrix() const noexcept;
const m4f& world_matrix() const noexcept;
v4f local_to_world(const v4f& local) const noexcept;
v4f world_to_local(const v4f& world) const noexcept;
node_iptr root() noexcept;
const_node_iptr root() const noexcept;
@@ -191,4 +194,17 @@ namespace e2d::nodes
void for_extracted_nodes_reversed(const const_node_iptr& root, F&& f);
}
namespace e2d::nodes
{
template < typename Component >
gcomponent<Component> get_component_in_parent(const const_node_iptr& root);
template < typename Component, typename Iter >
std::size_t get_components_in_parent(const const_node_iptr& root, Iter iter);
template < typename Component >
gcomponent<Component> get_component_in_children(const const_node_iptr& root);
template < typename Component, typename Iter >
std::size_t get_components_in_children(const const_node_iptr& root, Iter iter);
}
#include "node.inl"

View File

@@ -204,3 +204,74 @@ namespace e2d::nodes
nodes.end());
}
}
namespace e2d::nodes
{
template < typename Component >
gcomponent<Component> get_component_in_parent(const const_node_iptr& root) {
if ( !root ) {
return {};
}
if ( auto component = root->owner().component<Component>() ) {
return component;
}
return get_component_in_parent<Component>(root->parent());
}
template < typename Component, typename Iter >
std::size_t get_components_in_parent(const const_node_iptr& root, Iter iter) {
std::size_t count{0u};
if ( !root ) {
return count;
}
if ( auto component = root->owner().component<Component>() ) {
++count;
iter++ = component;
}
return count + get_components_in_parent(root->parent(), iter);
}
template < typename Component >
gcomponent<Component> get_component_in_children(const const_node_iptr& root) {
if ( !root ) {
return {};
}
if ( auto component = root->owner().component<Component>() ) {
return component;
}
for ( const_node_iptr child = root->first_child(); child; child = child->next_sibling() ) {
if ( auto component = get_component_in_children<Component>(child) ) {
return component;
}
}
return {};
}
template < typename Component, typename Iter >
std::size_t get_components_in_children(const const_node_iptr& root, Iter iter) {
std::size_t count{0u};
if ( !root ) {
return count;
}
if ( auto component = root->owner().component<Component>() ) {
++count;
iter++ = component;
}
for ( const_node_iptr child = root->first_child(); child; child = child->next_sibling() ) {
count += get_components_in_children<Component>(child, iter);
}
return count;
}
}

View File

@@ -46,6 +46,34 @@ local node = {
next_sibling = nil
}
---@param self node
---@param point v4f
---@return v4f
function node.local_to_world(self, point) end
---@param self node
---@param point v4f
---@return v4f
function node.world_to_local(self, point) end
---@param self node
---@return boolean
function node.has_parent(self) end
---@param self node
---@param parent node
---@return boolean
function node.has_parent_recursive(self, parent) end
---@param self node
---@return boolean
function node.has_children(self) end
---@param self node
---@param child node
---@return boolean
function node.has_child_recursive(self, child) end
---@param self node
---@return boolean
function node.remove_from_parent(self) end

View File

@@ -39,6 +39,14 @@ namespace e2d::bindings::high
"world_matrix", sol::property(
[](const node& n) -> m4f { return n.world_matrix(); }),
"local_to_world", [](const node& n, const v4f& v) -> v4f {
return n.local_to_world(v);
},
"world_to_local", [](const node& n, const v4f& v) -> v4f {
return n.world_to_local(v);
},
"root", sol::property(
[](node& n) -> node_iptr { return n.root(); }),

View File

@@ -123,6 +123,14 @@ namespace e2d
return world_matrix_;
}
v4f node::local_to_world(const v4f& local) const noexcept {
return local * world_matrix();
}
v4f node::world_to_local(const v4f& world) const noexcept {
return world * math::inversed(world_matrix()).first;
}
node_iptr node::root() noexcept {
node* n = this;
while ( n->parent_ ) {