dreamwell-runtime 1.0.0

Dreamwell Runtime — cross-platform GPU-accelerated game client
Documentation
//! Presentation world — interpolated state for rendering.
//! Rebuilt each frame from ClientMirror. Never fed back to authority.

/// Presentation-layer world state. Used by DreamFabric for rendering.
/// Interpolates between tick snapshots for smooth visuals.
#[derive(Debug, Default)]
pub struct PresentationWorld {
    /// Interpolated world-space transforms for rendering.
    pub transforms: Vec<glam::Mat4>,
    /// Whether each entity is visible this frame.
    pub visibility: Vec<bool>,
}

impl PresentationWorld {
    pub fn new() -> Self {
        Self::default()
    }

    /// Rebuild presentation state from the client mirror.
    pub fn rebuild_from_mirror(&mut self, mirror: &super::mirror::ClientMirror) {
        self.transforms.clear();
        self.visibility.clear();
        for i in 0..mirror.entity_count {
            let pos = mirror.positions.get(i).copied().unwrap_or([0.0; 3]);
            let rot = mirror.rotations.get(i).copied().unwrap_or([0.0, 0.0, 0.0, 1.0]);
            let q = glam::Quat::from_array(rot);
            let t = glam::Mat4::from_rotation_translation(q, glam::Vec3::from(pos));
            self.transforms.push(t);
            self.visibility.push(true);
        }
    }

    pub fn entity_count(&self) -> usize {
        self.transforms.len()
    }
}

#[cfg(test)]
mod tests {
    use super::super::mirror::ClientMirror;
    use super::*;

    #[test]
    fn rebuild_empty() {
        let mirror = ClientMirror::new();
        let mut pres = PresentationWorld::new();
        pres.rebuild_from_mirror(&mirror);
        assert_eq!(pres.entity_count(), 0);
    }

    #[test]
    fn rebuild_from_snapshot() {
        let mut mirror = ClientMirror::new();
        mirror.apply_snapshot(
            vec![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]],
            vec![[0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 1.0]],
        );
        let mut pres = PresentationWorld::new();
        pres.rebuild_from_mirror(&mirror);
        assert_eq!(pres.entity_count(), 2);
        assert!(pres.visibility.iter().all(|&v| v));
    }
}