easy_gltf/scene/
camera.rs1use cgmath::*;
2use gltf::camera::Projection as GltfProjection;
3
4#[derive(Clone, Debug)]
6pub struct Camera {
7 #[cfg(feature = "names")]
8 pub name: Option<String>,
10
11 #[cfg(feature = "extras")]
12 pub extras: gltf::json::extras::Extras,
14
15 pub transform: Matrix4<f32>,
17
18 pub projection: Projection,
20
21 pub zfar: f32,
25
26 pub znear: f32,
28}
29
30#[derive(Debug, Clone)]
32pub enum Projection {
33 Perspective {
35 yfov: Rad<f32>,
37 aspect_ratio: Option<f32>,
39 },
40 Orthographic {
42 scale: Vector2<f32>,
44 },
45}
46impl Default for Projection {
47 fn default() -> Self {
48 Self::Perspective {
49 yfov: Rad(0.399),
50 aspect_ratio: None,
51 }
52 }
53}
54
55impl Camera {
56 pub fn position(&self) -> Vector3<f32> {
58 Vector3::new(
59 self.transform[3][0],
60 self.transform[3][1],
61 self.transform[3][2],
62 )
63 }
64
65 pub fn right(&self) -> Vector3<f32> {
67 Vector3::new(
68 self.transform[0][0],
69 self.transform[0][1],
70 self.transform[0][2],
71 )
72 .normalize()
73 }
74
75 pub fn up(&self) -> Vector3<f32> {
77 Vector3::new(
78 self.transform[1][0],
79 self.transform[1][1],
80 self.transform[1][2],
81 )
82 .normalize()
83 }
84
85 pub fn forward(&self) -> Vector3<f32> {
87 Vector3::new(
88 self.transform[2][0],
89 self.transform[2][1],
90 self.transform[2][2],
91 )
92 .normalize()
93 }
94
95 pub fn apply_transform_vector(&self, pos: &Vector3<f32>) -> Vector3<f32> {
106 let pos = Vector4::new(pos[0], pos[1], pos[2], 0.);
107 (self.transform * pos).truncate()
108 }
109
110 pub(crate) fn load(gltf_cam: gltf::Camera, transform: &Matrix4<f32>) -> Self {
111 let mut cam = Self {
112 transform: *transform,
113 ..Default::default()
114 };
115
116 #[cfg(feature = "names")]
117 {
118 cam.name = gltf_cam.name().map(String::from);
119 }
120 #[cfg(feature = "extras")]
121 {
122 cam.extras = gltf_cam.extras().clone();
123 }
124
125 match gltf_cam.projection() {
126 GltfProjection::Orthographic(ortho) => {
127 cam.projection = Projection::Orthographic {
128 scale: Vector2::new(ortho.xmag(), ortho.ymag()),
129 };
130 cam.zfar = ortho.zfar();
131 cam.znear = ortho.znear();
132 }
133 GltfProjection::Perspective(pers) => {
134 cam.projection = Projection::Perspective {
135 yfov: Rad(pers.yfov()),
136 aspect_ratio: pers.aspect_ratio(),
137 };
138 cam.zfar = pers.zfar().unwrap_or(f32::INFINITY);
139 cam.znear = pers.znear();
140 }
141 };
142 cam
143 }
144}
145
146impl Default for Camera {
147 fn default() -> Self {
148 Camera {
149 #[cfg(feature = "names")]
150 name: None,
151 #[cfg(feature = "extras")]
152 extras: None,
153 transform: Zero::zero(),
154 projection: Projection::default(),
155 zfar: f32::INFINITY,
156 znear: 0.,
157 }
158 }
159}