Skip to main content

dreamwell_runtime/
presentation.rs

1//! Presentation world — interpolated state for rendering.
2//! Rebuilt each frame from ClientMirror. Never fed back to authority.
3
4/// Presentation-layer world state. Used by DreamFabric for rendering.
5/// Interpolates between tick snapshots for smooth visuals.
6#[derive(Debug, Default)]
7pub struct PresentationWorld {
8    /// Interpolated world-space transforms for rendering.
9    pub transforms: Vec<glam::Mat4>,
10    /// Whether each entity is visible this frame.
11    pub visibility: Vec<bool>,
12}
13
14impl PresentationWorld {
15    pub fn new() -> Self {
16        Self::default()
17    }
18
19    /// Rebuild presentation state from the client mirror.
20    pub fn rebuild_from_mirror(&mut self, mirror: &super::mirror::ClientMirror) {
21        self.transforms.clear();
22        self.visibility.clear();
23        for i in 0..mirror.entity_count {
24            let pos = mirror.positions.get(i).copied().unwrap_or([0.0; 3]);
25            let rot = mirror.rotations.get(i).copied().unwrap_or([0.0, 0.0, 0.0, 1.0]);
26            let q = glam::Quat::from_array(rot);
27            let t = glam::Mat4::from_rotation_translation(q, glam::Vec3::from(pos));
28            self.transforms.push(t);
29            self.visibility.push(true);
30        }
31    }
32
33    pub fn entity_count(&self) -> usize {
34        self.transforms.len()
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::super::mirror::ClientMirror;
41    use super::*;
42
43    #[test]
44    fn rebuild_empty() {
45        let mirror = ClientMirror::new();
46        let mut pres = PresentationWorld::new();
47        pres.rebuild_from_mirror(&mirror);
48        assert_eq!(pres.entity_count(), 0);
49    }
50
51    #[test]
52    fn rebuild_from_snapshot() {
53        let mut mirror = ClientMirror::new();
54        mirror.apply_snapshot(
55            vec![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]],
56            vec![[0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 1.0]],
57        );
58        let mut pres = PresentationWorld::new();
59        pres.rebuild_from_mirror(&mirror);
60        assert_eq!(pres.entity_count(), 2);
61        assert!(pres.visibility.iter().all(|&v| v));
62    }
63}