veloren_common_systems/
interpolation.rs

1use 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}