added a proper collision system
This commit is contained in:
parent
853c8dde3d
commit
b0ebc29a29
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
using namespace sim::graphics;
|
using namespace sim::graphics;
|
||||||
|
|
||||||
|
static bool on_ground = false;
|
||||||
static double yaw = 0, pitch = 0;
|
static double yaw = 0, pitch = 0;
|
||||||
static glm::vec<3, double> pos(0, 0, 2);
|
static glm::vec<3, double> pos(0, 0, 2);
|
||||||
static glm::vec<3, double> velocity(0);
|
static glm::vec<3, double> velocity(0);
|
||||||
|
@ -35,7 +36,7 @@ void camera::move(double xoff, double yoff, double zoff)
|
||||||
pos.z += zoff;
|
pos.z += zoff;
|
||||||
}
|
}
|
||||||
|
|
||||||
void camera::update(double dt)
|
void camera::update(const system& sys, double dt)
|
||||||
{
|
{
|
||||||
glm::vec<2, double> off(0, 0);
|
glm::vec<2, double> off(0, 0);
|
||||||
double m = 30;
|
double m = 30;
|
||||||
|
@ -61,46 +62,24 @@ void camera::update(double dt)
|
||||||
};
|
};
|
||||||
|
|
||||||
glm::vec<2, double> rotated = glm::vec<2, double>(off.x, off.y) * mat;
|
glm::vec<2, double> rotated = glm::vec<2, double>(off.x, off.y) * mat;
|
||||||
bool on_ground = false;
|
|
||||||
|
|
||||||
velocity.z -= 9.81 * dt;
|
velocity.z -= 9.81 * dt;
|
||||||
|
|
||||||
if(pos.z + velocity.z * dt < 1.6)
|
if(on_ground)
|
||||||
{
|
{
|
||||||
on_ground = true;
|
velocity.x += rotated.x * m * dt;
|
||||||
|
velocity.y += rotated.y * m * dt;
|
||||||
if(keyboard::is_pressed(GLFW_KEY_SPACE))
|
|
||||||
{
|
|
||||||
velocity.z = 3.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
velocity.z = 0;
|
|
||||||
pos.z = 1.6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
velocity.x += rotated.x * m * dt;
|
if(on_ground && keyboard::is_pressed(GLFW_KEY_SPACE))
|
||||||
velocity.y += rotated.y * m * dt;
|
{
|
||||||
|
velocity.z += 3.5;
|
||||||
|
}
|
||||||
|
|
||||||
double nx = pos.x + velocity.x * dt;
|
glm::vec<3, double> velocity2 = sys.scene.check_intersect(pos, velocity * dt) / dt;
|
||||||
double ny = pos.y + velocity.y * dt;
|
|
||||||
|
|
||||||
if(nx > 8.9 || nx < -2.9)
|
pos += velocity2 * dt;
|
||||||
velocity.x = 0;
|
on_ground = ((velocity * dt / dt).z != velocity2.z);
|
||||||
if(std::abs(ny) > 3.9)
|
velocity = velocity2 * std::pow(0.5, dt / (on_ground ? 0.05 : 10));
|
||||||
velocity.y = 0;
|
|
||||||
|
|
||||||
float m2 = std::pow(0.5, dt / (on_ground ? 0.05 : 1));
|
|
||||||
|
|
||||||
pos += velocity * dt;
|
|
||||||
velocity *= m2;
|
|
||||||
|
|
||||||
camera_mat = glm::mat4(1);
|
camera_mat = glm::mat4(1);
|
||||||
camera_mat = glm::rotate(camera_mat, (float)glm::radians(-pitch), glm::vec3(1, 0, 0));
|
camera_mat = glm::rotate(camera_mat, (float)glm::radians(-pitch), glm::vec3(1, 0, 0));
|
||||||
|
|
|
@ -4,13 +4,15 @@
|
||||||
#include <glm/matrix.hpp>
|
#include <glm/matrix.hpp>
|
||||||
#include <glm/vec3.hpp>
|
#include <glm/vec3.hpp>
|
||||||
|
|
||||||
|
#include "../system.hpp"
|
||||||
|
|
||||||
namespace sim::graphics::camera
|
namespace sim::graphics::camera
|
||||||
{
|
{
|
||||||
|
|
||||||
glm::mat4 get_matrix();
|
glm::mat4 get_matrix();
|
||||||
void rotate(double pitch, double yaw);
|
void rotate(double pitch, double yaw);
|
||||||
void move(double x, double y, double z);
|
void move(double x, double y, double z);
|
||||||
void update(double dt);
|
void update(const system& sys, double dt);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
#include "arrays.hpp"
|
#include "arrays.hpp"
|
||||||
#include "../shader.hpp"
|
#include "../shader.hpp"
|
||||||
#include "../camera.hpp"
|
#include "../camera.hpp"
|
||||||
|
#include "../../math.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
using namespace sim::graphics;
|
using namespace sim::graphics;
|
||||||
|
|
||||||
|
@ -50,3 +53,85 @@ void mesh::set_indices(const unsigned int* data, size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef glm::vec<3, double> vec3;
|
||||||
|
|
||||||
|
bool ray_intersects_triangle(vec3 ray_origin,
|
||||||
|
vec3 ray_vector,
|
||||||
|
const vec3* triangle,
|
||||||
|
vec3& out_intersection_point)
|
||||||
|
{
|
||||||
|
constexpr double epsilon = std::numeric_limits<double>::epsilon();
|
||||||
|
|
||||||
|
vec3 edge1 = triangle[1] - triangle[0];
|
||||||
|
vec3 edge2 = triangle[2] - triangle[0];
|
||||||
|
vec3 ray_cross_e2 = cross(ray_vector, edge2);
|
||||||
|
double det = dot(edge1, ray_cross_e2);
|
||||||
|
|
||||||
|
if (det > -epsilon && det < epsilon)
|
||||||
|
return false; // This ray is parallel to this triangle.
|
||||||
|
|
||||||
|
double inv_det = 1.0 / det;
|
||||||
|
vec3 s = ray_origin - triangle[0];
|
||||||
|
double u = inv_det * dot(s, ray_cross_e2);
|
||||||
|
|
||||||
|
if (u < 0 || u > 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
vec3 s_cross_e1 = cross(s, edge1);
|
||||||
|
double v = inv_det * dot(ray_vector, s_cross_e1);
|
||||||
|
|
||||||
|
if (v < 0 || u + v > 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// At this stage we can compute t to find out where the intersection point is on the line.
|
||||||
|
double t = inv_det * dot(edge2, s_cross_e1);
|
||||||
|
out_intersection_point = ray_origin + ray_vector * t;
|
||||||
|
|
||||||
|
if (t > epsilon) // ray intersection
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else // This means that there is a line intersection but not a ray intersection.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 mesh::check_intersect(vec3 pos, vec3 path) const
|
||||||
|
{
|
||||||
|
double l = glm::length(path);
|
||||||
|
|
||||||
|
if(l == 0)
|
||||||
|
{
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 path_n = path / l;
|
||||||
|
bool intersects = false;
|
||||||
|
|
||||||
|
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)
|
||||||
|
};
|
||||||
|
|
||||||
|
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)
|
||||||
|
continue;
|
||||||
|
if(!ray_intersects_triangle(pos, path_n, v, ipoint))
|
||||||
|
continue;
|
||||||
|
if(l < glm::length(ipoint - pos))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
intersects = true;
|
||||||
|
path -= normal * d;
|
||||||
|
l = glm::length(path);
|
||||||
|
path_n = path / l;
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@ struct mesh
|
||||||
void load_text(const char* text, double size);
|
void load_text(const char* text, double size);
|
||||||
void add(const mesh& o, glm::mat4 mat);
|
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;
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void load_text(const char* header, T& item, double size)
|
void load_text(const char* header, T& item, double size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include "coolant/valve.hpp"
|
#include "coolant/valve.hpp"
|
||||||
#include "coolant/pump.hpp"
|
#include "coolant/pump.hpp"
|
||||||
|
|
||||||
|
#include "graphics/mesh/mesh.hpp"
|
||||||
|
|
||||||
#include "graphics/window.hpp"
|
#include "graphics/window.hpp"
|
||||||
#include "graphics/camera.hpp"
|
#include "graphics/camera.hpp"
|
||||||
|
|
||||||
|
@ -39,7 +41,7 @@ int main()
|
||||||
clock += passed;
|
clock += passed;
|
||||||
|
|
||||||
sys.update(dt);
|
sys.update(dt);
|
||||||
graphics::camera::update(dt);
|
graphics::camera::update(sys, dt);
|
||||||
graphics::window::loop(sys);
|
graphics::window::loop(sys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,8 @@ system::system()
|
||||||
|
|
||||||
valve = new coolant::valve<reactor::coolant::vessel>(*vessel, 1, 500);
|
valve = new coolant::valve<reactor::coolant::vessel>(*vessel, 1, 500);
|
||||||
pump = new coolant::pump<reactor::coolant::vessel>(*vessel, 1e4, 15);
|
pump = new coolant::pump<reactor::coolant::vessel>(*vessel, 1e4, 15);
|
||||||
|
|
||||||
|
scene.load_model("../assets/model", "scene_collisions.stl");
|
||||||
}
|
}
|
||||||
|
|
||||||
system::system(system&& o)
|
system::system(system&& o)
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "reactor/reactor.hpp"
|
#include "reactor/reactor.hpp"
|
||||||
#include "coolant/pump.hpp"
|
#include "coolant/pump.hpp"
|
||||||
#include "coolant/valve.hpp"
|
#include "coolant/valve.hpp"
|
||||||
|
#include "graphics/mesh/mesh.hpp"
|
||||||
|
|
||||||
namespace sim
|
namespace sim
|
||||||
{
|
{
|
||||||
|
@ -17,6 +18,7 @@ struct system
|
||||||
sim::reactor::coolant::vessel* vessel;
|
sim::reactor::coolant::vessel* vessel;
|
||||||
sim::coolant::valve<sim::reactor::coolant::vessel>* valve;
|
sim::coolant::valve<sim::reactor::coolant::vessel>* valve;
|
||||||
sim::coolant::pump<sim::reactor::coolant::vessel>* pump;
|
sim::coolant::pump<sim::reactor::coolant::vessel>* pump;
|
||||||
|
sim::graphics::mesh scene;
|
||||||
|
|
||||||
system();
|
system();
|
||||||
system(system&& o);
|
system(system&& o);
|
||||||
|
|
Loading…
Reference in New Issue