modelio/physically_plausible_light.rs
1use std::path::Path;
2use std::ptr;
3
4use crate::error::Result;
5use crate::ffi;
6use crate::handle::ObjectHandle;
7use crate::light::Light;
8use crate::object::Object;
9use crate::texture::Texture;
10use crate::types::{AreaLightInfo, PhotometricLightInfo, PhysicallyPlausibleLightInfo};
11use crate::util::{parse_json, path_to_c_string, required_handle};
12
13#[derive(Debug, Clone)]
14/// Wraps the corresponding Model I/O physically plausible light counterpart.
15pub struct PhysicallyPlausibleLight {
16 handle: ObjectHandle,
17}
18
19impl PhysicallyPlausibleLight {
20 /// Builds this wrapper from the retained handle of the wrapped Model I/O physically plausible light counterpart.
21 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
22 Self { handle }
23 }
24
25 /// Wraps the corresponding Model I/O initializer for the wrapped Model I/O physically plausible light counterpart.
26 pub fn new() -> Result<Self> {
27 let mut out_light = ptr::null_mut();
28 let mut out_error = ptr::null_mut();
29 let status =
30 // SAFETY: Output pointers are initialized and managed; FFI function is called safely.
31 unsafe { ffi::mdl_physically_plausible_light_new(&mut out_light, &mut out_error) };
32 crate::util::status_result(status, out_error)?;
33 Ok(Self::from_handle(required_handle(
34 out_light,
35 "MDLPhysicallyPlausibleLight",
36 )?))
37 }
38
39 /// Calls the corresponding Model I/O method on the wrapped Model I/O physically plausible light counterpart.
40 pub fn info(&self) -> Result<PhysicallyPlausibleLightInfo> {
41 parse_json(
42 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
43 unsafe { ffi::mdl_physically_plausible_light_info_json(self.handle.as_ptr()) },
44 "MDLPhysicallyPlausibleLight",
45 )
46 }
47
48 /// Calls the corresponding Model I/O method on the wrapped Model I/O physically plausible light counterpart.
49 pub fn set_color_temperature(&self, temperature: f32) {
50 // SAFETY: The unsafe operation is valid in this context.
51 unsafe {
52 ffi::mdl_physically_plausible_light_set_color_temperature(
53 self.handle.as_ptr(),
54 temperature,
55 );
56 };
57 }
58
59 /// Calls the corresponding Model I/O method on the wrapped Model I/O physically plausible light counterpart.
60 pub fn set_color(&self, color: [f32; 4]) {
61 // SAFETY: The unsafe operation is valid in this context.
62 unsafe {
63 ffi::mdl_physically_plausible_light_set_color(
64 self.handle.as_ptr(),
65 color[0],
66 color[1],
67 color[2],
68 color[3],
69 );
70 };
71 }
72
73 /// Calls the corresponding Model I/O method on the wrapped Model I/O physically plausible light counterpart.
74 pub fn set_lumens(&self, lumens: f32) {
75 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
76 unsafe { ffi::mdl_physically_plausible_light_set_lumens(self.handle.as_ptr(), lumens) };
77 }
78
79 /// Calls the corresponding Model I/O method on the wrapped Model I/O physically plausible light counterpart.
80 pub fn set_inner_cone_angle(&self, angle: f32) {
81 // SAFETY: The unsafe operation is valid in this context.
82 unsafe {
83 ffi::mdl_physically_plausible_light_set_inner_cone_angle(self.handle.as_ptr(), angle);
84 };
85 }
86
87 /// Calls the corresponding Model I/O method on the wrapped Model I/O physically plausible light counterpart.
88 pub fn set_outer_cone_angle(&self, angle: f32) {
89 // SAFETY: The unsafe operation is valid in this context.
90 unsafe {
91 ffi::mdl_physically_plausible_light_set_outer_cone_angle(self.handle.as_ptr(), angle);
92 };
93 }
94
95 /// Calls the corresponding Model I/O method on the wrapped Model I/O physically plausible light counterpart.
96 pub fn set_attenuation_start_distance(&self, distance: f32) {
97 // SAFETY: The unsafe operation is valid in this context.
98 unsafe {
99 ffi::mdl_physically_plausible_light_set_attenuation_start_distance(
100 self.handle.as_ptr(),
101 distance,
102 );
103 };
104 }
105
106 /// Calls the corresponding Model I/O method on the wrapped Model I/O physically plausible light counterpart.
107 pub fn set_attenuation_end_distance(&self, distance: f32) {
108 // SAFETY: The unsafe operation is valid in this context.
109 unsafe {
110 ffi::mdl_physically_plausible_light_set_attenuation_end_distance(
111 self.handle.as_ptr(),
112 distance,
113 );
114 };
115 }
116
117 #[must_use]
118 /// Calls the corresponding Model I/O method on the wrapped Model I/O physically plausible light counterpart.
119 pub fn as_light(&self) -> Light {
120 Light::from_handle(self.handle.clone())
121 }
122
123 #[must_use]
124 /// Calls the corresponding Model I/O method on the wrapped Model I/O physically plausible light counterpart.
125 pub fn as_object(&self) -> Object {
126 Object::from_handle(self.handle.clone())
127 }
128}
129
130#[derive(Debug, Clone)]
131/// Wraps the corresponding Model I/O area light counterpart.
132pub struct AreaLight {
133 handle: ObjectHandle,
134}
135
136impl AreaLight {
137 /// Builds this wrapper from the retained handle of the wrapped Model I/O area light counterpart.
138 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
139 Self { handle }
140 }
141
142 /// Wraps the corresponding Model I/O initializer for the wrapped Model I/O area light counterpart.
143 pub fn new() -> Result<Self> {
144 let mut out_light = ptr::null_mut();
145 let mut out_error = ptr::null_mut();
146 // SAFETY: Output pointers are initialized and managed; FFI function is called safely.
147 let status = unsafe { ffi::mdl_area_light_new(&mut out_light, &mut out_error) };
148 crate::util::status_result(status, out_error)?;
149 Ok(Self::from_handle(required_handle(
150 out_light,
151 "MDLAreaLight",
152 )?))
153 }
154
155 /// Calls the corresponding Model I/O method on the wrapped Model I/O area light counterpart.
156 pub fn info(&self) -> Result<AreaLightInfo> {
157 parse_json(
158 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
159 unsafe { ffi::mdl_area_light_info_json(self.handle.as_ptr()) },
160 "MDLAreaLight",
161 )
162 }
163
164 /// Calls the corresponding Model I/O method on the wrapped Model I/O area light counterpart.
165 pub fn set_area_radius(&self, value: f32) {
166 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
167 unsafe { ffi::mdl_area_light_set_area_radius(self.handle.as_ptr(), value) };
168 }
169
170 /// Calls the corresponding Model I/O method on the wrapped Model I/O area light counterpart.
171 pub fn set_super_elliptic_power(&self, value: [f32; 2]) {
172 // SAFETY: The unsafe operation is valid in this context.
173 unsafe {
174 ffi::mdl_area_light_set_super_elliptic_power(self.handle.as_ptr(), value[0], value[1]);
175 };
176 }
177
178 /// Calls the corresponding Model I/O method on the wrapped Model I/O area light counterpart.
179 pub fn set_aspect(&self, value: f32) {
180 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
181 unsafe { ffi::mdl_area_light_set_aspect(self.handle.as_ptr(), value) };
182 }
183
184 #[must_use]
185 /// Calls the corresponding Model I/O method on the wrapped Model I/O area light counterpart.
186 pub fn as_physically_plausible_light(&self) -> PhysicallyPlausibleLight {
187 PhysicallyPlausibleLight::from_handle(self.handle.clone())
188 }
189
190 #[must_use]
191 /// Calls the corresponding Model I/O method on the wrapped Model I/O area light counterpart.
192 pub fn as_light(&self) -> Light {
193 Light::from_handle(self.handle.clone())
194 }
195
196 #[must_use]
197 /// Calls the corresponding Model I/O method on the wrapped Model I/O area light counterpart.
198 pub fn as_object(&self) -> Object {
199 Object::from_handle(self.handle.clone())
200 }
201}
202
203#[derive(Debug, Clone)]
204/// Wraps the corresponding Model I/O photometric light counterpart.
205pub struct PhotometricLight {
206 handle: ObjectHandle,
207}
208
209impl PhotometricLight {
210 /// Builds this wrapper from the retained handle of the wrapped Model I/O photometric light counterpart.
211 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
212 Self { handle }
213 }
214
215 /// Wraps the corresponding Model I/O initializer for the wrapped Model I/O photometric light counterpart.
216 pub fn new() -> Result<Self> {
217 let mut out_light = ptr::null_mut();
218 let mut out_error = ptr::null_mut();
219 // SAFETY: Output pointers are initialized and managed; FFI function is called safely.
220 let status = unsafe { ffi::mdl_photometric_light_new(&mut out_light, &mut out_error) };
221 crate::util::status_result(status, out_error)?;
222 Ok(Self::from_handle(required_handle(
223 out_light,
224 "MDLPhotometricLight",
225 )?))
226 }
227
228 /// Calls the corresponding Model I/O method on the wrapped Model I/O photometric light counterpart.
229 pub fn from_ies_profile(path: impl AsRef<Path>) -> Result<Self> {
230 let path = path_to_c_string(path.as_ref())?;
231 let mut out_light = ptr::null_mut();
232 let mut out_error = ptr::null_mut();
233 // SAFETY: The unsafe operation is valid in this context.
234 let status = unsafe {
235 ffi::mdl_photometric_light_new_with_ies_profile(
236 path.as_ptr(),
237 &mut out_light,
238 &mut out_error,
239 )
240 };
241 crate::util::status_result(status, out_error)?;
242 Ok(Self::from_handle(required_handle(
243 out_light,
244 "MDLPhotometricLight",
245 )?))
246 }
247
248 /// Calls the corresponding Model I/O method on the wrapped Model I/O photometric light counterpart.
249 pub fn info(&self) -> Result<PhotometricLightInfo> {
250 parse_json(
251 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
252 unsafe { ffi::mdl_photometric_light_info_json(self.handle.as_ptr()) },
253 "MDLPhotometricLight",
254 )
255 }
256
257 /// Calls the corresponding Model I/O method on the wrapped Model I/O photometric light counterpart.
258 pub fn generate_spherical_harmonics_from_light(&self, level: usize) {
259 // SAFETY: The unsafe operation is valid in this context.
260 unsafe {
261 ffi::mdl_photometric_light_generate_spherical_harmonics_from_light(
262 self.handle.as_ptr(),
263 level as u64,
264 );
265 };
266 }
267
268 /// Calls the corresponding Model I/O method on the wrapped Model I/O photometric light counterpart.
269 pub fn generate_cubemap_from_light(&self, texture_size: usize) {
270 // SAFETY: The unsafe operation is valid in this context.
271 unsafe {
272 ffi::mdl_photometric_light_generate_cubemap_from_light(
273 self.handle.as_ptr(),
274 texture_size as u64,
275 );
276 };
277 }
278
279 #[must_use]
280 /// Calls the corresponding Model I/O method on the wrapped Model I/O photometric light counterpart.
281 pub fn generate_texture(&self, texture_size: usize) -> Option<Texture> {
282 // SAFETY: The unsafe operation is valid in this context.
283 let ptr = unsafe {
284 ffi::mdl_photometric_light_generate_texture(self.handle.as_ptr(), texture_size as u64)
285 };
286 // SAFETY: The unsafe operation is valid in this context.
287 unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(Texture::from_handle)
288 }
289
290 #[must_use]
291 /// Calls the corresponding Model I/O method on the wrapped Model I/O photometric light counterpart.
292 pub fn light_cube_map(&self) -> Option<Texture> {
293 // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
294 let ptr = unsafe { ffi::mdl_photometric_light_light_cube_map(self.handle.as_ptr()) };
295 // SAFETY: The unsafe operation is valid in this context.
296 unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(Texture::from_handle)
297 }
298
299 #[must_use]
300 /// Calls the corresponding Model I/O method on the wrapped Model I/O photometric light counterpart.
301 pub fn as_physically_plausible_light(&self) -> PhysicallyPlausibleLight {
302 PhysicallyPlausibleLight::from_handle(self.handle.clone())
303 }
304
305 #[must_use]
306 /// Calls the corresponding Model I/O method on the wrapped Model I/O photometric light counterpart.
307 pub fn as_light(&self) -> Light {
308 Light::from_handle(self.handle.clone())
309 }
310
311 #[must_use]
312 /// Calls the corresponding Model I/O method on the wrapped Model I/O photometric light counterpart.
313 pub fn as_object(&self) -> Object {
314 Object::from_handle(self.handle.clone())
315 }
316}