const CAMERA_CONFIG_TOML: &str = "camera_config.toml";
#[derive(Deserialize)]
#[serde(default, deny_unknown_fields)]
struct CameraSettings {
field_of_view: f32,
distance_multiplier: f32,
render_distance_start: f32,
render_distance_end: f32,
aspect_width: f32,
aspect_height: f32,
}
impl Default for CameraSettings {
fn default() -> Self {
Self {
field_of_view: 48.0,
distance_multiplier: 1.0,
render_distance_start: 0.05,
render_distance_end: 10_000.0,
aspect_width: 16.0,
aspect_height: 9.0,
}
}
}
#[derive(Default)]
struct CameraConfig {
field_of_view: f32,
distance_multiplier: f32,
render_distance_start: f32,
render_distance_end: f32,
aspect_ratio: f32,
is_reloaded: bool,
}
static CAMERA_CONFIG: OnceLock<RwLock<CameraConfig>> = OnceLock::new();
fn get_camera_config() -> &'static RwLock<CameraConfig> {
CAMERA_CONFIG.get_or_init(|| {
let config = read_camera_config();
RwLock::new(config)
})
}
fn read_camera_config() -> CameraConfig {
let mut camera_config = CameraConfig::default();
if let Some(config) = std::env::current_exe().ok().and_then(|path_buf| {
path_buf
.parent()
.map(|path_buf| path_buf.join(CAMERA_CONFIG_TOML))
.and_then(|path_buf| std::fs::read_to_string(path_buf.as_path()).ok())
}) {
let camera_settings = toml::from_str::<CameraSettings>(&config).unwrap_or_default();
camera_config.field_of_view = camera_settings.field_of_view.to_radians();
camera_config.distance_multiplier = camera_settings.distance_multiplier;
camera_config.render_distance_end = camera_settings.render_distance_end;
camera_config.render_distance_start = camera_settings.render_distance_start;
camera_config.aspect_ratio = camera_settings.aspect_width / camera_settings.aspect_height;
}
camera_config
}