Unravel Engine C++ Reference
Loading...
Searching...
No Matches
transform_component.cpp
Go to the documentation of this file.
2
3#include <cstdint>
4#include <logging/logging.h>
5
6#include <algorithm>
7
8namespace unravel
9{
10namespace
11{
12auto is_ancestor_of(entt::handle potential_parent, entt::handle child) -> bool
13{
14 if(!child)
15 {
16 return false;
17 }
18 if(!potential_parent)
19 {
20 return false;
21 }
22 // If there is no parent, we've reached the root without a match.
23 auto& tc = child.get<transform_component>();
24 entt::handle current = tc.get_parent();
25 while(current)
26 {
27 if(current == potential_parent)
28 return true;
29 current = current.get<transform_component>().get_parent();
30 }
31 return false;
32}
33
34bool order_changed = false;
35
36auto get_next_order() -> uint64_t
37{
38 static uint64_t order{};
39 return order++;
40}
41
42} // namespace
43
45{
46 return order_changed;
47}
49{
50 order_changed = false;
51}
52
53void root_component::on_create_component(entt::registry& r, entt::entity e)
54{
55 order_changed = true;
56}
57
58void root_component::on_update_component(entt::registry& r, entt::entity e)
59{
60 order_changed = true;
61}
62
63void root_component::on_destroy_component(entt::registry& r, entt::entity e)
64{
65 order_changed = true;
66}
67
68void transform_component::on_create_component(entt::registry& r, entt::entity e)
69{
70 entt::handle entity(r, e);
71
72 auto& component = entity.get<transform_component>();
73 component.set_owner(entity);
74}
75
76void transform_component::on_destroy_component(entt::registry& r, entt::entity e)
77{
78 entt::handle entity(r, e);
79
80 auto& component = entity.get<transform_component>();
81
82 if(component.parent_)
83 {
84 auto parent_transform = component.parent_.try_get<transform_component>();
85 if(parent_transform)
86 {
87 parent_transform->remove_child(component.get_owner(), component);
88 }
89 }
90
91 for(auto& child : component.children_)
92 {
93 if(child)
94 {
95 child.destroy();
96 }
97 }
98}
99
100auto transform_component::is_parent_of(entt::handle parent_to_test, entt::handle child) -> bool
101{
102 return is_ancestor_of(parent_to_test, child);
103}
104
105auto transform_component::get_top_level_entities(const std::vector<entt::handle*>& list) -> std::vector<entt::handle>
106{
107 std::unordered_set<entt::entity> entity_set;
108 for(auto ent : list)
109 {
110 entity_set.insert(*ent);
111 }
112
113 std::vector<entt::handle> top_level;
114 top_level.reserve(list.size());
115
116 for(auto ent : list)
117 {
118 bool has_selected_ancestor = false;
119 auto current = *ent;
120
121 // Walk up the hierarchy. If any ancestor is also in the selection,
122 // we skip this entity.
123 while(true)
124 {
125 auto parent = current.get<transform_component>().get_parent();
126 if(!parent)
127 {
128 // No more parents, so no selected ancestor found.
129 break;
130 }
131 if(entity_set.find(parent) != entity_set.end())
132 {
133 // Found a parent in the selection; skip.
134 has_selected_ancestor = true;
135 break;
136 }
137 current = parent;
138 }
139
140 if(!has_selected_ancestor)
141 {
142 top_level.push_back(*ent);
143 }
144 }
145
146 return top_level;
147}
148
149auto transform_component::get_top_level_entities(const std::vector<entt::handle>& list) -> std::vector<entt::handle>
150{
151 std::unordered_set<entt::entity> entity_set;
152 for(auto ent : list)
153 {
154 entity_set.insert(ent);
155 }
156
157 std::vector<entt::handle> top_level;
158 top_level.reserve(list.size());
159
160 for(auto ent : list)
161 {
162 bool has_selected_ancestor = false;
163 auto current = ent;
164
165 // Walk up the hierarchy. If any ancestor is also in the selection,
166 // we skip this entity.
167 while(true)
168 {
169 auto parent = current.get<transform_component>().get_parent();
170 if(!parent)
171 {
172 // No more parents, so no selected ancestor found.
173 break;
174 }
175 if(entity_set.find(parent) != entity_set.end())
176 {
177 // Found a parent in the selection; skip.
178 has_selected_ancestor = true;
179 break;
180 }
181 current = parent;
182 }
183
184 if(!has_selected_ancestor)
185 {
186 top_level.push_back(ent);
187 }
188 }
189
190 return top_level;
191}
192
193void transform_component::set_owner(entt::handle owner)
194{
195 base::set_owner(owner);
196
197 if(owner)
198 {
199 auto& root = get_owner().emplace_or_replace<root_component>();
200 root.order = get_next_order();
201 }
202
203 transform_dirty_.set();
204
205 flags_t flags{};
206 flags.set();
207 flags_.set_dirty(this, false);
208 flags_.set_value(this, flags);
209}
210
211//---------------------------------------------
213//---------------------------------------------
214auto transform_component::get_transform_local() const noexcept -> const math::transform&
215{
216 return transform_.get_value(this);
217}
218
220{
221 transform_.set_value(this, trans);
222}
223
225{
226 if(transform_.has_auto_resolve())
227 {
229 }
230 else
231 {
232 transform_.get_global_value(this, true);
233
234 for(const auto& child : children_)
235 {
236 auto& component = child.get<transform_component>();
237 component.resolve_transform_global();
238 }
239 }
240}
241
242auto transform_component::get_transform_global() const noexcept -> const math::transform&
243{
244 return transform_.get_global_value(this, false);
245}
246
248{
249 return set_transform_global_epsilon(tr, math::epsilon<float>());
250}
251
252auto transform_component::set_transform_global_epsilon(const math::transform& tr, float epsilon) noexcept -> bool
253{
254 if(get_transform_global().compare(tr, epsilon) == 0)
255 {
256 return false;
257 }
258
259 apply_transform(tr);
260
261 return true;
262}
263
264//---------------------------------------------
266//---------------------------------------------
267auto transform_component::get_position_global() const noexcept -> const math::vec3&
268{
269 return get_transform_global().get_position();
270}
271
272void transform_component::set_position_global(const math::vec3& position) noexcept
273{
274 const auto& this_pos = get_position_global();
275 if(math::all(math::epsilonEqual(this_pos, position, math::epsilon<float>())))
276 {
277 return;
278 }
279 auto m = get_transform_global();
280 m.set_position(position);
281
282 apply_transform(m);
283}
284
285void transform_component::move_by_global(const math::vec3& amount) noexcept
286{
287 math::vec3 new_pos = get_position_global() + amount;
288 set_position_global(new_pos);
289}
290
292{
293 set_position_global(math::vec3(0.0f, 0.0f, 0.0f));
294}
295
296auto transform_component::get_position_local() const noexcept -> const math::vec3&
297{
298 return get_transform_local().get_position();
299}
300
301void transform_component::set_position_local(const math::vec3& position) noexcept
302{
303 transform_.value(this).set_position(position);
304}
305
306void transform_component::move_by_local(const math::vec3& amount) noexcept
307{
308 transform_.value(this).translate_local(amount);
309}
310
312{
313 set_position_local(math::vec3(0.0f, 0.0f, 0.0f));
314}
315
317 const math::quat& rotation,
318 float epsilon) noexcept -> bool
319{
320 const auto& this_pos = get_position_global();
321 const auto& this_rotation = get_rotation_global();
322 bool same_position = math::all(math::epsilonEqual(this_pos, position, epsilon));
323
324 if(same_position)
325 {
326 bool same_rotation = math::all(math::epsilonEqual(this_rotation, rotation, epsilon));
327
328 if(same_rotation)
329 {
330 return false;
331 }
332 }
333
334 auto m = get_transform_global();
335 m.set_rotation(rotation);
336 m.set_position(position);
337
338 apply_transform(m);
339
340 return true;
341}
342
343//---------------------------------------------
345//---------------------------------------------
346
347auto transform_component::get_rotation_global() const noexcept -> const math::quat&
348{
349 return get_transform_global().get_rotation();
350}
351
352void transform_component::set_rotation_global(const math::quat& rotation) noexcept
353{
354 const auto& this_rotation = get_rotation_global();
355 if(math::all(math::epsilonEqual(this_rotation, rotation, math::epsilon<float>())))
356 {
357 return;
358 }
359
360 auto m = get_transform_global();
361 m.set_rotation(rotation);
362
363 apply_transform(m);
364}
365
366void transform_component::rotate_by_global(const math::quat& rotation) noexcept
367{
368 auto m = get_transform_global();
369 m.rotate(rotation);
370
371 set_transform_global(m);
372}
373
378
379auto transform_component::get_rotation_local() const noexcept -> const math::quat&
380{
381 return get_transform_local().get_rotation();
382}
383
384void transform_component::set_rotation_local(const math::quat& rotation) noexcept
385{
386 transform_.value(this).set_rotation(rotation);
387}
388
389void transform_component::rotate_by_local(const math::quat& rotation) noexcept
390{
391 auto m = get_transform_local();
392 m.rotate(rotation);
393
394 set_transform_local(m);
395}
396
401
403{
404 return math::degrees(math::eulerAngles(get_rotation_global()));
405}
406
407void transform_component::set_rotation_euler_global(math::vec3 rotation) noexcept
408{
409 set_rotation_global(math::transform::quat_t(math::radians(rotation)));
410}
411
412void transform_component::rotate_by_euler_global(math::vec3 rotation) noexcept
413{
414 auto m = get_transform_global();
415 m.rotate(math::radians(rotation));
416
417 set_transform_global(m);
418}
419
421{
422 return math::degrees(math::eulerAngles(get_rotation_local()));
423}
424
425void transform_component::set_rotation_euler_local(math::vec3 rotation) noexcept
426{
427 set_rotation_local(math::transform::quat_t(math::radians(rotation)));
428}
429
430void transform_component::rotate_by_euler_local(math::vec3 rotation) noexcept
431{
432 auto m = get_transform_local();
433 m.rotate_local(math::radians(rotation));
434
435 set_transform_local(m);
436}
437
438void transform_component::rotate_axis_global(float degrees, const math::vec3& axis) noexcept
439{
440 auto m = get_transform_global();
441 m.rotate_axis(math::radians(degrees), axis);
442
443 set_transform_global(m);
444}
445
446void transform_component::rotate_around_global(const math::vec3& point, const math::vec3& axis, float degrees)
447{
448 auto vector = get_position_global();
449 auto quaternion = math::angleAxis(math::radians(degrees), axis);
450 auto vector2 = vector - point;
451 vector2 = quaternion * vector2;
452 vector = point + vector2;
453
454 set_position_global(vector);
455 rotate_axis_global(degrees, axis);
456}
457
458void transform_component::rotate_around_global(const math::vec3& point, const math::quat& rotation)
459{
460 auto euler = math::eulerAngles(rotation);
461 rotate_around_global(point, math::vec3(1, 0, 0), math::degrees(euler.x));
462 rotate_around_global(point, math::vec3(0, 1, 0), math::degrees(euler.y));
463 rotate_around_global(point, math::vec3(0, 0, 1), math::degrees(euler.z));
464}
465
466void transform_component::look_at(const math::vec3& point) noexcept
467{
468 look_at(point, math::vec3{0.0f, 1.0f, 0.0f});
469}
470
471void transform_component::look_at(const math::vec3& point, const math::vec3& up) noexcept
472{
473 auto eye = get_position_global();
474 math::transform m = math::lookAt(eye, point, up);
475 m = math::inverse(m);
476
477 set_rotation_global(m.get_rotation());
478}
479
480//---------------------------------------------
482//---------------------------------------------
483
484auto transform_component::get_scale_local() const noexcept -> const math::vec3&
485{
486 return get_transform_local().get_scale();
487}
488
489void transform_component::scale_by_local(const math::vec3& scale) noexcept
490{
491 transform_.value(this).scale(scale);
492}
493
494auto transform_component::get_skew_local() const noexcept -> const math::vec3&
495{
496 return get_transform_local().get_skew();
497}
498
499auto transform_component::get_perspective_local() const noexcept -> const math::vec4&
500{
501 return get_transform_local().get_perspective();
502}
503
504auto transform_component::get_x_axis_local() const noexcept -> math::vec3
505{
506 return get_transform_local().x_unit_axis();
507}
508
509auto transform_component::get_y_axis_local() const noexcept -> math::vec3
510{
511 return get_transform_local().y_unit_axis();
512}
513
514auto transform_component::get_z_axis_local() const noexcept -> math::vec3
515{
516 return get_transform_local().z_unit_axis();
517}
518
519auto transform_component::get_x_axis_global() const noexcept -> math::vec3
520{
521 return get_transform_global().x_unit_axis();
522}
523
524auto transform_component::get_y_axis_global() const noexcept -> math::vec3
525{
526 return get_transform_global().y_unit_axis();
527}
528
529auto transform_component::get_z_axis_global() const noexcept -> math::vec3
530{
531 return get_transform_global().z_unit_axis();
532}
533
534auto transform_component::get_scale_global() const noexcept -> const math::vec3&
535{
536 return get_transform_global().get_scale();
537}
538
539void transform_component::scale_by_global(const math::vec3& scale) noexcept
540{
541 auto m = get_transform_global();
542 m.scale(scale);
543
544 apply_transform(m);
545}
546
547auto transform_component::get_skew_global() const noexcept -> const math::vec3&
548{
549 return get_transform_global().get_skew();
550}
551
552auto transform_component::get_perspective_global() const noexcept -> const math::vec4&
553{
554 return get_transform_global().get_perspective();
555}
556
557void transform_component::set_scale_global(const math::vec3& scale) noexcept
558{
559 const auto& this_scale = get_scale_global();
560 if(math::all(math::epsilonEqual(this_scale, scale, math::epsilon<float>())))
561 {
562 return;
563 }
564
565 auto m = get_transform_global();
566 m.set_scale(scale);
567
568 apply_transform(m);
569}
570
571void transform_component::set_scale_local(const math::vec3& scale) noexcept
572{
573 transform_.value(this).set_scale(scale);
574}
575
576void transform_component::set_skew_global(const math::vec3& skew) noexcept
577{
578 const auto& this_skew = get_skew_global();
579 if(math::all(math::epsilonEqual(this_skew, skew, math::epsilon<float>())))
580 {
581 return;
582 }
583
584 auto m = get_transform_global();
585 m.set_skew(skew);
586
587 apply_transform(m);
588}
589
590void transform_component::set_skew_local(const math::vec3& skew) noexcept
591{
592 transform_.value(this).set_skew(skew);
593}
594
595void transform_component::set_perspective_global(const math::vec4& perspective) noexcept
596{
597 const auto& this_perspective = get_perspective_global();
598 if(math::all(math::epsilonEqual(this_perspective, perspective, math::epsilon<float>())))
599 {
600 return;
601 }
602
603 auto m = get_transform_global();
604 m.set_perspective(perspective);
605
606 apply_transform(m);
607}
608
609void transform_component::set_perspective_local(const math::vec4& perspective) noexcept
610{
611 transform_.value(this).set_perspective(perspective);
612}
613
615{
616 set_scale_global(math::vec3{1.0f, 1.0f, 1.0f});
617}
618
620{
621 set_scale_local(math::vec3{1.0f, 1.0f, 1.0f});
622}
623
625{
626 children_.clear();
627 parent_ = {};
628}
629
630auto transform_component::set_parent(const entt::handle& p, bool global_stays) -> bool
631{
632 auto new_parent = p;
633 auto old_parent = parent_;
634
635 if(new_parent == get_owner())
636 {
637 APPLOG_ERROR("Cannot set parent to self");
638 return false;
639 }
640
641 // Skip if this is a no-op.
642 if(old_parent == new_parent)
643 {
644 return false;
645 }
646
647 // Skip if the new parent is our descendant.
648 if(is_ancestor_of(get_owner(), new_parent))
649 {
650 return false;
651 }
652
653 // Before we do anything, make sure that all pending math::transform
654 // operations are resolved (including those applied to our parent).
655 math::transform cached_transform_global;
656 if(global_stays)
657 {
658 cached_transform_global = get_transform_global();
659 }
660
661 parent_ = new_parent;
662 set_dirty(true);
663
664 if(global_stays)
665 {
666 set_transform_global(cached_transform_global);
667 }
668
669 set_dirty(true);
670
671 if(new_parent)
672 {
673 new_parent.get<transform_component>().attach_child(get_owner(), *this);
674
675 if(!old_parent)
676 {
677 get_owner().remove<root_component>();
678 }
679 }
680 else
681 {
682 auto& root = get_owner().emplace_or_replace<root_component>();
683 root.order = get_next_order();
684 }
685
686 if(old_parent)
687 {
688 old_parent.get<transform_component>().remove_child(get_owner(), *this);
689 }
690
691 return true;
692}
693
695{
696 return parent_;
697}
698
699void transform_component::attach_child(const entt::handle& child, transform_component& child_transform)
700{
701 child_transform.sort_index_ = int32_t(children_.size());
702 children_.push_back(child);
705}
706
707auto transform_component::remove_child(const entt::handle& child, transform_component& child_transform) -> bool
708{
709 auto iter = std::remove_if(std::begin(children_),
710 std::end(children_),
711 [&child](const auto& other)
712 {
713 return child == other;
714 });
715 if(iter == std::end(children_))
716 {
717 return false;
718 }
719
720 assert(std::distance(iter, std::end(children_)) == 1);
721
722 auto removed_idx = child_transform.sort_index_;
723
724 children_.erase(iter, std::end(children_));
725
726 // shift all bigger sort indices
727 for(auto& c : children_)
728 {
729 auto& sort_idx = c.get<transform_component>().sort_index_;
730 if(sort_idx > removed_idx)
731 {
732 sort_idx--;
733 }
734 }
735 child_transform.sort_index_ = {-1};
736
737 return true;
738}
739
741{
742 std::sort(children_.begin(),
743 children_.end(),
744 [](const auto& lhs, const auto& rhs)
745 {
746 return lhs.template get<transform_component>().sort_index_ <
747 rhs.template get<transform_component>().sort_index_;
748 });
749}
750
751void transform_component::apply_transform(const math::transform& tr) noexcept
752{
753 auto parent = get_parent();
754 if(parent)
755 {
756 auto inv_parent_transform = inverse_parent_transform(parent);
757 set_transform_local(inv_parent_transform * tr);
758 }
759 else
760 {
761 set_transform_local(tr);
762 }
763}
764
765auto transform_component::inverse_parent_transform(const entt::handle& parent) noexcept -> math::transform
766{
767 const auto& parent_transform = parent.get<transform_component>().get_transform_global();
768 return math::inverse(parent_transform);
769}
770
771auto transform_component::to_local(const math::vec3& point) const noexcept -> math::vec3
772{
773 return get_transform_global().inverse_transform_coord(point);
774}
775
776auto transform_component::is_active() const noexcept -> bool
777{
778 return flags_.get_value(this)[flags_types::active];
779}
780
781auto transform_component::is_active_global() const noexcept -> bool
782{
783 return flags_.get_global_value(this, false)[flags_types::active];
784}
785
786void transform_component::set_active(bool active) noexcept
787{
788 auto val = flags_.get_value(this);
789 val[flags_types::active] = active;
790 flags_.set_value(this, val);
791}
792
793auto transform_component::is_dirty() const noexcept -> bool
794{
795 return transform_.dirty;
796}
797
798void transform_component::set_dirty(bool dirty) noexcept
799{
800 transform_.set_dirty(this, dirty);
801}
802
803auto transform_component::is_dirty(uint8_t id) const noexcept -> bool
804{
805 return transform_dirty_[id];
806}
807
808void transform_component::set_dirty(uint8_t id, bool dirty) noexcept
809{
810 transform_dirty_.set(id, dirty);
811}
812
813auto transform_component::get_children() const noexcept -> const std::vector<entt::handle>&
814{
815 return children_;
816}
817
818void transform_component::set_children(const std::vector<entt::handle>& children)
819{
820 children_ = children;
821}
822
823void transform_component::on_dirty_transform(bool dirty) noexcept
824{
825 if(dirty)
826 {
827 transform_dirty_.set();
828 }
829
830 if(transform_.has_auto_resolve())
831 {
832 for(const auto& child : get_children())
833 {
834 auto component = child.try_get<transform_component>();
835 if(component)
836 {
837 component->transform_.set_dirty(component, dirty);
838 }
839 }
840 }
841}
842
843auto transform_component::resolve_global_value_transform() const noexcept -> math::transform
844{
845 auto parent = get_parent();
846
847 if(parent)
848 {
849 const auto& parent_transform = parent.get<transform_component>().get_transform_global();
850 const auto& local_transform = get_transform_local();
851
852 return parent_transform * local_transform;
853 }
854
855 return get_transform_local();
856}
857
858void transform_component::on_dirty_flags(bool dirty) noexcept
859{
860 auto flags = flags_.get_global_value(this, false);
861 on_flags_changed(flags);
862
863 if(flags_.has_auto_resolve())
864 {
865 for(const auto& child : get_children())
866 {
867 auto component = child.try_get<transform_component>();
868 if(component)
869 {
870 component->flags_.set_dirty(component, dirty);
871 }
872 }
873 }
874}
875
876void transform_component::on_flags_changed(flags_t flags)
877{
878 if(flags[flags_types::active])
879 {
880 auto& comp = get_owner().get_or_emplace<active_component>();
881 (void)comp;
882 }
883 else
884 {
885 get_owner().remove<active_component>();
886 }
887}
888
889auto transform_component::get_flags_global() const noexcept -> flags_t
890{
891 return flags_.get_global_value(this, false);
892}
893
894auto transform_component::resolve_global_value_flags() const noexcept -> flags_t
895{
896 auto parent = get_parent();
897
898 const auto& local_flags = flags_.get_value(this);
899 if(parent)
900 {
901 const auto& parent_flags = parent.get<transform_component>().get_flags_global();
902
903 return parent_flags & local_flags;
904 }
905
906 return local_flags;
907}
908} // namespace unravel
General purpose transformation class designed to maintain each component of the transformation separa...
Definition transform.hpp:27
qua< T, Q > quat_t
Definition transform.hpp:34
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.
Component that handles transformations (position, rotation, scale, etc.) in the ACE framework.
void rotate_around_global(const math::vec3 &point, const math::vec3 &axis, float degrees)
auto is_dirty() const noexcept -> bool
Checks if the component is dirty.
auto get_scale_local() const noexcept -> const math::vec3 &
Gets the local scale.
void set_perspective_global(const math::vec4 &p) noexcept
Sets the global perspective.
static void on_create_component(entt::registry &r, entt::entity e)
Called when the component is created.
auto get_rotation_local() const noexcept -> const math::quat &
Gets the local rotation.
void reset_position_global() noexcept
Resets the global position to the origin.
static auto is_parent_of(entt::handle parent_to_test, entt::handle child) -> bool
void reset_scale_local() noexcept
Resets the local scale to the default value.
auto get_position_local() const noexcept -> const math::vec3 &
Gets the local position.
void scale_by_global(const math::vec3 &scale) noexcept
Scales the component by a specified amount globally.
void reset_scale_global() noexcept
Resets the global scale to the default value.
void set_position_local(const math::vec3 &position) noexcept
Sets the local position.
void look_at(const math::vec3 &point) noexcept
Orients the component to look at a specified point.
auto set_transform_global_epsilon(const math::transform &trans, float epsilon) noexcept -> bool
auto get_position_global() const noexcept -> const math::vec3 &
TRANSLATION.
auto set_position_and_rotation_global(const math::vec3 &position, const math::quat &rotation, float epsilon) noexcept -> bool
auto get_rotation_euler_global() const noexcept -> math::vec3
Gets the global rotation in Euler angles.
void rotate_by_euler_global(math::vec3 rotation) noexcept
Rotates the component by a specified amount in Euler angles globally.
auto get_z_axis_local() const noexcept -> math::vec3
Gets the local Z-axis.
void rotate_axis_global(float degrees, const math::vec3 &axis) noexcept
Rotates the component around a specified axis globally.
auto get_rotation_euler_local() const noexcept -> math::vec3
Gets the local rotation in Euler angles.
void set_rotation_euler_global(math::vec3 rotation) noexcept
Sets the global rotation in Euler angles.
void set_active(bool active) noexcept
Sets the active flag.
void set_rotation_global(const math::quat &rotation) noexcept
Sets the global rotation.
void scale_by_local(const math::vec3 &scale) noexcept
Scales the component by a specified amount locally.
void resolve_transform_global() noexcept
TRANSFORMS.
auto is_active_global() const noexcept -> bool
auto get_skew_local() const noexcept -> const math::vec3 &
Gets the local skew.
void set_perspective_local(const math::vec4 &p) noexcept
Sets the local perspective.
void move_by_global(const math::vec3 &amount) noexcept
Moves the component by a specified amount globally.
void sort_children() noexcept
Sorts the child entities.
void _clear_relationships()
Clears the relationships of the component.
static auto get_top_level_entities(const std::vector< entt::handle > &list) -> std::vector< entt::handle >
void set_skew_local(const math::vec3 &s) noexcept
Sets the local skew.
auto set_parent(const entt::handle &parent, bool global_stays=true) -> bool
Sets the parent entity.
auto get_y_axis_global() const noexcept -> math::vec3
Gets the global Y-axis.
void reset_rotation_local() noexcept
Resets the local rotation to the default orientation.
void rotate_by_euler_local(math::vec3 rotation) noexcept
Rotates the component by a specified amount in Euler angles locally.
void reset_position_local() noexcept
Resets the local position to the origin.
void set_children(const std::vector< entt::handle > &children)
Sets the child entities.
void reset_rotation_global() noexcept
Resets the global rotation to the default orientation.
auto get_rotation_global() const noexcept -> const math::quat &
ROTATION.
void move_by_local(const math::vec3 &amount) noexcept
Moves the component by a specified amount locally.
auto set_transform_global(const math::transform &trans) noexcept -> bool
Sets the global transform.
static void on_destroy_component(entt::registry &r, entt::entity e)
Called when the component is destroyed.
void set_scale_global(const math::vec3 &scale) noexcept
Sets the global scale.
auto get_perspective_local() const noexcept -> const math::vec4 &
Gets the local perspective.
auto get_x_axis_local() const noexcept -> math::vec3
Gets the local X-axis.
void set_rotation_euler_local(math::vec3 rotation) noexcept
Sets the local rotation in Euler angles.
auto get_z_axis_global() const noexcept -> math::vec3
Gets the global Z-axis.
void set_position_global(const math::vec3 &position) noexcept
Sets the global position.
auto get_x_axis_global() const noexcept -> math::vec3
BASIS.
void set_transform_local(const math::transform &trans) noexcept
Sets the local transform.
void set_dirty(bool dirty) noexcept
Sets the dirty flag.
auto get_transform_local() const noexcept -> const math::transform &
Gets the local transform.
void set_scale_local(const math::vec3 &scale) noexcept
Sets the local scale.
auto get_transform_global() const noexcept -> const math::transform &
Gets the global transform.
auto get_scale_global() const noexcept -> const math::vec3 &
SCALE.
void rotate_by_local(const math::quat &rotation) noexcept
Rotates the component by a specified amount locally.
auto get_y_axis_local() const noexcept -> math::vec3
Gets the local Y-axis.
auto is_active() const noexcept -> bool
Checks if the component is active.
auto to_local(const math::vec3 &point) const noexcept -> math::vec3
SPACE UTILS.
void set_skew_global(const math::vec3 &s) noexcept
Sets the global skew.
auto get_skew_global() const noexcept -> const math::vec3 &
SKEW.
void set_rotation_local(const math::quat &rotation) noexcept
Sets the local rotation.
auto get_parent() const noexcept -> entt::handle
RELATIONSHIP.
auto get_perspective_global() const noexcept -> const math::vec4 &
PERSPECTIVE.
void rotate_by_global(const math::quat &rotation) noexcept
Rotates the component by a specified amount globally.
auto get_children() const noexcept -> const std::vector< entt::handle > &
Gets the child entities.
float scale
Definition hub.cpp:25
#define APPLOG_ERROR(...)
Definition logging.h:20
Definition bbox.cpp:5
auto inverse(transform_t< T, Q > const &t) noexcept -> transform_t< T, Q >
auto is_roots_order_changed() -> bool
void reset_roots_order_changed()
entt::entity entity
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.
gfx::uniform_handle handle
Definition uniform.cpp:9