diff --git a/src/graphics/camera.cpp b/src/graphics/camera.cpp index 2c4f94d..93f8aec 100644 --- a/src/graphics/camera.cpp +++ b/src/graphics/camera.cpp @@ -4,7 +4,7 @@ #include "camera.hpp" #include "input/keyboard.hpp" -#include "../math.hpp" +#include "../util/math.hpp" #include #include @@ -75,7 +75,11 @@ void camera::update(const system& sys, double dt) velocity.z += 3.5; } - glm::vec<3, double> velocity2 = sys.scene.check_intersect(pos, velocity * dt) / dt; + glm::vec<3, double> normal_last(0); + glm::vec<3, double> velocity2; + + velocity2 = sys.scene.calc_intersect(pos, velocity * dt, normal_last); + velocity2 = sys.scene.calc_intersect(pos + glm::vec<3, double>(0, 0, -1.5), velocity2, normal_last) / dt; pos += velocity2 * dt; on_ground = ((velocity * dt / dt).z != velocity2.z); diff --git a/src/graphics/mesh/font.cpp b/src/graphics/mesh/font.cpp index 846e68d..0db843a 100644 --- a/src/graphics/mesh/font.cpp +++ b/src/graphics/mesh/font.cpp @@ -89,6 +89,8 @@ void font::init() chars[i] = c; } + + FT_Done_FreeType(ft); } void mesh::load_text(const char* text, double size) diff --git a/src/graphics/mesh/glmesh.cpp b/src/graphics/mesh/glmesh.cpp index 9e9b47e..ea8e82a 100644 --- a/src/graphics/mesh/glmesh.cpp +++ b/src/graphics/mesh/glmesh.cpp @@ -73,6 +73,11 @@ void glmesh::set(const mesh& m, int mode) void glmesh::render() { - glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0); + render(GL_TRIANGLES); +} + +void glmesh::render(int type) +{ + glDrawElements(type, size, GL_UNSIGNED_INT, 0); } diff --git a/src/graphics/mesh/glmesh.hpp b/src/graphics/mesh/glmesh.hpp index ff04e6d..b8a2223 100644 --- a/src/graphics/mesh/glmesh.hpp +++ b/src/graphics/mesh/glmesh.hpp @@ -27,6 +27,7 @@ struct glmesh void bind(); void uniform(); void set(const mesh& m, int mode); + void render(int type); void render(); }; diff --git a/src/graphics/mesh/mesh.cpp b/src/graphics/mesh/mesh.cpp index 93a01ca..7f60a12 100644 --- a/src/graphics/mesh/mesh.cpp +++ b/src/graphics/mesh/mesh.cpp @@ -3,7 +3,7 @@ #include "arrays.hpp" #include "../shader.hpp" #include "../camera.hpp" -#include "../../math.hpp" +#include "../../util/math.hpp" #include @@ -95,19 +95,18 @@ bool ray_intersects_triangle(vec3 ray_origin, return false; } -vec3 mesh::check_intersect(vec3 pos, vec3 path) const +bool mesh::check_intersect(vec3 pos, vec3 path) const { double l = glm::length(path); if(l == 0) { - return path; + return false; } vec3 path_n = path / l; - bool intersects = false; - - for(unsigned int i = 0; i < indices.size(); i += 3) + + for(unsigned int i = 0; i < indices.size(); i++) { vec3 v[3] = { vec3(this->vertices[indices[i]].pos), @@ -117,7 +116,7 @@ vec3 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); + double d = glm::dot(normal, path_n); if(d >= 0) continue; @@ -126,12 +125,107 @@ vec3 mesh::check_intersect(vec3 pos, vec3 path) const if(l < glm::length(ipoint - pos)) continue; - intersects = true; - path -= normal * d; - l = glm::length(path); - path_n = path / l; + return true; } + return false; +} + +vec3 mesh::calc_intersect(vec3 pos, vec3 path) const +{ + vec3 normal_last(0); + return calc_intersect(pos, path, normal_last); +} + +static bool calc_intercept_vert(vec3 v[3], vec3 pos, vec3& path, vec3& path_n, vec3& normal_last, double& l) +{ + vec3 ipoint; + vec3 normal = glm::normalize(glm::cross(v[1] - v[0], v[2] - v[0])); + double d = glm::dot(normal, path); + + if(d >= 0) + return false; + if(!ray_intersects_triangle(pos, path_n, v, ipoint)) + return false; + if(l < glm::length(ipoint - pos)) + return false; + + if(normal_last != vec3(0)) + { + vec3 n = glm::cross(normal_last, normal); + + if(glm::length(n) > 0) + { + normal = glm::normalize(glm::cross(glm::cross(normal_last, normal), normal_last)); + d = glm::dot(normal, path); + } + } + + path -= normal * d; + normal_last = normal; + l = glm::length(path); + path_n = path / l; + + return true; +} + +vec3 mesh::calc_intersect(vec3 pos, vec3 path, vec3& normal_last) const +{ + double l = glm::length(path); + + if(l == 0) + { + return path; + } + + vec3 path_n = path / l; + unsigned int i_found = 0; + + for(unsigned int i = 0; i < indices.size(); i += 3) + { + vec3 v[3] = { + vec3(this->vertices[indices[i]].pos), + vec3(this->vertices[indices[i + 1]].pos), + vec3(this->vertices[indices[i + 2]].pos) + }; + + if(calc_intercept_vert(v, pos, path, path_n, normal_last, l)) + { + i_found = i; + } + } +/* + for(unsigned int i = i_found - 1; i >= 0; i--) + { + vec3 v[3] = { + vec3(this->vertices[indices[i]].pos), + vec3(this->vertices[indices[i + 1]].pos), + vec3(this->vertices[indices[i + 2]].pos) + }; + + calc_intercept_vert(v, pos, path, path_n, normal_last, l); + } +*/ return path; } +mesh mesh::to_lines() const +{ + mesh m; + m.vertices = vertices; + + for(int i = 0; i < indices.size(); i += 3) + { + m.indices.push_back(indices[i]); + m.indices.push_back(indices[i + 1]); + m.indices.push_back(indices[i + 1]); + m.indices.push_back(indices[i + 2]); + m.indices.push_back(indices[i]); + 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 115d23e..7c54f5b 100644 --- a/src/graphics/mesh/mesh.hpp +++ b/src/graphics/mesh/mesh.hpp @@ -27,7 +27,10 @@ struct mesh void load_text(const char* text, double size); void add(const mesh& o, glm::mat4 mat); - glm::vec<3, double> check_intersect(glm::vec<3, double> pos, glm::vec<3, double> path) const; + mesh to_lines() 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; template void load_text(const char* header, T& item, double size) diff --git a/src/graphics/window.cpp b/src/graphics/window.cpp index b09996a..15f0cfc 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; +static glmesh MeshScene, MeshCollisionScene; static monitor::vessel MonitorVessel; static monitor::core MonitorCore; @@ -40,7 +40,7 @@ void GLAPIENTRY cb_debug_message(GLenum source, GLenum type, GLuint id, GLenum s } } -void window::create() +void window::create(system& sys) { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); @@ -96,11 +96,14 @@ void window::create() font::init(); shader::init_program(); - mesh rmesh; - rmesh.load_model("../assets", "scene-baked.glb"); + sys.scene.load_model("../assets", "scene-baked.glb"); MeshScene.bind(); - MeshScene.set(rmesh, GL_STATIC_DRAW); + MeshScene.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); MonitorCore.init(); MonitorVessel.init(); @@ -123,6 +126,10 @@ void window::loop(sim::system& sys) MeshScene.uniform(); MeshScene.render(); + MeshCollisionScene.bind(); + MeshCollisionScene.uniform(); + MeshCollisionScene.render(GL_LINES); + MonitorCore.render(sys); MonitorVessel.render(); diff --git a/src/graphics/window.hpp b/src/graphics/window.hpp index 52e2368..f9222d8 100644 --- a/src/graphics/window.hpp +++ b/src/graphics/window.hpp @@ -8,8 +8,8 @@ namespace sim::graphics::window { -void create(); bool should_close(); +void create(sim::system& sys); void loop(sim::system& sys); void destroy(); void close(); diff --git a/src/main.cpp b/src/main.cpp index 68f7277..d7f2a2d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,8 +28,8 @@ unsigned long get_now() int main() { - graphics::window::create(); sim::system sys; + graphics::window::create(sys); long clock = get_now(); diff --git a/src/reactor/builder.cpp b/src/reactor/builder.cpp index 53495b4..87ad129 100644 --- a/src/reactor/builder.cpp +++ b/src/reactor/builder.cpp @@ -3,6 +3,7 @@ #include #include +#include using namespace sim::reactor; @@ -14,31 +15,31 @@ sim::reactor::reactor sim::reactor::builder(const int W, const int H, const doub for(int x = 0; x < W; x++) { char c = lines[y][x]; - rod* r; + std::unique_ptr r; switch(c) { case 'F': - r = new fuel::fuel_rod(fr); + r = fr.clone(); break; case 'C': - r = new control::boron_rod(br); + r = br.clone(); break; case 'G': - r = new control::graphite_rod(); + r = std::make_unique(); break; case 'H': - r = new coolant::heater(); + r = std::make_unique(); break; case 'P': - r = new coolant::pipe(v); + r = std::make_unique(v); break; case ' ': - r = new rod(); + r = std::make_unique(); break; } - arr[y * W + x] = std::unique_ptr(std::move(r)); + arr[y * W + x] = std::move(r); } return reactor(&arr[0], W, H, CW, CH); diff --git a/src/reactor/control/boron_rod.hpp b/src/reactor/control/boron_rod.hpp index a5b59bf..f7347c2 100644 --- a/src/reactor/control/boron_rod.hpp +++ b/src/reactor/control/boron_rod.hpp @@ -15,7 +15,6 @@ class boron_rod : public sim::reactor::coolant::pipe virtual void display(std::ostream& o) const; virtual const char* get_name() const { return "Boron Control Rod"; } - virtual rod* clone() const { return new boron_rod(*this); } virtual glm::vec4 get_colour() const; virtual int get_id() const { return 5; } @@ -30,6 +29,7 @@ public: virtual bool should_display() const { return true; } virtual bool should_select() const { return true; } virtual void update_selected(double a); + virtual std::unique_ptr clone() const { return std::make_unique(*this); } }; } diff --git a/src/reactor/control/graphite_rod.hpp b/src/reactor/control/graphite_rod.hpp index a77b63e..f5b8316 100644 --- a/src/reactor/control/graphite_rod.hpp +++ b/src/reactor/control/graphite_rod.hpp @@ -12,7 +12,6 @@ class graphite_rod : public sim::reactor::rod virtual void display(std::ostream& o) const; virtual const char* get_name() const { return "Graphite Rod"; } - virtual rod* clone() const { return new graphite_rod(*this); }; virtual double get_k(val_t type) const; virtual glm::vec4 get_colour() const; virtual int get_id() const { return 4; } @@ -27,6 +26,7 @@ public: virtual bool should_display() const { return true; } virtual bool should_select() const { return true; } virtual void update_selected(double a); + virtual std::unique_ptr clone() const { return std::make_unique(*this); } }; } diff --git a/src/reactor/coolant/heater.hpp b/src/reactor/coolant/heater.hpp index c906335..75958f0 100644 --- a/src/reactor/coolant/heater.hpp +++ b/src/reactor/coolant/heater.hpp @@ -15,7 +15,6 @@ class heater : public sim::reactor::rod virtual bool has_sensors(val_t t) const { return true; } virtual const char* get_name() const { return "Heater"; } virtual double get_k(val_t type) const { return 0.5; } - virtual rod* clone() const { return new heater(*this); }; virtual int get_id() const { return 3; } public: @@ -24,6 +23,7 @@ public: virtual bool should_display() const { return true; } virtual bool should_select() const { return true; } virtual void update_selected(double a); + virtual std::unique_ptr clone() const { return std::make_unique(*this); } }; }; diff --git a/src/reactor/coolant/pipe.hpp b/src/reactor/coolant/pipe.hpp index 46deb5f..71cd9c1 100644 --- a/src/reactor/coolant/pipe.hpp +++ b/src/reactor/coolant/pipe.hpp @@ -16,7 +16,6 @@ protected: virtual double get_k(sim::reactor::rod::val_t type) const; virtual const char* get_name() const { return "Coolant"; } - virtual rod* clone() const { return new pipe(*this); }; virtual int get_id() const { return 2; } void update_pipe(double secs); @@ -25,6 +24,7 @@ public: pipe(coolant::vessel& v); + virtual std::unique_ptr clone() const { return std::make_unique(*this); } virtual bool should_display() const { return true; } virtual void update(double secs); diff --git a/src/reactor/fuel/fuel_rod.hpp b/src/reactor/fuel/fuel_rod.hpp index 1e1b12d..e2eebb1 100644 --- a/src/reactor/fuel/fuel_rod.hpp +++ b/src/reactor/fuel/fuel_rod.hpp @@ -16,7 +16,6 @@ class fuel_rod : public sim::reactor::rod virtual bool has_sensors(val_t t) const { return true; } virtual const char* get_name() const { return "Fuel"; } - virtual rod* clone() const { return new fuel_rod(*this); }; virtual int get_id() const { return 1; } virtual glm::vec4 get_colour() const; @@ -24,6 +23,7 @@ public: fuel_rod(double fuel); + virtual std::unique_ptr clone() const { return std::make_unique(*this); } virtual bool should_display() const { return true; } virtual void update(double secs); }; diff --git a/src/reactor/reactor.cpp b/src/reactor/reactor.cpp index 73b2a22..71c0a39 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 = new std::unique_ptr[width * height]; + this->rods = std::make_unique[]>(width * height); for(int i = 0; i < size; i++) { @@ -19,14 +19,13 @@ reactor::reactor(std::unique_ptr* rods, int w, int h, double cw, double ch) reactor::reactor(reactor&& o) : cell_width(o.cell_width), cell_height(o.cell_height), width(o.width), height(o.height), size(o.size) { - rods = o.rods; + rods = std::move(o.rods); cursor = o.cursor; - o.rods = nullptr; } reactor::reactor(const reactor& o) : cell_width(o.cell_width), cell_height(o.cell_height), width(o.width), height(o.height), size(o.size) { - rods = new std::unique_ptr[width * height]; + this->rods = std::make_unique[]>(width * height); for(int i = 0; i < size; i++) { @@ -34,14 +33,6 @@ reactor::reactor(const reactor& o) : cell_width(o.cell_width), cell_height(o.cel } } -reactor::~reactor() -{ - if(rods != nullptr) - { - delete[] rods; - } -} - void reactor::update(double secs) { int rods_lookup[size]; diff --git a/src/reactor/reactor.hpp b/src/reactor/reactor.hpp index 55e7e38..7fed016 100644 --- a/src/reactor/reactor.hpp +++ b/src/reactor/reactor.hpp @@ -18,13 +18,12 @@ struct reactor const int height; const int size; - std::unique_ptr* rods; + std::unique_ptr[]> rods; int cursor = 0; reactor(std::unique_ptr* rods, int width, int height, double cell_width, double cell_height); reactor(const reactor& r); reactor(reactor&& r); - ~reactor(); void update(double secs); void update_selected(int v); diff --git a/src/reactor/rod.hpp b/src/reactor/rod.hpp index 755e896..284da37 100644 --- a/src/reactor/rod.hpp +++ b/src/reactor/rod.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace sim::reactor { @@ -21,12 +22,13 @@ public: N_FAST = 2 }; + virtual ~rod() {}; virtual void interact(rod* o, double secs); virtual void update(double secs) { } virtual void add(val_t type, double v); virtual double extract(val_t type, double s, double k, double o); virtual double get(val_t type) const; - virtual rod* clone() const { return new rod(*this); } + virtual std::unique_ptr clone() const { return std::make_unique(*this); } virtual glm::vec4 get_colour() const { return {0, 0, 0, 0}; } virtual int get_id() const { return 0; } diff --git a/src/system.cpp b/src/system.cpp index 7785f24..64b5797 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -33,37 +33,22 @@ system::system() " C C C C " }; - vessel = new reactor::coolant::vessel(8, 10, 300, sim::coolant::WATER); - reactor = new sim::reactor::reactor(sim::reactor::builder(19, 19, 0.25, 8, + vessel = std::make_unique(8, 10, 300, sim::coolant::WATER); + reactor = std::make_unique(sim::reactor::builder(19, 19, 0.25, 8, reactor::fuel::fuel_rod(0.5), - reactor::control::boron_rod(*vessel, 1), - *vessel, layout)); + reactor::control::boron_rod(*vessel.get(), 1), + *vessel.get(), layout)); - valve = new coolant::valve(*vessel, 1, 500); - pump = new coolant::pump(*vessel, 1e4, 15); - - scene.load_model("../assets/model", "scene_collisions.stl"); + valve = std::make_unique>(*vessel.get(), 1, 500); + pump = std::make_unique>(*vessel.get(), 1e4, 15); } system::system(system&& o) { - vessel = o.vessel; - reactor = o.reactor; - valve = o.valve; - pump = o.pump; - - o.vessel = nullptr; - o.reactor = nullptr; - o.valve = nullptr; - o.pump = nullptr; -} - -system::~system() -{ - if(vessel != nullptr) delete vessel; - if(reactor != nullptr) delete reactor; - if(valve != nullptr) delete valve; - if(pump != nullptr) delete pump; + vessel = std::move(o.vessel); + reactor = std::move(o.reactor); + valve = std::move(o.valve); + pump = std::move(o.pump); } void system::update(double dt) diff --git a/src/system.hpp b/src/system.hpp index 36b0f4a..148ea54 100644 --- a/src/system.hpp +++ b/src/system.hpp @@ -14,16 +14,15 @@ namespace sim struct system { - sim::reactor::reactor* reactor; - sim::reactor::coolant::vessel* vessel; - sim::coolant::valve* valve; - sim::coolant::pump* pump; + std::unique_ptr reactor; + std::unique_ptr vessel; + std::unique_ptr> valve; + std::unique_ptr> pump; sim::graphics::mesh scene; system(); system(system&& o); system(const system& o) = delete; - ~system(); void update(double dt); }; diff --git a/src/math.hpp b/src/util/math.hpp similarity index 100% rename from src/math.hpp rename to src/util/math.hpp