diff --git a/.gitignore b/.gitignore
index fb28b96924601b1a55edad83e2a5323ecc050cbe..ec0971f6f5d06b1361ef2579a1dcfca4b1bdbac9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -85,3 +85,4 @@ cmake-build-debug-wsl
 cmake-build-debug
 
 toolchains-v1
+.clang-format
diff --git a/source/arviz_godot/CMakeLists.txt b/source/arviz_godot/CMakeLists.txt
index 64ea209f1011129b957b1b8dd75736e4a66835fc..536e21af9e2ee0cc881da798b0a0c05c69063f24 100644
--- a/source/arviz_godot/CMakeLists.txt
+++ b/source/arviz_godot/CMakeLists.txt
@@ -3,7 +3,7 @@
 add_subdirectory(godot-cpp)
 
 # Godot compile flags are too strict for their own code???
-set(GODOT_COMPILE_FLAGS_OVERRIDE "-fPIC -g -Wwrite-strings")
+set(GODOT_COMPILE_FLAGS_OVERRIDE "-fPIC -g -w -Wwrite-strings")
 
 if(CMAKE_BUILD_TYPE MATCHES Debug)
     set(GODOT_COMPILE_FLAGS_OVERRIDE "${GODOT_COMPILE_FLAGS_OVERRIDE} -fno-omit-frame-pointer -O0")
diff --git a/source/arviz_godot/lib/CMakeLists.txt b/source/arviz_godot/lib/CMakeLists.txt
index c50c8469f422a2858960707b6e0590d1001dc6aa..b547b44e7a3ed568a76f1671ad6d6369f1d07ab7 100644
--- a/source/arviz_godot/lib/CMakeLists.txt
+++ b/source/arviz_godot/lib/CMakeLists.txt
@@ -246,7 +246,6 @@ armarx_add_library(arviz_godot
         ${SOURCES}
     HEADERS
         ${HEADERS}
-        ${GODOT_HEADERS}
     DEPENDENCIES
         ArmarXCore
         RobotAPICore
@@ -260,6 +259,12 @@ armarx_add_library(arviz_godot
 
 target_link_libraries(arviz_godot PRIVATE godot-cpp)
 
+foreach (lib godot-cpp)
+    get_target_property(lib_include_dirs ${lib} INTERFACE_INCLUDE_DIRECTORIES)
+    target_include_directories(arviz_godot SYSTEM PRIVATE ${lib_include_dirs})
+    target_link_libraries(arviz_godot PRIVATE ${lib})
+endforeach (lib)
+
 if(UseTest AND Catch2_FOUND)
     message(STATUS "Including Catch2 tests")
 
@@ -276,13 +281,6 @@ if(UseTest AND Catch2_FOUND)
     catch_discover_tests(tests)
 endif()
 
-target_include_directories(arviz_godot SYSTEM PUBLIC
-     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/godot-cpp/include>
-     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/godot-cpp/include/core>
-     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/godot-cpp/include/gen>
-     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/godot-cpp/godot-headers>
-    )
-
 if(UseTest)
     target_compile_definitions(arviz_godot PRIVATE AVI_TEST_MAIN)
 
diff --git a/source/arviz_godot/lib/avi/app/ApplicationSettings.h b/source/arviz_godot/lib/avi/app/ApplicationSettings.h
index 1082dc09d045380881ae1599df7690bddaa97f2a..89812d5e3abf2e59c9a2c493738f5953bfc95aee 100644
--- a/source/arviz_godot/lib/avi/app/ApplicationSettings.h
+++ b/source/arviz_godot/lib/avi/app/ApplicationSettings.h
@@ -9,6 +9,7 @@ namespace avi::app
     {
     public:
         explicit ApplicationSettings(avi::core::Settings settings);
+        ~ApplicationSettings() override = default;
 
         [[nodiscard]] const std::string& getStorageIdentifier() const override;
 
diff --git a/source/arviz_godot/lib/avi/app/ArVizInteractive.cpp b/source/arviz_godot/lib/avi/app/ArVizInteractive.cpp
index af09f93b39ffe97f5df81285e194617dca990594..38719142f9b8746f42261fcf9cb7cbad03fd6baa 100644
--- a/source/arviz_godot/lib/avi/app/ArVizInteractive.cpp
+++ b/source/arviz_godot/lib/avi/app/ArVizInteractive.cpp
@@ -2,19 +2,13 @@
 
 namespace avi::app
 {
-    const std::string ArVizInteractive::defaultName = "arviz_interactive";
-    std::string ArVizInteractive::storageName = "";
+    std::string ArVizInteractive::storageName;
+    std::string ArVizInteractive::defaultName;
 
     std::string
     ArVizInteractive::getDefaultName() const
     {
-        return ArVizInteractive::defaultName;
-    }
-
-    std::string
-    ArVizInteractive::GetDefaultName()
-    {
-        return ArVizInteractive::defaultName;
+        return defaultName;
     }
 
     ArVizInteractive*
@@ -25,10 +19,8 @@ namespace avi::app
         IceUtil::Handle<ArVizInteractiveApp> app(new ArVizInteractiveApp());
         armarx::Application::setInstance(app);
 
-        app->appConfigDomain = "ArmarX";
-        app->appConfigName = "";
         app->enableLibLoading(false);
-        app->setName(GetDefaultName());
+        app->setName("arviz_godot");
         app->storeCommandLineArguments(0, nullptr);
 
         std::thread thread(
@@ -108,9 +100,25 @@ namespace avi::app
         const armarx::ManagedIceObjectRegistryInterfacePtr& registry,
         Ice::PropertiesPtr properties)
     {
-        component = armarx::Component::create<avi::app::ArVizInteractive>(
-            properties, appConfigName, appConfigDomain);
-        registry->addObject(component);
+        std::string namePrefix = "arviz_interactive";
+        size_t tryCount = 0;
+        bool done = false;
+
+        while (not done)
+        {
+            try
+            {
+                defaultName = tryCount > 0 ? namePrefix + std::to_string(tryCount) : namePrefix;
+                component = armarx::Component::create<avi::app::ArVizInteractive>(properties);
+
+                registry->addObject(component);
+                done = true;
+            }
+            catch (Ice::AlreadyRegisteredException& e)
+            {
+                tryCount++;
+            }
+        }
 
         component->app = this;
         setupDone = true;
diff --git a/source/arviz_godot/lib/avi/app/ArVizInteractive.h b/source/arviz_godot/lib/avi/app/ArVizInteractive.h
index 52d6373dff9f2612b90468d1740941b63ed56f3a..dcacad3e44d77ec50c7c394e80e7868cb5feefaa 100644
--- a/source/arviz_godot/lib/avi/app/ArVizInteractive.h
+++ b/source/arviz_godot/lib/avi/app/ArVizInteractive.h
@@ -22,22 +22,13 @@ namespace avi::app
             ArVizInteractiveInterface
     {
     public:
-        /// @see armarx::ManagedIceObject::getDefaultName()
-        std::string getDefaultName() const override;
 
-        /// Get the component's default name.
-        static std::string GetDefaultName();
+        ~ArVizInteractive() override = default;
+
+        std::string getDefaultName() const override;
 
-        /**
-			 * Initialize the component.
-			 * @return The initialized component.
-			 */
         static ArVizInteractive* Initialize(avi::app::ApplicationSettings& settings);
 
-        /**
-			 * Get whether the component is connected.
-			 * @return True if the component is connected, false otherwise.
-			 */
         bool isConnected() const override;
 
         armarx::viz::StorageInterfacePrx getStorageInterface() const override;
@@ -45,19 +36,11 @@ namespace avi::app
         void close();
 
     protected:
-        /// @see PropertyUser::createPropertyDefinitions()
         armarx::PropertyDefinitionsPtr createPropertyDefinitions() override;
 
-        /// @see armarx::ManagedIceObject::onInitComponent()
         void onInitComponent() override;
-
-        /// @see armarx::ManagedIceObject::onConnectComponent()
         void onConnectComponent() override;
-
-        /// @see armarx::ManagedIceObject::onDisconnectComponent()
         void onDisconnectComponent() override;
-
-        /// @see armarx::ManagedIceObject::onExitComponent()
         void onExitComponent() override;
 
     private:
@@ -72,17 +55,14 @@ namespace avi::app
             std::condition_variable condition{};
             std::thread thread;
 
-            std::string appConfigDomain;
-            std::string appConfigName;
-
             bool setupDone{false};
             IceInternal::Handle<avi::app::ArVizInteractive> component{};
 
             int exec(const armarx::ArmarXManagerPtr& armarXManager) override;
         };
 
-        static const std::string defaultName;
         static std::string storageName;
+        static std::string defaultName;
 
         armarx::viz::StorageInterfacePrx storage{};
         IceUtil::Handle<ArVizInteractiveApp> app{};
diff --git a/source/arviz_godot/lib/avi/app/EventList.h b/source/arviz_godot/lib/avi/app/EventList.h
index a34ea6f41885c785543f5efb18483b78929ac8c9..00b637e649e813b3129246a4e3a4b0775e487db3 100644
--- a/source/arviz_godot/lib/avi/app/EventList.h
+++ b/source/arviz_godot/lib/avi/app/EventList.h
@@ -13,6 +13,8 @@ namespace avi::app
         public avi::core::EventInvokingSystem
     {
     public:
+        ~EventList() override = default;
+
         void subscribe(std::string event, std::function<void()> callback) override;
 
         void invoke(const std::string& event) override;
diff --git a/source/arviz_godot/lib/avi/app/KeyInputEventDispatch.cpp b/source/arviz_godot/lib/avi/app/KeyInputEventDispatch.cpp
index 6c670e37f7757e8753b5b4b2a33d1221d7de104a..15fb47335d7be2edbd4e21334d226bbf8ed8a425 100644
--- a/source/arviz_godot/lib/avi/app/KeyInputEventDispatch.cpp
+++ b/source/arviz_godot/lib/avi/app/KeyInputEventDispatch.cpp
@@ -46,4 +46,9 @@ avi::app::KeyInputEventDispatch::_unhandled_input(godot::InputEvent* event)
         events->invoke("MANIPULATOR_ROTATE");
     if (event->is_action_pressed("avi_manipulator_scale"))
         events->invoke("MANIPULATOR_SCALE");
+
+    if (event->is_action_pressed("avi_camera_technical"))
+        events->invoke("CAMERA_TECHNICAL");
+    if (event->is_action_pressed("avi_camera_playful"))
+        events->invoke("CAMERA_PLAYFUL");
 }
diff --git a/source/arviz_godot/lib/avi/app/KeyInputEventDispatch.h b/source/arviz_godot/lib/avi/app/KeyInputEventDispatch.h
index 6e9ddcb94630b47b52f08de227f20e36cf74c4cd..3a4aa95c4008190b6da572dbd552df3bd39087da 100644
--- a/source/arviz_godot/lib/avi/app/KeyInputEventDispatch.h
+++ b/source/arviz_godot/lib/avi/app/KeyInputEventDispatch.h
@@ -11,6 +11,8 @@ namespace avi::app
         GODOT_CLASS(KeyInputEventDispatch, Node)
 
     public:
+        virtual ~KeyInputEventDispatch() = default;
+
         static void _register_methods();
 
         void _init();
@@ -20,6 +22,6 @@ namespace avi::app
         void hookup(avi::core::EventInvokingSystem& events);
 
     private:
-        avi::core::EventInvokingSystem* events;
+        avi::core::EventInvokingSystem* events = nullptr;
     };
 } // namespace avi::app
diff --git a/source/arviz_godot/lib/avi/app/Main.h b/source/arviz_godot/lib/avi/app/Main.h
index 979add64e2e9c8160781268fdf3b71f3508e2e87..f57c40c0db2c1179b3a97a16cac61311cf491d2e 100644
--- a/source/arviz_godot/lib/avi/app/Main.h
+++ b/source/arviz_godot/lib/avi/app/Main.h
@@ -24,6 +24,8 @@ namespace avi::app
         GODOT_CLASS(Main, Node)
 
     public:
+        virtual ~Main() = default;
+
         static void _register_methods();
 
         void _init();
diff --git a/source/arviz_godot/lib/avi/connection/ElementStorage.h b/source/arviz_godot/lib/avi/connection/ElementStorage.h
index 45dd0cf1279d8e82915cc1e145a7a39ffe3673f3..ff00e65f19d9b0167198db6b6fd6704ec58a03ce 100644
--- a/source/arviz_godot/lib/avi/connection/ElementStorage.h
+++ b/source/arviz_godot/lib/avi/connection/ElementStorage.h
@@ -19,6 +19,7 @@ namespace avi::connection
     {
     public:
         explicit ElementStorage(avi::connection::Component& component);
+        ~ElementStorage() override = default;
 
         armarx::viz::data::LayerUpdates getNext() override;
 
diff --git a/source/arviz_godot/lib/avi/connection/MockStorage.cpp b/source/arviz_godot/lib/avi/connection/MockStorage.cpp
index 845d7845d338a65c522f419ae826aa7af1df77ab..787ae8c90cb6e31593edf718c130efdf1e2598b5 100644
--- a/source/arviz_godot/lib/avi/connection/MockStorage.cpp
+++ b/source/arviz_godot/lib/avi/connection/MockStorage.cpp
@@ -13,253 +13,42 @@ avi::connection::MockStorage::getNext()
     layerUpdate.name = "Layer 1";
     layerUpdate.action = armarx::viz::data::Layer_CREATE_OR_UPDATE;
 
-    IceUtil::Handle<armarx::viz::data::ElementBox> element(new armarx::viz::data::ElementBox());
-    element->id = "Box";
-    element->size = {100, 100, 100};
-    element->pose = {0, 0, 0, 0, 0.3826834, 0, 0.9238795};
-    setStandardParameter(element, element->id);
-    element->color = {255, 0, 0, 255};
+    IceUtil::Handle<armarx::viz::data::ElementBox> elementBig(new armarx::viz::data::ElementBox());
+    elementBig->id = "BoxBig";
+    elementBig->size = {1000, 1000, 1000};
+    elementBig->pose = {0, 0, 0, 0, 0.3826834, 0, 0.9238795};
+    setStandardParameter(elementBig, elementBig->id);
+    elementBig->color = {255, 0, 0, 255};
 
-    IceUtil::Handle<armarx::viz::data::ElementBox> elementNoInteraction(
-        new armarx::viz::data::ElementBox());
-    elementNoInteraction->id = "BoxNoInteraction";
-    elementNoInteraction->size = {100, 100, 100};
-    elementNoInteraction->scale = {1, 1, 1};
-    elementNoInteraction->pose = {0, 0, -500, 0, 0, 0, 1};
-    elementNoInteraction->color = {255, 50, 100, 255};
-    elementNoInteraction->interaction.enableFlags = armarx::viz::data::InteractionEnableFlags::NONE;
 
-    IceUtil::Handle<armarx::viz::data::ElementSphere> elementSphereNoInteraction(
-        new armarx::viz::data::ElementSphere());
-    elementSphereNoInteraction->id = "SphereNoInteraction";
-    elementSphereNoInteraction->scale = {1, 1, 1};
-    elementSphereNoInteraction->radius = 300;
-    elementSphereNoInteraction->pose = {500, 500, -500, 0, 0, 0, 1};
-    elementSphereNoInteraction->color = {155, 250, 100, 100};
-    elementSphereNoInteraction->interaction.enableFlags =
-        armarx::viz::data::InteractionEnableFlags::NONE;
+    IceUtil::Handle<armarx::viz::data::ElementBox> elementSmall(new armarx::viz::data::ElementBox());
+    elementSmall->id = "BoxSmall";
+    elementSmall->size = {1, 1, 1};
+    elementSmall->pose = {0, 0, 0, 0, 0.3826834, 0, 0.9238795};
+    setStandardParameter(elementSmall, elementSmall->id);
+    elementSmall->color = {255, 255, 0, 0};
 
-    IceUtil::Handle<armarx::viz::data::ElementBox> elementLocalFlags(
-        new armarx::viz::data::ElementBox());
-    elementLocalFlags->id = "BoxLocal";
-    elementLocalFlags->size = {100, 100, 100};
-    elementLocalFlags->pose = {500, 0, 0, 0, 0, 0, 1};
-    elementLocalFlags->interaction.enableFlags =
-        armarx::viz::data::InteractionEnableFlags::SELECT |
-        armarx::viz::data::InteractionEnableFlags::CONTEXT_MENU |
-        armarx::viz::data::InteractionEnableFlags::ROTATION_LOCAL |
-        armarx::viz::data::InteractionEnableFlags::TRANSLATION_LOCAL |
-        armarx::viz::data::InteractionEnableFlags::SCALING_LOCAL;
-    setStandardParameter(elementLocalFlags, elementLocalFlags->id);
-    elementLocalFlags->interaction.contextMenuOptions = {elementLocalFlags->id,
-                                                         "flags:",
-                                                         "SELECT",
-                                                         "CONTEXT_MENU",
-                                                         "ROTATION_LOCAL",
-                                                         "TRANSLATION_LOCAL",
-                                                         "SCALING_LOCAL",
-                                                         "this element uses local manipulation"};
 
-    IceUtil::Handle<armarx::viz::data::ElementBox> elementTransformHide(
-        new armarx::viz::data::ElementBox());
-    elementTransformHide->id = "BoxTransformHide";
-    elementTransformHide->size = {100, 100, 100};
-    elementTransformHide->pose = {-500, 0, 0, 0, 0.3826834, 0, 0.9238795};
-    elementTransformHide->interaction.enableFlags =
-        armarx::viz::data::InteractionEnableFlags::TRANSFORM_HIDE |
-        armarx::viz::data::InteractionEnableFlags::ROTATION_LOCAL |
-        armarx::viz::data::InteractionEnableFlags::TRANSLATION_LOCAL |
-        armarx::viz::data::InteractionEnableFlags::SCALING_LOCAL;
-    setStandardParameter(elementTransformHide, elementTransformHide->id);
-    elementTransformHide->interaction.contextMenuOptions = {
-        elementTransformHide->id,
-        "flags:",
-        "SELECT",
-        "CONTEXT_MENU",
-        "TRANSFORM_HIDE",
-        "when manipulating this element should only show the ghost"};
-    elementTransformHide->color = {255, 0, 255, 0};
-
-    IceUtil::Handle<armarx::viz::data::ElementSphere> sphere(
-        new armarx::viz::data::ElementSphere());
-    sphere->id = "Sphere";
-    sphere->radius = 100;
-    sphere->pose = {0, 500, 0, 0, 0, 0, 1};
-    setStandardParameter(sphere, sphere->id);
 
     IceUtil::Handle<armarx::viz::data::ElementArrow> elementArrow(
-        new armarx::viz::data::ElementArrow);
+            new armarx::viz::data::ElementArrow);
     elementArrow->id = "elementArrow";
     elementArrow->length = 250;
     elementArrow->pose = {500, 500, 0, 0, 0, 0, 1};
     setStandardParameter(elementArrow, elementArrow->id);
 
-    IceUtil::Handle<armarx::viz::data::ElementArrowCircle> elementArrowCircle(
-        new armarx::viz::data::ElementArrowCircle);
-    elementArrowCircle->id = "elementArrowCircle";
-    elementArrowCircle->radius = 200;
-    elementArrowCircle->completion = 0.8;
-    elementArrowCircle->pose = {-500, 500, 0, 0, 90, 90, 1};
-    setStandardParameter(elementArrowCircle, elementArrowCircle->id);
-
-    IceUtil::Handle<armarx::viz::data::ElementCylinder> elementCylinder(
-        new armarx::viz::data::ElementCylinder);
-    elementCylinder->id = "elementCylinder";
-    elementCylinder->radius = 100;
-    elementCylinder->height = 200;
-    elementCylinder->pose = {-500, -500, 0, 0, 0, 0, 1};
-    setStandardParameter(elementCylinder, elementCylinder->id);
-
-    IceUtil::Handle<armarx::viz::data::ElementCylindroid> elementCylindroid(
-        new armarx::viz::data::ElementCylindroid);
-    elementCylindroid->id = "elementCylindroid";
-    elementCylindroid->axisLengths = {100, 200}; //maybe not correct
-    elementCylindroid->height = 100;
-    elementCylindroid->pose = {500, -500, 0, 0, 0, 0, 1};
-    setStandardParameter(elementCylindroid, elementCylindroid->id);
-    elementCylindroid->scale = {100, 1, 50};
-
-    IceUtil::Handle<armarx::viz::data::ElementEllipsoid> elementEllipsoid(
-        new armarx::viz::data::ElementEllipsoid);
-    elementEllipsoid->id = "elementEllipsoid";
-    elementEllipsoid->axisLengths = {100, 150, 200};
-    elementEllipsoid->pose = {0, -500, 0, 0, 0, 0, 1};
-    setStandardParameter(elementEllipsoid, elementEllipsoid->id);
-
-    IceUtil::Handle<armarx::viz::data::ElementLine> elementLine(new armarx::viz::data::ElementLine);
-    elementLine->id = "elementLine";
-
-    elementLine->lineWidth = 50;
-    elementLine->from = {1000, 0, 1000};
-    elementLine->to = {1000, 0, 0};
-    elementLine->scale = {50, 50, 50};
-    elementLine->pose = {0, 1000, 0, 0, 0, 0, 1};
-    setStandardParameter(elementLine, elementLine->id);
-
-    IceUtil::Handle<armarx::viz::data::ElementMesh> elementMesh(new armarx::viz::data::ElementMesh);
-    elementMesh->id = "elementMesh";
-    armarx::viz::data::Face face1;
-    face1.v0 = 0;
-    face1.v1 = 1;
-    face1.v2 = 2;
-    face1.c0 = 0;
-    face1.c1 = 0;
-    face1.c2 = 0;
-    armarx::viz::data::Face face2;
-    face2.v0 = 0;
-    face2.v1 = 1;
-    face2.v2 = 3;
-    face2.c0 = 0;
-    face2.c1 = 0;
-    face2.c2 = 0;
-    armarx::viz::data::Face face3;
-    face3.v0 = 1;
-    face3.v1 = 2;
-    face3.v2 = 3;
-    face3.c0 = 0;
-    face3.c1 = 0;
-    face3.c2 = 0;
-    armarx::viz::data::Face face4;
-    face4.v0 = 2;
-    face4.v1 = 0;
-    face4.v2 = 3;
-    face4.c0 = 0;
-    face4.c1 = 0;
-    face4.c2 = 0;
-    elementMesh->faces = {face1, face2, face3, face4};
-    elementMesh->vertices = {{0, 0, 0},
-                             {0, 0, 1000},
-                             {
-                                 0,
-                                 1000,
-                                 0,
-                             },
-                             {1000, 500, 500}};
-    elementMesh->colors = {{255, 255, 0, 0}};
-    elementMesh->scale = {50, 50, 50};
-    elementMesh->pose = {-2000, 0, 0, 0, 0, 0, 1};
-    setStandardParameter(elementMesh, elementMesh->id);
-
-    IceUtil::Handle<armarx::viz::data::ElementPath> elementPath(new armarx::viz::data::ElementPath);
-    elementPath->id = "elementPath";
-    elementPath->lineWidth = 50;
-    elementPath->points = {{0, 0, 0}, {1000, 1000, 1000}, {500, 500, -500}};
-    elementPath->scale = {50, 50, 50};
-    elementPath->pose = {0, -500, 0, 0, 0, 0, 1};
-    setStandardParameter(elementPath, elementPath->id);
-
-    IceUtil::Handle<armarx::viz::data::ElementPointCloud> elementPointCloud(
-        new armarx::viz::data::ElementPointCloud);
-    elementPointCloud->id = "elementPointCloud";
-    elementPointCloud->pointSizeInPixels = 10;
-    elementPointCloud->pose = {0, 0, 0, 0, 0, 0, 1};
-    elementPointCloud->pose = {0, 0, 500, 0, 0, 0, 0};
-    armarx::viz::data::ColoredPoint colored_point;
-
-    colored_point.x = 10;
-    colored_point.y = 10;
-    colored_point.z = 10;
-    elementPointCloud->points = {0, 0x1, 0x2, 0xaf};
-    setStandardParameter(elementPointCloud, elementPointCloud->id);
-
-    IceUtil::Handle<armarx::viz::data::ElementPolygon> elementPolygon(
-        new armarx::viz::data::ElementPolygon);
-    elementPolygon->id = "elementPolygon";
-    elementPolygon->points = {{0, 0, 0}, {500, 500, 500}, {-500, 500, 500}};
-    elementPolygon->pose = {0, 1500, 0, 0, 0, 0, 1};
-    setStandardParameter(elementPolygon, elementPolygon->id);
-
-    IceUtil::Handle<armarx::viz::data::ElementObject> elementObject(
-        new armarx::viz::data::ElementObject);
-    elementObject->id = " elementObject";
-    elementObject->filename = "res://models/pose.obj";
-    elementObject->drawStyle = 0;
-    elementObject->pose = {1500, 1500, 0, 0, 0, 0, 1};
-    setStandardParameter(elementObject, elementObject->id);
-
-    IceUtil::Handle<armarx::viz::data::ElementPose> elementPose(new armarx::viz::data::ElementPose);
-    elementPose->id = "elementPose";
-    elementPose->pose = {-1000, 0, 0, 0, 0, 0, 1};
-    setStandardParameter(elementPose, elementPose->id);
-
-    IceUtil::Handle<armarx::viz::data::ElementRobot> elementRobot(
-        new armarx::viz::data::ElementRobot);
-    elementRobot->id = "elementRobot";
-    elementRobot->pose = {0, 1000, 0, 0, 0, 0, 1};
-    setStandardParameter(elementRobot, elementRobot->id);
-
-    IceUtil::Handle<armarx::viz::data::ElementText> elementText(new armarx::viz::data::ElementText);
-    elementText->id = "elementText";
-    elementText->text = "Hello World";
-    elementText->pose = {1000, -1000, 0, 0, 0, 0, 1};
-    setStandardParameter(elementText, elementText->id);
-    elementText->scale = {25, 25, 25};
-
-    IceUtil::Handle<armarx::viz::data::ElementText> elementTextRotated(
-        new armarx::viz::data::ElementText);
-    elementTextRotated->id = "elementTextRotated";
-    elementTextRotated->text = "ArViz Interactive";
-    elementTextRotated->pose = {-2000, 3000, 5000, 90, 0, 70, 1};
-    setStandardParameter(elementTextRotated, elementTextRotated->id);
-    elementTextRotated->scale = {15, 15, 15};
+    IceUtil::Handle<armarx::viz::data::ElementArrow> elementArrowSmall(
+            new armarx::viz::data::ElementArrow);
+    elementArrowSmall->id = "elementArrowSmall";
+    elementArrowSmall->length = 50;
+    elementArrowSmall->pose = {0, 0, 0, 0, 0, 0, 1};
+    setStandardParameter(elementArrowSmall, elementArrowSmall->id);
+    elementArrowSmall->scale = {0.1,0.1,0.1};
 
-    layerUpdate.elements.push_back(element);
-    layerUpdate.elements.push_back(elementLocalFlags);
-    layerUpdate.elements.push_back(elementTransformHide);
-    layerUpdate.elements.push_back(sphere);
+    //layerUpdate.elements.push_back(elementBig);
+    //layerUpdate.elements.push_back(elementSmall);
     layerUpdate.elements.push_back(elementArrow);
-    layerUpdate.elements.push_back(elementArrowCircle);
-    layerUpdate.elements.push_back(elementCylinder);
-    layerUpdate.elements.push_back(elementCylindroid);
-    layerUpdate.elements.push_back(elementEllipsoid);
-    layerUpdate.elements.push_back(elementMesh);
-    layerUpdate.elements.push_back(elementPolygon);
-    layerUpdate.elements.push_back(elementObject);
-    layerUpdate.elements.push_back(elementPose);
-    layerUpdate.elements.push_back(elementText);
-    layerUpdate.elements.push_back(elementTextRotated);
-    layerUpdate.elements.push_back(elementNoInteraction);
-    layerUpdate.elements.push_back(elementSphereNoInteraction);
+    layerUpdate.elements.push_back(elementArrowSmall);
 
     layerUpdates.updates.push_back(layerUpdate);
     return layerUpdates;
diff --git a/source/arviz_godot/lib/avi/connection/MockStorage.h b/source/arviz_godot/lib/avi/connection/MockStorage.h
index e0a758e39fe6a8479cb3d0edaee9199197c78cc5..6e2257c0a630e34df052358062053a5713210a2b 100644
--- a/source/arviz_godot/lib/avi/connection/MockStorage.h
+++ b/source/arviz_godot/lib/avi/connection/MockStorage.h
@@ -17,6 +17,7 @@ namespace avi::connection
 
     public:
         MockStorage();
+        ~MockStorage() override = default;
 
         armarx::viz::data::LayerUpdates getNext() override;
 
diff --git a/source/arviz_godot/lib/avi/core/Element.h b/source/arviz_godot/lib/avi/core/Element.h
index 7d049029969015b7d538c3ccef0c7bef931952ed..3d46e868ba47582363f35e8c38888886ca136014 100644
--- a/source/arviz_godot/lib/avi/core/Element.h
+++ b/source/arviz_godot/lib/avi/core/Element.h
@@ -13,6 +13,8 @@ namespace avi::core
     class Element
     {
     public:
+        virtual ~Element() = default;
+
         virtual avi::connection::SentElementType getType() = 0;
 
         virtual std::string getName() = 0;
diff --git a/source/arviz_godot/lib/avi/core/EventInvokingSystem.h b/source/arviz_godot/lib/avi/core/EventInvokingSystem.h
index 0dc24ea626bfe55800de2913fed7785943ec7bb1..d224f681b2530fe8bac5a63cc2d6fe257f0acd08 100644
--- a/source/arviz_godot/lib/avi/core/EventInvokingSystem.h
+++ b/source/arviz_godot/lib/avi/core/EventInvokingSystem.h
@@ -1,5 +1,7 @@
 #pragma once
 
+#include <string>
+
 namespace avi::core
 {
     class EventInvokingSystem
diff --git a/source/arviz_godot/lib/avi/core/Layer.h b/source/arviz_godot/lib/avi/core/Layer.h
index 50ea32ab7db657a15dabc558eb8fba7bc2f25f7e..55fe2af6d0d8ebbddfdd52bddac318ee971d80b0 100644
--- a/source/arviz_godot/lib/avi/core/Layer.h
+++ b/source/arviz_godot/lib/avi/core/Layer.h
@@ -1,5 +1,7 @@
 #pragma once
 
+#include <string>
+
 namespace avi::core
 {
     class Layer
diff --git a/source/arviz_godot/lib/avi/core/ModelLoader.cpp b/source/arviz_godot/lib/avi/core/ModelLoader.cpp
index b6be703807d8fad419168279b356c33b7e6e769a..f66f0b19f59f95c2c965d578c9d397da8eb765d0 100644
--- a/source/arviz_godot/lib/avi/core/ModelLoader.cpp
+++ b/source/arviz_godot/lib/avi/core/ModelLoader.cpp
@@ -20,11 +20,9 @@
 #include <assimp/scene.h>
 
 avi::core::Object
-avi::core::ModelLoader::loadModel(std::string name)
+avi::core::ModelLoader::loadModel(const std::string& name, std::string& fullName)
 {
-
     std::string objectName = std::filesystem::path(name).filename().stem();
-    std::string fullName;
     armarx::ObjectFinder objectFinder;
 
     if (std::optional<armarx::ObjectInfo> info = objectFinder.findObject("", objectName))
@@ -42,74 +40,92 @@ avi::core::ModelLoader::loadModel(std::string name)
     return returnObject;
 }
 
-
 godot::Mesh* convertMesh(
         const aiMesh* aiMesh,
         const std::string& name
         )
 {
-    (void) name;  // Can be used for debugging.
+    (void)name; // Can be used for debugging.
 
     bool hasNormals = aiMesh->HasNormals();
     bool hasTexture = aiMesh->HasTextureCoords(0);
     bool hasVertexColors = aiMesh->HasVertexColors(0);
 
     godot::PoolVector3Array coords;
+    coords.resize(aiMesh->mNumFaces * 3);
+    godot::Vector3* coordsPtr = coords.write().ptr();
+
     godot::PoolVector3Array normals;
+    normals.resize(aiMesh->mNumFaces * 3);
+    godot::Vector3* normalsPtr = normals.write().ptr();
+
     godot::PoolVector2Array textureCoords;
+    if (hasTexture)
+    {
+        textureCoords.resize(aiMesh->mNumFaces * 3);
+    }
+    godot::Vector2* texturesPtr = textureCoords.write().ptr();
+
     godot::PoolColorArray colorArray;
+    if (hasVertexColors)
+    {
+        colorArray.resize(aiMesh->mNumVertices);
+    }
+    godot::Color* colorsPtr = colorArray.write().ptr();
 
     for (size_t i = 0; i < aiMesh->mNumFaces; i++)
     {
         aiFace& face = aiMesh->mFaces[i];
+        size_t v = i * 3;
 
         aiVector3t<float>* vertex;
         vertex = &aiMesh->mVertices[face.mIndices[2]];
-        coords.push_back(godot::Vector3(vertex->x, vertex->y, vertex->z));
+        coordsPtr[v + 0] = godot::Vector3(vertex->x, vertex->y, vertex->z);
         vertex = &aiMesh->mVertices[face.mIndices[1]];
-        coords.push_back(godot::Vector3(vertex->x, vertex->y, vertex->z));
+        coordsPtr[v + 1] = godot::Vector3(vertex->x, vertex->y, vertex->z);
         vertex = &aiMesh->mVertices[face.mIndices[0]];
-        coords.push_back(godot::Vector3(vertex->x, vertex->y, vertex->z));
+        coordsPtr[v + 2] = godot::Vector3(vertex->x, vertex->y, vertex->z);
 
         if (hasNormals)
         {
             aiVector3D* normal;
             normal = &aiMesh->mNormals[face.mIndices[2]];
-            normals.push_back(godot::Vector3(normal->x, normal->y, normal->z));
+            normalsPtr[v + 0] = godot::Vector3(normal->x, normal->y, normal->z);
             normal = &aiMesh->mNormals[face.mIndices[1]];
-            normals.push_back(godot::Vector3(normal->x, normal->y, normal->z));
+            normalsPtr[v + 1] = godot::Vector3(normal->x, normal->y, normal->z);
             normal = &aiMesh->mNormals[face.mIndices[0]];
-            normals.push_back(godot::Vector3(normal->x, normal->y, normal->z));
+            normalsPtr[v + 2] = godot::Vector3(normal->x, normal->y, normal->z);
         }
         else
         {
             vertex = &aiMesh->mVertices[face.mIndices[0]];
             godot::Vector3 vertA { vertex->x, vertex->y, vertex->z };
             vertex = &aiMesh->mVertices[face.mIndices[1]];
-            godot::Vector3 vertB { vertex->x, vertex->y, vertex->z };
+            godot::Vector3 vertB{vertex->x, vertex->y, vertex->z};
             vertex = &aiMesh->mVertices[face.mIndices[2]];
-            godot::Vector3 vertC { vertex->x, vertex->y, vertex->z };
+            godot::Vector3 vertC{vertex->x, vertex->y, vertex->z};
 
-            // create orthogonal vector
-            godot::Vector3 vertAB { vertA.x - vertB.x, vertA.y - vertB.y, vertA.z - vertB.z };
+            godot::Vector3 vertAB{vertA.x - vertB.x, vertA.y - vertB.y, vertA.z - vertB.z};
             vertAB *= -1;
-            godot::Vector3 vertAC { vertA.x - vertC.x, vertA.y - vertC.y, vertA.z - vertC.z };
+            godot::Vector3 vertAC{vertA.x - vertC.x, vertA.y - vertC.y, vertA.z - vertC.z};
             vertAC *= -1;
             godot::Vector3 orth = godot::vec3_cross(vertAB, vertAC);
             orth.normalize();
-            normals.push_back(orth);
-            normals.push_back(orth);
-            normals.push_back(orth);
+
+            normalsPtr[v + 0] = orth;
+            normalsPtr[v + 1] = orth;
+            normalsPtr[v + 2] = orth;
         }
+
         if (hasTexture)
         {
             aiVector3D* texture;
             texture = &aiMesh->mTextureCoords[0][face.mIndices[2]];
-            textureCoords.push_back(godot::Vector2(texture->x, texture->y));
+            texturesPtr[v + 0] = godot::Vector2(texture->x, texture->y);
             texture = &aiMesh->mTextureCoords[0][face.mIndices[1]];
-            textureCoords.push_back(godot::Vector2(texture->x, texture->y));
+            texturesPtr[v + 1] = godot::Vector2(texture->x, texture->y);
             texture = &aiMesh->mTextureCoords[0][face.mIndices[0]];
-            textureCoords.push_back(godot::Vector2(texture->x, texture->y));
+            texturesPtr[v + 2] = godot::Vector2(texture->x, texture->y);
         }
     }
 
@@ -118,8 +134,8 @@ godot::Mesh* convertMesh(
         aiColor4D* color = aiMesh->mColors[0];
         for (size_t i = 0; i < aiMesh->mNumVertices; i++)
         {
-            colorArray.push_back(godot::Color(color->r, color->g, color->b));
-            color++;
+            aiColor4D current = color[i];
+            colorsPtr[i] = godot::Color(current.r, current.g, current.b);
         }
     }
 
@@ -183,14 +199,17 @@ godot::SpatialMaterial* convertMaterial(
             material->set_diffuse_mode(godot::SpatialMaterial::DIFFUSE_BURLEY);
         }
     }
+
     material->set_specular_mode(godot::SpatialMaterial::SPECULAR_SCHLICK_GGX);
     material->set_specular(1);
 
     aiString fileName;
+
     if (mat)
     {
         aiGetMaterialTexture(mat, aiTextureType_DIFFUSE, 0, &fileName);
     }
+
     if (fileName != aiString())
     {
         std::string filePath = path.parent_path() / fileName.C_Str();
@@ -203,17 +222,19 @@ godot::SpatialMaterial* convertMaterial(
 
         // get length of file
         fseek(file, 0, SEEK_END);
-        long length = ftell(file);
+        size_t length = ftell(file);
         rewind(file);
-        uint8_t buffer;
-        for (int i = 0; i < length; i++)
+        bytes.resize(length);
+        size_t read = fread(bytes.write().ptr(), 1, length, file);
+        fclose(file);
+
+        if (read != length)
         {
-            fread(&buffer, 1, 1, file);
-            bytes.push_back(buffer);
+            ARMARX_WARNING << "Failed to load image '" << filePath << "'";
         }
-        fclose(file);
 
         std::string imageExt = std::filesystem::path{filePath}.extension();
+
         if (imageExt == ".png")
         {
             image->load_png_from_buffer(bytes);
@@ -233,7 +254,7 @@ godot::SpatialMaterial* convertMaterial(
 
 
 avi::core::Object
-avi::core::ModelLoader::loadModelFromFile(std::string name)
+avi::core::ModelLoader::loadModelFromFile(const std::string& name)
 {
     if (cache.contains(name))
     {
@@ -249,8 +270,6 @@ avi::core::ModelLoader::loadModelFromFile(std::string name)
     std::filesystem::path path{fullName};
     const std::string ext = simox::alg::to_lower(path.extension());
 
-    std::shared_ptr<VirtualRobot::TriMeshModel> model;
-
     if (ext != ".obj")
     {
         fullName = path.replace_extension(".obj");
@@ -263,6 +282,11 @@ avi::core::ModelLoader::loadModelFromFile(std::string name)
         return loadModelFromNonObjFile(name);
     }
 
+    if (scene->mNumMeshes == 0)
+    {
+        ARMARX_DEBUG << "Loading empty object '" << name << "'.";
+    }
+
     Object object;
     for (size_t i = 0; i < scene->mNumMeshes; ++i)
     {
@@ -278,7 +302,6 @@ avi::core::ModelLoader::loadModelFromFile(std::string name)
             return error;
         }
     }
-
     cache.emplace(name, object);
     return object;
 }
@@ -303,34 +326,27 @@ avi::core::ModelLoader::ModelLoader() :
 }
 
 avi::core::Object
-avi::core::ModelLoader::loadModelFromNonObjFile(std::string name)
+avi::core::ModelLoader::loadModelFromNonObjFile(const std::string& name)
 {
     std::string fullName = name;
     std::filesystem::path path{fullName};
     const std::string ext = simox::alg::to_lower(path.extension());
-    std::shared_ptr<VirtualRobot::TriMeshModel> model;
-    if (ext == ".xml" || ext == ".moxml")
-    {
-        VirtualRobot::ManipulationObjectPtr visPointer =
-            VirtualRobot::ObjectIO::loadManipulationObject(fullName);
-        model = visPointer->getVisualization()->getTriMeshModel();
-    }
-    else if (ext == ".wrl" || ext == ".iv")
-    {
-        VirtualRobot::VisualizationFactoryPtr factory =
-            VirtualRobot::VisualizationFactory::fromName("inventor", nullptr);
-        VirtualRobot::VisualizationNodePtr vis = factory->getVisualizationFromFile(fullName);
-        VirtualRobot::ManipulationObjectPtr visPointer =
-            VirtualRobot::ManipulationObjectPtr(new VirtualRobot::ManipulationObject(name, vis));
-        model = visPointer->getVisualization()->getTriMeshModel();
-    }
+
+    VirtualRobot::ManipulationObjectPtr object = getObject(name);
+    VirtualRobot::TriMeshModelPtr model = object ? object->getVisualization()->getTriMeshModel() : nullptr;
 
     if (!model)
     {
-        ARMARX_WARNING << "Error loading mesh" << name;
+        ARMARX_WARNING << "Error loading mesh: '" << name << "'";
         return error;
     }
 
+    return createObjectFromTriMesh(model);
+}
+
+avi::core::Object
+avi::core::ModelLoader::createObjectFromTriMesh(std::shared_ptr<VirtualRobot::TriMeshModel> model)
+{
     model->scale(1.0f / avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR);
     avi::core::Object returnObject;
     godot::ArrayMesh* mesh = godot::ArrayMesh::_new();
@@ -359,7 +375,7 @@ avi::core::ModelLoader::loadModelFromNonObjFile(std::string name)
         normals.push_back(godot::Vector3(normal->x(), normal->y(), normal->z()));
         normals.push_back(godot::Vector3(normal->x(), normal->y(), normal->z()));
 
-        if (model->materials.size() > 0)
+        if (!model->materials.empty())
         {
             color = &model->materials[face.idMaterial].diffuse;
             colorGd = godot::Color(color->r, color->g, color->b, color->transparency);
@@ -393,3 +409,32 @@ avi::core::ModelLoader::loadModelFromNonObjFile(std::string name)
     returnMesh.material = material;
     return returnObject;
 }
+
+VirtualRobot::ManipulationObjectPtr avi::core::ModelLoader::getObject(const std::string& name)
+{
+    std::filesystem::path path{name};
+    const std::string ext = simox::alg::to_lower(path.extension());
+
+    if (not std::filesystem::exists(path))
+    {
+        return nullptr; // Apparently the methods below do not return null when the file does not exist.
+    }
+
+    if (ext == ".xml" || ext == ".moxml")
+    {
+        VirtualRobot::ManipulationObjectPtr visPointer =
+            VirtualRobot::ObjectIO::loadManipulationObject(name);
+        return visPointer;
+    }
+    else if (ext == ".wrl" || ext == ".iv")
+    {
+        VirtualRobot::VisualizationFactoryPtr factory =
+            VirtualRobot::VisualizationFactory::fromName("inventor", nullptr);
+        VirtualRobot::VisualizationNodePtr vis = factory->getVisualizationFromFile(name);
+        VirtualRobot::ManipulationObjectPtr visPointer =
+                std::make_shared<VirtualRobot::ManipulationObject>(name, vis);
+        return visPointer;
+    }
+
+    return nullptr;
+}
diff --git a/source/arviz_godot/lib/avi/core/ModelLoader.h b/source/arviz_godot/lib/avi/core/ModelLoader.h
index ec8c759494ab67e168030a195d6f4411fc77bcc5..dafacaf656dadb15f77fcf9d32e1a97b03785a3f 100644
--- a/source/arviz_godot/lib/avi/core/ModelLoader.h
+++ b/source/arviz_godot/lib/avi/core/ModelLoader.h
@@ -11,14 +11,17 @@ namespace avi::core
     class ModelLoader
     {
     public:
-        avi::core::Object loadModel(std::string name);
+        VirtualRobot::ManipulationObjectPtr getObject(const std::string& name);
 
-        avi::core::Object loadModelFromFile(std::string name);
+        avi::core::Object loadModel(const std::string& name, std::string& fullName);
+        avi::core::Object loadModelFromFile(const std::string& name);
 
         ModelLoader();
 
+        static avi::core::Object createObjectFromTriMesh(std::shared_ptr<VirtualRobot::TriMeshModel> model);
+
     private:
-        avi::core::Object loadModelFromNonObjFile(std::string name);
+        avi::core::Object loadModelFromNonObjFile(const std::string& name);
 
         avi::core::ModelCache cache;
         avi::core::Object error;
diff --git a/source/arviz_godot/lib/avi/gui/CameraModeMenu.cpp b/source/arviz_godot/lib/avi/gui/CameraModeMenu.cpp
index 58d566a3c73212b23c5c7bbb00a40c419473aa65..beb734d6608d7fec9c61090c40af61d4c01e9afa 100644
--- a/source/arviz_godot/lib/avi/gui/CameraModeMenu.cpp
+++ b/source/arviz_godot/lib/avi/gui/CameraModeMenu.cpp
@@ -25,9 +25,18 @@ avi::gui::CameraModeMenu::_ready()
 }
 
 void
-avi::gui::CameraModeMenu::setup(avi::core::EventInvokingSystem& invokingSystem)
+avi::gui::CameraModeMenu::setup(avi::core::EventInvokingSystem& invokingSystem,
+                                avi::core::EventSubscriptionSystem& eventSubscriptionSystem)
 {
     this->events = &invokingSystem;
+
+    eventSubscriptionSystem.subscribe("CAMERA_TECHNICAL",
+                                      [this]() -> void { this->select(CAMERA_TECHNICAL); });
+    eventSubscriptionSystem.subscribe("CAMERA_PLAYFUL",
+                                      [this]() -> void { this->select(CAMERA_PLAYFUL); });
+
+    this->set_item_text(CAMERA_TECHNICAL, "Technical [4]");
+    this->set_item_text(CAMERA_PLAYFUL, "Playful [5]");
 }
 
 int
@@ -53,7 +62,6 @@ avi::gui::CameraModeMenu::setActiveManipulator()
     {
         case CAMERA_TECHNICAL:
             avi::gui::CameraModeMenu::disableActiveItemText();
-            this->set_item_text(activeManipulatorID, "Technical");
 
             if (current != CAMERA_TECHNICAL)
                 events->invoke("VIEW_SCHEME_SWITCH");
@@ -63,7 +71,6 @@ avi::gui::CameraModeMenu::setActiveManipulator()
 
         case CAMERA_PLAYFUL:
             avi::gui::CameraModeMenu::disableActiveItemText();
-            this->set_item_text(activeManipulatorID, "Playful");
 
             if (current != CAMERA_PLAYFUL)
                 events->invoke("VIEW_SCHEME_SWITCH");
diff --git a/source/arviz_godot/lib/avi/gui/CameraModeMenu.h b/source/arviz_godot/lib/avi/gui/CameraModeMenu.h
index 6ae7efabd946219627014c3c99b56f32bcaec09d..8d2897b87b11ac11f5058ec5fe7037f0bef988bc 100644
--- a/source/arviz_godot/lib/avi/gui/CameraModeMenu.h
+++ b/source/arviz_godot/lib/avi/gui/CameraModeMenu.h
@@ -4,6 +4,7 @@
 #include <Godot.hpp>
 #include <ItemList.hpp>
 #include <arviz_godot/lib/avi/core/EventInvokingSystem.h>
+#include <arviz_godot/lib/avi/core/EventSubscriptionSystem.h>
 
 namespace avi::gui
 {
@@ -12,6 +13,8 @@ namespace avi::gui
         GODOT_CLASS(CameraModeMenu, Control)
 
     public:
+        virtual ~CameraModeMenu() = default;
+
         static void _register_methods();
 
         void _init();
@@ -20,7 +23,8 @@ namespace avi::gui
 
         void _ready();
 
-        void setup(avi::core::EventInvokingSystem& invokingSystem);
+        void setup(avi::core::EventInvokingSystem& invokingSystem,
+                   avi::core::EventSubscriptionSystem& eventSubscriptionSystem);
 
     private:
         avi::core::EventInvokingSystem* events;
diff --git a/source/arviz_godot/lib/avi/gui/GraphicsSettings.h b/source/arviz_godot/lib/avi/gui/GraphicsSettings.h
index a77c1fb73c2add5d2f24debebc200db18fc223cb..19e8df21524acd2750008403f109ddcc1c426db3 100644
--- a/source/arviz_godot/lib/avi/gui/GraphicsSettings.h
+++ b/source/arviz_godot/lib/avi/gui/GraphicsSettings.h
@@ -17,6 +17,8 @@ namespace avi::gui
         GODOT_CLASS(GraphicsSettings, Control)
 
     public:
+        virtual ~GraphicsSettings() = default;
+
         static void _register_methods();
 
         void _init();
diff --git a/source/arviz_godot/lib/avi/gui/LayerSelection.cpp b/source/arviz_godot/lib/avi/gui/LayerSelection.cpp
index 382d3fe3184a6fac1504204f12aadc93cda117a8..aced20c3ff128374c10e00ec649f9f8958062904 100644
--- a/source/arviz_godot/lib/avi/gui/LayerSelection.cpp
+++ b/source/arviz_godot/lib/avi/gui/LayerSelection.cpp
@@ -1,17 +1,20 @@
 #include "LayerSelection.h"
 
 #include <Label.hpp>
-#include <ResourceLoader.hpp>
 #include <TreeItem.hpp>
 
+
 void
 avi::gui::LayerSelection::_register_methods()
 {
     register_method("_ready", &LayerSelection::_ready);
     register_method("update_layers", &LayerSelection::update_layers);
-    register_method("show", &LayerSelection::show);
-    register_method("hide", &LayerSelection::hide);
     register_method("setVisibility", &LayerSelection::setVisibility);
+    register_method("updateActiveComponents", &LayerSelection::updateActiveComponents);
+    register_method("setVisibilityAll", &LayerSelection::setVisibilityAll);
+    register_method("setCollapseAll", &LayerSelection::setCollapseAll);
+    register_method("filterLayers", &LayerSelection::filterLayers);
+    register_method("setFilterVisibility", &LayerSelection::setFilterVisibility);
 }
 
 void
@@ -22,11 +25,18 @@ avi::gui::LayerSelection::_init()
 void
 avi::gui::LayerSelection::_ready()
 {
-    container = get_node<godot::Control>("Background/Scroll/Container");
+    container = get_node<godot::Control>("Background/Content/Scroll/Layers");
+    hideAllButton = get_node<godot::Control>("Background/Content/Buttons/HideAllButton");
+    showAllButton = get_node<godot::Control>("Background/Content/Buttons/ShowAllButton");
+
+    collapseAllButton = get_node<godot::Control>("Background/Content/Buttons/CollapseAllButton");
+    expandAllButton = get_node<godot::Control>("Background/Content/Buttons/ExpandAllButton");
 
-    godot::ResourceLoader* loader = godot::ResourceLoader::get_singleton();
-    itemScene = loader->load("res://scenes/layer_item.tscn");
-    layerScene = loader->load("res://scenes/component_item.tscn");
+    filterTextBox = get_node<godot::LineEdit>("Background/Content/FilterButtons/FilterTextBox");
+    hideFilteredButton =
+        get_node<godot::Control>("Background/Content/FilterButtons/HideFilteredButton");
+    showFilteredButton =
+        get_node<godot::Control>("Background/Content/FilterButtons/ShowFilteredButton");
 }
 
 void
@@ -35,6 +45,17 @@ avi::gui::LayerSelection::setup(avi::scene::VisualizedScene& scene)
     this->scene = &scene;
 
     scene.connect("layers_changed", this, "update_layers");
+
+    godot::Array args = godot::Array::make(false);
+    hideAllButton->connect("button_down", this, "setVisibilityAll", args);
+    expandAllButton->connect("button_down", this, "setCollapseAll", args);
+    hideFilteredButton->connect("button_down", this, "setFilterVisibility", args);
+    args[0] = true;
+    showAllButton->connect("button_down", this, "setVisibilityAll", args);
+    collapseAllButton->connect("button_down", this, "setCollapseAll", args);
+    showFilteredButton->connect("button_down", this, "setFilterVisibility", args);
+
+    filterTextBox->connect("text_changed", this, "filterLayers");
 }
 
 void
@@ -48,90 +69,211 @@ avi::gui::LayerSelection::update_layers()
     }
 
     components = scene->getComponents();
-    layers.clear();
+    buildTree();
+}
 
-    int64_t c = 0;
 
-    for (auto& component : components)
+void
+avi::gui::LayerSelection::updateActiveComponents()
+{
+    for (auto& layerTreeItem : layerTreeItems)
     {
-        godot::Node* currentComponent = layerScene->instance();
-        godot::String componentName = component.c_str();
-        godot::Array args = godot::Array::make(c);
-
-        currentComponent->get_node<godot::Label>("Title/Label")->set_text(componentName);
-        currentComponent->get_node<godot::Button>("Title/Show")
-            ->connect("pressed", this, "show", args);
-        currentComponent->get_node<godot::Button>("Title/Hide")
-            ->connect("pressed", this, "hide", args);
-
-        godot::Node* itemRoot = currentComponent->get_node<godot::Node>("Layers");
+        scene->setLayerVisibility(components[layerTreeItem.componentIndex],
+                                  layers[layerTreeItem.componentIndex][layerTreeItem.layerIndex],
+                                  layerTreeItem.treeItem->is_checked(0));
+    }
 
-        layers.push_back(scene->getLayers(component));
-        int64_t l = 0;
+    int component = 0;
+    for (auto& componentTreeItem : componentTreeItems)
+    {
 
-        for (auto& layer : layers.back())
+        if ((!componentTreeItem.treeItem->is_checked(0) && componentTreeItem.previousState) ||
+            (componentTreeItem.treeItem->is_checked(0) && !componentTreeItem.previousState))
         {
-            godot::Node* item = itemScene->instance();
-            godot::String layerName = layer.c_str();
-            godot::Array args = godot::Array::make(c, l);
 
-            item->get_node<godot::Label>("Label")->set_text(layerName);
-            auto* button = item->get_node<godot::Button>("CheckBox");
-            button->connect("toggled", this, "setVisibility", args);
-            button->set_pressed(scene->getLayerVisibility(component, layer));
+            for (auto& layerTreeItem : layerTreeItems)
+            {
+                if (layerTreeItem.treeItem->get_parent() == componentTreeItem.treeItem)
+                {
+                    layerTreeItem.treeItem->set_checked(0,
+                                                        componentTreeItem.treeItem->is_checked(0));
+                }
 
-            itemRoot->add_child(item);
+                if (!layerTreeItem.active)
+                {
+                    layerTreeItem.treeItem->set_checked(
+                        0,
+                        componentTreeItems[layerTreeItem.componentIndex].treeItem->is_checked(0));
+                }
+            }
 
-            l++;
+            for (auto& layer : layers[component])
+            {
+                scene->setLayerVisibility(
+                    components[component], layer, componentTreeItem.treeItem->is_checked(0));
+            }
         }
 
-        container->add_child(currentComponent);
-        c++;
+        componentTreeItem.previousState = componentTreeItem.treeItem->is_checked(0);
+        component++;
     }
 }
 
+
 void
-avi::gui::LayerSelection::hide(int64_t component)
+avi::gui::LayerSelection::setVisibility(bool visible, int64_t component, int64_t layer)
 {
-    std::lock_guard<std::mutex> lock(mutex);
-    int64_t l = 0;
+    scene->setLayerVisibility(components[component], layers[component][layer], visible);
+}
 
-    for (auto& layer : layers[component])
+void
+avi::gui::LayerSelection::setVisibilityAll(bool visible)
+{
+    for (auto& componentTreeItem : componentTreeItems)
     {
-        scene->setLayerVisibility(components[component], layer, false);
-        container->get_child(component)
-            ->get_node<godot::Node>("Layers")
-            ->get_child(l)
-            ->get_node<godot::Button>("CheckBox")
-            ->set_pressed(false);
-
-        l++;
+        componentTreeItem.treeItem->set_checked(0, visible);
     }
+
+    for (auto& layerTreeItem : layerTreeItems)
+    {
+        layerTreeItem.treeItem->set_checked(0, visible);
+    }
+
+    updateActiveComponents();
 }
 
 void
-avi::gui::LayerSelection::show(int64_t component)
+avi::gui::LayerSelection::setCollapseAll(bool collapsed)
 {
-    std::lock_guard<std::mutex> lock(mutex);
-    int64_t l = 0;
 
-    for (auto& layer : layers[component])
+    for (auto& componentTreeItem : componentTreeItems)
     {
-        scene->setLayerVisibility(components[component], layer, true);
-        container->get_child(component)
-            ->get_node<godot::Node>("Layers")
-            ->get_child(l)
-            ->get_node<godot::Button>("CheckBox")
-            ->set_pressed(true);
-
-        l++;
+        componentTreeItem.treeItem->set_collapsed(collapsed);
+    }
+
+    for (auto& layerTreeItem : layerTreeItems)
+    {
+        layerTreeItem.treeItem->set_collapsed(collapsed);
     }
 }
 
 void
-avi::gui::LayerSelection::setVisibility(bool visible, int64_t component, int64_t layer)
+avi::gui::LayerSelection::setFilterVisibility(bool visible)
 {
-    scene->setLayerVisibility(components[component], layers[component][layer], visible);
+    filterLayers();
+
+    for (auto& layerTreeItem : layerTreeItems)
+    {
+        if (layerTreeItem.active)
+        {
+            layerTreeItem.treeItem->set_checked(0, visible);
+        }
+    }
+
+    updateActiveComponents();
+}
+
+void
+avi::gui::LayerSelection::filterLayers()
+{
+    godot::String filterName = filterTextBox->get_text();
+
+    buildTree();
+
+    if (filterName.to_lower() == "")
+    {
+        return;
+    }
+
+    int componentIndex = 0;
+    for (auto& componentTreeItem : componentTreeItems)
+    {
+        for (auto& layerTreeItem : layerTreeItems)
+        {
+            if (layerTreeItem.componentIndex != componentIndex)
+            {
+                continue;
+            }
+
+            if (layerTreeItem.treeItem->get_text(0).to_lower().find(filterName.to_lower()) ==
+                std::string::npos)
+            {
+                componentTreeItem.treeItem->remove_child(layerTreeItem.treeItem);
+                layerTreeItem.active = false;
+            }
+        }
+
+        if (componentTreeItem.treeItem->get_children() == nullptr)
+        {
+            treeRootNode->remove_child(componentTreeItem.treeItem);
+        }
+
+        componentIndex++;
+    }
+}
+
+void
+avi::gui::LayerSelection::buildTree()
+{
+    if (tree != nullptr)
+    {
+        tree->queue_free();
+    }
+
+    tree = godot::Tree::_new();
+    container->add_child(tree);
+    godot::Vector2 tree_min_size = godot::Vector2(339, 430);
+    tree->set_custom_minimum_size(tree_min_size);
+    tree->set_h_size_flags(3);
+    tree->set_v_size_flags(3);
+    treeRootNode = tree->create_item();
+    tree->set_hide_root(true);
+
+    for (auto& layerTreeItem : layerTreeItems)
+    {
+        layerTreeItem.treeItem->free();
+    }
+
+    for (auto& componentTreeItem : componentTreeItems)
+    {
+        componentTreeItem.treeItem->free();
+    }
+
+    componentTreeItems.clear();
+    layerTreeItems.clear();
+    layers.clear();
+
+    int componentIndex = 0;
+    for (auto& component : components)
+    {
+        godot::TreeItem* componentTreeItem = tree->create_item(treeRootNode);
+        componentTreeItem->set_cell_mode(0, 1); //mode 1 = checkbox
+        componentTreeItem->set_checked(0, true);
+        componentTreeItem->set_editable(0, true);
+        componentTreeItem->set_tooltip(0, "Show / Hide a Layer");
+        componentTreeItem->set_text(0, component.c_str());
+        componentTreeItems.push_back({componentTreeItem, true});
+
+        layers.push_back(scene->getLayers(component));
+
+        int layerIndex = 0;
+        for (auto& layer : layers.back())
+        {
+            godot::TreeItem* layerTreeItem = tree->create_item(componentTreeItem);
+            layerTreeItem->set_cell_mode(0, 1); //mode 1 = checkbox
+            layerTreeItem->set_checked(
+                0,
+                scene->getLayerVisibility(components[componentIndex],
+                                          layers[componentIndex][layerIndex]));
+            layerTreeItem->set_editable(0, true);
+            layerTreeItem->set_tooltip(0, "Show / Hide a Layer");
+            layerTreeItem->set_text(0, layer.c_str());
+            layerTreeItems.push_back({layerTreeItem, componentIndex, layerIndex, true});
+            layerIndex++;
+        }
+        componentIndex++;
+    }
+    tree->connect("item_edited", this, "updateActiveComponents");
 }
 
 void
diff --git a/source/arviz_godot/lib/avi/gui/LayerSelection.h b/source/arviz_godot/lib/avi/gui/LayerSelection.h
index 95d3227860cb02e7c9c9281f751444cb2bfc1f34..02a9158130f6a90486cefaa1da8205b5be1409ea 100644
--- a/source/arviz_godot/lib/avi/gui/LayerSelection.h
+++ b/source/arviz_godot/lib/avi/gui/LayerSelection.h
@@ -5,6 +5,7 @@
 #include <Button.hpp>
 #include <Control.hpp>
 #include <Godot.hpp>
+#include <LineEdit.hpp>
 #include <PackedScene.hpp>
 #include <ResourceLoader.hpp>
 #include <Texture.hpp>
@@ -18,6 +19,8 @@ namespace avi::gui
         GODOT_CLASS(LayerSelection, Control)
 
     public:
+        virtual ~LayerSelection() = default;
+
         static void _register_methods();
 
         void _init();
@@ -35,17 +38,54 @@ namespace avi::gui
     private:
         void update_layers();
 
-        void hide(int64_t component);
-
-        void show(int64_t component);
+        void updateActiveComponents();
 
         void setVisibility(bool visible, int64_t component, int64_t layer);
 
+        void setVisibilityAll(bool visible);
+
+        void setCollapseAll(bool collapsed);
+
+        void filterLayers();
+
+        void buildTree();
+
+        void setFilterVisibility(bool visible);
+
+        struct LayerTreeItem
+        {
+            godot::TreeItem* treeItem;
+            int componentIndex;
+            int layerIndex;
+            bool active;
+        };
+
+        struct ComponentTreeItem
+        {
+            godot::TreeItem* treeItem;
+            bool previousState;
+        };
+
     private:
         godot::Ref<godot::PackedScene> itemScene;
         godot::Ref<godot::PackedScene> layerScene;
 
+        godot::Tree* tree{};
+        godot::TreeItem* treeRootNode{};
+        std::vector<ComponentTreeItem> componentTreeItems{};
+        std::vector<LayerTreeItem> layerTreeItems{};
+
         godot::Control* container{nullptr};
+        godot::Control* hideAllButton{nullptr};
+        godot::Control* showAllButton{nullptr};
+
+        godot::Control* collapseAllButton{nullptr};
+        godot::Control* expandAllButton{nullptr};
+
+        godot::LineEdit* filterTextBox{nullptr};
+        godot::Control* hideFilteredButton{nullptr};
+        godot::Control* showFilteredButton{nullptr};
+
         std::vector<std::string> components{};
         std::vector<std::vector<std::string>> layers{};
         avi::scene::VisualizedScene* scene{nullptr};
diff --git a/source/arviz_godot/lib/avi/gui/ManipulationMenu.cpp b/source/arviz_godot/lib/avi/gui/ManipulationMenu.cpp
index 53d7c5a7545d4eb57be4a838ae9a3007f69ab1a6..720e925056d1211fc409e023174494a0ae3b93d0 100644
--- a/source/arviz_godot/lib/avi/gui/ManipulationMenu.cpp
+++ b/source/arviz_godot/lib/avi/gui/ManipulationMenu.cpp
@@ -28,6 +28,11 @@ avi::gui::ManipulationMenu::setup(avi::interaction::Manipulator& manipulator,
                                       [this]() -> void { this->select(MANIPULATOR_ROTATE); });
     eventSubscriptionSystem.subscribe("MANIPULATOR_SCALE",
                                       [this]() -> void { this->select(MANIPULATOR_SCALE); });
+
+    this->set_item_text(MANIPULATOR_NONE, "[0]");
+    this->set_item_text(MANIPULATOR_MOVE, "Move [1]");
+    this->set_item_text(MANIPULATOR_ROTATE, "Rotate [2]");
+    this->set_item_text(MANIPULATOR_SCALE, "Scale [3]");
 }
 
 void
@@ -70,19 +75,16 @@ avi::gui::ManipulationMenu::setActiveManipulator()
             break;
         case MANIPULATOR_MOVE:
             avi::gui::ManipulationMenu::disableActiveItemText();
-            this->set_item_text(activeManipulatorID, "Move");
             selectionMode = ManipulationMode::TRANSLATE;
             manipulator->setManipulationMode(selectionMode);
             break;
         case MANIPULATOR_ROTATE:
             avi::gui::ManipulationMenu::disableActiveItemText();
-            this->set_item_text(activeManipulatorID, "Rotate");
             selectionMode = ManipulationMode::ROTATE;
             manipulator->setManipulationMode(selectionMode);
             break;
         case MANIPULATOR_SCALE:
             avi::gui::ManipulationMenu::disableActiveItemText();
-            this->set_item_text(activeManipulatorID, "Scale");
             selectionMode = ManipulationMode::SCALE;
             manipulator->setManipulationMode(selectionMode);
             break;
diff --git a/source/arviz_godot/lib/avi/gui/ManipulationMenu.h b/source/arviz_godot/lib/avi/gui/ManipulationMenu.h
index 89f5b901dc008341dd21d3fdb8c051721d538194..6183647c46690ffa9a8abbdb77cb7d514e116397 100644
--- a/source/arviz_godot/lib/avi/gui/ManipulationMenu.h
+++ b/source/arviz_godot/lib/avi/gui/ManipulationMenu.h
@@ -15,6 +15,8 @@ namespace avi::gui
         GODOT_CLASS(ManipulationMenu, Control)
 
     public:
+        virtual ~ManipulationMenu() = default;
+
         static void _register_methods();
 
         void _init();
diff --git a/source/arviz_godot/lib/avi/gui/OrientationWindow.h b/source/arviz_godot/lib/avi/gui/OrientationWindow.h
index 0410c5a6ce2ede23a480825433f1f60811dbee5c..84efd44c4e817516d7bd91dbb9fa5a8a256c6e18 100644
--- a/source/arviz_godot/lib/avi/gui/OrientationWindow.h
+++ b/source/arviz_godot/lib/avi/gui/OrientationWindow.h
@@ -12,6 +12,8 @@ namespace avi::gui
         GODOT_CLASS(OrientationWindow, godot::WindowDialog)
 
     public:
+        virtual ~OrientationWindow() = default;
+
         static void _register_methods();
 
         void _init();
diff --git a/source/arviz_godot/lib/avi/gui/ReplayCockpit.cpp b/source/arviz_godot/lib/avi/gui/ReplayCockpit.cpp
index 8f2861a6c1273f3b390b69f1754542227cd2acfc..c15c5ace0130d21e22a77e82f4f17abbffad82fb 100644
--- a/source/arviz_godot/lib/avi/gui/ReplayCockpit.cpp
+++ b/source/arviz_godot/lib/avi/gui/ReplayCockpit.cpp
@@ -17,6 +17,7 @@ avi::gui::ReplayCockpit::_register_methods()
     register_method("_enterReplayMode", &ReplayCockpit::_enterReplayMode);
 
     register_method("_select", &ReplayCockpit::_select);
+    register_method("_refresh", &ReplayCockpit::update_replays);
 
     register_method("_play", &ReplayCockpit::_play);
 
@@ -59,9 +60,12 @@ avi::gui::ReplayCockpit::_ready()
     slider->connect("mouse_entered", this, "_useSlider");
     slider->connect("mouse_exited", this, "_unUseSlider");
 
-    replayChooser = get_node<godot::OptionButton>("Background/Content/OptionButton");
+    replayChooser = get_node<godot::OptionButton>("Background/Content/Select/Chooser");
     replayChooser->connect("item_selected", this, "_select");
 
+    refresh = get_node<godot::Button>("Background/Content/Select/Refresh");
+    refresh->connect("pressed", this, "_refresh");
+
     forward1Button = get_node<godot::Button>("Background/Content/Buttons/Forward1");
     forward1Button->connect("pressed", this, "_forward1");
 
@@ -129,7 +133,11 @@ void
 avi::gui::ReplayCockpit::update_replays()
 {
     replayChooser->clear();
-    for (auto& name : controller->getNames())
+
+    std::vector<std::string> recordingNames = controller->getNames();
+    recordingsAvailable = not recordingNames.empty();
+
+    for (auto& name : recordingNames)
     {
         replayChooser->add_item(name.c_str());
     }
@@ -252,12 +260,12 @@ avi::gui::ReplayCockpit::_slide()
 void
 avi::gui::ReplayCockpit::_process(float delta)
 {
-    if (!controller->getNames().empty() && (!controller->getRecordingStatus()))
+    if (recordingsAvailable && (!controller->getRecordingStatus()))
     {
         this->modeButton->set_disabled(false);
         this->replayChooser->set_disabled(false);
     }
-    else if (controller->getNames().empty() || controller->getRecordingStatus())
+    else if (!recordingsAvailable || controller->getRecordingStatus())
     {
         this->modeButton->set_disabled(true);
         this->replayChooser->set_disabled(true);
diff --git a/source/arviz_godot/lib/avi/gui/ReplayCockpit.h b/source/arviz_godot/lib/avi/gui/ReplayCockpit.h
index 097a0a8bd5eb31ac2cbab3bdf2491af3d979d61b..2cfc07be3b986ede41d5fcf26deaa0b16a6300a1 100644
--- a/source/arviz_godot/lib/avi/gui/ReplayCockpit.h
+++ b/source/arviz_godot/lib/avi/gui/ReplayCockpit.h
@@ -18,6 +18,8 @@ namespace avi::gui
         GODOT_CLASS(ReplayCockpit, Control)
 
     public:
+        virtual ~ReplayCockpit() = default;
+
         static void _register_methods();
 
         void _init();
@@ -68,10 +70,12 @@ namespace avi::gui
         bool sliderUsed = false;
         bool playingBeforeSlider = false;
         bool actualizeSlider = false;
+        bool recordingsAvailable = false;
 
         std::string selectedReplay{};
 
         godot::OptionButton* replayChooser{};
+        godot::Button* refresh{};
 
         godot::Button* recordButton{};
 
diff --git a/source/arviz_godot/lib/avi/gui/SelectionMenu.cpp b/source/arviz_godot/lib/avi/gui/SelectionMenu.cpp
index 01a3117b2bfe9382dd7bdc166b946ca8fa43af9e..5993118546cac27f9b8550bf22430e2808c15cf1 100644
--- a/source/arviz_godot/lib/avi/gui/SelectionMenu.cpp
+++ b/source/arviz_godot/lib/avi/gui/SelectionMenu.cpp
@@ -49,7 +49,15 @@ avi::gui::SelectionMenu::open(godot::Vector2 mousePosition,
 void
 avi::gui::SelectionMenu::sendInteraction()
 {
-    if (this->get_current_index() < options.size())
+    int64_t index = this->get_current_index();
+    if (index < 0)
+    {
+        return;
+    }
+
+    size_t idx = index;
+
+    if (idx < options.size())
     {
         this->callback(this->get_current_index());
     }
diff --git a/source/arviz_godot/lib/avi/gui/SelectionMenu.h b/source/arviz_godot/lib/avi/gui/SelectionMenu.h
index be88006820d18a5daf115bf62d10a706f95931b8..2350a52fd484c449c0336c91292506d6bacdd387 100644
--- a/source/arviz_godot/lib/avi/gui/SelectionMenu.h
+++ b/source/arviz_godot/lib/avi/gui/SelectionMenu.h
@@ -13,6 +13,8 @@ namespace avi::gui
         GODOT_CLASS(SelectionMenu, godot::PopupMenu)
 
     public:
+        virtual ~SelectionMenu() = default;
+
         static void _register_methods();
 
         void _init();
diff --git a/source/arviz_godot/lib/avi/gui/SettingsWindow.h b/source/arviz_godot/lib/avi/gui/SettingsWindow.h
index 227333cb5beed7ca8f32c5dc7ae4e0a6d56b494c..ab47ef82bc713e852aa7de35e15fccdcfa9bf92d 100644
--- a/source/arviz_godot/lib/avi/gui/SettingsWindow.h
+++ b/source/arviz_godot/lib/avi/gui/SettingsWindow.h
@@ -12,6 +12,8 @@ namespace avi::gui
         GODOT_CLASS(SettingsWindow, godot::WindowDialog)
 
     public:
+        virtual ~SettingsWindow() = default;
+
         static void _register_methods();
 
         void _init();
diff --git a/source/arviz_godot/lib/avi/gui/StatusIcons.h b/source/arviz_godot/lib/avi/gui/StatusIcons.h
index 6b584ce741beec12870d31beb75f2e2a7c76ffde..80ea9ab9134f27bef182673dd8702ee9c1f76cff 100644
--- a/source/arviz_godot/lib/avi/gui/StatusIcons.h
+++ b/source/arviz_godot/lib/avi/gui/StatusIcons.h
@@ -15,6 +15,8 @@ namespace avi::gui
         GODOT_CLASS(StatusIcons, Control)
 
     public:
+        virtual ~StatusIcons() = default;
+
         static void _register_methods();
 
         void _init();
diff --git a/source/arviz_godot/lib/avi/gui/UserInterface.cpp b/source/arviz_godot/lib/avi/gui/UserInterface.cpp
index ffcd6520c6c61c6326a408cf16f6ed1755028276..85ffe2b89e6cdb4d25c9803f5f993fced6f53122 100644
--- a/source/arviz_godot/lib/avi/gui/UserInterface.cpp
+++ b/source/arviz_godot/lib/avi/gui/UserInterface.cpp
@@ -67,7 +67,7 @@ avi::gui::UserInterface::setupUI(avi::core::EventInvokingSystem& eventInvokingSy
     settingsWindow->setup(settings);
 
     get_node<avi::gui::CameraModeMenu>("Bar/Bar Background/Bar Container/CameraMenu")
-        ->setup(eventInvokingSystem);
+        ->setup(eventInvokingSystem, eventSubscriptionSystem);
 }
 
 void
diff --git a/source/arviz_godot/lib/avi/gui/UserInterface.h b/source/arviz_godot/lib/avi/gui/UserInterface.h
index 13e539d891c1395cdc95017f20e4b2300dc17feb..f512b8399d199cf587a092c037e57b25a25c1483 100644
--- a/source/arviz_godot/lib/avi/gui/UserInterface.h
+++ b/source/arviz_godot/lib/avi/gui/UserInterface.h
@@ -27,6 +27,8 @@ namespace avi::gui
         GODOT_CLASS(UserInterface, Control)
 
     public:
+        virtual ~UserInterface() = default;
+
         static void _register_methods();
 
         void _init();
diff --git a/source/arviz_godot/lib/avi/interaction/InteractionDispatch.cpp b/source/arviz_godot/lib/avi/interaction/InteractionDispatch.cpp
index a9a87debada197d234e423aa6900c603b7e7b3e0..2bef71381d5aa9d29d85f497179bc5c350409283 100644
--- a/source/arviz_godot/lib/avi/interaction/InteractionDispatch.cpp
+++ b/source/arviz_godot/lib/avi/interaction/InteractionDispatch.cpp
@@ -74,6 +74,8 @@ avi::interaction::InteractionDispatch::_process(float delta)
         hasHitSelectable = element->isSelectable() || element->hasContextMenu();
     }
 
+
+
     godot::Input* input = godot::Input::get_singleton();
 
     if (hasHitSelectable)
diff --git a/source/arviz_godot/lib/avi/interaction/InteractionDispatch.h b/source/arviz_godot/lib/avi/interaction/InteractionDispatch.h
index 51af53d666b1841255eba45f18b69f7ad34c6691..7d632d530b1cdfd0c2302d1511ec5a3b9a868da7 100644
--- a/source/arviz_godot/lib/avi/interaction/InteractionDispatch.h
+++ b/source/arviz_godot/lib/avi/interaction/InteractionDispatch.h
@@ -17,6 +17,8 @@ namespace avi::interaction
         GODOT_CLASS(InteractionDispatch, Node)
 
     public:
+        virtual ~InteractionDispatch() = default;
+
         static void _register_methods();
 
         void _init();
diff --git a/source/arviz_godot/lib/avi/interaction/Move.h b/source/arviz_godot/lib/avi/interaction/Move.h
index c68d2f9bb52bea706bdd75174df00b2cdb65ff50..8eb6ed8e3fac50d6a69bd6117f06f6a15f4597fb 100644
--- a/source/arviz_godot/lib/avi/interaction/Move.h
+++ b/source/arviz_godot/lib/avi/interaction/Move.h
@@ -14,6 +14,8 @@ namespace avi::interaction
         GODOT_CLASS(Move, Spatial)
 
     public:
+        virtual ~Move() = default;
+
         static void _register_methods();
 
         void _init();
diff --git a/source/arviz_godot/lib/avi/interaction/MoveAxisGizmo.h b/source/arviz_godot/lib/avi/interaction/MoveAxisGizmo.h
index 883bc0f7c77bafe373056e124c6521f830437508..7aa9ff05f66a3073a3376f76838a12f81bc3c951 100644
--- a/source/arviz_godot/lib/avi/interaction/MoveAxisGizmo.h
+++ b/source/arviz_godot/lib/avi/interaction/MoveAxisGizmo.h
@@ -26,7 +26,7 @@ namespace avi::interaction
         static void _register_methods();
 
         MoveAxisGizmo();
-        ~MoveAxisGizmo();
+        virtual ~MoveAxisGizmo();
 
         void _init();
 
diff --git a/source/arviz_godot/lib/avi/interaction/None.h b/source/arviz_godot/lib/avi/interaction/None.h
index 76b5ad4e6af55a3517612f747561d5fc8ccc7808..65b14c92627218a4de0a28c07a9b280f594bc90a 100644
--- a/source/arviz_godot/lib/avi/interaction/None.h
+++ b/source/arviz_godot/lib/avi/interaction/None.h
@@ -14,6 +14,8 @@ namespace avi::interaction
         GODOT_CLASS(None, Spatial)
 
     public:
+        virtual ~None() = default;
+
         static void _register_methods();
 
         void _init();
diff --git a/source/arviz_godot/lib/avi/interaction/Rotate.h b/source/arviz_godot/lib/avi/interaction/Rotate.h
index 613fc910ada2ec3c6444d35a19f8a020e66e4a44..4d0624af1548259c62d2aaa24d47128a31fa29ff 100644
--- a/source/arviz_godot/lib/avi/interaction/Rotate.h
+++ b/source/arviz_godot/lib/avi/interaction/Rotate.h
@@ -14,6 +14,8 @@ namespace avi::interaction
         GODOT_CLASS(Rotate, Spatial)
 
     public:
+        virtual ~Rotate() = default;
+
         static void _register_methods();
 
         void _init();
diff --git a/source/arviz_godot/lib/avi/interaction/RotateAxisGizmo.h b/source/arviz_godot/lib/avi/interaction/RotateAxisGizmo.h
index c942ee5fca4ed9aff28922bacd1faf86e7c606ef..d5691397bd43da2d7c0b3c0bf81117f8854e347d 100644
--- a/source/arviz_godot/lib/avi/interaction/RotateAxisGizmo.h
+++ b/source/arviz_godot/lib/avi/interaction/RotateAxisGizmo.h
@@ -25,7 +25,7 @@ namespace avi::interaction
         static void _register_methods();
 
         RotateAxisGizmo();
-        ~RotateAxisGizmo();
+        virtual ~RotateAxisGizmo();
 
         void _init();
 
diff --git a/source/arviz_godot/lib/avi/interaction/Scale.h b/source/arviz_godot/lib/avi/interaction/Scale.h
index 502b254d16ea3e04a70fb867e43d852e931bded3..2674a01e88d9a5d24a75cb40d715dc72e97f0af6 100644
--- a/source/arviz_godot/lib/avi/interaction/Scale.h
+++ b/source/arviz_godot/lib/avi/interaction/Scale.h
@@ -14,6 +14,8 @@ namespace avi::interaction
         GODOT_CLASS(Scale, Spatial)
 
     public:
+        virtual ~Scale() = default;
+
         static void _register_methods();
 
         void _init();
diff --git a/source/arviz_godot/lib/avi/interaction/ScaleAxisGizmo.cpp b/source/arviz_godot/lib/avi/interaction/ScaleAxisGizmo.cpp
index be8d1370ddf16f602fc554afe731e65f15e411b1..f0d55c547d370b72f9b4a1cdff19880d3c5e750d 100644
--- a/source/arviz_godot/lib/avi/interaction/ScaleAxisGizmo.cpp
+++ b/source/arviz_godot/lib/avi/interaction/ScaleAxisGizmo.cpp
@@ -99,7 +99,6 @@ avi::interaction::ScaleAxisGizmo::_process(float delta)
 
         Vector3 motion_mask;
         Plane plane;
-        bool plane_move = false;
 
         switch (_edit.plane)
         {
@@ -146,10 +145,6 @@ avi::interaction::ScaleAxisGizmo::_process(float delta)
                                      const godot::Transform& original_local,
                                      bool is_local) -> Transform
         {
-            Vector3 motion_in_gizmo_space = _edit.original_local.basis.inverse().xform(motion);
-            Vector3 motion_in_proxy_space =
-                original_local.basis.inverse().xform(motion_in_gizmo_space);
-
             Transform s;
 
             if (is_local)
diff --git a/source/arviz_godot/lib/avi/interaction/ScaleAxisGizmo.h b/source/arviz_godot/lib/avi/interaction/ScaleAxisGizmo.h
index c089d81acd573e2900150b594d5bd5bcf830085d..2aa5975a544ccd9568f3b0826bb463cbfaf59bf8 100644
--- a/source/arviz_godot/lib/avi/interaction/ScaleAxisGizmo.h
+++ b/source/arviz_godot/lib/avi/interaction/ScaleAxisGizmo.h
@@ -25,7 +25,7 @@ namespace avi::interaction
         static void _register_methods();
 
         ScaleAxisGizmo();
-        ~ScaleAxisGizmo();
+        virtual ~ScaleAxisGizmo();
 
         void _init();
 
diff --git a/source/arviz_godot/lib/avi/scene/ArrowCircleElementNode.cpp b/source/arviz_godot/lib/avi/scene/ArrowCircleElementNode.cpp
index 30aba508c549f53738a863d2bf5bf69ee30b5c89..52e2ccbf340d5c9ac473ca9c3f7d953bcebf123e 100644
--- a/source/arviz_godot/lib/avi/scene/ArrowCircleElementNode.cpp
+++ b/source/arviz_godot/lib/avi/scene/ArrowCircleElementNode.cpp
@@ -210,10 +210,8 @@ avi::scene::ArrowCircleElementNode::_init()
 void
 avi::scene::ArrowCircleElementNode::generateMesh()
 {
-
-    godot::PoolVector3Array normals;
-
     godot::PoolVector3Array vertexPositions;
+    godot::PoolVector3Array normals;
     godot::PoolIntArray faces;
 
     float completion2 = std::min<float>(1.0f, std::max(-1.0f, completion));
@@ -233,11 +231,19 @@ avi::scene::ArrowCircleElementNode::generateMesh()
         int numVerticesPerRow = SIDES + 1;
         int numVerticesPerColumn = RINGS + 1;
 
+        int storageSize = numVerticesPerRow * numVerticesPerColumn;
+        vertexPositions.resize(storageSize);
+        godot::Vector3* positionsPtr = vertexPositions.write().ptr();
+        normals.resize(storageSize);
+        godot::Vector3* normalsPtr = normals.write().ptr();
+
         float theta = 0.0f;
         float phi = 0.0f;
         float verticalAngularStride = TWO_PI / RINGS;
         float horizontalAngularStride = TWO_PI / SIDES;
 
+        size_t writeIndex = 0;
+
         for (int verticalIt = 0; verticalIt < numVerticesPerColumn; verticalIt++)
         {
             theta = verticalAngularStride * verticalIt * torusCompletion;
@@ -257,29 +263,34 @@ avi::scene::ArrowCircleElementNode::generateMesh()
 
                 godot::Vector3 normal = godot::Vector3(x - xCenter, y - yCenter, z - zCenter);
                 normal.normalize();
-                normals.push_back(normal);
 
-                vertexPositions.push_back({x, y, z});
+                positionsPtr[writeIndex] = {x, y, z};
+                normalsPtr[writeIndex] = normal;
+                writeIndex++;
             }
         }
 
+        faces.resize(RINGS * SIDES * 6);
+        int* facesPtr = faces.write().ptr();
+        writeIndex = 0;
+
         for (int verticalIt = 0; verticalIt < RINGS; verticalIt++)
         {
             for (int horizontalIt = 0; horizontalIt < SIDES; horizontalIt++)
             {
-                short lt = (short)(horizontalIt + verticalIt * (numVerticesPerRow));
-                short rt = (short)((horizontalIt + 1) + verticalIt * (numVerticesPerRow));
+                int lt = static_cast<int>(horizontalIt + verticalIt * (numVerticesPerRow));
+                int rt = static_cast<int>((horizontalIt + 1) + verticalIt * (numVerticesPerRow));
 
-                short lb = (short)(horizontalIt + (verticalIt + 1) * (numVerticesPerRow));
-                short rb = (short)((horizontalIt + 1) + (verticalIt + 1) * (numVerticesPerRow));
+                int lb = static_cast<int>(horizontalIt + (verticalIt + 1) * (numVerticesPerRow));
+                int rb = static_cast<int>((horizontalIt + 1) + (verticalIt + 1) * (numVerticesPerRow));
 
-                faces.push_back(lt);
-                faces.push_back(rt);
-                faces.push_back(lb);
+                facesPtr[writeIndex++] = lt;
+                facesPtr[writeIndex++] = rt;
+                facesPtr[writeIndex++] = lb;
 
-                faces.push_back(rt);
-                faces.push_back(rb);
-                faces.push_back(lb);
+                facesPtr[writeIndex++] = rt;
+                facesPtr[writeIndex++] = rb;
+                facesPtr[writeIndex++] = lb;
             }
         }
     }
diff --git a/source/arviz_godot/lib/avi/scene/ArrowCircleElementNode.h b/source/arviz_godot/lib/avi/scene/ArrowCircleElementNode.h
index 2b57781b0f55193fe364a2558efa9035c2846004..cf5d76efdc8fa0f80725142a438088a7cc2ff49d 100644
--- a/source/arviz_godot/lib/avi/scene/ArrowCircleElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/ArrowCircleElementNode.h
@@ -17,6 +17,8 @@ namespace avi::scene
         GODOT_CLASS(ArrowCircleElementNode, ElementNode)
 
     public:
+        ~ArrowCircleElementNode() override = default;
+
         ArrowCircleElementNode();
 
         void _init();
diff --git a/source/arviz_godot/lib/avi/scene/ArrowElementNode.cpp b/source/arviz_godot/lib/avi/scene/ArrowElementNode.cpp
index 13ee9e1b3cf2b3dccf781f6895a2a57839d3de2b..21c3566e11601e88622a01dbac2159061e72258a 100644
--- a/source/arviz_godot/lib/avi/scene/ArrowElementNode.cpp
+++ b/source/arviz_godot/lib/avi/scene/ArrowElementNode.cpp
@@ -13,9 +13,10 @@ avi::scene::ArrowElementNode::ArrowElementNode()
 godot::AABB
 avi::scene::ArrowElementNode::getVolume()
 {
-    godot::AABB correctedAABB = cylinder->get_aabb().merge(cone->get_aabb());
+    godot::AABB correctedAABB = cone->get_transformed_aabb();
     correctedAABB.position = staticBody->get_transform().origin;
-    correctedAABB.size = correctedAABB.size * staticBody->get_scale() * 100;
+    correctedAABB.size = correctedAABB.size * 0.5f;
+
 
     return correctedAABB;
 }
diff --git a/source/arviz_godot/lib/avi/scene/ArrowElementNode.h b/source/arviz_godot/lib/avi/scene/ArrowElementNode.h
index 2f8426546746c26f75d9d36e6c13fa3eb41b0081..a88c4e7a3f08ae4444b150408482f969117a6e63 100644
--- a/source/arviz_godot/lib/avi/scene/ArrowElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/ArrowElementNode.h
@@ -18,6 +18,7 @@ namespace avi::scene
 
     public:
         ArrowElementNode();
+        ~ArrowElementNode() override = default;
 
         void _init();
 
diff --git a/source/arviz_godot/lib/avi/scene/CameraControlScheme.h b/source/arviz_godot/lib/avi/scene/CameraControlScheme.h
index 2f49572d0eaad5ebba8884d00dd54e14d8943b54..c093ba6dda08f8cc7ebec9110e58b7d241172696 100644
--- a/source/arviz_godot/lib/avi/scene/CameraControlScheme.h
+++ b/source/arviz_godot/lib/avi/scene/CameraControlScheme.h
@@ -17,7 +17,7 @@ namespace avi::scene
 
         virtual void focus(godot::AABB box) = 0;
 
-        virtual void focus(godot::Vector3 point) = 0;
+        virtual void focus(godot::Vector3 point, avi::core::Element*) = 0;
 
         virtual godot::Basis getRotationBasis() = 0;
 
diff --git a/source/arviz_godot/lib/avi/scene/Converter.cpp b/source/arviz_godot/lib/avi/scene/Converter.cpp
index 81b895849dc3306b6087edf720de95bd780331f0..55689745f560a039e215b10972cc9792da8ef313 100644
--- a/source/arviz_godot/lib/avi/scene/Converter.cpp
+++ b/source/arviz_godot/lib/avi/scene/Converter.cpp
@@ -59,7 +59,7 @@ avi::scene::Converter::apply()
                 case armarx::viz::data::Layer_DELETE:
                     if (layers.find(name) != layers.end())
                     {
-                        layers.at(name)->queue_free();
+                        layers.at(name)->saveRemove();
                         layers.erase(name);
                     }
                     break;
@@ -361,15 +361,16 @@ avi::scene::Converter::createElement(avi::scene::LayerNode* layer,
         {
             avi::scene::PointCloudElementNode* pointCloudNode =
                 avi::scene::PointCloudElementNode::newPointCloudElementNode(
-                    avi::connection::SentElementType::POINT_CLOUD,
-                    elementInfo->id,
-                    layer,
-                    graphicsController);
+                    avi::connection::SentElementType::POINT_CLOUD, elementInfo->id, layer);
 
             pointCloudNode->update(elementInfo);
             created = pointCloudNode;
             break;
         }
+
+        case connection::SentElementType::ERROR:
+            assert(false && "unreachable");
+            break;
     }
 
     if (created && created->getType() != avi::connection::SentElementType::TEXT)
@@ -493,7 +494,7 @@ avi::scene::Converter::clear()
 {
     for (auto& [name, l] : layers)
     {
-        l->queue_free();
+        l->saveRemove();
     }
     layers.clear();
 
diff --git a/source/arviz_godot/lib/avi/scene/CubeElementNode.h b/source/arviz_godot/lib/avi/scene/CubeElementNode.h
index 6fc28aa2c27d7eb18aa03183a9bd874b9fb2dd2c..cdd828da2972ce31272a2da74b742c006d8be43b 100644
--- a/source/arviz_godot/lib/avi/scene/CubeElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/CubeElementNode.h
@@ -10,6 +10,8 @@ namespace avi::scene
         GODOT_CLASS(CubeElementNode, ElementNode)
 
     public:
+        ~CubeElementNode() override = default;
+
         static void _register_methods();
 
         void _ready();
diff --git a/source/arviz_godot/lib/avi/scene/CustomMeshElementNode.cpp b/source/arviz_godot/lib/avi/scene/CustomMeshElementNode.cpp
index 8c8f6d061ccd5fc0c59f1e19876c47222e4b8463..e669018caf374c25b34155aba6c5d9778448bed4 100644
--- a/source/arviz_godot/lib/avi/scene/CustomMeshElementNode.cpp
+++ b/source/arviz_godot/lib/avi/scene/CustomMeshElementNode.cpp
@@ -25,50 +25,52 @@ avi::scene::CustomMeshElementNode::update(
 {
     auto meshEl = IceInternal::Handle<armarx::viz::data::ElementMesh>::dynamicCast(elementInfo);
     auto* mesh = godot::Object::cast_to<godot::ArrayMesh>(getMesh());
+
+    int storageSize = meshEl->faces.size() * 6;
+
     godot::PoolVector3Array coords;
+    coords.resize(storageSize);
+    godot::Vector3* coordsPtr = coords.write().ptr();
+
     godot::PoolColorArray colors;
+    colors.resize(storageSize);
+    godot::Color* colorsPtr = colors.write().ptr();
+
     godot::PoolVector3Array normals;
-    armarx::Vector3f vertex = {};
+    normals.resize(storageSize);
+    godot::Vector3* normalsPtr = normals.write().ptr();
+
+    size_t writeIndex = 0;
+
     for (auto face : meshEl->faces)
     {
+        auto putVertex = [&](int vertexIdx, int colorIdx, godot::Vector3 normal)
+        {
+            armarx::Vector3f vertex = meshEl->vertices.at(vertexIdx);
+            coordsPtr[writeIndex] = godot::Vector3(vertex.e0, vertex.e1, vertex.e2);
+            colorsPtr[writeIndex] = avi::scene::Converter::getColor(meshEl->colors.at(colorIdx));
+            normalsPtr[writeIndex] = normal;
+
+            writeIndex++;
+        };
+
         godot::Vector3 normal1 = avi::scene::Converter::getNormal(meshEl->vertices.at(face.v0),
                                                                   meshEl->vertices.at(face.v2),
                                                                   meshEl->vertices.at(face.v1));
 
+        putVertex(face.v0, face.c0, normal1);
+        putVertex(face.v1, face.c1, normal1);
+        putVertex(face.v2, face.c2, normal1);
+
         godot::Vector3 normal2 = avi::scene::Converter::getNormal(meshEl->vertices.at(face.v0),
                                                                   meshEl->vertices.at(face.v1),
                                                                   meshEl->vertices.at(face.v2));
 
-        vertex = meshEl->vertices.at(face.v0);
-        coords.push_back(godot::Vector3(vertex.e0, vertex.e1, vertex.e2));
-        colors.push_back(avi::scene::Converter::getColor(meshEl->colors.at(face.c0)));
-        normals.push_back(normal1);
-
-        vertex = meshEl->vertices.at(face.v1);
-        coords.push_back(godot::Vector3(vertex.e0, vertex.e1, vertex.e2));
-        colors.push_back(avi::scene::Converter::getColor(meshEl->colors.at(face.c1)));
-        normals.push_back(normal1);
-
-        vertex = meshEl->vertices.at(face.v2);
-        coords.push_back(godot::Vector3(vertex.e0, vertex.e1, vertex.e2));
-        colors.push_back(avi::scene::Converter::getColor(meshEl->colors.at(face.c2)));
-        normals.push_back(normal1);
-
-        vertex = meshEl->vertices.at(face.v0);
-        coords.push_back(godot::Vector3(vertex.e0, vertex.e1, vertex.e2));
-        colors.push_back(avi::scene::Converter::getColor(meshEl->colors.at(face.c0)));
-        normals.push_back(normal2);
-
-        vertex = meshEl->vertices.at(face.v2);
-        coords.push_back(godot::Vector3(vertex.e0, vertex.e1, vertex.e2));
-        colors.push_back(avi::scene::Converter::getColor(meshEl->colors.at(face.c2)));
-        normals.push_back(normal2);
-
-        vertex = meshEl->vertices.at(face.v1);
-        coords.push_back(godot::Vector3(vertex.e0, vertex.e1, vertex.e2));
-        colors.push_back(avi::scene::Converter::getColor(meshEl->colors.at(face.c1)));
-        normals.push_back(normal2);
+        putVertex(face.v0, face.c0, normal2);
+        putVertex(face.v2, face.c2, normal2);
+        putVertex(face.v1, face.c1, normal2);
     }
+
     godot::Array arr{};
     arr.resize(godot::ArrayMesh::ARRAY_MAX);
     arr[godot::ArrayMesh::ARRAY_VERTEX] = coords;
diff --git a/source/arviz_godot/lib/avi/scene/CustomMeshElementNode.h b/source/arviz_godot/lib/avi/scene/CustomMeshElementNode.h
index 6dbb2e508a3c2c61c6c4ec3739f9715abcf9147e..71579246844e3273f1f8b7d89621d2c4cfb7eb73 100644
--- a/source/arviz_godot/lib/avi/scene/CustomMeshElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/CustomMeshElementNode.h
@@ -10,6 +10,8 @@ namespace avi::scene
         GODOT_CLASS(CustomMeshElementNode, ElementNode)
 
     public:
+        ~CustomMeshElementNode() override = default;
+
         static void _register_methods();
 
         void _ready();
diff --git a/source/arviz_godot/lib/avi/scene/CylinderElementNode.h b/source/arviz_godot/lib/avi/scene/CylinderElementNode.h
index 91b5c33fb7d448a6d419773924108cd69ed8cdc1..5bc09f8001997731d7bbe8e91d8048ded4b16218 100644
--- a/source/arviz_godot/lib/avi/scene/CylinderElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/CylinderElementNode.h
@@ -10,6 +10,8 @@ namespace avi::scene
         GODOT_CLASS(CylinderElementNode, ElementNode)
 
     public:
+        ~CylinderElementNode() override = default;
+
         static void _register_methods();
 
         void _ready();
diff --git a/source/arviz_godot/lib/avi/scene/CylindroidElementNode.h b/source/arviz_godot/lib/avi/scene/CylindroidElementNode.h
index 255478c353d0d2e7b0912811212c98094bdd0459..f098f7a95dca314d8b904041ecdfa925b6e9dad6 100644
--- a/source/arviz_godot/lib/avi/scene/CylindroidElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/CylindroidElementNode.h
@@ -10,6 +10,8 @@ namespace avi::scene
         GODOT_CLASS(CylindroidElementNode, ElementNode)
 
     public:
+        ~CylindroidElementNode() override = default;
+
         static void _register_methods();
 
         void _ready();
diff --git a/source/arviz_godot/lib/avi/scene/ElementNode.h b/source/arviz_godot/lib/avi/scene/ElementNode.h
index d2625aaab7fde72c4eedb453a33c2536c114f02c..54379576da894258ba5799a9a093aad4accd151e 100644
--- a/source/arviz_godot/lib/avi/scene/ElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/ElementNode.h
@@ -21,6 +21,7 @@ namespace avi::scene
 
     public:
         ElementNode();
+        ~ElementNode() override = default;
 
         static void _register_methods();
 
diff --git a/source/arviz_godot/lib/avi/scene/EllipsoidElementNode.h b/source/arviz_godot/lib/avi/scene/EllipsoidElementNode.h
index 7278dd0dc789411f4630e6a6d872eaf7eb122c5b..23488d238f445ca54aa155c562bd7cfc9d154d6f 100644
--- a/source/arviz_godot/lib/avi/scene/EllipsoidElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/EllipsoidElementNode.h
@@ -10,6 +10,8 @@ namespace avi::scene
         GODOT_CLASS(EllipsoidElementNode, ElementNode)
 
     public:
+        ~EllipsoidElementNode() override = default;
+
         static void _register_methods();
 
         void _ready();
diff --git a/source/arviz_godot/lib/avi/scene/GraphicsController.cpp b/source/arviz_godot/lib/avi/scene/GraphicsController.cpp
index e2205f38a3e9f7a38c6b84bcd050101576238c14..184d594bf56a8c078d2858040f15934e1e4e5779 100644
--- a/source/arviz_godot/lib/avi/scene/GraphicsController.cpp
+++ b/source/arviz_godot/lib/avi/scene/GraphicsController.cpp
@@ -88,9 +88,3 @@ avi::scene::GraphicsController::getCurrentHeadlightState() const
 {
     return activeProfile.cameraHeadlight;
 }
-
-bool
-avi::scene::GraphicsController::getPointCloudStyle() const
-{
-    return activeProfile.coloredPointCloud;
-}
diff --git a/source/arviz_godot/lib/avi/scene/GraphicsController.h b/source/arviz_godot/lib/avi/scene/GraphicsController.h
index 6d6dedfa9187dc6bcfe6b8d776cd744c3593f146..156e4c5594aa155474c86fc0ec8e2da0c891e1d2 100644
--- a/source/arviz_godot/lib/avi/scene/GraphicsController.h
+++ b/source/arviz_godot/lib/avi/scene/GraphicsController.h
@@ -26,8 +26,6 @@ namespace avi::scene
 
         [[nodiscard]] bool getCurrentHeadlightState() const;
 
-        [[nodiscard]] bool getPointCloudStyle() const;
-
         void registerChangeListener(void* listener, const std::function<void()>& callback);
 
         void unregisterChangeListener(void* listener);
diff --git a/source/arviz_godot/lib/avi/scene/LayerNode.cpp b/source/arviz_godot/lib/avi/scene/LayerNode.cpp
index 314a0924ec216dafbed065b9feb66335f363f84a..9b55ee14f0579ba99b7e7c5c385c019e6eb1d182 100644
--- a/source/arviz_godot/lib/avi/scene/LayerNode.cpp
+++ b/source/arviz_godot/lib/avi/scene/LayerNode.cpp
@@ -35,6 +35,18 @@ avi::scene::LayerNode::setVisibility(bool isVisible)
     if (visible == isVisible)
         return;
 
+    if(not isVisible) {
+        for (auto& [_, element] : elements)
+        {
+            this->remove_child(element);
+        }
+    } else {
+        for (auto& [_, element] : elements)
+        {
+            this->add_child(element);
+        }
+    }
+
     this->set_visible(isVisible);
     visible = isVisible;
 }
@@ -86,19 +98,46 @@ avi::scene::LayerNode::removeElement(std::string name)
 {
     if (elements.find(name) != elements.end())
     {
-        //remove_child(elements.at(name));
+        if(not this->is_a_parent_of(elements.at(name))) {
+            this->add_child(elements.at(name));
+        }
+
+        remove_child(elements.at(name));
         elements.erase(name);
     }
 }
 
+void
+avi::scene::LayerNode::saveRemove() {
+    for (auto& [_, element] : elements)
+    {
+        if(not this->is_a_parent_of(element)) {
+            this->add_child(element);
+        }
+    }
+
+    this->queue_free();
+}
+
+
 godot::AABB
 avi::scene::LayerNode::getAABB()
 {
+    bool noBaseAABB = true;
     godot::AABB aabb;
-    for (auto& [_, element] : elements)
+
+    for (const auto& [_, element] : elements)
     {
-        aabb = aabb.merge(element->getVolume());
+        if (noBaseAABB)
+        {
+            aabb = element->getVolume();
+            noBaseAABB = false;
+        }
+        else
+        {
+            aabb = aabb.merge(element->getVolume());
+        }
     }
 
     return aabb;
-}
+}
\ No newline at end of file
diff --git a/source/arviz_godot/lib/avi/scene/LayerNode.h b/source/arviz_godot/lib/avi/scene/LayerNode.h
index b6488fc1cbbe53afb5f4ef8cc664a54ad9642968..bf8612fdb48297a8561e0853914a81bdbfb50ec1 100644
--- a/source/arviz_godot/lib/avi/scene/LayerNode.h
+++ b/source/arviz_godot/lib/avi/scene/LayerNode.h
@@ -24,6 +24,8 @@ namespace avi::scene
         GODOT_CLASS(LayerNode, Spatial)
 
     public:
+        ~LayerNode() override = default;
+
         static void _register_methods();
 
         void _init();
@@ -44,6 +46,8 @@ namespace avi::scene
 
         void removeElement(std::string name);
 
+        void saveRemove();
+
         godot::AABB getAABB();
 
     private:
diff --git a/source/arviz_godot/lib/avi/scene/LineElementNode.h b/source/arviz_godot/lib/avi/scene/LineElementNode.h
index ab0c0ff85a43054919f63430972a3d22c16bfdb1..b2588e1102658657e1cb97f7daf01cbd5c0e174f 100644
--- a/source/arviz_godot/lib/avi/scene/LineElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/LineElementNode.h
@@ -9,6 +9,8 @@ namespace avi::scene
         GODOT_CLASS(LineElementNode, ElementNode)
 
     public:
+        ~LineElementNode() override = default;
+
         static void _register_methods();
 
         void _ready();
diff --git a/source/arviz_godot/lib/avi/scene/MeshElementNode.h b/source/arviz_godot/lib/avi/scene/MeshElementNode.h
index 058fd8745857f627716acd4bff5783d7a2457e59..55549bbd3cf466079baf336635bd3fa6dc079f37 100644
--- a/source/arviz_godot/lib/avi/scene/MeshElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/MeshElementNode.h
@@ -15,6 +15,7 @@ namespace avi::scene
 
     public:
         MeshElementNode();
+        ~MeshElementNode() override = default;
 
         void _init();
 
diff --git a/source/arviz_godot/lib/avi/scene/MultiMeshElementNode.cpp b/source/arviz_godot/lib/avi/scene/MultiMeshElementNode.cpp
index 03b4f8b9c9e71496412826c0f4beb273fac1d9e9..9ec0a8b4fdfc0243f64d663b85510999e3cd71e5 100644
--- a/source/arviz_godot/lib/avi/scene/MultiMeshElementNode.cpp
+++ b/source/arviz_godot/lib/avi/scene/MultiMeshElementNode.cpp
@@ -23,12 +23,13 @@ avi::scene::MultiMeshElementNode::getVolume()
 }
 
 void
-avi::scene::MultiMeshElementNode::setPosition(godot::Vector3 position, int index)
+avi::scene::MultiMeshElementNode::setPosition(godot::Vector3 position, size_t index)
 {
 
     auto transform = meshInstances.at(index)->get_transform();
     transform.set_origin(position * avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR);
     meshInstances.at(index)->set_transform(transform);
+
     if (index < collisionShapes.size())
     {
         collisionShapes.at(index)->set_transform(transform);
@@ -36,7 +37,7 @@ avi::scene::MultiMeshElementNode::setPosition(godot::Vector3 position, int index
 }
 
 void
-avi::scene::MultiMeshElementNode::setScale(godot::Vector3 scale, int index)
+avi::scene::MultiMeshElementNode::setScale(godot::Vector3 scale, size_t index)
 {
     staticBody->set_scale({0.001, 0.001, 0.001});
     meshInstances.at(index)->set_scale(scale * avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR);
@@ -47,7 +48,7 @@ avi::scene::MultiMeshElementNode::setScale(godot::Vector3 scale, int index)
 }
 
 void
-avi::scene::MultiMeshElementNode::setRotation(godot::Quat rotation, int index)
+avi::scene::MultiMeshElementNode::setRotation(godot::Quat rotation, size_t index)
 {
     meshInstances.at(index)->set_rotation(rotation.get_euler());
     if (index < collisionShapes.size())
@@ -57,7 +58,7 @@ avi::scene::MultiMeshElementNode::setRotation(godot::Quat rotation, int index)
 }
 
 void
-avi::scene::MultiMeshElementNode::setColor(godot::Color color, int index)
+avi::scene::MultiMeshElementNode::setColor(godot::Color color, size_t index)
 {
     godot::SpatialMaterial* mat =
         cast_to<godot::SpatialMaterial>(meshInstances.at(index)->get_surface_material(0).ptr());
@@ -133,7 +134,7 @@ avi::scene::MultiMeshElementNode::updateAttributes(int flag,
         shapeChecked = true;
     }
     setInteractions(interactions);
-    for (int i = 0; i < meshInstances.size(); i++)
+    for (size_t i = 0; i < meshInstances.size(); i++)
     {
         setPosition(position, i);
         setScale(scale, i);
@@ -160,8 +161,6 @@ avi::scene::MultiMeshElementNode::setMesh(std::vector<godot::Mesh*> meshes)
         material->set_flag(godot::SpatialMaterial::FEATURE_TRANSPARENT, true);
         material->set_flag(godot::SpatialMaterial::FLAG_UNSHADED, false);
         mesh_instance->set_surface_material(0, material);
-        godot::SpatialMaterial* mat =
-            cast_to<godot::SpatialMaterial>(mesh_instance->get_surface_material(0).ptr());
         staticBody->add_child(mesh_instance);
     }
 }
diff --git a/source/arviz_godot/lib/avi/scene/MultiMeshElementNode.h b/source/arviz_godot/lib/avi/scene/MultiMeshElementNode.h
index 4c3091531b2698944e62b12ba67125894ada13f2..336cdeb2922e348f765dd49638ad0c84f9bce21a 100644
--- a/source/arviz_godot/lib/avi/scene/MultiMeshElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/MultiMeshElementNode.h
@@ -15,6 +15,7 @@ namespace avi::scene
 
     public:
         MultiMeshElementNode();
+        ~MultiMeshElementNode() override = default;
 
         void _init();
 
@@ -25,13 +26,13 @@ namespace avi::scene
         godot::AABB getVolume() override;
         godot::Transform getTransform() override;
 
-        void setPosition(godot::Vector3 position, int index);
+        void setPosition(godot::Vector3 position, size_t index);
 
-        void setScale(godot::Vector3 scale, int index);
+        void setScale(godot::Vector3 scale, size_t index);
 
-        void setRotation(godot::Quat rotation, int index);
+        void setRotation(godot::Quat rotation, size_t index);
 
-        void setColor(godot::Color color, int index);
+        void setColor(godot::Color color, size_t index);
 
         void setMesh(std::vector<godot::Mesh*> meshes);
 
diff --git a/source/arviz_godot/lib/avi/scene/ObjectElementNode.cpp b/source/arviz_godot/lib/avi/scene/ObjectElementNode.cpp
index 20e8f37a9713946d28cced85e539841bc76d9280..0535ca08e7705eda83a93608e5e052f06902e6da 100644
--- a/source/arviz_godot/lib/avi/scene/ObjectElementNode.cpp
+++ b/source/arviz_godot/lib/avi/scene/ObjectElementNode.cpp
@@ -4,6 +4,9 @@
 
 #include <CubeMesh.hpp>
 #include <SpatialMaterial.hpp>
+
+#include <VirtualRobot/ManipulationObject.h>
+
 #include <arviz_godot/lib/avi/core/Constants.h>
 #include <arviz_godot/lib/avi/scene/Converter.h>
 
@@ -14,7 +17,17 @@ avi::scene::ObjectElementNode::ObjectElementNode()
 godot::AABB
 avi::scene::ObjectElementNode::getVolume()
 {
-    ARMARX_CHECK_POSITIVE(meshes.size());
+    if (meshes.empty())
+    {
+        // Object files can be empty.
+
+        godot::AABB emptyAABB;
+        emptyAABB.position = staticBody->get_transform().origin;
+        emptyAABB.size = godot::Vector3::ZERO;
+
+        return emptyAABB;
+    }
+
     godot::AABB correctedAABB = meshes.front().meshInstance->get_aabb();
     for (size_t i = 1; i < meshes.size(); ++i)
     {
@@ -84,11 +97,6 @@ avi::scene::ObjectElementNode::newObjectElementNode(avi::core::ModelLoader* load
 
     ObjectElementNode* node = ObjectElementNode::_new();
     node->staticBody = godot::StaticBody::_new();
-    // The collision shapes and mesh instances are created when we set an object model.
-    // node->collisionShape = godot::CollisionShape::_new();
-    // node->meshInstance = godot::MeshInstance::_new();
-    // node->staticBody->add_child(node->collisionShape);
-    // node->staticBody->add_child(node->meshInstance);
     node->add_child(node->staticBody);
     node->loader = loader;
 
@@ -118,23 +126,21 @@ avi::scene::ObjectElementNode::updateAttributes(std::string fileName,
     setInteractionFlag(flag);
     if (this->fileName != fileName)
     {
-        this->fileName = fileName;
-        avi::core::Object object = loader->loadModel(fileName);
-
         // Remove old mesh instances and collision shapes.
         {
             for (Mesh& mesh : meshes)
             {
                 staticBody->remove_child(mesh.meshInstance);
-                // This is probably done by the model cache.
-                // mesh.meshInstance->get_mesh()->unreference();
-                // mesh.meshInstance->get_surface_material(0)->unreference();
 
                 staticBody->remove_child(mesh.collisionShape);
             }
             meshes.clear();
         }
 
+        this->fileName = fileName;
+        std::string fullName;
+        avi::core::Object object = loader->loadModel(fileName, fullName);
+
         for (core::Mesh& m : object.meshes)
         {
             Mesh& mesh = meshes.emplace_back();
@@ -146,18 +152,17 @@ avi::scene::ObjectElementNode::updateAttributes(std::string fileName,
             }
             {
                 mesh.collisionShape = godot::CollisionShape::_new();
-                staticBody->add_child(mesh.collisionShape );
+                staticBody->add_child(mesh.collisionShape);
             }
         }
+
         if (!shapeChecked)
         {
-            if (ElementNode::isSelectable())
-            {
-                setShape();
-            }
+            setShape(loader->getObject(fullName));
             shapeChecked = true;
         }
     }
+
     setInteractions(interactions);
     setPosition(position);
     setScale(scale);
@@ -210,12 +215,21 @@ avi::scene::ObjectElementNode::getTransform()
 }
 
 void
-avi::scene::ObjectElementNode::setShape()
+avi::scene::ObjectElementNode::setShape(VirtualRobot::ManipulationObjectPtr visualization)
 {
-    for (Mesh& mesh : meshes)
+    if (visualization && visualization->getCollisionModel())
+    {
+        core::Object obj = avi::core::ModelLoader::createObjectFromTriMesh(visualization->getCollisionModel()->getTriMeshModel());
+        meshes[0].collisionShape->set_shape(obj.meshes.front().mesh->create_trimesh_shape());
+        obj.meshes.front().material->free();
+    }
+    else
     {
-        godot::Ref<godot::Shape> shape = mesh.meshInstance->get_mesh()->create_trimesh_shape();
-        mesh.collisionShape->set_shape(shape);
+        for (Mesh& mesh : meshes)
+        {
+            godot::Ref<godot::Shape> shape = mesh.meshInstance->get_mesh()->create_trimesh_shape();
+            mesh.collisionShape->set_shape(shape);
+        }
     }
 }
 
diff --git a/source/arviz_godot/lib/avi/scene/ObjectElementNode.h b/source/arviz_godot/lib/avi/scene/ObjectElementNode.h
index 541c7e1c6579730706f7efb2a389f48e411d5e78..7ab2a6aafcf78025ff383105311753af42d72933 100644
--- a/source/arviz_godot/lib/avi/scene/ObjectElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/ObjectElementNode.h
@@ -20,6 +20,7 @@ namespace avi::scene
 
     public:
         ObjectElementNode();
+        ~ObjectElementNode() override = default;
 
         void _init();
 
@@ -49,7 +50,7 @@ namespace avi::scene
 
         godot::Vector3 getScale();
 
-        void setShape();
+        void setShape(VirtualRobot::ManipulationObjectPtr visualization);
 
         void setStartAttributes(avi::connection::SentElementType type,
                                 std::string name,
diff --git a/source/arviz_godot/lib/avi/scene/OrientationIndicator.h b/source/arviz_godot/lib/avi/scene/OrientationIndicator.h
index c6f3db0a2830c126703c9ff4310440d932cebe6f..dbd0d0b6b000a4b06c3b7cd17fda587c60e266aa 100644
--- a/source/arviz_godot/lib/avi/scene/OrientationIndicator.h
+++ b/source/arviz_godot/lib/avi/scene/OrientationIndicator.h
@@ -13,6 +13,7 @@ namespace avi::scene
 
     public:
         OrientationIndicator();
+        ~OrientationIndicator() = default;
 
         void _init();
 
diff --git a/source/arviz_godot/lib/avi/scene/PathElementNode.cpp b/source/arviz_godot/lib/avi/scene/PathElementNode.cpp
index b59f41789519d3560bb5592124d42bd9346fe390..673a2b2d1c41f511ac5a5ccc47289e7e71e82b67 100644
--- a/source/arviz_godot/lib/avi/scene/PathElementNode.cpp
+++ b/source/arviz_godot/lib/avi/scene/PathElementNode.cpp
@@ -24,8 +24,15 @@ avi::scene::PathElementNode::update(IceInternal::Handle<armarx::viz::data::Eleme
     auto path = IceInternal::Handle<armarx::viz::data::ElementPath>::dynamicCast(elementInfo);
     auto* mesh = godot::Object::cast_to<godot::ArrayMesh>(getMesh());
     godot::PoolVector3Array coords;
+    coords.resize(path->points.size());
+    godot::Vector3* coordsPtr = coords.write().ptr();
+
     for (auto& vertex : path->points)
-        coords.push_back(godot::Vector3(vertex.e0, vertex.e1, vertex.e2));
+    {
+        *coordsPtr = godot::Vector3(vertex.e0, vertex.e1, vertex.e2);
+        coordsPtr++;
+    }
+
     godot::Array arr{};
     arr.resize(godot::ArrayMesh::ARRAY_MAX);
     arr[godot::ArrayMesh::ARRAY_VERTEX] = coords;
diff --git a/source/arviz_godot/lib/avi/scene/PathElementNode.h b/source/arviz_godot/lib/avi/scene/PathElementNode.h
index 0dea46faca213a2215122e3eac05618ea060e5c0..5fe20e578faee39438cb11a7a60e80d6a625d540 100644
--- a/source/arviz_godot/lib/avi/scene/PathElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/PathElementNode.h
@@ -9,6 +9,8 @@ namespace avi::scene
         GODOT_CLASS(PathElementNode, ElementNode)
 
     public:
+        ~PathElementNode() override = default;
+
         static void _register_methods();
 
         void _ready();
diff --git a/source/arviz_godot/lib/avi/scene/PlayfulControlScheme.cpp b/source/arviz_godot/lib/avi/scene/PlayfulControlScheme.cpp
index 2b062ec3bc62054689f9d5685e69df20f75177e1..acf64f3956467979b4e835cbd1464aef4be40484 100644
--- a/source/arviz_godot/lib/avi/scene/PlayfulControlScheme.cpp
+++ b/source/arviz_godot/lib/avi/scene/PlayfulControlScheme.cpp
@@ -23,8 +23,18 @@ void
 avi::scene::PlayfulControlScheme::_init()
 {
     viewCamera = nullptr;
-    gui = nullptr;
     scrollValue = 0.0f;
+
+    inputState = std::vector<bool>(MAX_INPUT_INDEX, false);
+
+    inputKeys.push_back("avi_camera_forward");
+    inputKeys.push_back("avi_camera_backward");
+    inputKeys.push_back("avi_camera_left");
+    inputKeys.push_back("avi_camera_right");
+    inputKeys.push_back("avi_camera_up");
+    inputKeys.push_back("avi_camera_down");
+    inputKeys.push_back("avi_camera_roll_left");
+    inputKeys.push_back("avi_camera_roll_right");
 }
 
 void
@@ -36,7 +46,7 @@ avi::scene::PlayfulControlScheme::_ready()
 void
 avi::scene::PlayfulControlScheme::_unhandled_input(godot::InputEvent* event)
 {
-    if (!this->viewCamera) return;
+    if (!isActive()) return;
 
     auto* mouseMotionEvent = cast_to<godot::InputEventMouseMotion>(event);
     if (mouseMotionEvent)
@@ -63,17 +73,22 @@ avi::scene::PlayfulControlScheme::_unhandled_input(godot::InputEvent* event)
         scrollValue += change;
         scrollValue = std::clamp(scrollValue, -100.0f, 200.0f);
     }
+
+    for (auto i = 0; i < MAX_INPUT_INDEX; i++)
+    {
+        if (event->is_action_pressed(inputKeys[i]))
+            inputState[i] = true;
+    }
 }
 
 void
 avi::scene::PlayfulControlScheme::_process(float delta)
 {
+    if (!isActive()) return;
+
     godot::Vector2 oldMouseDelta = mouseDelta;
     mouseDelta = {0, 0};
 
-    if (!isActive())
-        return;
-
     if (isTraveling)
     {
         doTravel(delta);
@@ -82,6 +97,12 @@ avi::scene::PlayfulControlScheme::_process(float delta)
 
     godot::Input* input = godot::Input::get_singleton();
 
+    for (auto i = 0; i < MAX_INPUT_INDEX; i++)
+    {
+        if (!input->is_action_pressed(inputKeys[i]))
+            inputState[i] = false;
+    }
+
     bool rotate = input->is_action_pressed("avi_camera_mouse") || viewCamera->isMouseLocked();
 
     if (rotate)
@@ -90,23 +111,18 @@ avi::scene::PlayfulControlScheme::_process(float delta)
         attachment->rotate_object_local({1, 0, 0}, oldMouseDelta.y * delta * -1.0f);
     }
 
-    // To prevent moving while typing, we check if any gui element has focus.
-    // This is not ideal (using just unhandled input would be better), but accumulating the unhandled input is not as smooth.
-    auto* focus = gui->get_focus_owner();
-    if (focus) return;
-
     godot::Vector3 movement;
-    if (input->is_action_pressed("avi_camera_forward"))
+    if (inputState[INPUT_FORWARD])
         movement += {0, 0, -1};
-    if (input->is_action_pressed("avi_camera_backward"))
+    if (inputState[INPUT_BACKWARD])
         movement += {0, 0, 1};
-    if (input->is_action_pressed("avi_camera_left"))
+    if (inputState[INPUT_LEFT])
         movement += {-1, 0, 0};
-    if (input->is_action_pressed("avi_camera_right"))
+    if (inputState[INPUT_RIGHT])
         movement += {1, 0, 0};
-    if (input->is_action_pressed("avi_camera_up"))
+    if (inputState[INPUT_UP])
         movement += {0, 1, 0};
-    if (input->is_action_pressed("avi_camera_down"))
+    if (inputState[INPUT_DOWN])
         movement += {0, -1, 0};
 
     if (movement.length() > 0)
@@ -119,9 +135,9 @@ avi::scene::PlayfulControlScheme::_process(float delta)
     }
 
     float roll = 0;
-    if (input->is_action_pressed("avi_camera_roll_left"))
+    if (inputState[INPUT_ROLL_LEFT])
         roll += 1;
-    if (input->is_action_pressed("avi_camera_roll_right"))
+    if (inputState[INPUT_ROLL_RIGHT])
         roll -= 1;
 
     if (roll != 0)
@@ -140,8 +156,6 @@ avi::scene::PlayfulControlScheme::takeOver(avi::scene::ViewCamera* viewCamera)
     viewCamera->set_transform(godot::Transform());
 
     attachment->add_child(viewCamera);
-
-    if (!gui) gui = get_tree()->get_root()->get_node<godot::Control>("Root/GUI");
 }
 
 void
@@ -164,7 +178,7 @@ avi::scene::PlayfulControlScheme::focus(godot::AABB box)
     godot::Transform transform;
     transform.origin = box.position + (box.size * 0.5f);
 
-    transform.origin.x -= box.get_longest_axis_size() * 2;
+    transform.origin.x -= box.get_longest_axis_size();
     //transform.origin.y += box.size.y;
 
     transform = transform.looking_at(box.position + box.size * 0.5f, {0, 1, 0});
@@ -173,7 +187,7 @@ avi::scene::PlayfulControlScheme::focus(godot::AABB box)
 }
 
 void
-avi::scene::PlayfulControlScheme::focus(godot::Vector3 point)
+avi::scene::PlayfulControlScheme::focus(godot::Vector3 point, avi::core::Element* target)
 {
     godot::Transform transform = attachment->get_transform();
     godot::Vector3 path = point - transform.origin;
diff --git a/source/arviz_godot/lib/avi/scene/PlayfulControlScheme.h b/source/arviz_godot/lib/avi/scene/PlayfulControlScheme.h
index e9d2ca6bf0be28c280eef6ddfa073295e86769ad..093532a52597085a34a7b796ac2d93f0c8a34469 100644
--- a/source/arviz_godot/lib/avi/scene/PlayfulControlScheme.h
+++ b/source/arviz_godot/lib/avi/scene/PlayfulControlScheme.h
@@ -13,6 +13,8 @@ namespace avi::scene
         GODOT_CLASS(PlayfulControlScheme, Spatial)
 
     public:
+        ~PlayfulControlScheme() override = default;
+
         static void _register_methods();
 
         void _init();
@@ -32,7 +34,7 @@ namespace avi::scene
 
         void focus(godot::AABB box) override;
 
-        void focus(godot::Vector3 point) override;
+        void focus(godot::Vector3 point, avi::core::Element* target) override;
 
         godot::Basis getRotationBasis() override;
 
@@ -44,8 +46,6 @@ namespace avi::scene
         void doTravel(float delta);
 
     private:
-        godot::Control* gui;
-
         struct Travel
         {
             godot::Transform startTransform{};
@@ -61,6 +61,22 @@ namespace avi::scene
         godot::Spatial* attachment;
         avi::scene::ViewCamera* viewCamera;
 
+        std::vector<bool> inputState;
+        std::vector<const char*> inputKeys;
+
+        enum InputStateIndex
+        {
+            INPUT_FORWARD,
+            INPUT_BACKWARD,
+            INPUT_LEFT,
+            INPUT_RIGHT,
+            INPUT_UP,
+            INPUT_DOWN,
+            INPUT_ROLL_LEFT,
+            INPUT_ROLL_RIGHT,
+            MAX_INPUT_INDEX
+        };
+
         godot::Vector2 mouseDelta;
         float scrollValue;
     };
diff --git a/source/arviz_godot/lib/avi/scene/PointCloudElementNode.cpp b/source/arviz_godot/lib/avi/scene/PointCloudElementNode.cpp
index 9fb6cd2672c617c739479e09db87ef002827b50f..bb1bf91ee97c8ff390ff1cd18ecfb000c493db3e 100644
--- a/source/arviz_godot/lib/avi/scene/PointCloudElementNode.cpp
+++ b/source/arviz_godot/lib/avi/scene/PointCloudElementNode.cpp
@@ -3,6 +3,7 @@
 #include <BoxShape.hpp>
 #include <Mesh.hpp>
 #include <MeshInstance.hpp>
+#include <PointMesh.hpp>
 #include <arviz_godot/lib/avi/core/Constants.h>
 #include <arviz_godot/lib/avi/scene/Converter.h>
 
@@ -27,24 +28,34 @@ avi::scene::PointCloudElementNode::_ready()
 }
 
 avi::scene::PointCloudElementNode*
-avi::scene::PointCloudElementNode::newPointCloudElementNode(
-    avi::connection::SentElementType type,
-    std::string name,
-    avi::core::Layer* layer,
-    avi::scene::GraphicsController* controller)
+avi::scene::PointCloudElementNode::newPointCloudElementNode(avi::connection::SentElementType type,
+                                                            std::string name,
+                                                            avi::core::Layer* layer)
 {
     PointCloudElementNode* node = PointCloudElementNode::_new();
     node->staticBody = godot::StaticBody::_new();
     node->collisionShape = godot::CollisionShape::_new();
-    node->im = godot::ImmediateGeometry::_new();
-    node->add_child(node->im);
+    node->multiMeshInstance = godot::MultiMeshInstance::_new();
+
+    node->mesh = godot::PointMesh::_new();
+    node->multiMesh = godot::MultiMesh::_new();
+    node->multiMesh->set_mesh(node->mesh);
+
+    node->multiMesh->set_transform_format(godot::MultiMesh::TRANSFORM_3D);
+    node->multiMesh->set_color_format(godot::MultiMesh::COLOR_8BIT);
+    node->multiMesh->set_custom_data_format(godot::MultiMesh::CUSTOM_DATA_NONE);
+
     node->staticBody->add_child(node->collisionShape);
+    node->staticBody->add_child(node->multiMeshInstance);
     node->add_child(node->staticBody);
+
+    node->multiMeshInstance->set_multimesh(node->multiMesh);
+
     node->material = godot::SpatialMaterial::_new();
     node->material->set_flag(godot::SpatialMaterial::FLAG_USE_POINT_SIZE, true);
-    node->material->set_albedo(avi::core::KIT_GREEN);
-    node->im->set_material_override(node->material);
-    node->controller = controller;
+    node->material->set_flag(godot::SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+    node->multiMeshInstance->set_material_override(node->material);
+
     node->setStartAttributes(type, name, layer);
     return node;
 }
@@ -100,14 +111,11 @@ avi::scene::PointCloudElementNode::updateAttributes(int flag,
                                                     godot::Color color)
 {
     setInteractionFlag(flag);
-    if (!shapeChecked)
+    if (ElementNode::isSelectable())
     {
-        if (ElementNode::isSelectable())
-        {
-            setShape();
-        }
-        shapeChecked = true;
+        setShape();
     }
+
     setInteractions(interactions);
     setPosition(position);
     setScale(scale);
@@ -118,101 +126,64 @@ void
 avi::scene::PointCloudElementNode::drawPointCloud(ulong pointCloudSize,
                                                   const armarx::viz::data::ColoredPoint* pointPtr)
 {
+    const size_t perInstanceData = 12 + 1;
 
-    im->clear();
-    for (auto geo : drawers)
+    int requiredSize = static_cast<int>(pointCloudSize * perInstanceData);
+    if (multiMeshData.size() != requiredSize)
     {
-        geo.second->clear();
+        multiMeshData.resize(requiredSize);
     }
-    colored = controller->getPointCloudStyle();
-    if (!colored)
-    {
-        im->begin(godot::Mesh::PRIMITIVE_POINTS, nullptr);
-        for (ulong i = 0; i < pointCloudSize; i++)
-        {
-            im->add_vertex(godot::Vector3(
-                (pointPtr[i].x / avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR + (position.x)),
-                (pointPtr[i].y / avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR + (position.y)),
-                (pointPtr[i].z / avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR + (position.z))));
-        }
-        im->end();
-    }
-    else
+
+    real_t* data = multiMeshData.write().ptr();
+
+    for (ulong pointIndex = 0; pointIndex < pointCloudSize; pointIndex++)
     {
-        for (auto geo : drawers)
-        {
-            geo.second->begin(godot::Mesh::PRIMITIVE_POINTS, nullptr);
-        }
-        for (ulong i = 0; i < pointCloudSize; i++)
-        {
-            if (drawers.count(pointPtr[i].color) > 0)
-            {
-                drawers.at(pointPtr[i].color)
-                    ->add_vertex(godot::Vector3(
-                        (pointPtr[i].x / avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR +
-                         (position.x)),
-                        (pointPtr[i].y / avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR +
-                         (position.y)),
-                        (pointPtr[i].z / avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR +
-                         (position.z))));
-            }
-            else
-            {
-                auto imm = godot::ImmediateGeometry::_new();
-                this->add_child(imm);
-                material = godot::SpatialMaterial::_new();
-                material->set_flag(godot::SpatialMaterial::FLAG_USE_POINT_SIZE, true);
-                if (pointPtr[i].color.a < 255)
-                {
-                    material->set_feature(godot::SpatialMaterial::FEATURE_TRANSPARENT, true);
-                }
-                material->set_albedo(godot::Color(
-                    (static_cast<float>(pointPtr[i].color.r)) / avi::core::RGB_CONVERSION_FACTOR,
-                    (static_cast<float>(pointPtr[i].color.g)) / avi::core::RGB_CONVERSION_FACTOR,
-                    (static_cast<float>(pointPtr[i].color.b)) / avi::core::RGB_CONVERSION_FACTOR,
-                    (static_cast<float>(pointPtr[i].color.a)) / avi::core::RGB_CONVERSION_FACTOR));
-                imm->set_material_override(material);
-                imm->begin(godot::Mesh::PRIMITIVE_POINTS, nullptr);
-                imm->add_vertex(godot::Vector3(
-                    (pointPtr[i].x / avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR + (position.x)),
-                    (pointPtr[i].y / avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR + (position.y)),
-                    (pointPtr[i].z / avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR + (position.z))));
-                drawers.insert(std::make_pair(pointPtr[i].color, imm));
-            }
-        }
-        for (auto geo : drawers)
-        {
-            geo.second->end();
-        }
+        const armarx::viz::data::ColoredPoint* point = pointPtr + pointIndex;
+        real_t* currentData = data + (pointIndex * perInstanceData);
+
+        size_t i = 0;
+
+        currentData[i++] = 1.0f;
+        currentData[i++] = 0.0f;
+        currentData[i++] = 0.0f;
+        currentData[i++] = point->x;
+
+        currentData[i++] = 0.0f;
+        currentData[i++] = 1.0f;
+        currentData[i++] = 0.0f;
+        currentData[i++] = point->y;
+
+        currentData[i++] = 0.0f;
+        currentData[i++] = 0.0f;
+        currentData[i++] = 1.0f;
+        currentData[i++] = point->z;
+
+        auto* colors = reinterpret_cast<uint8_t*>(currentData + i++);
+        colors[0] = point->color.r;
+        colors[1] = point->color.g;
+        colors[2] = point->color.b;
+        colors[3] = point->color.a;
+
+        minPoint = {std::min(minPoint.x, point->x),
+                    std::min(minPoint.y, point->y),
+                    std::min(minPoint.z, point->z)};
+        maxPoint = {std::max(maxPoint.x, point->x),
+                    std::max(maxPoint.y, point->y),
+                    std::max(maxPoint.z, point->z)};
     }
+
+    multiMesh->set_instance_count(static_cast<int64_t>(pointCloudSize));
+    multiMesh->set_as_bulk_array(multiMeshData);
 }
 
 godot::AABB
 avi::scene::PointCloudElementNode::getVolume()
 {
-    godot::AABB volume;
-    if (colored)
-    {
-        bool init = false;
-        for (auto drawer : drawers)
-        {
-            if (init)
-            {
-                volume.merge_with(drawer.second->get_aabb());
-            }
-            else
-            {
-                volume = drawer.second->get_aabb();
-                init = true;
-            }
-        }
-    }
-    else
-    {
-        volume = im->get_aabb();
-    }
+    godot::Vector3 position = minPoint;
+    godot::Vector3 size = maxPoint - minPoint;
 
-    return volume;
+    return {position / avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR,
+            size / avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR};
 }
 
 void
@@ -222,12 +193,12 @@ avi::scene::PointCloudElementNode::update(
     auto pointCloud =
         IceInternal::Handle<armarx::viz::data::ElementPointCloud>::dynamicCast(elementInfo);
 
-    ulong pointCloudSize = pointCloud->points.size() / sizeof(armarx::viz::data::ColoredPoint);
+    material->set_point_size(pointCloud->pointSizeInPixels);
 
+    ulong pointCloudSize = pointCloud->points.size() / sizeof(armarx::viz::data::ColoredPoint);
     auto pointPtr = (armarx::viz::data::ColoredPoint const*)pointCloud->points.data();
 
-    avi::scene::PointCloudElementNode* pointCloudNode =
-        godot::Object::cast_to<avi::scene::PointCloudElementNode>(this);
+    auto* pointCloudNode = godot::Object::cast_to<avi::scene::PointCloudElementNode>(this);
 
     pointCloudNode->updateAttributes(pointCloud->interaction.enableFlags,
                                      pointCloud->interaction.contextMenuOptions,
@@ -252,14 +223,30 @@ avi::scene::PointCloudElementNode::getTransform()
 void
 avi::scene::PointCloudElementNode::setShape()
 {
-    godot::Ref<godot::BoxShape> shape = godot::BoxShape::_new();
-    collisionShape->set_shape(shape);
-    collisionShape->set_scale({100, 100, 100});
-    collisionShape->set_translation(position);
+    if (!shapeExists)
+    {
+        godot::Ref<godot::BoxShape> shape = godot::BoxShape::_new();
+        collisionShape->set_shape(shape);
+
+        shapeExists = true;
+    }
+
+    godot::AABB volume = getVolume();
+
+    if (volume != shapeVolume)
+    {
+        shapeVolume = volume;
+
+        volume.position *= avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR;
+        volume.size *= avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR;
+
+        collisionShape->set_scale(volume.size * 0.5f);
+        collisionShape->set_translation(volume.position + volume.size * 0.5f);
+    }
 }
 
 std::vector<godot::Spatial*>
 avi::scene::PointCloudElementNode::getSpatial()
 {
-    return std::vector<godot::Spatial*>();
+    return {};
 }
diff --git a/source/arviz_godot/lib/avi/scene/PointCloudElementNode.h b/source/arviz_godot/lib/avi/scene/PointCloudElementNode.h
index 63cd58f5d07bcfac4d491591ece12b20f18919e7..711f9b8a7345dae7e9fec314590fe5898e99dca8 100644
--- a/source/arviz_godot/lib/avi/scene/PointCloudElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/PointCloudElementNode.h
@@ -3,7 +3,10 @@
 #include <RobotAPI/interface/ArViz/Elements.h>
 
 #include <CollisionShape.hpp>
-#include <ImmediateGeometry.hpp>
+#include <MeshInstance.hpp>
+#include <Mesh.hpp>
+#include <MultiMesh.hpp>
+#include <MultiMeshInstance.hpp>
 #include <SpatialMaterial.hpp>
 #include <StaticBody.hpp>
 #include <Texture.hpp>
@@ -19,6 +22,7 @@ namespace avi::scene
 
     public:
         PointCloudElementNode();
+        ~PointCloudElementNode() override = default;
 
         void _init();
 
@@ -36,8 +40,7 @@ namespace avi::scene
         static PointCloudElementNode*
         newPointCloudElementNode(avi::connection::SentElementType type,
                                  std::string name,
-                                 avi::core::Layer* layer,
-                                 avi::scene::GraphicsController* controller);
+                                 avi::core::Layer* layer);
 
         void setPosition(godot::Vector3 position);
 
@@ -62,8 +65,12 @@ namespace avi::scene
                               godot::Color color);
 
     private:
-        godot::ImmediateGeometry* im;
-        std::map<armarx::viz::data::Color, godot::ImmediateGeometry*> drawers{};
+        godot::MultiMeshInstance* multiMeshInstance;
+        godot::Mesh* mesh;
+        godot::MultiMesh* multiMesh;
+
+        godot::PoolRealArray multiMeshData{};
+
         godot::SpatialMaterial* material;
         godot::Vector3 position;
         godot::Vector3 scale;
@@ -72,11 +79,11 @@ namespace avi::scene
         godot::StaticBody* staticBody;
         godot::CollisionShape* collisionShape;
 
-        avi::scene::GraphicsController* controller{};
-
-        bool colored = false;
+        godot::Vector3 minPoint{};
+        godot::Vector3 maxPoint{};
 
-        bool shapeChecked = false;
+        bool shapeExists = false;
+        godot::AABB shapeVolume;
 
     protected:
         std::vector<godot::Spatial*> getSpatial() override;
diff --git a/source/arviz_godot/lib/avi/scene/PolygonElementNode.h b/source/arviz_godot/lib/avi/scene/PolygonElementNode.h
index 97e56c0d2f0c88be2cb27125233df142d84ebca6..d7fe0bb94551eb7022611ffa6c2e0975f4e9455a 100644
--- a/source/arviz_godot/lib/avi/scene/PolygonElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/PolygonElementNode.h
@@ -9,6 +9,7 @@ namespace avi::scene
         GODOT_CLASS(PolygonElementNode, ElementNode)
 
     public:
+        ~PolygonElementNode() override = default;
         static void _register_methods();
 
         void _ready();
diff --git a/source/arviz_godot/lib/avi/scene/PoseElementNode.cpp b/source/arviz_godot/lib/avi/scene/PoseElementNode.cpp
index a07a6649154f7e08d036a150a6e5f44dd0162084..e390654acd9ff58c20f0cf0916825f53e4ebc3a0 100644
--- a/source/arviz_godot/lib/avi/scene/PoseElementNode.cpp
+++ b/source/arviz_godot/lib/avi/scene/PoseElementNode.cpp
@@ -8,11 +8,9 @@
 #include <arviz_godot/lib/avi/core/Constants.h>
 #include <arviz_godot/lib/avi/scene/Converter.h>
 
-godot::Mesh* avi::scene::PoseElementNode::mesh = nullptr;
+godot::Ref<godot::Mesh> avi::scene::PoseElementNode::mesh = nullptr;
 
-avi::scene::PoseElementNode::PoseElementNode()
-{
-}
+avi::scene::PoseElementNode::PoseElementNode() = default;
 
 godot::AABB
 avi::scene::PoseElementNode::getVolume()
@@ -26,12 +24,6 @@ avi::scene::PoseElementNode::getVolume()
 
 void
 avi::scene::PoseElementNode::_register_methods()
-{
-    register_method("_ready", &PoseElementNode::_ready);
-}
-
-void
-avi::scene::PoseElementNode::_ready()
 {
 }
 
@@ -41,14 +33,14 @@ avi::scene::PoseElementNode::setPosition(godot::Vector3 position)
     auto transform = staticBody->get_transform();
     transform.set_origin(position);
     staticBody->set_transform(transform);
-    sprite->set_translation({5, static_cast<real_t>(label->get_size().y * 0.0025 + 5), 0});
+    sprite->set_translation({5, label->get_size().y * textDownscaling * 0.5f + 5, 2});
 }
 
 void
 avi::scene::PoseElementNode::setScale(godot::Vector3 scale)
 {
     staticBody->set_scale(scale);
-    sprite->set_scale({0.025, 0.025, 0.025});
+    sprite->set_scale({textDownscaling, textDownscaling, textDownscaling});
 }
 
 void
@@ -98,24 +90,27 @@ avi::scene::PoseElementNode::newPoseElementNode()
     godot::Ref<godot::Font> font = loader->load("res://fonts/font.tres");
 
     PoseElementNode* node = PoseElementNode::_new();
+
     node->staticBody = godot::StaticBody::_new();
     node->collisionShape = godot::CollisionShape::_new();
     node->poseMeshInstance = godot::MeshInstance::_new();
-    godot::Sprite3D* sprite3D = godot::Sprite3D::_new();
-    godot::Label* label = godot::Label::_new();
-    label->add_font_override("font", font);
-    label->set_modulate(godot::Color(0, 0, 0));
 
-    godot::Viewport* viewport = godot::Viewport::_new();
+    node->label = godot::Label::_new();
+    node->label->add_font_override("font", font);
+    node->label->set_modulate(godot::Color(0, 0, 0));
+
+    node->viewport = godot::Viewport::_new();
+    node->sprite = godot::Sprite3D::_new();
+
+    node->viewport->add_child(node->label);
+    node->sprite->add_child(node->viewport);
+
     node->staticBody->add_child(node->collisionShape);
     node->staticBody->add_child(node->poseMeshInstance);
-    viewport->add_child(label);
-    sprite3D->add_child(viewport);
-    node->staticBody->add_child(sprite3D);
+    node->staticBody->add_child(node->sprite);
+
     node->add_child(node->staticBody);
-    node->sprite = sprite3D;
-    node->label = label;
-    node->viewport = viewport;
+
     return node;
 }
 
@@ -127,16 +122,14 @@ avi::scene::PoseElementNode::setStartAttributes(avi::connection::SentElementType
     setType(type);
     setName(name);
     setLayer(layer);
-    if (!mesh)
+
+    if (mesh.is_null())
     {
         godot::ResourceLoader* loader = godot::ResourceLoader::get_singleton();
-        godot::Ref<godot::Mesh> poseMesh = loader->load("res://models/pose.obj");
-        mesh = poseMesh.ptr();
-    }
-    if (poseMeshInstance->get_mesh().is_null())
-    {
-        poseMeshInstance->set_mesh(mesh);
+        mesh = loader->load("res://models/pose.obj");
     }
+
+    poseMeshInstance->set_mesh(mesh);
 }
 
 void
@@ -150,18 +143,23 @@ avi::scene::PoseElementNode::updateAttributes(int flag,
     if (sprite->get_texture().ptr() == nullptr)
     {
         sprite->set_texture(viewport->get_texture());
+
         viewport->set_transparent_background(true);
         viewport->set_vflip(true);
+
         sprite->set_pixel_size(1);
+
         label->set_text(ElementNode::getName().c_str());
         label->set_size(label->get_custom_minimum_size());
         label->_update_minimum_size();
         label->set_size(godot::Vector2(2 * label->get_size().x, label->get_size().y));
         label->set_align(godot::Label::ALIGN_RIGHT);
+
         viewport->set_size(label->get_size());
     }
 
     setInteractionFlag(flag);
+
     if (!shapeChecked)
     {
         if (ElementNode::isSelectable())
@@ -170,6 +168,7 @@ avi::scene::PoseElementNode::updateAttributes(int flag,
         }
         shapeChecked = true;
     }
+
     setInteractions(interactions);
     setScale(scale);
     setPosition(position);
diff --git a/source/arviz_godot/lib/avi/scene/PoseElementNode.h b/source/arviz_godot/lib/avi/scene/PoseElementNode.h
index 5dc2dc6a860bed198fb82688f448d736d7dbaff7..72c5603d8fd3b4de285cbc5fab3ee3ef67ba2c23 100644
--- a/source/arviz_godot/lib/avi/scene/PoseElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/PoseElementNode.h
@@ -22,6 +22,7 @@ namespace avi::scene
 
     public:
         PoseElementNode();
+        ~PoseElementNode() override = default;
 
         void _init();
 
@@ -33,8 +34,6 @@ namespace avi::scene
 
         static void _register_methods();
 
-        void _ready();
-
         godot::AABB getVolume() override;
         godot::Transform getTransform() override;
 
@@ -67,9 +66,11 @@ namespace avi::scene
                               godot::Quat rotation,
                               godot::Color color);
 
-        static godot::Mesh* mesh;
+        static godot::Ref<godot::Mesh> mesh;
 
     private:
+        const real_t textDownscaling = 0.025;
+
         godot::MeshInstance* poseMeshInstance;
         godot::Sprite3D* sprite;
         godot::Label* label;
diff --git a/source/arviz_godot/lib/avi/scene/Profile.h b/source/arviz_godot/lib/avi/scene/Profile.h
index 442101252fdbea13adc77dde0c78cbe5a887e81f..afaf10f3ade03eada5a9d25999faadb821e21ac3 100644
--- a/source/arviz_godot/lib/avi/scene/Profile.h
+++ b/source/arviz_godot/lib/avi/scene/Profile.h
@@ -17,7 +17,6 @@ namespace avi::scene
         double lightIntensity = 1.0f;
         double fov = 70.0f;
         avi::scene::DrawStyle drawStyle = avi::scene::DrawStyle::ORIGINAL;
-        bool coloredPointCloud = false;
         bool cameraHeadlight = false;
 
     public:
@@ -40,7 +39,6 @@ namespace avi::scene
             options.ADD_OPTION(double, lightIntensity);
             options.ADD_OPTION(double, fov);
             options.ADD_OPTION(avi::scene::DrawStyle, drawStyle);
-            options.ADD_OPTION(bool, coloredPointCloud);
             options.ADD_OPTION(bool, cameraHeadlight);
 
             return options;
diff --git a/source/arviz_godot/lib/avi/scene/RobotElementNode.cpp b/source/arviz_godot/lib/avi/scene/RobotElementNode.cpp
index 3b6f8aa0b73ac65d2dbdcc4e832e175b4ab54de1..423c99cf8bb8327d712b2bb460e20ab73dd33759 100644
--- a/source/arviz_godot/lib/avi/scene/RobotElementNode.cpp
+++ b/source/arviz_godot/lib/avi/scene/RobotElementNode.cpp
@@ -241,77 +241,98 @@ avi::scene::RobotElementNode::_init()
 void
 avi::scene::RobotElementNode::visualizeRobot()
 {
-
     for (auto node : nodes)
     {
         node.second->queue_free();
     }
+
     nodes.clear();
-    for (auto collisionShape : collisionShapes)
+
+    for (const auto& collisionShape : collisionShapes)
     {
         collisionShape.second->queue_free();
     }
     collisionShapes.clear();
+
     if (!robot)
         return;
-    if (drawStyle == avi::scene::DrawStyle::VISUALIZATION)
+
+
+    for (const std::string& nodeName : robot->getRobotNodeNames())
     {
-        for (const std::string& nodeName : robot->getRobotNodeNames())
-        {
-            auto node = robot->getRobotNode(nodeName);
+        auto node = robot->getRobotNode(nodeName);
 
-            if (!node->getVisualization())
+        auto loadObject = [&] (VirtualRobot::VisualizationNodePtr visualization) -> std::optional<avi::core::Object> {
+            std::string nodeFilename = visualization->getFilename();
+
+            if (not nodeFilename.empty())
+            {
+                avi::core::Object object = modelLoader->loadModelFromFile(nodeFilename);
+
+                ARMARX_CHECK_POSITIVE(object.meshes.size());
+                return object;
+            }
+            else if (visualization->getTriMeshModel())
             {
-                continue;
+                avi::core::Object object
+                    = avi::core::ModelLoader::createObjectFromTriMesh(visualization->getTriMeshModel());
+
+                ARMARX_CHECK_POSITIVE(object.meshes.size());
+                return object;
             }
 
-            std::string nodeFilename = node->getVisualization()->getFilename();
-            avi::core::Object object = modelLoader->loadModelFromFile(nodeFilename);
-            ARMARX_CHECK_POSITIVE(object.meshes.size());
+            return {};
+        };
+
+        auto addMeshFromObject = [&] (const std::optional<avi::core::Object>& object) {
+            if (not object.has_value()) return;
+            auto actualObject = object.value();
+
+            const avi::core::Mesh& mesh = actualObject.meshes.front();
+            godot::MeshInstance* m = godot::MeshInstance::_new();
+            m->set_name(nodeName.c_str());
+            m->set_mesh(mesh.mesh);
+            mesh.material->set_flag(godot::SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+            m->set_material_override(mesh.material);
+
+            staticBody->add_child(m);
+            nodes.emplace(nodeName, m);
+        };
+
+        auto addShapeFromObject = [&] (const std::optional<avi::core::Object>& object) {
+            if (not object.has_value()) return;
+            auto actualObject = object.value();
+
+            const avi::core::Mesh& mesh = actualObject.meshes.front();
+            addShape(mesh.mesh, nodeName);
+
+            mesh.material->unreference();
+        };
+
+        VirtualRobot::VisualizationNodePtr visualization = node->getVisualization();
+        VirtualRobot::VisualizationNodePtr collision = node->getCollisionModel() ? node->getCollisionModel()->getVisualization() : nullptr;
+
+        bool useCollisionAsVisualization = drawStyle != avi::scene::DrawStyle::VISUALIZATION;
+
+        if (useCollisionAsVisualization)
+        {
+            if (collision)
             {
-                core::Mesh& mesh = object.meshes.front();
-                godot::MeshInstance* m = godot::MeshInstance::_new();
-                m->set_mesh(mesh.mesh);
-                mesh.material->set_flag(godot::SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
-                m->set_material_override(mesh.material);
-
-                staticBody->add_child(m);
-                nodes.emplace(nodeName, m);
-                if (ElementNode::isSelectable())
-                {
-                    addShape(mesh.mesh, nodeName);
-                }
+                auto object = loadObject(collision);
+                addMeshFromObject(object);
+                addShapeFromObject(object);
             }
         }
-    }
-    else
-    {
-        for (const std::string& nodeName : robot->getRobotNodeNames())
+        else
         {
-            auto node = robot->getRobotNode(nodeName);
-
-            if (!node->getCollisionModel() || !node->getCollisionModel()->getVisualization())
+            if (visualization)
             {
-                continue;
+                addMeshFromObject(loadObject(visualization));
             }
 
-            std::string nodeFilename = node->getCollisionModel()->getVisualization()->getFilename();
-            avi::core::Object object = modelLoader->loadModelFromFile(nodeFilename);
-            ARMARX_CHECK_POSITIVE(object.meshes.size());
+            if (collision)
             {
-                core::Mesh& mesh = object.meshes.front();
-
-                godot::MeshInstance* m = godot::MeshInstance::_new();
-                m->set_mesh(mesh.mesh);
-                mesh.material->set_flag(godot::SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
-                m->set_material_override(mesh.material);
-
-                staticBody->add_child(m);
-                nodes.emplace(nodeName, m);
-                if (ElementNode::isSelectable())
-                {
-                    addShape(mesh.mesh, nodeName);
-                }
+                addShapeFromObject(loadObject(collision));
             }
         }
     }
diff --git a/source/arviz_godot/lib/avi/scene/RobotElementNode.h b/source/arviz_godot/lib/avi/scene/RobotElementNode.h
index 3c50fe573ff4a9d3c15f2b0b0e83884c2c560b7b..7fb623f08a59d26bc95960fb3fcde9cd8285bc15 100644
--- a/source/arviz_godot/lib/avi/scene/RobotElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/RobotElementNode.h
@@ -33,6 +33,7 @@ namespace avi::scene
         void _init();
         static void _register_methods();
         RobotElementNode();
+        ~RobotElementNode() override = default;
 
         godot::AABB getVolume() override;
         godot::Transform getTransform() override;
diff --git a/source/arviz_godot/lib/avi/scene/SphereElementNode.h b/source/arviz_godot/lib/avi/scene/SphereElementNode.h
index d12a3b20cf95eaa265248170b509fc2bd552268e..c11ea6bdfc6e73697cb09b9174ab5234630104fc 100644
--- a/source/arviz_godot/lib/avi/scene/SphereElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/SphereElementNode.h
@@ -10,6 +10,7 @@ namespace avi::scene
         GODOT_CLASS(SphereElementNode, ElementNode)
 
     public:
+        ~SphereElementNode() override = default;
         static void _register_methods();
 
         void _ready();
diff --git a/source/arviz_godot/lib/avi/scene/TechnicalControlScheme.cpp b/source/arviz_godot/lib/avi/scene/TechnicalControlScheme.cpp
index c7c237c83d1a8c75455009c099e3cb76cdc9dfa6..a27dbdaec63028ea1b3f070c711ea50ebad4b42a 100644
--- a/source/arviz_godot/lib/avi/scene/TechnicalControlScheme.cpp
+++ b/source/arviz_godot/lib/avi/scene/TechnicalControlScheme.cpp
@@ -41,6 +41,8 @@ avi::scene::TechnicalControlScheme::_ready()
 void
 avi::scene::TechnicalControlScheme::_unhandled_input(godot::InputEvent* event)
 {
+    if (!isActive()) return;
+
     auto* mouseMotionEvent = cast_to<godot::InputEventMouseMotion>(event);
     if (mouseMotionEvent)
     {
@@ -70,6 +72,8 @@ avi::scene::TechnicalControlScheme::_unhandled_input(godot::InputEvent* event)
 void
 avi::scene::TechnicalControlScheme::_process(float delta)
 {
+    if (!isActive()) return;
+
     godot::Vector2 oldMouseDelta = mouseDelta;
     mouseDelta = {0, 0};
 
@@ -78,9 +82,6 @@ avi::scene::TechnicalControlScheme::_process(float delta)
 
     smoothWheelDelta = godot::Math::lerp(smoothWheelDelta, oldWheelDelta, 0.4f);
 
-    if (!isActive())
-        return;
-
     if (isTraveling)
     {
         doTravel(delta);
@@ -150,22 +151,25 @@ avi::scene::TechnicalControlScheme::reset()
 void
 avi::scene::TechnicalControlScheme::focus(godot::AABB box)
 {
-    godot::Transform transform;
+    godot::Transform transform = anchor->get_transform();
     transform.origin = box.position + (box.size * 0.5f);
 
     float distance = box.size.length();
-    float value = -std::log(distance);
+    float value = -std::log(distance * 2);
 
-    startTravel(transform, distance > 0.01f ? value : 0.0f, 0.5f);
+    startTravel(transform, value, 0.5f);
 }
 
 void
-avi::scene::TechnicalControlScheme::focus(godot::Vector3 point)
+avi::scene::TechnicalControlScheme::focus(godot::Vector3 point, avi::core::Element* target)
 {
     godot::Transform transform = anchor->get_transform();
     transform.origin = point;
 
-    startTravel(transform, zoomValue, 0.5f);
+    float distance = target->getVolume().size.length() * 2;
+    float value = -std::log(distance * 2);
+
+    startTravel(transform, value, 0.5f);
 }
 
 godot::Basis
@@ -218,6 +222,12 @@ avi::scene::TechnicalControlScheme::zoom(float delta, float deltaTime)
     godot::Transform transform = zoomer->get_transform();
     transform.origin = godot::Vector3(0, 0, zoomDistance);
     zoomer->set_transform(transform);
+
+    float clipPlaneValue = 0.001f;
+    if(zoomValue > 5) {
+        clipPlaneValue = 0.0001f;
+    }
+    this->viewCamera->setClipPlanes(clipPlaneValue);
 }
 
 void
diff --git a/source/arviz_godot/lib/avi/scene/TechnicalControlScheme.h b/source/arviz_godot/lib/avi/scene/TechnicalControlScheme.h
index bacf37bb6fa3a8299ba8412cf30f0eadc6b1a55d..6736bdf3be161c129e04bfcabc6fb84b33118fde 100644
--- a/source/arviz_godot/lib/avi/scene/TechnicalControlScheme.h
+++ b/source/arviz_godot/lib/avi/scene/TechnicalControlScheme.h
@@ -14,6 +14,7 @@ namespace avi::scene
         GODOT_CLASS(TechnicalControlScheme, Spatial)
 
     public:
+        ~TechnicalControlScheme() override = default;
         static void _register_methods();
 
         void _init();
@@ -32,7 +33,7 @@ namespace avi::scene
 
         void focus(godot::AABB box) override;
 
-        void focus(godot::Vector3 point) override;
+        void focus(godot::Vector3 point, avi::core::Element* target) override;
 
         godot::Basis getRotationBasis() override;
 
diff --git a/source/arviz_godot/lib/avi/scene/TextElementNode.cpp b/source/arviz_godot/lib/avi/scene/TextElementNode.cpp
index 0d03cd8d4d1d26e0d937802e9709b4d45e797979..a569eea9d1a34db9895d3e02f52e6c38aa35d55a 100644
--- a/source/arviz_godot/lib/avi/scene/TextElementNode.cpp
+++ b/source/arviz_godot/lib/avi/scene/TextElementNode.cpp
@@ -18,8 +18,7 @@ godot::AABB
 avi::scene::TextElementNode::getVolume()
 {
     godot::AABB correctedAABB = sprite->get_aabb();
-    correctedAABB.set_size(correctedAABB.get_size() * getScale() /
-                           avi::core::GODOT_TO_ARMARX_CONVERSION_FACTOR);
+    correctedAABB.set_size(correctedAABB.get_size() * getScale() * scalingFactor);
     correctedAABB.position = staticBody->get_transform().origin;
 
     return correctedAABB;
@@ -134,12 +133,19 @@ avi::scene::TextElementNode::setText(std::string text)
     label->set_text(text.c_str());
     label->set_size(label->get_custom_minimum_size());
     label->_update_minimum_size();
-    label->set_size(godot::Vector2(2 * label->get_size().x, label->get_size().y));
-    label->set_align(godot::Label::ALIGN_RIGHT);
+    label->set_align(godot::Label::ALIGN_LEFT);
     viewport->set_size(label->get_size());
+
+    godot::Vector3 position = {label->get_size().x * scalingFactor * 0.5f,
+                               label->get_size().y * scalingFactor * 0.33f,
+                               0.0f};
+
+    sprite->set_translation(position);
+
     collisionShape->set_scale(
-        {label->get_size().x * scalingFactor / 4, label->get_size().y * scalingFactor / 2, 1});
-    collisionShape->set_translation({label->get_size().x * scalingFactor / 4, 0, 0});
+        {label->get_size().x * scalingFactor / 2, label->get_size().y * scalingFactor / 2, 1});
+
+    collisionShape->set_translation(position);
 }
 
 godot::Vector3
diff --git a/source/arviz_godot/lib/avi/scene/TextElementNode.h b/source/arviz_godot/lib/avi/scene/TextElementNode.h
index 241d2d5e2b974d47c8e0fe2c2360f262b387b401..c141459171f962ec7bad262adc93f08bf81107ed 100644
--- a/source/arviz_godot/lib/avi/scene/TextElementNode.h
+++ b/source/arviz_godot/lib/avi/scene/TextElementNode.h
@@ -20,6 +20,7 @@ namespace avi::scene
         static TextElementNode* newTextElementNode();
 
         TextElementNode();
+        ~TextElementNode() override = default;
 
         godot::AABB getVolume() override;
         godot::Transform getTransform() override;
diff --git a/source/arviz_godot/lib/avi/scene/ViewCamera.cpp b/source/arviz_godot/lib/avi/scene/ViewCamera.cpp
index dfbe3d8f6668f98247411ffd980375e50d6154fb..58790247425c80a79b83d9216b5f439d09447447 100644
--- a/source/arviz_godot/lib/avi/scene/ViewCamera.cpp
+++ b/source/arviz_godot/lib/avi/scene/ViewCamera.cpp
@@ -10,6 +10,8 @@
 #include <Viewport.hpp>
 #include <ViewportTexture.hpp>
 #include <World.hpp>
+#include <Node.hpp>
+#include <SceneTree.hpp>
 #include <arviz_godot/lib/avi/scene/PlayfulControlScheme.h>
 #include <arviz_godot/lib/avi/scene/TechnicalControlScheme.h>
 
@@ -63,6 +65,9 @@ avi::scene::ViewCamera::setup(avi::scene::VisualizedScene& scene,
     graphicsController = &graphics;
     graphics.registerChangeListener(this, [this]() { this->visualizationChanged(); });
     visualizationChanged();
+
+    this->set_znear(0.0001);
+    this->set_zfar(300);
 }
 
 void
@@ -125,7 +130,7 @@ avi::scene::ViewCamera::screenPointToWorldPoint(godot::Vector2 point)
 {
     direct_space_state = get_world()->get_direct_space_state();
     ray_origin_position = this->project_ray_origin(point);
-    ray_end_position = ray_origin_position + this->project_ray_normal(point) * 100;
+    ray_end_position = ray_origin_position + this->project_ray_normal(point) * 1000;
     result_dict = direct_space_state->intersect_ray(ray_origin_position, ray_end_position);
 
     if (!result_dict.empty())
@@ -156,10 +161,13 @@ avi::scene::ViewCamera::toggleLock()
 void
 avi::scene::ViewCamera::focusPoint()
 {
-    auto pos = screenPointToWorldPoint(get_viewport()->get_mouse_position());
-    if (pos.has_value())
-    {
-        currentScheme->focus(pos.value());
+
+    godot::Vector2 mousePosition = this->get_tree()->get_root()->get_viewport()->get_mouse_position();
+    auto pos = screenPointToWorldPoint(mousePosition);
+    auto target = getSelectedElement(mousePosition);
+
+    if (target.has_value() && target->first && pos.has_value()) {
+        currentScheme->focus(pos.value(), target->first);
     }
 }
 
@@ -225,3 +233,16 @@ avi::scene::ViewCamera::visualizationChanged()
     this->get_node<godot::Light>("SpotLight")
         ->set_visible(graphicsController->getCurrentHeadlightState());
 }
+
+void
+avi::scene::ViewCamera::setClipPlanes(float near)
+{
+    const float distance = 5.0f;
+
+    float near_exp = std::log10(near);
+    float far_exp = distance + near_exp;
+    float far = std::pow(12.0f, far_exp);
+
+    this->set_znear(near);
+    this->set_zfar(far);
+}
diff --git a/source/arviz_godot/lib/avi/scene/ViewCamera.h b/source/arviz_godot/lib/avi/scene/ViewCamera.h
index 4a44dbee64186b56b8d410c28c0d257eeb788ccb..0603d8fbd1fc4606d3ae05d088587ccbbcc574a8 100644
--- a/source/arviz_godot/lib/avi/scene/ViewCamera.h
+++ b/source/arviz_godot/lib/avi/scene/ViewCamera.h
@@ -11,11 +11,8 @@
 namespace avi::scene
 {
     class TechnicalControlScheme;
-
     class PlayfulControlScheme;
-
     class CameraControlScheme;
-
     class VisualizedScene;
 
     class ViewCamera : public godot::Camera, public avi::core::Camera
@@ -27,7 +24,7 @@ namespace avi::scene
 
         void _init();
 
-        virtual ~ViewCamera() = default;
+        ~ViewCamera() override = default;
 
     public:
         void setup(avi::scene::VisualizedScene& scene,
@@ -52,6 +49,8 @@ namespace avi::scene
 
         void visualizationChanged();
 
+        void setClipPlanes(float near);
+
     private:
         void toggleLock();
 
diff --git a/source/arviz_godot/lib/avi/scene/VisualizedScene.cpp b/source/arviz_godot/lib/avi/scene/VisualizedScene.cpp
index 2e4b7a18b8d48351d5652ff8ac97d29367f87a04..b3fea2421d6bed212f19dadf1836d25ff6b43ed7 100644
--- a/source/arviz_godot/lib/avi/scene/VisualizedScene.cpp
+++ b/source/arviz_godot/lib/avi/scene/VisualizedScene.cpp
@@ -108,11 +108,23 @@ avi::scene::VisualizedScene::getLayerVisibility(const std::string& component,
 godot::AABB
 avi::scene::VisualizedScene::getSceneVolume()
 {
+    bool noBaseAABB = true;
     godot::AABB aabb;
 
     for (auto& [name, layer] : layers)
     {
-        aabb = aabb.merge(layer->getAABB());
+        if (layer->isVisible())
+        {
+            if (noBaseAABB)
+            {
+                aabb = layer->getAABB();
+                noBaseAABB = false;
+            }
+            else
+            {
+                aabb = aabb.merge(layer->getAABB());
+            }
+        }
     }
 
     return aabb;
@@ -123,7 +135,7 @@ avi::scene::VisualizedScene::clearScene()
 {
     for (auto& layer : layers)
     {
-        layer.second->queue_free();
+        layer.second->saveRemove();
     }
     layers.clear();
     converter->clear();
diff --git a/source/arviz_godot/lib/avi/scene/VisualizedScene.h b/source/arviz_godot/lib/avi/scene/VisualizedScene.h
index c0c494b42e037e2ac89e8e3f37e384330a7cbd8b..122d6533c5836d7ce25bf93046b8898236bc9582 100644
--- a/source/arviz_godot/lib/avi/scene/VisualizedScene.h
+++ b/source/arviz_godot/lib/avi/scene/VisualizedScene.h
@@ -17,6 +17,7 @@ namespace avi::scene
 
     public:
         static void _register_methods();
+        ~VisualizedScene() = default;
 
         void _init();
 
diff --git a/source/arviz_godot/project/Layers.tscn b/source/arviz_godot/project/Layers.tscn
new file mode 100644
index 0000000000000000000000000000000000000000..f25b9ecad70b260eb6e6d25c5e99ae9bb042a346
--- /dev/null
+++ b/source/arviz_godot/project/Layers.tscn
@@ -0,0 +1,134 @@
+[gd_scene load_steps=3 format=2]
+
+[ext_resource path="res://scenes/options/tree_component_item.tscn" type="PackedScene" id=1]
+[ext_resource path="res://bin/gui/layer_selection.gdns" type="Script" id=2]
+
+[node name="Layers" type="Control"]
+anchor_right = 1.0
+anchor_bottom = 1.0
+margin_top = 40.0
+script = ExtResource( 2 )
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="Background" type="ColorRect" parent="."]
+self_modulate = Color( 0.2, 0.2, 0.2, 1 )
+anchor_right = 1.0
+anchor_bottom = 1.0
+margin_bottom = -519.0
+rect_min_size = Vector2( 0, 521 )
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="Content" type="VBoxContainer" parent="Background"]
+margin_left = 10.0
+margin_top = 10.0
+margin_right = 349.0
+margin_bottom = 510.0
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="FilterButtons" type="HBoxContainer" parent="Background/Content"]
+margin_right = 339.0
+margin_bottom = 24.0
+size_flags_horizontal = 3
+size_flags_vertical = 3
+size_flags_stretch_ratio = 0.0
+alignment = 1
+
+[node name="FilterTextBox" type="LineEdit" parent="Background/Content/FilterButtons"]
+margin_right = 110.0
+margin_bottom = 24.0
+size_flags_horizontal = 3
+
+[node name="HideFilteredButton" type="Button" parent="Background/Content/FilterButtons"]
+margin_left = 114.0
+margin_right = 224.0
+margin_bottom = 24.0
+rect_pivot_offset = Vector2( -902, 338 )
+size_flags_horizontal = 3
+size_flags_vertical = 3
+text = "Hide Filtered"
+
+[node name="ShowFilteredButton" type="Button" parent="Background/Content/FilterButtons"]
+margin_left = 228.0
+margin_right = 339.0
+margin_bottom = 24.0
+rect_pivot_offset = Vector2( -902, 338 )
+size_flags_horizontal = 3
+size_flags_vertical = 3
+text = "Show Filtered"
+
+[node name="HSeparator" type="HSeparator" parent="Background/Content"]
+margin_top = 28.0
+margin_right = 339.0
+margin_bottom = 32.0
+
+[node name="Buttons" type="HBoxContainer" parent="Background/Content"]
+margin_top = 36.0
+margin_right = 339.0
+margin_bottom = 56.0
+size_flags_horizontal = 3
+size_flags_vertical = 3
+size_flags_stretch_ratio = 0.0
+alignment = 1
+
+[node name="HideAllButton" type="Button" parent="Background/Content/Buttons"]
+margin_right = 77.0
+margin_bottom = 20.0
+rect_pivot_offset = Vector2( -902, 338 )
+size_flags_horizontal = 3
+size_flags_vertical = 3
+text = "Hide All"
+
+[node name="ShowAllButton" type="Button" parent="Background/Content/Buttons"]
+margin_left = 81.0
+margin_right = 158.0
+margin_bottom = 20.0
+rect_pivot_offset = Vector2( -902, 338 )
+size_flags_horizontal = 3
+size_flags_vertical = 3
+text = "Show All"
+
+[node name="VSeparator" type="VSeparator" parent="Background/Content/Buttons"]
+margin_left = 162.0
+margin_right = 166.0
+margin_bottom = 20.0
+
+[node name="CollapseAllButton" type="Button" parent="Background/Content/Buttons"]
+margin_left = 170.0
+margin_right = 257.0
+margin_bottom = 20.0
+rect_pivot_offset = Vector2( -902, 338 )
+size_flags_horizontal = 3
+size_flags_vertical = 3
+text = "Collapse All"
+
+[node name="ExpandAllButton" type="Button" parent="Background/Content/Buttons"]
+margin_left = 261.0
+margin_right = 339.0
+margin_bottom = 20.0
+rect_pivot_offset = Vector2( -902, 338 )
+size_flags_horizontal = 3
+size_flags_vertical = 3
+text = "Expand All"
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="Scroll" type="ScrollContainer" parent="Background/Content"]
+margin_top = 60.0
+margin_right = 339.0
+margin_bottom = 500.0
+size_flags_horizontal = 3
+size_flags_vertical = 3
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="Layers" parent="Background/Content/Scroll" instance=ExtResource( 1 )]
+anchor_right = 0.0
+anchor_bottom = 0.0
diff --git a/source/arviz_godot/project/Replay.tscn b/source/arviz_godot/project/Replay.tscn
index a585484df1efe6bbe34cb63ff0ea9e1c020073fb..716baf18eb8831606edaa79142c031b05d217d0c 100644
--- a/source/arviz_godot/project/Replay.tscn
+++ b/source/arviz_godot/project/Replay.tscn
@@ -3,17 +3,20 @@
 [ext_resource path="res://bin/gui/replay_cockpit.gdns" type="Script" id=1]
 
 [node name="Replay" type="Control"]
-visible = false
 anchor_right = 1.0
 anchor_bottom = 1.0
 margin_top = 40.0
 script = ExtResource( 1 )
+__meta__ = {
+"_edit_use_anchors_": false
+}
 
 [node name="Background" type="ColorRect" parent="."]
 self_modulate = Color( 0.2, 0.2, 0.2, 1 )
 anchor_right = 1.0
 anchor_bottom = 1.0
 margin_bottom = -519.0
+rect_min_size = Vector2( 0, 521 )
 __meta__ = {
 "_edit_use_anchors_": false
 }
@@ -25,86 +28,101 @@ margin_left = 10.0
 margin_top = 10.0
 margin_right = -10.0
 margin_bottom = -10.0
+__meta__ = {
+"_edit_use_anchors_": false
+}
 
 [node name="Record" type="Button" parent="Background/Content"]
-margin_right = 339.0
-margin_bottom = 40.0
+margin_right = 1900.0
+margin_bottom = 20.0
 size_flags_horizontal = 3
 action_mode = 0
 text = "Start Recording"
 
 [node name="ReplayName" type="LineEdit" parent="Background/Content"]
-margin_top = 44.0
-margin_right = 339.0
-margin_bottom = 68.0
+margin_top = 24.0
+margin_right = 1900.0
+margin_bottom = 48.0
 text = "recording"
 
-[node name="OptionButton" type="OptionButton" parent="Background/Content"]
-margin_right = 34.0
-margin_bottom = 40.0
+[node name="Select" type="HBoxContainer" parent="Background/Content"]
+margin_top = 52.0
+margin_right = 1900.0
+margin_bottom = 72.0
+
+[node name="Chooser" type="OptionButton" parent="Background/Content/Select"]
+margin_right = 1836.0
+margin_bottom = 20.0
+size_flags_horizontal = 3
+
+[node name="Refresh" type="Button" parent="Background/Content/Select"]
+margin_left = 1840.0
+margin_right = 1900.0
+margin_bottom = 20.0
+text = "Refresh"
 
 [node name="ChangeMode" type="Button" parent="Background/Content"]
-margin_right = 20.0
-margin_bottom = 40.0
+margin_top = 76.0
+margin_right = 1900.0
+margin_bottom = 96.0
 text = "Enter Replay Mode"
 
 [node name="Buttons" type="HBoxContainer" parent="Background/Content"]
-margin_right = 40.0
-margin_bottom = 40.0
+margin_top = 100.0
+margin_right = 1900.0
+margin_bottom = 120.0
 
 [node name="Rewind2" type="Button" parent="Background/Content/Buttons"]
-margin_top = 72.0
-margin_right = 66.8
-margin_bottom = 112.0
+margin_right = 376.0
+margin_bottom = 20.0
 size_flags_horizontal = 3
 text = "<<"
 
 [node name="Rewind1" type="Button" parent="Background/Content/Buttons"]
-margin_left = -10.0
-margin_top = 62.0
-margin_right = 56.8
-margin_bottom = 102.0
+margin_left = 380.0
+margin_right = 757.0
+margin_bottom = 20.0
 size_flags_horizontal = 3
 text = "<|"
 
 [node name="Play" type="Button" parent="Background/Content/Buttons"]
-margin_left = -10.0
-margin_top = 62.0
-margin_right = 56.8
-margin_bottom = 102.0
+margin_left = 761.0
+margin_right = 1138.0
+margin_bottom = 20.0
 size_flags_horizontal = 3
 text = "Play"
 
 [node name="Forward1" type="Button" parent="Background/Content/Buttons"]
-margin_left = -10.0
-margin_top = 62.0
-margin_right = 56.8
-margin_bottom = 102.0
+margin_left = 1142.0
+margin_right = 1519.0
+margin_bottom = 20.0
 size_flags_horizontal = 3
 text = "|>"
 
 [node name="Forward2" type="Button" parent="Background/Content/Buttons"]
-margin_left = -10.0
-margin_top = 62.0
-margin_right = 56.8
-margin_bottom = 102.0
+margin_left = 1523.0
+margin_right = 1900.0
+margin_bottom = 20.0
 size_flags_horizontal = 3
 text = ">>"
 
 [node name="PlayBack" type="HBoxContainer" parent="Background/Content"]
-margin_right = 176.0
-margin_bottom = 24.0
+margin_top = 124.0
+margin_right = 1900.0
+margin_bottom = 148.0
 
 [node name="Label" type="Label" parent="Background/Content/PlayBack"]
+margin_top = 5.0
 margin_right = 98.0
-margin_bottom = 14.0
+margin_bottom = 19.0
 grow_horizontal = 0
 grow_vertical = 0
 size_flags_horizontal = 2
 text = "Playback speed"
 
 [node name="PlayBackSpeed" type="SpinBox" parent="Background/Content/PlayBack"]
-margin_right = 74.0
+margin_left = 952.0
+margin_right = 1900.0
 margin_bottom = 24.0
 grow_horizontal = 0
 size_flags_horizontal = 3
@@ -116,54 +134,62 @@ allow_lesser = true
 align = 2
 
 [node name="MinTimestamp" type="HBoxContainer" parent="Background/Content"]
+margin_top = 152.0
+margin_right = 1900.0
+margin_bottom = 166.0
 size_flags_horizontal = 3
 
 [node name="Min" type="Label" parent="Background/Content/MinTimestamp"]
-anchor_bottom = 0.018
-margin_right = 104.0
+margin_right = 948.0
 margin_bottom = 14.0
 size_flags_horizontal = 3
 text = "First Timestamp in µs"
 
 [node name="Value" type="Label" parent="Background/Content/MinTimestamp"]
+margin_left = 952.0
+margin_right = 1900.0
 margin_bottom = 14.0
 size_flags_horizontal = 3
 text = "0"
 align = 2
 
 [node name="MaxTimestamp" type="HBoxContainer" parent="Background/Content"]
+margin_top = 170.0
+margin_right = 1900.0
+margin_bottom = 184.0
 size_flags_horizontal = 3
 
 [node name="Max" type="Label" parent="Background/Content/MaxTimestamp"]
-margin_left = -10.0
-margin_top = -10.0
-margin_right = 92.0
-margin_bottom = 4.0
+margin_right = 948.0
+margin_bottom = 14.0
 size_flags_horizontal = 3
 text = "Last Timestamp in µs"
 
 [node name="Value" type="Label" parent="Background/Content/MaxTimestamp"]
-anchor_bottom = 0.018
-margin_right = 40.0
+margin_left = 952.0
+margin_right = 1900.0
 margin_bottom = 14.0
 size_flags_horizontal = 3
 text = "0"
 align = 2
 
 [node name="Progress" type="HBoxContainer" parent="Background/Content"]
-margin_right = 176.0
-margin_bottom = 24.0
+margin_top = 188.0
+margin_right = 1900.0
+margin_bottom = 212.0
 
 [node name="Label" type="Label" parent="Background/Content/Progress"]
-margin_right = 98.0
-margin_bottom = 14.0
+margin_top = 5.0
+margin_right = 126.0
+margin_bottom = 19.0
 grow_horizontal = 0
 grow_vertical = 0
 size_flags_horizontal = 2
 text = "Time elapsed in ms"
 
 [node name="Timestamp" type="SpinBox" parent="Background/Content/Progress"]
-margin_right = 74.0
+margin_left = 952.0
+margin_right = 1900.0
 margin_bottom = 24.0
 grow_horizontal = 0
 size_flags_horizontal = 3
@@ -171,11 +197,8 @@ allow_greater = true
 align = 2
 
 [node name="Slider" type="HSlider" parent="Background/Content"]
-anchor_right = 1.0
-anchor_bottom = 1.0
-margin_left = 10.0
-margin_top = 10.0
-margin_right = -10.0
-margin_bottom = -10.0
+margin_top = 216.0
+margin_right = 1900.0
+margin_bottom = 232.0
 max_value = 1.0
 step = 0.01
diff --git a/source/arviz_godot/project/UI/Themes/button_normal_stylebox.tres b/source/arviz_godot/project/UI/Themes/button_normal_stylebox.tres
index 13cbcc113c289c9dc2e14a50bc19f76a10431646..02b043071fac2b768136afe75b9708a3fb3b3b4b 100644
--- a/source/arviz_godot/project/UI/Themes/button_normal_stylebox.tres
+++ b/source/arviz_godot/project/UI/Themes/button_normal_stylebox.tres
@@ -2,8 +2,8 @@
 
 [resource]
 bg_color = Color( 0.258824, 0.258824, 0.258824, 1 )
-border_width_left = 10
+border_width_left = 8
 border_width_top = 13
-border_width_right = 10
+border_width_right = 8
 border_width_bottom = 13
 border_color = Color( 0.258824, 0.258824, 0.258824, 1 )
diff --git a/source/arviz_godot/project/UI/Themes/main_theme.tres b/source/arviz_godot/project/UI/Themes/main_theme.tres
index 17cb32a4971460d6da719c0bdeb7d1f2cb2252c5..dda954b7ab16cd6b8deb887484dced7de324c2a3 100644
--- a/source/arviz_godot/project/UI/Themes/main_theme.tres
+++ b/source/arviz_godot/project/UI/Themes/main_theme.tres
@@ -83,6 +83,23 @@ PopupMenu/styles/labeled_separator_right = null
 PopupMenu/styles/panel = ExtResource( 3 )
 PopupMenu/styles/panel_disabled = null
 PopupMenu/styles/separator = null
+RichTextLabel/colors/default_color = Color( 1, 1, 1, 0.784314 )
+RichTextLabel/colors/font_color_selected = Color( 0.49, 0.49, 0.49, 1 )
+RichTextLabel/colors/font_color_shadow = Color( 0, 0, 0, 0 )
+RichTextLabel/colors/selection_color = Color( 0.1, 0.1, 1, 0.8 )
+RichTextLabel/constants/line_separation = 1
+RichTextLabel/constants/shadow_as_outline = 1
+RichTextLabel/constants/shadow_offset_x = 1
+RichTextLabel/constants/shadow_offset_y = 1
+RichTextLabel/constants/table_hseparation = 3
+RichTextLabel/constants/table_vseparation = 3
+RichTextLabel/fonts/bold_font = null
+RichTextLabel/fonts/bold_italics_font = null
+RichTextLabel/fonts/italics_font = null
+RichTextLabel/fonts/mono_font = null
+RichTextLabel/fonts/normal_font = null
+RichTextLabel/styles/focus = null
+RichTextLabel/styles/normal = null
 TabContainer/colors/font_color_bg = Color( 1, 1, 1, 0.568627 )
 TabContainer/colors/font_color_disabled = Color( 0.9, 0.9, 0.9, 0.2 )
 TabContainer/colors/font_color_fg = Color( 1, 1, 1, 1 )
@@ -102,6 +119,42 @@ TabContainer/styles/panel = null
 TabContainer/styles/tab_bg = ExtResource( 3 )
 TabContainer/styles/tab_disabled = ExtResource( 2 )
 TabContainer/styles/tab_fg = ExtResource( 1 )
+Tree/colors/custom_button_font_highlight = Color( 0.94, 0.94, 0.94, 1 )
+Tree/colors/drop_position_color = Color( 0, 0, 0, 1 )
+Tree/colors/font_color = Color( 1, 1, 1, 1 )
+Tree/colors/font_color_selected = Color( 1, 1, 1, 1 )
+Tree/colors/guide_color = Color( 1, 1, 1, 0 )
+Tree/colors/relationship_line_color = Color( 1, 1, 1, 0.396078 )
+Tree/colors/title_button_color = Color( 1, 1, 1, 1 )
+Tree/constants/button_margin = 10
+Tree/constants/draw_guides = 1
+Tree/constants/draw_relationship_lines = 1
+Tree/constants/hseparation = 5
+Tree/constants/item_margin = 10
+Tree/constants/scroll_border = 4
+Tree/constants/scroll_speed = 12
+Tree/constants/vseparation = 10
+Tree/fonts/font = null
+Tree/fonts/title_button_font = null
+Tree/icons/arrow = null
+Tree/icons/arrow_collapsed = null
+Tree/icons/checked = null
+Tree/icons/select_arrow = null
+Tree/icons/unchecked = null
+Tree/icons/updown = null
+Tree/styles/bg = ExtResource( 3 )
+Tree/styles/bg_focus = null
+Tree/styles/button_pressed = null
+Tree/styles/cursor = null
+Tree/styles/cursor_unfocused = null
+Tree/styles/custom_button = null
+Tree/styles/custom_button_hover = ExtResource( 2 )
+Tree/styles/custom_button_pressed = null
+Tree/styles/selected = ExtResource( 1 )
+Tree/styles/selected_focus = null
+Tree/styles/title_button_hover = ExtResource( 2 )
+Tree/styles/title_button_normal = null
+Tree/styles/title_button_pressed = ExtResource( 1 )
 WindowDialog/colors/title_color = Color( 1, 1, 1, 1 )
 WindowDialog/constants/close_h_ofs = 18
 WindowDialog/constants/close_v_ofs = 0
diff --git a/source/arviz_godot/project/Visuals.tscn b/source/arviz_godot/project/Visuals.tscn
new file mode 100644
index 0000000000000000000000000000000000000000..307ffa7fd0bedb26e2969d9d7c54d735c4613750
--- /dev/null
+++ b/source/arviz_godot/project/Visuals.tscn
@@ -0,0 +1,71 @@
+[gd_scene load_steps=2 format=2]
+
+[ext_resource path="res://bin/gui/graphics_settings.gdns" type="Script" id=1]
+
+[node name="Visuals" type="Control"]
+visible = false
+anchor_right = 1.0
+anchor_bottom = 1.0
+margin_top = 40.0
+script = ExtResource( 1 )
+
+[node name="Background" type="ColorRect" parent="."]
+self_modulate = Color( 0.2, 0.2, 0.2, 1 )
+anchor_right = 1.0
+anchor_bottom = 1.0
+margin_bottom = -519.0
+rect_min_size = Vector2( 0, 521 )
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="Content" type="VBoxContainer" parent="Background"]
+anchor_right = 1.0
+anchor_bottom = 1.0
+margin_left = 10.0
+margin_top = 10.0
+margin_right = -10.0
+margin_bottom = -10.0
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="Profiles" type="OptionButton" parent="Background/Content"]
+margin_right = 339.0
+margin_bottom = 40.0
+
+[node name="Name" type="LineEdit" parent="Background/Content"]
+margin_top = 44.0
+margin_right = 339.0
+margin_bottom = 68.0
+
+[node name="Buttons" type="HBoxContainer" parent="Background/Content"]
+margin_top = 72.0
+margin_right = 339.0
+margin_bottom = 112.0
+
+[node name="Save" type="Button" parent="Background/Content/Buttons"]
+margin_right = 167.0
+margin_bottom = 40.0
+size_flags_horizontal = 3
+text = "Save"
+
+[node name="Copy" type="Button" parent="Background/Content/Buttons"]
+margin_left = 171.0
+margin_right = 339.0
+margin_bottom = 40.0
+size_flags_horizontal = 3
+text = "Copy"
+
+[node name="Scroll" type="ScrollContainer" parent="Background/Content"]
+margin_top = 116.0
+margin_right = 339.0
+margin_bottom = 530.0
+size_flags_vertical = 3
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="Container" type="VBoxContainer" parent="Background/Content/Scroll"]
+margin_right = 339.0
+size_flags_horizontal = 3
diff --git a/source/arviz_godot/project/keyboard-layout.png b/source/arviz_godot/project/keyboard-layout.png
index 539cfb319bfb78ce9e3e9c68d96b978735ad8177..52f829f82735031bf202ef02ab825ae326e31411 100644
Binary files a/source/arviz_godot/project/keyboard-layout.png and b/source/arviz_godot/project/keyboard-layout.png differ
diff --git a/source/arviz_godot/project/models/pose.mtl b/source/arviz_godot/project/models/pose.mtl
index 0ea6c6cedab81147fc829fa05bcdc0fcfd56e0e9..d37b8cd739799339c737d93abb9a7292e389d9a7 100644
--- a/source/arviz_godot/project/models/pose.mtl
+++ b/source/arviz_godot/project/models/pose.mtl
@@ -1,8 +1,8 @@
 # Blender MTL File: 'None'
-# Material Count: 5
+# Material Count: 4
 
 newmtl Neutral
-Ns 225.000000
+Ns 224.999983
 Ka 1.000000 1.000000 1.000000
 Kd 0.000000 0.000000 0.000000
 Ks 0.500000 0.500000 0.500000
@@ -12,27 +12,17 @@ d 1.000000
 illum 2
 
 newmtl X
-Ns 225.000000
+Ns 224.999983
 Ka 1.000000 1.000000 1.000000
 Kd 0.800000 0.000000 0.007330
-Ks 0.500000 0.500000 0.500000
+Ks 0.000000 0.000000 0.000000
 Ke 0.000000 0.000000 0.000000
 Ni 1.450000
 d 1.000000
-illum 2
+illum 1
 
 newmtl Y
-Ns 225.000000
-Ka 1.000000 1.000000 1.000000
-Kd 0.000864 0.800000 0.000000
-Ks 0.500000 0.500000 0.500000
-Ke 0.000000 0.000000 0.000000
-Ni 1.450000
-d 1.000000
-illum 2
-
-newmtl Y.001
-Ns 225.000000
+Ns 224.999983
 Ka 1.000000 1.000000 1.000000
 Kd 0.000864 0.800000 0.000000
 Ks 0.500000 0.500000 0.500000
@@ -42,7 +32,7 @@ d 1.000000
 illum 2
 
 newmtl Z
-Ns 225.000000
+Ns 224.999983
 Ka 1.000000 1.000000 1.000000
 Kd 0.000000 0.016938 0.800000
 Ks 0.500000 0.500000 0.500000
diff --git a/source/arviz_godot/project/models/pose.obj b/source/arviz_godot/project/models/pose.obj
index bb0b1914e0ff4590803a3a5b5d9ef18f486fa280..12cb0996dc993393bf3275b2563630bcf1d507f0 100644
--- a/source/arviz_godot/project/models/pose.obj
+++ b/source/arviz_godot/project/models/pose.obj
@@ -1,4 +1,4 @@
-# Blender v3.0.1 OBJ File: ''
+# Blender v3.1.2 OBJ File: ''
 # www.blender.org
 mtllib pose.mtl
 o Pose_Cube.001
@@ -10,148 +10,193 @@ v 0.000000 5.000000 5.000000
 v 0.000000 5.000000 0.000000
 v 5.000000 5.000000 0.000000
 v 5.000000 5.000000 5.000000
-v 99.999992 0.000004 5.000000
-v 99.999992 5.000004 5.000000
-v 99.999992 5.000004 0.000000
-v 99.999992 0.000004 0.000000
-v -0.000004 99.999992 5.000008
-v -0.000004 99.999992 0.000008
-v 4.999996 99.999992 5.000008
-v 4.999996 99.999992 0.000008
-v 5.000000 -0.000008 99.999992
-v 0.000000 -0.000009 99.999992
-v 0.000000 4.999991 99.999992
-v 5.000000 4.999992 99.999992
+v -0.000004 99.999992 5.000012
+v -0.000004 99.999992 0.000012
+v 4.999996 99.999992 5.000012
+v 4.999996 99.999992 0.000012
+v 2.500000 12.499996 90.500000
+v 2.500000 2.499995 110.500000
+v 12.500000 2.499996 90.500000
+v 2.499999 -7.500004 90.500000
+v -7.500000 2.499996 90.500000
+v 5.000000 -0.000012 99.999992
+v 0.000000 -0.000013 99.999992
+v 0.000000 4.999987 99.999992
+v 5.000000 4.999988 99.999992
+v 2.500000 90.500000 -7.499996
+v 2.500000 110.500000 2.500005
+v 12.500000 90.500000 2.500005
+v 2.499999 90.500000 12.500004
+v -7.500000 90.500000 2.500004
+v 90.500000 0.000004 0.000000
+v 90.500000 0.000003 5.000000
+v 90.500000 5.000003 5.000000
+v 90.500000 5.000003 0.000000
 v 90.500000 2.500000 -7.500000
-v 90.500000 -7.500000 2.500001
-v 90.500000 2.500001 12.500000
-v 90.500000 12.500000 2.500000
 v 110.500000 2.500000 2.500000
-v 2.500000 90.500000 -7.500000
-v 12.500000 90.500000 2.500001
-v 2.499999 90.500000 12.500000
-v -7.500000 90.500000 2.500000
-v 2.500000 110.500000 2.500000
-v 2.500000 12.500000 90.500000
-v 12.500000 2.500000 90.500000
-v 2.499999 -7.500000 90.500000
-v -7.500000 2.500000 90.500000
-v 2.500000 2.500000 110.500000
-vt 0.375000 0.000000
-vt 0.625000 0.000000
-vt 0.625000 0.250000
-vt 0.375000 0.250000
-vt 0.625000 0.500000
-vt 0.375000 0.500000
-vt 0.125000 0.500000
-vt 0.375000 0.750000
-vt 0.125000 0.750000
-vt 0.250000 0.490000
-vt 0.250000 0.250000
-vt 0.490000 0.250000
-vt 0.250000 0.010000
-vt 0.750000 0.490000
-vt 0.990000 0.250000
-vt 0.750000 0.010000
-vt 0.510000 0.250000
-vt 0.010000 0.250000
-vt 0.625000 0.750000
-vt 0.875000 0.750000
-vt 0.875000 0.750000
-vt 0.625000 0.750000
-vt 0.375000 0.750000
-vt 0.625000 1.000000
-vt 0.375000 1.000000
-vt 0.375000 0.000000
-vt 0.625000 0.000000
-vt 0.125000 0.750000
-vt 0.625000 0.500000
-vt 0.375000 0.500000
-vt 0.625000 0.750000
-vt 0.375000 0.750000
-vt 0.250000 0.490000
-vt 0.250000 0.250000
-vt 0.490000 0.250000
-vt 0.250000 0.010000
-vt 0.750000 0.490000
-vt 0.990000 0.250000
-vt 0.750000 0.010000
-vt 0.510000 0.250000
-vt 0.010000 0.250000
-vt 0.625000 0.000000
-vt 0.625000 0.250000
-vt 0.625000 0.500000
-vt 0.875000 0.500000
-vt 0.875000 0.750000
-vt 0.625000 0.750000
-vt 0.250000 0.490000
-vt 0.250000 0.250000
-vt 0.490000 0.250000
-vt 0.250000 0.010000
-vt 0.750000 0.490000
-vt 0.990000 0.250000
-vt 0.750000 0.010000
-vt 0.510000 0.250000
-vt 0.010000 0.250000
+v 90.500000 -7.500000 2.500001
+v 90.500000 2.500000 12.500000
+v 105.499992 5.000003 2.500000
+v 90.500000 5.000003 9.999997
+v 90.500000 5.000003 -4.999997
+v 5.000000 5.000000 0.000000
+v 5.000000 5.000000 5.000000
+v 90.500000 5.000003 5.000000
+v 90.500000 5.000003 0.000000
+vt 0.487053 0.511406
+vt 0.462708 0.511406
+vt 0.462708 0.487053
+vt 0.487053 0.487053
+vt 0.462708 0.462708
+vt 0.487053 0.462708
+vt 0.511410 0.462708
+vt 0.511410 0.487053
+vt 0.927843 0.462708
+vt 0.927843 0.487053
+vt 0.669377 0.487057
+vt 0.693730 0.487057
+vt 0.693730 0.903490
+vt 0.669377 0.903490
+vt 0.487053 0.927841
+vt 0.462708 0.927841
+vt 0.000000 0.000000
+vt 0.839847 0.584465
+vt 0.791142 0.584465
+vt 0.839847 0.487053
+vt 0.742435 0.779289
+vt 0.693729 0.779289
+vt 0.742435 0.681877
+vt 0.754611 0.706230
+vt 0.754611 0.779289
+vt 0.517061 0.511314
+vt 0.514935 0.487053
+vt 0.571966 0.579834
+vt 0.559835 0.580902
+vt 0.511316 0.585159
+vt 0.535576 0.583031
+vt 0.571966 0.997871
+vt 0.547707 1.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.462708 0.000000
+vt 0.487053 0.000000
+vt 0.864200 0.555937
+vt 0.864200 0.580290
+vt 0.839847 0.580290
+vt 0.839847 0.555937
+vt 0.645024 0.949760
+vt 0.620671 0.949760
+vt 0.620671 0.487053
+vt 0.645024 0.487053
+vt 0.511410 0.000000
+vt 0.645024 0.487057
+vt 0.669377 0.949760
+vt 0.645024 0.949760
+vt 0.803318 0.779289
+vt 0.852024 0.681877
+vt 0.852024 0.779289
+vt 0.754612 0.779289
+vt 0.803318 0.681877
+vt 0.803318 0.779289
+vt 0.880196 0.779291
+vt 0.880196 0.848171
+vt 0.811316 0.848171
+vt 0.811316 0.779291
+vt 0.791145 0.681880
+vt 0.693733 0.633174
+vt 0.791145 0.633174
+vt 0.791145 0.584468
+vt 0.762610 0.876701
+vt 0.811316 0.779289
+vt 0.811316 0.876701
+vt 0.791142 0.681877
+vt 0.839848 0.584465
+vt 0.839848 0.681877
+vt 0.693730 0.779291
+vt 0.762610 0.779291
+vt 0.762610 0.848171
+vt 0.693730 0.848171
+vt 0.791145 0.584468
+vt 0.693733 0.535763
+vt 0.791145 0.535763
+vt 0.791145 0.487057
+vt 0.000000 0.511406
+vt 0.000000 0.487053
+vt 0.864200 0.580290
+vt 0.864200 0.604643
+vt 0.839847 0.604643
+vt 0.839847 0.580290
+vt 0.596318 0.487057
+vt 0.620671 0.487057
+vt 0.620671 0.949760
+vt 0.596318 0.949760
+vt 0.000000 0.462708
+vt 0.571966 0.487057
+vt 0.596319 0.487057
+vt 0.596319 0.949760
+vt 0.571966 0.949760
 vn 0.0000 -1.0000 -0.0000
 vn -1.0000 0.0000 0.0000
 vn 0.0000 0.0000 -1.0000
+vn 0.0000 0.0000 1.0000
 vn 0.3333 -0.6667 -0.6667
 vn 0.3333 -0.6667 0.6667
 vn 0.3333 0.6667 0.6667
 vn 0.3333 0.6667 -0.6667
-vn 0.0000 0.0000 1.0000
-vn 1.0000 -0.0000 0.0000
 vn -0.0000 1.0000 0.0000
-vn 0.6667 0.6667 0.3333
-vn 0.6667 -0.6667 0.3333
-vn -0.6667 -0.6667 0.3333
-vn -0.6667 0.6667 0.3333
+vn 1.0000 0.0000 0.0000
 vn 0.6667 0.3333 -0.6667
 vn 0.6667 0.3333 0.6667
 vn -0.6667 0.3333 0.6667
 vn -0.6667 0.3333 -0.6667
+vn 0.6667 0.6667 0.3333
+vn 0.6667 -0.6667 0.3333
+vn -0.6667 -0.6667 0.3333
+vn -0.6667 0.6667 0.3333
 usemtl Neutral
-s 1
+s off
 f 1/1/1 2/2/1 3/3/1 4/4/1
 f 4/4/2 3/3/2 5/5/2 6/6/2
-f 4/7/3 6/6/3 7/8/3 1/9/3
+f 4/4/3 6/6/3 7/7/3 1/8/3
 usemtl X
-s off
-f 21/10/4 25/11/4 22/12/4
-f 22/12/5 25/11/5 23/13/5
-f 21/14/2 22/15/2 23/16/2 24/17/2
-f 23/13/6 25/11/6 24/18/6
-f 24/18/7 25/11/7 21/10/7
-s 1
-f 8/19/8 2/20/8 9/21/8 10/22/8
-f 11/23/9 10/22/9 9/24/9 12/25/9
-f 7/8/10 8/19/10 10/22/10 11/23/10
-f 2/2/1 1/1/1 12/26/1 9/27/1
-f 1/9/3 7/8/3 11/23/3 12/28/3
+f 7/7/3 30/9/3 27/10/3 1/8/3
+f 8/11/4 2/12/4 28/13/4 29/14/4
+f 2/2/1 1/1/1 27/15/1 28/16/1
+f 27/15/2 33/17/2 28/16/2
+f 33/18/5 31/19/5 32/20/5
+f 34/21/6 33/22/6 32/23/6
+f 34/21/7 32/23/7 35/24/7 36/25/7
+f 35/26/8 32/27/8 31/28/8 37/29/8
+f 40/30/9 41/31/9 38/32/9 39/33/9
+f 33/17/2 34/21/2 28/16/2
+f 34/21/2 36/25/2 28/16/2
+f 40/34/2 28/16/2 36/25/2
+f 33/18/2 27/15/2 31/19/2
+f 31/19/2 27/15/2 37/29/2
+f 37/29/2 27/15/2 41/35/2
+f 40/30/9 35/36/9 41/31/9
+f 35/36/9 40/30/9 36/25/9
+f 37/29/9 41/35/9 35/36/9
 usemtl Y
-f 6/6/2 5/5/2 13/29/2 14/30/2
-f 14/30/10 13/29/10 15/31/10 16/32/10
-f 8/19/9 7/8/9 16/32/9 15/31/9
-f 7/8/3 6/6/3 14/30/3 16/32/3
-f 5/5/8 8/19/8 15/31/8 13/29/8
+f 6/6/2 5/5/2 9/37/2 10/38/2
+f 10/39/9 9/40/9 11/41/9 12/42/9
+f 8/43/10 7/44/10 12/45/10 11/46/10
+f 7/7/3 6/6/3 10/38/3 12/47/3
+f 5/48/4 8/11/4 11/49/4 9/50/4
+f 22/51/11 23/52/11 24/53/11
+f 24/54/12 23/55/12 25/56/12
+f 22/57/1 24/58/1 25/59/1 26/60/1
+f 25/61/13 23/62/13 26/63/13
+f 26/63/14 23/62/14 22/64/14
 usemtl Z
-s off
-f 31/33/11 35/34/11 32/35/11
-f 32/35/12 35/34/12 33/36/12
-f 31/37/3 32/38/3 33/39/3 34/40/3
-f 33/36/13 35/34/13 34/41/13
-f 34/41/14 35/34/14 31/33/14
-s 1
-f 3/3/1 2/2/1 17/42/1 18/43/1
-f 19/44/8 18/45/8 17/46/8 20/47/8
-f 2/20/9 8/19/9 20/47/9 17/46/9
-f 5/5/2 3/3/2 18/43/2 19/44/2
-f 8/19/10 5/5/10 19/44/10 20/47/10
-usemtl Y.001
-s off
-f 26/48/15 30/49/15 27/50/15
-f 27/50/16 30/49/16 28/51/16
-f 26/52/1 27/53/1 28/54/1 29/55/1
-f 28/51/17 30/49/17 29/56/17
-f 29/56/18 30/49/18 26/48/18
+f 13/65/15 14/66/15 15/67/15
+f 15/68/16 14/69/16 16/70/16
+f 13/71/3 15/72/3 16/73/3 17/74/3
+f 16/75/17 14/76/17 17/77/17
+f 17/77/18 14/76/18 13/78/18
+f 3/3/1 2/2/1 18/79/1 19/80/1
+f 20/81/4 19/82/4 18/83/4 21/84/4
+f 2/85/10 8/86/10 21/87/10 18/88/10
+f 5/5/2 3/3/2 19/80/2 20/89/2
+f 8/90/9 5/91/9 20/92/9 21/93/9
diff --git a/source/arviz_godot/project/models/pose_orientationindicator.obj b/source/arviz_godot/project/models/pose_orientationindicator.obj
new file mode 100644
index 0000000000000000000000000000000000000000..bb0b1914e0ff4590803a3a5b5d9ef18f486fa280
--- /dev/null
+++ b/source/arviz_godot/project/models/pose_orientationindicator.obj
@@ -0,0 +1,157 @@
+# Blender v3.0.1 OBJ File: ''
+# www.blender.org
+mtllib pose.mtl
+o Pose_Cube.001
+v 5.000000 0.000000 0.000000
+v 5.000000 -0.000000 5.000000
+v 0.000000 -0.000000 5.000000
+v 0.000000 0.000000 0.000000
+v 0.000000 5.000000 5.000000
+v 0.000000 5.000000 0.000000
+v 5.000000 5.000000 0.000000
+v 5.000000 5.000000 5.000000
+v 99.999992 0.000004 5.000000
+v 99.999992 5.000004 5.000000
+v 99.999992 5.000004 0.000000
+v 99.999992 0.000004 0.000000
+v -0.000004 99.999992 5.000008
+v -0.000004 99.999992 0.000008
+v 4.999996 99.999992 5.000008
+v 4.999996 99.999992 0.000008
+v 5.000000 -0.000008 99.999992
+v 0.000000 -0.000009 99.999992
+v 0.000000 4.999991 99.999992
+v 5.000000 4.999992 99.999992
+v 90.500000 2.500000 -7.500000
+v 90.500000 -7.500000 2.500001
+v 90.500000 2.500001 12.500000
+v 90.500000 12.500000 2.500000
+v 110.500000 2.500000 2.500000
+v 2.500000 90.500000 -7.500000
+v 12.500000 90.500000 2.500001
+v 2.499999 90.500000 12.500000
+v -7.500000 90.500000 2.500000
+v 2.500000 110.500000 2.500000
+v 2.500000 12.500000 90.500000
+v 12.500000 2.500000 90.500000
+v 2.499999 -7.500000 90.500000
+v -7.500000 2.500000 90.500000
+v 2.500000 2.500000 110.500000
+vt 0.375000 0.000000
+vt 0.625000 0.000000
+vt 0.625000 0.250000
+vt 0.375000 0.250000
+vt 0.625000 0.500000
+vt 0.375000 0.500000
+vt 0.125000 0.500000
+vt 0.375000 0.750000
+vt 0.125000 0.750000
+vt 0.250000 0.490000
+vt 0.250000 0.250000
+vt 0.490000 0.250000
+vt 0.250000 0.010000
+vt 0.750000 0.490000
+vt 0.990000 0.250000
+vt 0.750000 0.010000
+vt 0.510000 0.250000
+vt 0.010000 0.250000
+vt 0.625000 0.750000
+vt 0.875000 0.750000
+vt 0.875000 0.750000
+vt 0.625000 0.750000
+vt 0.375000 0.750000
+vt 0.625000 1.000000
+vt 0.375000 1.000000
+vt 0.375000 0.000000
+vt 0.625000 0.000000
+vt 0.125000 0.750000
+vt 0.625000 0.500000
+vt 0.375000 0.500000
+vt 0.625000 0.750000
+vt 0.375000 0.750000
+vt 0.250000 0.490000
+vt 0.250000 0.250000
+vt 0.490000 0.250000
+vt 0.250000 0.010000
+vt 0.750000 0.490000
+vt 0.990000 0.250000
+vt 0.750000 0.010000
+vt 0.510000 0.250000
+vt 0.010000 0.250000
+vt 0.625000 0.000000
+vt 0.625000 0.250000
+vt 0.625000 0.500000
+vt 0.875000 0.500000
+vt 0.875000 0.750000
+vt 0.625000 0.750000
+vt 0.250000 0.490000
+vt 0.250000 0.250000
+vt 0.490000 0.250000
+vt 0.250000 0.010000
+vt 0.750000 0.490000
+vt 0.990000 0.250000
+vt 0.750000 0.010000
+vt 0.510000 0.250000
+vt 0.010000 0.250000
+vn 0.0000 -1.0000 -0.0000
+vn -1.0000 0.0000 0.0000
+vn 0.0000 0.0000 -1.0000
+vn 0.3333 -0.6667 -0.6667
+vn 0.3333 -0.6667 0.6667
+vn 0.3333 0.6667 0.6667
+vn 0.3333 0.6667 -0.6667
+vn 0.0000 0.0000 1.0000
+vn 1.0000 -0.0000 0.0000
+vn -0.0000 1.0000 0.0000
+vn 0.6667 0.6667 0.3333
+vn 0.6667 -0.6667 0.3333
+vn -0.6667 -0.6667 0.3333
+vn -0.6667 0.6667 0.3333
+vn 0.6667 0.3333 -0.6667
+vn 0.6667 0.3333 0.6667
+vn -0.6667 0.3333 0.6667
+vn -0.6667 0.3333 -0.6667
+usemtl Neutral
+s 1
+f 1/1/1 2/2/1 3/3/1 4/4/1
+f 4/4/2 3/3/2 5/5/2 6/6/2
+f 4/7/3 6/6/3 7/8/3 1/9/3
+usemtl X
+s off
+f 21/10/4 25/11/4 22/12/4
+f 22/12/5 25/11/5 23/13/5
+f 21/14/2 22/15/2 23/16/2 24/17/2
+f 23/13/6 25/11/6 24/18/6
+f 24/18/7 25/11/7 21/10/7
+s 1
+f 8/19/8 2/20/8 9/21/8 10/22/8
+f 11/23/9 10/22/9 9/24/9 12/25/9
+f 7/8/10 8/19/10 10/22/10 11/23/10
+f 2/2/1 1/1/1 12/26/1 9/27/1
+f 1/9/3 7/8/3 11/23/3 12/28/3
+usemtl Y
+f 6/6/2 5/5/2 13/29/2 14/30/2
+f 14/30/10 13/29/10 15/31/10 16/32/10
+f 8/19/9 7/8/9 16/32/9 15/31/9
+f 7/8/3 6/6/3 14/30/3 16/32/3
+f 5/5/8 8/19/8 15/31/8 13/29/8
+usemtl Z
+s off
+f 31/33/11 35/34/11 32/35/11
+f 32/35/12 35/34/12 33/36/12
+f 31/37/3 32/38/3 33/39/3 34/40/3
+f 33/36/13 35/34/13 34/41/13
+f 34/41/14 35/34/14 31/33/14
+s 1
+f 3/3/1 2/2/1 17/42/1 18/43/1
+f 19/44/8 18/45/8 17/46/8 20/47/8
+f 2/20/9 8/19/9 20/47/9 17/46/9
+f 5/5/2 3/3/2 18/43/2 19/44/2
+f 8/19/10 5/5/10 19/44/10 20/47/10
+usemtl Y.001
+s off
+f 26/48/15 30/49/15 27/50/15
+f 27/50/16 30/49/16 28/51/16
+f 26/52/1 27/53/1 28/54/1 29/55/1
+f 28/51/17 30/49/17 29/56/17
+f 29/56/18 30/49/18 26/48/18
diff --git a/source/arviz_godot/project/models/pose_orientationindicator.obj.import b/source/arviz_godot/project/models/pose_orientationindicator.obj.import
new file mode 100644
index 0000000000000000000000000000000000000000..783271b99d9b00760ab9802c5027cb47e5514edd
--- /dev/null
+++ b/source/arviz_godot/project/models/pose_orientationindicator.obj.import
@@ -0,0 +1,20 @@
+[remap]
+
+importer="wavefront_obj"
+type="Mesh"
+path="res://.import/pose_orientationindicator.obj-4fac95edc52858042a1b84e8f5a3345c.mesh"
+
+[deps]
+
+files=[ "res://.import/pose_orientationindicator.obj-4fac95edc52858042a1b84e8f5a3345c.mesh" ]
+
+source_file="res://models/pose_orientationindicator.obj"
+dest_files=[ "res://.import/pose_orientationindicator.obj-4fac95edc52858042a1b84e8f5a3345c.mesh", "res://.import/pose_orientationindicator.obj-4fac95edc52858042a1b84e8f5a3345c.mesh" ]
+
+[params]
+
+generate_tangents=true
+scale_mesh=Vector3( 1, 1, 1 )
+offset_mesh=Vector3( 0, 0, 0 )
+octahedral_compression=true
+optimize_mesh_flags=4286
diff --git a/source/arviz_godot/project/project.godot b/source/arviz_godot/project/project.godot
index 068e4688030453af2ad6fe4606c9bcf45dbd0bfb..a91e6616bdf1c1a7a14367eb0cd58f5535b5942d 100644
--- a/source/arviz_godot/project/project.godot
+++ b/source/arviz_godot/project/project.godot
@@ -44,7 +44,7 @@ avi_camera_view_reset={
 }
 avi_camera_focus_point={
 "deadzone": 0.5,
-"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":72,"unicode":0,"echo":false,"script":null)
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":70,"unicode":0,"echo":false,"script":null)
  ]
 }
 avi_camera_focus_scene={
@@ -54,7 +54,7 @@ avi_camera_focus_scene={
 }
 avi_screenshot={
 "deadzone": 0.5,
-"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":66,"unicode":0,"echo":false,"script":null)
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":67,"unicode":0,"echo":false,"script":null)
  ]
 }
 avi_video={
@@ -64,7 +64,7 @@ avi_video={
 }
 avi_hide_ui={
 "deadzone": 0.5,
-"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":73,"unicode":0,"echo":false,"script":null)
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":84,"unicode":0,"echo":false,"script":null)
  ]
 }
 avi_camera_forward={
@@ -109,7 +109,7 @@ avi_camera_up={
 }
 avi_camera_down={
 "deadzone": 0.5,
-"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":67,"unicode":0,"echo":false,"script":null)
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":88,"unicode":0,"echo":false,"script":null)
  ]
 }
 avi_manipulator_none={
@@ -135,6 +135,17 @@ avi_manipulator_scale={
 avi_lock_escape={
 "deadzone": 0.5,
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":16777217,"unicode":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":52,"unicode":0,"echo":false,"script":null)
+ ]
+}
+avi_camera_technical={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":52,"unicode":0,"echo":false,"script":null)
+ ]
+}
+avi_camera_playful={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":53,"unicode":0,"echo":false,"script":null)
  ]
 }
 
diff --git a/source/arviz_godot/project/root.tscn b/source/arviz_godot/project/root.tscn
index e7976e328e0bc2e9aa566a985c5f0fac7f21e737..7f2fa17693b57ad9c1440b2d085ad8916392892c 100644
--- a/source/arviz_godot/project/root.tscn
+++ b/source/arviz_godot/project/root.tscn
@@ -17,9 +17,9 @@
 [ext_resource path="res://bin/gui/camera_mode_menu.gdns" type="Script" id=15]
 [ext_resource path="res://bin/scene/view_camera.gdns" type="Script" id=16]
 [ext_resource path="res://bin/scene/visualized_scene.gdns" type="Script" id=17]
-[ext_resource path="res://bin/gui/layer_selection.gdns" type="Script" id=18]
+[ext_resource path="res://Layers.tscn" type="PackedScene" id=18]
 [ext_resource path="res://env.tres" type="Environment" id=19]
-[ext_resource path="res://bin/gui/graphics_settings.gdns" type="Script" id=20]
+[ext_resource path="res://Visuals.tscn" type="PackedScene" id=20]
 [ext_resource path="res://bin/interaction/interaction_dispatch.gdns" type="Script" id=21]
 [ext_resource path="res://bin/gui/settings_window.gdns" type="Script" id=22]
 [ext_resource path="res://bin/gui/orientation_window.gdns" type="Script" id=23]
@@ -38,7 +38,6 @@
 [ext_resource path="res://bin/interaction/rotate_axis_gizmo.gdns" type="Script" id=36]
 [ext_resource path="res://bin/interaction/scale_axis_gizmo.gdns" type="Script" id=37]
 [ext_resource path="res://bin/scene/orientation_indicator.gdns" type="Script" id=38]
-[ext_resource path="res://models/pose.obj" type="ArrayMesh" id=39]
 [ext_resource path="res://Replay.tscn" type="PackedScene" id=40]
 [ext_resource path="res://models/move_gizmo.obj" type="ArrayMesh" id=41]
 [ext_resource path="res://materials/gizmo_z_mat.tres" type="Material" id=42]
@@ -48,6 +47,7 @@
 [ext_resource path="res://models/rotation_gizmo.obj" type="ArrayMesh" id=46]
 [ext_resource path="res://UI/Icons/replay_recording_icon.png" type="Texture" id=47]
 [ext_resource path="res://bin/interaction/none.gdns" type="Script" id=48]
+[ext_resource path="res://models/pose_orientationindicator.obj" type="ArrayMesh" id=49]
 
 [sub_resource type="Environment" id=11]
 ambient_light_color = Color( 1, 1, 1, 1 )
@@ -129,7 +129,7 @@ transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 30 )
 
 [node name="Pose" type="MeshInstance" parent="OrientationIndicator"]
 transform = Transform( 0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0, 0, 0 )
-mesh = ExtResource( 39 )
+mesh = ExtResource( 49 )
 material/0 = null
 material/1 = null
 material/2 = null
@@ -153,7 +153,8 @@ render_target_update_mode = 3
 physics_object_picking = true
 
 [node name="View Camera" type="Camera" parent="3D/3D"]
-far = 2000.0
+near = 0.01
+far = 1000.0
 script = ExtResource( 16 )
 
 [node name="SpotLight" type="SpotLight" parent="3D/3D/View Camera"]
@@ -343,7 +344,7 @@ __meta__ = {
 [node name="Bar Container" type="HBoxContainer" parent="GUI/Bar/Bar Background"]
 anchor_right = 1.0
 anchor_bottom = 1.0
-margin_right = -913.0
+margin_right = -220.0
 rect_min_size = Vector2( 50, 32 )
 rect_pivot_offset = Vector2( -12, -70 )
 theme = ExtResource( 14 )
@@ -352,7 +353,7 @@ __meta__ = {
 }
 
 [node name="Scene Menu" type="MenuButton" parent="GUI/Bar/Bar Background/Bar Container"]
-margin_right = 58.0
+margin_right = 54.0
 margin_bottom = 40.0
 focus_mode = 2
 theme = ExtResource( 14 )
@@ -360,19 +361,19 @@ text = "Scene"
 items = [ "Orientation", null, 0, false, false, 0, 0, null, "", false, "Settings", null, 0, false, false, 1, 0, null, "", false, "Help", null, 0, false, false, 2, 0, null, "", false ]
 
 [node name="View Menu" type="MenuButton" parent="GUI/Bar/Bar Background/Bar Container"]
-margin_left = 62.0
-margin_right = 112.0
+margin_left = 58.0
+margin_right = 104.0
 margin_bottom = 40.0
 focus_mode = 2
 theme = ExtResource( 14 )
 text = "View"
-items = [ "Reset View", null, 0, false, false, 0, 0, null, "", false, "Focus All", null, 0, false, false, 1, 0, null, "", false, "Take Screenshot", null, 0, false, false, 2, 0, null, "", false, "Record Video", null, 0, false, false, 3, 0, null, "", false, "Hide UI", null, 0, false, false, 4, 0, null, "", false ]
+items = [ "[R] Reset View", null, 0, false, false, 0, 0, null, "", false, "[G] Focus All", null, 0, false, false, 1, 0, null, "", false, "[B] Take Screenshot", null, 0, false, false, 2, 0, null, "", false, "[V] Record Video", null, 0, false, false, 3, 0, null, "", false, "[I] Hide UI", null, 0, false, false, 4, 0, null, "", false ]
 
 [node name="ManipulationMenu" type="ItemList" parent="GUI/Bar/Bar Background/Bar Container"]
-margin_left = 116.0
-margin_right = 396.0
+margin_left = 108.0
+margin_right = 468.0
 margin_bottom = 40.0
-rect_min_size = Vector2( 280, 0 )
+rect_min_size = Vector2( 360, 0 )
 focus_mode = 0
 items = [ "", ExtResource( 12 ), false, "Move", ExtResource( 10 ), false, "Rotate", ExtResource( 8 ), false, "Scale", ExtResource( 11 ), false ]
 max_columns = 0
@@ -383,10 +384,10 @@ __meta__ = {
 }
 
 [node name="CameraMenu" type="ItemList" parent="GUI/Bar/Bar Background/Bar Container"]
-margin_left = 400.0
-margin_right = 595.0
+margin_left = 472.0
+margin_right = 707.0
 margin_bottom = 40.0
-rect_min_size = Vector2( 195, 0 )
+rect_min_size = Vector2( 235, 0 )
 focus_mode = 0
 items = [ "Technical", ExtResource( 27 ), false, "Playful", ExtResource( 25 ), false ]
 max_columns = 0
@@ -396,124 +397,185 @@ __meta__ = {
 "_edit_use_anchors_": false
 }
 
-[node name="Overlays" type="TabContainer" parent="GUI"]
-anchor_left = 1.0
-anchor_right = 1.0
-anchor_bottom = 1.0
-margin_left = -359.0
-custom_styles/panel = SubResource( 3 )
-tab_align = 2
+[node name="CenterHere" type="CenterContainer" parent="GUI/Bar/Bar Background/Bar Container"]
+margin_left = 711.0
+margin_right = 771.0
+margin_bottom = 40.0
 __meta__ = {
 "_edit_use_anchors_": false
 }
 
-[node name="X" type="Control" parent="GUI/Overlays"]
-anchor_right = 1.0
-anchor_bottom = 1.0
-margin_top = 40.0
+[node name="Focus" type="RichTextLabel" parent="GUI/Bar/Bar Background/Bar Container/CenterHere"]
+margin_top = 12.0
+margin_right = 60.0
+margin_bottom = 27.0
+rect_min_size = Vector2( 60, 0 )
+text = "[F] Focus"
+fit_content_height = true
+__meta__ = {
+"_edit_use_anchors_": false
+}
 
-[node name="Visuals" type="Control" parent="GUI/Overlays"]
-visible = false
-anchor_right = 1.0
-anchor_bottom = 1.0
-margin_top = 40.0
-script = ExtResource( 20 )
+[node name="CenterViewAll" type="CenterContainer" parent="GUI/Bar/Bar Background/Bar Container"]
+margin_left = 775.0
+margin_right = 855.0
+margin_bottom = 40.0
+__meta__ = {
+"_edit_use_anchors_": false
+}
 
-[node name="Background" type="ColorRect" parent="GUI/Overlays/Visuals"]
-self_modulate = Color( 0.2, 0.2, 0.2, 1 )
-anchor_right = 1.0
-anchor_bottom = 1.0
-margin_bottom = -519.0
+[node name="ViewAll" type="RichTextLabel" parent="GUI/Bar/Bar Background/Bar Container/CenterViewAll"]
+margin_top = 12.0
+margin_right = 80.0
+margin_bottom = 27.0
+rect_min_size = Vector2( 80, 0 )
+rect_pivot_offset = Vector2( 10, 10 )
+text = "[G] View All"
+fit_content_height = true
+
+[node name="CenterResetView" type="CenterContainer" parent="GUI/Bar/Bar Background/Bar Container"]
+margin_left = 859.0
+margin_right = 959.0
+margin_bottom = 40.0
 __meta__ = {
 "_edit_use_anchors_": false
 }
 
-[node name="Content" type="VBoxContainer" parent="GUI/Overlays/Visuals/Background"]
-anchor_right = 1.0
-anchor_bottom = 1.0
-margin_left = 10.0
-margin_top = 10.0
-margin_right = -10.0
-margin_bottom = -10.0
+[node name="ResetView" type="RichTextLabel" parent="GUI/Bar/Bar Background/Bar Container/CenterResetView"]
+margin_top = 12.0
+margin_right = 100.0
+margin_bottom = 27.0
+rect_min_size = Vector2( 100, 0 )
+text = "[R] Reset View"
+fit_content_height = true
 __meta__ = {
 "_edit_use_anchors_": false
 }
 
-[node name="Profiles" type="OptionButton" parent="GUI/Overlays/Visuals/Background/Content"]
-margin_right = 339.0
+[node name="CenterHideUI" type="CenterContainer" parent="GUI/Bar/Bar Background/Bar Container"]
+margin_left = 963.0
+margin_right = 1043.0
 margin_bottom = 40.0
+__meta__ = {
+"_edit_use_anchors_": false
+}
 
-[node name="Name" type="LineEdit" parent="GUI/Overlays/Visuals/Background/Content"]
-margin_top = 44.0
-margin_right = 339.0
-margin_bottom = 68.0
-
-[node name="Buttons" type="HBoxContainer" parent="GUI/Overlays/Visuals/Background/Content"]
-margin_top = 72.0
-margin_right = 339.0
-margin_bottom = 112.0
+[node name="HideUI" type="RichTextLabel" parent="GUI/Bar/Bar Background/Bar Container/CenterHideUI"]
+margin_top = 12.0
+margin_right = 80.0
+margin_bottom = 27.0
+rect_min_size = Vector2( 80, 0 )
+text = "[T] Toggle UI"
+fit_content_height = true
+__meta__ = {
+"_edit_use_anchors_": false
+}
 
-[node name="Save" type="Button" parent="GUI/Overlays/Visuals/Background/Content/Buttons"]
-margin_right = 167.0
+[node name="CenterCaptureScreen" type="CenterContainer" parent="GUI/Bar/Bar Background/Bar Container"]
+margin_left = 1047.0
+margin_right = 1167.0
 margin_bottom = 40.0
-size_flags_horizontal = 3
-text = "Save"
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="CaptureScreen" type="RichTextLabel" parent="GUI/Bar/Bar Background/Bar Container/CenterCaptureScreen"]
+margin_top = 12.0
+margin_right = 120.0
+margin_bottom = 27.0
+rect_min_size = Vector2( 120, 0 )
+rect_pivot_offset = Vector2( -317, 266 )
+text = "[C] Capture Screen"
+fit_content_height = true
+__meta__ = {
+"_edit_use_anchors_": false
+}
 
-[node name="Copy" type="Button" parent="GUI/Overlays/Visuals/Background/Content/Buttons"]
-margin_left = 171.0
-margin_right = 339.0
+[node name="CenterRecordVideo" type="CenterContainer" parent="GUI/Bar/Bar Background/Bar Container"]
+margin_left = 1171.0
+margin_right = 1281.0
 margin_bottom = 40.0
-size_flags_horizontal = 3
-text = "Copy"
+__meta__ = {
+"_edit_use_anchors_": false
+}
 
-[node name="Scroll" type="ScrollContainer" parent="GUI/Overlays/Visuals/Background/Content"]
-margin_top = 116.0
-margin_right = 339.0
-margin_bottom = 501.0
-size_flags_vertical = 3
+[node name="RecordVideo" type="RichTextLabel" parent="GUI/Bar/Bar Background/Bar Container/CenterRecordVideo"]
+margin_top = 12.0
+margin_right = 110.0
+margin_bottom = 27.0
+rect_min_size = Vector2( 110, 0 )
+rect_pivot_offset = Vector2( -317, 266 )
+text = "[V] Record Video"
+fit_content_height = true
 __meta__ = {
 "_edit_use_anchors_": false
 }
 
-[node name="Container" type="VBoxContainer" parent="GUI/Overlays/Visuals/Background/Content/Scroll"]
-margin_right = 339.0
-size_flags_horizontal = 3
+[node name="CenterLockMouse" type="CenterContainer" parent="GUI/Bar/Bar Background/Bar Container"]
+margin_left = 1285.0
+margin_right = 1385.0
+margin_bottom = 40.0
+__meta__ = {
+"_edit_use_anchors_": false
+}
 
-[node name="Replay" parent="GUI/Overlays" instance=ExtResource( 40 )]
+[node name="LockMouse" type="RichTextLabel" parent="GUI/Bar/Bar Background/Bar Container/CenterLockMouse"]
+margin_top = 12.0
+margin_right = 100.0
+margin_bottom = 27.0
+rect_min_size = Vector2( 100, 0 )
+rect_pivot_offset = Vector2( -317, 266 )
+text = "[L] Lock Mouse"
+fit_content_height = true
+__meta__ = {
+"_edit_use_anchors_": false
+}
 
-[node name="Layers" type="Control" parent="GUI/Overlays"]
-visible = false
-anchor_right = 1.0
-anchor_bottom = 1.0
-margin_top = 40.0
-script = ExtResource( 18 )
+[node name="CenterMouseWheel" type="CenterContainer" parent="GUI/Bar/Bar Background/Bar Container"]
+margin_left = 1389.0
+margin_right = 1509.0
+margin_bottom = 40.0
 __meta__ = {
 "_edit_use_anchors_": false
 }
 
-[node name="Background" type="ColorRect" parent="GUI/Overlays/Layers"]
-self_modulate = Color( 0.2, 0.2, 0.2, 1 )
-anchor_right = 1.0
-anchor_bottom = 1.0
-margin_bottom = -519.0
+[node name="MouseWheel" type="RichTextLabel" parent="GUI/Bar/Bar Background/Bar Container/CenterMouseWheel"]
+margin_top = 12.0
+margin_right = 120.0
+margin_bottom = 27.0
+rect_min_size = Vector2( 120, 0 )
+rect_pivot_offset = Vector2( -317, 266 )
+text = "[M] Mouse Wheel"
+fit_content_height = true
 __meta__ = {
 "_edit_use_anchors_": false
 }
 
-[node name="Scroll" type="ScrollContainer" parent="GUI/Overlays/Layers/Background"]
+[node name="Overlays" type="TabContainer" parent="GUI"]
+anchor_left = 1.0
 anchor_right = 1.0
 anchor_bottom = 1.0
-margin_left = 10.0
-margin_top = 10.0
-margin_right = -10.0
-margin_bottom = -10.0
+margin_left = -359.0
+margin_bottom = -530.0
+custom_styles/panel = SubResource( 3 )
+tab_align = 2
+drag_to_rearrange_enabled = true
 __meta__ = {
 "_edit_use_anchors_": false
 }
 
-[node name="Container" type="VBoxContainer" parent="GUI/Overlays/Layers/Background/Scroll"]
-margin_right = 339.0
-size_flags_horizontal = 3
+[node name="X" type="Control" parent="GUI/Overlays"]
+anchor_right = 1.0
+anchor_bottom = 1.0
+margin_top = 40.0
+
+[node name="Visuals" parent="GUI/Overlays" instance=ExtResource( 20 )]
+
+[node name="Replay" parent="GUI/Overlays" instance=ExtResource( 40 )]
+visible = false
+
+[node name="Layers" parent="GUI/Overlays" instance=ExtResource( 18 )]
+visible = false
 
 [node name="Settings" type="WindowDialog" parent="GUI"]
 margin_right = 400.0
@@ -538,33 +600,33 @@ __meta__ = {
 }
 
 [node name="Info" type="Label" parent="GUI/Settings/Container"]
-margin_right = 377.0
-margin_bottom = 20.0
+margin_right = 380.0
+margin_bottom = 14.0
 text = "Some settings require a restart to take effect."
 align = 1
 
 [node name="Save" type="Button" parent="GUI/Settings/Container"]
 margin_top = 18.0
-margin_right = 377.0
+margin_right = 380.0
 margin_bottom = 58.0
 custom_styles/normal = ExtResource( 7 )
 text = "Save"
 
 [node name="Table Head" type="HBoxContainer" parent="GUI/Settings/Container"]
 margin_top = 62.0
-margin_right = 377.0
+margin_right = 380.0
 margin_bottom = 76.0
 
 [node name="Option" type="Label" parent="GUI/Settings/Container/Table Head"]
-margin_right = 186.0
+margin_right = 188.0
 margin_bottom = 14.0
 size_flags_horizontal = 3
 text = "Option"
 align = 1
 
 [node name="Value" type="Label" parent="GUI/Settings/Container/Table Head"]
-margin_left = 190.0
-margin_right = 377.0
+margin_left = 192.0
+margin_right = 380.0
 margin_bottom = 14.0
 size_flags_horizontal = 3
 text = "Value"
@@ -572,15 +634,15 @@ align = 1
 
 [node name="Scroll" type="ScrollContainer" parent="GUI/Settings/Container"]
 margin_top = 80.0
-margin_right = 377.0
-margin_bottom = 225.0
+margin_right = 380.0
+margin_bottom = 265.0
 size_flags_vertical = 3
 __meta__ = {
 "_edit_use_anchors_": false
 }
 
 [node name="Content" type="VBoxContainer" parent="GUI/Settings/Container/Scroll"]
-margin_right = 377.0
+margin_right = 380.0
 size_flags_horizontal = 3
 
 [node name="Orientation" type="WindowDialog" parent="GUI"]
@@ -602,9 +664,9 @@ __meta__ = {
 }
 
 [node name="Values" type="HBoxContainer" parent="GUI/Orientation/Container"]
-margin_top = 3.0
+margin_top = 6.0
 margin_right = 274.0
-margin_bottom = 27.0
+margin_bottom = 30.0
 
 [node name="Label-X" type="Label" parent="GUI/Orientation/Container/Values"]
 margin_top = 5.0
@@ -652,14 +714,14 @@ max_value = 180.0
 value = 180.0
 
 [node name="Center" type="HBoxContainer" parent="GUI/Orientation/Container"]
-margin_top = 31.0
+margin_top = 34.0
 margin_right = 274.0
-margin_bottom = 71.0
+margin_bottom = 74.0
 alignment = 1
 
 [node name="Accept" type="Button" parent="GUI/Orientation/Container/Center"]
-margin_left = 117.0
-margin_right = 156.0
+margin_left = 119.0
+margin_right = 154.0
 margin_bottom = 40.0
 size_flags_horizontal = 0
 size_flags_vertical = 0
@@ -672,6 +734,7 @@ theme = ExtResource( 14 )
 script = ExtResource( 6 )
 
 [node name="StatusBar" type="Control" parent="GUI"]
+visible = false
 anchor_top = 1.0
 anchor_right = 1.0
 anchor_bottom = 1.0
@@ -716,6 +779,7 @@ __meta__ = {
 [node name="Help" type="WindowDialog" parent="GUI"]
 anchor_right = 0.5
 anchor_bottom = 0.5
+margin_bottom = 210.0
 theme = ExtResource( 14 )
 custom_constants/title_height = -20
 window_title = "Control Layout"
@@ -743,29 +807,51 @@ stretch_mode = 6
 [node name="Description" type="RichTextLabel" parent="GUI/Help/Content"]
 margin_top = 294.0
 margin_right = 920.0
-margin_bottom = 444.0
+margin_bottom = 693.0
 custom_constants/table_vseparation = 0
 custom_constants/table_hseparation = 0
 custom_constants/line_separation = 5
 bbcode_enabled = true
 bbcode_text = "
 
-The [color=#9e9e9e]gray[/color] keys are available in every mode.
+The [color=#9e9e9e]grey[/color] keys are used for selecting manipulators.
+
+The [color=#9eff9e]green[/color] keys are used for selecting a camera mode.
 
-The [color=#ffb5b5]red[/color] keys are used for the technical control scheme. 
+The [color=#ffe68a]yellow[/color] keys are used for setting the camera focus in the scene.
 
-The [color=#a7d9d9]blue[/color] keys are used for the playful control scheme. 
+The [color=#ff6b86]red[/color] keys are used for capturing videos or screenshots.
 
-Both control schemes use the mouse, and require the mouse wheel to be pressed. This can be disabled by locking the mouse. It is also possible to simulate a mouse wheel press using the mouse wheel key."
+The [color=#d28aff]pink[/color] keys are a substitute if no mouse is available.
+
+The [color=#6bcaff]blue[/color] keys are used for the playful control scheme. 
+[Shift + Mouse Wheel Scroll] Adjust the movement speed.
+
+The [color=#cdbaff]violet[/color] key is used for the technical control scheme. 
+[Shift + Mouse Wheel Scrool] Rotate the camera around its own axis. 
+[Shift + Mouse Wheel Press] Move the camera fixpoint around the scene.
+
+Both control schemes use the mouse and require the mouse wheel to be pressed. This can be disabled by locking the mouse. It is also possible to simulate a mouse wheel press by using the mouse wheel key."
 text = "
 
-The gray keys are available in every mode.
+The grey keys are used for selecting manipulators.
+
+The green keys are used for selecting a camera mode.
 
-The red keys are used for the technical control scheme. 
+The yellow keys are used for setting the camera focus in the scene.
+
+The red keys are used for capturing videos or screenshots.
+
+The pink keys are a substitute if no mouse is available.
 
 The blue keys are used for the playful control scheme. 
+[Shift + Mouse Wheel Scroll] Adjust the movement speed.
+
+The violet key is used for the technical control scheme. 
+[Shift + Mouse Wheel Scrool] Rotate the camera around its own axis. 
+[Shift + Mouse Wheel Press] Move the camera fixpoint around the scene.
 
-Both control schemes use the mouse, and require the mouse wheel to be pressed. This can be disabled by locking the mouse. It is also possible to simulate a mouse wheel press using the mouse wheel key."
+Both control schemes use the mouse and require the mouse wheel to be pressed. This can be disabled by locking the mouse. It is also possible to simulate a mouse wheel press by using the mouse wheel key."
 fit_content_height = true
 
 [node name="TextureRect" type="TextureRect" parent="GUI"]
diff --git a/source/arviz_godot/project/scenes/GUI.tscn b/source/arviz_godot/project/scenes/GUI.tscn
index f6bc0543bc4a66571fcf47d943d81fe7d1899692..0ee47c2f70c79f097e4a117b60bca7b80becdf3a 100644
--- a/source/arviz_godot/project/scenes/GUI.tscn
+++ b/source/arviz_godot/project/scenes/GUI.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=24 format=2]
+[gd_scene load_steps=25 format=2]
 
 [ext_resource path="res://bin/gui/camera_mode_menu.gdns" type="Script" id=1]
 [ext_resource path="res://bin/gui/manipulation_menu.gdns" type="Script" id=2]
@@ -22,6 +22,7 @@
 [ext_resource path="res://UI/Themes/transparent_styleboxflat.tres" type="StyleBox" id=20]
 [ext_resource path="res://UI/Icons/connected_icon256.png" type="Texture" id=21]
 [ext_resource path="res://UI/Icons/replay_icon256.png" type="Texture" id=22]
+[ext_resource path="res://scenes/options/tree_component_item.tscn" type="PackedScene" id=23]
 
 [sub_resource type="StyleBoxFlat" id=4]
 bg_color = Color( 0.6, 0.6, 0.6, 0 )
@@ -261,9 +262,9 @@ __meta__ = {
 "_edit_use_anchors_": false
 }
 
-[node name="Container" type="VBoxContainer" parent="Overlays/Layers/Background/Scroll"]
-margin_right = 339.0
-size_flags_horizontal = 3
+[node name="Layers" parent="Overlays/Layers/Background/Scroll" instance=ExtResource( 23 )]
+anchor_right = 0.0
+anchor_bottom = 0.0
 
 [node name="StatusBar" type="Control" parent="."]
 anchor_top = 1.0
diff --git a/source/arviz_godot/project/scenes/options/tree_component_item.tscn b/source/arviz_godot/project/scenes/options/tree_component_item.tscn
new file mode 100644
index 0000000000000000000000000000000000000000..558413f12144c9fa1035907518a1da63f01526da
--- /dev/null
+++ b/source/arviz_godot/project/scenes/options/tree_component_item.tscn
@@ -0,0 +1,8 @@
+[gd_scene format=2]
+
+[node name="Layers" type="Control"]
+anchor_right = 1.0
+anchor_bottom = 1.0
+__meta__ = {
+"_edit_use_anchors_": false
+}