diff --git a/src/cfg/scene.rs b/src/cfg/scene.rs index 574f514..a3bd8ee 100644 --- a/src/cfg/scene.rs +++ b/src/cfg/scene.rs @@ -89,6 +89,12 @@ pub struct CfgCamera { #[serde(default)] pub projection: ProjectionMode, + + #[serde(default)] + pub near: Option, + + #[serde(default)] + pub far: Option, } impl CfgCamera { @@ -110,6 +116,8 @@ impl Default for CfgCamera { anchor: default_camera_anchor(), up: default_camera_up(), projection: ProjectionMode::default(), + near: None, + far: None, } } } diff --git a/src/cfg/spice.rs b/src/cfg/spice.rs index 5a4536f..0188574 100644 --- a/src/cfg/spice.rs +++ b/src/cfg/spice.rs @@ -4,6 +4,8 @@ use serde::{Deserialize, Serialize}; use snafu::prelude::*; use std::path::PathBuf; +pub const DEFAULT_FRAME: &str = "ECLIPJ2000"; + pub type CfgSpiceResult = std::result::Result; /// Errors related to Kalast config. @@ -15,21 +17,21 @@ pub struct CfgSpice { #[serde(default)] pub kernel: Option, - #[serde(default = "default_frame")] - pub frame: String, + #[serde(default)] + pub frame: Option, + + #[serde(default)] + pub origin: Option, } impl Default for CfgSpice { fn default() -> Self { Self { kernel: None, - frame: default_frame(), + frame: None, + origin: None, } } } impl Configuration for CfgSpice {} - -pub fn default_frame() -> String { - "ECLIPJ2000".to_string() -} diff --git a/src/simu/routines/core.rs b/src/simu/routines/core.rs index 1f0fdd3..decd7a0 100644 --- a/src/simu/routines/core.rs +++ b/src/simu/routines/core.rs @@ -3,7 +3,7 @@ use crate::{ find_ref_orbit, matrix_orientation_obliquity, matrix_spin, position_in_inertial_frame, update_colormap_scalar, util::*, AirlessBody, BodyData, Cfg, CfgBody, CfgCamera, CfgCameraDirection, CfgCameraPosition, CfgFrameCenter, CfgScalar, CfgState, CfgStateCartesian, - CfgSun, CfgSunPosition, FoldersRun, MovementMode, Time, Window, WindowScene, + CfgSun, CfgSunPosition, FoldersRun, MovementMode, Time, Window, WindowScene, DEFAULT_FRAME, }; use downcast_rs::{impl_downcast, DowncastSync}; @@ -40,7 +40,11 @@ pub trait Routines: DowncastSync { let (position, _lt) = spice::spkpos( "Sun", elapsed_from_start as f64, - &cfg.spice.frame, + &cfg.spice + .frame + .as_ref() + .cloned() + .unwrap_or(DEFAULT_FRAME.to_string()), "none", &body.id, ); @@ -114,7 +118,11 @@ pub trait Routines: DowncastSync { let (position, _lt) = spice::spkpos( _name, elapsed_from_start as f64, - &cfg.spice.frame, + &cfg.spice + .frame + .as_ref() + .cloned() + .unwrap_or(DEFAULT_FRAME.to_string()), "none", &_body.id, ); @@ -173,6 +181,14 @@ pub trait Routines: DowncastSync { scene.camera.up = cfg.scene.camera.up; scene.camera.up_world = cfg.scene.camera.up; scene.camera.projection = cfg.scene.camera.projection; + + if let Some(near) = cfg.scene.camera.near { + scene.camera.near = Some(near); + } + + if let Some(far) = cfg.scene.camera.far { + scene.camera.far = Some(far); + } } } @@ -306,9 +322,14 @@ pub trait Routines: DowncastSync { #[cfg(feature = "spice")] { let position = { - if let Some(origin) = &_spice.origin { - let frame_to = - _spice.into_frame.clone().unwrap_or(cfg.spice.frame.clone()); + if let Some(origin) = &_spice.origin.as_ref().or(cfg.spice.origin.as_ref()) + { + let frame_to = _spice + .into_frame + .as_ref() + .or(cfg.spice.frame.as_ref()) + .cloned() + .unwrap_or(DEFAULT_FRAME.to_string()); let (position, _lt) = spice::spkpos( &cfg.bodies[body].id, elapsed_from_start as f64, @@ -324,8 +345,12 @@ pub trait Routines: DowncastSync { let rotation = { if let Some(frame) = &_spice.frame { - let frame_to = - _spice.into_frame.clone().unwrap_or(cfg.spice.frame.clone()); + let frame_to = _spice + .into_frame + .as_ref() + .or(cfg.spice.frame.as_ref()) + .cloned() + .unwrap_or(DEFAULT_FRAME.to_string()); let rotation = spice::pxform(&frame, &frame_to, elapsed_from_start as f64); Mat3::from_row_slice(&rotation.iter().cloned().flatten().collect_vec()) diff --git a/src/win/camera.rs b/src/win/camera.rs index 4312fc4..5fd87a2 100644 --- a/src/win/camera.rs +++ b/src/win/camera.rs @@ -49,16 +49,13 @@ impl Default for ProjectionMode { } impl ProjectionMode { - pub fn matrix(&self, distance: Float, aspect: Float) -> Mat4 { - let side = distance; - let zfar = distance * FAR_FACTOR; - let znear = zfar * NEAR_FACTOR; - + pub fn matrix(&self, near: Float, far: Float, aspect: Float) -> Mat4 { match self { ProjectionMode::Orthographic => { - glm::ortho(side * aspect, side * aspect, side, side, znear, zfar) + let side = far; + glm::ortho(side * aspect, side * aspect, side, side, near, far) } - ProjectionMode::Perspective(fovy) => glm::perspective(aspect, *fovy, znear, zfar), + ProjectionMode::Perspective(fovy) => glm::perspective(aspect, *fovy, near, far), } } } @@ -72,6 +69,8 @@ pub struct Camera { pub projection: ProjectionMode, pub movement_mode: MovementMode, pub up_world: Vec3, + pub near: Option, + pub far: Option, } impl Camera { @@ -84,6 +83,8 @@ impl Camera { projection: ProjectionMode::default(), movement_mode: MovementMode::Lock, up_world: UP, + near: None, + far: None, } } @@ -128,7 +129,21 @@ impl Camera { } pub fn matrix_projection(&self, aspect: Float) -> Mat4 { - self.projection.matrix(self.position.magnitude(), aspect) + let distance = self.position.magnitude(); + + let near = if let Some(near) = self.near { + near + } else { + distance * NEAR_FACTOR + }; + + let far = if let Some(far) = self.far { + far + } else { + distance * FAR_FACTOR + }; + + self.projection.matrix(near, far, aspect) } pub fn reset_anchor(&mut self) { diff --git a/src/win/lighting.rs b/src/win/lighting.rs index 8e4575b..5d2c25c 100644 --- a/src/win/lighting.rs +++ b/src/win/lighting.rs @@ -1,4 +1,4 @@ -use crate::{util::*, ProjectionMode, Shapes, Surface}; +use crate::{util::*, ProjectionMode, Shapes, Surface, FAR_FACTOR, NEAR_FACTOR}; /// The lighting manager. /// @@ -32,6 +32,9 @@ impl Light { } pub fn matrix_projection(&self, aspect: Float) -> Mat4 { - self.projection.matrix(self.position.magnitude(), aspect) + let distance = self.position.magnitude(); + let near = distance * NEAR_FACTOR; + let far = distance * FAR_FACTOR; + self.projection.matrix(near, far, aspect) } }