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