🦀 collision detection bugs are gone 🦀
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
191f9b1f28
commit
6794213f7d
4 changed files with 64 additions and 26 deletions
44
src/aabb.rs
44
src/aabb.rs
|
@ -1,11 +1,9 @@
|
|||
use cgmath::Point3;
|
||||
|
||||
type T = f32;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Aabb {
|
||||
pub min: Point3<T>,
|
||||
pub max: Point3<T>,
|
||||
pub min: Point3<f32>,
|
||||
pub max: Point3<f32>,
|
||||
}
|
||||
|
||||
impl Aabb {
|
||||
|
@ -15,17 +13,33 @@ impl Aabb {
|
|||
&& (self.min.z <= other.max.z && self.max.z >= other.min.z)
|
||||
}
|
||||
|
||||
pub fn get_corners(&self) -> [Point3<T>; 8] {
|
||||
[
|
||||
Point3::new(self.min.x, self.min.y, self.min.z),
|
||||
Point3::new(self.min.x, self.min.y, self.max.z),
|
||||
Point3::new(self.min.x, self.max.y, self.min.z),
|
||||
Point3::new(self.min.x, self.max.y, self.max.z),
|
||||
Point3::new(self.max.x, self.min.y, self.min.z),
|
||||
Point3::new(self.max.x, self.min.y, self.max.z),
|
||||
Point3::new(self.max.x, self.max.y, self.min.z),
|
||||
Point3::new(self.max.x, self.max.y, self.max.z),
|
||||
]
|
||||
/// Gets the corners of the AABB that should be checked when checking
|
||||
/// collision with the world.
|
||||
///
|
||||
/// Returns a `Vec` of all `Point3`s that cover the faces of `self` with
|
||||
/// no more than 1 unit of distance between them.
|
||||
pub fn get_corners(&self) -> Vec<Point3<f32>> {
|
||||
let mut corners = Vec::new();
|
||||
|
||||
let mut x = self.min.x;
|
||||
while x < self.max.x.ceil() {
|
||||
let mut y = self.min.y;
|
||||
while y < self.max.y.ceil() {
|
||||
let mut z = self.min.z;
|
||||
while z < self.max.z.ceil() {
|
||||
corners.push(Point3::new(
|
||||
x.min(self.max.x),
|
||||
y.min(self.max.y),
|
||||
z.min(self.max.z),
|
||||
));
|
||||
z += 1.0;
|
||||
}
|
||||
y += 1.0;
|
||||
}
|
||||
x += 1.0;
|
||||
}
|
||||
|
||||
corners
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ mod time;
|
|||
mod vertex;
|
||||
mod view;
|
||||
mod world;
|
||||
mod utils;
|
||||
|
||||
use std::time::{Duration, Instant};
|
||||
use wgpu::SwapChainError;
|
||||
|
|
|
@ -17,6 +17,7 @@ use crate::{
|
|||
renderable::Renderable,
|
||||
texture::{Texture, TextureManager},
|
||||
time::Time,
|
||||
utils,
|
||||
vertex::{BlockVertex, Vertex},
|
||||
view::View,
|
||||
world::World,
|
||||
|
@ -408,35 +409,38 @@ impl WorldState {
|
|||
None
|
||||
}
|
||||
|
||||
/// Updates the player's position by their velocity, checks for and
|
||||
/// resolves any subsequent collisions, and then adds the jumping speed to
|
||||
/// the velocity.
|
||||
fn update_position(&mut self, dt: Duration) {
|
||||
let dt_seconds = dt.as_secs_f32();
|
||||
let (yaw_sin, yaw_cos) = self.camera.yaw.0.sin_cos();
|
||||
|
||||
let speed = 10.0 * (self.sprinting as i32 * 2 + 1) as f32;
|
||||
let speed = 10.0 * (self.sprinting as i32 * 2 + 1) as f32 * dt.as_secs_f32();
|
||||
|
||||
let forward_speed = self.forward_pressed as i32 - self.backward_pressed as i32;
|
||||
let forward = Vector3::new(yaw_cos, 0.0, yaw_sin);
|
||||
let forward = forward * forward_speed as f32;
|
||||
let forward = Vector3::new(yaw_cos, 0.0, yaw_sin) * forward_speed as f32;
|
||||
|
||||
let right_speed = self.right_pressed as i32 - self.left_pressed as i32;
|
||||
let right = Vector3::new(-yaw_sin, 0.0, yaw_cos);
|
||||
let right = right * right_speed as f32;
|
||||
let right = Vector3::new(-yaw_sin, 0.0, yaw_cos) * right_speed as f32;
|
||||
|
||||
let mut velocity = forward + right;
|
||||
if velocity.magnitude2() > 1.0 {
|
||||
velocity = velocity.normalize();
|
||||
}
|
||||
velocity *= speed * dt.as_secs_f32();
|
||||
velocity *= speed;
|
||||
velocity.y = self.up_speed * 10.0 * dt.as_secs_f32();
|
||||
|
||||
let mut new_position = self.camera.position;
|
||||
|
||||
// y component (jumping)
|
||||
new_position.y += self.up_speed * speed * dt_seconds;
|
||||
new_position.y += velocity.y;
|
||||
if let Some(aabb) = self.check_collision(new_position) {
|
||||
if self.up_speed < 0.0 {
|
||||
new_position.y = aabb.min.y.ceil() + 1.62;
|
||||
new_position.y = utils::f32_successor(new_position.y);
|
||||
} else if self.up_speed > 0.0 {
|
||||
new_position.y = aabb.max.y.floor() - 0.1801;
|
||||
new_position.y = aabb.max.y.floor() - 0.18;
|
||||
new_position.y = utils::f32_predecessor(new_position.y);
|
||||
}
|
||||
|
||||
self.up_speed = 0.0;
|
||||
|
@ -447,8 +451,10 @@ impl WorldState {
|
|||
if let Some(aabb) = self.check_collision(new_position) {
|
||||
if velocity.x < 0.0 {
|
||||
new_position.x = aabb.min.x.ceil() + 0.3;
|
||||
new_position.x = utils::f32_successor(new_position.x);
|
||||
} else if velocity.x > 0.0 {
|
||||
new_position.x = aabb.max.x.floor() - 0.3001;
|
||||
new_position.x = aabb.max.x.floor() - 0.3;
|
||||
new_position.x = utils::f32_predecessor(new_position.x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -457,8 +463,10 @@ impl WorldState {
|
|||
if let Some(aabb) = self.check_collision(new_position) {
|
||||
if velocity.z < 0.0 {
|
||||
new_position.z = aabb.min.z.ceil() + 0.3;
|
||||
new_position.z = utils::f32_successor(new_position.z);
|
||||
} else if velocity.z > 0.0 {
|
||||
new_position.z = aabb.max.z.floor() - 0.3001;
|
||||
new_position.z = aabb.max.z.floor() - 0.3;
|
||||
new_position.z = utils::f32_predecessor(new_position.z);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
15
src/utils.rs
Normal file
15
src/utils.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
/// Returns `x` incremented with the lowest possible value that a
|
||||
/// single-precision floating point with `x`'s value can represent.
|
||||
pub fn f32_successor(x: f32) -> f32 {
|
||||
let x = x.to_bits();
|
||||
let x = if (x >> 31) == 0 { x + 1 } else { x - 1 };
|
||||
f32::from_bits(x)
|
||||
}
|
||||
|
||||
/// Returns `x` decremented with the lowest possible value that a
|
||||
/// single-precision floating point with `x`'s value can represent.
|
||||
pub fn f32_predecessor(x: f32) -> f32 {
|
||||
let x = x.to_bits();
|
||||
let x = if (x >> 31) == 0 { x - 1 } else { x + 1 };
|
||||
f32::from_bits(x)
|
||||
}
|
Loading…
Reference in a new issue