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
use crate::{
    c::{
        c_float, c_ushort, spAttachment, spMeshAttachment, spMeshAttachment_newLinkedMesh,
        spMeshAttachment_updateRegion, spTextureRegion, spVertexAttachment,
    },
    c_interface::{NewFromPtr, SyncPtr},
    texture_region::TextureRegion,
    Attachment,
};

#[cfg(feature = "mint")]
use mint::Vector2;

/// A deforming mesh attachment.
///
/// [Spine API Reference](http://esotericsoftware.com/spine-api-reference#MeshAttachment)
#[derive(Debug)]
pub struct MeshAttachment {
    c_mesh_attachment: SyncPtr<spMeshAttachment>,
}

impl NewFromPtr<spMeshAttachment> for MeshAttachment {
    unsafe fn new_from_ptr(c_mesh_attachment: *mut spMeshAttachment) -> Self {
        Self {
            c_mesh_attachment: SyncPtr(c_mesh_attachment),
        }
    }
}

impl MeshAttachment {
    #[must_use]
    fn attachment(&self) -> &spAttachment {
        unsafe { &self.c_ptr_ref().super_0.super_0 }
    }

    #[must_use]
    fn vertex_attachment(&self) -> &spVertexAttachment {
        unsafe { &self.c_ptr_ref().super_0 }
    }

    #[must_use]
    pub fn new_linked_mesh(&self) -> Attachment {
        unsafe {
            Attachment::new_from_ptr(
                spMeshAttachment_newLinkedMesh(self.c_ptr()).cast::<spAttachment>(),
            )
        }
    }

    pub fn update_region(&mut self) {
        unsafe {
            spMeshAttachment_updateRegion(self.c_ptr());
        }
    }

    c_attachment_accessors!();
    c_vertex_attachment_accessors!();
    c_accessor_string!(path, path);
    c_accessor_color!(color, color);
    c_accessor!(hull_length, hullLength, i32);
    c_accessor!(width, width, f32);
    c_accessor!(height, height, f32);
    c_accessor_renderer_object!();
    c_accessor_tmp_ptr_optional_mut!(region, region_mut, region, TextureRegion, spTextureRegion);
    c_accessor_tmp_ptr_mut!(
        parent_mesh,
        parent_mesh_mut,
        parentMesh,
        MeshAttachment,
        spMeshAttachment
    );
    c_accessor!(triangles_count, trianglesCount, i32);
    c_accessor_passthrough!(triangles, triangles, *mut c_ushort);
    c_accessor!(edges_count, edgesCount, usize);
    c_accessor_passthrough!(edges, edges, *mut i32);
    c_accessor_passthrough!(uvs, uvs, *mut c_float);
    c_accessor_passthrough!(region_uvs, regionUVs, *mut c_float);
    c_ptr!(c_mesh_attachment, spMeshAttachment);
    // TODO: sequence accessor
}

/// Functions available if using the `mint` feature.
#[cfg(feature = "mint")]
impl MeshAttachment {
    #[must_use]
    pub fn size(&self) -> Vector2<f32> {
        Vector2 {
            x: self.width(),
            y: self.height(),
        }
    }

    c_vertex_attachment_accessors_mint!();
}