Comments and fmt

This commit is contained in:
Joshua Barretto 2019-06-26 11:50:55 +01:00
parent 4a340f69b5
commit 7b7d843d0f
3 changed files with 45 additions and 22 deletions

View File

@ -1,4 +1,4 @@
#![type_length_limit="1652471"] #![type_length_limit = "1652471"]
#![feature( #![feature(
euclidean_division, euclidean_division,
duration_float, duration_float,

View File

@ -159,11 +159,9 @@ impl<'a> System<'a> for Sys {
let player_rad = 0.3; // half-width of the player's AABB let player_rad = 0.3; // half-width of the player's AABB
let player_height = 1.7; let player_height = 1.7;
let dist = 2; let dist = 2; // distance to probe the terrain for collisions
let near_iter = (-dist..=dist) let near_iter = (-dist..=dist)
.map(move |i| (-dist..=dist) .map(move |i| (-dist..=dist).map(move |j| (-dist..=dist).map(move |k| (i, j, k))))
.map(move |j| (-dist..=dist)
.map(move |k| (i, j, k))))
.flatten() .flatten()
.flatten(); .flatten();
@ -194,38 +192,57 @@ impl<'a> System<'a> for Sys {
false false
}; };
on_grounds.remove(entity); on_grounds.remove(entity); // Assume we're in the air - unless we can prove otherwise
pos.0.z -= 0.0001; // To force collision with the floor pos.0.z -= 0.0001; // To force collision with the floor
let mut on_ground = false; let mut on_ground = false;
let mut attempts = 0; let mut attempts = 0; // Don't loop infinitely here
// While the player is colliding with the terrain...
while collision_with(pos.0, near_iter.clone()) && attempts < 32 { while collision_with(pos.0, near_iter.clone()) && attempts < 32 {
// Calculate the player's AABB
let player_aabb = Aabb { let player_aabb = Aabb {
min: pos.0 + Vec3::new(-player_rad, -player_rad, 0.0), min: pos.0 + Vec3::new(-player_rad, -player_rad, 0.0),
max: pos.0 + Vec3::new(player_rad, player_rad, player_height), max: pos.0 + Vec3::new(player_rad, player_rad, player_height),
}; };
// Determine the block that we are colliding with most (based on minimum collision axis)
let (block_pos, block_aabb) = near_iter let (block_pos, block_aabb) = near_iter
.clone() .clone()
// Calculate the block's position in world space
.map(|(i, j, k)| pos.0.map(|e| e.floor() as i32) + Vec3::new(i, j, k)) .map(|(i, j, k)| pos.0.map(|e| e.floor() as i32) + Vec3::new(i, j, k))
// Calculate the AABB of the block
.map(|block_pos| { .map(|block_pos| {
let block_aabb = Aabb { (
min: block_pos.map(|e| e as f32), block_pos,
max: block_pos.map(|e| e as f32) + 1.0, Aabb {
}; min: block_pos.map(|e| e as f32),
max: block_pos.map(|e| e as f32) + 1.0,
(block_pos, block_aabb) },
)
}) })
// Determine whether the block's AABB collides with the player's AABB
.filter(|(_, block_aabb)| block_aabb.collides_with_aabb(player_aabb)) .filter(|(_, block_aabb)| block_aabb.collides_with_aabb(player_aabb))
.filter(|(block_pos, _)| terrain // Make sure the block is actually solid
.get(*block_pos) .filter(|(block_pos, _)| {
.map(|vox| !vox.is_empty()) terrain
.unwrap_or(false)) .get(*block_pos)
.max_by_key(|(_, block_aabb)| ((player_aabb.collision_vector_with_aabb(*block_aabb) / vel.0).map(|e| e.abs()).reduce_partial_min() * 1000.0) as i32) .map(|vox| !vox.is_empty())
.unwrap_or(false)
})
// Find the maximum of the minimum collision axes (this bit is weird, trust me that it works)
.max_by_key(|(_, block_aabb)| {
((player_aabb.collision_vector_with_aabb(*block_aabb) / vel.0)
.map(|e| e.abs())
.reduce_partial_min()
* 1000.0) as i32
})
.expect("Collision detected, but no colliding blocks found!"); .expect("Collision detected, but no colliding blocks found!");
// Find the intrusion vector of the collision
let dir = player_aabb.collision_vector_with_aabb(block_aabb); let dir = player_aabb.collision_vector_with_aabb(block_aabb);
// Determine an appropriate resolution vector (i.e: the minimum distance needed to push out of the block)
let max_axis = dir.map(|e| e.abs()).reduce_partial_min(); let max_axis = dir.map(|e| e.abs()).reduce_partial_min();
let resolve_dir = -dir.map(|e| if e.abs() == max_axis { e } else { 0.0 }); let resolve_dir = -dir.map(|e| if e.abs() == max_axis { e } else { 0.0 });
@ -234,13 +251,17 @@ impl<'a> System<'a> for Sys {
on_ground = true; on_ground = true;
} }
// When the resolution direction is non-vertical, we must be colliding with a wall
// If the space above is free...
if resolve_dir.z == 0.0 if resolve_dir.z == 0.0
&& !collision_with(pos.0 + Vec3::unit_z() * 1.1, near_iter.clone()) && !collision_with(pos.0 + Vec3::unit_z() * 1.1, near_iter.clone())
{ {
// ...block-hop!
pos.0.z = (pos.0.z + 1.0).ceil(); pos.0.z = (pos.0.z + 1.0).ceil();
on_ground = true; on_ground = true;
break; break;
} else { } else {
// Resolve the collision normally
pos.0 += resolve_dir; pos.0 += resolve_dir;
vel.0 = vel vel.0 = vel
.0 .0
@ -252,6 +273,7 @@ impl<'a> System<'a> for Sys {
if on_ground { if on_ground {
on_grounds.insert(entity, OnGround); on_grounds.insert(entity, OnGround);
// If we're not on the ground but the space below us is free, then "snap" to the ground
} else if collision_with(pos.0 - Vec3::unit_z() * 1.0, near_iter.clone()) } else if collision_with(pos.0 - Vec3::unit_z() * 1.0, near_iter.clone())
&& vel.0.z < 0.0 && vel.0.z < 0.0
&& vel.0.z > -1.0 && vel.0.z > -1.0

View File

@ -1,9 +1,9 @@
use client::Client; use client::Client;
use common::vol::ReadVol; use common::vol::{ReadVol, Vox};
use std::f32::consts::PI; use std::f32::consts::PI;
use vek::*; use vek::*;
const NEAR_PLANE: f32 = 0.1; const NEAR_PLANE: f32 = 0.01;
const FAR_PLANE: f32 = 10000.0; const FAR_PLANE: f32 = 10000.0;
const INTERP_TIME: f32 = 0.1; const INTERP_TIME: f32 = 0.1;
@ -40,13 +40,13 @@ impl Camera {
pub fn compute_dependents(&self, client: &Client) -> (Mat4<f32>, Mat4<f32>, Vec3<f32>) { pub fn compute_dependents(&self, client: &Client) -> (Mat4<f32>, Mat4<f32>, Vec3<f32>) {
let dist = { let dist = {
let (start, end) = ( let (start, end) = (
self.focus,
self.focus self.focus
+ (Vec3::new( + (Vec3::new(
-f32::sin(self.ori.x) * f32::cos(self.ori.y), -f32::sin(self.ori.x) * f32::cos(self.ori.y),
-f32::cos(self.ori.x) * f32::cos(self.ori.y), -f32::cos(self.ori.x) * f32::cos(self.ori.y),
f32::sin(self.ori.y), f32::sin(self.ori.y),
) * self.dist), ) * self.dist),
self.focus,
); );
match client match client
@ -55,9 +55,10 @@ impl Camera {
.ray(start, end) .ray(start, end)
.ignore_error() .ignore_error()
.max_iter(500) .max_iter(500)
.until(|b| b.is_empty())
.cast() .cast()
{ {
(d, Ok(Some(_))) => f32::min(d - 1.0, self.dist), (d, Ok(Some(_))) => f32::min(self.dist - d - 0.03, self.dist),
(_, Ok(None)) => self.dist, (_, Ok(None)) => self.dist,
(_, Err(_)) => self.dist, (_, Err(_)) => self.dist,
} }