Skip to main content

concinnity_core/components/
cubemap_texture.rs

1// HDR cubemap texture schema.
2
3use crate::ecs::PayloadLocator;
4use crate::ecs::asset_id::AssetId;
5use alloc::string::String;
6
7/// A six-face HDR cubemap baked from an equirectangular Radiance HDR source.
8///
9/// The build resamples the source into six square HDR faces of `face_size`
10/// pixels each, used as an environment / image-based-lighting source.
11///
12/// ```rust
13/// # use concinnity_core::components::CubemapTexture;
14/// CubemapTexture {
15///     source: "assets/hdri/studio.hdr".into(),
16///     face_size: 512,
17///     ..Default::default()
18/// };
19/// ```
20#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
21#[serde(default)]
22pub struct CubemapTexture {
23    /// Asset identity; injected via `inject_name`. Not part of `args`.
24    #[serde(skip)]
25    pub asset_id: AssetId,
26    /// Path to the source equirectangular HDR (`.hdr`) file, relative to the
27    /// project root.
28    pub source: String,
29    /// Edge length of each cube face in pixels. Must be a power of two.
30    pub face_size: u32,
31    /// Injected at load time from the compiled blob payload.
32    #[serde(skip)]
33    pub locator: Option<PayloadLocator>,
34}
35
36impl Default for CubemapTexture {
37    fn default() -> Self {
38        Self {
39            asset_id: AssetId::default(),
40            source: String::new(),
41            face_size: 256,
42            locator: None,
43        }
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn a_blank_cubemap_bakes_at_the_default_face_size() {
53        let c = CubemapTexture::default();
54        assert!(c.source.is_empty());
55        assert_eq!(c.face_size, 256);
56        assert_eq!(c.asset_id, AssetId::default());
57        assert!(c.locator.is_none());
58    }
59
60    #[test]
61    fn an_authored_face_size_parses_and_round_trips_through_postcard() {
62        let c: CubemapTexture =
63            serde_json::from_str(r#"{"source":"sky.hdr","face_size":1024}"#).unwrap();
64        assert_eq!(c.source, "sky.hdr");
65        assert_eq!(c.face_size, 1024);
66
67        let bytes = postcard::to_allocvec(&c).unwrap();
68        let back: CubemapTexture = postcard::from_bytes(&bytes).unwrap();
69        assert_eq!(back.face_size, 1024);
70        // Identity and payload location are injected, never carried on the wire.
71        assert_eq!(back.asset_id, AssetId::default());
72        assert!(back.locator.is_none());
73    }
74}