use crate::core::color::CreateRGBToSpectrumTable; use once_cell::sync::Lazy; use shared::core::color::{RGBToSpectrumTable, RES}; use shared::Float; use shared::PBRTOptions; use std::sync::OnceLock; static OPTIONS: OnceLock = OnceLock::new(); pub fn init_pbrt(options: PBRTOptions) { OPTIONS .set(options) .expect("PBRT has already been initialized!"); } pub fn get_options() -> &'static PBRTOptions { OPTIONS.get().unwrap_or_else(|| { static DEFAULT: OnceLock = OnceLock::new(); DEFAULT.get_or_init(PBRTOptions::default) }) } fn aligned_cast(bytes: &[u8]) -> &[Float] { match bytemuck::try_cast_slice(bytes) { Ok(s) => s, Err(_) => { let v: Vec = bytemuck::pod_collect_to_vec(bytes); Box::leak(v.into_boxed_slice()) } } } static SRGB_SCALE_BYTES: &[u8] = include_bytes!("../data/srgb_scale.dat"); static SRGB_COEFFS_BYTES: &[u8] = include_bytes!("../data/srgb_coeffs.dat"); static DCI_P3_SCALE_BYTES: &[u8] = include_bytes!("../data/dcip3_scale.dat"); static DCI_P3_COEFFS_BYTES: &[u8] = include_bytes!("../data/dcip3_coeffs.dat"); static ACES_SCALE_BYTES: &[u8] = include_bytes!("../data/aces_scale.dat"); static ACES_COEFFS_BYTES: &[u8] = include_bytes!("../data/aces_coeffs.dat"); static REC2020_SCALE_BYTES: &[u8] = include_bytes!("../data/rec2020_scale.dat"); static REC2020_COEFFS_BYTES: &[u8] = include_bytes!("../data/rec2020_coeffs.dat"); fn strip_to_len(bytes: &[u8], expected_len: usize) -> &'static [Float] { let all: Vec = bytemuck::pod_collect_to_vec(bytes); let skip = all.len() - expected_len; let data = all[skip..].to_vec(); Box::leak(data.into_boxed_slice()) } const COEFFS_LEN: usize = (RES * RES * RES) as usize * 3 * 3; pub static SRGB_SCALE: Lazy<&[Float]> = Lazy::new(|| strip_to_len(SRGB_SCALE_BYTES, RES as usize)); pub static SRGB_COEFFS: Lazy<&[Float]> = Lazy::new(|| strip_to_len(SRGB_COEFFS_BYTES, COEFFS_LEN)); pub static DCI_P3_SCALE: Lazy<&[Float]> = Lazy::new(|| strip_to_len(DCI_P3_SCALE_BYTES, RES as usize)); pub static DCI_P3_COEFFS: Lazy<&[Float]> = Lazy::new(|| strip_to_len(DCI_P3_COEFFS_BYTES, COEFFS_LEN)); pub static ACES_SCALE: Lazy<&[Float]> = Lazy::new(|| strip_to_len(ACES_SCALE_BYTES, RES as usize)); pub static ACES_COEFFS: Lazy<&[Float]> = Lazy::new(|| strip_to_len(ACES_COEFFS_BYTES, COEFFS_LEN)); pub static REC2020_SCALE: Lazy<&[Float]> = Lazy::new(|| strip_to_len(REC2020_SCALE_BYTES, RES as usize)); pub static REC2020_COEFFS: Lazy<&[Float]> = Lazy::new(|| strip_to_len(REC2020_COEFFS_BYTES, COEFFS_LEN)); pub static SRGB_TABLE: Lazy = Lazy::new(|| RGBToSpectrumTableData::new(SRGB_SCALE, SRGB_COEFFS)); pub static DCI_P3_TABLE: Lazy = Lazy::new(|| RGBToSpectrumTableData::new(DCI_P3_SCALE.to_vec(), DCI_P3_COEFFS.to_vec())); pub static REC2020_TABLE: Lazy = Lazy::new(|| RGBToSpectrumTableData::new(REC2020_SCALE.to_vec(), REC2020_COEFFS.to_vec())); pub static ACES_TABLE: Lazy = Lazy::new(|| RGBToSpectrumTableData::new(ACES_SCALE.to_vec(), ACES_COEFFS.to_vec()));