Add machinery for storing component buffers for interpolation.

This commit is contained in:
Avi Weinstock 2021-03-12 21:53:19 -05:00
parent f6c6319952
commit a71bacdce0
7 changed files with 72 additions and 7 deletions

1
Cargo.lock generated
View File

@ -5619,6 +5619,7 @@ dependencies = [
"hashbrown",
"serde",
"specs",
"specs-idvs",
"sum_type",
"tracing",
"vek 0.14.1",

View File

@ -25,6 +25,7 @@ authc = { git = "https://gitlab.com/veloren/auth.git", rev = "fb3dcbc4962b367253
# ECS
specs = { git = "https://github.com/amethyst/specs.git", features = ["serde", "storage-event-control"], rev = "5a9b71035007be0e3574f35184acac1cd4530496" }
specs-idvs = { git = "https://gitlab.com/veloren/specs-idvs.git", rev = "b65fb220e94f5d3c9bc30074a076149763795556" }
# Serde
serde = { version = "1.0.110", features = ["derive"] }
serde = { version = "1.0.110", features = ["derive"] }

View File

@ -100,7 +100,7 @@ impl sync::CompPacket for EcsCompPacket {
EcsCompPacket::Gravity(comp) => sync::handle_insert(comp, entity, world),
EcsCompPacket::Sticky(comp) => sync::handle_insert(comp, entity, world),
EcsCompPacket::CharacterState(comp) => sync::handle_insert(comp, entity, world),
EcsCompPacket::Pos(comp) => sync::handle_insert(comp, entity, world),
EcsCompPacket::Pos(comp) => sync::handle_interp_insert(comp, entity, world),
EcsCompPacket::Vel(comp) => sync::handle_insert(comp, entity, world),
EcsCompPacket::Ori(comp) => sync::handle_insert(comp, entity, world),
EcsCompPacket::Shockwave(comp) => sync::handle_insert(comp, entity, world),
@ -132,7 +132,7 @@ impl sync::CompPacket for EcsCompPacket {
EcsCompPacket::Gravity(comp) => sync::handle_modify(comp, entity, world),
EcsCompPacket::Sticky(comp) => sync::handle_modify(comp, entity, world),
EcsCompPacket::CharacterState(comp) => sync::handle_modify(comp, entity, world),
EcsCompPacket::Pos(comp) => sync::handle_modify(comp, entity, world),
EcsCompPacket::Pos(comp) => sync::handle_interp_modify(comp, entity, world),
EcsCompPacket::Vel(comp) => sync::handle_modify(comp, entity, world),
EcsCompPacket::Ori(comp) => sync::handle_modify(comp, entity, world),
EcsCompPacket::Shockwave(comp) => sync::handle_modify(comp, entity, world),
@ -168,7 +168,7 @@ impl sync::CompPacket for EcsCompPacket {
EcsCompPhantom::CharacterState(_) => {
sync::handle_remove::<comp::CharacterState>(entity, world)
},
EcsCompPhantom::Pos(_) => sync::handle_remove::<comp::Pos>(entity, world),
EcsCompPhantom::Pos(_) => sync::handle_interp_remove::<comp::Pos>(entity, world),
EcsCompPhantom::Vel(_) => sync::handle_remove::<comp::Vel>(entity, world),
EcsCompPhantom::Ori(_) => sync::handle_remove::<comp::Ori>(entity, world),
EcsCompPhantom::Shockwave(_) => sync::handle_remove::<comp::Shockwave>(entity, world),

View File

@ -0,0 +1,26 @@
// impls of `InterpolatableComponent` on things defined in `common`, since `common_net` is
// downstream of `common`
use common::comp::{Pos, Vel};
use super::InterpolatableComponent;
use specs::{Component, Entity, World};
use specs_idvs::IdvStorage;
use vek::Vec3;
#[derive(Default)]
pub struct PosBuffer(pub [Vec3<f32>; 4]);
impl Component for PosBuffer {
type Storage = IdvStorage<Self>;
}
impl InterpolatableComponent for Pos {
type InterpData = PosBuffer;
fn interpolate(self, data: &mut Self::InterpData, entity: Entity, world: &World) -> Self {
for i in 0..data.0.len()-1 {
data.0[i] = data.0[i+1];
}
data.0[data.0.len()-1] = self.0;
self
}
}

View File

@ -1,5 +1,6 @@
// Note: Currently only one-way sync is supported until a usecase for two-way
// sync arises
pub mod interpolation;
mod packet;
mod sync_ext;
mod track;
@ -7,8 +8,9 @@ mod track;
// Reexports
pub use common::uid::{Uid, UidAllocator};
pub use packet::{
handle_insert, handle_modify, handle_remove, CompPacket, CompSyncPackage, EntityPackage,
EntitySyncPackage, StatePackage,
handle_insert, handle_interp_insert, handle_interp_modify, handle_interp_remove, handle_modify,
handle_remove, CompPacket, CompSyncPackage, EntityPackage, EntitySyncPackage,
InterpolatableComponent, StatePackage,
};
pub use sync_ext::WorldSyncExt;
pub use track::UpdateTracker;

View File

@ -42,6 +42,40 @@ pub fn handle_remove<C: Component>(entity: Entity, world: &World) {
world.write_storage::<C>().remove(entity);
}
pub trait InterpolatableComponent: Component {
type InterpData: Component + Default;
fn interpolate(self, data: &mut Self::InterpData, entity: Entity, world: &World) -> Self;
}
pub fn handle_interp_insert<C: InterpolatableComponent>(comp: C, entity: Entity, world: &World) {
let mut interp_data = C::InterpData::default();
let comp = comp.interpolate(&mut interp_data, entity, world);
handle_insert(comp, entity, world);
handle_insert(interp_data, entity, world);
}
pub fn handle_interp_modify<C: InterpolatableComponent + Debug>(
comp: C,
entity: Entity,
world: &World,
) {
if let Some(mut interp_data) = world.write_storage::<C::InterpData>().get_mut(entity) {
let comp = comp.interpolate(&mut interp_data, entity, world);
handle_modify(comp, entity, world);
} else {
error!(
?comp,
"Error modifying interpolation data for synced component, it doesn't seem to exist"
);
}
}
pub fn handle_interp_remove<C: InterpolatableComponent>(entity: Entity, world: &World) {
handle_remove::<C>(entity, world);
handle_remove::<C::InterpData>(entity, world);
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub enum CompUpdateKind<P: CompPacket> {
Inserted(P),

View File

@ -15,7 +15,7 @@ use common::{
};
use common_base::span;
use common_ecs::{PhysicsMetrics, SysMetrics};
use common_net::sync::WorldSyncExt;
use common_net::sync::{interpolation, WorldSyncExt};
use hashbrown::{HashMap, HashSet};
use rayon::{ThreadPool, ThreadPoolBuilder};
use specs::{
@ -164,6 +164,7 @@ impl State {
// Register client-local components
// TODO: only register on the client
ecs.register::<comp::LightAnimation>();
ecs.register::<interpolation::PosBuffer>();
// Register server-local components
// TODO: only register on the server