mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Stop drawing entities outside the vd
Former-commit-id: 34878fb66ec22ac77a7400724b80ad7f8321f4cf
This commit is contained in:
parent
59967c603c
commit
e3e8afd99b
@ -110,6 +110,10 @@ impl Client {
|
||||
.send_message(ClientMsg::SetViewDistance(self.view_distance.unwrap())); // Can't fail
|
||||
}
|
||||
|
||||
pub fn view_distance(&self) -> Option<u32> {
|
||||
self.view_distance
|
||||
}
|
||||
|
||||
/// Send a chat message to the server.
|
||||
#[allow(dead_code)]
|
||||
pub fn send_chat(&mut self, msg: String) {
|
||||
|
@ -283,19 +283,22 @@ impl Server {
|
||||
// Also, send the chunk data to anybody that is close by.
|
||||
if let Ok((key, chunk)) = self.chunk_rx.try_recv() {
|
||||
// Send the chunk to all nearby players.
|
||||
for (entity, player, pos) in (
|
||||
for (entity, view_distance, pos) in (
|
||||
&self.state.ecs().entities(),
|
||||
&self.state.ecs().read_storage::<comp::Player>(),
|
||||
&self.state.ecs().read_storage::<comp::phys::Pos>(),
|
||||
)
|
||||
.join()
|
||||
.filter_map(|(entity, player, pos)| {
|
||||
player.view_distance.map(|vd| (entity, vd, pos))
|
||||
})
|
||||
{
|
||||
let chunk_pos = self.state.terrain().pos_key(pos.0.map(|e| e as i32));
|
||||
let dist = (Vec2::from(chunk_pos) - Vec2::from(key))
|
||||
.map(|e: i32| e.abs())
|
||||
.reduce_max() as u32;
|
||||
|
||||
if player.view_distance.map(|vd| dist <= vd).unwrap_or(false) {
|
||||
if dist <= view_distance {
|
||||
self.clients.notify(
|
||||
entity,
|
||||
ServerMsg::TerrainChunkUpdate {
|
||||
|
@ -31,8 +31,7 @@ use crate::{
|
||||
GlobalState,
|
||||
};
|
||||
use client::Client;
|
||||
use common::comp;
|
||||
use common::comp::phys::Pos;
|
||||
use common::{comp, terrain::TerrainChunkSize, vol::VolSize};
|
||||
use conrod_core::{
|
||||
color, graph,
|
||||
widget::{self, Button, Image, Rectangle, Text},
|
||||
@ -105,7 +104,7 @@ font_ids! {
|
||||
pub struct DebugInfo {
|
||||
pub tps: f64,
|
||||
pub ping_ms: f64,
|
||||
pub coordinates: Option<Pos>,
|
||||
pub coordinates: Option<comp::phys::Pos>,
|
||||
}
|
||||
|
||||
pub enum Event {
|
||||
@ -305,6 +304,14 @@ impl Hud {
|
||||
let player = ecs.read_storage::<comp::Player>();
|
||||
let entities = ecs.entities();
|
||||
let me = client.entity();
|
||||
let view_distance = client.view_distance().unwrap_or(1);
|
||||
// Get player position.
|
||||
let player_pos = client
|
||||
.state()
|
||||
.ecs()
|
||||
.read_storage::<comp::phys::Pos>()
|
||||
.get(client.entity())
|
||||
.map_or(Vec3::zero(), |pos| pos.0);
|
||||
let mut name_id_walker = self.ids.name_tags.walk();
|
||||
let mut health_id_walker = self.ids.health_bars.walk();
|
||||
let mut health_back_id_walker = self.ids.health_bar_backs.walk();
|
||||
@ -313,6 +320,14 @@ impl Hud {
|
||||
for (pos, name) in (&entities, &pos, &actor, &stats, player.maybe())
|
||||
.join()
|
||||
.filter(|(entity, _, _, stats, _)| *entity != me && !stats.is_dead)
|
||||
// Don't process nametags outside the vd (visibility further limited by ui backend)
|
||||
.filter(|(_, pos, _, _, _)| {
|
||||
(pos.0 - player_pos)
|
||||
.map2(TerrainChunkSize::SIZE, |d, sz| {
|
||||
(d.abs() as u32) < view_distance * sz as u32
|
||||
})
|
||||
.reduce_and()
|
||||
})
|
||||
.map(|(entity, pos, actor, _, player)| match actor {
|
||||
comp::Actor::Character {
|
||||
name: char_name, ..
|
||||
@ -342,14 +357,21 @@ impl Hud {
|
||||
}
|
||||
|
||||
// Render Health Bars
|
||||
for (entity, pos, stats) in
|
||||
(&entities, &pos, &stats)
|
||||
.join()
|
||||
.filter(|(entity, _, stats)| {
|
||||
*entity != me
|
||||
&& !stats.is_dead
|
||||
&& stats.hp.get_current() != stats.hp.get_maximum()
|
||||
})
|
||||
for (entity, pos, stats) in (&entities, &pos, &stats)
|
||||
.join()
|
||||
.filter(|(entity, _, stats)| {
|
||||
*entity != me
|
||||
&& !stats.is_dead
|
||||
&& stats.hp.get_current() != stats.hp.get_maximum()
|
||||
})
|
||||
// Don't process health bars outside the vd (visibility further limited by ui backend)
|
||||
.filter(|(_, pos, _)| {
|
||||
(pos.0 - player_pos)
|
||||
.map2(TerrainChunkSize::SIZE, |d, sz| {
|
||||
(d.abs() as u32) < view_distance * sz as u32
|
||||
})
|
||||
.reduce_and()
|
||||
})
|
||||
{
|
||||
let back_id = health_back_id_walker.next(
|
||||
&mut self.ids.health_bar_backs,
|
||||
|
@ -26,6 +26,8 @@ use common::{
|
||||
figure::Segment,
|
||||
msg,
|
||||
msg::ClientState,
|
||||
terrain::TerrainChunkSize,
|
||||
vol::VolSize,
|
||||
};
|
||||
use dot_vox::DotVoxData;
|
||||
use specs::{Component, Entity as EcsEntity, Join, VecStorage};
|
||||
@ -461,6 +463,15 @@ impl FigureMgr {
|
||||
pub fn maintain(&mut self, renderer: &mut Renderer, client: &Client) {
|
||||
let time = client.state().get_time();
|
||||
let ecs = client.state().ecs();
|
||||
let view_distance = client.view_distance().unwrap_or(1);
|
||||
// Get player position.
|
||||
let player_pos = client
|
||||
.state()
|
||||
.ecs()
|
||||
.read_storage::<comp::phys::Pos>()
|
||||
.get(client.entity())
|
||||
.map_or(Vec3::zero(), |pos| pos.0);
|
||||
|
||||
for (entity, pos, vel, dir, actor, animation_info, stats) in (
|
||||
&ecs.entities(),
|
||||
&ecs.read_storage::<comp::phys::Pos>(),
|
||||
@ -472,6 +483,32 @@ impl FigureMgr {
|
||||
)
|
||||
.join()
|
||||
{
|
||||
// Don't process figures outside the vd
|
||||
let vd_percent = (pos.0 - player_pos)
|
||||
.map2(TerrainChunkSize::SIZE, |d, sz| {
|
||||
(100 * d.abs() as u32) / (view_distance * sz)
|
||||
})
|
||||
.reduce_max();
|
||||
// Keep from re-adding/removing entities on the border of the vd
|
||||
if vd_percent > 120 {
|
||||
match actor {
|
||||
comp::Actor::Character { body, .. } => match body {
|
||||
Body::Humanoid(_) => {
|
||||
self.character_states.remove(&entity);
|
||||
}
|
||||
Body::Quadruped(_) => {
|
||||
self.quadruped_states.remove(&entity);
|
||||
}
|
||||
Body::QuadrupedMedium(_) => {
|
||||
self.QuadrupedMedium_states.remove(&entity);
|
||||
}
|
||||
},
|
||||
}
|
||||
continue;
|
||||
} else if vd_percent > 100 {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Change in health as color!
|
||||
let col = stats
|
||||
.and_then(|stats| stats.hp.last_change)
|
||||
@ -610,17 +647,36 @@ impl FigureMgr {
|
||||
let tick = client.get_tick();
|
||||
let ecs = client.state().ecs();
|
||||
|
||||
for (entity, actor, stat) in (
|
||||
let view_distance = client.view_distance().unwrap_or(1);
|
||||
// Get player position.
|
||||
let player_pos = client
|
||||
.state()
|
||||
.ecs()
|
||||
.read_storage::<comp::phys::Pos>()
|
||||
.get(client.entity())
|
||||
.map_or(Vec3::zero(), |pos| pos.0);
|
||||
|
||||
for (entity, _, _, _, actor, _, _) in (
|
||||
&ecs.entities(),
|
||||
&ecs.read_storage::<comp::phys::Pos>(),
|
||||
&ecs.read_storage::<comp::phys::Vel>(),
|
||||
&ecs.read_storage::<comp::phys::Dir>(),
|
||||
&ecs.read_storage::<comp::Actor>(),
|
||||
&ecs.read_storage::<comp::Stats>(), // Just to make sure the entity is alive
|
||||
&ecs.read_storage::<comp::AnimationInfo>(),
|
||||
ecs.read_storage::<comp::Stats>().maybe(),
|
||||
)
|
||||
.join()
|
||||
// Don't render figures outside the vd
|
||||
.filter(|(_, pos, _, _, _, _, _)| {
|
||||
(pos.0 - player_pos)
|
||||
.map2(TerrainChunkSize::SIZE, |d, sz| {
|
||||
(d.abs() as u32) < view_distance * sz as u32
|
||||
})
|
||||
.reduce_and()
|
||||
})
|
||||
// Don't render dead entities
|
||||
.filter(|(e, _, _, _, a, _, stats)| stats.map_or(true, |s| !s.is_dead))
|
||||
{
|
||||
if stat.is_dead {
|
||||
continue;
|
||||
}
|
||||
|
||||
match actor {
|
||||
comp::Actor::Character { body, .. } => {
|
||||
if let Some((locals, bone_consts)) = match body {
|
||||
|
@ -116,8 +116,7 @@ impl Scene {
|
||||
.ecs()
|
||||
.read_storage::<comp::phys::Pos>()
|
||||
.get(client.entity())
|
||||
.map(|pos| pos.0)
|
||||
.unwrap_or(Vec3::zero());
|
||||
.map_or(Vec3::zero(), |pos| pos.0);
|
||||
|
||||
// Alter camera position to match player.
|
||||
self.camera.set_focus_pos(player_pos + Vec3::unit_z() * 2.1);
|
||||
|
Loading…
Reference in New Issue
Block a user