Add an entity view distance setting that allows limiting the distance

entities are synced from and displayed in.

NOTE: Syncing entities work at the granularity regions which are
multi-chunk squares but the display of entities in voxygen is limited in
a circle with the radiues of the supplied distance.

Additional details and changes:
* Added `ViewDistances` struct in `common` that contains separate
  terrain and entity view distances (the entity view distance will be
  clamped by the terrain view distance in uses of this).
* View distance requests from the client to the server now use this
  type.
* When requesting the character or spectate state the client now passes
  its desired view distances. This is exposed as a new parameter on
  `Client::request_character`/`Client::request_spectate`. And the client
  no longer needs to send a view distance request after entering these
  states. This also allows us to avoid needing to initialize `Presence`
  with a default view distance value on the server.
* Removed `DerefFlaggedStorage` from `Presence` and `RegionSubscription` since the
  change tracking isn't used for these components.
* Add sliders in voxygen graphics and network tabs for this new setting.
  Show the clamped value as well as the selected value next to the
  slider.
* Rename existing "Entities View Distance" slider (which AFAIK controls
  the distance at which different LOD levels apply to figures) to
  "Entities Detail Distance" so we can use the former name for this new
  slider.
This commit is contained in:
Imbris
2022-08-21 23:21:39 -04:00
parent 895d6a2d8b
commit 334937568e
26 changed files with 435 additions and 219 deletions

View File

@ -26,6 +26,7 @@ use common::{
resources::{Time, TimeOfDay},
slowjob::SlowJobPool,
uid::{Uid, UidAllocator},
ViewDistances,
};
use common_net::{
msg::{CharacterInfo, PlayerListUpdate, PresenceKind, ServerGeneral},
@ -107,9 +108,14 @@ pub trait StateExt {
index: &world::IndexOwned,
) -> EcsEntityBuilder;
/// Insert common/default components for a new character joining the server
fn initialize_character_data(&mut self, entity: EcsEntity, character_id: CharacterId);
fn initialize_character_data(
&mut self,
entity: EcsEntity,
character_id: CharacterId,
view_distances: ViewDistances,
);
/// Insert common/default components for a new spectator joining the server
fn initialize_spectator_data(&mut self, entity: EcsEntity);
fn initialize_spectator_data(&mut self, entity: EcsEntity, view_distances: ViewDistances);
/// Update the components associated with the entity's current character.
/// Performed after loading component data from the database
fn update_character_data(&mut self, entity: EcsEntity, components: PersistedComponents);
@ -488,10 +494,21 @@ impl StateExt for State {
self.ecs_mut()
.create_entity_synced()
.with(pos)
.with(Presence::new(view_distance, PresenceKind::Spectator))
.with(Presence::new(
ViewDistances {
terrain: view_distance,
entity: view_distance,
},
PresenceKind::Spectator,
))
}
fn initialize_character_data(&mut self, entity: EcsEntity, character_id: CharacterId) {
fn initialize_character_data(
&mut self,
entity: EcsEntity,
character_id: CharacterId,
view_distances: ViewDistances,
) {
let spawn_point = self.ecs().read_resource::<SpawnPoint>().0;
if let Some(player_uid) = self.read_component_copied::<Uid>(entity) {
@ -519,10 +536,9 @@ impl StateExt for State {
// Make sure physics components are updated
self.write_component_ignore_entity_dead(entity, comp::ForceUpdate::forced());
const INITIAL_VD: u32 = 5; // will be changed after login
self.write_component_ignore_entity_dead(
entity,
Presence::new(INITIAL_VD, PresenceKind::Character(character_id)),
Presence::new(view_distances, PresenceKind::Character(character_id)),
);
// Tell the client its request was successful.
@ -532,7 +548,7 @@ impl StateExt for State {
}
}
fn initialize_spectator_data(&mut self, entity: EcsEntity) {
fn initialize_spectator_data(&mut self, entity: EcsEntity, view_distances: ViewDistances) {
let spawn_point = self.ecs().read_resource::<SpawnPoint>().0;
if self.read_component_copied::<Uid>(entity).is_some() {
@ -545,10 +561,9 @@ impl StateExt for State {
// Make sure physics components are updated
self.write_component_ignore_entity_dead(entity, comp::ForceUpdate::forced());
const INITIAL_VD: u32 = 5; //will be changed after login
self.write_component_ignore_entity_dead(
entity,
Presence::new(INITIAL_VD, PresenceKind::Spectator),
Presence::new(view_distances, PresenceKind::Spectator),
);
// Tell the client its request was successful.