From 09de33155e248af415b8b01a64f6cd6c40b1e751 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20=C5=A0toura=C4=8D?= <525032@mail.muni.cz>
Date: Thu, 18 May 2023 16:44:00 +0200
Subject: [PATCH] found light & camera vectors in simulator, light frame from
 node

---
 src/gfx/include/gfx/control.hpp         |  2 +-
 src/gfx/include/gfx/frame.hpp           | 16 +++++-----
 src/gfx/include/gfx/light.hpp           | 16 +++++++---
 src/gfx/include/gfx/node.hpp            | 12 +++++---
 src/gfx/include/gfx/objectbase.hpp      |  3 +-
 src/gfx/src/cam_control.cpp             | 23 +++++++++-----
 src/gfx/src/render.cpp                  |  4 +--
 src/studio/include/studio/simulator.hpp |  8 +++--
 src/studio/src/simulator.cpp            | 40 ++++++++++++++++++++++---
 9 files changed, 91 insertions(+), 33 deletions(-)

diff --git a/src/gfx/include/gfx/control.hpp b/src/gfx/include/gfx/control.hpp
index 13d5dc9..515f0b4 100644
--- a/src/gfx/include/gfx/control.hpp
+++ b/src/gfx/include/gfx/control.hpp
@@ -25,7 +25,7 @@ public:
     void setFrame(std::shared_ptr<Frame> frame) { bound_frame = frame; }
 
     virtual glm::vec3 getFrontVec() const { return -bound_frame->getRotationAxisZ(); }
-    virtual glm::vec3 getUpVec() const { return glm::vec3(0.0f, 1.0f, 0.0f); }
+    virtual glm::vec3 getUpVec() const { return bound_frame->getRotationAxisY(); }
     // virtual void setUpVec();
 
     void setStep(float dt);
diff --git a/src/gfx/include/gfx/frame.hpp b/src/gfx/include/gfx/frame.hpp
index 58cd06e..9c597ae 100644
--- a/src/gfx/include/gfx/frame.hpp
+++ b/src/gfx/include/gfx/frame.hpp
@@ -29,9 +29,9 @@ public:
     glm::quat getRotation() const { return rotationQuat; }
     glm::vec3 getScale() const { return scaleVec; }
 
-    glm::vec3 getRotationAxisX() const { return glm::column(glm::toMat3(rotationQuat), 0); }
-    glm::vec3 getRotationAxisY() const { return glm::column(glm::toMat3(rotationQuat), 1); }
-    glm::vec3 getRotationAxisZ() const { return glm::column(glm::toMat3(rotationQuat), 2); }
+    glm::vec3 getRotationAxisX() const { return glm::normalize(glm::column(glm::toMat3(rotationQuat), 0)); }
+    glm::vec3 getRotationAxisY() const { return glm::normalize(glm::column(glm::toMat3(rotationQuat), 1)); }
+    glm::vec3 getRotationAxisZ() const { return glm::normalize(glm::column(glm::toMat3(rotationQuat), 2)); }
 
     glm::mat4 getTranslationMat() const { return glm::translate(glm::mat4(1.0f), positionVec); }
     glm::mat4 getRotationMat() const { return glm::toMat4(rotationQuat); }
@@ -42,11 +42,13 @@ public:
 
     void setPosVec(glm::vec3 new_position) { positionVec = new_position; }
     void translatePosVec(glm::vec3 direction) { positionVec += direction; }
-    void setRotationQuat(glm::vec3 new_rotation) { rotationQuat = glm::tquat(glm::radians(new_rotation)); }
-    void setRotationQuat(glm::quat new_rotation) { rotationQuat = new_rotation; }
-    void rotateRotationQuat(glm::vec3 rotation) { rotationQuat *= glm::tquat(glm::radians(rotation)); }
-    void rotateRotationQuat(glm::quat rotation) { rotationQuat *= rotation; }
+    void setRotationQuat(glm::vec3 new_rotation) { rotationQuat = glm::normalize(glm::tquat(glm::radians(new_rotation))); normalizeQuat(); }
+    void setRotationQuat(glm::quat new_rotation) { rotationQuat = glm::normalize(new_rotation); normalizeQuat(); }
+    void rotateRotationQuat(glm::vec3 rotation) { rotationQuat *= glm::normalize(glm::tquat(glm::radians(rotation))); normalizeQuat(); }
+    void rotateRotationQuat(glm::quat rotation) { rotationQuat *= glm::normalize(rotation); normalizeQuat(); }
     void setScale(glm::vec3 new_scale) { scaleVec = new_scale; }
+
+    void normalizeQuat() { rotationQuat = glm::normalize(rotationQuat); } 
 };
 
 #endif
\ No newline at end of file
diff --git a/src/gfx/include/gfx/light.hpp b/src/gfx/include/gfx/light.hpp
index 5eacac2..4696f2c 100644
--- a/src/gfx/include/gfx/light.hpp
+++ b/src/gfx/include/gfx/light.hpp
@@ -5,19 +5,27 @@
 #include <glm/glm.hpp>
 
 #include <gfx/frame.hpp>
+#include <gfx/node.hpp>
 #include <gfx/objectbase.hpp>
 
+using frame_ptr = std::shared_ptr<Frame>;
+using frame_weak_ptr = std::weak_ptr<Frame>;
+
 class Light : public ObjectBase
 {
 protected:
     glm::vec3 color;
-    Frame frame;
+    frame_weak_ptr frame;
 public:
-    Light(glm::vec3 _color, glm::vec3 _pos) : color{_color}, frame{_pos} {}
+    Light(glm::vec3 _color, frame_ptr _pos) : color{_color}, frame{_pos} {}
     glm::vec3 getColor() { return color; }
 
-    virtual glm::vec3 getPosition() const { return frame.getPosition(); }
-    virtual glm::vec3 getDirection() const { return frame.getPosition(); }
+    virtual glm::vec3 getPosition() const
+    { 
+        frame_ptr f = frame.lock();
+        return f->getPosition();
+    }
+    virtual glm::vec3 getDirection() const { return getPosition(); }
     virtual ~Light() = default;
 };
 
diff --git a/src/gfx/include/gfx/node.hpp b/src/gfx/include/gfx/node.hpp
index 10c8b1a..e012dfd 100644
--- a/src/gfx/include/gfx/node.hpp
+++ b/src/gfx/include/gfx/node.hpp
@@ -9,29 +9,33 @@
 using objectbase_ptr = std::shared_ptr<ObjectBase>;
 using frame_ptr = std::shared_ptr<Frame>;
 
+class Node;
+
+using parent_weak_ptr = std::weak_ptr<Node>;
+
 class Node
 {
     using node_ptr = std::shared_ptr<Node>;
     frame_ptr frame;
     std::vector<node_ptr> children;
-    Node* parent;
+    parent_weak_ptr parent;
 
     std::vector<objectbase_ptr> objects;
 
 public:
-    Node(frame_ptr _frame, Node* _parent = nullptr, std::vector<node_ptr> _children = {})
+    Node(frame_ptr _frame, parent_weak_ptr _parent = std::weak_ptr<Node>(), std::vector<node_ptr> _children = {})
     : frame{_frame}, parent{_parent}, children{_children} {}
 
     frame_ptr getFrame() { return frame; }
     std::vector<node_ptr> &getChildren() { return children; }
-    Node* getParent() { return parent; }
+    parent_weak_ptr getParent() { return parent; }
     std::vector<objectbase_ptr> &getObjects() { return objects; };
 
     void setFrame(frame_ptr _frame) { frame = _frame; }
     void addChild(Node child) { children.emplace_back(std::make_shared<Node>(child)); }
     void addChild(node_ptr child) { children.emplace_back(child); }
     // void setChildren(std::vector<node_ptr> _children) { children = _children; }
-    void setParent(Node* _parent) { parent = _parent; }
+    void setParent(parent_weak_ptr _parent) { parent = _parent; }
 
     void addObject(ObjectBase _obj) { objects.emplace_back(std::make_shared<ObjectBase>(_obj)); }
     void addObject(objectbase_ptr _obj) { objects.emplace_back(_obj); }
diff --git a/src/gfx/include/gfx/objectbase.hpp b/src/gfx/include/gfx/objectbase.hpp
index 6fc09d4..b00081e 100644
--- a/src/gfx/include/gfx/objectbase.hpp
+++ b/src/gfx/include/gfx/objectbase.hpp
@@ -5,7 +5,8 @@
 class ObjectBase
 {
 public:
-    virtual int polymorph() { return 1; }
+    // virtual int polymorph() { return 1; }
+    virtual ~ObjectBase() = default;
 };
 
 #endif
\ No newline at end of file
diff --git a/src/gfx/src/cam_control.cpp b/src/gfx/src/cam_control.cpp
index 404da09..21f3163 100644
--- a/src/gfx/src/cam_control.cpp
+++ b/src/gfx/src/cam_control.cpp
@@ -3,16 +3,23 @@
 
 void CameraController::setFrontVec(float xoffset, float yoffset)
 {
-    // TO DO: fix pitch
-    auto pitch = glm::angleAxis(yoffset, glm::vec3(1, 0, 0));
-    auto yaw = glm::angleAxis(-xoffset, glm::vec3(0, 1, 0));
-    auto temp_rot_quat = pitch * bound_frame->getRotation();
-    auto temp_y_axis = glm::column(glm::toMat3(temp_rot_quat), 1);
-    std::cout << "dot product: " << glm::dot(temp_y_axis, glm::vec3(0, 1, 0)) << std::endl;
-    if (glm::dot(temp_y_axis, glm::vec3(0, 1, 0)) > 0.15f) // 0
+    // TO DO: fix yaw - normalizing zero vectors is an issue?
+    auto pitch = glm::angleAxis(yoffset, bound_frame->getRotationAxisX());
+    auto yaw = glm::angleAxis(-xoffset, glm::vec3(0.0f, 1.0f, 0.0f));
+    //auto yaw = glm::angleAxis(0.0001f, glm::vec3(0.0f, 1.0f, 0.0f));
+
+    auto R = glm::toMat3(glm::angleAxis(yoffset, bound_frame->getRotationAxisX()));
+    glm::vec3 rotated_y = R * bound_frame->getRotationAxisY();
+    
+    auto dprod = glm::dot(rotated_y, glm::vec3(0.0f, 1.0f, 0.0f));
+    std::cout << "dot: " << dprod << std::endl;
+
+    if (dprod > 0.0f)
     {
-        bound_frame->rotateRotationQuat(pitch * yaw);
+        bound_frame->rotateRotationQuat(yaw);
+        bound_frame->rotateRotationQuat(pitch);
     }
+
 }
 
 void CameraController::turn(float xoffset, float yoffset)
diff --git a/src/gfx/src/render.cpp b/src/gfx/src/render.cpp
index 66bf62d..98da051 100644
--- a/src/gfx/src/render.cpp
+++ b/src/gfx/src/render.cpp
@@ -183,8 +183,8 @@ void gfx_draw(std::map<std::string, shader_ptr> &myShaders, light_ptr light,
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     ASSUMPTION(glGetError() == GL_NO_ERROR);
 
-    std::vector<Node*> lights;
-    find_lights(scene, lights);
+    // std::vector<Node*> lights;
+    // find_lights(scene, lights);
 
     /* DRAW OBJECTS */
     draw_objects(myShaders, light, cam_frames, active_camera, scene, view, projection);
diff --git a/src/studio/include/studio/simulator.hpp b/src/studio/include/studio/simulator.hpp
index 749ba38..00a761f 100644
--- a/src/studio/include/studio/simulator.hpp
+++ b/src/studio/include/studio/simulator.hpp
@@ -46,6 +46,8 @@ struct Simulator : public osi::Simulator
     void update() override;
     void present() override;
     void showUI();
+    void find_lights(std::vector<node_ptr> &scene);
+    void find_cameras(std::vector<node_ptr> &scene);
     void create_scene();
     void process_input();
     void process_mouse();
@@ -59,7 +61,6 @@ struct Simulator : public osi::Simulator
     int active_camera = 0;  // FTO DO: vector of active cameras
     int active_camera_type = 0;
 
-    std::vector<camera_ptr> cameras;
     std::vector<frame_ptr> cam_frames;
     std::vector<cam_control_ptr> cam_controls;
 
@@ -68,7 +69,10 @@ struct Simulator : public osi::Simulator
     std::vector<obj_control_ptr> obj_controls;
 
     std::vector<node_ptr> scene;
-    Node* selection;
+    node_ptr selection;
+    std::vector<light_ptr> lights;
+    std::vector<camera_ptr> cameras;
+    // find cameras, lights zde vektory
 
     Object grid = Object(generate_grid_vertices(100), generate_grid_indices(100), {0, -1, 0},
                          glm::vec3(0.5f, 0.5f, 0.5f), "basic");
diff --git a/src/studio/src/simulator.cpp b/src/studio/src/simulator.cpp
index e7e76e5..ccfb6f4 100644
--- a/src/studio/src/simulator.cpp
+++ b/src/studio/src/simulator.cpp
@@ -124,13 +124,15 @@ Simulator::Simulator()
     , obj_frames{std::make_shared<Frame>(),
                  std::make_shared<Frame>(glm::vec3(1.2f, 2.0f, 2.0f ))}
     , obj_controls{std::make_shared<ObjectController>()}
-    , light{std::make_shared<Light>(glm::vec3(1.0f, 1.0f, 1.0f), obj_frames[1]->getPosition())}
+    //, light{std::make_shared<Light>(glm::vec3(1.0f, 1.0f, 1.0f), obj_frames[1]->getPosition())}
 {
     /* SET LIGHT CUBE SHADER AND SIZE */
     objects[1]->setShaderType("basic");
     obj_frames[1]->setScale(glm::vec3(0.1f, 0.1f, 0.1f));
 
     create_scene();
+    find_cameras(scene);
+    find_lights(scene);
 
     /* SET ACTIVE OBJECT AND ROTATE */
     active_object_idx = 0; // 1 for light
@@ -148,6 +150,8 @@ void Simulator::update()
 {
     /* Update the state (i.e., transform objects, create/destroy objects, ... ) */
     
+    // find_cameras(scene);
+    // find_lights(scene);
     process_input();
     process_mouse(); 
 
@@ -166,7 +170,7 @@ void Simulator::present()
         cameras[active_camera]->setWindowSize(window().size());
     }
     
-    gfx_draw(myShaders, light, cameras, cam_frames, active_camera, scene, grid, grid_frame);
+    gfx_draw(myShaders, lights[0], cameras, cam_frames, active_camera, scene, grid, grid_frame);
 }
 
 void Simulator::showUI()
@@ -188,6 +192,34 @@ void Simulator::showUI()
 	ImGui::End();
 }
 
+void Simulator::find_lights(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);
+        } 
+        find_lights(node->getChildren());
+    }
+}
+
+void Simulator::find_cameras(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);
+        } 
+        find_lights(node->getChildren());
+    }
+}
+
 void Simulator::create_scene()
 {
     for (std::size_t i = 0; i < objects.size(); ++i)
@@ -197,8 +229,8 @@ void Simulator::create_scene()
     }
     // scene.emplace_back(std::make_shared<Node>(grid_frame));
     // scene.back()->addObject(grid);
-    // scene.emplace_back(std::make_shared<Node>(light->getPosition()));
-    // scene.back()->addObject(std::make_shared<Light>(light));
+    scene.emplace_back(std::make_shared<Node>(obj_frames[1]));
+    scene.back()->addObject(std::make_shared<Light>(glm::vec3(1.0f, 1.0f, 1.0f), scene.back()->getFrame()));
 }
 
 /* Object movement now works only for one object */
-- 
GitLab