Improve collision
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Sijmen 2021-06-07 01:24:38 +02:00
parent b13be0ebc1
commit 4a56bc5a24
Signed by: vijfhoek
GPG key ID: 82D05C89B28B0DAE
4 changed files with 88 additions and 33 deletions

View file

@ -1,8 +1,14 @@
use cgmath::Point3; use std::ops::Sub;
use cgmath::{Point3, Vector3};
use itertools::Itertools;
type T = f32;
#[derive(Debug)]
pub struct Aabb { pub struct Aabb {
pub min: Point3<f32>, pub min: Point3<T>,
pub max: Point3<f32>, pub max: Point3<T>,
} }
impl Aabb { impl Aabb {
@ -11,6 +17,19 @@ impl Aabb {
&& (self.min.y <= other.max.y && self.max.y >= other.min.y) && (self.min.y <= other.max.y && self.max.y >= other.min.y)
&& (self.min.z <= other.max.z && self.max.z >= other.min.z) && (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),
]
}
} }
impl Default for Aabb { impl Default for Aabb {

View file

@ -1,5 +1,7 @@
use cgmath::{Matrix4, Point3, Rad, Vector3}; use cgmath::{Matrix4, Point3, Rad, Vector3};
use crate::aabb::Aabb;
#[rustfmt::skip] #[rustfmt::skip]
pub const OPENGL_TO_WGPU_MATRIX: Matrix4<f32> = Matrix4::new( pub const OPENGL_TO_WGPU_MATRIX: Matrix4<f32> = Matrix4::new(
1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,

View file

@ -1,6 +1,6 @@
use std::time::Duration; use std::time::Duration;
use cgmath::{InnerSpace, Point3, Rad, Vector3}; use cgmath::{ElementWise, InnerSpace, Point3, Rad, Vector3};
use wgpu::{ use wgpu::{
util::{BufferInitDescriptor, DeviceExt}, util::{BufferInitDescriptor, DeviceExt},
CommandEncoder, SwapChainTexture, CommandEncoder, SwapChainTexture,
@ -11,6 +11,7 @@ use winit::{
}; };
use crate::{ use crate::{
aabb::Aabb,
camera::{Camera, Projection}, camera::{Camera, Projection},
render_context::RenderContext, render_context::RenderContext,
renderable::Renderable, renderable::Renderable,
@ -378,13 +379,24 @@ impl WorldState {
} }
fn check_collision(&self, position: Point3<f32>) -> bool { fn check_collision(&self, position: Point3<f32>) -> bool {
self.world let aabb = Aabb {
.get_block( min: position + Vector3::new(-0.3, -1.8, -0.3),
position.x as isize, max: position + Vector3::new(0.3, 0.0, 0.3),
(position.y - 1.8) as isize, };
position.z as isize,
) for corner in &aabb.get_corners() {
.is_some() let block = self.world.get_block(
corner.x.floor() as isize,
corner.y.floor() as isize,
corner.z.floor() as isize,
);
if block.is_some() {
return true;
}
}
false
} }
fn update_position(&mut self, dt: Duration) { fn update_position(&mut self, dt: Duration) {
@ -393,29 +405,52 @@ impl WorldState {
let speed = 10.0 * (self.sprinting as i32 * 2 + 1) as f32; let speed = 10.0 * (self.sprinting as i32 * 2 + 1) as f32;
let mut new_position = self.camera.position;
let up = Vector3::unit_y() * self.up_speed * speed * dt_seconds;
new_position += up;
if !self.creative && self.check_collision(new_position) {
new_position -= up;
self.up_speed = 0.0;
}
let forward_speed = self.forward_pressed as i32 - self.backward_pressed as i32; let forward_speed = self.forward_pressed as i32 - self.backward_pressed as i32;
let forward = Vector3::new(yaw_cos, 0.0, yaw_sin).normalize(); let forward = Vector3::new(yaw_cos, 0.0, yaw_sin);
let forward = forward * forward_speed as f32 * speed * dt_seconds; let forward = forward * forward_speed as f32;
new_position += forward;
if !self.creative && self.check_collision(new_position) {
new_position -= forward;
}
let right_speed = self.right_pressed as i32 - self.left_pressed as i32; let right_speed = self.right_pressed as i32 - self.left_pressed as i32;
let right = Vector3::new(-yaw_sin, 0.0, yaw_cos).normalize(); let right = Vector3::new(-yaw_sin, 0.0, yaw_cos);
let right = right * right_speed as f32 * speed * dt_seconds; let right = right * right_speed as f32;
new_position += right;
if !self.creative && self.check_collision(new_position) { let mut velocity = forward + right;
new_position -= right; if velocity.magnitude2() > 1.0 {
velocity = velocity.normalize();
}
velocity *= speed * dt.as_secs_f32();
let mut new_position = self.camera.position;
// y component (jumping)
new_position.y += self.up_speed * speed * dt_seconds;
while self.check_collision(new_position) {
self.up_speed = 0.0;
if velocity.y <= -0.0 {
new_position.y = (new_position.y - 1.8).floor() + 2.8;
} else {
new_position.y = (new_position.y - 0.0001).ceil() - 1.0001;
}
}
// x component
new_position.x += velocity.x;
while self.check_collision(new_position) {
if velocity.x <= -0.0 {
new_position.x = (new_position.x - 0.2999).floor() + 1.3;
} else {
new_position.x = (new_position.x + 0.3).ceil() - 1.3001;
}
}
// z component
new_position.z += velocity.z;
while self.check_collision(new_position) {
if velocity.z <= -0.0 {
new_position.z = (new_position.z - 0.2999).floor() + 1.3;
} else {
new_position.z = (new_position.z + 0.3).ceil() - 1.3001;
}
} }
self.camera.position = new_position; self.camera.position = new_position;

View file

@ -10,7 +10,6 @@ use std::{
use crate::{ use crate::{
camera::Camera, camera::Camera,
geometry::GeometryBuffers,
npc::Npc, npc::Npc,
render_context::RenderContext, render_context::RenderContext,
renderable::Renderable, renderable::Renderable,
@ -342,7 +341,7 @@ impl World {
let mut face; let mut face;
while lengths.magnitude() < 100.0 { while lengths.magnitude2() < 100.0_f32.powi(2) {
if lengths.x < lengths.y && lengths.x < lengths.z { if lengths.x < lengths.y && lengths.x < lengths.z {
lengths.x += scale.x; lengths.x += scale.x;
position.x += step.x; position.x += step.x;