veloren_common_systems/
interpolation.rs1use common::{
2 comp::{Ori, Pos, Vel},
3 resources::{PlayerEntity, Time},
4};
5use common_base::prof_span;
6use common_ecs::{Job, Origin, Phase, System};
7use common_net::sync::InterpolatableComponent;
8use specs::{
9 Entities, ParJoin, Read, ReadStorage, SystemData, WriteStorage, prelude::ParallelIterator,
10 shred,
11};
12
13#[derive(SystemData)]
14pub struct ReadData<'a> {
15 time: Read<'a, Time>,
16 player: Read<'a, PlayerEntity>,
17 entities: Entities<'a>,
18 pos_interpdata: ReadStorage<'a, <Pos as InterpolatableComponent>::InterpData>,
19 vel_interpdata: ReadStorage<'a, <Vel as InterpolatableComponent>::InterpData>,
20 ori_interpdata: ReadStorage<'a, <Ori as InterpolatableComponent>::InterpData>,
21}
22
23#[derive(Default)]
24pub struct Sys;
25
26impl<'a> System<'a> for Sys {
27 type SystemData = (
28 ReadData<'a>,
29 WriteStorage<'a, Pos>,
30 WriteStorage<'a, Vel>,
31 WriteStorage<'a, Ori>,
32 );
33
34 const NAME: &'static str = "interpolation";
35 const ORIGIN: Origin = Origin::Common;
36 const PHASE: Phase = Phase::Apply;
37
38 fn run(_job: &mut Job<Self>, (data, mut pos, mut vel, mut ori): Self::SystemData) {
39 let time = data.time.0;
40 let player = data.player.0;
41
42 (
43 &data.entities,
44 &mut pos,
45 &data.pos_interpdata,
46 &data.vel_interpdata,
47 )
48 .par_join()
49 .filter(|(e, _, _, _)| Some(e) != player.as_ref())
50 .for_each_init(
51 || {
52 prof_span!(guard, "interpolate pos rayon job");
53 guard
54 },
55 |_guard, (_, pos, interp, vel)| {
56 *pos = pos.interpolate(interp, time, vel);
57 },
58 );
59 (&data.entities, &mut vel, &data.vel_interpdata)
60 .par_join()
61 .filter(|(e, _, _)| Some(e) != player.as_ref())
62 .for_each_init(
63 || {
64 prof_span!(guard, "interpolate vel rayon job");
65 guard
66 },
67 |_guard, (_, vel, interp)| {
68 *vel = vel.interpolate(interp, time, &());
69 },
70 );
71 (&data.entities, &mut ori, &data.ori_interpdata)
72 .par_join()
73 .filter(|(e, _, _)| Some(e) != player.as_ref())
74 .for_each_init(
75 || {
76 prof_span!(guard, "interpolate ori rayon job");
77 guard
78 },
79 |_guard, (_, ori, interp)| {
80 *ori = ori.interpolate(interp, time, &());
81 },
82 );
83 }
84}