13auto is_ancestor_of(entt::handle potential_parent, entt::handle child) ->
bool
24 auto& tc = child.get<transform_component>();
25 entt::handle current = tc.get_parent();
28 if(current == potential_parent)
30 current = current.get<transform_component>().get_parent();
35bool order_changed =
false;
37auto get_next_order() -> uint64_t
39 static uint64_t order{};
51 order_changed =
false;
74 component.set_owner(
entity);
88 parent_transform->remove_child(component.get_owner(), component);
92 for(
auto& child : component.children_)
103 return is_ancestor_of(parent_to_test, child);
108 std::unordered_set<entt::entity> entity_set;
111 entity_set.insert(*ent);
114 std::vector<entt::handle> top_level;
115 top_level.reserve(list.size());
119 bool has_selected_ancestor =
false;
132 if(entity_set.find(parent) != entity_set.end())
135 has_selected_ancestor =
true;
141 if(!has_selected_ancestor)
143 top_level.push_back(*ent);
152 std::unordered_set<entt::entity> entity_set;
155 entity_set.insert(ent);
158 std::vector<entt::handle> top_level;
159 top_level.reserve(list.size());
163 bool has_selected_ancestor =
false;
176 if(entity_set.find(parent) != entity_set.end())
179 has_selected_ancestor =
true;
185 if(!has_selected_ancestor)
187 top_level.push_back(ent);
194void transform_component::set_owner(entt::handle
owner)
201 root.
order = get_next_order();
204 transform_dirty_.set();
208 flags_.set_dirty(
this,
false);
209 flags_.set_value(
this, flags);
217 return transform_.get_value(
this);
222 transform_.set_value(
this, trans);
227 if(transform_.has_auto_resolve())
233 transform_.get_global_value(
this,
true);
235 for(
const auto& child : children_)
245 return transform_.get_global_value(
this,
false);
250 return set_transform_global_epsilon(tr, math::epsilon<float>());
255 if(get_transform_global().compare(tr, epsilon) == 0)
275 const auto& this_pos = get_position_global();
276 if(math::all(math::epsilonEqual(this_pos,
position, math::epsilon<float>())))
280 auto m = get_transform_global();
288 math::vec3 new_pos = get_position_global() + amount;
289 set_position_global(new_pos);
304 transform_.value(
this).set_position(
position);
309 transform_.value(
this).translate_local(amount);
319 float epsilon)
noexcept ->
bool
321 const auto& this_pos = get_position_global();
322 const auto& this_rotation = get_rotation_global();
323 bool same_position = math::all(math::epsilonEqual(this_pos,
position, epsilon));
327 bool same_rotation = math::all(math::epsilonEqual(this_rotation,
rotation, epsilon));
335 auto m = get_transform_global();
355 const auto& this_rotation = get_rotation_global();
356 if(math::all(math::epsilonEqual(this_rotation,
rotation, math::epsilon<float>())))
361 auto m = get_transform_global();
369 auto m = get_transform_global();
372 set_transform_global(m);
387 transform_.value(
this).set_rotation(
rotation);
392 auto m = get_transform_local();
395 set_transform_local(m);
415 auto m = get_transform_global();
418 set_transform_global(m);
433 auto m = get_transform_local();
434 m.rotate_local(math::radians(
rotation));
436 set_transform_local(m);
441 auto m = get_transform_global();
442 m.rotate_axis(math::radians(degrees), axis);
444 set_transform_global(m);
450 auto quaternion = math::angleAxis(math::radians(degrees), axis);
451 auto vector2 = vector -
point;
452 vector2 = quaternion * vector2;
453 vector =
point + vector2;
461 auto euler = math::eulerAngles(
rotation);
469 look_at(
point, math::vec3{0.0f, 1.0f, 0.0f});
474 auto eye = get_position_global();
478 set_rotation_global(m.get_rotation());
492 transform_.value(
this).scale(
scale);
542 auto m = get_transform_global();
560 const auto& this_scale = get_scale_global();
561 if(math::all(math::epsilonEqual(this_scale,
scale, math::epsilon<float>())))
566 auto m = get_transform_global();
574 transform_.value(
this).set_scale(
scale);
579 const auto& this_skew = get_skew_global();
580 if(math::all(math::epsilonEqual(this_skew, skew, math::epsilon<float>())))
585 auto m = get_transform_global();
593 transform_.value(
this).set_skew(skew);
598 const auto& this_perspective = get_perspective_global();
599 if(math::all(math::epsilonEqual(this_perspective, perspective, math::epsilon<float>())))
604 auto m = get_transform_global();
605 m.set_perspective(perspective);
612 transform_.value(
this).set_perspective(perspective);
636 if(new_parent == get_owner())
643 if(old_parent == new_parent)
649 if(is_ancestor_of(get_owner(), new_parent))
659 cached_transform_global = get_transform_global();
662 bool was_active = is_active();
668 set_transform_global(cached_transform_global);
685 root.
order = get_next_order();
693 set_active(was_active);
703void transform_component::attach_child(
const entt::handle& child,
transform_component& child_transform)
705 children_.emplace_back(child);
709auto transform_component::remove_child(
const entt::handle& child, transform_component& child_transform) ->
bool
711 return std::erase_if(children_, [&child](
const auto& other)
713 return child == other;
717void transform_component::apply_transform(
const math::transform& tr)
noexcept
719 auto parent = get_parent();
722 auto inv_parent_transform = inverse_parent_transform(parent);
723 set_transform_local(inv_parent_transform * tr);
727 set_transform_local(tr);
731auto transform_component::inverse_parent_transform(
const entt::handle& parent)
noexcept ->
math::transform
733 const auto& parent_transform = parent.get<transform_component>().get_transform_global();
739 return get_transform_global().inverse_transform_coord(
point);
744 return flags_.get_value(
this)[flags_types::active];
749 return flags_.get_global_value(
this,
false)[flags_types::active];
754 auto val = flags_.get_value(
this);
755 val[flags_types::active] = active;
756 flags_.set_value(
this, val);
761 return transform_.dirty;
766 transform_.set_dirty(
this, dirty);
771 return transform_dirty_[
id];
776 transform_dirty_.set(
id, dirty);
781 transform_dirty_.set();
794void transform_component::on_dirty_transform(
bool dirty)
noexcept
798 transform_dirty_.set();
801 if(transform_.has_auto_resolve())
803 for(
const auto& child : get_children())
805 auto component = child.try_get<transform_component>();
808 component->transform_.set_dirty(component, dirty);
814auto transform_component::resolve_global_value_transform() const noexcept ->
math::transform
823 return parent_transform * local_transform;
829void transform_component::on_dirty_flags(
bool dirty)
noexcept
835 transform_dirty_.set();
838 auto flags = flags_.get_global_value(
this,
false);
839 on_flags_changed(flags);
841 if(flags_.has_auto_resolve())
843 for(
const auto& child : get_children())
845 auto component = child.try_get<transform_component>();
848 component->flags_.set_dirty(component, dirty);
854void transform_component::on_flags_changed(flags_t flags)
856 if(flags[flags_types::active])
858 auto& comp =
get_owner().get_or_emplace<active_component>();
867auto transform_component::get_flags_global() const noexcept -> flags_t
869 return flags_.get_global_value(
this,
false);
872auto transform_component::resolve_global_value_flags() const noexcept -> flags_t
876 const auto& local_flags = flags_.get_value(
this);
879 const auto& parent_flags = parent.get<transform_component>().get_flags_global();
881 return parent_flags & local_flags;
auto get_owner() const noexcept -> entt::const_handle
Gets the owner of the component.
void set_owner(entt::handle owner)
Sets the owner of the component.
#define APPLOG_ERROR(...)
std::vector< size_t > parent_
auto inverse(transform_t< T, Q > const &t) noexcept -> transform_t< T, Q >
Hash specialization for batch_key to enable use in std::unordered_map.
auto is_roots_order_changed() -> bool
void reset_roots_order_changed()
std::vector< float > scale
std::vector< math::quat > rotation
Root component structure for the ACE framework, serves as the base component.
static void on_update_component(entt::registry &r, entt::entity e)
Called when the component is updated.
static void on_create_component(entt::registry &r, entt::entity e)
Called when the component is created.
static void on_destroy_component(entt::registry &r, entt::entity e)
Called when the component is destroyed.