made interfaces actually semi functional! :)

This commit is contained in:
Jay Robson 2024-01-30 19:39:19 +11:00
parent a7ced6a773
commit 3812b727df
19 changed files with 324 additions and 44 deletions

View File

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

View File

@ -2,7 +2,6 @@
#pragma once
#include <glm/matrix.hpp>
#include <glm/vec3.hpp>
#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);

View File

@ -0,0 +1,82 @@
#include "focus.hpp"
#include "../camera.hpp"
#include "../../util/math.hpp"
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
using namespace sim::graphics;
static std::unique_ptr<focus::focus_t> 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<focus_t> f)
{
state = std::move(f);
}
bool focus::is_triggered()
{
return triggered;
}
void focus::clear_trigger()
{
triggered = false;
}

View File

@ -0,0 +1,30 @@
#pragma once
#include <memory>
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<focus_t> 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);
};

View File

@ -4,6 +4,7 @@
#include <unordered_map>
#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);
}

View File

@ -2,6 +2,7 @@
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#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);
}

View File

@ -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
});
}

View File

@ -1,9 +1,7 @@
#pragma once
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <glm/matrix.hpp>
namespace sim::graphics::arrays
{
@ -17,6 +15,7 @@ struct vertex
};
void vertex_attrib_pointers();
glm::mat4 colour(glm::vec4 code);
};

View File

@ -3,6 +3,7 @@
#include "arrays.hpp"
#include "../shader.hpp"
#include "../camera.hpp"
#include "../input/focus.hpp"
#include "../../util/math.hpp"
#include <iostream>
@ -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;
}

View File

@ -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;

View File

@ -4,12 +4,89 @@
#include "core.hpp"
#include "../locations.hpp"
#include "../input/focus.hpp"
#include "../mesh/arrays.hpp"
#include <glm/ext/matrix_transform.hpp>
#include <iostream>
#include <sstream>
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<core_focus_t>(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();
}
}
}

View File

@ -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);
};

View File

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

View File

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

View File

@ -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<fuel::fuel_rod>(fr);
break;
case 'C':
r = br.clone();
r = std::make_unique<control::boron_rod>(br);
break;
case 'G':
r = std::make_unique<control::graphite_rod>();
@ -34,7 +34,7 @@ sim::reactor::reactor sim::reactor::builder(const int W, const int H, const doub
case 'P':
r = std::make_unique<coolant::pipe>(v);
break;
case ' ':
default:
r = std::make_unique<rod>();
break;
}

View File

@ -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";
}

View File

@ -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;

View File

@ -8,7 +8,7 @@ using namespace sim::reactor;
reactor::reactor(std::unique_ptr<rod>* 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<std::unique_ptr<rod>[]>(width * height);
this->rods = std::vector<std::unique_ptr<rod>>(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<std::unique_ptr<rod>[]>(width * height);
rods = std::vector<std::unique_ptr<rod>>(width * height);
cursor = o.cursor;
for(int i = 0; i < size; i++)
{
this->rods[i] = std::unique_ptr<rod>(o.rods[i]->clone());
rods[i] = std::unique_ptr<rod>(o.rods[i]->clone());
rods[i]->reactor = this;
}
}

View File

@ -18,7 +18,7 @@ struct reactor
const int height;
const int size;
std::unique_ptr<std::unique_ptr<rod>[]> rods;
std::vector<std::unique_ptr<rod>> rods;
int cursor = 0;
reactor(std::unique_ptr<rod>* rods, int width, int height, double cell_width, double cell_height);