modelio/camera.rs
1use std::ptr;
2
3use crate::error::Result;
4use crate::ffi;
5use crate::handle::ObjectHandle;
6use crate::object::Object;
7use crate::texture::Texture;
8use crate::types::{BoundingBox, CameraInfo, CameraProjection, StereoscopicCameraInfo};
9use crate::util::{parse_json, required_handle};
10
11#[derive(Debug, Clone)]
12/// Wraps the corresponding Model I/O camera counterpart.
13pub struct Camera {
14 handle: ObjectHandle,
15}
16
17impl Camera {
18 /// Builds this wrapper from the retained handle of the wrapped Model I/O camera counterpart.
19 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
20 Self { handle }
21 }
22
23 /// Wraps the corresponding Model I/O initializer for the wrapped Model I/O camera counterpart.
24 pub fn new() -> Result<Self> {
25 let mut out_camera = ptr::null_mut();
26 let mut out_error = ptr::null_mut();
27 // SAFETY: Output pointers are initialized and managed; FFI function is called safely.
28 let status = unsafe { ffi::mdl_camera_new(&mut out_camera, &mut out_error) };
29 crate::util::status_result(status, out_error)?;
30 Ok(Self::from_handle(required_handle(out_camera, "MDLCamera")?))
31 }
32
33 /// Calls the corresponding Model I/O method on the wrapped Model I/O camera counterpart.
34 pub fn info(&self) -> Result<CameraInfo> {
35 parse_json(
36 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
37 unsafe { ffi::mdl_camera_info_json(self.handle.as_ptr()) },
38 "MDLCamera",
39 )
40 }
41
42 /// Calls the corresponding Model I/O method on the wrapped Model I/O camera counterpart.
43 pub fn set_projection(&self, projection: CameraProjection) {
44 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
45 unsafe { ffi::mdl_camera_set_projection(self.handle.as_ptr(), projection.as_raw()) };
46 }
47
48 /// Calls the corresponding Model I/O method on the wrapped Model I/O camera counterpart.
49 pub fn set_near_visibility_distance(&self, value: f32) {
50 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
51 unsafe { ffi::mdl_camera_set_near_visibility_distance(self.handle.as_ptr(), value) };
52 }
53
54 /// Calls the corresponding Model I/O method on the wrapped Model I/O camera counterpart.
55 pub fn set_far_visibility_distance(&self, value: f32) {
56 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
57 unsafe { ffi::mdl_camera_set_far_visibility_distance(self.handle.as_ptr(), value) };
58 }
59
60 /// Calls the corresponding Model I/O method on the wrapped Model I/O camera counterpart.
61 pub fn set_world_to_meters_conversion_scale(&self, value: f32) {
62 // SAFETY: The unsafe operation is valid in this context.
63 unsafe {
64 ffi::mdl_camera_set_world_to_meters_conversion_scale(self.handle.as_ptr(), value);
65 };
66 }
67
68 /// Calls the corresponding Model I/O method on the wrapped Model I/O camera counterpart.
69 pub fn set_focal_length(&self, value: f32) {
70 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
71 unsafe { ffi::mdl_camera_set_focal_length(self.handle.as_ptr(), value) };
72 }
73
74 /// Calls the corresponding Model I/O method on the wrapped Model I/O camera counterpart.
75 pub fn set_focus_distance(&self, value: f32) {
76 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
77 unsafe { ffi::mdl_camera_set_focus_distance(self.handle.as_ptr(), value) };
78 }
79
80 /// Calls the corresponding Model I/O method on the wrapped Model I/O camera counterpart.
81 pub fn set_field_of_view(&self, value: f32) {
82 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
83 unsafe { ffi::mdl_camera_set_field_of_view(self.handle.as_ptr(), value) };
84 }
85
86 /// Calls the corresponding Model I/O method on the wrapped Model I/O camera counterpart.
87 pub fn look_at(&self, focus_position: [f32; 3]) {
88 // SAFETY: The unsafe operation is valid in this context.
89 unsafe {
90 ffi::mdl_camera_look_at(
91 self.handle.as_ptr(),
92 focus_position[0],
93 focus_position[1],
94 focus_position[2],
95 );
96 };
97 }
98
99 /// Calls the corresponding Model I/O method on the wrapped Model I/O camera counterpart.
100 pub fn look_at_from(&self, focus_position: [f32; 3], camera_position: [f32; 3]) {
101 // SAFETY: The unsafe operation is valid in this context.
102 unsafe {
103 ffi::mdl_camera_look_at_from(
104 self.handle.as_ptr(),
105 focus_position[0],
106 focus_position[1],
107 focus_position[2],
108 camera_position[0],
109 camera_position[1],
110 camera_position[2],
111 );
112 };
113 }
114
115 /// Calls the corresponding Model I/O method on the wrapped Model I/O camera counterpart.
116 pub fn frame_bounding_box(&self, bounding_box: BoundingBox, set_near_and_far: bool) {
117 // SAFETY: The unsafe operation is valid in this context.
118 unsafe {
119 ffi::mdl_camera_frame_bounding_box(
120 self.handle.as_ptr(),
121 bounding_box.min[0],
122 bounding_box.min[1],
123 bounding_box.min[2],
124 bounding_box.max[0],
125 bounding_box.max[1],
126 bounding_box.max[2],
127 i32::from(set_near_and_far),
128 );
129 };
130 }
131
132 #[must_use]
133 /// Calls the corresponding Model I/O method on the wrapped Model I/O camera counterpart.
134 pub fn ray_to(&self, pixel: [i32; 2], viewport: [i32; 2]) -> [f32; 3] {
135 let mut ray = [0.0_f32; 3];
136 // SAFETY: The unsafe operation is valid in this context.
137 unsafe {
138 ffi::mdl_camera_ray_to(
139 self.handle.as_ptr(),
140 pixel[0],
141 pixel[1],
142 viewport[0],
143 viewport[1],
144 &mut ray[0],
145 &mut ray[1],
146 &mut ray[2],
147 );
148 };
149 ray
150 }
151
152 #[must_use]
153 /// Calls the corresponding Model I/O method on the wrapped Model I/O camera counterpart.
154 pub fn bokeh_kernel(&self, size: [i32; 2]) -> Option<Texture> {
155 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
156 let ptr = unsafe { ffi::mdl_camera_bokeh_kernel(self.handle.as_ptr(), size[0], size[1]) };
157 // SAFETY: The unsafe operation is valid in this context.
158 unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(Texture::from_handle)
159 }
160
161 #[must_use]
162 /// Calls the corresponding Model I/O method on the wrapped Model I/O camera counterpart.
163 pub fn as_object(&self) -> Object {
164 Object::from_handle(self.handle.clone())
165 }
166}
167
168#[derive(Debug, Clone)]
169/// Wraps the corresponding Model I/O stereoscopic camera counterpart.
170pub struct StereoscopicCamera {
171 handle: ObjectHandle,
172}
173
174impl StereoscopicCamera {
175 /// Builds this wrapper from the retained handle of the wrapped Model I/O stereoscopic camera counterpart.
176 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
177 Self { handle }
178 }
179
180 /// Wraps the corresponding Model I/O initializer for the wrapped Model I/O stereoscopic camera counterpart.
181 pub fn new() -> Result<Self> {
182 let mut out_camera = ptr::null_mut();
183 let mut out_error = ptr::null_mut();
184 // SAFETY: Output pointers are initialized and managed; FFI function is called safely.
185 let status = unsafe { ffi::mdl_stereoscopic_camera_new(&mut out_camera, &mut out_error) };
186 crate::util::status_result(status, out_error)?;
187 Ok(Self::from_handle(required_handle(
188 out_camera,
189 "MDLStereoscopicCamera",
190 )?))
191 }
192
193 /// Calls the corresponding Model I/O method on the wrapped Model I/O stereoscopic camera counterpart.
194 pub fn info(&self) -> Result<StereoscopicCameraInfo> {
195 parse_json(
196 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
197 unsafe { ffi::mdl_stereoscopic_camera_info_json(self.handle.as_ptr()) },
198 "MDLStereoscopicCamera",
199 )
200 }
201
202 /// Calls the corresponding Model I/O method on the wrapped Model I/O stereoscopic camera counterpart.
203 pub fn set_inter_pupillary_distance(&self, value: f32) {
204 // SAFETY: The unsafe operation is valid in this context.
205 unsafe {
206 ffi::mdl_stereoscopic_camera_set_inter_pupillary_distance(self.handle.as_ptr(), value);
207 };
208 }
209
210 /// Calls the corresponding Model I/O method on the wrapped Model I/O stereoscopic camera counterpart.
211 pub fn set_left_vergence(&self, value: f32) {
212 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
213 unsafe { ffi::mdl_stereoscopic_camera_set_left_vergence(self.handle.as_ptr(), value) };
214 }
215
216 /// Calls the corresponding Model I/O method on the wrapped Model I/O stereoscopic camera counterpart.
217 pub fn set_right_vergence(&self, value: f32) {
218 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
219 unsafe { ffi::mdl_stereoscopic_camera_set_right_vergence(self.handle.as_ptr(), value) };
220 }
221
222 /// Calls the corresponding Model I/O method on the wrapped Model I/O stereoscopic camera counterpart.
223 pub fn set_overlap(&self, value: f32) {
224 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
225 unsafe { ffi::mdl_stereoscopic_camera_set_overlap(self.handle.as_ptr(), value) };
226 }
227
228 #[must_use]
229 /// Calls the corresponding Model I/O method on the wrapped Model I/O stereoscopic camera counterpart.
230 pub fn as_camera(&self) -> Camera {
231 Camera::from_handle(self.handle.clone())
232 }
233
234 #[must_use]
235 /// Calls the corresponding Model I/O method on the wrapped Model I/O stereoscopic camera counterpart.
236 pub fn as_object(&self) -> Object {
237 Object::from_handle(self.handle.clone())
238 }
239}