physics are hooked up but edge collisions are not working
parent
47e835005b
commit
8e7101dccd
|
@ -1,3 +1,4 @@
|
||||||
|
/quic_server.crt
|
||||||
/target
|
/target
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -8,6 +8,7 @@ use maplit::hashmap;
|
||||||
use opengl_rust::{
|
use opengl_rust::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
gl_state::*,
|
gl_state::*,
|
||||||
|
physics::PhysicsBody,
|
||||||
renderable_model::{
|
renderable_model::{
|
||||||
attributes,
|
attributes,
|
||||||
RenderableModel,
|
RenderableModel,
|
||||||
|
@ -30,6 +31,11 @@ pub const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive (Default)]
|
||||||
|
struct GameState {
|
||||||
|
player: PhysicsBody,
|
||||||
|
}
|
||||||
|
|
||||||
struct GameGraphics {
|
struct GameGraphics {
|
||||||
passes: Vec <Pass>,
|
passes: Vec <Pass>,
|
||||||
|
|
||||||
|
@ -38,6 +44,7 @@ struct GameGraphics {
|
||||||
|
|
||||||
mesh_cube: RenderableModel,
|
mesh_cube: RenderableModel,
|
||||||
mesh_sky: RenderableModel,
|
mesh_sky: RenderableModel,
|
||||||
|
mesh_sphere: RenderableModel,
|
||||||
|
|
||||||
text_stream: TriangleStream,
|
text_stream: TriangleStream,
|
||||||
|
|
||||||
|
@ -53,6 +60,7 @@ impl ShaderLookup for GameGraphics {
|
||||||
impl GameGraphics {
|
impl GameGraphics {
|
||||||
fn draw (
|
fn draw (
|
||||||
&self,
|
&self,
|
||||||
|
state: &GameState,
|
||||||
gl_state: &mut GlState,
|
gl_state: &mut GlState,
|
||||||
) {
|
) {
|
||||||
use uniforms as u;
|
use uniforms as u;
|
||||||
|
@ -71,7 +79,7 @@ impl GameGraphics {
|
||||||
let world_model_mat = Mat4::IDENTITY;
|
let world_model_mat = Mat4::IDENTITY;
|
||||||
|
|
||||||
self.passes [0].with (gl_state, || {
|
self.passes [0].with (gl_state, || {
|
||||||
glezz::clear_color (1.0f32, 0.0f32, 1.0f32, 1.0f32);
|
glezz::clear_color (0.5f32, 0.5f32, 0.5f32, 1.0f32);
|
||||||
glezz::clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT);
|
glezz::clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -80,14 +88,21 @@ impl GameGraphics {
|
||||||
let unis = shader_vars.unis;
|
let unis = shader_vars.unis;
|
||||||
|
|
||||||
{
|
{
|
||||||
let mvp = view_mat * Mat4::IDENTITY;
|
let mvp = view_mat *
|
||||||
|
Mat4::from_translation (state.player.pos) *
|
||||||
|
Mat4::from_scale ((0.5, 0.5, 0.5).into ());
|
||||||
glezz::uniform_matrix_4fv (unis [&u::MVP], &mvp);
|
glezz::uniform_matrix_4fv (unis [&u::MVP], &mvp);
|
||||||
|
|
||||||
//let object_space_light = make_object_space_vec (&inverse_truck, &light);
|
self.mesh_sphere.draw_all (attrs, |_| {
|
||||||
//let object_space_sky = make_object_space_vec (&inverse_truck, &Vec3::from ((0.0, 0.0, 1.0)));
|
true
|
||||||
|
});
|
||||||
//glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &object_space_light);
|
}
|
||||||
//glezz::uniform_3fv (unis [&OBJECT_SPACE_SKY], &object_space_sky);
|
|
||||||
|
{
|
||||||
|
let mvp = view_mat *
|
||||||
|
Mat4::from_scale ((4.0, 4.0, 1.0).into ()) *
|
||||||
|
Mat4::from_translation ((0.0, 0.0, -2.0).into ());
|
||||||
|
glezz::uniform_matrix_4fv (unis [&u::MVP], &mvp);
|
||||||
|
|
||||||
self.mesh_cube.draw_all (attrs, |_| {
|
self.mesh_cube.draw_all (attrs, |_| {
|
||||||
true
|
true
|
||||||
|
@ -104,7 +119,7 @@ impl GameGraphics {
|
||||||
glezz::uniform_3fv (unis [&u::MIN_ALBEDO], &black);
|
glezz::uniform_3fv (unis [&u::MIN_ALBEDO], &black);
|
||||||
glezz::uniform_1i (unis [&u::TEXTURE], 0);
|
glezz::uniform_1i (unis [&u::TEXTURE], 0);
|
||||||
|
|
||||||
self.mesh_sky.draw_all (attrs, |_| true);
|
// self.mesh_sky.draw_all (attrs, |_| true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -169,6 +184,7 @@ async fn main () -> Result <()> {
|
||||||
|
|
||||||
let mesh_cube = renderable_from_iqm_file ("cube.iqm");
|
let mesh_cube = renderable_from_iqm_file ("cube.iqm");
|
||||||
let mesh_sky = renderable_from_iqm_file ("sky-sphere.iqm");
|
let mesh_sky = renderable_from_iqm_file ("sky-sphere.iqm");
|
||||||
|
let mesh_sphere = renderable_from_iqm_file ("sphere.iqm");
|
||||||
|
|
||||||
let passes = vec![
|
let passes = vec![
|
||||||
// Clear everything
|
// Clear everything
|
||||||
|
@ -185,7 +201,7 @@ async fn main () -> Result <()> {
|
||||||
(gl::TEXTURE_2D, true),
|
(gl::TEXTURE_2D, true),
|
||||||
(gl::STENCIL_TEST, false),
|
(gl::STENCIL_TEST, false),
|
||||||
].into_iter ())
|
].into_iter ())
|
||||||
.front_face (FrontFace::Cw)
|
.front_face (FrontFace::Ccw)
|
||||||
.color_mask ([1, 1, 1, 1])
|
.color_mask ([1, 1, 1, 1])
|
||||||
.depth_mask (1)
|
.depth_mask (1)
|
||||||
.clone (),
|
.clone (),
|
||||||
|
@ -221,6 +237,7 @@ async fn main () -> Result <()> {
|
||||||
let graphics = GameGraphics {
|
let graphics = GameGraphics {
|
||||||
mesh_cube,
|
mesh_cube,
|
||||||
mesh_sky,
|
mesh_sky,
|
||||||
|
mesh_sphere,
|
||||||
passes,
|
passes,
|
||||||
shader_lookup,
|
shader_lookup,
|
||||||
shaders,
|
shaders,
|
||||||
|
@ -229,6 +246,35 @@ async fn main () -> Result <()> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut gl_state = Default::default ();
|
let mut gl_state = Default::default ();
|
||||||
|
let mut game_state = GameState::default ();
|
||||||
|
let phys_params = opengl_rust::physics::Params {
|
||||||
|
dt: 1.0 / 60.0,
|
||||||
|
gravity: (0.0, 0.0, -0.25).into (),
|
||||||
|
margin: 0.00125,
|
||||||
|
};
|
||||||
|
let phys_world: Vec <_> = vec! [
|
||||||
|
(
|
||||||
|
(-4.0, -4.0, -1.0),
|
||||||
|
(-4.0, 4.0, -1.0),
|
||||||
|
(4.0, -4.0, -1.0),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
(4.0, 4.0, -1.0),
|
||||||
|
(4.0, -4.0, -1.0),
|
||||||
|
(-4.0, 4.0, -1.0),
|
||||||
|
),
|
||||||
|
].into_iter ()
|
||||||
|
.map (|(v0, v1, v2)| {
|
||||||
|
opengl_rust::physics::Triangle {
|
||||||
|
verts: [
|
||||||
|
v0.into (),
|
||||||
|
v1.into (),
|
||||||
|
v2.into (),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect ();
|
||||||
|
let player_speed = 2.0;
|
||||||
|
|
||||||
'running: loop {
|
'running: loop {
|
||||||
let _frames_to_do = time_step.step ();
|
let _frames_to_do = time_step.step ();
|
||||||
|
@ -239,13 +285,35 @@ async fn main () -> Result <()> {
|
||||||
Event::KeyDown { keycode: Some (Keycode::Escape), .. } => {
|
Event::KeyDown { keycode: Some (Keycode::Escape), .. } => {
|
||||||
break 'running
|
break 'running
|
||||||
},
|
},
|
||||||
|
Event::KeyDown { keycode: Some (Keycode::R), .. } => {
|
||||||
|
game_state = Default::default ();
|
||||||
|
},
|
||||||
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let kb_state = event_pump.keyboard_state ();
|
||||||
|
game_state.player.vel.x = 0.0;
|
||||||
|
game_state.player.vel.y = 0.0;
|
||||||
|
if kb_state.is_scancode_pressed (Scancode::Left) {
|
||||||
|
game_state.player.vel.x -= player_speed;
|
||||||
|
}
|
||||||
|
if kb_state.is_scancode_pressed (Scancode::Right) {
|
||||||
|
game_state.player.vel.x += player_speed;
|
||||||
|
}
|
||||||
|
if kb_state.is_scancode_pressed (Scancode::Up) {
|
||||||
|
game_state.player.vel.y += player_speed;
|
||||||
|
}
|
||||||
|
if kb_state.is_scancode_pressed (Scancode::Down) {
|
||||||
|
game_state.player.vel.y -= player_speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
game_state.player = opengl_rust::physics::step (&phys_params, &phys_world, 0.5, &game_state.player).body;
|
||||||
|
|
||||||
window.gl_make_current (&gl_ctx).unwrap ();
|
window.gl_make_current (&gl_ctx).unwrap ();
|
||||||
|
|
||||||
graphics.draw (&mut gl_state);
|
graphics.draw (&game_state, &mut gl_state);
|
||||||
|
|
||||||
window.gl_swap_window ();
|
window.gl_swap_window ();
|
||||||
graphics_frames += 1;
|
graphics_frames += 1;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use glam::{Vec2, Vec3};
|
use glam::{Vec2, Vec3};
|
||||||
use partial_min_max::{min, max};
|
use partial_min_max::{min, max};
|
||||||
|
|
||||||
#[derive (Debug, PartialEq)]
|
#[derive (Debug, Default, PartialEq)]
|
||||||
pub struct PhysicsBody {
|
pub struct PhysicsBody {
|
||||||
pos: Vec3,
|
pub pos: Vec3,
|
||||||
vel: Vec3,
|
pub vel: Vec3,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive (Debug, PartialEq)]
|
#[derive (Debug, PartialEq)]
|
||||||
|
@ -16,7 +16,7 @@ pub struct PhysicsResult {
|
||||||
|
|
||||||
#[derive (Copy, Clone)]
|
#[derive (Copy, Clone)]
|
||||||
pub struct Triangle {
|
pub struct Triangle {
|
||||||
verts: [Vec3; 3],
|
pub verts: [Vec3; 3],
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vec_min (a: &Vec3, b: &Vec3) -> Vec3 {
|
fn vec_min (a: &Vec3, b: &Vec3) -> Vec3 {
|
||||||
|
@ -193,6 +193,7 @@ pub fn get_candidate (world: &[Triangle], p0: Vec3, p1: Vec3, radius: f32)
|
||||||
|
|
||||||
let denom = (p1 - p0).length ();
|
let denom = (p1 - p0).length ();
|
||||||
let t_times_denom = a_ray.x - discriminant.sqrt ();
|
let t_times_denom = a_ray.x - discriminant.sqrt ();
|
||||||
|
let t = t_times_denom / denom;
|
||||||
|
|
||||||
if t_times_denom < 0.0 || t_times_denom > denom {
|
if t_times_denom < 0.0 || t_times_denom > denom {
|
||||||
// The cylinder is along the line,
|
// The cylinder is along the line,
|
||||||
|
@ -204,11 +205,10 @@ pub fn get_candidate (world: &[Triangle], p0: Vec3, p1: Vec3, radius: f32)
|
||||||
let p_impact_times_denom = p0 * (denom - t_times_denom) + p1 * (t_times_denom);
|
let p_impact_times_denom = p0 * (denom - t_times_denom) + p1 * (t_times_denom);
|
||||||
let p_impact = p_impact_times_denom / denom;
|
let p_impact = p_impact_times_denom / denom;
|
||||||
|
|
||||||
let impact_along_cylinder_times_denom = Vec3::dot (cylinder_axis, p_impact_times_denom);
|
let impact_along_cylinder = Vec3::dot (cylinder_axis, p_impact);
|
||||||
let impact_along_cylinder = impact_along_cylinder_times_denom / denom;
|
|
||||||
let a_along_cylinder = Vec3::dot (cylinder_axis, a);
|
let a_along_cylinder = Vec3::dot (cylinder_axis, a);
|
||||||
|
|
||||||
if impact_along_cylinder_times_denom < a_along_cylinder * denom || impact_along_cylinder_times_denom > Vec3::dot (cylinder_axis, b) * denom
|
if impact_along_cylinder < a_along_cylinder || impact_along_cylinder > Vec3::dot (cylinder_axis, b)
|
||||||
{
|
{
|
||||||
// The infinite cylinder is on the line segment,
|
// The infinite cylinder is on the line segment,
|
||||||
// but the finite cylinder is not.
|
// but the finite cylinder is not.
|
||||||
|
@ -279,12 +279,12 @@ pub fn get_candidate (world: &[Triangle], p0: Vec3, p1: Vec3, radius: f32)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Params {
|
pub struct Params {
|
||||||
dt: f32,
|
pub dt: f32,
|
||||||
gravity: Vec3,
|
pub gravity: Vec3,
|
||||||
margin: f32,
|
pub margin: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn physics_step (
|
pub fn step (
|
||||||
params: &Params, world: &[Triangle],
|
params: &Params, world: &[Triangle],
|
||||||
radius: f32, input: &PhysicsBody,
|
radius: f32, input: &PhysicsBody,
|
||||||
) -> PhysicsResult
|
) -> PhysicsResult
|
||||||
|
@ -447,7 +447,7 @@ mod test {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
] {
|
] {
|
||||||
let a = physics_step (¶ms, &world, radius, &body_before);
|
let a = step (¶ms, &world, radius, &body_before);
|
||||||
|
|
||||||
assert! (a.body.pos.distance_squared (e.body.pos) <= 0.00125);
|
assert! (a.body.pos.distance_squared (e.body.pos) <= 0.00125);
|
||||||
assert! (a.body.vel.distance_squared (e.body.vel) <= 0.00125);
|
assert! (a.body.vel.distance_squared (e.body.vel) <= 0.00125);
|
||||||
|
@ -480,7 +480,7 @@ mod test {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let a = physics_step (¶ms, &world, radius, &body_before);
|
let a = step (¶ms, &world, radius, &body_before);
|
||||||
|
|
||||||
let e = PhysicsResult {
|
let e = PhysicsResult {
|
||||||
body: PhysicsBody {
|
body: PhysicsBody {
|
||||||
|
@ -503,7 +503,7 @@ mod test {
|
||||||
vel: (0.0, 0.0, 0.0).into (),
|
vel: (0.0, 0.0, 0.0).into (),
|
||||||
};
|
};
|
||||||
|
|
||||||
let a = physics_step (¶ms, &world, radius, &body_before);
|
let a = step (¶ms, &world, radius, &body_before);
|
||||||
|
|
||||||
let e = PhysicsResult {
|
let e = PhysicsResult {
|
||||||
body: PhysicsBody {
|
body: PhysicsBody {
|
||||||
|
|
Loading…
Reference in New Issue