fmod/core/geometry/
general.rs

1// Copyright (c) 2024 Melody Madeline Lyons
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
7use fmod_sys::*;
8use std::ffi::{c_float, c_int, c_void};
9
10use crate::{FmodResultExt, Result};
11use crate::{Geometry, Vector};
12
13impl Geometry {
14    /// Adds a polygon.
15    ///
16    /// All vertices must lay in the same plane otherwise behavior may be unpredictable.
17    /// The polygon is assumed to be convex. A non convex polygon will produce unpredictable behavior.
18    /// Polygons with zero area will be ignored.
19    ///
20    /// Polygons cannot be added if already at the maximum number of polygons or if the addition of their verticies would result in exceeding the maximum number of vertices.
21    ///
22    /// Vertices of an object are in object space, not world space, and so are relative to the position, or center of the object.
23    /// See [`Geometry::set_position`].
24    pub fn add_polygon(
25        &self,
26        direct_occlusion: c_float,
27        reverb_occlusion: c_float,
28        double_sided: bool,
29        vertices: &[Vector],
30    ) -> Result<c_int> {
31        let mut index = 0;
32        unsafe {
33            FMOD_Geometry_AddPolygon(
34                self.inner.as_ptr(),
35                direct_occlusion,
36                reverb_occlusion,
37                double_sided.into(),
38                vertices.len() as c_int,
39                vertices.as_ptr().cast(),
40                &raw mut index,
41            )
42            .to_result()?;
43        }
44        Ok(index)
45    }
46
47    /// Sets whether an object is processed by the geometry engine.
48    pub fn set_active(&self, active: bool) -> Result<()> {
49        unsafe { FMOD_Geometry_SetActive(self.inner.as_ptr(), active.into()).to_result() }
50    }
51
52    /// Retrieves whether an object is processed by the geometry engine.
53    pub fn get_active(&self) -> Result<bool> {
54        let mut active = FMOD_BOOL::FALSE;
55        unsafe {
56            FMOD_Geometry_GetActive(self.inner.as_ptr(), &raw mut active).to_result()?;
57        }
58        Ok(active.into())
59    }
60
61    /// Retrieves the maximum number of polygons and vertices allocatable for this object.
62    ///
63    /// The maximum number was set with [`crate::System::create_geometry`].
64    pub fn get_max_polygons(&self) -> Result<(c_int, c_int)> {
65        let mut max_polygons = 0;
66        let mut max_vertices = 0;
67        unsafe {
68            FMOD_Geometry_GetMaxPolygons(
69                self.inner.as_ptr(),
70                &raw mut max_polygons,
71                &raw mut max_vertices,
72            )
73            .to_result()?;
74        }
75        Ok((max_polygons, max_vertices))
76    }
77
78    /// Retrieves the number of polygons in this object.
79    pub fn get_polygon_count(&self) -> Result<c_int> {
80        let mut count = 0;
81        unsafe {
82            FMOD_Geometry_GetNumPolygons(self.inner.as_ptr(), &raw mut count).to_result()?;
83        }
84        Ok(count)
85    }
86
87    /// Sets the user data.
88    #[allow(clippy::not_unsafe_ptr_arg_deref)] // fmod doesn't dereference the passed in pointer, and the user dereferencing it is unsafe anyway
89    pub fn set_userdata(&self, userdata: *mut c_void) -> Result<()> {
90        unsafe { FMOD_Geometry_SetUserData(self.inner.as_ptr(), userdata).to_result() }
91    }
92
93    /// Retrieves user data.
94    pub fn get_userdata(&self) -> Result<*mut c_void> {
95        let mut userdata = std::ptr::null_mut();
96        unsafe {
97            FMOD_Geometry_GetUserData(self.inner.as_ptr(), &raw mut userdata).to_result()?;
98        }
99        Ok(userdata)
100    }
101
102    /// Frees a geometry object and releases its memory.
103    pub fn release(&self) -> Result<()> {
104        unsafe { FMOD_Geometry_Release(self.inner.as_ptr()).to_result() }
105    }
106
107    /// Saves the geometry object as a serialized binary block to a [`Vec`].
108    ///
109    /// The data can be saved to a file if required and loaded later with [`crate::System::load_geometry`].
110    pub fn save(&self) -> Result<Vec<u8>> {
111        let mut data_size = 0;
112        unsafe {
113            FMOD_Geometry_Save(
114                self.inner.as_ptr(),
115                std::ptr::null_mut(),
116                &raw mut data_size,
117            )
118            .to_result()?;
119        }
120
121        let mut data = vec![0; data_size as usize];
122        unsafe {
123            FMOD_Geometry_Save(
124                self.inner.as_ptr(),
125                data.as_mut_ptr().cast(),
126                &raw mut data_size,
127            )
128            .to_result()?;
129        }
130
131        Ok(data)
132    }
133}