mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Terrain pop-in, fixed agent pathfinding in water
This commit is contained in:
parent
717fd88565
commit
b352ef5d55
@ -61,10 +61,12 @@ out vec4 tgt_color;
|
||||
#include <lod.glsl>
|
||||
|
||||
void main() {
|
||||
/*
|
||||
float nz = abs(hash(vec4(floor((f_pos + focus_off.xyz) * 5.0), 0)));
|
||||
if (nz > (tick.x - load_time) / 0.5 || distance(focus_pos.xy, f_pos.xy) / view_distance.x + nz * 0.1 > 1.0) {
|
||||
discard;
|
||||
}
|
||||
*/
|
||||
|
||||
// discard;
|
||||
// vec4 f_col_light = textureGrad(t_col_light, f_uv_pos / texSize, 0.25, 0.25);
|
||||
|
@ -75,7 +75,7 @@ void main() {
|
||||
f_pos = f_chunk_pos + model_offs - focus_off.xyz;
|
||||
|
||||
f_load_time = load_time;
|
||||
//f_pos.z -= 250.0 * (1.0 - min(1.0001 - 0.02 / pow(tick.x - load_time, 10.0), 1.0));
|
||||
f_pos.z -= 250.0 * (1.0 - min(1.0001 - 0.02 / pow(tick.x - load_time, 10.0), 1.0));
|
||||
// f_pos.z -= min(32.0, 25.0 * pow(distance(focus_pos.xy, f_pos.xy) / view_distance.x, 20.0));
|
||||
|
||||
// vec3 light_col = vec3(
|
||||
|
@ -65,6 +65,8 @@ pub struct TraversalConfig {
|
||||
pub slow_factor: f32,
|
||||
/// Whether the agent is currently on the ground.
|
||||
pub on_ground: bool,
|
||||
/// Whether the agent is currently in water.
|
||||
pub in_liquid: bool,
|
||||
/// The distance to the target below which it is considered reached.
|
||||
pub min_tgt_dist: f32,
|
||||
}
|
||||
@ -127,7 +129,7 @@ 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))
|
||||
&& (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
|
||||
@ -434,15 +436,15 @@ where
|
||||
V: BaseVol<Vox = Block> + ReadVol,
|
||||
{
|
||||
vol.get(pos - Vec3::new(0, 0, 1))
|
||||
.map(|b| b.is_solid() && b.solid_height() == 1.0)
|
||||
.map(|b| b.is_filled())
|
||||
.unwrap_or(false)
|
||||
&& vol
|
||||
.get(pos + Vec3::new(0, 0, 0))
|
||||
.map(|b| !b.is_solid())
|
||||
.map(|b| !b.is_filled())
|
||||
.unwrap_or(true)
|
||||
&& vol
|
||||
.get(pos + Vec3::new(0, 0, 1))
|
||||
.map(|b| !b.is_solid())
|
||||
.map(|b| !b.is_filled())
|
||||
.unwrap_or(true)
|
||||
}
|
||||
|
||||
@ -531,17 +533,17 @@ where
|
||||
&& ((dir.z < 1
|
||||
|| vol
|
||||
.get(pos + Vec3::unit_z() * 2)
|
||||
.map(|b| !b.is_solid())
|
||||
.map(|b| !b.is_filled())
|
||||
.unwrap_or(true))
|
||||
&& (dir.z < 2
|
||||
|| vol
|
||||
.get(pos + Vec3::unit_z() * 3)
|
||||
.map(|b| !b.is_solid())
|
||||
.map(|b| !b.is_filled())
|
||||
.unwrap_or(true))
|
||||
&& (dir.z >= 0
|
||||
|| vol
|
||||
.get(pos + *dir + Vec3::unit_z() * 2)
|
||||
.map(|b| !b.is_solid())
|
||||
.map(|b| !b.is_filled())
|
||||
.unwrap_or(true)))
|
||||
})
|
||||
.map(move |(pos, dir)| pos + dir)
|
||||
|
@ -223,6 +223,7 @@ impl<'a> System<'a> for Sys {
|
||||
node_tolerance,
|
||||
slow_factor,
|
||||
on_ground: physics_state.on_ground,
|
||||
in_liquid: physics_state.in_liquid.is_some(),
|
||||
min_tgt_dist: 1.25,
|
||||
},
|
||||
) {
|
||||
@ -232,7 +233,8 @@ 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);
|
||||
inputs.climb = Some(comp::Climb::Up)
|
||||
.filter(|_| bearing.z > 1.5 || physics_state.in_liquid.is_some());
|
||||
inputs.move_z = bearing.z;
|
||||
}
|
||||
} else {
|
||||
@ -303,6 +305,7 @@ impl<'a> System<'a> for Sys {
|
||||
node_tolerance,
|
||||
slow_factor,
|
||||
on_ground: physics_state.on_ground,
|
||||
in_liquid: physics_state.in_liquid.is_some(),
|
||||
min_tgt_dist: AVG_FOLLOW_DIST,
|
||||
},
|
||||
) {
|
||||
@ -429,6 +432,7 @@ impl<'a> System<'a> for Sys {
|
||||
node_tolerance,
|
||||
slow_factor,
|
||||
on_ground: physics_state.on_ground,
|
||||
in_liquid: physics_state.in_liquid.is_some(),
|
||||
min_tgt_dist: 1.25,
|
||||
},
|
||||
) {
|
||||
@ -590,6 +594,7 @@ impl<'a> System<'a> for Sys {
|
||||
node_tolerance,
|
||||
slow_factor,
|
||||
on_ground: physics_state.on_ground,
|
||||
in_liquid: physics_state.in_liquid.is_some(),
|
||||
min_tgt_dist: 1.25,
|
||||
},
|
||||
) {
|
||||
|
@ -28,7 +28,7 @@ pub const BOUYANCY: f32 = 1.0;
|
||||
// 60.
|
||||
pub const FRIC_GROUND: f32 = 0.15;
|
||||
pub const FRIC_AIR: f32 = 0.0125;
|
||||
pub const FRIC_FLUID: f32 = 0.2;
|
||||
pub const FRIC_FLUID: f32 = 0.4;
|
||||
|
||||
// Integrates forces, calculates the new velocity based off of the old velocity
|
||||
// dt = delta time
|
||||
|
@ -36,11 +36,21 @@ use vek::*;
|
||||
|
||||
const SPRITE_SCALE: Vec3<f32> = Vec3::new(1.0 / 11.0, 1.0 / 11.0, 1.0 / 11.0);
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||
enum Visibility {
|
||||
OutOfRange = 0,
|
||||
InRange = 1,
|
||||
Visible = 2,
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct Visibility {
|
||||
in_range: bool,
|
||||
in_frustum: bool,
|
||||
}
|
||||
|
||||
impl Visibility {
|
||||
/// Should the chunk actually get rendered?
|
||||
fn is_visible(&self) -> bool {
|
||||
// Currently, we don't take into account in_range to allow all chunks to do pop-in.
|
||||
// This isn't really a problem because we no longer have VD mist or anything like that.
|
||||
// Also, we don't load chunks outside of the VD anyway so this literally just controls
|
||||
// which chunks get actually rendered.
|
||||
/*self.in_range &&*/ self.in_frustum
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TerrainChunkData {
|
||||
@ -237,7 +247,7 @@ pub struct Terrain<V: RectRasterableVol> {
|
||||
|
||||
impl TerrainChunkData {
|
||||
pub fn can_shadow_sun(&self) -> bool {
|
||||
self.visible == Visibility::Visible || self.can_shadow_sun
|
||||
self.visible.is_visible() || self.can_shadow_sun
|
||||
}
|
||||
}
|
||||
|
||||
@ -751,7 +761,10 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
load_time,
|
||||
}])
|
||||
.expect("Failed to upload chunk locals to the GPU!"),
|
||||
visible: Visibility::OutOfRange,
|
||||
visible: Visibility {
|
||||
in_range: false,
|
||||
in_frustum: false,
|
||||
},
|
||||
can_shadow_point: false,
|
||||
can_shadow_sun: false,
|
||||
blocks_of_interest: response.blocks_of_interest,
|
||||
@ -793,10 +806,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
let distance_2 = Vec2::<f32>::from(focus_pos).distance_squared(nearest_in_chunk);
|
||||
let in_range = distance_2 < loaded_distance.powf(2.0);
|
||||
|
||||
if !in_range {
|
||||
chunk.visible = Visibility::OutOfRange;
|
||||
continue;
|
||||
}
|
||||
chunk.visible.in_range = in_range;
|
||||
|
||||
// Ensure the chunk is within the view frustum
|
||||
let chunk_min = [chunk_pos.x, chunk_pos.y, chunk.z_bounds.0];
|
||||
@ -810,11 +820,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
.coherent_test_against_frustum(&frustum, chunk.frustum_last_plane_index);
|
||||
|
||||
chunk.frustum_last_plane_index = last_plane_index;
|
||||
chunk.visible = if in_frustum {
|
||||
Visibility::Visible
|
||||
} else {
|
||||
Visibility::InRange
|
||||
};
|
||||
chunk.visible.in_frustum = in_frustum;
|
||||
let chunk_box = Aabb {
|
||||
min: Vec3::from(chunk_min),
|
||||
max: Vec3::from(chunk_max),
|
||||
@ -910,7 +916,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
// NOTE: We deliberately avoid doing this computation for chunks we already know
|
||||
// are visible, since by definition they'll always intersect the visible view
|
||||
// frustum.
|
||||
.filter(|chunk| chunk.1.visible <= Visibility::InRange)
|
||||
.filter(|chunk| !chunk.1.visible.in_frustum)
|
||||
.for_each(|(&pos, chunk)| {
|
||||
chunk.can_shadow_sun = can_shadow_sun(pos, chunk);
|
||||
});
|
||||
@ -958,7 +964,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
pub fn visible_chunk_count(&self) -> usize {
|
||||
self.chunks
|
||||
.iter()
|
||||
.filter(|(_, c)| c.visible == Visibility::Visible)
|
||||
.filter(|(_, c)| c.visible.is_visible())
|
||||
.count()
|
||||
}
|
||||
|
||||
@ -1046,7 +1052,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
.take(self.chunks.len());
|
||||
|
||||
for (_, chunk) in chunk_iter {
|
||||
if chunk.visible == Visibility::Visible {
|
||||
if chunk.visible.is_visible() {
|
||||
renderer.render_terrain_chunk(
|
||||
&chunk.opaque_model,
|
||||
&self.col_lights,
|
||||
@ -1086,7 +1092,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
let chunk_size = V::RECT_SIZE.map(|e| e as f32);
|
||||
let chunk_mag = (chunk_size * (f32::consts::SQRT_2 * 0.5)).magnitude_squared();
|
||||
for (pos, chunk) in chunk_iter.clone() {
|
||||
if chunk.visible == Visibility::Visible {
|
||||
if chunk.visible.is_visible() {
|
||||
let sprite_low_detail_distance = sprite_render_distance * 0.75;
|
||||
let sprite_mid_detail_distance = sprite_render_distance * 0.5;
|
||||
let sprite_hid_detail_distance = sprite_render_distance * 0.35;
|
||||
@ -1146,7 +1152,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
// Translucent
|
||||
chunk_iter
|
||||
.clone()
|
||||
.filter(|(_, chunk)| chunk.visible == Visibility::Visible)
|
||||
.filter(|(_, chunk)| chunk.visible.is_visible())
|
||||
.filter_map(|(_, chunk)| {
|
||||
chunk
|
||||
.fluid_model
|
||||
|
Loading…
Reference in New Issue
Block a user