diff --git a/CMakeLists.txt b/CMakeLists.txt index 7078029..9d76563 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,20 +3,25 @@ cmake_minimum_required(VERSION 3.25) project(FastNuclearSim VERSION 1.0) set(CMAKE_CXX_STANDARD 26) +set(CMAKE_CXX_FLAGS "-g") -if(WIN32) - set(CMAKE_CXX_FLAGS "-g -O3") -else() - set(CMAKE_CXX_FLAGS "-g -O3 -I/usr/include/freetype2") +if(NOT DEBUG_SET) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") +endif() +if(NOT WIN32) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/usr/include/freetype2") endif() +message("Using cmake flags: ${CMAKE_CXX_FLAGS}") file(GLOB_RECURSE SOURCES src/*.cpp) - add_executable(FastNuclearSim ${SOURCES}) if(WIN32) - target_link_libraries(FastNuclearSim PUBLIC stdc++ m brotlidec assimp-5 glew32 opengl32 glfw3 freetype jsoncpp zlibstatic) + set(libs stdc++ m brotlidec assimp-5 glew32 opengl32 glfw3 freetype jsoncpp zlibstatic) else() - target_link_libraries(FastNuclearSim PUBLIC stdc++ m GLEW glfw GL freetype assimp jsoncpp) + set(libs stdc++ m GLEW glfw GL freetype assimp jsoncpp) endif() +message("Using libs ${libs}") +target_link_libraries(FastNuclearSim PUBLIC ${libs}) + diff --git a/assets/model/monitor_graphics.stl b/assets/model/monitor_graphics.stl new file mode 100644 index 0000000..72323ff --- /dev/null +++ b/assets/model/monitor_graphics.stl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a70c8eac39dc5209e3210431c16bc01122080a6e8dd5a6d40951f7e1e55d8484 +size 32884 diff --git a/assets/model/monitor_turbine.stl b/assets/model/monitor_turbine.stl new file mode 100644 index 0000000..6862c6b --- /dev/null +++ b/assets/model/monitor_turbine.stl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d0d99daed1da2d6c93ce8ff07c4a8c1c5ea10e066807fa73807c01f57a40d4f +size 6484 diff --git a/assets/model/primary_coolant_pump_switch.glb b/assets/model/primary_coolant_pump_switch.glb deleted file mode 100644 index 7ce8622..0000000 --- a/assets/model/primary_coolant_pump_switch.glb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4344c73249a535c6472aaa177e75ecd94daef875444e9216fa3d03d50a9c8b2b -size 2300 diff --git a/assets/model/primary_coolant_pump_switch.stl b/assets/model/primary_coolant_pump_switch.stl deleted file mode 100644 index f8bead3..0000000 --- a/assets/model/primary_coolant_pump_switch.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:578b9844f451434d7439918972840abe9734e0e681a6714b4880994f221feda2 -size 1384 diff --git a/assets/model/pump_switch_1.fbx b/assets/model/pump_switch_1.fbx new file mode 100644 index 0000000..e4437bd Binary files /dev/null and b/assets/model/pump_switch_1.fbx differ diff --git a/assets/model/pump_switch_1.glb b/assets/model/pump_switch_1.glb deleted file mode 100644 index 7349c91..0000000 --- a/assets/model/pump_switch_1.glb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3173c61c356d50c3dab1428ba5248a89ac3c6ec7625777ab1dc73685efba58ab -size 2288 diff --git a/assets/model/pump_switch_2.fbx b/assets/model/pump_switch_2.fbx new file mode 100644 index 0000000..78d74df Binary files /dev/null and b/assets/model/pump_switch_2.fbx differ diff --git a/assets/model/pump_switch_2.glb b/assets/model/pump_switch_2.glb deleted file mode 100644 index fadd4b1..0000000 --- a/assets/model/pump_switch_2.glb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fbc192f0fada6db983af27c7e0cd1376683dee5636ce2bef1042699fedd27f6e -size 2288 diff --git a/assets/model/pump_switch_3.fbx b/assets/model/pump_switch_3.fbx new file mode 100644 index 0000000..97db982 Binary files /dev/null and b/assets/model/pump_switch_3.fbx differ diff --git a/assets/model/pump_switch_3.glb b/assets/model/pump_switch_3.glb deleted file mode 100644 index 2a76b7a..0000000 --- a/assets/model/pump_switch_3.glb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5d5dfa5402e80bc83145cf61a2cc734234da560940909db5237a5921d26ad45e -size 2284 diff --git a/assets/model/pump_switch_click_1.stl b/assets/model/pump_switch_click_1.stl index b1c62b9..fa0a029 100644 --- a/assets/model/pump_switch_click_1.stl +++ b/assets/model/pump_switch_click_1.stl @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:55f81f7613267436a5f975ca68ca786223a7e11328445a73809d883bb7fd8192 +oid sha256:509fefc8613bb51abbc48805412fbdae81203ffde615e90dc5308473f0fe4bf6 size 584 diff --git a/assets/model/pump_switch_click_3.stl b/assets/model/pump_switch_click_3.stl index 1d38c12..b13f6b2 100644 --- a/assets/model/pump_switch_click_3.stl +++ b/assets/model/pump_switch_click_3.stl @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bb67a784f702dc1ec1bd60749aaa1f11ba8fca989ba6f82170b1ce4f28255f1b +oid sha256:925b82ff8b2f7a0a0fee88ac56b49e54614d1138e6f7dfef2356a26314207151 size 584 diff --git a/assets/model/reactor_core_joystick.stl b/assets/model/reactor_core_joystick.stl index 475670b..074cdce 100644 --- a/assets/model/reactor_core_joystick.stl +++ b/assets/model/reactor_core_joystick.stl @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:80061016f494879ad7e05e7d3f95743935589c7d8d68438c56c1930ac3f6b67d +oid sha256:ce0130dd410d23dc89f12ffc8006cad1764b48e64429e3788266c70c06df36d7 size 2384 diff --git a/assets/model/secondary_coolant_pump_switch.glb b/assets/model/secondary_coolant_pump_switch.glb deleted file mode 100644 index 217e781..0000000 --- a/assets/model/secondary_coolant_pump_switch.glb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3b78531b28fd2aa3a4187910a9d3e12589ce90bf618f1c6a06ba9dd87289eea4 -size 2304 diff --git a/assets/model/secondary_coolant_pump_switch.stl b/assets/model/secondary_coolant_pump_switch.stl deleted file mode 100644 index bbee054..0000000 --- a/assets/model/secondary_coolant_pump_switch.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:08cb689a2e9589f2cf900dda401a4050c4a7ca0df9dec993fb0b95194cf44152 -size 1384 diff --git a/assets/model/switch.png b/assets/model/switch.png new file mode 100644 index 0000000..474c73f --- /dev/null +++ b/assets/model/switch.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df6c4c042faa33b4a41641c2b8048d2d1484326c495156096eff32cfbaeb3cc1 +size 178 diff --git a/assets/model/synchroscope_dial.stl b/assets/model/synchroscope_dial.stl new file mode 100644 index 0000000..697165c --- /dev/null +++ b/assets/model/synchroscope_dial.stl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6dbd76a72b87b5bf50c0587d7a99b45f357578d0db780dc264b10a4039cbbb8 +size 684 diff --git a/assets/model/turbine_breaker_switch.fbx b/assets/model/turbine_breaker_switch.fbx new file mode 100644 index 0000000..d879dd0 Binary files /dev/null and b/assets/model/turbine_breaker_switch.fbx differ diff --git a/assets/model/turbine_breaker_switch_click.stl b/assets/model/turbine_breaker_switch_click.stl new file mode 100644 index 0000000..12f1d20 --- /dev/null +++ b/assets/model/turbine_breaker_switch_click.stl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8065cdceb0397455032012ea4d022809da525c4995c2d1666042129fcdaa6e92 +size 584 diff --git a/assets/model/turbine_valve_bypass_joystick.stl b/assets/model/turbine_valve_bypass_joystick.stl index b4ba457..c3a5135 100644 --- a/assets/model/turbine_valve_bypass_joystick.stl +++ b/assets/model/turbine_valve_bypass_joystick.stl @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:32a36024215b2eabc09a6c23aa133a3b5653d9666a634d56f7304c97e8379d76 +oid sha256:c0ad408b2ba4c0748e1851413fc7764cb5b8ea6283ff0a633cbe224ec4f399fd size 2384 diff --git a/assets/model/turbine_valve_bypass_switch.fbx b/assets/model/turbine_valve_bypass_switch.fbx new file mode 100644 index 0000000..fe29286 Binary files /dev/null and b/assets/model/turbine_valve_bypass_switch.fbx differ diff --git a/assets/model/turbine_valve_bypass_switch_click.stl b/assets/model/turbine_valve_bypass_switch_click.stl new file mode 100644 index 0000000..5ecbcfd --- /dev/null +++ b/assets/model/turbine_valve_bypass_switch_click.stl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87ac1b611dd584e4fbffe2a05ed398825016a145c6e8db71a8f38ff2c828bf36 +size 584 diff --git a/assets/model/turbine_valve_inlet_joystick.stl b/assets/model/turbine_valve_inlet_joystick.stl index 34e7452..3ae1e5b 100644 --- a/assets/model/turbine_valve_inlet_joystick.stl +++ b/assets/model/turbine_valve_inlet_joystick.stl @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:42d79043838dc5425fedc62b1f80b53d75c4039bd8ce20788c517b824f0ca6ab +oid sha256:194100b1b3cc1993a91d60fd7fb38f365bd89f917632c983b67cdc12b9b042bb size 2384 diff --git a/assets/model/turbine_valve_inlet_switch.fbx b/assets/model/turbine_valve_inlet_switch.fbx new file mode 100644 index 0000000..f9a898f Binary files /dev/null and b/assets/model/turbine_valve_inlet_switch.fbx differ diff --git a/assets/model/turbine_valve_inlet_switch_click.stl b/assets/model/turbine_valve_inlet_switch_click.stl new file mode 100644 index 0000000..3ec953e --- /dev/null +++ b/assets/model/turbine_valve_inlet_switch_click.stl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42cd63cdd604d39d928a9ef676c06d52fc91b7020cb24df481417698b8c6fcb1 +size 584 diff --git a/assets/scene-baked.glb b/assets/scene-baked.glb index e512f24..a532c3d 100644 --- a/assets/scene-baked.glb +++ b/assets/scene-baked.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:748d437c09a212c8f66cb47a61dcc17ccbbb67b4697f52d7af93177f71769fd0 -size 52246948 +oid sha256:48f678610eab0b98ecc0fffeaea709cd89e27fabf37ed6f238e2ae2f84310c5a +size 53796580 diff --git a/assets/unbaked/scene.blend b/assets/unbaked/scene.blend index c7287a5..f7bab57 100644 --- a/assets/unbaked/scene.blend +++ b/assets/unbaked/scene.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e7d76bd1e935ab78f9156c217a4bf6727deac37e39cbae1a5592c877422404f0 -size 10470332 +oid sha256:7fe8cb06eeaf56c4fa736eb074b366baaac8086e109bc1eccbc6938b686cdb5f +size 12366148 diff --git a/assets/unbaked/scene/labels.png b/assets/unbaked/scene/labels.png index 183f442..d11d4d7 100644 --- a/assets/unbaked/scene/labels.png +++ b/assets/unbaked/scene/labels.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c544574d9fa0b14faa254f856bdb691a914fc7dae1875def98bcc52ed6f14563 -size 61947 +oid sha256:3c9693bce1628544ff43f27ce16cd629b129ad4e34d3676fe37068abcbf7c50a +size 72605 diff --git a/assets/unbaked/scene/labels.xcf b/assets/unbaked/scene/labels.xcf index 5e64e5d..90ccda6 100644 Binary files a/assets/unbaked/scene/labels.xcf and b/assets/unbaked/scene/labels.xcf differ diff --git a/assets/unbaked/scene/labels_1.png b/assets/unbaked/scene/labels_1.png new file mode 100644 index 0000000..3ccdb6a --- /dev/null +++ b/assets/unbaked/scene/labels_1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b123897907a1d257e0437981f985827af7597ea2cfa823d0c739c993d0b98d2 +size 69005 diff --git a/assets/unbaked/scene/labels_2.png b/assets/unbaked/scene/labels_2.png new file mode 100644 index 0000000..d72a618 --- /dev/null +++ b/assets/unbaked/scene/labels_2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ffe08c25461a0f9e625ffd64d82bf7b64e4588e8c7e70e2d782f0db16caa195 +size 40461 diff --git a/src/coolant/valve.cpp b/src/coolant/valve.cpp index 18d7b1a..9512219 100644 --- a/src/coolant/valve.cpp +++ b/src/coolant/valve.cpp @@ -23,9 +23,39 @@ void valve::clear_open_speed() speed = 0; } +void valve::toggle_auto() +{ + set_auto(!auto_on); +} + +void valve::set_auto(bool state) +{ + if(state) + { + auto_th = src->get_heat(); + } + + else + { + auto_th = 0; + } + + auto_on = state; + speed = 0; +} + void valve::update(double dt) { - state += speed * dt; + if(auto_on) + { + state -= pid.calculate(dt, auto_th, src->get_heat()) * dt; + auto_th += speed * dt * 100; + } + + else + { + state += speed * dt; + } if(state > 1) state = 1; if(state < 0) state = 0; @@ -81,11 +111,12 @@ void valve::update(double dt) this->flow = (mass_s + mass_a) / dt; } -valve::valve(const Json::Value& node, fluid_holder* src, fluid_holder* dst) : src(src), dst(dst), max(node["max"].asDouble()) +valve::valve(const Json::Value& node, fluid_holder* src, fluid_holder* dst) : src(src), dst(dst), max(node["max"].asDouble()), pid(node["pid"]) { - speed = node["speed"].asDouble(); state = node["state"].asDouble(); flow = node["flow"].asDouble(); + auto_th = node["auto_th"].asDouble(); + auto_on = node["auto_on"].asBool(); } valve::operator Json::Value() const @@ -93,9 +124,11 @@ valve::operator Json::Value() const Json::Value node; node["max"] = max; - node["speed"] = speed; node["state"] = state; node["flow"] = flow; + node["auto_th"] = auto_th; + node["auto_on"] = auto_on; + node["pid"] = pid; return node; } diff --git a/src/coolant/valve.hpp b/src/coolant/valve.hpp index ab78698..92cc308 100644 --- a/src/coolant/valve.hpp +++ b/src/coolant/valve.hpp @@ -2,6 +2,7 @@ #pragma once #include "fluid_holder.hpp" +#include "../util/pid.hpp" namespace sim::coolant { @@ -17,6 +18,11 @@ class valve double state = 0; double flow = 0; // L/s + bool auto_on = false; + double auto_th = 0; // C + + util::PID pid {1e-3, -1e-3, 100, 0, 0}; + public: valve(fluid_holder* src, fluid_holder* dst, double state, double max); @@ -25,11 +31,15 @@ public: void update(double secs); void add_open_speed(double v); void clear_open_speed(); + void set_auto(bool state); + void toggle_auto(); operator Json::Value() const; constexpr double get_state() const { return state; } constexpr double get_flow() const { return flow; } + constexpr double get_setpoint() const { return auto_th; } + constexpr bool get_auto() const { return auto_on; } }; }; diff --git a/src/electric/turbine.cpp b/src/electric/turbine.cpp index fb3d6dd..168c88b 100644 --- a/src/electric/turbine.cpp +++ b/src/electric/turbine.cpp @@ -30,12 +30,35 @@ turbine::turbine(const Json::Value& node, coolant::condenser* condenser) : sim::coolant::fluid_holder(node) { velocity = node["velocity"].asDouble(); + phase = node["phase"].asDouble(); + breaker_closed = node["breaker_closed"].asBool(); } void turbine::update(double dt) { double work = get_rpm() / 60 * dt * friction; + phase = std::fmod(phase + util::map( get_rpm(), 0, 60, 0, 2 * M_PI ) * dt, 2 * M_PI); + + // do energy transfer stuff here + if(breaker_closed) + { + double r_diff = util::map(get_phase_diff(), -M_PI, M_PI, -30, 30); + double w = r_diff * 1e6; + + double v2 = util::mod((velocity - 3600) / 60 + 30, 60) - 30; + double w2 = w * w * v2; + + energy_generated = w2 * extra_mass; + work += w * dt; + } + + else + { + energy_generated = 0; + } + velocity = std::max(velocity - work, 0.0); + } double turbine::get_rpm() const @@ -43,6 +66,12 @@ double turbine::get_rpm() const return velocity / (M_PI * extra_mass * 0.001 * diameter * diameter * 0.25); } +double turbine::get_phase_diff() const +{ + double phase_g = std::fmod(system::active.clock * 60, 1) * 2 * M_PI; + return util::mod(phase - phase_g + M_PI, 2*M_PI) - M_PI; +} + void turbine::add_gas(double steam, double air, double t) { double joules = (steam + air) * fluid.jPg; @@ -58,6 +87,8 @@ turbine::operator Json::Value() const node["diameter"] = diameter; node["velocity"] = velocity; node["friction"] = friction; + node["breaker_closed"] = breaker_closed; + node["phase"] = phase; return node; } diff --git a/src/electric/turbine.hpp b/src/electric/turbine.hpp index eb6683c..35fd8d1 100644 --- a/src/electric/turbine.hpp +++ b/src/electric/turbine.hpp @@ -15,9 +15,13 @@ class turbine : public sim::coolant::fluid_holder const double diameter; const double friction = 1; + double energy_generated = 0; // W double velocity = 0; // m/s + double phase = 0; public: + + bool breaker_closed = false; turbine(coolant::fluid_t type, coolant::condenser* condenser, double length, double diameter, double mass); turbine(const Json::Value& node, coolant::condenser* condenser); @@ -44,6 +48,10 @@ public: virtual double get_pressure() const { return condenser->get_pressure(); } // pascals virtual double get_gas_density() const { return condenser->get_gas_density(); } // g/L + constexpr double get_energy_generated() const { return energy_generated; } + constexpr double get_phase() const { return phase; } + double get_phase_diff() const; + operator Json::Value() const; }; diff --git a/src/graphics/mesh/mesh.cpp b/src/graphics/mesh/mesh.cpp index 01c9b39..2361257 100644 --- a/src/graphics/mesh/mesh.cpp +++ b/src/graphics/mesh/mesh.cpp @@ -21,8 +21,8 @@ void mesh::add(const mesh& o, glm::mat4 mat) for(unsigned int i = 0; i < o.vertices.size(); i++) { arrays::vertex v = o.vertices[i]; - v.normal = v.normal * mat3; - v.pos = v.pos * mat; + v.normal = mat3 * v.normal; + v.pos = mat * v.pos; vertices.push_back(v); } diff --git a/src/graphics/monitor/core.cpp b/src/graphics/monitor/core.cpp index 79e966d..65bc307 100644 --- a/src/graphics/monitor/core.cpp +++ b/src/graphics/monitor/core.cpp @@ -7,6 +7,7 @@ #include "../locations.hpp" #include "../input/focus.hpp" #include "../mesh/arrays.hpp" +#include "../mesh/texture.hpp" #include "../../system.hpp" #include @@ -106,17 +107,24 @@ void core::init() mesh1.model_matrix = locations::monitors[2]; mesh1.colour_matrix = arrays::colour({1, 1, 1, 1}); - sim::graphics::mesh rmesh1, rmesh2; + sim::graphics::mesh rmesh; - rmesh1.load_text("Reactor Core", 0.04); - rmesh2.load_model("../assets/model/", "reactor_core_interface_circle.stl"); - rmesh1.add(rmesh2, glm::mat4(1)); - + rmesh.load_text("Reactor Core", 0.04); mesh1.bind(); - mesh1.set(rmesh1, GL_STATIC_DRAW); - rmesh2.load_model("../assets/model/", "reactor_core_interface_cell.stl"); + mesh1.set(rmesh, GL_STATIC_DRAW); + + unsigned int indices[] = {0, 1, 3, 0, 3, 2}; + arrays::vertex vertices[] = { + {texture::handle_white, {0, 0}, {-0.75, -0.75, 0, 1}, {0, 0, -1}}, + {texture::handle_white, {0, 1}, {-0.75, 0.75, 0, 1}, {0, 0, -1}}, + {texture::handle_white, {1, 0}, { 0.75, -0.75, 0, 1}, {0, 0, -1}}, + {texture::handle_white, {1, 1}, { 0.75, 0.75, 0, 1}, {0, 0, -1}}, + }; + + rmesh.set_indices(indices, 6); + rmesh.set_vertices(vertices, 4); mesh2.bind(); - mesh2.set(rmesh2, GL_STATIC_DRAW); + mesh2.set(rmesh, GL_STATIC_DRAW); m_buttons[0].load_model("../assets/model/", "reactor_core_button1.stl"); m_buttons[1].load_model("../assets/model/", "reactor_core_button2.stl"); @@ -169,14 +177,17 @@ void core::render() double sy = 0.5 - (sys.reactor->height - 1) * step / 2.0; 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)); + 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.25, 0.25, 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.25, 0.25, 1)); + glm::mat4 mat_spec = glm::translate(glm::mat4(1), glm::vec3(0.8, -0.8, -0.001)) * glm::scale(glm::mat4(1), glm::vec3(0.25, 0.25, 1)); mesh1.bind(); mesh1.uniform(); mesh1.render(); mesh2.bind(); + // this renderer is disgusting + for(int i = 0; i < sys.reactor->size; i++) { int x = i % sys.reactor->width; @@ -185,9 +196,16 @@ void core::render() double oy = sy + y * step; reactor::rod* r = sys.reactor->rods[i].get(); - glm::vec4 colour = r->get_colour(); - if(colour[3] == 0) + if(!r->should_display()) + { + continue; + } + + glm::vec4 colour_heat = r->get_heat_colour() * glm::vec4(glm::vec3(1), 1); + glm::vec4 colour_spec = r->get_colour(); + + if(colour_heat[3] == 0) { continue; } @@ -195,7 +213,7 @@ void core::render() 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.colour_matrix = arrays::colour(colour_heat); mesh2.uniform(); mesh2.render(); @@ -214,6 +232,14 @@ void core::render() mesh2.uniform(); mesh2.render(); } + + if(colour_spec[3] != 0) + { + mesh2.model_matrix = mat * mat_spec; + mesh2.colour_matrix = arrays::colour(colour_spec); + mesh2.uniform(); + mesh2.render(); + } } } diff --git a/src/graphics/monitor/primary_loop.cpp b/src/graphics/monitor/primary_loop.cpp index 4c1f567..64ccca6 100644 --- a/src/graphics/monitor/primary_loop.cpp +++ b/src/graphics/monitor/primary_loop.cpp @@ -54,15 +54,6 @@ primary_loop::primary_loop() } -void primary_loop::toggle_primary_pump() -{ - system& sys = sim::system::active; - bool state; - - sys.primary_pump->powered = state = !sys.primary_pump->powered; - gm_switch_1.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, state ? 0.07 : 0, 0)); -} - void primary_loop::init() { mesh1.model_matrix = locations::monitors[3]; @@ -79,9 +70,9 @@ void primary_loop::init() sim::graphics::mesh rmesh; ss << "Turbine Bypass Valve\n\n"; - ss << "Opened\nFlow\n\n"; + ss << "Opened\nFlow\nSetpoint\n\n"; ss << "Turbine Inlet Valve\n\n"; - ss << "Opened\nFlow\n\n"; + ss << "Opened\nFlow\nSetpoint\n\n"; ss << "Primary Pump\n\n"; ss << "Power\nSpeed\nFlow\n\n"; ss << "Condenser\n\n"; @@ -94,13 +85,23 @@ void primary_loop::init() mesh1.bind(); mesh1.set(rmesh, GL_STATIC_DRAW); - rmesh.load_model("../assets/model", "pump_switch_1.glb"); - gm_switch_1.bind(); - gm_switch_1.set(rmesh, GL_STATIC_DRAW); + rmesh.load_model("../assets/model", "pump_switch_1.fbx"); + gm_switch_pump.bind(); + gm_switch_pump.set(rmesh, GL_STATIC_DRAW); + + rmesh.load_model("../assets/model", "turbine_valve_bypass_switch.fbx"); + gm_switch_bypass.bind(); + gm_switch_bypass.set(rmesh, GL_STATIC_DRAW); + + rmesh.load_model("../assets/model", "turbine_valve_inlet_switch.fbx"); + gm_switch_inlet.bind(); + gm_switch_inlet.set(rmesh, GL_STATIC_DRAW); m_joystick_turbine_bypass.load_model("../assets/model", "turbine_valve_bypass_joystick.stl"); m_joystick_turbine_inlet.load_model("../assets/model", "turbine_valve_inlet_joystick.stl"); - m_switch_1.load_model("../assets/model", "pump_switch_click_1.stl"); + m_switch_pump.load_model("../assets/model", "pump_switch_click_1.stl"); + m_switch_bypass.load_model("../assets/model", "turbine_valve_bypass_switch_click.stl"); + m_switch_inlet.load_model("../assets/model", "turbine_valve_inlet_switch_click.stl"); } void primary_loop::update(double dt) @@ -117,9 +118,31 @@ void primary_loop::update(double dt) ss << "\n\n"; ss << show( sys.turbine_bypass_valve->get_state() * 100 ) << " %\n"; ss << show( sys.turbine_bypass_valve->get_flow() / 1000 ) << " kg/s\n"; + + if(sys.turbine_bypass_valve->get_auto()) + { + ss << show( sys.turbine_bypass_valve->get_setpoint() ) << " C\n"; + } + + else + { + ss << "-\n"; + } + ss << "\n\n\n"; ss << show( sys.turbine_inlet_valve->get_state() * 100 ) << " %\n"; ss << show( sys.turbine_inlet_valve->get_flow() / 1000 ) << " kg/s\n"; + + if(sys.turbine_inlet_valve->get_auto()) + { + ss << show( sys.turbine_inlet_valve->get_setpoint() ) << " C\n"; + } + + else + { + ss << "-\n"; + } + ss << "\n\n\n"; ss << show( sys.primary_pump->get_power() * 100 ) << " %\n"; ss << show( sys.primary_pump->get_rpm() ) << " r/min\n"; @@ -139,8 +162,16 @@ void primary_loop::update(double dt) focus::set(std::make_unique(sys.turbine_bypass_valve.get())); if(m_joystick_turbine_inlet.check_focus()) focus::set(std::make_unique(sys.turbine_inlet_valve.get())); - if(m_switch_1.check_focus()) - toggle_primary_pump(); + if(m_switch_pump.check_focus()) + sys.primary_pump->powered = !sys.primary_pump->powered; + if(m_switch_inlet.check_focus()) + sys.turbine_inlet_valve->toggle_auto(); + if(m_switch_bypass.check_focus()) + sys.turbine_bypass_valve->toggle_auto(); + + gm_switch_inlet.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.turbine_inlet_valve->get_auto() ? 0.07 : 0, 0)); + gm_switch_bypass.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.turbine_bypass_valve->get_auto() ? 0.07 : 0, 0)); + gm_switch_pump.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.primary_pump->powered ? 0.07 : 0, 0)); } void primary_loop::render() @@ -153,8 +184,16 @@ void primary_loop::render() mesh2.uniform(); mesh2.render(); - gm_switch_1.bind(); - gm_switch_1.uniform(); - gm_switch_1.render(); + gm_switch_pump.bind(); + gm_switch_pump.uniform(); + gm_switch_pump.render(); + + gm_switch_inlet.bind(); + gm_switch_inlet.uniform(); + gm_switch_inlet.render(); + + gm_switch_bypass.bind(); + gm_switch_bypass.uniform(); + gm_switch_bypass.render(); } diff --git a/src/graphics/monitor/primary_loop.hpp b/src/graphics/monitor/primary_loop.hpp index 1440714..617841a 100644 --- a/src/graphics/monitor/primary_loop.hpp +++ b/src/graphics/monitor/primary_loop.hpp @@ -8,16 +8,19 @@ namespace sim::graphics::monitor class primary_loop { - sim::graphics::glmesh mesh1, mesh2; + glmesh mesh1, mesh2; double clock_at = 0, clock_now = 0; - sim::graphics::glmesh gm_switch_1; + glmesh gm_switch_pump; + glmesh gm_switch_bypass; + glmesh gm_switch_inlet; - sim::graphics::mesh m_joystick_turbine_bypass; - sim::graphics::mesh m_joystick_turbine_inlet; - sim::graphics::mesh m_switch_1; + mesh m_joystick_turbine_bypass; + mesh m_joystick_turbine_inlet; - void toggle_primary_pump(); + mesh m_switch_pump; + mesh m_switch_bypass; + mesh m_switch_inlet; public: diff --git a/src/graphics/monitor/secondary_loop.cpp b/src/graphics/monitor/secondary_loop.cpp index c47682d..13550ef 100644 --- a/src/graphics/monitor/secondary_loop.cpp +++ b/src/graphics/monitor/secondary_loop.cpp @@ -20,22 +20,6 @@ secondary_loop::secondary_loop() } -void secondary_loop::toggle_secondary_pump() -{ - system& sys = sim::system::active; - bool state = false; - sys.secondary_pump->powered = state = !sys.secondary_pump->powered; - gm_switch_2.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, state ? 0.07 : 0, 0)); -} - -void secondary_loop::toggle_freight_pump() -{ - system& sys = sim::system::active; - bool state = false; - sys.freight_pump->powered = state = !sys.freight_pump->powered; - gm_switch_3.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, state ? 0.07 : 0, 0)); -} - void secondary_loop::init() { mesh1.model_matrix = locations::monitors[5]; @@ -62,11 +46,11 @@ void secondary_loop::init() mesh1.bind(); mesh1.set(rmesh, GL_STATIC_DRAW); - rmesh.load_model("../assets/model", "pump_switch_2.glb"); + rmesh.load_model("../assets/model", "pump_switch_2.fbx"); gm_switch_2.bind(); gm_switch_2.set(rmesh, GL_STATIC_DRAW); - rmesh.load_model("../assets/model", "pump_switch_3.glb"); + rmesh.load_model("../assets/model", "pump_switch_3.fbx"); gm_switch_3.bind(); gm_switch_3.set(rmesh, GL_STATIC_DRAW); @@ -106,11 +90,13 @@ void secondary_loop::update(double dt) mesh2.set(rmesh, GL_DYNAMIC_DRAW); } - if(m_switch_2.check_focus()) - toggle_secondary_pump(); + sys.secondary_pump->powered = !sys.secondary_pump->powered; if(m_switch_3.check_focus()) - toggle_freight_pump(); + sys.freight_pump->powered = !sys.freight_pump->powered; + + gm_switch_2.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.secondary_pump->powered ? 0.07 : 0, 0)); + gm_switch_3.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.freight_pump->powered ? 0.07 : 0, 0)); } void secondary_loop::render() diff --git a/src/graphics/monitor/secondary_loop.hpp b/src/graphics/monitor/secondary_loop.hpp index 1e08335..f9240d6 100644 --- a/src/graphics/monitor/secondary_loop.hpp +++ b/src/graphics/monitor/secondary_loop.hpp @@ -18,9 +18,6 @@ class secondary_loop sim::graphics::mesh m_joystick_turbine_inlet; sim::graphics::mesh m_switch_2; sim::graphics::mesh m_switch_3; - - void toggle_secondary_pump(); - void toggle_freight_pump(); public: diff --git a/src/graphics/monitor/turbine.cpp b/src/graphics/monitor/turbine.cpp index 0876031..52ac61c 100644 --- a/src/graphics/monitor/turbine.cpp +++ b/src/graphics/monitor/turbine.cpp @@ -22,9 +22,7 @@ turbine::turbine() void turbine::init() { - mesh1.model_matrix = locations::monitors[4]; - mesh2.model_matrix = glm::translate(mesh1.model_matrix, glm::vec3(0.5, 0, 0)); - + mesh1.model_matrix = mesh2.model_matrix = locations::monitors[4]; mesh1.colour_matrix = mesh2.colour_matrix = { 1, 1, 1, 1, 0, 0, 0, 0, @@ -33,14 +31,27 @@ void turbine::init() }; std::stringstream ss; - sim::graphics::mesh rmesh; + sim::graphics::mesh rmesh, rmesh2; ss << "Turbine\n\n"; ss << "Heat\nPressure\nSpeed\n\n"; rmesh.load_text(ss.str().c_str(), 0.04); + rmesh2.load_text("Synchroscope", 0.04); + rmesh.add(rmesh2, glm::translate(glm::mat4(1), glm::vec3(0, 0.6, 0))); + mesh1.bind(); mesh1.set(rmesh, GL_STATIC_DRAW); + + rmesh.load_model("../assets/model", "synchroscope_dial.stl"); + gm_synchroscope_dial.bind(); + gm_synchroscope_dial.set(rmesh, GL_STATIC_DRAW); + + rmesh.load_model("../assets/model", "turbine_breaker_switch.fbx"); + gm_switch_breaker.bind(); + gm_switch_breaker.set(rmesh, GL_STATIC_DRAW); + + m_switch_breaker.load_model("../assets/model", "turbine_breaker_switch_click.stl"); } void turbine::update(double dt) @@ -51,7 +62,7 @@ void turbine::update(double dt) if(clock_at + 1.0/30.0 < clock_now) { std::stringstream ss; - sim::graphics::mesh rmesh; + sim::graphics::mesh rmesh, rmesh2; clock_at += 1.0/30.0; ss << "\n\n"; @@ -59,10 +70,45 @@ void turbine::update(double dt) ss << show( sys.turbine->get_pressure() / 1000 ) << " kPa\n"; ss << show( sys.turbine->get_rpm() ) << " r/min\n"; - rmesh.load_text(ss.str().c_str(), 0.04); + rmesh2.load_text(ss.str().c_str(), 0.04); + rmesh.add(rmesh2, glm::translate(glm::mat4(1), glm::vec3(0.5, 0, 0))); + + ss = std::stringstream(); + + ss << "Local\n\n"; + ss << show( sys.turbine->get_rpm() / 60 ) << " Hz\n"; + ss << show( sys.turbine->get_energy_generated() ) << " W\n"; + + rmesh2.load_text(ss.str().c_str(), 0.04); + rmesh.add(rmesh2, glm::translate(glm::mat4(1), glm::vec3(0.4, 0.7, 0))); + + ss = std::stringstream(); + + ss << "Grid\n\n"; + ss << show( 60 ) << " Hz\n"; + + rmesh2.load_text(ss.str().c_str(), 0.04); + rmesh.add(rmesh2, glm::translate(glm::mat4(1), glm::vec3(0.7, 0.7, 0))); + mesh2.bind(); mesh2.set(rmesh, GL_DYNAMIC_DRAW); } + + double rpm = sys.turbine->get_rpm(); + + if(rpm > 3570 && rpm < 3630) + { + glm::mat4 mat = glm::mat4(1); + mat = glm::translate(mat, glm::vec3(6.35, 3.949, 1.35)); + mat = glm::rotate(mat, float(sys.turbine->get_phase_diff()), glm::vec3(0, 1, 0)); + mat = glm::translate(mat, glm::vec3(-6.35, -3.949, -1.35)); + gm_synchroscope_dial.model_matrix = mat; + } + + if(m_switch_breaker.check_focus()) + sys.turbine->breaker_closed = !sys.turbine->breaker_closed; + + gm_switch_breaker.model_matrix = glm::translate(glm::mat4(1), glm::vec3(0, sys.turbine->breaker_closed ? 0.07 : 0, 0)); } void turbine::render() @@ -74,5 +120,18 @@ void turbine::render() mesh2.bind(); mesh2.uniform(); mesh2.render(); + + double rpm = system::active.turbine->get_rpm(); + + if(rpm > 3570 && rpm < 3630) + { + gm_synchroscope_dial.bind(); + gm_synchroscope_dial.uniform(); + gm_synchroscope_dial.render(); + } + + gm_switch_breaker.bind(); + gm_switch_breaker.uniform(); + gm_switch_breaker.render(); } diff --git a/src/graphics/monitor/turbine.hpp b/src/graphics/monitor/turbine.hpp index a6a3c60..b341779 100644 --- a/src/graphics/monitor/turbine.hpp +++ b/src/graphics/monitor/turbine.hpp @@ -11,6 +11,10 @@ class turbine sim::graphics::glmesh mesh1, mesh2; double clock_at = 0, clock_now = 0; + sim::graphics::glmesh gm_synchroscope_dial; + sim::graphics::glmesh gm_switch_breaker; + sim::graphics::mesh m_switch_breaker; + public: turbine(); diff --git a/src/graphics/monitor/vessel.cpp b/src/graphics/monitor/vessel.cpp index 87377a2..6afb01b 100644 --- a/src/graphics/monitor/vessel.cpp +++ b/src/graphics/monitor/vessel.cpp @@ -41,8 +41,8 @@ void vessel::init() ss << "Level\n"; ss << "Void Ratio\n\n"; ss << "Reactor Core\n\n"; - ss << "Energy Output\n"; ss << "Neutron Flux\n\n"; +// ss << "Increase Rate\n\n"; ss << "Temperature\nMin\nMax\n\n"; ss << "Control Rods\nMin\nMax\nSpeed\n"; @@ -98,8 +98,8 @@ void vessel::update(double dt) ss << show( sys.vessel->get_pressure() * 0.001 ) << " kPa\n"; ss << show( sys.vessel->get_level() / 1000 ) << " / " << show( sys.vessel->get_volume() / 1000 ) << " kL\n"; ss << show( sys.vessel->get_void_ratio() * 100 ) << " %\n\n\n\n"; - ss << show( sys.reactor->get_energy_output() * 0.001 ) << " kW\n"; ss << show( sys.reactor->get_flux() ) << " n/cm2/s\n\n\n"; +// ss << show( sys.reactor->flux_rate * 100 ) << " %/s\n\n\n"; ss << show( temp_min ) << " C\n"; ss << show( temp_max ) << " C\n\n\n"; ss << show( 100 - crod_max * 100 ) << " %\n"; diff --git a/src/graphics/window.cpp b/src/graphics/window.cpp index 8fa6e3b..3e4b515 100644 --- a/src/graphics/window.cpp +++ b/src/graphics/window.cpp @@ -109,9 +109,12 @@ void window::create() shader::init_program(); sim::system& sys = sim::system::active; - mesh m; + mesh m, m2; m.load_model("../assets", "scene-baked.glb"); + m2.load_model("../assets/model", "monitor_graphics.stl"); + m.add(m2, glm::mat4(1)); + mesh_scene.bind(); mesh_scene.set(m, GL_STATIC_DRAW); diff --git a/src/reactor/fuel/fuel_rod.cpp b/src/reactor/fuel/fuel_rod.cpp index a029aa0..87f0cd4 100644 --- a/src/reactor/fuel/fuel_rod.cpp +++ b/src/reactor/fuel/fuel_rod.cpp @@ -45,49 +45,6 @@ double fuel_rod::get_energy_output() const return s.get_energy() * mol * energy_density; } -static float map(float v, float imin, float imax, float omin, float omax) -{ - return (v - imin) * (omax - omin) / (imax - imin) + omin; -} - -glm::vec4 fuel_rod::get_colour() const -{ - double temp = vals[val_t::HEAT]; - - if(temp < 0) - { - temp = 0; - } - - // this should not happen - if(std::isnan(temp)) - { - return {1, 0, 1, 1}; - } - - if(temp < 120) - { - return {0, map(temp, 0, 120, 0, 1), 1, 1}; - } - - if(temp < 240) - { - return {0, 1, map(temp, 120, 240, 1, 0), 1}; - } - - if(temp < 280) - { - return {map(temp, 240, 280, 0, 1), 1, 0, 1}; - } - - if(temp < 320) - { - return {1, map(temp, 280, 320, 1, 0), 0, 1}; - } - - return {1, 0, 0, 1}; -} - void fuel_rod::update(double secs) { update_rod(secs); diff --git a/src/reactor/fuel/fuel_rod.hpp b/src/reactor/fuel/fuel_rod.hpp index 291eb81..cbfca93 100644 --- a/src/reactor/fuel/fuel_rod.hpp +++ b/src/reactor/fuel/fuel_rod.hpp @@ -18,7 +18,6 @@ class fuel_rod : public sim::reactor::rod virtual const char* get_name() const { return "Fuel"; } virtual int get_id() const { return 1; } virtual double get_energy_output() const; - virtual glm::vec4 get_colour() const; public: diff --git a/src/reactor/reactor.cpp b/src/reactor/reactor.cpp index a64af7b..63db165 100644 --- a/src/reactor/reactor.cpp +++ b/src/reactor/reactor.cpp @@ -74,6 +74,7 @@ void reactor::update(double secs) { int rods_lookup[size]; double temp_min, temp_max; + double flux_initial = get_flux(); get_stats(rod::val_t::HEAT, temp_min, temp_max); @@ -103,6 +104,11 @@ void reactor::update(double secs) { update_selected(secs); } + + if(flux_initial > 0) + { + flux_rate = (get_flux() - flux_initial) / flux_initial / secs; + } } void reactor::update_selected(double dt) @@ -243,9 +249,9 @@ void reactor::get_stats(rod::val_t type, double& min, double& max) reactor::reactor(const Json::Value& node, coolant::vessel* v) : cell_width(node["cell_width"].asDouble()), cell_height(node["cell_height"].asDouble()), - width(node["width"].asDouble()), - height(node["height"].asDouble()), - size(node["size"].asDouble()) + width(node["width"].asInt()), + height(node["height"].asInt()), + size(node["size"].asInt()) { const Json::Value& j_rods = node["rods"]; diff --git a/src/reactor/reactor.hpp b/src/reactor/reactor.hpp index c824b40..5a1efc4 100644 --- a/src/reactor/reactor.hpp +++ b/src/reactor/reactor.hpp @@ -21,6 +21,8 @@ struct reactor const int size; std::vector> rods; + + double flux_rate = 0; double rod_speed = 0; int cursor; diff --git a/src/reactor/rod.cpp b/src/reactor/rod.cpp index 03e1923..fe4190d 100644 --- a/src/reactor/rod.cpp +++ b/src/reactor/rod.cpp @@ -1,6 +1,7 @@ #include "rod.hpp" #include "reactor.hpp" +#include "../util/math.hpp" #include @@ -51,6 +52,44 @@ void rod::interact(rod* o, double secs) } } +glm::vec4 rod::get_heat_colour() const +{ + double temp = vals[val_t::HEAT]; + + if(temp < 0) + { + temp = 0; + } + + // this should not happen + if(std::isnan(temp)) + { + return {1, 0, 1, 1}; + } + + if(temp < 120) + { + return {0, util::map(temp, 0, 120, 0, 1), 1, 1}; + } + + if(temp < 240) + { + return {0, 1, util::map(temp, 120, 240, 1, 0), 1}; + } + + if(temp < 280) + { + return {util::map(temp, 240, 280, 0, 1), 1, 0, 1}; + } + + if(temp < 320) + { + return {1, util::map(temp, 280, 320, 1, 0), 0, 1}; + } + + return {1, 0, 0, 1}; +} + double rod::get_flux() const { return (vals_n[val_t::N_FAST] + vals_n[val_t::N_SLOW]) * N_a / (get_side_area() * 10000) / 4; diff --git a/src/reactor/rod.hpp b/src/reactor/rod.hpp index 608420f..d257aff 100644 --- a/src/reactor/rod.hpp +++ b/src/reactor/rod.hpp @@ -35,9 +35,11 @@ public: virtual double extract(val_t type, double s, double k, double o); virtual double get(val_t type) const; virtual std::unique_ptr clone() const { return std::make_unique(*this); } - virtual glm::vec4 get_colour() const { return {0, 0, 0, 0}; } virtual double get_energy_output() const { return 0; } virtual int get_id() const { return 0; } + + virtual glm::vec4 get_colour() const { return {0, 0, 0, 0}; } + glm::vec4 get_heat_colour() const; virtual bool has_sensors(val_t t) const { return false; } virtual bool should_display() const { return false; } diff --git a/src/util/math.hpp b/src/util/math.hpp index 131656e..6f78444 100644 --- a/src/util/math.hpp +++ b/src/util/math.hpp @@ -34,5 +34,23 @@ constexpr double calc_work(double j, double mass) return m * std::sqrt(m * j / (mass * 0.001)); } +constexpr float map(float v, float imin, float imax, float omin, float omax) +{ + return (v - imin) * (omax - omin) / (imax - imin) + omin; +} + +template +constexpr A mod(A a, B b) +{ + A v = std::fmod(a, b); + + if(v < 0) + { + v += b; + } + + return v; +} + };