mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Optimised entity sync code, increased animation throttling distance
This commit is contained in:
parent
bf66886e7c
commit
6f10a56589
@ -15,9 +15,7 @@ use common::{
|
|||||||
};
|
};
|
||||||
use common_ecs::{Job, Origin, Phase, System};
|
use common_ecs::{Job, Origin, Phase, System};
|
||||||
use common_net::{msg::ServerGeneral, sync::CompSyncPackage};
|
use common_net::{msg::ServerGeneral, sync::CompSyncPackage};
|
||||||
use specs::{
|
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, Write, WriteStorage};
|
||||||
Entities, Entity as EcsEntity, Join, Read, ReadExpect, ReadStorage, Write, WriteStorage,
|
|
||||||
};
|
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
/// This system will send physics updates to the client
|
/// This system will send physics updates to the client
|
||||||
@ -201,22 +199,35 @@ impl<'a> System<'a> for Sys {
|
|||||||
.map(|msg| client.send_prepared(&msg));
|
.map(|msg| client.send_prepared(&msg));
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut send_general = |msg: ServerGeneral,
|
|
||||||
entity: EcsEntity,
|
|
||||||
pos: Pos,
|
|
||||||
force_update: Option<&ForceUpdate>,
|
|
||||||
throttle: bool| {
|
|
||||||
for (client, _, client_entity, client_pos) in &mut subscribers {
|
for (client, _, client_entity, client_pos) in &mut subscribers {
|
||||||
if if client_entity == &entity {
|
let mut comp_sync_package = CompSyncPackage::new();
|
||||||
|
|
||||||
|
for (_, entity, &uid, &pos, vel, ori, force_update, collider) in (
|
||||||
|
region.entities(),
|
||||||
|
&entities,
|
||||||
|
&uids,
|
||||||
|
&positions,
|
||||||
|
velocities.maybe(),
|
||||||
|
orientations.maybe(),
|
||||||
|
force_updates.maybe(),
|
||||||
|
colliders.maybe(),
|
||||||
|
)
|
||||||
|
.join()
|
||||||
|
{
|
||||||
|
// Decide how regularly to send physics updates.
|
||||||
|
let send_now = if client_entity == &entity {
|
||||||
// Don't send client physics updates about itself unless force update is set
|
// Don't send client physics updates about itself unless force update is set
|
||||||
force_update.is_some()
|
force_update.is_some()
|
||||||
} else if !throttle {
|
} else if matches!(collider, Some(Collider::Voxel { .. })) {
|
||||||
// Send the message if not throttling
|
// Things with a voxel collider (airships, etc.) need to have very stable
|
||||||
|
// physics so we always send updated for these where
|
||||||
|
// we can.
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
// Throttle update rate based on distance to client
|
// Throttle update rates for all other entities based on distance to client
|
||||||
let distance_sq = client_pos.0.distance_squared(pos.0);
|
let distance_sq = client_pos.0.distance_squared(pos.0);
|
||||||
let id_staggered_tick = tick + entity.id() as u64;
|
let id_staggered_tick = tick + entity.id() as u64;
|
||||||
|
|
||||||
// More entities farther away so checks start there
|
// More entities farther away so checks start there
|
||||||
if distance_sq > 350.0f32.powi(2) {
|
if distance_sq > 350.0f32.powi(2) {
|
||||||
id_staggered_tick % 64 == 0
|
id_staggered_tick % 64 == 0
|
||||||
@ -231,108 +242,37 @@ impl<'a> System<'a> for Sys {
|
|||||||
} else {
|
} else {
|
||||||
id_staggered_tick % 3 == 0
|
id_staggered_tick % 3 == 0
|
||||||
}
|
}
|
||||||
} {
|
|
||||||
client.send_fallible(msg.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sync physics components
|
if send_now {
|
||||||
for (_, entity, &uid, &pos, maybe_vel, maybe_ori, force_update, collider) in (
|
if last_pos.get(entity).is_none() {
|
||||||
region.entities(),
|
|
||||||
&entities,
|
|
||||||
&uids,
|
|
||||||
&positions,
|
|
||||||
velocities.maybe(),
|
|
||||||
orientations.maybe(),
|
|
||||||
force_updates.maybe(),
|
|
||||||
colliders.maybe(),
|
|
||||||
)
|
|
||||||
.join()
|
|
||||||
{
|
|
||||||
let mut comp_sync_package = CompSyncPackage::new();
|
|
||||||
let mut throttle = true;
|
|
||||||
|
|
||||||
// Extrapolation depends on receiving several frames indicating that something
|
|
||||||
// has stopped in order for the extrapolated value to have
|
|
||||||
// stopped
|
|
||||||
const SEND_UNCHANGED_PHYSICS_DATA: bool = true;
|
|
||||||
|
|
||||||
// TODO: An entity that stopped moving on a tick that it wasn't sent to the
|
|
||||||
// player will never have its position updated
|
|
||||||
match last_pos
|
|
||||||
.get(entity)
|
|
||||||
.map(|&l| l.0 != pos || SEND_UNCHANGED_PHYSICS_DATA)
|
|
||||||
{
|
|
||||||
Some(false) => {},
|
|
||||||
Some(true) => {
|
|
||||||
let _ = last_pos.insert(entity, Last(pos));
|
|
||||||
comp_sync_package.comp_modified(uid, pos);
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
let _ = last_pos.insert(entity, Last(pos));
|
|
||||||
throttle = false;
|
|
||||||
comp_sync_package.comp_inserted(uid, pos);
|
comp_sync_package.comp_inserted(uid, pos);
|
||||||
},
|
let _ = last_pos.insert(entity, Last(pos));
|
||||||
|
} else {
|
||||||
|
comp_sync_package.comp_modified(uid, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(&vel) = maybe_vel {
|
vel.map(|v| {
|
||||||
match last_vel
|
if last_vel.get(entity).is_none() {
|
||||||
.get(entity)
|
comp_sync_package.comp_inserted(uid, *v);
|
||||||
.map(|&l| l.0 != vel || SEND_UNCHANGED_PHYSICS_DATA)
|
let _ = last_vel.insert(entity, Last(*v));
|
||||||
{
|
} else {
|
||||||
Some(false) => {},
|
comp_sync_package.comp_modified(uid, *v);
|
||||||
Some(true) => {
|
}
|
||||||
let _ = last_vel.insert(entity, Last(vel));
|
});
|
||||||
comp_sync_package.comp_modified(uid, vel);
|
|
||||||
},
|
ori.map(|o| {
|
||||||
None => {
|
if last_ori.get(entity).is_none() {
|
||||||
let _ = last_vel.insert(entity, Last(vel));
|
comp_sync_package.comp_inserted(uid, *o);
|
||||||
throttle = false;
|
let _ = last_ori.insert(entity, Last(*o));
|
||||||
comp_sync_package.comp_inserted(uid, vel);
|
} else {
|
||||||
},
|
comp_sync_package.comp_modified(uid, *o);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else if last_vel.remove(entity).is_some() {
|
|
||||||
// Send removal message if Vel was removed
|
|
||||||
// Note: we don't have to handle this for position because the entity will be
|
|
||||||
// removed from the client by the region system
|
|
||||||
throttle = false;
|
|
||||||
comp_sync_package.comp_removed::<Vel>(uid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(&ori) = maybe_ori {
|
client.send_fallible(ServerGeneral::CompSync(comp_sync_package));
|
||||||
match last_ori
|
|
||||||
.get(entity)
|
|
||||||
.map(|&l| l.0 != ori || SEND_UNCHANGED_PHYSICS_DATA)
|
|
||||||
{
|
|
||||||
Some(false) => {},
|
|
||||||
Some(true) => {
|
|
||||||
let _ = last_ori.insert(entity, Last(ori));
|
|
||||||
comp_sync_package.comp_modified(uid, ori);
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
let _ = last_ori.insert(entity, Last(ori));
|
|
||||||
throttle = false;
|
|
||||||
comp_sync_package.comp_inserted(uid, ori);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
} else if last_ori.remove(entity).is_some() {
|
|
||||||
// Send removal message if Ori was removed
|
|
||||||
throttle = false;
|
|
||||||
comp_sync_package.comp_removed::<Ori>(uid);
|
|
||||||
}
|
|
||||||
|
|
||||||
if matches!(collider, Some(Collider::Voxel { .. })) {
|
|
||||||
throttle = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
send_general(
|
|
||||||
ServerGeneral::CompSync(comp_sync_package),
|
|
||||||
entity,
|
|
||||||
pos,
|
|
||||||
force_update,
|
|
||||||
throttle,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -635,7 +635,7 @@ impl FigureMgr {
|
|||||||
// goes further and further away, we start to 'skip' update ticks.
|
// goes further and further away, we start to 'skip' update ticks.
|
||||||
// TODO: Investigate passing the velocity into the shader so we can at least
|
// TODO: Investigate passing the velocity into the shader so we can at least
|
||||||
// interpolate motion
|
// interpolate motion
|
||||||
const MIN_PERFECT_RATE_DIST: f32 = 50.0;
|
const MIN_PERFECT_RATE_DIST: f32 = 100.0;
|
||||||
|
|
||||||
if (i as u64 + tick)
|
if (i as u64 + tick)
|
||||||
% (1 + ((pos.0.distance_squared(focus_pos).powf(0.25)
|
% (1 + ((pos.0.distance_squared(focus_pos).powf(0.25)
|
||||||
|
Loading…
Reference in New Issue
Block a user