mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Neater compass
This commit is contained in:
@ -56,6 +56,18 @@ impl From<Path<Vec3<i32>>> for Route {
|
|||||||
fn from(path: Path<Vec3<i32>>) -> Self { Self { path, next_idx: 0 } }
|
fn from(path: Path<Vec3<i32>>) -> Self { Self { path, next_idx: 0 } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct TraversalConfig {
|
||||||
|
/// The distance to a node at which node is considered visited.
|
||||||
|
pub node_tolerance: f32,
|
||||||
|
/// The slowdown factor when following corners.
|
||||||
|
/// 0.0 = no slowdown on corners, 1.0 = total slowdown on corners.
|
||||||
|
pub slow_factor: f32,
|
||||||
|
/// Whether the agent is currently on the ground.
|
||||||
|
pub on_ground: bool,
|
||||||
|
/// The distance to the target below which it is considered reached.
|
||||||
|
pub min_tgt_dist: f32,
|
||||||
|
}
|
||||||
|
|
||||||
impl Route {
|
impl Route {
|
||||||
pub fn path(&self) -> &Path<Vec3<i32>> { &self.path }
|
pub fn path(&self) -> &Path<Vec3<i32>> { &self.path }
|
||||||
|
|
||||||
@ -70,9 +82,7 @@ impl Route {
|
|||||||
vol: &V,
|
vol: &V,
|
||||||
pos: Vec3<f32>,
|
pos: Vec3<f32>,
|
||||||
vel: Vec3<f32>,
|
vel: Vec3<f32>,
|
||||||
on_ground: bool,
|
traversal_cfg: TraversalConfig,
|
||||||
traversal_tolerance: f32,
|
|
||||||
slow_factor: f32,
|
|
||||||
) -> Option<(Vec3<f32>, f32)>
|
) -> Option<(Vec3<f32>, f32)>
|
||||||
where
|
where
|
||||||
V: BaseVol<Vox = Block> + ReadVol,
|
V: BaseVol<Vox = Block> + ReadVol,
|
||||||
@ -120,8 +130,8 @@ impl Route {
|
|||||||
|
|
||||||
// Determine whether we're close enough to the next to to consider it completed
|
// Determine whether we're close enough to the next to to consider it completed
|
||||||
let dist_sqrd = pos.xy().distance_squared(closest_tgt.xy());
|
let dist_sqrd = pos.xy().distance_squared(closest_tgt.xy());
|
||||||
if dist_sqrd < traversal_tolerance.powf(2.0) * if be_precise { 0.25 } else { 1.0 }
|
if dist_sqrd < traversal_cfg.node_tolerance.powf(2.0) * if be_precise { 0.25 } else { 1.0 }
|
||||||
&& (pos.z - closest_tgt.z > 1.2 || (pos.z - closest_tgt.z > -0.2 && on_ground))
|
&& (pos.z - closest_tgt.z > 1.2 || (pos.z - closest_tgt.z > -0.2 && traversal_cfg.on_ground))
|
||||||
&& (pos.z - closest_tgt.z < 1.2 || (pos.z - closest_tgt.z < 2.9 && vel.z < -0.05))
|
&& (pos.z - closest_tgt.z < 1.2 || (pos.z - closest_tgt.z < 2.9 && vel.z < -0.05))
|
||||||
&& vel.z <= 0.0
|
&& vel.z <= 0.0
|
||||||
// Only consider the node reached if there's nothing solid between us and it
|
// Only consider the node reached if there's nothing solid between us and it
|
||||||
@ -242,7 +252,7 @@ impl Route {
|
|||||||
|
|
||||||
let bez = CubicBezier2 {
|
let bez = CubicBezier2 {
|
||||||
start: pos.xy(),
|
start: pos.xy(),
|
||||||
ctrl0: pos.xy() + vel.xy().try_normalized().unwrap_or(Vec2::zero()) * 1.0,
|
ctrl0: pos.xy() + vel.xy().try_normalized().unwrap_or_default() * 1.0,
|
||||||
ctrl1: align(next0, 1.0),
|
ctrl1: align(next0, 1.0),
|
||||||
end: align(next1, 1.0),
|
end: align(next1, 1.0),
|
||||||
};
|
};
|
||||||
@ -254,7 +264,7 @@ impl Route {
|
|||||||
let next_dir = bez
|
let next_dir = bez
|
||||||
.evaluate_derivative(0.85)
|
.evaluate_derivative(0.85)
|
||||||
.try_normalized()
|
.try_normalized()
|
||||||
.unwrap_or(Vec2::zero());
|
.unwrap_or_default();
|
||||||
let straight_factor = next_dir
|
let straight_factor = next_dir
|
||||||
.dot(vel.xy().try_normalized().unwrap_or(next_dir))
|
.dot(vel.xy().try_normalized().unwrap_or(next_dir))
|
||||||
.max(0.0)
|
.max(0.0)
|
||||||
@ -262,12 +272,11 @@ impl Route {
|
|||||||
|
|
||||||
let bez = CubicBezier2 {
|
let bez = CubicBezier2 {
|
||||||
start: pos.xy(),
|
start: pos.xy(),
|
||||||
ctrl0: pos.xy() + vel.xy().try_normalized().unwrap_or(Vec2::zero()) * 1.0,
|
ctrl0: pos.xy() + vel.xy().try_normalized().unwrap_or_default() * 1.0,
|
||||||
ctrl1: align(
|
ctrl1: align(
|
||||||
next0,
|
next0,
|
||||||
(1.0 - straight_factor
|
(1.0 - if (next0.z as f32 - pos.z).abs() < 0.25 && !be_precise {
|
||||||
* if (next0.z as f32 - pos.z).abs() < 0.25 && !be_precise {
|
straight_factor
|
||||||
1.0
|
|
||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
})
|
})
|
||||||
@ -292,7 +301,7 @@ impl Route {
|
|||||||
// Control the entity's speed to hopefully stop us falling off walls on sharp corners.
|
// Control the entity's speed to hopefully stop us falling off walls on sharp corners.
|
||||||
// This code is very imperfect: it does its best but it can still fail for particularly
|
// This code is very imperfect: it does its best but it can still fail for particularly
|
||||||
// fast entities.
|
// fast entities.
|
||||||
straight_factor * slow_factor + (1.0 - slow_factor),
|
straight_factor * traversal_cfg.slow_factor + (1.0 - traversal_cfg.slow_factor),
|
||||||
))
|
))
|
||||||
.filter(|(bearing, _)| bearing.z < 2.1)
|
.filter(|(bearing, _)| bearing.z < 2.1)
|
||||||
}
|
}
|
||||||
@ -317,11 +326,8 @@ impl Chaser {
|
|||||||
vol: &V,
|
vol: &V,
|
||||||
pos: Vec3<f32>,
|
pos: Vec3<f32>,
|
||||||
vel: Vec3<f32>,
|
vel: Vec3<f32>,
|
||||||
on_ground: bool,
|
|
||||||
tgt: Vec3<f32>,
|
tgt: Vec3<f32>,
|
||||||
min_dist: f32,
|
traversal_cfg: TraversalConfig,
|
||||||
traversal_tolerance: f32,
|
|
||||||
slow_factor: f32,
|
|
||||||
) -> Option<(Vec3<f32>, f32)>
|
) -> Option<(Vec3<f32>, f32)>
|
||||||
where
|
where
|
||||||
V: BaseVol<Vox = Block> + ReadVol,
|
V: BaseVol<Vox = Block> + ReadVol,
|
||||||
@ -329,7 +335,9 @@ impl Chaser {
|
|||||||
let pos_to_tgt = pos.distance(tgt);
|
let pos_to_tgt = pos.distance(tgt);
|
||||||
|
|
||||||
// If we're already close to the target then there's nothing to do
|
// If we're already close to the target then there's nothing to do
|
||||||
if ((pos - tgt) * Vec3::new(1.0, 1.0, 2.0)).magnitude_squared() < min_dist.powf(2.0) {
|
if ((pos - tgt) * Vec3::new(1.0, 1.0, 2.0)).magnitude_squared()
|
||||||
|
< traversal_cfg.min_tgt_dist.powf(2.0)
|
||||||
|
{
|
||||||
self.route = None;
|
self.route = None;
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -349,7 +357,7 @@ impl Chaser {
|
|||||||
} else {
|
} else {
|
||||||
self.route
|
self.route
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.and_then(|r| r.traverse(vol, pos, vel, on_ground, traversal_tolerance, slow_factor))
|
.and_then(|r| r.traverse(vol, pos, vel, traversal_cfg))
|
||||||
// In theory this filter isn't needed, but in practice agents often try to take
|
// In theory this filter isn't needed, but in practice agents often try to take
|
||||||
// stale paths that start elsewhere. This code makes sure that we're only using
|
// stale paths that start elsewhere. This code makes sure that we're only using
|
||||||
// paths that start near us, avoiding the agent doubling back to chase a stale
|
// paths that start near us, avoiding the agent doubling back to chase a stale
|
||||||
|
@ -16,6 +16,7 @@ impl Spiral2d {
|
|||||||
impl Iterator for Spiral2d {
|
impl Iterator for Spiral2d {
|
||||||
type Item = Vec2<i32>;
|
type Item = Vec2<i32>;
|
||||||
|
|
||||||
|
#[allow(clippy::erasing_op)]
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let layer_size = (self.layer * 8 + 4 * self.layer.min(1) - 4).max(1);
|
let layer_size = (self.layer * 8 + 4 * self.layer.min(1) - 4).max(1);
|
||||||
if self.i >= layer_size {
|
if self.i >= layer_size {
|
||||||
|
@ -7,7 +7,7 @@ use crate::{
|
|||||||
MountState, Ori, PhysicsState, Pos, Scale, Stats, Vel,
|
MountState, Ori, PhysicsState, Pos, Scale, Stats, Vel,
|
||||||
},
|
},
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
path::Chaser,
|
path::{Chaser, TraversalConfig},
|
||||||
state::{DeltaTime, Time},
|
state::{DeltaTime, Time},
|
||||||
sync::{Uid, UidAllocator},
|
sync::{Uid, UidAllocator},
|
||||||
terrain::TerrainGrid,
|
terrain::TerrainGrid,
|
||||||
@ -134,7 +134,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
// and so can afford to be less precise when trying to move around
|
// and so can afford to be less precise when trying to move around
|
||||||
// the world (especially since they would otherwise get stuck on
|
// the world (especially since they would otherwise get stuck on
|
||||||
// obstacles that smaller entities would not).
|
// obstacles that smaller entities would not).
|
||||||
let traversal_tolerance = scale + vel.0.xy().magnitude() * 0.2;
|
let node_tolerance = scale + vel.0.xy().magnitude() * 0.2;
|
||||||
let slow_factor = body.map(|b| b.base_accel() / 250.0).unwrap_or(0.0).min(1.0);
|
let slow_factor = body.map(|b| b.base_accel() / 250.0).unwrap_or(0.0).min(1.0);
|
||||||
|
|
||||||
let mut do_idle = false;
|
let mut do_idle = false;
|
||||||
@ -207,11 +207,13 @@ impl<'a> System<'a> for Sys {
|
|||||||
&*terrain,
|
&*terrain,
|
||||||
pos.0,
|
pos.0,
|
||||||
vel.0,
|
vel.0,
|
||||||
physics_state.on_ground,
|
|
||||||
tgt_pos.0,
|
tgt_pos.0,
|
||||||
AVG_FOLLOW_DIST,
|
TraversalConfig {
|
||||||
traversal_tolerance,
|
node_tolerance,
|
||||||
slow_factor,
|
slow_factor,
|
||||||
|
on_ground: physics_state.on_ground,
|
||||||
|
min_tgt_dist: AVG_FOLLOW_DIST,
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
inputs.move_dir =
|
inputs.move_dir =
|
||||||
bearing.xy().try_normalized().unwrap_or(Vec2::zero())
|
bearing.xy().try_normalized().unwrap_or(Vec2::zero())
|
||||||
@ -325,11 +327,13 @@ impl<'a> System<'a> for Sys {
|
|||||||
&*terrain,
|
&*terrain,
|
||||||
pos.0,
|
pos.0,
|
||||||
vel.0,
|
vel.0,
|
||||||
physics_state.on_ground,
|
|
||||||
tgt_pos.0,
|
tgt_pos.0,
|
||||||
1.25,
|
TraversalConfig {
|
||||||
traversal_tolerance,
|
node_tolerance,
|
||||||
slow_factor,
|
slow_factor,
|
||||||
|
on_ground: physics_state.on_ground,
|
||||||
|
min_tgt_dist: 1.25,
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
inputs.move_dir = Vec2::from(bearing)
|
inputs.move_dir = Vec2::from(bearing)
|
||||||
.try_normalized()
|
.try_normalized()
|
||||||
|
@ -234,7 +234,7 @@ impl<'a> Widget for MiniMap<'a> {
|
|||||||
+ Vec2::unit_y().rotated_z(self.ori.x as f64) * dir.y;
|
+ Vec2::unit_y().rotated_z(self.ori.x as f64) * dir.y;
|
||||||
let clamped = (cardinal_dir * 3.0)
|
let clamped = (cardinal_dir * 3.0)
|
||||||
/ (cardinal_dir * 3.0).map(|e| e.abs()).reduce_partial_max();
|
/ (cardinal_dir * 3.0).map(|e| e.abs()).reduce_partial_max();
|
||||||
let pos = clamped * (map_size * 0.75 - 10.0);
|
let pos = clamped * (map_size * 0.73 - 10.0);
|
||||||
Text::new(name)
|
Text::new(name)
|
||||||
.x_y_position_relative_to(
|
.x_y_position_relative_to(
|
||||||
state.ids.grid,
|
state.ids.grid,
|
||||||
|
Reference in New Issue
Block a user