Added configurable details

This commit is contained in:
Joshua Barretto 2019-06-26 01:28:30 +01:00
parent 0d984a5671
commit ae168711d7

View File

@ -156,19 +156,26 @@ impl<'a> System<'a> for Sys {
vel.0 = integrate_forces(dt.0, vel.0, friction);
// Basic collision with terrain
let player_rad = 0.3; // half-width of the player's AABB
let player_height = 1.7;
// Iterate through nearby blocks, prioritise closer ones
let near_iter = (0..5)
.map(move |dist| (-dist..=dist)
.map(move |x| (-dist..=dist)
.map(move |y| (-dist..=dist)
.map(move |z| Vec3::new(x, y, z))
.filter(move |p| p.map(|e: i32| e.abs()).reduce_max() == dist)
.map(|p| p.into_tuple()))))
.map(move |dist| {
(-dist..=dist).map(move |x| {
(-dist..=dist).map(move |y| {
(-dist..=dist)
.map(move |z| Vec3::new(x, y, z))
.filter(move |p| p.map(|e: i32| e.abs()).reduce_max() == dist)
.map(|p| p.into_tuple())
})
})
})
.flatten()
.flatten()
.flatten();
// Function for determining whether the player at a specific position collides with the ground
let collision_with = |pos: Vec3<f32>, near_iter| {
for (i, j, k) in near_iter {
let block_pos = pos.map(|e| e.floor() as i32) + Vec3::new(i, j, k);
@ -178,8 +185,14 @@ impl<'a> System<'a> for Sys {
.map(|vox| !vox.is_empty())
.unwrap_or(false)
{
let this_aabb = Aabb { min: pos + Vec3::new(-0.3, -0.3, 0.0), max: pos + Vec3::new(0.3, 0.3, 1.7) };
let block_aabb = Aabb { min: block_pos.map(|e| e as f32), max: block_pos.map(|e| e as f32) + 1.0 };
let this_aabb = Aabb {
min: pos + Vec3::new(-player_rad, -player_rad, 0.0),
max: pos + Vec3::new(player_rad, player_rad, player_height),
};
let block_aabb = Aabb {
min: block_pos.map(|e| e as f32),
max: block_pos.map(|e| e as f32) + 1.0,
};
if this_aabb.collides_with_aabb(block_aabb) {
return true;
@ -204,8 +217,14 @@ impl<'a> System<'a> for Sys {
.unwrap_or(false)
{
// ...and calculate bounding boxes for both the player's body and the block.
let this_aabb = Aabb { min: pos.0 + Vec3::new(-0.3, -0.3, 0.0), max: pos.0 + Vec3::new(0.3, 0.3, 1.7) };
let block_aabb = Aabb { min: block_pos.map(|e| e as f32), max: block_pos.map(|e| e as f32) + 1.0 };
let this_aabb = Aabb {
min: pos.0 + Vec3::new(-player_rad, -player_rad, 0.0),
max: pos.0 + Vec3::new(player_rad, player_rad, player_height),
};
let block_aabb = Aabb {
min: block_pos.map(|e| e as f32),
max: block_pos.map(|e| e as f32) + 1.0,
};
// If the bounding boxes collide, resolve the collision
if this_aabb.collides_with_aabb(block_aabb) {
@ -219,12 +238,16 @@ impl<'a> System<'a> for Sys {
on_ground = true;
}
if resolve_dir.z == 0.0 && !collision_with(pos.0 + Vec3::unit_z() * 1.0, near_iter.clone()) {
if resolve_dir.z == 0.0
&& !collision_with(pos.0 + Vec3::unit_z() * 1.0, near_iter.clone())
{
pos.0.z += 1.0;
break;
} else {
pos.0 += resolve_dir;
vel.0 = vel.0.map2(resolve_dir, |e, d| if d == 0.0 { e } else { 0.0 });
vel.0 = vel
.0
.map2(resolve_dir, |e, d| if d == 0.0 { e } else { 0.0 });
}
}
}
@ -232,7 +255,10 @@ impl<'a> System<'a> for Sys {
if on_ground {
on_grounds.insert(entity, OnGround);
} else if collision_with(pos.0 - Vec3::unit_z() * 1.0, near_iter.clone()) && vel.0.z < 0.0 && vel.0.z > -1.0 {
} else if collision_with(pos.0 - Vec3::unit_z() * 1.0, near_iter.clone())
&& vel.0.z < 0.0
&& vel.0.z > -1.0
{
pos.0.z = (pos.0.z - 0.05).floor();
on_grounds.insert(entity, OnGround);
}