1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Copyright (c) 2024 Lily Lyons
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use fmod_sys::*;
use std::{
    ffi::{c_float, c_int},
    mem::MaybeUninit,
};

use crate::{Geometry, Vector};

impl Geometry {
    /// Sets individual attributes for a polygon inside a geometry object.
    pub fn set_polygon_attributes(
        &self,
        index: c_int,
        direct_occlusion: c_float,
        reverb_occlusion: c_float,
        double_sided: bool,
    ) -> Result<()> {
        unsafe {
            FMOD_Geometry_SetPolygonAttributes(
                self.inner,
                index,
                direct_occlusion,
                reverb_occlusion,
                double_sided.into(),
            )
            .to_result()
        }
    }

    /// Retrieves the attributes for a polygon.
    pub fn get_polygon_attributes(&self, index: c_int) -> Result<(c_float, c_float, bool)> {
        let mut direct = 0.0;
        let mut reverb = 0.0;
        let mut double_sided = FMOD_BOOL::FALSE;
        unsafe {
            FMOD_Geometry_GetPolygonAttributes(
                self.inner,
                index,
                &mut direct,
                &mut reverb,
                &mut double_sided,
            )
            .to_result()?;
        }
        Ok((direct, reverb, double_sided.into()))
    }

    /// Gets the number of vertices in a polygon.
    pub fn get_polygon_vertex_count(&self, index: c_int) -> Result<c_int> {
        let mut count = 0;
        unsafe {
            FMOD_Geometry_GetPolygonNumVertices(self.inner, index, &mut count).to_result()?;
        }
        Ok(count)
    }

    /// Alters the position of a polygon's vertex inside a geometry object.
    ///
    /// Vertices are relative to the position of the object. See [`Geometry::set_position`].
    ///
    /// There may be some significant overhead with this function as it may cause some reconfiguration of internal data structures used to speed up sound-ray testing.
    ///
    /// You may get better results if you want to modify your object by using [`Geometry::set_position`], [`Geometry::set_scale`] and [`Geometry::set_rotation`].
    pub fn set_polygon_vertex(
        &self,
        index: c_int,
        vertex_index: c_int,
        vertex: Vector,
    ) -> Result<()> {
        unsafe {
            FMOD_Geometry_SetPolygonVertex(
                self.inner,
                index,
                vertex_index,
                std::ptr::from_ref(&vertex).cast(),
            )
            .to_result()
        }
    }

    /// Retrieves the position of a vertex.
    ///
    /// Vertices are relative to the position of the object. See [`Geometry::set_osition`].
    pub fn get_polygon_vertex(&self, index: c_int, vertex_index: c_int) -> Result<Vector> {
        let mut vertex = MaybeUninit::uninit();
        unsafe {
            FMOD_Geometry_GetPolygonVertex(self.inner, index, vertex_index, vertex.as_mut_ptr())
                .to_result()?;
            let vertex = vertex.assume_init().into();
            Ok(vertex)
        }
    }
}