From 8e690cc3d1a63dda860c3b2a05533ec416134228 Mon Sep 17 00:00:00 2001 From: Jay Robson Date: Tue, 30 Jan 2024 19:39:19 +1100 Subject: [PATCH] made interfaces actually semi functional! :) --- src/graphics/camera.cpp | 11 +++ src/graphics/camera.hpp | 4 +- src/graphics/input/focus.cpp | 82 +++++++++++++++++++++ src/graphics/input/focus.hpp | 30 ++++++++ src/graphics/input/keyboard.cpp | 14 ++++ src/graphics/input/mouse.cpp | 14 ++++ src/graphics/mesh/arrays.cpp | 10 +++ src/graphics/mesh/arrays.hpp | 5 +- src/graphics/mesh/mesh.cpp | 20 +++-- src/graphics/mesh/mesh.hpp | 1 + src/graphics/monitor/core.cpp | 126 ++++++++++++++++++++++++++++---- src/graphics/monitor/core.hpp | 2 + src/graphics/window.cpp | 22 ++++-- src/main.cpp | 2 + src/reactor/builder.cpp | 6 +- src/reactor/fuel/fuel_rod.cpp | 2 +- src/reactor/fuel/sample.hpp | 2 +- src/reactor/reactor.cpp | 13 +++- src/reactor/reactor.hpp | 2 +- 19 files changed, 324 insertions(+), 44 deletions(-) create mode 100644 src/graphics/input/focus.cpp create mode 100644 src/graphics/input/focus.hpp diff --git a/src/graphics/camera.cpp b/src/graphics/camera.cpp index 93f8aec..f8e2d21 100644 --- a/src/graphics/camera.cpp +++ b/src/graphics/camera.cpp @@ -36,6 +36,17 @@ void camera::move(double xoff, double yoff, double zoff) pos.z += zoff; } +glm::vec<3, double> camera::get_normal() +{ + glm::mat<3, 3, double> mat(camera_mat); + return glm::vec<3, double>(0, 0, -1) * mat; +} + +glm::vec<3, double> camera::get_pos() +{ + return pos; +} + void camera::update(const system& sys, double dt) { glm::vec<2, double> off(0, 0); diff --git a/src/graphics/camera.hpp b/src/graphics/camera.hpp index 7d08761..50b809a 100644 --- a/src/graphics/camera.hpp +++ b/src/graphics/camera.hpp @@ -2,7 +2,6 @@ #pragma once #include -#include #include "../system.hpp" @@ -10,6 +9,9 @@ namespace sim::graphics::camera { glm::mat4 get_matrix(); +glm::vec<3, double> get_normal(); +glm::vec<3, double> get_pos(); + void rotate(double pitch, double yaw); void move(double x, double y, double z); void update(const system& sys, double dt); diff --git a/src/graphics/input/focus.cpp b/src/graphics/input/focus.cpp new file mode 100644 index 0000000..cd0293c --- /dev/null +++ b/src/graphics/input/focus.cpp @@ -0,0 +1,82 @@ + +#include "focus.hpp" +#include "../camera.hpp" +#include "../../util/math.hpp" + +#include + +#include +#include + +using namespace sim::graphics; + +static std::unique_ptr state = nullptr; +static bool triggered = false; + +void focus::on_keypress(int key, int sc, int action, int mods) +{ + if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + { + state = nullptr; + } + + if(state) + { + state->on_keypress(key, sc, action, mods); + } +} + +void focus::on_mouse_button(int button, int action, int mods) +{ + if(state) + { + state->on_mouse_button(button, action, mods); + } + + else if(button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE) + { + triggered = true; + } +} + +void focus::on_cursor_pos(double x, double y) +{ + if(state) + { + state->on_cursor_pos(x, y); + } +} + +void focus::on_charcode(unsigned int c) +{ + if(state) + { + state->on_charcode(c); + } +} + +bool focus::is_focused() +{ + return (state != nullptr); +} + +void focus::clear() +{ + state = nullptr; +} + +void focus::set(std::unique_ptr f) +{ + state = std::move(f); +} + +bool focus::is_triggered() +{ + return triggered; +} + +void focus::clear_trigger() +{ + triggered = false; +} + diff --git a/src/graphics/input/focus.hpp b/src/graphics/input/focus.hpp new file mode 100644 index 0000000..1bd4af7 --- /dev/null +++ b/src/graphics/input/focus.hpp @@ -0,0 +1,30 @@ + +#pragma once + +#include + +namespace sim::graphics::focus +{ + +struct focus_t +{ + virtual ~focus_t() { } + virtual void on_keypress(int key, int sc, int action, int mods) { } + virtual void on_mouse_button(int button, int action, int mods) { } + virtual void on_cursor_pos(double x, double y) { } + virtual void on_charcode(unsigned int c) { } +}; + +bool is_triggered(); +void clear_trigger(); + +void clear(); +bool is_focused(); +void set(std::unique_ptr f); +void on_keypress(int key, int sc, int action, int mods); +void on_mouse_button(int button, int action, int mods); +void on_cursor_pos(double x, double y); +void on_charcode(unsigned int c); + +}; + diff --git a/src/graphics/input/keyboard.cpp b/src/graphics/input/keyboard.cpp index 09252cb..285a2a6 100644 --- a/src/graphics/input/keyboard.cpp +++ b/src/graphics/input/keyboard.cpp @@ -4,6 +4,7 @@ #include +#include "focus.hpp" #include "keyboard.hpp" #include "../window.hpp" #include "../resize.hpp" @@ -29,10 +30,22 @@ static void cb_keypress(GLFWwindow* win, int key, int sc, int action, int mods) { pressed[key] = false; } + + focus::on_keypress(key, sc, action, mods); +} + +static void cb_charcode(GLFWwindow* win, unsigned int code) +{ + focus::on_charcode(code); } bool keyboard::is_pressed(int key) { + if(focus::is_focused()) + { + return false; + } + auto it = pressed.find(key); if(it == pressed.end()) @@ -50,5 +63,6 @@ void keyboard::init() { GLFWwindow* win = window::get_window(); glfwSetKeyCallback(win, cb_keypress); + glfwSetCharCallback(win, cb_charcode); } diff --git a/src/graphics/input/mouse.cpp b/src/graphics/input/mouse.cpp index 96a4a6a..a850103 100644 --- a/src/graphics/input/mouse.cpp +++ b/src/graphics/input/mouse.cpp @@ -2,6 +2,7 @@ #include #include +#include "focus.hpp" #include "mouse.hpp" #include "../window.hpp" #include "../camera.hpp" @@ -12,12 +13,24 @@ static double xpos = 0, ypos = 0; static void cb_cursor_pos(GLFWwindow* win, double x, double y) { + focus::on_cursor_pos(x, y); + + if(focus::is_focused()) + { + return; + } + camera::rotate(x - xpos, y - ypos); xpos = x; ypos = y; } +void cb_mouse_button(GLFWwindow* window, int button, int action, int mods) +{ + focus::on_mouse_button(button, action, mods); +} + void mouse::get(double& x, double& y) { x = xpos; @@ -28,6 +41,7 @@ void mouse::init() { GLFWwindow* win = window::get_window(); glfwSetCursorPosCallback(win, cb_cursor_pos); + glfwSetMouseButtonCallback(win, cb_mouse_button); glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetCursorPos(win, 0, 0); } diff --git a/src/graphics/mesh/arrays.cpp b/src/graphics/mesh/arrays.cpp index 63023f3..4d6978f 100644 --- a/src/graphics/mesh/arrays.cpp +++ b/src/graphics/mesh/arrays.cpp @@ -34,3 +34,13 @@ void arrays::vertex_attrib_pointers() glEnableVertexAttribArray(3); } +glm::mat4 arrays::colour(glm::vec4 c) +{ + return glm::mat4({ + c.r, c.g, c.b, c.a, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 + }); +} + diff --git a/src/graphics/mesh/arrays.hpp b/src/graphics/mesh/arrays.hpp index 2e42132..1b6f41c 100644 --- a/src/graphics/mesh/arrays.hpp +++ b/src/graphics/mesh/arrays.hpp @@ -1,9 +1,7 @@ #pragma once -#include -#include -#include +#include namespace sim::graphics::arrays { @@ -17,6 +15,7 @@ struct vertex }; void vertex_attrib_pointers(); +glm::mat4 colour(glm::vec4 code); }; diff --git a/src/graphics/mesh/mesh.cpp b/src/graphics/mesh/mesh.cpp index 7f60a12..725046f 100644 --- a/src/graphics/mesh/mesh.cpp +++ b/src/graphics/mesh/mesh.cpp @@ -3,6 +3,7 @@ #include "arrays.hpp" #include "../shader.hpp" #include "../camera.hpp" +#include "../input/focus.hpp" #include "../../util/math.hpp" #include @@ -95,6 +96,11 @@ bool ray_intersects_triangle(vec3 ray_origin, return false; } +bool mesh::check_focus(double len) const +{ + return focus::is_triggered() && check_intersect(camera::get_pos(), camera::get_normal() * len); +} + bool mesh::check_intersect(vec3 pos, vec3 path) const { double l = glm::length(path); @@ -106,7 +112,7 @@ bool mesh::check_intersect(vec3 pos, vec3 path) const vec3 path_n = path / l; - for(unsigned int i = 0; i < indices.size(); i++) + for(unsigned int i = 0; i < indices.size(); i += 3) { vec3 v[3] = { vec3(this->vertices[indices[i]].pos), @@ -116,7 +122,7 @@ bool mesh::check_intersect(vec3 pos, vec3 path) const vec3 ipoint; vec3 normal = glm::normalize(glm::cross(v[1] - v[0], v[2] - v[0])); - double d = glm::dot(normal, path_n); + double d = glm::dot(normal, path); if(d >= 0) continue; @@ -124,7 +130,7 @@ bool mesh::check_intersect(vec3 pos, vec3 path) const continue; if(l < glm::length(ipoint - pos)) continue; - + return true; } @@ -194,8 +200,8 @@ vec3 mesh::calc_intersect(vec3 pos, vec3 path, vec3& normal_last) const i_found = i; } } -/* - for(unsigned int i = i_found - 1; i >= 0; i--) + + for(unsigned int i = 0; i < i_found; i += 3) { vec3 v[3] = { vec3(this->vertices[indices[i]].pos), @@ -205,7 +211,7 @@ vec3 mesh::calc_intersect(vec3 pos, vec3 path, vec3& normal_last) const calc_intercept_vert(v, pos, path, path_n, normal_last, l); } -*/ + return path; } @@ -224,8 +230,6 @@ mesh mesh::to_lines() const m.indices.push_back(indices[i + 2]); } - std::cout << "indices.size() = " << m.indices.size() << ", vertices.size() = " << m.vertices.size() << "\n"; - return m; } diff --git a/src/graphics/mesh/mesh.hpp b/src/graphics/mesh/mesh.hpp index 7c54f5b..9aea398 100644 --- a/src/graphics/mesh/mesh.hpp +++ b/src/graphics/mesh/mesh.hpp @@ -28,6 +28,7 @@ struct mesh void add(const mesh& o, glm::mat4 mat); mesh to_lines() const; + bool check_focus(double len) const; bool check_intersect(glm::vec<3, double> pos, glm::vec<3, double> path) const; glm::vec<3, double> calc_intersect(glm::vec<3, double> pos, glm::vec<3, double> path) const; glm::vec<3, double> calc_intersect(glm::vec<3, double> pos, glm::vec<3, double> path, glm::vec<3, double>& normal_last) const; diff --git a/src/graphics/monitor/core.cpp b/src/graphics/monitor/core.cpp index 522760f..04c9105 100644 --- a/src/graphics/monitor/core.cpp +++ b/src/graphics/monitor/core.cpp @@ -4,12 +4,89 @@ #include "core.hpp" #include "../locations.hpp" +#include "../input/focus.hpp" +#include "../mesh/arrays.hpp" #include + +#include #include +using namespace sim::graphics; using namespace sim::graphics::monitor; +struct core_focus_t : public focus::focus_t +{ + sim::system* sys; + + core_focus_t(sim::system& sys) + { + this->sys = &sys; + } + + void on_keypress(int key, int sc, int action, int mods) + { + if(action != GLFW_PRESS) + { + return; + } + + } + + void on_mouse_button(int button, int action, int mods) + { + + } + + void on_cursor_pos(double x, double y) + { + + } + + void set_all(bool state) + { + for(int i = 0; i < sys->reactor->rods.size(); i++) + { + sim::reactor::rod* r = sys->reactor->rods[i].get(); + + if(r->should_select() && (r->is_selected() != state)) + { + r->toggle_selected(); + } + } + } + + void toggle_auto() + { + //TODO + } + + void on_charcode(unsigned int c) + { + switch(c) + { + case 'a': case 'A': + sys->reactor->move_cursor(-1); + break; + case 'd': case 'D': + sys->reactor->move_cursor(1); + break; + case 's': case 'S': + sys->reactor->toggle_selected(); + break; + case 'w': case 'W': + toggle_auto(); + break; + case 'q': case 'Q': + set_all(false); + break; + case 'e': case 'E': + set_all(true); + break; + } + } +}; + core::core() { @@ -18,12 +95,7 @@ core::core() void core::init() { mesh1.model_matrix = locations::monitors[2]; - mesh1.colour_matrix = { - 1, 1, 1, 1, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0 - }; + mesh1.colour_matrix = arrays::colour({1, 1, 1, 1}); sim::graphics::mesh rmesh1, rmesh2; @@ -36,6 +108,16 @@ void core::init() rmesh2.load_model("../assets/model/", "reactor_core_interface_cell.stl"); mesh2.bind(); mesh2.set(rmesh2, GL_STATIC_DRAW); + + mesh_click.load_model("../assets/model/", "reactor_core_input.stl"); +} + +void core::update(sim::system& sys) +{ + if(mesh_click.check_focus(2)) + { + focus::set(std::make_unique(sys)); + } } void core::render(sim::system& sys) @@ -44,7 +126,9 @@ void core::render(sim::system& sys) double sx = 0.5 - (sys.reactor->width - 1) * step / 2.0; double sy = 0.5 - (sys.reactor->height - 1) * step / 2.0; - glm::mat4 mat_scale = glm::scale(glm::mat4(1), glm::vec3(step * 0.5, step * 0.5, 1)); + glm::mat4 mat_scale = glm::scale(glm::mat4(1), glm::vec3(step * 0.4, step * 0.4, 1)); + glm::mat4 mat_select = glm::translate(glm::mat4(1), glm::vec3(-0.8, -0.8, -0.001)) * glm::scale(glm::mat4(1), glm::vec3(0.5, 0.5, 1)); + glm::mat4 mat_cursor = glm::translate(glm::mat4(1), glm::vec3(-0.8, 0.8, -0.001)) * glm::scale(glm::mat4(1), glm::vec3(0.5, 0.5, 1)); mesh1.bind(); mesh1.uniform(); @@ -61,21 +145,33 @@ void core::render(sim::system& sys) reactor::rod* r = sys.reactor->rods[i].get(); glm::vec4 colour = r->get_colour(); - if(!r->should_display() || colour[3] == 0) + if(colour[3] == 0) { continue; } - mesh2.model_matrix = mesh1.model_matrix * glm::translate(glm::mat4(1), glm::vec3(ox, oy, 0)) * mat_scale; - mesh2.colour_matrix = glm::mat4({ - colour[0], colour[1], colour[2], colour[3], - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0 - }); + glm::mat4 mat = mesh1.model_matrix * glm::translate(glm::mat4(1), glm::vec3(ox, oy, 0)) * mat_scale; + mesh2.model_matrix = mat; + mesh2.colour_matrix = arrays::colour(colour); mesh2.uniform(); mesh2.render(); + + if(sys.reactor->cursor == i && r->should_select()) + { + mesh2.model_matrix = mat * mat_cursor; + mesh2.colour_matrix = arrays::colour({1, 0, 0, 1}); + mesh2.uniform(); + mesh2.render(); + } + + if(r->is_selected()) + { + mesh2.model_matrix = mat * mat_select; + mesh2.colour_matrix = arrays::colour({1, 1, 0, 1}); + mesh2.uniform(); + mesh2.render(); + } } } diff --git a/src/graphics/monitor/core.hpp b/src/graphics/monitor/core.hpp index 09908f2..44ca65f 100644 --- a/src/graphics/monitor/core.hpp +++ b/src/graphics/monitor/core.hpp @@ -9,12 +9,14 @@ namespace sim::graphics::monitor class core { + sim::graphics::mesh mesh_click; sim::graphics::glmesh mesh1, mesh2; public: core(); void init(); + void update(sim::system& sys); void render(sim::system& sys); }; diff --git a/src/graphics/window.cpp b/src/graphics/window.cpp index 15f0cfc..325815e 100644 --- a/src/graphics/window.cpp +++ b/src/graphics/window.cpp @@ -28,7 +28,7 @@ using namespace sim::graphics; static GLFWwindow* win; static bool win_should_close = false; -static glmesh MeshScene, MeshCollisionScene; +static glmesh MeshScene, MeshDebug; static monitor::vessel MonitorVessel; static monitor::core MonitorCore; @@ -101,9 +101,13 @@ void window::create(system& sys) MeshScene.bind(); MeshScene.set(sys.scene, GL_STATIC_DRAW); +// sys.scene.load_model("../assets/model", "reactor_core_input.stl"); +// MeshDebug.bind(); +// MeshDebug.set(sys.scene, GL_STATIC_DRAW); + sys.scene.load_model("../assets/model", "scene_collisions.stl"); - MeshCollisionScene.bind(); - MeshCollisionScene.set(sys.scene.to_lines(), GL_STATIC_DRAW); +// MeshCollisionScene.bind(); +// MeshCollisionScene.set(sys.scene.to_lines(), GL_STATIC_DRAW); MonitorCore.init(); MonitorVessel.init(); @@ -114,6 +118,9 @@ void window::create(system& sys) void window::loop(sim::system& sys) { + glfwPollEvents(); + + MonitorCore.update(sys); MonitorVessel.update(sys); glm::mat4 mat_projection = glm::perspective(glm::radians(80.0f), resize::get_aspect(), 0.01f, 20.f); @@ -121,20 +128,19 @@ void window::loop(sim::system& sys) glClearColor(0, 0, 0, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + +// MeshDebug.bind(); +// MeshDebug.uniform(); +// MeshDebug.render(); MeshScene.bind(); MeshScene.uniform(); MeshScene.render(); - MeshCollisionScene.bind(); - MeshCollisionScene.uniform(); - MeshCollisionScene.render(GL_LINES); - MonitorCore.render(sys); MonitorVessel.render(); glfwSwapBuffers(win); - glfwPollEvents(); } bool window::should_close() diff --git a/src/main.cpp b/src/main.cpp index d7f2a2d..bec1ecd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,6 +11,7 @@ #include "coolant/pump.hpp" #include "graphics/mesh/mesh.hpp" +#include "graphics/input/focus.hpp" #include "graphics/window.hpp" #include "graphics/camera.hpp" @@ -43,6 +44,7 @@ int main() sys.update(dt); graphics::camera::update(sys, dt); graphics::window::loop(sys); + graphics::focus::clear_trigger(); } graphics::window::destroy(); diff --git a/src/reactor/builder.cpp b/src/reactor/builder.cpp index 87ad129..2c14fee 100644 --- a/src/reactor/builder.cpp +++ b/src/reactor/builder.cpp @@ -20,10 +20,10 @@ sim::reactor::reactor sim::reactor::builder(const int W, const int H, const doub switch(c) { case 'F': - r = fr.clone(); + r = std::make_unique(fr); break; case 'C': - r = br.clone(); + r = std::make_unique(br); break; case 'G': r = std::make_unique(); @@ -34,7 +34,7 @@ sim::reactor::reactor sim::reactor::builder(const int W, const int H, const doub case 'P': r = std::make_unique(v); break; - case ' ': + default: r = std::make_unique(); break; } diff --git a/src/reactor/fuel/fuel_rod.cpp b/src/reactor/fuel/fuel_rod.cpp index 6951be9..954a8dd 100644 --- a/src/reactor/fuel/fuel_rod.cpp +++ b/src/reactor/fuel/fuel_rod.cpp @@ -21,7 +21,7 @@ void fuel_rod::display(std::ostream& o) const o << "Fuel: " << (s.get_fuel() * mol) << " / " << (s.get_mass() * mol) << " mol\n"; o << "Efficiency: " << (s.get_efficiency() * 100) << " %\n"; - o << "Output: " << (s.get_energy() * mol * energy_density) << " W/s\n"; + o << "Output: " << (s.get_energy() * mol * energy_density) << " W\n"; o << "Iodine: " << (s.get_i_135() * mol) << " mol\n"; o << "Xenon: " << (s.get_xe_135() * mol) << " mol\n"; } diff --git a/src/reactor/fuel/sample.hpp b/src/reactor/fuel/sample.hpp index 4579c0c..bad2c8c 100644 --- a/src/reactor/fuel/sample.hpp +++ b/src/reactor/fuel/sample.hpp @@ -21,7 +21,7 @@ class sample double te_135 = 0; double mass = 0; - double energy = 0; // W/s + double energy = 0; // W double fast_neutrons = 0; // mol/s double slow_neutrons = 0; // mol/s double efficiency = 0; diff --git a/src/reactor/reactor.cpp b/src/reactor/reactor.cpp index 71c0a39..00def97 100644 --- a/src/reactor/reactor.cpp +++ b/src/reactor/reactor.cpp @@ -8,7 +8,7 @@ using namespace sim::reactor; reactor::reactor(std::unique_ptr* rods, int w, int h, double cw, double ch) : cell_width(cw), cell_height(ch), width(w), height(h), size(w * h) { - this->rods = std::make_unique[]>(width * height); + this->rods = std::vector>(w * h); for(int i = 0; i < size; i++) { @@ -21,15 +21,22 @@ reactor::reactor(reactor&& o) : cell_width(o.cell_width), cell_height(o.cell_hei { rods = std::move(o.rods); cursor = o.cursor; + + for(int i = 0; i < size; i++) + { + rods[i]->reactor = this; + } } reactor::reactor(const reactor& o) : cell_width(o.cell_width), cell_height(o.cell_height), width(o.width), height(o.height), size(o.size) { - this->rods = std::make_unique[]>(width * height); + rods = std::vector>(width * height); + cursor = o.cursor; for(int i = 0; i < size; i++) { - this->rods[i] = std::unique_ptr(o.rods[i]->clone()); + rods[i] = std::unique_ptr(o.rods[i]->clone()); + rods[i]->reactor = this; } } diff --git a/src/reactor/reactor.hpp b/src/reactor/reactor.hpp index 7fed016..7ebc894 100644 --- a/src/reactor/reactor.hpp +++ b/src/reactor/reactor.hpp @@ -18,7 +18,7 @@ struct reactor const int height; const int size; - std::unique_ptr[]> rods; + std::vector> rods; int cursor = 0; reactor(std::unique_ptr* rods, int width, int height, double cell_width, double cell_height);