gltf/
camera.rs

1use crate::Document;
2
3#[cfg(feature = "extensions")]
4use serde_json::{Map, Value};
5
6/// A camera's projection.
7#[derive(Clone, Debug)]
8pub enum Projection<'a> {
9    /// Describes an orthographic projection.
10    Orthographic(Orthographic<'a>),
11
12    /// Describes a perspective projection.
13    Perspective(Perspective<'a>),
14}
15
16/// A camera's projection.  A node can reference a camera to apply a transform to
17/// place the camera in the scene.
18#[derive(Clone, Debug)]
19pub struct Camera<'a> {
20    /// The parent `Document` struct.
21    document: &'a Document,
22
23    /// The corresponding JSON index.
24    index: usize,
25
26    /// The corresponding JSON struct.
27    json: &'a json::camera::Camera,
28}
29
30///  Values for an orthographic camera projection.
31#[derive(Clone, Debug)]
32pub struct Orthographic<'a> {
33    /// The parent `Document` struct.
34    #[allow(dead_code)]
35    document: &'a Document,
36
37    /// The corresponding JSON struct.
38    json: &'a json::camera::Orthographic,
39}
40
41/// Values for a perspective camera projection.
42#[derive(Clone, Debug)]
43pub struct Perspective<'a> {
44    /// The parent `Document` struct.
45    #[allow(dead_code)]
46    document: &'a Document,
47
48    /// The corresponding JSON struct.
49    json: &'a json::camera::Perspective,
50}
51
52impl<'a> Camera<'a> {
53    /// Constructs a `Camera`.
54    pub(crate) fn new(
55        document: &'a Document,
56        index: usize,
57        json: &'a json::camera::Camera,
58    ) -> Self {
59        Self {
60            document,
61            index,
62            json,
63        }
64    }
65
66    /// Returns the internal JSON index.
67    pub fn index(&self) -> usize {
68        self.index
69    }
70
71    /// Optional user-defined name for this object.
72    #[cfg(feature = "names")]
73    #[cfg_attr(docsrs, doc(cfg(feature = "names")))]
74    pub fn name(&self) -> Option<&'a str> {
75        self.json.name.as_deref()
76    }
77
78    /// Returns the camera's projection.
79    pub fn projection(&self) -> Projection {
80        match self.json.type_.unwrap() {
81            json::camera::Type::Orthographic => {
82                let json = self.json.orthographic.as_ref().unwrap();
83                Projection::Orthographic(Orthographic::new(self.document, json))
84            }
85            json::camera::Type::Perspective => {
86                let json = self.json.perspective.as_ref().unwrap();
87                Projection::Perspective(Perspective::new(self.document, json))
88            }
89        }
90    }
91
92    /// Returns extension data unknown to this crate version.
93    #[cfg(feature = "extensions")]
94    #[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
95    pub fn extensions(&self) -> Option<&Map<String, Value>> {
96        let ext = self.json.extensions.as_ref()?;
97        Some(&ext.others)
98    }
99
100    /// Queries extension data unknown to this crate version.
101    #[cfg(feature = "extensions")]
102    #[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
103    pub fn extension_value(&self, ext_name: &str) -> Option<&Value> {
104        let ext = self.json.extensions.as_ref()?;
105        ext.others.get(ext_name)
106    }
107
108    /// Optional application specific data.
109    pub fn extras(&self) -> &'a json::Extras {
110        &self.json.extras
111    }
112}
113
114impl<'a> Orthographic<'a> {
115    /// Constructs a `Orthographic` camera projection.
116    pub(crate) fn new(document: &'a Document, json: &'a json::camera::Orthographic) -> Self {
117        Self { document, json }
118    }
119
120    ///  The horizontal magnification of the view.
121    pub fn xmag(&self) -> f32 {
122        self.json.xmag
123    }
124
125    ///  The vertical magnification of the view.
126    pub fn ymag(&self) -> f32 {
127        self.json.ymag
128    }
129
130    ///  The distance to the far clipping plane.
131    pub fn zfar(&self) -> f32 {
132        self.json.zfar
133    }
134
135    ///  The distance to the near clipping plane.
136    pub fn znear(&self) -> f32 {
137        self.json.znear
138    }
139
140    /// Returns extension data unknown to this crate version.
141    #[cfg(feature = "extensions")]
142    #[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
143    pub fn extensions(&self) -> Option<&Map<String, Value>> {
144        let ext = self.json.extensions.as_ref()?;
145        Some(&ext.others)
146    }
147
148    /// Queries extension data unknown to this crate version.
149    #[cfg(feature = "extensions")]
150    #[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
151    pub fn extension_value(&self, ext_name: &str) -> Option<&Value> {
152        let ext = self.json.extensions.as_ref()?;
153        ext.others.get(ext_name)
154    }
155
156    ///  Optional application specific data.
157    pub fn extras(&self) -> &'a json::Extras {
158        &self.json.extras
159    }
160}
161
162impl<'a> Perspective<'a> {
163    /// Constructs a `Perspective` camera projection.
164    pub(crate) fn new(document: &'a Document, json: &'a json::camera::Perspective) -> Self {
165        Self { document, json }
166    }
167
168    ///  Aspect ratio of the field of view.
169    pub fn aspect_ratio(&self) -> Option<f32> {
170        self.json.aspect_ratio
171    }
172
173    ///  The vertical field of view in radians.
174    pub fn yfov(&self) -> f32 {
175        self.json.yfov
176    }
177
178    ///  The distance to the far clipping plane.
179    pub fn zfar(&self) -> Option<f32> {
180        self.json.zfar
181    }
182
183    ///  The distance to the near clipping plane.
184    pub fn znear(&self) -> f32 {
185        self.json.znear
186    }
187
188    /// Returns extension data unknown to this crate version.
189    #[cfg(feature = "extensions")]
190    #[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
191    pub fn extensions(&self) -> Option<&Map<String, Value>> {
192        let ext = self.json.extensions.as_ref()?;
193        Some(&ext.others)
194    }
195
196    /// Queries extension data unknown to this crate version.
197    #[cfg(feature = "extensions")]
198    #[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
199    pub fn extension_value(&self, ext_name: &str) -> Option<&Value> {
200        let ext = self.json.extensions.as_ref()?;
201        ext.others.get(ext_name)
202    }
203
204    ///  Optional application specific data.
205    pub fn extras(&self) -> &'a json::Extras {
206        &self.json.extras
207    }
208}