diff --git a/engine/includes/components/actor.h b/engine/includes/components/actor.h index 329fc4d8a..1ccc9d777 100644 --- a/engine/includes/components/actor.h +++ b/engine/includes/components/actor.h @@ -46,6 +46,12 @@ class ENGINE_EXPORT Actor : public Object { World *world() const; Component *component(const std::string type); + + template + T *getComponent() { + return static_cast(component(T::metaClass()->name())); + } + Component *componentInChild(const std::string type); std::list componentsInChild(const std::string type); diff --git a/engine/includes/editor/editortool.h b/engine/includes/editor/editortool.h index 50caf57ee..dbd302aae 100644 --- a/engine/includes/editor/editortool.h +++ b/engine/includes/editor/editortool.h @@ -4,36 +4,11 @@ #include #include -#include #include -class Actor; -class Renderable; - class ENGINE_EXPORT EditorTool { public: - struct ENGINE_EXPORT Select { - Select(); - - bool operator==(const Select &left) { - return (uuid == left.uuid); - } - - uint32_t uuid; - Actor *object; - Renderable *renderable; - Vector3 position; - Vector3 scale; - Vector3 euler; - Vector3 pivot; - Quaternion quat; - AABBox box; - }; - - typedef QList SelectList; + +public: + explicit WidgetTool(WidgetController *controller); void update(bool pivot, bool local, bool snap) override; void beginControl() override; + void cancelControl() override; QString icon() const override; QString name() const override; + Vector3 objectPosition(); + AABBox objectBound(); + + const VariantList &cache() const; + protected: + VariantList m_propertiesCache; + WidgetController *m_controller; AABBox m_savedBox; diff --git a/modules/uikit/includes/editor/widgetcontroller.h b/modules/uikit/includes/editor/widgetcontroller.h index 0f9201fb8..ab06b19ce 100644 --- a/modules/uikit/includes/editor/widgetcontroller.h +++ b/modules/uikit/includes/editor/widgetcontroller.h @@ -19,6 +19,7 @@ class WidgetController : public CameraController { void clear(bool signal); QList selected() override; + WidgetTool::SelectList &selectList() { return m_selected; } void selectActors(const std::list &list); @@ -46,14 +47,12 @@ public slots: Widget *getHoverWidget(float x, float y); private: - EditorTool::SelectList m_selected; + WidgetTool::SelectList m_selected; std::list m_objectsList; Object *m_rootObject; - Widget *m_focusWidget; - WidgetTool *m_widgetTool; uint32_t m_width; diff --git a/modules/uikit/src/editor/tools/widgettool.cpp b/modules/uikit/src/editor/tools/widgettool.cpp index 1ad52c2f3..41823cced 100644 --- a/modules/uikit/src/editor/tools/widgettool.cpp +++ b/modules/uikit/src/editor/tools/widgettool.cpp @@ -17,8 +17,7 @@ const Vector3 cornerB(10.0f,-20.0f, 0.0f); const Vector3 cornerC(20.0f, 10.0f, 0.0f); const Vector3 cornerD(10.0f, 20.0f, 0.0f); -WidgetTool::WidgetTool(WidgetController *controller, SelectList &selection) : - EditorTool(selection), +WidgetTool::WidgetTool(WidgetController *controller) : m_controller(controller) { } @@ -26,13 +25,59 @@ WidgetTool::WidgetTool(WidgetController *controller, SelectList &selection) : void WidgetTool::beginControl() { EditorTool::beginControl(); + m_propertiesCache.clear(); + + for(auto &it : m_controller->selectList()) { + Transform *t = it.object->transform(); + it.position = t->position(); + it.scale = t->scale(); + it.euler = t->rotation(); + it.quat = t->quaternion(); + + VariantMap components; + for(auto &child : it.object->getChildren()) { + Component *component = dynamic_cast(child); + if(component) { + VariantMap properies; + const MetaObject *meta = component->metaObject(); + for(int i = 0; i < meta->propertyCount(); i++) { + MetaProperty property = meta->property(i); + properies[property.name()] = property.read(component); + } + components[std::to_string(component->uuid())] = properies; + } + } + m_propertiesCache.push_back(components); + } + + m_position = objectPosition(); m_savedWorld = m_world; } +void WidgetTool::cancelControl() { + auto cache = m_propertiesCache.begin(); + for(auto &it : m_controller->selectList()) { + VariantMap components = (*cache).toMap(); + for(auto &child : it.object->getChildren()) { + Component *component = dynamic_cast(child); + if(component) { + VariantMap properties = components[std::to_string(component->uuid())].toMap(); + const MetaObject *meta = component->metaObject(); + for(int i = 0; i < meta->propertyCount(); i++) { + MetaProperty property = meta->property(i); + property.write(component, properties[property.name()]); + } + } + } + + ++cache; + } +} + void WidgetTool::update(bool pivot, bool local, bool snap) { EditorTool::update(pivot, local, snap); - RectTransform *rect = static_cast(m_selected.front().object->transform()); + RectTransform *rect = static_cast(m_controller->selectList().front().object->transform()); RectTransform *parent = dynamic_cast(rect->parentTransform()); if(parent) { @@ -81,7 +126,7 @@ void WidgetTool::update(bool pivot, bool local, bool snap) { if(isDrag) { Vector3 delta(m_world - m_savedWorld); if(delta.length() > 1.0f) { - for(const auto &it : qAsConst(m_selected)) { + for(const auto &it : qAsConst(m_controller->selectList())) { RectTransform *rect = static_cast(it.object->transform()); Vector3 p(rect->position()); @@ -144,3 +189,42 @@ QString WidgetTool::icon() const { QString WidgetTool::name() const { return "Resize"; } + +const VariantList &WidgetTool::cache() const { + return m_propertiesCache; +} + +Vector3 WidgetTool::objectPosition() { + if(m_controller->selectList().size() == 1) { + return m_controller->selectList().front().object->transform()->worldPosition(); + } + return objectBound().center; +} + +AABBox WidgetTool::objectBound() { + AABBox result; + result.extent = Vector3(-1.0f); + if(!m_controller->selectList().empty()) { + bool first = true; + for(auto &it : m_controller->selectList()) { + if(it.renderable == nullptr) { + it.renderable = it.object->getComponent(); + } + if(it.renderable) { + if(first) { + result = it.renderable->bound(); + first = false; + } else { + result.encapsulate(it.renderable->bound()); + } + } else { + if(first) { + result.center = it.object->transform()->worldPosition(); + } else { + result.encapsulate(it.object->transform()->worldPosition()); + } + } + } + } + return result; +} diff --git a/modules/uikit/src/editor/widgetcontroller.cpp b/modules/uikit/src/editor/widgetcontroller.cpp index 925a1dc50..6f908c975 100644 --- a/modules/uikit/src/editor/widgetcontroller.cpp +++ b/modules/uikit/src/editor/widgetcontroller.cpp @@ -22,8 +22,7 @@ WidgetController::WidgetController(Object *rootObject, QWidget *view) : CameraController(), m_rootObject(rootObject), - m_focusWidget(nullptr), - m_widgetTool(new WidgetTool(this, m_selected)), + m_widgetTool(new WidgetTool(this)), m_width(0), m_height(0), m_canceled(false), @@ -65,7 +64,7 @@ void WidgetController::selectActors(const std::list &list) { for(auto it : list) { Actor *actor = dynamic_cast(findObject(it)); if(actor) { - EditorTool::Select data; + WidgetTool::Select data; data.object = actor; data.uuid = actor->uuid(); m_selected.push_back(data); @@ -123,7 +122,6 @@ void WidgetController::drawHandles() { if(!m_selected.empty()) { m_widgetTool->update(false, true, Input::isKey(Input::KEY_LEFT_CONTROL)); } - } void WidgetController::update() { @@ -132,14 +130,14 @@ void WidgetController::update() { CameraController::update(); - m_focusWidget = getHoverWidget(pos.x, pos.y); + Widget *focusWidget = getHoverWidget(pos.x, pos.y); if(Input::isMouseButtonUp(Input::MOUSE_LEFT)) { if(!m_drag) { std::list objects; if(!m_canceled) { - if(m_focusWidget) { - objects.push_back(m_focusWidget->actor()->uuid()); + if(focusWidget) { + objects.push_back(focusWidget->actor()->uuid()); } onSelectActor(objects, Input::isKey(Input::KEY_LEFT_CONTROL)); } else { @@ -184,14 +182,12 @@ void WidgetController::update() { setDrag(false); } - if(Input::isMouseButtonDown(Input::MOUSE_RIGHT)) { - if(m_drag) { - m_widgetTool->cancelControl(); + if(m_drag && Input::isMouseButtonDown(Input::MOUSE_RIGHT)) { + m_widgetTool->cancelControl(); - setDrag(false); - m_canceled = true; - emit sceneUpdated(); - } + setDrag(false); + m_canceled = true; + emit sceneUpdated(); } if(!m_selected.empty()) { @@ -206,7 +202,7 @@ void WidgetController::update() { if(m_widgetTool->cursor() != Qt::ArrowCursor) { emit setCursor(QCursor(m_widgetTool->cursor())); - } else if(m_focusWidget) { + } else if(focusWidget) { emit setCursor(QCursor(Qt::CrossCursor)); } else { emit unsetCursor(); diff --git a/worldeditor/src/screens/objecthierarchy/objecthierarchymodel.cpp b/worldeditor/src/screens/objecthierarchy/objecthierarchymodel.cpp index 6c0007ff2..d2ee3adb8 100644 --- a/worldeditor/src/screens/objecthierarchy/objecthierarchymodel.cpp +++ b/worldeditor/src/screens/objecthierarchy/objecthierarchymodel.cpp @@ -174,7 +174,9 @@ QModelIndex ObjectHierarchyModel::index(int row, int column, const QModelIndex & ptr = *std::next(children.begin(), row-1); } } - return createIndex(row, column, ptr->uuid()); + if(ptr) { + return createIndex(row, column, ptr->uuid()); + } } return QModelIndex(); } diff --git a/worldeditor/src/screens/scenecomposer/objectcontroller.cpp b/worldeditor/src/screens/scenecomposer/objectcontroller.cpp index 587f279a2..ca96962f8 100644 --- a/worldeditor/src/screens/scenecomposer/objectcontroller.cpp +++ b/worldeditor/src/screens/scenecomposer/objectcontroller.cpp @@ -179,11 +179,11 @@ ObjectController::ObjectController() : EditorSettings::instance()->value(gIsolationColor, QColor(0, 76, 140, 0)); m_tools = { - new SelectTool(this, m_selected), - new MoveTool(this, m_selected), - new RotateTool(this, m_selected), - new ScaleTool(this, m_selected), - new ResizeTool(this, m_selected), + new SelectTool(this), + new MoveTool(this), + new RotateTool(this), + new ScaleTool(this), + new ResizeTool(this), }; } @@ -430,7 +430,7 @@ void ObjectController::selectActors(const std::list &list) { for(auto it : list) { Actor *actor = dynamic_cast(findObject(it)); if(actor) { - EditorTool::Select data; + SelectTool::Select data; data.object = actor; data.uuid = actor->uuid(); m_selected.push_back(data); diff --git a/worldeditor/src/screens/scenecomposer/objectcontroller.h b/worldeditor/src/screens/scenecomposer/objectcontroller.h index 336b6feb8..817dd688b 100644 --- a/worldeditor/src/screens/scenecomposer/objectcontroller.h +++ b/worldeditor/src/screens/scenecomposer/objectcontroller.h @@ -4,10 +4,11 @@ #include #include -#include #include #include +#include "tools/selecttool.h" + class Actor; class Scene; @@ -43,9 +44,9 @@ class ObjectController : public CameraController { void setIsolatedModified(bool flag) { m_isolatedActorModified = flag; } bool isIsolatedModified() const { return m_isolatedActorModified; } - QList tools() const { return m_tools; } + QList tools() const { return m_tools; } - EditorTool::SelectList &selectList() { return m_selected; } + SelectTool::SelectList &selectList() { return m_selected; } bool isDrag() const { return m_drag; } void setDrag(bool drag); @@ -95,7 +96,7 @@ private slots: void onPrefabCreated(uint32_t uuid, uint32_t clone); protected: - EditorTool::SelectList m_selected; + SelectTool::SelectList m_selected; QList m_isolationSelectedBackup; @@ -104,7 +105,7 @@ private slots: std:: list m_objectsList; - QList m_tools; + QList m_tools; Vector2 m_mousePosition; @@ -112,7 +113,7 @@ private slots: Actor *m_isolatedActor; - EditorTool *m_activeTool; + SelectTool *m_activeTool; ViewportRaycast *m_rayCast; diff --git a/worldeditor/src/screens/scenecomposer/scenecomposer.cpp b/worldeditor/src/screens/scenecomposer/scenecomposer.cpp index 59f77c89f..b92188f7b 100644 --- a/worldeditor/src/screens/scenecomposer/scenecomposer.cpp +++ b/worldeditor/src/screens/scenecomposer/scenecomposer.cpp @@ -383,7 +383,7 @@ void SceneComposer::restoreBackupScenes() { emit objectsHierarchyChanged(Engine::world()); // Repick selection bool first = true; - EditorTool::SelectList &list = m_controller->selectList(); + SelectTool::SelectList &list = m_controller->selectList(); for(auto &it : list) { Actor *actor = dynamic_cast(ObjectSystem::findObject(it.uuid, Engine::world())); if(actor) { diff --git a/worldeditor/src/screens/scenecomposer/tools/movetool.cpp b/worldeditor/src/screens/scenecomposer/tools/movetool.cpp index 7da3c58fc..28c1c6788 100644 --- a/worldeditor/src/screens/scenecomposer/tools/movetool.cpp +++ b/worldeditor/src/screens/scenecomposer/tools/movetool.cpp @@ -7,8 +7,8 @@ #include "../objectcontroller.h" -MoveTool::MoveTool(ObjectController *controller, SelectList &selection) : - SelectTool(controller, selection) { +MoveTool::MoveTool(ObjectController *controller) : + SelectTool(controller) { m_snap = 0.25f; @@ -19,7 +19,7 @@ void MoveTool::update(bool center, bool local, bool snap) { bool isDrag = m_controller->isDrag(); - Transform *t = m_selected.back().object->transform(); + Transform *t = m_controller->selectList().back().object->transform(); m_world = Handles::moveTool(objectPosition(), local ? t->worldQuaternion() : Quaternion(), isDrag); if(isDrag) { @@ -30,7 +30,7 @@ void MoveTool::update(bool center, bool local, bool snap) { } } QSet scenes; - for(const auto &it : qAsConst(m_selected)) { + for(const auto &it : qAsConst(m_controller->selectList())) { Vector3 dt(local ? t->worldQuaternion() * delta : delta); Actor *a = dynamic_cast(it.object->parent()); if(!local && a && a->transform()) { diff --git a/worldeditor/src/screens/scenecomposer/tools/movetool.h b/worldeditor/src/screens/scenecomposer/tools/movetool.h index 5e66bba07..22d53b8b7 100644 --- a/worldeditor/src/screens/scenecomposer/tools/movetool.h +++ b/worldeditor/src/screens/scenecomposer/tools/movetool.h @@ -7,7 +7,7 @@ class ObjectCtrl; class MoveTool : public SelectTool { public: - explicit MoveTool(ObjectController *controller, SelectList &selection); + explicit MoveTool(ObjectController *controller); void update(bool center, bool local, bool snap) override; diff --git a/worldeditor/src/screens/scenecomposer/tools/resizetool.cpp b/worldeditor/src/screens/scenecomposer/tools/resizetool.cpp index b39e4cc61..c25c264d4 100644 --- a/worldeditor/src/screens/scenecomposer/tools/resizetool.cpp +++ b/worldeditor/src/screens/scenecomposer/tools/resizetool.cpp @@ -9,15 +9,15 @@ #include "../objectcontroller.h" -ResizeTool::ResizeTool(ObjectController *controller, SelectList &selection) : - SelectTool(controller, selection) { +ResizeTool::ResizeTool(ObjectController *controller) : + SelectTool(controller) { } void ResizeTool::beginControl() { SelectTool::beginControl(); m_savedBox = m_box; - for(auto &it : m_selected) { + for(auto &it : m_controller->selectList()) { if(it.renderable) { it.box = it.renderable->bound(); @@ -84,7 +84,7 @@ void ResizeTool::update(bool pivot, bool local, bool snap) { QSet scenes; - for(const auto &it : qAsConst(m_selected)) { + for(const auto &it : qAsConst(m_controller->selectList())) { Transform *tr = it.object->transform(); Matrix4 parent; diff --git a/worldeditor/src/screens/scenecomposer/tools/resizetool.h b/worldeditor/src/screens/scenecomposer/tools/resizetool.h index c6a8f94d9..fbfe1af10 100644 --- a/worldeditor/src/screens/scenecomposer/tools/resizetool.h +++ b/worldeditor/src/screens/scenecomposer/tools/resizetool.h @@ -5,7 +5,7 @@ class ResizeTool : public SelectTool { public: - explicit ResizeTool(ObjectController *controller, EditorTool::SelectList &selection); + explicit ResizeTool(ObjectController *controller); void update(bool pivot, bool local, bool snap) override; diff --git a/worldeditor/src/screens/scenecomposer/tools/rotatetool.cpp b/worldeditor/src/screens/scenecomposer/tools/rotatetool.cpp index f87e048a8..2c8287ed6 100644 --- a/worldeditor/src/screens/scenecomposer/tools/rotatetool.cpp +++ b/worldeditor/src/screens/scenecomposer/tools/rotatetool.cpp @@ -8,8 +8,8 @@ #include "../objectcontroller.h" -RotateTool::RotateTool(ObjectController *controller, SelectList &selection) : - SelectTool(controller, selection) { +RotateTool::RotateTool(ObjectController *controller) : + SelectTool(controller) { m_snap = 5.0f; } @@ -21,7 +21,7 @@ void RotateTool::update(bool pivot, bool local, bool snap) { m_position = objectPosition(); } - EditorTool::Select &sel = m_selected.back(); + SelectTool::Select &sel = m_controller->selectList().back(); float angle = Handles::rotationTool(m_position, local ? sel.quat : Quaternion(), m_controller->isDrag()); if(m_snap > 0) { @@ -31,7 +31,7 @@ void RotateTool::update(bool pivot, bool local, bool snap) { if(m_controller->isDrag()) { QSet scenes; - for(const auto &it : qAsConst(m_selected)) { + for(const auto &it : qAsConst(m_controller->selectList())) { Transform *tr = it.object->transform(); Matrix4 parent; if(tr->parentTransform()) { diff --git a/worldeditor/src/screens/scenecomposer/tools/rotatetool.h b/worldeditor/src/screens/scenecomposer/tools/rotatetool.h index a7950992a..d16bac639 100644 --- a/worldeditor/src/screens/scenecomposer/tools/rotatetool.h +++ b/worldeditor/src/screens/scenecomposer/tools/rotatetool.h @@ -5,7 +5,7 @@ class RotateTool : public SelectTool { public: - explicit RotateTool(ObjectController *controller, EditorTool::SelectList &selection); + explicit RotateTool(ObjectController *controller); void update(bool pivot, bool local, bool snap) override; diff --git a/worldeditor/src/screens/scenecomposer/tools/scaletool.cpp b/worldeditor/src/screens/scenecomposer/tools/scaletool.cpp index 56586dfae..3d72fb6c6 100644 --- a/worldeditor/src/screens/scenecomposer/tools/scaletool.cpp +++ b/worldeditor/src/screens/scenecomposer/tools/scaletool.cpp @@ -8,8 +8,8 @@ #include "../objectcontroller.h" -ScaleTool::ScaleTool(ObjectController *controller, SelectList &selection) : - SelectTool(controller, selection) { +ScaleTool::ScaleTool(ObjectController *controller) : + SelectTool(controller) { m_snap = 1.0f; } @@ -24,7 +24,7 @@ void ScaleTool::update(bool center, bool local, bool snap) { Handles::s_Axes = 0; } - Transform *t = m_selected.back().object->transform(); + Transform *t = m_controller->selectList().back().object->transform(); m_world = Handles::scaleTool(m_position, local ? t->worldQuaternion() : Quaternion(), isDrag); @@ -58,7 +58,7 @@ void ScaleTool::update(bool center, bool local, bool snap) { } QSet scenes; - for(const auto &it : qAsConst(m_selected)) { + for(const auto &it : qAsConst(m_controller->selectList())) { Transform *tr = it.object->transform(); Matrix4 parent; if(tr->parentTransform()) { diff --git a/worldeditor/src/screens/scenecomposer/tools/scaletool.h b/worldeditor/src/screens/scenecomposer/tools/scaletool.h index a12e35469..56f2a3d0b 100644 --- a/worldeditor/src/screens/scenecomposer/tools/scaletool.h +++ b/worldeditor/src/screens/scenecomposer/tools/scaletool.h @@ -5,7 +5,7 @@ class ScaleTool : public SelectTool { public: - explicit ScaleTool(ObjectController *controller, EditorTool::SelectList &selection); + explicit ScaleTool(ObjectController *controller); void update(bool center, bool local, bool snap) override; diff --git a/worldeditor/src/screens/scenecomposer/tools/selecttool.cpp b/worldeditor/src/screens/scenecomposer/tools/selecttool.cpp index bc2ef32da..d63f1a2ab 100644 --- a/worldeditor/src/screens/scenecomposer/tools/selecttool.cpp +++ b/worldeditor/src/screens/scenecomposer/tools/selecttool.cpp @@ -2,13 +2,14 @@ #include #include +#include #include #include "../objectcontroller.h" -SelectTool::SelectTool(ObjectController *controller, SelectList &selection) : - EditorTool(selection), +SelectTool::SelectTool(ObjectController *controller) : + EditorTool(), m_controller(controller) { } @@ -16,10 +17,55 @@ SelectTool::SelectTool(ObjectController *controller, SelectList &selection) : void SelectTool::beginControl() { EditorTool::beginControl(); + m_propertiesCache.clear(); + + for(auto &it : m_controller->selectList()) { + Transform *t = it.object->transform(); + it.position = t->position(); + it.scale = t->scale(); + it.euler = t->rotation(); + it.quat = t->quaternion(); + + VariantMap components; + for(auto &child : it.object->getChildren()) { + Component *component = dynamic_cast(child); + if(component) { + VariantMap properies; + const MetaObject *meta = component->metaObject(); + for(int i = 0; i < meta->propertyCount(); i++) { + MetaProperty property = meta->property(i); + properies[property.name()] = property.read(component); + } + components[std::to_string(component->uuid())] = properies; + } + } + m_propertiesCache.push_back(components); + } + m_position = objectPosition(); m_savedWorld = m_world; } +void SelectTool::cancelControl() { + auto cache = m_propertiesCache.begin(); + for(auto &it : m_controller->selectList()) { + VariantMap components = (*cache).toMap(); + for(auto &child : it.object->getChildren()) { + Component *component = dynamic_cast(child); + if(component) { + VariantMap properties = components[std::to_string(component->uuid())].toMap(); + const MetaObject *meta = component->metaObject(); + for(int i = 0; i < meta->propertyCount(); i++) { + MetaProperty property = meta->property(i); + property.write(component, properties[property.name()]); + } + } + } + + ++cache; + } +} + QString SelectTool::icon() const { return ":/Images/editor/Select.png"; } @@ -27,3 +73,42 @@ QString SelectTool::icon() const { QString SelectTool::name() const { return "Select"; } + +const VariantList &SelectTool::cache() const { + return m_propertiesCache; +} + +Vector3 SelectTool::objectPosition() { + if(m_controller->selectList().size() == 1) { + return m_controller->selectList().front().object->transform()->worldPosition(); + } + return objectBound().center; +} + +AABBox SelectTool::objectBound() { + AABBox result; + result.extent = Vector3(-1.0f); + if(!m_controller->selectList().empty()) { + bool first = true; + for(auto &it : m_controller->selectList()) { + if(it.renderable == nullptr) { + it.renderable = it.object->getComponent(); + } + if(it.renderable) { + if(first) { + result = it.renderable->bound(); + first = false; + } else { + result.encapsulate(it.renderable->bound()); + } + } else { + if(first) { + result.center = it.object->transform()->worldPosition(); + } else { + result.encapsulate(it.object->transform()->worldPosition()); + } + } + } + } + return result; +} diff --git a/worldeditor/src/screens/scenecomposer/tools/selecttool.h b/worldeditor/src/screens/scenecomposer/tools/selecttool.h index a0e4d0c9c..d574af6c3 100644 --- a/worldeditor/src/screens/scenecomposer/tools/selecttool.h +++ b/worldeditor/src/screens/scenecomposer/tools/selecttool.h @@ -4,17 +4,46 @@ #include "editor/editortool.h" class ObjectController; +class Renderable; class SelectTool : public EditorTool { public: - explicit SelectTool(ObjectController *controller, EditorTool::SelectList &selection); + struct Select { + bool operator==(const Select &left) { + return (uuid == left.uuid); + } + + uint32_t uuid = 0; + Actor *object = nullptr; + Renderable *renderable = nullptr; + + Vector3 position; + Vector3 scale; + Vector3 euler; + Vector3 pivot; + Quaternion quat; + AABBox box; + }; + + typedef QList