added a proper collision system
This commit is contained in:
parent
853c8dde3d
commit
b0ebc29a29
|
@ -14,6 +14,7 @@
|
|||
|
||||
using namespace sim::graphics;
|
||||
|
||||
static bool on_ground = false;
|
||||
static double yaw = 0, pitch = 0;
|
||||
static glm::vec<3, double> pos(0, 0, 2);
|
||||
static glm::vec<3, double> velocity(0);
|
||||
|
@ -35,7 +36,7 @@ void camera::move(double xoff, double yoff, double zoff)
|
|||
pos.z += zoff;
|
||||
}
|
||||
|
||||
void camera::update(double dt)
|
||||
void camera::update(const system& sys, double dt)
|
||||
{
|
||||
glm::vec<2, double> off(0, 0);
|
||||
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;
|
||||
bool on_ground = false;
|
||||
|
||||
velocity.z -= 9.81 * dt;
|
||||
|
||||
if(pos.z + velocity.z * dt < 1.6)
|
||||
if(on_ground)
|
||||
{
|
||||
on_ground = true;
|
||||
|
||||
if(keyboard::is_pressed(GLFW_KEY_SPACE))
|
||||
{
|
||||
velocity.z = 3.5;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
velocity.z = 0;
|
||||
pos.z = 1.6;
|
||||
}
|
||||
velocity.x += rotated.x * m * dt;
|
||||
velocity.y += rotated.y * m * dt;
|
||||
}
|
||||
|
||||
else
|
||||
if(on_ground && keyboard::is_pressed(GLFW_KEY_SPACE))
|
||||
{
|
||||
m = 0;
|
||||
velocity.z += 3.5;
|
||||
}
|
||||
|
||||
velocity.x += rotated.x * m * dt;
|
||||
velocity.y += rotated.y * m * dt;
|
||||
glm::vec<3, double> velocity2 = sys.scene.check_intersect(pos, velocity * dt) / dt;
|
||||
|
||||
double nx = pos.x + velocity.x * dt;
|
||||
double ny = pos.y + velocity.y * dt;
|
||||
|
||||
if(nx > 8.9 || nx < -2.9)
|
||||
velocity.x = 0;
|
||||
if(std::abs(ny) > 3.9)
|
||||
velocity.y = 0;
|
||||
|
||||
float m2 = std::pow(0.5, dt / (on_ground ? 0.05 : 1));
|
||||
|
||||
pos += velocity * dt;
|
||||
velocity *= m2;
|
||||
pos += velocity2 * dt;
|
||||
on_ground = ((velocity * dt / dt).z != velocity2.z);
|
||||
velocity = velocity2 * std::pow(0.5, dt / (on_ground ? 0.05 : 10));
|
||||
|
||||
camera_mat = glm::mat4(1);
|
||||
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/vec3.hpp>
|
||||
|
||||
#include "../system.hpp"
|
||||
|
||||
namespace sim::graphics::camera
|
||||
{
|
||||
|
||||
glm::mat4 get_matrix();
|
||||
void rotate(double pitch, double yaw);
|
||||
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 "../shader.hpp"
|
||||
#include "../camera.hpp"
|
||||
#include "../../math.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
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 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>
|
||||
void load_text(const char* header, T& item, double size)
|
||||
{
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "coolant/valve.hpp"
|
||||
#include "coolant/pump.hpp"
|
||||
|
||||
#include "graphics/mesh/mesh.hpp"
|
||||
|
||||
#include "graphics/window.hpp"
|
||||
#include "graphics/camera.hpp"
|
||||
|
||||
|
@ -39,7 +41,7 @@ int main()
|
|||
clock += passed;
|
||||
|
||||
sys.update(dt);
|
||||
graphics::camera::update(dt);
|
||||
graphics::camera::update(sys, dt);
|
||||
graphics::window::loop(sys);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@ system::system()
|
|||
|
||||
valve = new coolant::valve<reactor::coolant::vessel>(*vessel, 1, 500);
|
||||
pump = new coolant::pump<reactor::coolant::vessel>(*vessel, 1e4, 15);
|
||||
|
||||
scene.load_model("../assets/model", "scene_collisions.stl");
|
||||
}
|
||||
|
||||
system::system(system&& o)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "reactor/reactor.hpp"
|
||||
#include "coolant/pump.hpp"
|
||||
#include "coolant/valve.hpp"
|
||||
#include "graphics/mesh/mesh.hpp"
|
||||
|
||||
namespace sim
|
||||
{
|
||||
|
@ -17,6 +18,7 @@ struct system
|
|||
sim::reactor::coolant::vessel* vessel;
|
||||
sim::coolant::valve<sim::reactor::coolant::vessel>* valve;
|
||||
sim::coolant::pump<sim::reactor::coolant::vessel>* pump;
|
||||
sim::graphics::mesh scene;
|
||||
|
||||
system();
|
||||
system(system&& o);
|
||||
|
|
Loading…
Reference in New Issue