#[cfg(feature = "serde")]
use serde::Serialize;
use crate::raw::drawing::{scene::camera::XlsxCamera, st_types::st_angle_to_degree};
use super::rotation::Rotation;
#[cfg_attr(feature = "serde", derive(Serialize))]
#[derive(Debug, PartialEq, Clone)]
pub struct Camera {
pub preset: PresetCameraValues,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub rotation: Option<Rotation>,
pub perspective: f64,
}
impl Camera {
pub(crate) fn from_raw(raw: Option<XlsxCamera>) -> Option<Self> {
let Some(raw) = raw else { return None };
if raw.prst.is_none() && raw.rot.is_none() {
return None;
};
let preset = PresetCameraValues::from_string(raw.clone().prst);
let rotation = Rotation::from_camera(raw.clone().rot, Some(preset.clone()));
let perspective = if let Some(p) = raw.clone().fov {
st_angle_to_degree(p)
} else {
Self::perspective_from_preset(preset.clone())
};
return Some(Self {
preset,
rotation,
perspective,
});
}
fn perspective_from_preset(preset: PresetCameraValues) -> f64 {
match preset {
PresetCameraValues::IsometricBottomDown => 0.0,
PresetCameraValues::IsometricBottomUp => 0.0,
PresetCameraValues::IsometricLeftDown => 0.0,
PresetCameraValues::IsometricLeftUp => 0.0,
PresetCameraValues::IsometricOffAxis1Left => 0.0,
PresetCameraValues::IsometricOffAxis1Right => 0.0,
PresetCameraValues::IsometricOffAxis1Top => 0.0,
PresetCameraValues::IsometricOffAxis2Left => 0.0,
PresetCameraValues::IsometricOffAxis2Right => 0.0,
PresetCameraValues::IsometricOffAxis2Top => 0.0,
PresetCameraValues::IsometricOffAxis3Bottom => 0.0,
PresetCameraValues::IsometricOffAxis3Left => 0.0,
PresetCameraValues::IsometricOffAxis3Right => 0.0,
PresetCameraValues::IsometricOffAxis4Bottom => 0.0,
PresetCameraValues::IsometricOffAxis4Left => 0.0,
PresetCameraValues::IsometricOffAxis4Right => 0.0,
PresetCameraValues::IsometricRightDown => 0.0,
PresetCameraValues::IsometricRightUp => 0.0,
PresetCameraValues::IsometricTopDown => 0.0,
PresetCameraValues::IsometricTopUp => 0.0,
PresetCameraValues::LegacyObliqueBottom => 0.0,
PresetCameraValues::LegacyObliqueBottomLeft => 0.0,
PresetCameraValues::LegacyObliqueBottomRight => 0.0,
PresetCameraValues::LegacyObliqueFront => 0.0,
PresetCameraValues::LegacyObliqueLeft => 0.0,
PresetCameraValues::LegacyObliqueRight => 0.0,
PresetCameraValues::LegacyObliqueTop => 0.0,
PresetCameraValues::LegacyObliqueTopLeft => 0.0,
PresetCameraValues::LegacyObliqueTopRight => 0.0,
PresetCameraValues::LegacyPerspectiveBottom => 45.0,
PresetCameraValues::LegacyPerspectiveBottomLeft => 0.0,
PresetCameraValues::LegacyPerspectiveBottomRight => 0.0,
PresetCameraValues::LegacyPerspectiveFront => 45.0,
PresetCameraValues::LegacyPerspectiveLeft => 45.0,
PresetCameraValues::LegacyPerspectiveRight => 45.0,
PresetCameraValues::LegacyPerspectiveTop => 45.0,
PresetCameraValues::LegacyPerspectiveTopLeft => 0.0,
PresetCameraValues::LegacyPerspectiveTopRight => 0.0,
PresetCameraValues::ObliqueBottom => 0.0,
PresetCameraValues::ObliqueBottomLeft => 0.0,
PresetCameraValues::ObliqueBottomRight => 0.0,
PresetCameraValues::ObliqueLeft => 0.0,
PresetCameraValues::ObliqueRight => 0.0,
PresetCameraValues::ObliqueTop => 0.0,
PresetCameraValues::ObliqueTopLeft => 0.0,
PresetCameraValues::ObliqueTopRight => 0.0,
PresetCameraValues::OrthographicFront => 0.0,
PresetCameraValues::PerspectiveAbove => 45.0,
PresetCameraValues::PerspectiveAboveLeftFacing => 0.0,
PresetCameraValues::PerspectiveAboveRightFacing => 0.0,
PresetCameraValues::PerspectiveBelow => 45.0,
PresetCameraValues::PerspectiveContrastingLeftFacing => 45.0,
PresetCameraValues::PerspectiveContrastingRightFacing => 45.0,
PresetCameraValues::PerspectiveFront => 45.0,
PresetCameraValues::PerspectiveHeroicExtremeLeftFacing => 80.0,
PresetCameraValues::PerspectiveHeroicExtremeRightFacing => 80.0,
PresetCameraValues::PerspectiveHeroicLeftFacing => 0.0,
PresetCameraValues::PerspectiveHeroicRightFacing => 0.0,
PresetCameraValues::PerspectiveLeft => 45.0,
PresetCameraValues::PerspectiveRelaxed => 45.0,
PresetCameraValues::PerspectiveRelaxedModerately => 45.0,
PresetCameraValues::PerspectiveRight => 45.0,
}
}
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum PresetCameraValues {
IsometricBottomDown,
IsometricBottomUp,
IsometricLeftDown,
IsometricLeftUp,
IsometricOffAxis1Left,
IsometricOffAxis1Right,
IsometricOffAxis1Top,
IsometricOffAxis2Left,
IsometricOffAxis2Right,
IsometricOffAxis2Top,
IsometricOffAxis3Bottom,
IsometricOffAxis3Left,
IsometricOffAxis3Right,
IsometricOffAxis4Bottom,
IsometricOffAxis4Left,
IsometricOffAxis4Right,
IsometricRightDown,
IsometricRightUp,
IsometricTopDown,
IsometricTopUp,
LegacyObliqueBottom,
LegacyObliqueBottomLeft,
LegacyObliqueBottomRight,
LegacyObliqueFront,
LegacyObliqueLeft,
LegacyObliqueRight,
LegacyObliqueTop,
LegacyObliqueTopLeft,
LegacyObliqueTopRight,
LegacyPerspectiveBottom,
LegacyPerspectiveBottomLeft,
LegacyPerspectiveBottomRight,
LegacyPerspectiveFront,
LegacyPerspectiveLeft,
LegacyPerspectiveRight,
LegacyPerspectiveTop,
LegacyPerspectiveTopLeft,
LegacyPerspectiveTopRight,
ObliqueBottom,
ObliqueBottomLeft,
ObliqueBottomRight,
ObliqueLeft,
ObliqueRight,
ObliqueTop,
ObliqueTopLeft,
ObliqueTopRight,
OrthographicFront,
PerspectiveAbove,
PerspectiveAboveLeftFacing,
PerspectiveAboveRightFacing,
PerspectiveBelow,
PerspectiveContrastingLeftFacing,
PerspectiveContrastingRightFacing,
PerspectiveFront,
PerspectiveHeroicExtremeLeftFacing,
PerspectiveHeroicExtremeRightFacing,
PerspectiveHeroicLeftFacing,
PerspectiveHeroicRightFacing,
PerspectiveLeft,
PerspectiveRelaxed,
PerspectiveRelaxedModerately,
PerspectiveRight,
}
impl PresetCameraValues {
pub(crate) fn default() -> Self {
Self::OrthographicFront
}
pub(crate) fn from_string(s: Option<String>) -> Self {
let Some(s) = s else { return Self::default() };
return match s.as_ref() {
"isometricBottomDown" => Self::IsometricBottomDown,
"isometricBottomUp" => Self::IsometricBottomUp,
"isometricLeftDown" => Self::IsometricLeftDown,
"isometricLeftUp" => Self::IsometricLeftUp,
"isometricOffAxis1Left" => Self::IsometricOffAxis1Left,
"isometricOffAxis1Right" => Self::IsometricOffAxis1Right,
"isometricOffAxis1Top" => Self::IsometricOffAxis1Top,
"isometricOffAxis2Left" => Self::IsometricOffAxis2Left,
"isometricOffAxis2Right" => Self::IsometricOffAxis2Right,
"isometricOffAxis2Top" => Self::IsometricOffAxis2Top,
"isometricOffAxis3Bottom" => Self::IsometricOffAxis3Bottom,
"isometricOffAxis3Left" => Self::IsometricOffAxis3Left,
"isometricOffAxis3Right" => Self::IsometricOffAxis3Right,
"isometricOffAxis4Bottom" => Self::IsometricOffAxis4Bottom,
"isometricOffAxis4Left" => Self::IsometricOffAxis4Left,
"isometricOffAxis4Right" => Self::IsometricOffAxis4Right,
"isometricRightDown" => Self::IsometricRightDown,
"isometricRightUp" => Self::IsometricRightUp,
"isometricTopDown" => Self::IsometricTopDown,
"isometricTopUp" => Self::IsometricTopUp,
"legacyObliqueBottom" => Self::LegacyObliqueBottom,
"legacyObliqueBottomLeft" => Self::LegacyObliqueBottomLeft,
"legacyObliqueBottomRight" => Self::LegacyObliqueBottomRight,
"legacyObliqueFront" => Self::LegacyObliqueFront,
"legacyObliqueLeft" => Self::LegacyObliqueLeft,
"legacyObliqueRight" => Self::LegacyObliqueRight,
"legacyObliqueTop" => Self::LegacyObliqueTop,
"legacyObliqueTopLeft" => Self::LegacyObliqueTopLeft,
"legacyObliqueTopRight" => Self::LegacyObliqueTopRight,
"legacyPerspectiveBottom" => Self::LegacyPerspectiveBottom,
"legacyPerspectiveBottomLeft" => Self::LegacyPerspectiveBottomLeft,
"legacyPerspectiveBottomRight" => Self::LegacyPerspectiveBottomRight,
"legacyPerspectiveFront" => Self::LegacyPerspectiveFront,
"legacyPerspectiveLeft" => Self::LegacyPerspectiveLeft,
"legacyPerspectiveRight" => Self::LegacyPerspectiveRight,
"legacyPerspectiveTop" => Self::LegacyPerspectiveTop,
"legacyPerspectiveTopLeft" => Self::LegacyPerspectiveTopLeft,
"legacyPerspectiveTopRight" => Self::LegacyPerspectiveTopRight,
"obliqueBottom" => Self::ObliqueBottom,
"obliqueBottomLeft" => Self::ObliqueBottomLeft,
"obliqueBottomRight" => Self::ObliqueBottomRight,
"obliqueLeft" => Self::ObliqueLeft,
"obliqueRight" => Self::ObliqueRight,
"obliqueTop" => Self::ObliqueTop,
"obliqueTopLeft" => Self::ObliqueTopLeft,
"obliqueTopRight" => Self::ObliqueTopRight,
"orthographicFront" => Self::OrthographicFront,
"perspectiveAbove" => Self::PerspectiveAbove,
"perspectiveAboveLeftFacing" => Self::PerspectiveAboveLeftFacing,
"perspectiveAboveRightFacing" => Self::PerspectiveAboveRightFacing,
"perspectiveBelow" => Self::PerspectiveBelow,
"perspectiveContrastingLeftFacing" => Self::PerspectiveContrastingLeftFacing,
"perspectiveContrastingRightFacing" => Self::PerspectiveContrastingRightFacing,
"perspectiveFront" => Self::PerspectiveFront,
"perspectiveHeroicExtremeLeftFacing" => Self::PerspectiveHeroicExtremeLeftFacing,
"perspectiveHeroicExtremeRightFacing" => Self::PerspectiveHeroicExtremeRightFacing,
"perspectiveHeroicLeftFacing" => Self::PerspectiveHeroicLeftFacing,
"perspectiveHeroicRightFacing" => Self::PerspectiveHeroicRightFacing,
"perspectiveLeft" => Self::PerspectiveLeft,
"perspectiveRelaxed" => Self::PerspectiveRelaxed,
"perspectiveRelaxedModerately" => Self::PerspectiveRelaxedModerately,
"perspectiveRight" => Self::PerspectiveRight,
_ => Self::default(),
};
}
}