]> git.tdb.fi Git - libs/game.git/blobdiff - source/game/transformpropagator.cpp
Add a transform component and propagation system
[libs/game.git] / source / game / transformpropagator.cpp
diff --git a/source/game/transformpropagator.cpp b/source/game/transformpropagator.cpp
new file mode 100644 (file)
index 0000000..73ecf64
--- /dev/null
@@ -0,0 +1,47 @@
+#include "transformpropagator.h"
+#include "events.h"
+#include "root.h"
+#include "stage.h"
+#include "transform.h"
+
+using namespace std;
+
+namespace Msp::Game {
+
+TransformPropagator::TransformPropagator(Stage &s):
+       System(s),
+       observer(s.get_event_bus())
+{
+       observer.observe<Events::EntityCreated>([this](const Events::EntityCreated &){ transforms_dirty = true; });
+       observer.observe<Events::EntityDestroyed>([this](const Events::EntityDestroyed &){ transforms_dirty = true; });
+}
+
+void TransformPropagator::tick(Time::TimeDelta)
+{
+       if(transforms_dirty)
+               rebuild_transform_order();
+
+       for(const ParentedTransform &t: transforms)
+               t.transform->update_world_matrix(t.parent.get());
+}
+
+void TransformPropagator::rebuild_transform_order()
+{
+       transforms.clear();
+       for(Handle<Entity> c: stage.get_root()->get_children())
+               rebuild_transform_order(c, nullptr);
+}
+
+void TransformPropagator::rebuild_transform_order(Handle<Entity> entity, Handle<Transform> parent_trans)
+{
+       if(Handle<Transform> trans = entity->get_transform())
+       {
+               transforms.emplace_back(trans, parent_trans);
+               parent_trans = trans;
+       }
+
+       for(Handle<Entity> c: entity->get_children())
+               rebuild_transform_order(c, parent_trans);
+}
+
+} // namespace Msp::Game