diff --git a/assets/scene.blend b/assets/scene.blend index 26aa843..cd4761b 100644 --- a/assets/scene.blend +++ b/assets/scene.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8f3bfe3273bc69e19caf98fb967b5f57e2f01fd7650c33b3f65aba0edb9e1a35 -size 12259665 +oid sha256:41ba57a844b0436beed7f41a2ec804b9fa8b58e3809e6fba5181c5c42b711478 +size 16405769 diff --git a/assets/scene.glb b/assets/scene.glb index 479b32d..fe23400 100644 --- a/assets/scene.glb +++ b/assets/scene.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b01a5e8079b95c2f32d653a2622a6204ffebb36ec58950c410bf3492a6901831 -size 1603960 +oid sha256:1e2ae295c30e9008808b575fd251d3fc2cdbd882e5d7e9b9bba84d087ea1712b +size 5679556 diff --git a/assets/shader/main.fsh b/assets/shader/main.fsh index 37d473c..272e354 100644 --- a/assets/shader/main.fsh +++ b/assets/shader/main.fsh @@ -10,6 +10,7 @@ in VS_OUT { vec3 pos; vec2 tex_pos; vec3 material; + float ambient; } vin; struct Light @@ -37,6 +38,17 @@ uniform float far_plane; uniform bool shadows_enabled; uniform int lights_count; +float Map(float v, float i_min, float i_max, float o_min, float o_max) +{ + return o_min + (o_max - o_min) * (v - i_min) / (i_max - i_min); +} + +float Ramp(float v, float i_min, float i_max, float o_min, float o_max) +{ + float t = clamp(v, i_min, i_max); + return Map(t, i_min, i_max, o_min, o_max); +} + vec3 FresnelSchlick(float cosTheta, vec3 F0) { return F0 + (1.f - F0) * pow(clamp(1.f - cosTheta, 0.f, 1.f), 5.f); @@ -113,15 +125,28 @@ void main() vec3 F0 = vec3(0.04f); F0 = mix(F0, albedo_lin, metalness); - vec3 Lo = vec3(0.0f); + vec3 Lo = vec3(0.f); for(int i = 0; i < lights_count; i++) { Light l = lights[i]; + float light_m; vec3 L = normalize(l.pos.xyz - vin.pos); - vec3 H = normalize(V + L); - float d = length(vin.pos - l.pos.xyz); + + if(shadows_enabled) + { + float max_d = texture(shadow_maps[i], -L).r * far_plane; + light_m = Ramp(d - max_d, 0.f, 2.5e-2f, 1.f, 0.f); + if(light_m <= 0.f) continue; + } + + else + { + light_m = 1.f; + } + + vec3 H = normalize(V + L); float atten = 1.f / (d*d); vec3 radiance = l.colour.rgb * atten; @@ -138,28 +163,13 @@ void main() float denominator = 4.f * max(dot(N, V), 0.f) * max(dot(N, L), 0.f) + 1e-4f; vec3 specular = numerator / denominator; - float light_m; - float spec_m; - - if(shadows_enabled) - { - float max_d = texture(shadow_maps[i], -L).r * far_plane + 1e-2f; - spec_m = max_d > d ? 1.f : 0.f; - light_m = spec_m * 0.25f + 0.75f; - } - - else - { - light_m = 1.f; - spec_m = 1.f; - } // add to outgoing radiance Lo float NdotL = max(dot(N, L), 0.f); - Lo += (kD * albedo_lin / PI + specular * spec_m) * radiance * NdotL * light_m; + Lo += (kD * albedo_lin / PI + specular) * radiance * NdotL * light_m; } - vec3 ambient = vec3(0.03f) * albedo_lin * brightness; + vec3 ambient = vec3(vin.ambient) * albedo_lin * brightness; vec3 light = LinRGB_To_sRGB(ambient + Lo); light = mix(light, albedo.rgb, luminance); diff --git a/assets/shader/main.vsh b/assets/shader/main.vsh index 441434f..abccc2a 100644 --- a/assets/shader/main.vsh +++ b/assets/shader/main.vsh @@ -24,6 +24,7 @@ out VS_OUT { vec3 pos; vec2 tex_pos; vec3 material; + float ambient; } vout; out flat sampler2D frag_tex; @@ -33,6 +34,11 @@ mat4 load_model_mat(int index) return index < 0 ? mat4(1.f) : transforms[index]; } +float Map(float v, float i_min, float i_max, float o_min, float o_max) +{ + return o_min + (o_max - o_min) * (v - i_min) / (i_max - i_min); +} + void main() { vec4 pos = vec4(aPos, 1.f); @@ -40,7 +46,8 @@ void main() mat4 mv = camera * model; mat4 mvp = projection * mv; - vout.normal = mat3(model) * aNormal; + vout.normal = normalize(mat3(model) * aNormal); + vout.ambient = Map(dot(vout.normal, vec3(0.f, 0.f, 1.f)), -1.f, 1.f, 0.2f, 0.25f); vout.pos = (model * pos).xyz; vout.colour = aColour; vout.tex_pos = aTexPos; diff --git a/src/coolant/evaporator.cpp b/src/coolant/evaporator.cpp index 9628b09..f3c704a 100644 --- a/src/coolant/evaporator.cpp +++ b/src/coolant/evaporator.cpp @@ -14,18 +14,20 @@ constexpr static double calc_cylinder(double h, double d) return M_PI * r * r * h * 1000; } -Evaporator::Evaporator(Fluid type, double height, double diameter, double mass, double level) : - height(height), - diameter(diameter), - FluidHolder(type, calc_cylinder(height, diameter), mass) +Evaporator::Evaporator(Fluid type, double volume, double mass, double level) + : FluidHolder(type, volume, mass) { this->level = level; } -Evaporator::Evaporator(const Json::Value& node) : - height(node["height"].asDouble()), - diameter(node["diameter"].asDouble()), - FluidHolder(node) +Evaporator::Evaporator(Fluid type, double height, double diameter, double mass, double level) + : FluidHolder(type, calc_cylinder(height, diameter), mass) +{ + this->level = level; +} + +Evaporator::Evaporator(const Json::Value& node) + : FluidHolder(node) { steam_output = node["steam_output"].asDouble(); } @@ -70,8 +72,6 @@ Evaporator::operator Json::Value() const { Json::Value node(FluidHolder::operator::Json::Value()); - node["height"] = height; - node["diameter"] = diameter; node["steam_output"] = steam_output; return node; diff --git a/src/coolant/evaporator.hpp b/src/coolant/evaporator.hpp index 148f11a..f235237 100644 --- a/src/coolant/evaporator.hpp +++ b/src/coolant/evaporator.hpp @@ -8,13 +8,11 @@ namespace Sim::Coolant class Evaporator : public FluidHolder { - const double height; - const double diameter; - double steam_output = 0; public: + Evaporator(Fluid type, double volume, double mass, double level); Evaporator(Fluid type, double height, double diameter, double mass, double level); Evaporator(const Json::Value& node); diff --git a/src/coolant/pool.cpp b/src/coolant/pool.cpp new file mode 100644 index 0000000..78b1d5c --- /dev/null +++ b/src/coolant/pool.cpp @@ -0,0 +1,35 @@ + +#include "pool.hpp" + +using namespace Sim::Coolant; + +Pool::Pool(const Json::Value& node) + : Evaporator(node) + , dimensions(node["dimensions"]["x"].asDouble(), node["dimensions"]["y"].asDouble(), node["dimensions"]["z"].asDouble()) +{ + +} + +Pool::Pool(Fluid fluid, const glm::vec3& dimensions, double heat, double mass, double level) + : Evaporator(fluid, dimensions.x * dimensions.y * dimensions.z * 1000, mass, level) + , dimensions(dimensions) +{ + this->heat = heat; + this->level = level; +} + +Pool::operator Json::Value() const +{ + Json::Value node = Evaporator::operator Json::Value(); + node["dimensions"]["x"] = dimensions.x; + node["dimensions"]["y"] = dimensions.y; + node["dimensions"]["z"] = dimensions.z; + return node; +} + +double Pool::get_level_height() const +{ + double ratio = level / volume; + return dimensions.z * ratio; +} + diff --git a/src/coolant/pool.hpp b/src/coolant/pool.hpp new file mode 100644 index 0000000..2af58da --- /dev/null +++ b/src/coolant/pool.hpp @@ -0,0 +1,23 @@ + +#include "evaporator.hpp" + +#include + +namespace Sim::Coolant +{ + +class Pool : public Evaporator +{ +public: + + const glm::vec3 dimensions; + + Pool(Fluid fluid, const glm::vec3& dimensions, double temperature, double mass, double level); + Pool(const Json::Value& node); + + operator Json::Value() const; + double get_level_height() const; +}; + +}; + diff --git a/src/graphics/equipment/generator.cpp b/src/graphics/equipment/generator.cpp new file mode 100644 index 0000000..c847cac --- /dev/null +++ b/src/graphics/equipment/generator.cpp @@ -0,0 +1,25 @@ + +#include "generator.hpp" +#include "../../system.hpp" + +#include + +using namespace Sim::Graphics::Equipment; + +Generator::Generator(const Model& model) +{ + g_rotor = model.load("visual_generator_rotor"); +} + +void Generator::remesh_static(Mesh& rmesh) +{ + rmesh.add(g_rotor); +} + +void Generator::get_static_transforms(std::vector& transforms) +{ + Sim::System& sys = *Sim::System::active; + glm::mat4 rot = glm::rotate(glm::mat4(1), (float)sys.loop.generator.get_phase(), glm::vec3(0, 0, 1)); + transforms.push_back(rot); +} + diff --git a/src/graphics/equipment/generator.hpp b/src/graphics/equipment/generator.hpp new file mode 100644 index 0000000..28a8b8f --- /dev/null +++ b/src/graphics/equipment/generator.hpp @@ -0,0 +1,21 @@ + +#pragma once + +#include "../mesh/meshgen.hpp" + +namespace Sim::Graphics::Equipment +{ + +class Generator : public MeshGen +{ + Mesh g_rotor; + +public: + + Generator(const Model& model); + virtual void get_static_transforms(std::vector& transforms); + virtual void remesh_static(Mesh& rmesh); +}; + +}; + diff --git a/src/graphics/equipment/pool.cpp b/src/graphics/equipment/pool.cpp new file mode 100644 index 0000000..d97c255 --- /dev/null +++ b/src/graphics/equipment/pool.cpp @@ -0,0 +1,35 @@ + +#include "pool.hpp" +#include "../../system.hpp" + +#include + +using namespace Sim::Graphics::Equipment; + +Pool::Pool(const Model& model) +{ + g_pool = model.load("visual_water"); +} + +void Pool::remesh_static(Mesh& rmesh) +{ + rmesh.add(g_pool); +} + +void Pool::get_static_transforms(std::vector& transforms) +{ + Sim::System& sys = *Sim::System::active; + double z = sys.pool.get_level_height(); + + if(z > 0.1) + { + transforms.push_back(glm::translate(glm::mat4(1), glm::vec3(0, 0, z - sys.pool.dimensions.z))); + } + + else + { + // hacky solution to prevent z fighting with the bottom of the pool + transforms.push_back(glm::mat4(0)); + } +} + diff --git a/src/graphics/equipment/pool.hpp b/src/graphics/equipment/pool.hpp new file mode 100644 index 0000000..c918dd8 --- /dev/null +++ b/src/graphics/equipment/pool.hpp @@ -0,0 +1,21 @@ + +#pragma once + +#include "../mesh/meshgen.hpp" + +namespace Sim::Graphics::Equipment +{ + +class Pool : public MeshGen +{ + Mesh g_pool; + +public: + + Pool(const Model& model); + virtual void get_static_transforms(std::vector& transforms); + virtual void remesh_static(Mesh& rmesh); +}; + +}; + diff --git a/src/graphics/window.cpp b/src/graphics/window.cpp index 5985e6d..2074112 100644 --- a/src/graphics/window.cpp +++ b/src/graphics/window.cpp @@ -31,6 +31,8 @@ #include "mesh/gllight.hpp" #include "mesh/meshgen.hpp" #include "equipment/reactor.hpp" +#include "equipment/generator.hpp" +#include "equipment/pool.hpp" #include "../system.hpp" #include "../util/streams.hpp" #include "ui.hpp" @@ -53,7 +55,6 @@ static Mesh g_scene; static std::vector g_scene_transforms; static GLMesh gm_scene; -static GLMesh gm_transparent; static GLMesh gm_dynamic_slow[2]; static std::vector lights; @@ -171,8 +172,6 @@ void Window::create() Mesh m_transparent; Model model("../assets", "scene.glb"); - m_transparent = model.load("visual_water"); - m_transparent.bake_transforms(); g_scene.add(model.load("cr")); g_scene.add(model.load("cb")); @@ -195,12 +194,11 @@ void Window::create() monitors.push_back(std::make_unique(model)); monitors.push_back(std::make_unique(model)); equipment.push_back(std::make_unique(model)); + equipment.push_back(std::make_unique(model)); + equipment.push_back(std::make_unique(model)); remesh_static(); - gm_transparent.bind(); - gm_transparent.set(m_transparent, GL_STATIC_DRAW); - glfwShowWindow(win); // setup lighting and prerender shadows @@ -313,7 +311,7 @@ void Window::update(double dt) UI::update(dt); glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo_transforms[ssbo_transforms_at]); - glBufferData(GL_SHADER_STORAGE_BUFFER, transforms.size() * sizeof(transforms[0]), &transforms[0], GL_DYNAMIC_DRAW); + glBufferData(GL_SHADER_STORAGE_BUFFER, transforms.size() * sizeof(transforms[0]), &transforms[0], GL_STREAM_DRAW); ssbo_transforms_at = (ssbo_transforms_at + 1) % SSBO_TRANSFORMS_LEN; if(wait_at++ % 4 == 0) @@ -331,9 +329,6 @@ void Window::render_scene() gm_dynamic_slow[gm_dynamic_slow_at].bind(); gm_dynamic_slow[gm_dynamic_slow_at].render(); - gm_transparent.bind(); - gm_transparent.render(); - Focus::render(); } diff --git a/src/system.cpp b/src/system.cpp index 4a5571b..b7fb2fc 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -41,6 +41,7 @@ System::System() : vessel(Coolant::WATER, 8, 10, 6e6, 5e5, 10), reactor(Reactor::Builder(19, 19, 0.4, 4, Reactor::Fuel::FuelRod(0.5), &vessel, CORE_LAYOUT)), evaporator(Coolant::WATER, 2, 30, 0, 1000), + pool(Coolant::WATER, {16, 32, 11.3}, 16, 1e5, 0), sink(Coolant::WATER, 11, 0, 0), grid(), freight_pump(&sink, &evaporator, 1e5, 1, 1e4, 0.1, 10, Coolant::Pump::mode_t::DST, 1e6), @@ -55,6 +56,7 @@ System::System(const Json::Value& node) : reactor(node["reactor"], &vessel), grid(node["grid"]), evaporator(node["evaporator"]), + pool(node["pool"]), sink(evaporator.fluid, 11, 0, 0), freight_pump(node["pump"]["freight"], &sink, &evaporator), loop(node, &vessel, &evaporator, &grid) @@ -82,6 +84,7 @@ System::operator Json::Value() const node["grid"] = grid; node["vessel"] = vessel; node["evaporator"] = evaporator; + node["pool"] = pool; node["pump"]["freight"] = freight_pump; node["reactor"] = reactor; node["clock"] = clock; diff --git a/src/system.hpp b/src/system.hpp index a6c96db..4b8e24f 100644 --- a/src/system.hpp +++ b/src/system.hpp @@ -8,6 +8,7 @@ #include "reactor/reactor.hpp" #include "electric/grid.hpp" #include "coolant/loop.hpp" +#include "coolant/pool.hpp" namespace Sim { @@ -20,6 +21,7 @@ struct System Reactor::Reactor reactor; Reactor::Coolant::Vessel vessel; Coolant::Evaporator evaporator; + Coolant::Pool pool; Coolant::Pump freight_pump; Coolant::Sink sink; Coolant::Loop loop;