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
100
101
102
103
use crate::{
    c::{spBoneData, spIkConstraintData},
    c_interface::{NewFromPtr, SyncPtr},
    BoneData,
};

/// Stores the setup pose for an [`IkConstraint`](`crate::IkConstraint`).
///
/// [Spine API Reference](https://esotericsoftware.com/spine-api-reference#IkConstraintData)
#[derive(Debug)]
pub struct IkConstraintData {
    c_ik_constraint_data: SyncPtr<spIkConstraintData>,
}

impl NewFromPtr<spIkConstraintData> for IkConstraintData {
    unsafe fn new_from_ptr(c_slot: *mut spIkConstraintData) -> Self {
        Self {
            c_ik_constraint_data: SyncPtr(c_slot),
        }
    }
}

impl IkConstraintData {
    c_accessor_string!(
        /// The constraint's name, which is unique across all constraints in the skeleton of the
        /// same type.
        name,
        name
    );
    c_accessor!(
        /// The ordinal of this constraint for the order a skeleton's constraints will be applied by
        /// [`Skeleton::update_world_transform`](`crate::Skeleton::update_world_transform`).
        order,
        order,
        i32
    );
    c_accessor_bool!(
        /// When true,
        /// [`Skeleton::update_world_transform`](`crate::Skeleton::update_world_transform`) only
        /// updates this constraint if the skin contains this constraint.
        skin_required,
        skinRequired
    );

    c_accessor!(
        /// For two bone IK, controls the bend direction of the IK bones, either 1 or -1.
        bend_direction,
        bendDirection,
        i32
    );
    c_accessor_bool!(
        /// For one bone IK, when true and the target is too close, the bone is scaled to reach it.
        compress,
        compress
    );
    c_accessor!(
        /// A percentage (0-1) that controls the mix between the constrained and unconstrained
        /// rotation.
        ///
        /// For two bone IK: if the parent bone has local nonuniform scale, the child bone's local Y
        /// translation is set to 0.
        mix,
        mix,
        f32
    );
    c_accessor!(
        /// For two bone IK, the target bone's distance from the maximum reach of the bones where
        /// rotation begins to slow. The bones will not straighten completely until the target is this
        /// far out of range.
        softness,
        softness,
        f32
    );
    c_accessor_bool!(
        /// When true and the target is out of range, the parent bone is scaled to reach it.
        ///
        /// For two bone IK: 1) the child bone's local Y translation is set to 0, 2) stretch is not
        /// applied if [`softness`](`Self::softness`) is > 0, and 3) if the parent bone has local
        /// nonuniform scale, stretch is not applied.
        stretch,
        stretch
    );
    c_accessor_bool!(
        /// When true and [`compress`](`Self::compress`) or [`stretch`](`Self::stretch`) is used,
        /// the bone is scaled on both the X and Y axes.
        uniform,
        uniform
    );

    c_accessor!(bones_count, bonesCount, usize);
    c_accessor_array!(
        bones,
        bone_at_index,
        IkConstraintData,
        BoneData,
        spBoneData,
        bones,
        bones_count
    );
    c_accessor_tmp_ptr!(target, target, BoneData, spBoneData);

    c_ptr!(c_ik_constraint_data, spIkConstraintData);
}