diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6d2557ea435010d73fc36b67bab796e9b9c95a2e..3db9c3351ab442c30de1699aafcf6cf84ab0544e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -7,6 +7,7 @@ include_directories(
     "${PROJECT_SOURCE_DIR}/src/filein/include"
     "${PROJECT_SOURCE_DIR}/src/common/include"
     "${PROJECT_SOURCE_DIR}/src/controls/include"
+    "${PROJECT_SOURCE_DIR}/src/editor/include"
     )
 
 set(ROFIBOTS_LIBRARIES_TO_LINK_WITH
@@ -17,6 +18,7 @@ set(ROFIBOTS_LIBRARIES_TO_LINK_WITH
     filein
     common
     controls
+    editor
     )
 
 message("Including the following libraries to the build:")
@@ -34,6 +36,8 @@ add_subdirectory(./common)
 message("-- common")  
 add_subdirectory(./controls)
 message("-- controls")  
+add_subdirectory(./editor)
+message("-- editor")  
 
 message("Including the following executables to the build:")
 add_subdirectory(./studio)
diff --git a/src/editor/CMakeLists.txt b/src/editor/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..33aaa1d1cba2e17f8b7fb3c66a4abace3050f405
--- /dev/null
+++ b/src/editor/CMakeLists.txt
@@ -0,0 +1,15 @@
+set(THIS_TARGET_NAME editor)
+
+add_library(${THIS_TARGET_NAME}
+    ./include/editor/scene.hpp
+    ./src/scene.cpp
+
+    )
+
+set_target_properties(${THIS_TARGET_NAME} PROPERTIES
+    DEBUG_OUTPUT_NAME "${THIS_TARGET_NAME}_${CMAKE_SYSTEM_NAME}_Debug"
+    RELEASE_OUTPUT_NAME "${THIS_TARGET_NAME}_${CMAKE_SYSTEM_NAME}_Release"
+    RELWITHDEBINFO_OUTPUT_NAME "${THIS_TARGET_NAME}_${CMAKE_SYSTEM_NAME}_RelWithDebInfo"
+    )
+
+#install(TARGETS ${THIS_TARGET_NAME} DESTINATION "lib")
diff --git a/src/editor/include/editor/scene.hpp b/src/editor/include/editor/scene.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..344f40bc9afe6dcbd8b41d1f010a1ae8c9f4eea8
--- /dev/null
+++ b/src/editor/include/editor/scene.hpp
@@ -0,0 +1,95 @@
+#ifndef SCENE_INCLUDED
+#define SCENE_INCLUDED
+
+#include <common/frame.hpp>
+#include <common/node.hpp>
+#include <gfx/camera.hpp>
+#include <gfx/light.hpp>
+#include <gfx/mesh.hpp>
+#include <utils/math.hpp>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+using camera_ptr = std::shared_ptr<Camera>;
+using camera_weak_ptr = std::weak_ptr<Camera>;
+using light_ptr = std::shared_ptr<Light>;
+using mesh_ptr = std::shared_ptr<Mesh>;
+
+class Scene
+{
+private:
+    std::vector<node_ptr> scene;
+    node_ptr selection;
+    node_ptr selection_AABB;
+    node_ptr pre_add_AABB;
+
+    std::vector<light_ptr> lights;
+
+    std::vector<camera_ptr> cameras;
+    std::vector<camera_weak_ptr> active_cameras;
+
+public:
+    Scene(/* args */) = default;
+
+    /*const*/ std::vector<node_ptr>& getScene() { return scene; }
+    node_ptr getSelection() const { return selection; }
+    node_ptr getSelectionAABB() const { return selection_AABB; }
+    node_ptr getPreAddAABB() const { return pre_add_AABB; }
+
+    std::vector<light_ptr>& getLights() { return lights; }
+    std::vector<camera_ptr>& getCameras() { return cameras; }
+    std::vector<camera_weak_ptr>& getActiveCameras() { return active_cameras; }
+
+    void addActiveCamera(camera_ptr camera) { active_cameras.emplace_back(camera); }
+    void removeActiveCamera(camera_ptr camera);
+
+    void setSelection (node_ptr _selection) { selection = _selection; }
+    void setSelectionAABB (node_ptr _selection_AABB) { selection = _selection_AABB; }
+    void setPreAddAABB (node_ptr _pre_add_AABB) { pre_add_AABB = _pre_add_AABB; }
+
+    void addNode(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f));
+    void addNode(Frame frame = Frame());
+    void addNode(frame_ptr frame = std::make_shared<Frame>());
+    void addNode(Node node);
+
+    void removeNode(node_ptr node);
+
+    void addMeshNode(const std::string &file_name, frame_ptr frame);
+    void addMeshNode(const std::string &file_name, Frame frame);
+    void addMeshNode(const std::string &file_name, glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f));
+
+    void addLightNode(glm::vec3 color = glm::vec3(1.0f, 1.0f, 1.0f), frame_ptr frame = std::make_shared<Frame>());
+    void addLightNode(glm::vec3 color = glm::vec3(1.0f, 1.0f, 1.0f), Frame frame = Frame{});
+    void addLightNode(glm::vec3 color = glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f));
+
+    void addCameraNode(float FOV, frame_ptr frame);
+    void addCameraNode(float FOV, Frame frame);
+    void addCameraNode(float FOV, glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f));
+
+    void addMesh(node_ptr node, const std::string &file_name);
+    void addMesh(node_ptr node, mesh_ptr mesh);
+    void addMesh(node_ptr node, Mesh mesh);
+    void addMesh(node_ptr node, std::vector<float> vertices, std::vector<unsigned int> indices, std::vector<float> normals);
+
+    void addLight(node_ptr node, light_ptr light);
+    void addLight(node_ptr node, Light light);
+    void addLight(node_ptr node, glm::vec3 color = glm::vec3(1.0f, 1.0f, 1.0f));
+
+    void addCamera(node_ptr node, camera_ptr camera);
+    void addCamera(node_ptr node, Camera camera);
+    void addCamera(node_ptr node, float FOV);
+
+    void addRay(glm::vec3 ray_position, glm::vec3 ray_direction);
+    void addSelectionAABB(node_ptr node);
+    void addPreAddAABB(node_ptr node, Frame position);
+
+    void findLights(const std::vector<node_ptr> &nodes);
+    void findCameras(const std::vector<node_ptr> &nodes);
+
+    void changeDrawMode(node_ptr node, unsigned int mode);
+    void manageSelection(node_ptr nearest_node); // Not node tree compatible
+};
+
+#endif
\ No newline at end of file
diff --git a/src/editor/src/scene.cpp b/src/editor/src/scene.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..89d19f75be47e3010213336506182c01c31cbcfb
--- /dev/null
+++ b/src/editor/src/scene.cpp
@@ -0,0 +1,252 @@
+#include <editor/scene.hpp>
+#include <filein/obj_loader.hpp>
+
+#include <iostream>
+
+void Scene::removeActiveCamera(camera_ptr camera)
+{
+    // if (!camera)
+    //     return;
+    // auto it = std::find(active_cameras.begin(), active_cameras.end(), camera);
+    // if (it != active_cameras.end())
+    //     active_cameras.erase(it);
+}
+
+void Scene::addNode(glm::vec3 position) 
+{
+    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(position)));
+}
+
+void Scene::addNode(Frame frame)
+{
+    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(frame)));
+}
+
+void Scene::addNode(frame_ptr frame)
+{
+    scene.emplace_back(std::make_shared<Node>(frame));
+}
+
+void Scene::addNode(Node node)
+{
+    scene.emplace_back(std::make_shared<Node>(std::move(node)));
+}
+
+void Scene::removeNode(node_ptr node)
+{
+    if (!node)
+        return;
+    auto it = std::find(scene.begin(), scene.end(), node);
+    if (it != scene.end())
+        scene.erase(it);
+    node = nullptr;
+}
+void Scene::addMeshNode(const std::string &file_name, frame_ptr frame)
+{
+    scene.emplace_back(std::make_shared<Node>(frame));
+    scene.back()->addObject(load_object(file_name));
+}
+
+void Scene::addMeshNode(const std::string &file_name, Frame frame)
+{
+    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(frame)));
+    scene.back()->addObject(load_object(file_name));
+}
+
+void Scene::addMeshNode(const std::string &file_name, glm::vec3 position)
+{
+    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(position)));
+    scene.back()->addObject(load_object(file_name));
+}
+
+void Scene::addLightNode(glm::vec3 color, frame_ptr frame)
+{
+    scene.emplace_back(std::make_shared<Node>(frame));
+    scene.back()->addObject(std::make_shared<Light>(color, scene.back()->getFrame()));
+}
+
+void Scene::addLightNode(glm::vec3 color, Frame frame)
+{
+    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(frame)));
+    scene.back()->addObject(std::make_shared<Light>(color, scene.back()->getFrame()));
+}
+
+void Scene::addLightNode(glm::vec3 color, glm::vec3 position)
+{
+    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(position)));
+    scene.back()->addObject(std::make_shared<Light>(color, scene.back()->getFrame()));
+}
+
+void Scene::addCameraNode(float FOV, frame_ptr frame)
+{
+    scene.emplace_back(std::make_shared<Node>(frame));
+    scene.back()->addObject(std::make_shared<Camera>(FOV, scene.back()->getFrame()));
+}
+
+void Scene::addCameraNode(float FOV, Frame frame)
+{
+    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(frame)));
+    scene.back()->addObject(std::make_shared<Camera>(FOV, scene.back()->getFrame()));
+}
+
+void Scene::addCameraNode(float FOV, glm::vec3 position)
+{
+    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(position)));
+    scene.back()->addObject(std::make_shared<Camera>(FOV, scene.back()->getFrame()));
+}
+
+void Scene::addMesh(node_ptr node, const std::string &file_name)
+{
+    node->addObject(std::move(load_object(file_name)));
+}
+
+void Scene::addMesh(node_ptr node, mesh_ptr mesh)
+{
+    node->addObject(std::move(mesh));
+}
+
+void Scene::addMesh(node_ptr node, Mesh mesh)
+{
+    node->addObject(std::make_shared<Mesh>(mesh));
+}
+
+void Scene::addMesh(node_ptr node, std::vector<float> vertices, std::vector<unsigned int> indices, std::vector<float> normals)
+{
+    node->addObject(std::make_shared<Mesh>(Mesh{vertices, indices, normals}));
+}
+
+void Scene::addLight(node_ptr node, light_ptr light)
+{
+    node->addObject(std::move(light));
+}
+
+void Scene::addLight(node_ptr node, Light light)
+{
+    node->addObject(std::make_shared<Light>(light));
+}
+
+void Scene::addLight(node_ptr node, glm::vec3 color)
+{
+    node->addObject(std::make_shared<Light>(Light{color, node->getFrame()}));
+}
+
+void Scene::addCamera(node_ptr node, camera_ptr camera)
+{
+    node->addObject(std::move(camera));
+}
+
+void Scene::addCamera(node_ptr node, Camera camera)
+{
+    node->addObject(std::make_shared<Camera>(camera));
+}
+
+void Scene::addCamera(node_ptr node, float FOV)
+{
+    node->addObject(std::make_shared<Camera>(Camera{FOV, node->getFrame()}));
+}
+void Scene::addRay(glm::vec3 ray_position, glm::vec3 ray_direction)
+{
+    mesh_ptr ray = std::make_shared<Mesh>(Mesh{{0, 0, 0, ray_direction.x, ray_direction.y, ray_direction.z},
+                                                     {0, 1}, 
+                                                     {}, 
+                                                     glm::vec3(0.5f, 1, 0.31f), "basic"});
+    ray->setDrawMode(GL_LINES);
+    ray->setSelectability(false);
+
+    addNode(ray_position);
+    addMesh(scene.back(), ray);
+}
+
+// TO DO: following two functions almost identical - fix
+
+void Scene::addSelectionAABB(node_ptr node)
+{
+    addNode(node->getFrame());
+    selection_AABB = scene.back();
+    for (auto &object : node->getObjects())
+    {
+        auto obj = dynamic_pointer_cast<Mesh>(object);
+        if (!obj)
+            continue;
+        
+        Mesh obj_bbox(obj->getAABB().getVertices(), obj->getAABB().getIndices(), 
+                        std::vector<float>{}, glm::vec3(0.5f, 1, 0.31f), "basic");
+        obj_bbox.setSelectability(false);
+        obj_bbox.setDrawMode(GL_LINES);
+        
+        addMesh(selection_AABB, std::move(obj_bbox));
+    }
+}
+
+void Scene::addPreAddAABB(node_ptr node, Frame position)
+{
+    addNode(position);
+    pre_add_AABB = scene.back();
+    for (auto &object : node->getObjects())
+    {
+        auto obj = dynamic_pointer_cast<Mesh>(object);
+        if (!obj)
+            continue;
+            
+        Mesh obj_bbox(obj->getAABB().getVertices(), obj->getAABB().getIndices(), 
+                        std::vector<float>{}, glm::vec3(0.5f, 1, 0.31f), "basic");
+        obj_bbox.setSelectability(false);
+        obj_bbox.setDrawMode(GL_LINES);
+
+        scene.back()->addObject(std::make_shared<Mesh>(std::move(obj_bbox)));
+        addMesh(scene.back(), std::move(obj_bbox));
+    }
+}
+void Scene::findLights(const std::vector<node_ptr> &nodes)
+{
+    for (auto &node : nodes)
+    {
+        for (auto &object : node->getObjects())
+        {
+            auto light = dynamic_pointer_cast<Light>(object);
+            if (light)
+                lights.emplace_back(light);
+        } 
+        findLights(node->getChildren());
+    }
+}
+
+void Scene::findCameras(const std::vector<node_ptr> &nodes)
+{
+    int node_num = 0;
+    for (auto &node : nodes)
+    {
+        std::cout << node_num << std::endl;
+        for (auto &object : node->getObjects())
+        {
+            auto camera = dynamic_pointer_cast<Camera>(object);
+            if (camera)
+                cameras.emplace_back(camera);
+        } 
+        ++node_num;
+        findCameras(node->getChildren());
+    }
+}
+void Scene::changeDrawMode(node_ptr node, unsigned int mode)
+{
+    for (auto &object : node->getObjects())
+    {
+        auto obj = dynamic_pointer_cast<Mesh>(object);
+        if (!obj)
+            continue;
+        obj->setDrawMode(mode);
+    }
+}
+
+void Scene::manageSelection(node_ptr nearest_node)
+{
+    removeNode(selection_AABB);
+
+    if (!nearest_node)
+    {
+        selection = nullptr;
+        return;
+    }
+    selection = nearest_node;
+    addSelectionAABB(nearest_node);
+}
diff --git a/src/gfx/include/gfx/mesh.hpp b/src/gfx/include/gfx/mesh.hpp
index d6b8bb48ad27f6b310a041e9840f2c674eacf813..7db99b9df4aae8c165b05a0e2d929a3156f6919a 100644
--- a/src/gfx/include/gfx/mesh.hpp
+++ b/src/gfx/include/gfx/mesh.hpp
@@ -18,7 +18,7 @@ class Mesh : public ObjectBase
 {
     VAO_ptr _VAO = std::make_shared<VAO>();
     glm::vec3 color;
-    std::string shader_type;
+    std::string shader_type = "lit";
     bool selectable = true;
 
     int draw_mode = GL_TRIANGLES;
diff --git a/src/gfx/include/gfx/render.hpp b/src/gfx/include/gfx/render.hpp
index ec6070eea9d4e6268d9afc71b17594165336d546..7276519135f1d2cc6d0dc702668ddbf0aa000ab7 100644
--- a/src/gfx/include/gfx/render.hpp
+++ b/src/gfx/include/gfx/render.hpp
@@ -28,6 +28,6 @@ glm::mat4 get_projection_matrix(camera_ptr camera);
 void gfx_draw(std::map<std::string, shader_ptr> &my_shaders, 
               std::vector<light_ptr> lights,
               camera_ptr camera,
-              std::vector<node_ptr> &scene);
+              const std::vector<node_ptr> &scene);
 
 #endif
\ No newline at end of file
diff --git a/src/gfx/src/render.cpp b/src/gfx/src/render.cpp
index 9da79e27a034a9b841708c57766f98027451c400..78d7101b2adf5adbb002dde52c0fe44bf3e41b37 100644
--- a/src/gfx/src/render.cpp
+++ b/src/gfx/src/render.cpp
@@ -123,7 +123,7 @@ void draw_objects(std::map<std::string, shader_ptr> &my_shaders, std::vector<lig
 void gfx_draw(std::map<std::string, shader_ptr> &my_shaders, 
               std::vector<light_ptr> lights,
               camera_ptr camera,
-              std::vector<node_ptr> &scene)
+              const std::vector<node_ptr> &scene)
 {
     glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
diff --git a/src/studio/include/studio/simulator.hpp b/src/studio/include/studio/simulator.hpp
index 0d0e712008937ca09c3f7d4212317acba0705646..9e9b00a1659e3a42df4e9ec191ba5965c8cc6935 100644
--- a/src/studio/include/studio/simulator.hpp
+++ b/src/studio/include/studio/simulator.hpp
@@ -8,6 +8,7 @@
 #include <common/node.hpp>
 #include <controls/cam_control.hpp>
 #include <controls/obj_control.hpp>
+#include <editor/scene.hpp>
 #include <gfx/camera.hpp>
 #include <gfx/light.hpp>
 #include <gfx/mesh.hpp>
@@ -27,6 +28,7 @@ using node_ptr = std::shared_ptr<Node>;
 using obj_control_ptr = std::shared_ptr<ObjectController>;
 using cam_control_ptr = std::shared_ptr<CameraController>;
 using light_ptr = std::shared_ptr<Light>;
+using scene_ptr = std::shared_ptr<Scene>;
 using shader_ptr = std::shared_ptr<Shader>;
 
 enum class state { select, move, rotate, plus };
@@ -39,24 +41,21 @@ struct Simulator : public osi::Simulator
     void update() override;
     void present() override;
 
-    // std::string stateToStr();
-    // void showUI();
-
-    void findLights(const std::vector<node_ptr> &scene);
-    void findCameras(const std::vector<node_ptr> &scene);
+    // void findLights(const std::vector<node_ptr> &scene);
+    // void findCameras(const std::vector<node_ptr> &scene);
     void createScene();
     
     void processInput();
 
-    void addRay(glm::vec3 ray_position, glm::vec3 ray_direction);
-    void addSelectionAABB(node_ptr node);
-    void addPreAddAABB(node_ptr node, Frame position);
+    // void addRay(glm::vec3 ray_position, glm::vec3 ray_direction);
+    // void addSelectionAABB(node_ptr node);
+    // void addPreAddAABB(node_ptr node, Frame position);
 
     std::pair<glm::vec3, glm::vec3> getPickRay();
-    void manageSelection(node_ptr nearest_node); // Not node tree compatible
+    // void manageSelection(node_ptr nearest_node); // Not node tree compatible
 
-    void removeNode(node_ptr node);
-    void changeDrawMode(node_ptr node, unsigned int mode);
+    // void removeNode(node_ptr node);
+    // void changeDrawMode(node_ptr node, unsigned int mode);
 
     void selectObject();
     void rotateObject();
@@ -80,15 +79,16 @@ private:
     std::vector<cam_control_ptr> cam_controls;
 
     /* SCENE */
-    std::vector<node_ptr> scene;
-    node_ptr selection;
-    node_ptr selection_AABB;
-    node_ptr pre_add_AABB;
+    scene_ptr scene = std::make_shared<Scene>();
+    // std::vector<node_ptr> scene;
+    // node_ptr selection;
+    // node_ptr selection_AABB;
+    // node_ptr pre_add_AABB;
 
-    std::vector<light_ptr> lights;
+    // std::vector<light_ptr> lights;
 
-    std::vector<camera_ptr> cameras;
-    std::vector<camera_ptr> active_cameras;
+    // std::vector<camera_ptr> cameras;
+    // std::vector<camera_ptr> active_cameras;
 
     /* SHADERS */
     std::map<std::string, shader_ptr> my_shaders;
@@ -98,7 +98,7 @@ std::pair<float, float> intersect_axis(float ray_direction_a, float ray_position
 std::pair<float, float> intersect(glm::vec3 ray_position, glm::vec3 ray_direction, std::pair<glm::vec3, glm::vec3> LH);
 // findIntersection uses functions 'intersect_axis' and 'intersect' and is NOT node tree compatible yet
 // Also unsure if it should be a free function
-node_ptr find_intersection(std::vector<node_ptr> scene, glm::vec3 ray_position, glm::vec3 ray_direction);
+node_ptr find_intersection(const std::vector<node_ptr> &scene, glm::vec3 ray_position, glm::vec3 ray_direction);
 
 }
 
diff --git a/src/studio/src/simulator.cpp b/src/studio/src/simulator.cpp
index b257d688d9d9b91add9a579af0db8bf136addf92..bb472942895547cab2c00e4ed4aa264b8cf4a5cc 100644
--- a/src/studio/src/simulator.cpp
+++ b/src/studio/src/simulator.cpp
@@ -107,19 +107,24 @@ Simulator::Simulator()
     , cam_controls{std::make_shared<CameraController>()}
 {
     createScene();
-    findCameras(scene);
-    findLights(scene);
+    // findCameras(scene);
+    // findLights(scene);
+    scene->findCameras(scene->getScene());
+    scene->findLights(scene->getScene());
 
     /* ROTATE FIRST OBJECT */
-    obj_controls[object_ctrl_type]->setFrame(scene[0]->getFrame());
+    obj_controls[object_ctrl_type]->setFrame(scene->getScene()[0]->getFrame());
     obj_controls[object_ctrl_type]->rotate(glm::vec3(0.0f, 50.0f, 0.0f));
     obj_controls[object_ctrl_type]->rotate(glm::vec3(45.0f, 0.0f, 0.0f));  
 
     /* SET ACTIVE CAMERA AND CONTROLLER TYPE 
      * ADD ACTIVE CAMERAS HERE. */
-    active_cameras.emplace_back(cameras[0]);
-    active_cameras[0]->setWindowSize(window().size()); 
-    cam_controls[active_camera_type]->setFrame(active_cameras[0]->getFrame());
+    // active_cameras.emplace_back(cameras[0]);
+    scene->addActiveCamera(scene->getCameras()[0]);
+    // active_cameras[0]->setWindowSize(window().size()); 
+    scene->getActiveCameras()[0].lock()->setWindowSize(window().size());
+    // cam_controls[active_camera_type]->setFrame(active_cameras[0]->getFrame());
+    cam_controls[active_camera_type]->setFrame(scene->getActiveCameras()[0].lock()->getFrame());
 }
 
 Simulator::~Simulator() {}
@@ -142,168 +147,134 @@ void Simulator::present()
     /* Present the state to the user (i.e., render objects)
      * For now, we just clear screen buffers and show some gui widget. */
 
-    // showUI();
     show_ui(control_state);
 
-    for (auto &active_cam : active_cameras)
+    for (auto &active_cam : scene->getActiveCameras())
     {
         if (window().is_resized())
         {
-            active_cam->setWindowSize(window().size());
+            active_cam.lock()->setWindowSize(window().size());
         }
-        gfx_draw(my_shaders, lights, active_cam, scene);
+        gfx_draw(my_shaders, scene->getLights(), active_cam.lock(), scene->getScene());
     }
     
 }
 
-// std::string Simulator::stateToStr()
+// void Simulator::findLights(const std::vector<node_ptr> &scene)
 // {
-//     using enum state;
-//     switch(control_state)
+//     for (auto &node : scene)
 //     {
-//         case select:
-//             return "Select";
-//         case move:
-//             return "Move";
-//         case rotate:
-//             return "Rotate";
-//         case plus:
-//             return "+";
-//         default:
-//             return "Enum Error";
+//         for (auto &object : node->getObjects())
+//         {
+//             auto light = dynamic_pointer_cast<Light>(object);
+//             if (light)
+//                 lights.emplace_back(light);
+//         } 
+//         findLights(node->getChildren());
 //     }
 // }
 
-// void Simulator::showUI()
+// void Simulator::findCameras(const std::vector<node_ptr> &scene)
 // {
-//     ImGui::SetNextWindowPos(ImVec2(0, 0));
-//     ImGui::SetNextWindowSize(ImVec2(ImGui::CalcTextSize("Select Move Rotate +").x * 1.5f, 80));
-//     ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_NoMove 
-//                                       | ImGuiWindowFlags_NoResize 
-//                                       | ImGuiWindowFlags_NoCollapse);
-// 	    ImGui::Text("Operation: %s", stateToStr().c_str());
-
-//         if (ImGui::Button("Select"))
+//     for (auto &node : scene)
+//     {
+//         for (auto &object : node->getObjects())
 //         {
-//             control_state = state::select;
-//             std::cout << "mode: SELECT" << std::endl;
+//             auto camera = dynamic_pointer_cast<Camera>(object);
+//             if (camera)
+//                 cameras.emplace_back(camera);
 //         } 
-//         ImGui::SameLine();
-//         ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 10);
-
-//         if (ImGui::Button("Move"))
-//         {
-//             control_state = state::move;
-//             std::cout << "mode: MOVE" << std::endl;
-//         }
-//         ImGui::SameLine();
-//         ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 10);
-
-//         if (ImGui::Button("Rotate"))
-//         {
-//             control_state = state::rotate;
-//             std::cout << "mode: ROTATE" << std::endl;
-//         }
-
-//         ImGui::SameLine();
-//         ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 10);
-
-//         if (ImGui::Button("+"))
-//         {
-//             control_state = state::plus;
-//             std::cout << "mode: +" << std::endl;
-//         }
-
-// 	ImGui::End();
+//         findCameras(node->getChildren());
+//     }
 // }
 
-void Simulator::findLights(const std::vector<node_ptr> &scene)
-{
-    for (auto &node : scene)
-    {
-        for (auto &object : node->getObjects())
-        {
-            auto light = dynamic_pointer_cast<Light>(object);
-            if (light)
-                lights.emplace_back(light);
-        } 
-        findLights(node->getChildren());
-    }
-}
-
-void Simulator::findCameras(const std::vector<node_ptr> &scene)
-{
-    for (auto &node : scene)
-    {
-        for (auto &object : node->getObjects())
-        {
-            auto camera = dynamic_pointer_cast<Camera>(object);
-            if (camera)
-                cameras.emplace_back(camera);
-        } 
-        findCameras(node->getChildren());
-    }
-}
-
 void Simulator::createScene()
 {
     /* ADD DEFAULT CUBE */
     Mesh cube(lit_cube_vertices, lit_cube_indices, lit_cube_normals);
-    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(Frame{})));
-    scene.back()->addObject(std::make_shared<Mesh>(std::move(cube)));
-    auto cube_ptr = scene.back()->getObjects()[0];
+    // scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(Frame{})));
+    // scene.back()->addObject(std::make_shared<Mesh>(std::move(cube)));
+    // auto cube_ptr = scene.back()->getObjects()[0];
+
+    scene->addNode(Frame{});
+    scene->addMesh(scene->getScene().back(), cube);
 
     // // AXIS OBJECT
     // Mesh axis(axis_obj_vertices, axis_obj_indices, axis_obj_normals);
     // axis.setShaderType("basic");
     // scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(Frame{glm::vec3(3, 2, 0)})));
     // scene.back()->addObject(std::make_shared<Mesh>(std::move(axis)));
-    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(Frame{glm::vec3(5, 1, -4)})));
-    scene.back()->addObject(cube_ptr);
+    // scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(Frame{glm::vec3(5, 1, -4)})));
+    // scene.back()->addObject(cube_ptr);
+
+    scene->addNode(glm::vec3(5, 1, -4));
+    scene->addMesh(scene->getScene().back(), cube);
 
     // TRIANGLE
     Mesh triangle(triangle_vertices, triangle_indices);
     triangle.setShaderType("basic");
     //scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(Frame{glm::vec3(-2, 1, 0)})));
-    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(Frame{glm::vec3(0, -0.5f, 0)})));
-    scene.back()->addObject(std::make_shared<Mesh>(std::move(triangle)));
+    // scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(Frame{glm::vec3(0, -0.5f, 0)})));
+    // scene.back()->addObject(std::make_shared<Mesh>(std::move(triangle)));
+
+    scene->addNode(glm::vec3(0, -0.5f, 0));
+    scene->addMesh(scene->getScene().back(), triangle);
 
     /* ADD LIGHT CUBE AND ITS LIGHT */
-    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(Frame{glm::vec3(1.2f, 2.0f, 2.0f)})));
-    scene.back()->addObject(std::make_shared<Mesh>(lit_cube_vertices, 
-                                                     lit_cube_indices, 
-                                                     std::vector<float>{},
-                                                     glm::vec3(1.0f, 1.0f, 1.0f), 
-                                                     "basic"));
-    scene.back()->getFrame()->setScale(glm::vec3(0.1f, 0.1f, 0.1f));
-    scene.back()->addObject(std::make_shared<Light>(glm::vec3(1.0f, 1.0f, 1.0f), scene.back()->getFrame()));
+    // scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(Frame{glm::vec3(1.2f, 2.0f, 2.0f)})));
+    // scene.back()->addObject(std::make_shared<Mesh>(lit_cube_vertices, 
+    //                                                  lit_cube_indices, 
+    //                                                  std::vector<float>{},
+    //                                                  glm::vec3(1.0f, 1.0f, 1.0f), 
+    //                                                  "basic"));
+    // scene.back()->getFrame()->setScale(glm::vec3(0.1f, 0.1f, 0.1f));
+    // scene.back()->addObject(std::make_shared<Light>(glm::vec3(1.0f, 1.0f, 1.0f), scene.back()->getFrame()));
+
+
+    Mesh light_cube(lit_cube_vertices, 
+                    lit_cube_indices, 
+                    std::vector<float>{},
+                    glm::vec3(1.0f, 1.0f, 1.0f), 
+                    "basic");
+    scene->addNode(glm::vec3(1.2f, 2.0f, 2.0f));
+    scene->getScene().back()->getFrame()->setScale(glm::vec3(0.1f, 0.1f, 0.1f));
+    scene->addMesh(scene->getScene().back(), light_cube);
+    scene->addLight(scene->getScene().back(), glm::vec3(1.0f, 1.0f, 1.0f));
 
     /* ADD GRID */
-    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(glm::vec3(0, 0, 0))));
+    // scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(glm::vec3(0, 0, 0))));
     mesh_ptr grid = std::make_shared<Mesh>(generate_grid_vertices(100), 
                                                generate_grid_indices(100), 
                                                std::vector<float>{},
                                                glm::vec3(0.5f, 0.5f, 0.5f), 
                                                "basic");
     grid->setDrawMode(GL_LINES);     
-    grid->setSelectability(false);                                       
-    scene.back()->addObject(std::move(grid));
+    grid->setSelectability(false);   
+
+    // scene.back()->addObject(std::move(grid)); 
+
+    scene->addNode(Frame{});
+    scene->addMesh(scene->getScene().back(), std::move(grid));
 
     /* ADD DEER */
-    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(glm::vec3(0, 2, 0))));
-    mesh_ptr deer = load_object("./data/models/deer.obj");
-    scene.back()->getFrame()->setScale(glm::vec3(0.01f, 0.01f, 0.01f));
-    scene.back()->addObject(std::move(deer));
+    // scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(glm::vec3(0, 2, 0))));
+    // mesh_ptr deer = load_object("./data/models/deer.obj");
+    // scene.back()->getFrame()->setScale(glm::vec3(0.01f, 0.01f, 0.01f));
+    // scene.back()->addObject(std::move(deer));
+    scene->addMeshNode("./data/models/deer.obj", glm::vec3(0, 2, 0));
+    scene->getScene().back()->getFrame()->setScale(glm::vec3(0.01f, 0.01f, 0.01f));
 
     /* ADD .OBJ CUBE */
-    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(glm::vec3(-3, 2, 0))));
-    mesh_ptr file_cube = load_object("./data/models/cube.obj");
-    scene.back()->addObject(std::move(file_cube));
+    // scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(glm::vec3(-3, 2, 0))));
+    // mesh_ptr file_cube = load_object("./data/models/cube.obj");
+    // scene.back()->addObject(std::move(file_cube));
+    scene->addMeshNode("./data/models/cube.obj", glm::vec3(-3, 2, 0));
 
     /* ADD .OBJ VASE */
-    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(glm::vec3(2, 1, -1))));
-    mesh_ptr vase = load_object("./data/models/smooth_vase.obj");
-    scene.back()->addObject(std::move(vase));
+    // scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(glm::vec3(2, 1, -1))));
+    // mesh_ptr vase = load_object("./data/models/smooth_vase.obj");
+    // scene.back()->addObject(std::move(vase));
+    scene->addMeshNode("./data/models/smooth_vase.obj", glm::vec3(2, 1, -1));
 
     // /* ADD .OBJ GIRAFFE */
     // scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(glm::vec3(-5, 1, 3))));
@@ -311,8 +282,9 @@ void Simulator::createScene()
     // scene.back()->addObject(std::move(giraffe));
 
     /* ADD CAMERA */
-    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(glm::vec3(0.0f, 1.0f, 6.0f))));
-    scene.back()->addObject(std::make_shared<Camera>(60.0f, scene.back()->getFrame()));
+    // scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(glm::vec3(0.0f, 1.0f, 6.0f))));
+    // scene.back()->addObject(std::make_shared<Camera>(60.0f, scene.back()->getFrame()));
+    scene->addCameraNode(60.0f, glm::vec3(0.0f, 1.0f, 6.0f));
 }
 
 /* Object movement now works only for one object */
@@ -321,11 +293,11 @@ void Simulator::processInput()
     if (!window().has_keyboard_focus())
         return;
 
-    if (keyboard().down().contains("O") && selection)
+    if (keyboard().down().contains("O") && scene->getSelection())
     {
         for (auto &controller : obj_controls)
         {
-            controller->setup(timer().dt(), selection->getFrame());
+            controller->setup(timer().dt(), scene->getSelection()->getFrame());
             controller->keyboardMove(keyboard().down());
         }
     }
@@ -340,57 +312,57 @@ void Simulator::processInput()
     ASSUMPTION(glGetError() == GL_NO_ERROR);
 }
 
-void Simulator::addRay(glm::vec3 ray_position, glm::vec3 ray_direction)
-{
-    mesh_ptr ray = std::make_shared<Mesh>(Mesh{{0, 0, 0, ray_direction.x, ray_direction.y, ray_direction.z},
-                                                     {0, 1}, {}, glm::vec3(0.5f, 1, 0.31f), "basic"});
-    ray->setDrawMode(GL_LINES);
-    ray->setSelectability(false);
-
-    frame_ptr ray_frame = std::make_shared<Frame>(ray_position);
-    scene.emplace_back(std::make_shared<Node>(ray_frame));
-    scene.back()->addObject(std::move(ray));
-}
+// void Simulator::addRay(glm::vec3 ray_position, glm::vec3 ray_direction)
+// {
+//     mesh_ptr ray = std::make_shared<Mesh>(Mesh{{0, 0, 0, ray_direction.x, ray_direction.y, ray_direction.z},
+//                                                      {0, 1}, {}, glm::vec3(0.5f, 1, 0.31f), "basic"});
+//     ray->setDrawMode(GL_LINES);
+//     ray->setSelectability(false);
+
+//     frame_ptr ray_frame = std::make_shared<Frame>(ray_position);
+//     scene.emplace_back(std::make_shared<Node>(ray_frame));
+//     scene.back()->addObject(std::move(ray));
+// }
 
-void Simulator::addSelectionAABB(node_ptr node)
-{
-    scene.emplace_back(std::make_shared<Node>(node->getFrame()));
-    selection_AABB = scene.back();
-    for (auto &object : node->getObjects())
-    {
-        auto obj = dynamic_pointer_cast<Mesh>(object);
-        if (!obj)
-            continue;
+// void Simulator::addSelectionAABB(node_ptr node)
+// {
+//     scene.emplace_back(std::make_shared<Node>(node->getFrame()));
+//     selection_AABB = scene.back();
+//     for (auto &object : node->getObjects())
+//     {
+//         auto obj = dynamic_pointer_cast<Mesh>(object);
+//         if (!obj)
+//             continue;
         
-        Mesh obj_bbox(obj->getAABB().getVertices(), obj->getAABB().getIndices(), 
-                        std::vector<float>{}, glm::vec3(0.5f, 1, 0.31f), "basic");
-        obj_bbox.setSelectability(false);
-        obj_bbox.setDrawMode(GL_LINES);
-        scene.back()->addObject(std::make_shared<Mesh>(std::move(obj_bbox)));
-    }
-}
+//         Mesh obj_bbox(obj->getAABB().getVertices(), obj->getAABB().getIndices(), 
+//                         std::vector<float>{}, glm::vec3(0.5f, 1, 0.31f), "basic");
+//         obj_bbox.setSelectability(false);
+//         obj_bbox.setDrawMode(GL_LINES);
+//         scene.back()->addObject(std::make_shared<Mesh>(std::move(obj_bbox)));
+//     }
+// }
 
-void Simulator::addPreAddAABB(node_ptr node, Frame position)
-{
-    scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(position)));
-    pre_add_AABB = scene.back();
-    for (auto &object : node->getObjects())
-    {
-        auto obj = dynamic_pointer_cast<Mesh>(object);
-        if (!obj)
-            continue;
+// void Simulator::addPreAddAABB(node_ptr node, Frame position)
+// {
+//     scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(position)));
+//     pre_add_AABB = scene.back();
+//     for (auto &object : node->getObjects())
+//     {
+//         auto obj = dynamic_pointer_cast<Mesh>(object);
+//         if (!obj)
+//             continue;
             
-        Mesh obj_bbox(obj->getAABB().getVertices(), obj->getAABB().getIndices(), 
-                        std::vector<float>{}, glm::vec3(0.5f, 1, 0.31f), "basic");
-        obj_bbox.setSelectability(false);
-        obj_bbox.setDrawMode(GL_LINES);
-        scene.back()->addObject(std::make_shared<Mesh>(std::move(obj_bbox)));
-    }
-}
+//         Mesh obj_bbox(obj->getAABB().getVertices(), obj->getAABB().getIndices(), 
+//                         std::vector<float>{}, glm::vec3(0.5f, 1, 0.31f), "basic");
+//         obj_bbox.setSelectability(false);
+//         obj_bbox.setDrawMode(GL_LINES);
+//         scene.back()->addObject(std::make_shared<Mesh>(std::move(obj_bbox)));
+//     }
+// }
 
 std::pair<glm::vec3, glm::vec3> Simulator::getPickRay()
 {
-    camera_ptr camera = active_cameras[0]; // Should be changed to which viewport is in focus
+    camera_ptr camera = scene->getActiveCameras()[0].lock(); // Should be changed to which viewport is in focus
     glm::mat4 view = get_view_matrix(camera);
     glm::mat4 projection = get_projection_matrix(camera);
     
@@ -434,39 +406,39 @@ std::pair<glm::vec3, glm::vec3> Simulator::getPickRay()
     return {ray_position, ray_direction};
 }
 
-void Simulator::removeNode(node_ptr node)
-{
-    if (!node)
-        return;
-    auto it = std::find(scene.begin(), scene.end(), node);
-    if (it != scene.end())
-        scene.erase(it);
-    node = nullptr;
-}
+// void Simulator::removeNode(node_ptr node)
+// {
+//     if (!node)
+//         return;
+//     auto it = std::find(scene.begin(), scene.end(), node);
+//     if (it != scene.end())
+//         scene.erase(it);
+//     node = nullptr;
+// }
 
-void Simulator::changeDrawMode(node_ptr node, unsigned int mode)
-{
-    for (auto &object : node->getObjects())
-    {
-        auto obj = dynamic_pointer_cast<Mesh>(object);
-        if (!obj)
-            continue;
-        obj->setDrawMode(mode);
-    }
-}
+// void Simulator::changeDrawMode(node_ptr node, unsigned int mode)
+// {
+//     for (auto &object : node->getObjects())
+//     {
+//         auto obj = dynamic_pointer_cast<Mesh>(object);
+//         if (!obj)
+//             continue;
+//         obj->setDrawMode(mode);
+//     }
+// }
 
-void Simulator::manageSelection(node_ptr nearest_node)
-{
-    removeNode(selection_AABB);
+// void Simulator::manageSelection(node_ptr nearest_node)
+// {
+//     removeNode(selection_AABB);
 
-    if (!nearest_node)
-    {
-        selection = nullptr;
-        return;
-    }
-    selection = nearest_node;
-    addSelectionAABB(nearest_node);
-}
+//     if (!nearest_node)
+//     {
+//         selection = nullptr;
+//         return;
+//     }
+//     selection = nearest_node;
+//     addSelectionAABB(nearest_node);
+// }
 
 void Simulator::selectObject()
 {
@@ -475,14 +447,14 @@ void Simulator::selectObject()
 
     auto [ ray_position, ray_direction ] = getPickRay();
 
-    auto nearest_node = find_intersection(scene, ray_position, ray_direction);
+    auto nearest_node = find_intersection(scene->getScene(), ray_position, ray_direction);
 
-    manageSelection(nearest_node);
+    scene->manageSelection(nearest_node);
 }
 
 void Simulator::moveObject()
 {
-    if(!selection)
+    if(!scene->getSelection())
         return;
 
     // Mouse held down with init. click not on object
@@ -499,16 +471,16 @@ void Simulator::moveObject()
     auto [ ray_position, ray_direction ] = getPickRay();
 
     // Initial click not onto the selected object
-    if (!object_moving && find_intersection(scene, ray_position, ray_direction) != selection) 
+    if (!object_moving && find_intersection(scene->getScene(), ray_position, ray_direction) != scene->getSelection()) 
         return;
 
     /* Controller setup */
     auto controller = obj_controls[object_ctrl_type];
-    controller->setup(timer().dt(), selection->getFrame());
+    controller->setup(timer().dt(), scene->getSelection()->getFrame());
 
     if (keyboard().down().contains("LeftShift"))
         controller->mouseElevationMove(ray_position, ray_direction, 
-                                         active_cameras[0]->getFrame()->getRotation(), 
+                                         scene->getActiveCameras()[0].lock()->getFrame()->getRotation(), 
                                          prev_plane_intersect, object_moving);
     else
         controller->mouseHorizontalMove(ray_position, ray_direction, prev_plane_intersect, object_moving);
@@ -516,21 +488,21 @@ void Simulator::moveObject()
 
 void Simulator::rotateObject()
 {
-    if (!selection)
+    if (!scene->getSelection())
         return;
     auto controller = obj_controls[object_ctrl_type];
-    controller->setup(timer().dt(), selection->getFrame());
+    controller->setup(timer().dt(), scene->getSelection()->getFrame());
     controller->mouseRotate(mouse());
 }
 
 void Simulator::addObject()
 {
-    if (!selection || !(mouse().just_released().contains("MouseLeft") || mouse().down().contains("MouseLeft")))
+    if (!scene->getSelection() || !(mouse().just_released().contains("MouseLeft") || mouse().down().contains("MouseLeft")))
         return;
 
-    glm::vec3 position = selection->getFrame()->getPosition();
-    glm::quat rotation = selection->getFrame()->getRotation();
-    glm::vec3 scale = selection->getFrame()->getScale();
+    glm::vec3 position = scene->getSelection()->getFrame()->getPosition();
+    glm::quat rotation = scene->getSelection()->getFrame()->getRotation();
+    glm::vec3 scale = scene->getSelection()->getFrame()->getScale();
 
     auto [ ray_position , ray_direction ] = getPickRay();
 
@@ -541,25 +513,25 @@ void Simulator::addObject()
     Node selection_copy(std::make_shared<Frame>(new_item_frame));
 
     // TO DO: rewrite ifs in this method - ugly
-    if ((!pre_add_AABB && mouse().down().contains("MouseLeft"))
+    if ((!scene->getPreAddAABB() && mouse().down().contains("MouseLeft"))
         || mouse().just_released().contains("MouseLeft"))
     {    
-        for (auto &object : selection->getObjects())
+        for (auto &object : scene->getSelection()->getObjects())
             selection_copy.addObject(object);   
     }
 
-    if (!pre_add_AABB && mouse().down().contains("MouseLeft"))
-        addPreAddAABB(std::make_shared<Node>(std::move(selection_copy)), new_item_frame);
+    if (!scene->getPreAddAABB() && mouse().down().contains("MouseLeft"))
+        scene->addPreAddAABB(std::make_shared<Node>(std::move(selection_copy)), new_item_frame);
     else if (mouse().down().contains("MouseLeft"))
-        pre_add_AABB->setFrame(std::make_shared<Frame>(new_item_frame));
+        scene->getPreAddAABB()->setFrame(std::make_shared<Frame>(new_item_frame));
     else if (mouse().just_released().contains("MouseLeft"))
     {
-        scene.emplace_back(std::make_shared<Node>(std::move(selection_copy)));
-        selection = scene.back();
-        manageSelection(selection);
+        scene->addNode(std::move(selection_copy));
+        scene->setSelection(scene->getScene().back());
+        scene->manageSelection(scene->getSelection());
 
-        removeNode(pre_add_AABB);
-        pre_add_AABB = nullptr;
+        scene->removeNode(scene->getPreAddAABB());
+        scene->setPreAddAABB(nullptr);
     }
 }
 
@@ -621,7 +593,7 @@ std::pair<float, float> intersect(glm::vec3 ray_position, glm::vec3 ray_directio
     return {t0, t1};
 }
 
-node_ptr find_intersection(std::vector<node_ptr> scene, glm::vec3 ray_position, glm::vec3 ray_direction)
+node_ptr find_intersection(const std::vector<node_ptr> &scene, glm::vec3 ray_position, glm::vec3 ray_direction)
 {
     node_ptr nearest_node = nullptr;
     float nearest_t = std::numeric_limits<float>::infinity();