Skip to main content

mmd_anim_runtime/
pose.rs

1use glam::{Mat4, Quat, Vec3A};
2
3use crate::{MorphIndex, model::BoneIndex};
4
5#[derive(Debug)]
6pub struct PoseArena {
7    local_position_offsets: Box<[Vec3A]>,
8    local_rotations: Box<[Quat]>,
9    local_scales: Box<[Vec3A]>,
10    append_position_offsets: Box<[Vec3A]>,
11    append_rotations: Box<[Quat]>,
12    morph_weights: Box<[f32]>,
13    ik_enabled: Box<[u8]>,
14    world_matrices: Box<[Mat4]>,
15    skinning_matrices: Box<[Mat4]>,
16}
17
18impl PoseArena {
19    pub fn new(bone_count: usize) -> Self {
20        Self::new_with_counts(bone_count, 0, 0)
21    }
22
23    pub fn new_with_morphs(bone_count: usize, morph_count: usize) -> Self {
24        Self::new_with_counts(bone_count, morph_count, 0)
25    }
26
27    pub fn new_with_counts(bone_count: usize, morph_count: usize, ik_count: usize) -> Self {
28        Self {
29            local_position_offsets: vec![Vec3A::ZERO; bone_count].into_boxed_slice(),
30            local_rotations: vec![Quat::IDENTITY; bone_count].into_boxed_slice(),
31            local_scales: vec![Vec3A::ONE; bone_count].into_boxed_slice(),
32            append_position_offsets: vec![Vec3A::ZERO; bone_count].into_boxed_slice(),
33            append_rotations: vec![Quat::IDENTITY; bone_count].into_boxed_slice(),
34            morph_weights: vec![0.0; morph_count].into_boxed_slice(),
35            ik_enabled: vec![1; ik_count].into_boxed_slice(),
36            world_matrices: vec![Mat4::IDENTITY; bone_count].into_boxed_slice(),
37            skinning_matrices: vec![Mat4::IDENTITY; bone_count].into_boxed_slice(),
38        }
39    }
40
41    pub fn reset_local_pose(&mut self) {
42        self.local_position_offsets.fill(Vec3A::ZERO);
43        self.local_rotations.fill(Quat::IDENTITY);
44        self.local_scales.fill(Vec3A::ONE);
45        self.reset_append_transforms();
46        self.morph_weights.fill(0.0);
47        self.ik_enabled.fill(1);
48    }
49
50    pub(crate) fn reset_append_transforms(&mut self) {
51        self.append_position_offsets.fill(Vec3A::ZERO);
52        self.append_rotations.fill(Quat::IDENTITY);
53    }
54
55    pub(crate) fn reset_append_transform(&mut self, bone: BoneIndex) {
56        self.append_position_offsets[bone.as_usize()] = Vec3A::ZERO;
57        self.append_rotations[bone.as_usize()] = Quat::IDENTITY;
58    }
59
60    #[inline]
61    pub fn set_local_position_offset(&mut self, bone: BoneIndex, value: Vec3A) {
62        self.local_position_offsets[bone.as_usize()] = value;
63    }
64
65    #[inline]
66    pub fn set_local_rotation(&mut self, bone: BoneIndex, value: Quat) {
67        self.local_rotations[bone.as_usize()] = value;
68    }
69
70    #[inline]
71    pub fn set_local_scale(&mut self, bone: BoneIndex, value: Vec3A) {
72        self.local_scales[bone.as_usize()] = value;
73    }
74
75    #[inline]
76    pub fn local_position_offset(&self, bone: BoneIndex) -> Vec3A {
77        self.local_position_offsets[bone.as_usize()]
78    }
79
80    #[inline]
81    pub fn local_rotation(&self, bone: BoneIndex) -> Quat {
82        self.local_rotations[bone.as_usize()]
83    }
84
85    #[inline]
86    pub fn local_scale(&self, bone: BoneIndex) -> Vec3A {
87        self.local_scales[bone.as_usize()]
88    }
89
90    #[inline]
91    pub(crate) fn append_position_offset(&self, bone: BoneIndex) -> Vec3A {
92        self.append_position_offsets[bone.as_usize()]
93    }
94
95    #[inline]
96    pub(crate) fn append_rotation(&self, bone: BoneIndex) -> Quat {
97        self.append_rotations[bone.as_usize()]
98    }
99
100    #[inline]
101    pub(crate) fn set_append_position_offset(&mut self, bone: BoneIndex, value: Vec3A) {
102        self.append_position_offsets[bone.as_usize()] = value;
103    }
104
105    #[inline]
106    pub(crate) fn set_append_rotation(&mut self, bone: BoneIndex, value: Quat) {
107        self.append_rotations[bone.as_usize()] = value;
108    }
109
110    #[inline]
111    pub(crate) fn set_world_matrix(&mut self, bone: BoneIndex, value: Mat4) {
112        self.world_matrices[bone.as_usize()] = value;
113    }
114
115    #[inline]
116    pub(crate) fn set_skinning_matrix(&mut self, bone: BoneIndex, value: Mat4) {
117        self.skinning_matrices[bone.as_usize()] = value;
118    }
119
120    #[inline]
121    pub fn set_morph_weight(&mut self, morph: MorphIndex, value: f32) {
122        self.morph_weights[morph.as_usize()] = value;
123    }
124
125    #[inline]
126    pub fn morph_weight(&self, morph: MorphIndex) -> f32 {
127        self.morph_weights[morph.as_usize()]
128    }
129
130    #[inline]
131    pub fn morph_weights(&self) -> &[f32] {
132        &self.morph_weights
133    }
134
135    #[inline]
136    pub fn set_ik_enabled(&mut self, ik_index: usize, enabled: bool) {
137        self.ik_enabled[ik_index] = u8::from(enabled);
138    }
139
140    #[inline]
141    pub fn ik_enabled(&self) -> &[u8] {
142        &self.ik_enabled
143    }
144
145    #[inline]
146    pub fn world_matrices(&self) -> &[Mat4] {
147        &self.world_matrices
148    }
149
150    #[inline]
151    pub fn skinning_matrices(&self) -> &[Mat4] {
152        &self.skinning_matrices
153    }
154}