1use nalgebra::{Point2, RealField};
2use simba::scalar::SubsetOf;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub enum Fixed<N: Copy + RealField> {
12 Hor(N),
14 Ver(N),
16 Upp(N),
18}
19
20impl<N: Copy + RealField> Default for Fixed<N> {
21 fn default() -> Self {
22 N::frac_pi_4().into()
23 }
24}
25
26impl<N: Copy + RealField> From<N> for Fixed<N> {
27 fn from(fov: N) -> Self {
28 Self::Ver(fov)
29 }
30}
31
32impl<N: Copy + RealField> Fixed<N> {
33 #[must_use]
35 pub fn to_hor(self, max: &Point2<N>) -> Self {
36 let two = N::one() + N::one();
37 Self::Hor(match self {
38 Self::Hor(fov) => fov,
39 Self::Ver(fov) => (max.x / max.y * (fov / two).tan()).atan() * two,
40 Self::Upp(upp) => (max.x / two * upp).atan() * two,
41 })
42 }
43 #[must_use]
45 pub fn to_ver(self, max: &Point2<N>) -> Self {
46 let two = N::one() + N::one();
47 Self::Ver(match self {
48 Self::Hor(fov) => (max.y / max.x * (fov / two).tan()).atan() * two,
49 Self::Ver(fov) => fov,
50 Self::Upp(upp) => (max.y / two * upp).atan() * two,
51 })
52 }
53 #[must_use]
56 pub fn to_upp(self, max: &Point2<N>) -> Self {
57 let two = N::one() + N::one();
58 Self::Upp(match self {
59 Self::Hor(fov) => (fov / two).tan() * two / max.x,
60 Self::Ver(fov) => (fov / two).tan() * two / max.y,
61 Self::Upp(upp) => upp,
62 })
63 }
64 #[must_use]
67 pub fn max_and_upp(&self, zat: N, max: &Point2<N>) -> (Point2<N>, N) {
68 let two = N::one() + N::one();
69 match *self {
70 Self::Hor(fov) => {
71 let x = zat * (fov / two).tan();
72 let y = max.y / max.x * x;
73 (Point2::new(x, y), x * two / max.x)
74 }
75 Self::Ver(fov) => {
76 let y = zat * (fov / two).tan();
77 let x = max.x / max.y * y;
78 (Point2::new(x, y), y * two / max.y)
79 }
80 Self::Upp(upp) => {
81 let upp = upp * zat;
82 (max / two * upp, upp)
83 }
84 }
85 }
86 #[must_use]
88 pub const fn into_inner(self) -> N {
89 match self {
90 Self::Hor(fov) | Self::Ver(fov) => fov,
91 Self::Upp(upp) => upp,
92 }
93 }
94 #[must_use]
96 pub fn cast<M: Copy + RealField>(self) -> Fixed<M>
97 where
98 N: SubsetOf<M>,
99 {
100 match self {
101 Self::Hor(fov) => Fixed::Hor(fov.to_superset()),
102 Self::Ver(fov) => Fixed::Ver(fov.to_superset()),
103 Self::Upp(fov) => Fixed::Upp(fov.to_superset()),
104 }
105 }
106}
107
108#[cfg(feature = "rkyv")]
109impl<N: Copy + RealField> rkyv::Archive for Fixed<N> {
110 type Archived = Self;
111 type Resolver = ();
112
113 #[inline]
114 #[allow(unsafe_code)]
115 unsafe fn resolve(&self, _: usize, (): Self::Resolver, out: *mut Self::Archived) {
116 unsafe {
117 out.write(rkyv::to_archived!(*self as Self));
118 }
119 }
120}
121
122#[cfg(feature = "rkyv")]
123impl<Ser: rkyv::Fallible + ?Sized, N: Copy + RealField> rkyv::Serialize<Ser> for Fixed<N> {
124 #[inline]
125 fn serialize(&self, _: &mut Ser) -> Result<Self::Resolver, Ser::Error> {
126 Ok(())
127 }
128}
129
130#[cfg(feature = "rkyv")]
131impl<De: rkyv::Fallible + ?Sized, N: Copy + RealField> rkyv::Deserialize<Self, De> for Fixed<N> {
132 #[inline]
133 fn deserialize(&self, _: &mut De) -> Result<Self, De::Error> {
134 Ok(rkyv::from_archived!(*self))
135 }
136}