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();