mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Improved water pathfinding
This commit is contained in:
parent
71b7e1ef90
commit
de685b00b2
@ -139,6 +139,7 @@ void main() {
|
||||
// f_pos = v_pos + (model_offs - focus_off.xyz);
|
||||
|
||||
f_pos = (inst_mat * vec4(v_pos_, 1.0)).xyz * SCALE + inst_offs;
|
||||
f_pos.z -= 250.0 * (1.0 - min(1.0001 - 0.02 / pow(tick.x - load_time, 10.0), 1.0));
|
||||
// f_pos = (inst_mat * v_pos_) * SCALE + sprite_pos;
|
||||
|
||||
// f_pos = (inst_mat * vec4(v_pos * SCALE, 1)).xyz + (model_offs - focus_off.xyz);
|
||||
|
@ -131,17 +131,18 @@ impl Route {
|
||||
// Determine whether we're close enough to the next to to consider it completed
|
||||
let dist_sqrd = pos.xy().distance_squared(closest_tgt.xy());
|
||||
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 && (traversal_cfg.on_ground || traversal_cfg.in_liquid)))
|
||||
&& (pos.z - closest_tgt.z < 1.2 || (pos.z - closest_tgt.z < 2.9 && vel.z < -0.05))
|
||||
&& vel.z <= 0.0
|
||||
// Only consider the node reached if there's nothing solid between us and it
|
||||
&& (vol
|
||||
.ray(pos + Vec3::unit_z() * 1.5, closest_tgt + Vec3::unit_z() * 1.5)
|
||||
.until(Block::is_solid)
|
||||
.cast()
|
||||
.0
|
||||
> pos.distance(closest_tgt) * 0.9 || dist_sqrd < 0.5)
|
||||
&& self.next_idx < self.path.len()
|
||||
&& (((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))
|
||||
&& vel.z <= 0.0
|
||||
// Only consider the node reached if there's nothing solid between us and it
|
||||
&& (vol
|
||||
.ray(pos + Vec3::unit_z() * 1.5, closest_tgt + Vec3::unit_z() * 1.5)
|
||||
.until(Block::is_solid)
|
||||
.cast()
|
||||
.0
|
||||
> pos.distance(closest_tgt) * 0.9 || dist_sqrd < 0.5)
|
||||
&& self.next_idx < self.path.len())
|
||||
|| (traversal_cfg.in_liquid && pos.z < closest_tgt.z + 0.8 && pos.z > closest_tgt.z))
|
||||
{
|
||||
// Node completed, move on to the next one
|
||||
self.next_idx += 1;
|
||||
@ -419,7 +420,7 @@ impl Chaser {
|
||||
vol.get(
|
||||
(pos + Vec3::<f32>::from(tgt_dir) * 2.5).map(|e| e as i32) + Vec3::unit_z() * z,
|
||||
)
|
||||
.map(|b| !b.is_solid())
|
||||
.map(|b| b.is_air())
|
||||
.unwrap_or(false)
|
||||
});
|
||||
|
||||
@ -437,17 +438,22 @@ fn walkable<V>(vol: &V, pos: Vec3<i32>) -> bool
|
||||
where
|
||||
V: BaseVol<Vox = Block> + ReadVol,
|
||||
{
|
||||
vol.get(pos - Vec3::new(0, 0, 1))
|
||||
.map(|b| b.is_filled())
|
||||
.unwrap_or(false)
|
||||
&& vol
|
||||
.get(pos + Vec3::new(0, 0, 0))
|
||||
.map(|b| !b.is_filled())
|
||||
.unwrap_or(true)
|
||||
&& vol
|
||||
.get(pos + Vec3::new(0, 0, 1))
|
||||
.map(|b| !b.is_filled())
|
||||
.unwrap_or(true)
|
||||
let below = vol.get(pos - Vec3::unit_z())
|
||||
.ok()
|
||||
.copied()
|
||||
.unwrap_or_else(Block::empty);
|
||||
let a = vol.get(pos)
|
||||
.ok()
|
||||
.copied()
|
||||
.unwrap_or_else(Block::empty);
|
||||
let b = vol.get(pos + Vec3::unit_z())
|
||||
.ok()
|
||||
.copied()
|
||||
.unwrap_or_else(Block::empty);
|
||||
|
||||
let on_ground = below.is_filled();
|
||||
let in_liquid = a.is_liquid();
|
||||
(on_ground || in_liquid) && !a.is_solid() && !b.is_solid()
|
||||
}
|
||||
|
||||
/// Attempt to search for a path to a target, returning the path (if one was
|
||||
@ -546,17 +552,17 @@ where
|
||||
&& ((dir.z < 1
|
||||
|| vol
|
||||
.get(pos + Vec3::unit_z() * 2)
|
||||
.map(|b| !b.is_filled())
|
||||
.map(|b| !b.is_solid())
|
||||
.unwrap_or(true))
|
||||
&& (dir.z < 2
|
||||
|| vol
|
||||
.get(pos + Vec3::unit_z() * 3)
|
||||
.map(|b| !b.is_filled())
|
||||
.map(|b| !b.is_solid())
|
||||
.unwrap_or(true))
|
||||
&& (dir.z >= 0
|
||||
|| vol
|
||||
.get(pos + *dir + Vec3::unit_z() * 2)
|
||||
.map(|b| !b.is_filled())
|
||||
.map(|b| !b.is_solid())
|
||||
.unwrap_or(true)))
|
||||
})
|
||||
.map(move |(pos, dir)| pos + dir)
|
||||
|
@ -239,9 +239,9 @@ impl<'a> System<'a> for Sys {
|
||||
.unwrap_or(Vec2::zero())
|
||||
* speed.min(agent.rtsim_controller.speed_factor);
|
||||
inputs.jump.set_state(bearing.z > 1.5);
|
||||
inputs.climb = Some(comp::Climb::Up)
|
||||
.filter(|_| bearing.z > 1.5 || physics_state.in_liquid.is_some());
|
||||
inputs.move_z = bearing.z;
|
||||
inputs.climb = Some(comp::Climb::Up);
|
||||
//.filter(|_| bearing.z > 0.1 || physics_state.in_liquid.is_some());
|
||||
inputs.move_z = bearing.z + 0.05;
|
||||
}
|
||||
} else {
|
||||
*bearing += Vec2::new(
|
||||
|
@ -116,11 +116,15 @@ impl TerrainGrid {
|
||||
let mut z_diff = 0;
|
||||
for _ in 0..128 {
|
||||
let test_pos = pos + Vec3::unit_z() * z_diff;
|
||||
if (0..2)
|
||||
.all(|z| self
|
||||
.get(test_pos + Vec3::unit_z() * z)
|
||||
.map(|b| !b.is_solid())
|
||||
.unwrap_or(true))
|
||||
if self
|
||||
.get(test_pos - Vec3::unit_z())
|
||||
.map(|b| b.is_filled())
|
||||
.unwrap_or(false)
|
||||
&& (0..2)
|
||||
.all(|z| self
|
||||
.get(test_pos + Vec3::unit_z() * z)
|
||||
.map(|b| !b.is_solid())
|
||||
.unwrap_or(true))
|
||||
{
|
||||
return test_pos;
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ impl Entity {
|
||||
|
||||
let travel_to = self.pos.xy() + Vec3::from((wpos.map(|e| e as f32 + 0.5) - self.pos.xy())
|
||||
.try_normalized()
|
||||
.unwrap_or_else(Vec2::zero)) * 32.0;
|
||||
.unwrap_or_else(Vec2::zero)) * 64.0;
|
||||
let travel_to_alt = world.sim().get_alt_approx(travel_to.map(|e| e as i32)).unwrap_or(0.0) as i32;
|
||||
let travel_to = terrain.find_space(Vec3::new(travel_to.x as i32, travel_to.y as i32, travel_to_alt)).map(|e| e as f32) + Vec3::new(0.5, 0.5, 0.0);
|
||||
self.controller.travel_to = Some(travel_to);
|
||||
|
@ -87,7 +87,7 @@ pub fn add_server_systems(dispatch_builder: &mut DispatcherBuilder) {
|
||||
pub fn init(state: &mut State, world: &world::World) {
|
||||
let mut rtsim = RtSim::new(world.sim().get_size());
|
||||
|
||||
for _ in 0..10000 {
|
||||
for _ in 0..2500 {
|
||||
let pos = rtsim.chunks.size().map2(
|
||||
TerrainChunk::RECT_SIZE,
|
||||
|sz, chunk_sz| thread_rng().gen_range(0, sz * chunk_sz) as i32,
|
||||
|
@ -24,6 +24,7 @@ pub mod sim;
|
||||
pub mod sim2;
|
||||
pub mod site;
|
||||
pub mod util;
|
||||
pub mod pathfinding;
|
||||
|
||||
// Reexports
|
||||
pub use crate::{
|
||||
|
35
world/src/pathfinding.rs
Normal file
35
world/src/pathfinding.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use crate::sim::WorldSim;
|
||||
use common::{
|
||||
astar::Astar,
|
||||
path::Path,
|
||||
};
|
||||
use hashbrown::hash_map::DefaultHashBuilder;
|
||||
use vek::*;
|
||||
|
||||
pub struct SearchCfg {
|
||||
// 0.0 = no discount, 1.0 = free travel
|
||||
path_discount: f32,
|
||||
// Cost per metre altitude change per metre horizontal
|
||||
// 0.0 = no cost, 1.0 = same cost vertical as horizontal
|
||||
gradient_aversion: f32,
|
||||
}
|
||||
|
||||
pub struct Searcher<'a> {
|
||||
land: &'a WorldSim,
|
||||
pub cfg: SearchCfg,
|
||||
}
|
||||
|
||||
impl<'a> Searcher<'a> {
|
||||
/// Attempt to find a path between two chunks on the map.
|
||||
pub fn search(self, a: Vec2<i32>, b: Vec2<i32>) -> Option<Path<i32>> {
|
||||
let heuristic = |pos: &Vec2<i32>| (pos - b).map(|e| e as f32).magnitude();
|
||||
// Astar::new(
|
||||
// 100_000,
|
||||
// a,
|
||||
// heuristc,
|
||||
// DefaultHashBuilder::default(),
|
||||
// );
|
||||
|
||||
None
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user