physics are hooked up but edge collisions are not working

main
_ 2021-12-18 23:03:02 +00:00
parent 47e835005b
commit 8e7101dccd
5 changed files with 93 additions and 24 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
/quic_server.crt
/target
**/*.rs.bk

BIN
cube.iqm Normal file

Binary file not shown.

BIN
sphere.iqm Normal file

Binary file not shown.

View File

@ -8,6 +8,7 @@ use maplit::hashmap;
use opengl_rust::{
prelude::*,
gl_state::*,
physics::PhysicsBody,
renderable_model::{
attributes,
RenderableModel,
@ -30,6 +31,11 @@ pub const
}
}
#[derive (Default)]
struct GameState {
player: PhysicsBody,
}
struct GameGraphics {
passes: Vec <Pass>,
@ -38,6 +44,7 @@ struct GameGraphics {
mesh_cube: RenderableModel,
mesh_sky: RenderableModel,
mesh_sphere: RenderableModel,
text_stream: TriangleStream,
@ -53,6 +60,7 @@ impl ShaderLookup for GameGraphics {
impl GameGraphics {
fn draw (
&self,
state: &GameState,
gl_state: &mut GlState,
) {
use uniforms as u;
@ -71,7 +79,7 @@ impl GameGraphics {
let world_model_mat = Mat4::IDENTITY;
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);
});
@ -80,14 +88,21 @@ impl GameGraphics {
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);
//let object_space_light = make_object_space_vec (&inverse_truck, &light);
//let object_space_sky = make_object_space_vec (&inverse_truck, &Vec3::from ((0.0, 0.0, 1.0)));
//glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &object_space_light);
//glezz::uniform_3fv (unis [&OBJECT_SPACE_SKY], &object_space_sky);
self.mesh_sphere.draw_all (attrs, |_| {
true
});
}
{
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, |_| {
true
@ -104,7 +119,7 @@ impl GameGraphics {
glezz::uniform_3fv (unis [&u::MIN_ALBEDO], &black);
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_sky = renderable_from_iqm_file ("sky-sphere.iqm");
let mesh_sphere = renderable_from_iqm_file ("sphere.iqm");
let passes = vec![
// Clear everything
@ -185,7 +201,7 @@ async fn main () -> Result <()> {
(gl::TEXTURE_2D, true),
(gl::STENCIL_TEST, false),
].into_iter ())
.front_face (FrontFace::Cw)
.front_face (FrontFace::Ccw)
.color_mask ([1, 1, 1, 1])
.depth_mask (1)
.clone (),
@ -221,6 +237,7 @@ async fn main () -> Result <()> {
let graphics = GameGraphics {
mesh_cube,
mesh_sky,
mesh_sphere,
passes,
shader_lookup,
shaders,
@ -229,6 +246,35 @@ async fn main () -> Result <()> {
};
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 {
let _frames_to_do = time_step.step ();
@ -239,13 +285,35 @@ async fn main () -> Result <()> {
Event::KeyDown { keycode: Some (Keycode::Escape), .. } => {
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 ();
graphics.draw (&mut gl_state);
graphics.draw (&game_state, &mut gl_state);
window.gl_swap_window ();
graphics_frames += 1;

View File

@ -1,10 +1,10 @@
use glam::{Vec2, Vec3};
use partial_min_max::{min, max};
#[derive (Debug, PartialEq)]
#[derive (Debug, Default, PartialEq)]
pub struct PhysicsBody {
pos: Vec3,
vel: Vec3,
pub pos: Vec3,
pub vel: Vec3,
}
#[derive (Debug, PartialEq)]
@ -16,7 +16,7 @@ pub struct PhysicsResult {
#[derive (Copy, Clone)]
pub struct Triangle {
verts: [Vec3; 3],
pub verts: [Vec3; 3],
}
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 t_times_denom = a_ray.x - discriminant.sqrt ();
let t = t_times_denom / denom;
if t_times_denom < 0.0 || t_times_denom > denom {
// 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 = p_impact_times_denom / denom;
let impact_along_cylinder_times_denom = Vec3::dot (cylinder_axis, p_impact_times_denom);
let impact_along_cylinder = impact_along_cylinder_times_denom / denom;
let impact_along_cylinder = Vec3::dot (cylinder_axis, p_impact);
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,
// 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 {
dt: f32,
gravity: Vec3,
margin: f32,
pub dt: f32,
pub gravity: Vec3,
pub margin: f32,
}
pub fn physics_step (
pub fn step (
params: &Params, world: &[Triangle],
radius: f32, input: &PhysicsBody,
) -> PhysicsResult
@ -447,7 +447,7 @@ mod test {
},
),
] {
let a = physics_step (&params, &world, radius, &body_before);
let a = step (&params, &world, radius, &body_before);
assert! (a.body.pos.distance_squared (e.body.pos) <= 0.00125);
assert! (a.body.vel.distance_squared (e.body.vel) <= 0.00125);
@ -480,7 +480,7 @@ mod test {
},
);
let a = physics_step (&params, &world, radius, &body_before);
let a = step (&params, &world, radius, &body_before);
let e = PhysicsResult {
body: PhysicsBody {
@ -503,7 +503,7 @@ mod test {
vel: (0.0, 0.0, 0.0).into (),
};
let a = physics_step (&params, &world, radius, &body_before);
let a = step (&params, &world, radius, &body_before);
let e = PhysicsResult {
body: PhysicsBody {