mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Comments and fmt
This commit is contained in:
parent
4a340f69b5
commit
7b7d843d0f
@ -1,4 +1,4 @@
|
|||||||
#![type_length_limit="1652471"]
|
#![type_length_limit = "1652471"]
|
||||||
#![feature(
|
#![feature(
|
||||||
euclidean_division,
|
euclidean_division,
|
||||||
duration_float,
|
duration_float,
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user