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    ik_rotations: Box<[Quat]>,
13    morph_weights: Box<[f32]>,
14    ik_enabled: Box<[u8]>,
15    world_matrices: Box<[Mat4]>,
16    skinning_matrices: Box<[Mat4]>,
17}
18
19impl PoseArena {
20    pub fn new(bone_count: usize) -> Self {
21        Self::new_with_counts(bone_count, 0, 0)
22    }
23
24    pub fn new_with_morphs(bone_count: usize, morph_count: usize) -> Self {
25        Self::new_with_counts(bone_count, morph_count, 0)
26    }
27
28    pub fn new_with_counts(bone_count: usize, morph_count: usize, ik_count: usize) -> Self {
29        Self {
30            local_position_offsets: vec![Vec3A::ZERO; bone_count].into_boxed_slice(),
31            local_rotations: vec![Quat::IDENTITY; bone_count].into_boxed_slice(),
32            local_scales: vec![Vec3A::ONE; bone_count].into_boxed_slice(),
33            append_position_offsets: vec![Vec3A::ZERO; bone_count].into_boxed_slice(),
34            append_rotations: vec![Quat::IDENTITY; bone_count].into_boxed_slice(),
35            ik_rotations: vec![Quat::IDENTITY; bone_count].into_boxed_slice(),
36            morph_weights: vec![0.0; morph_count].into_boxed_slice(),
37            ik_enabled: vec![1; ik_count].into_boxed_slice(),
38            world_matrices: vec![Mat4::IDENTITY; bone_count].into_boxed_slice(),
39            skinning_matrices: vec![Mat4::IDENTITY; bone_count].into_boxed_slice(),
40        }
41    }
42
43    pub fn reset_local_pose(&mut self) {
44        self.local_position_offsets.fill(Vec3A::ZERO);
45        self.local_rotations.fill(Quat::IDENTITY);
46        self.local_scales.fill(Vec3A::ONE);
47        self.reset_append_transforms();
48        self.ik_rotations.fill(Quat::IDENTITY);
49        self.morph_weights.fill(0.0);
50        self.ik_enabled.fill(1);
51    }
52
53    pub(crate) fn reset_append_transforms(&mut self) {
54        self.append_position_offsets.fill(Vec3A::ZERO);
55        self.append_rotations.fill(Quat::IDENTITY);
56    }
57
58    pub(crate) fn reset_append_transform(&mut self, bone: BoneIndex) {
59        self.append_position_offsets[bone.as_usize()] = Vec3A::ZERO;
60        self.append_rotations[bone.as_usize()] = Quat::IDENTITY;
61    }
62
63    pub(crate) fn reset_ik_rotations(&mut self) {
64        self.ik_rotations.fill(Quat::IDENTITY);
65    }
66
67    #[inline]
68    pub fn set_local_position_offset(&mut self, bone: BoneIndex, value: Vec3A) {
69        self.local_position_offsets[bone.as_usize()] = value;
70    }
71
72    #[inline]
73    pub fn set_local_rotation(&mut self, bone: BoneIndex, value: Quat) {
74        self.local_rotations[bone.as_usize()] = value;
75    }
76
77    #[inline]
78    pub fn set_local_scale(&mut self, bone: BoneIndex, value: Vec3A) {
79        self.local_scales[bone.as_usize()] = value;
80    }
81
82    #[inline]
83    pub fn local_position_offset(&self, bone: BoneIndex) -> Vec3A {
84        self.local_position_offsets[bone.as_usize()]
85    }
86
87    #[inline]
88    pub fn local_rotation(&self, bone: BoneIndex) -> Quat {
89        self.local_rotations[bone.as_usize()]
90    }
91
92    #[inline]
93    pub fn local_scale(&self, bone: BoneIndex) -> Vec3A {
94        self.local_scales[bone.as_usize()]
95    }
96
97    #[inline]
98    pub fn local_position_offsets(&self) -> &[Vec3A] {
99        &self.local_position_offsets
100    }
101
102    #[inline]
103    pub fn local_rotations(&self) -> &[Quat] {
104        &self.local_rotations
105    }
106
107    #[inline]
108    pub fn local_scales(&self) -> &[Vec3A] {
109        &self.local_scales
110    }
111
112    pub(crate) fn set_local_position_offsets_from_slice(&mut self, src: &[Vec3A]) {
113        self.local_position_offsets.copy_from_slice(src);
114    }
115
116    pub(crate) fn set_local_rotations_from_slice(&mut self, src: &[Quat]) {
117        self.local_rotations.copy_from_slice(src);
118    }
119
120    pub(crate) fn set_local_scales_from_slice(&mut self, src: &[Vec3A]) {
121        self.local_scales.copy_from_slice(src);
122    }
123
124    pub(crate) fn set_morph_weights_from_slice(&mut self, src: &[f32]) {
125        self.morph_weights.copy_from_slice(src);
126    }
127
128    pub(crate) fn set_ik_enabled_from_slice(&mut self, src: &[u8]) {
129        self.ik_enabled.copy_from_slice(src);
130    }
131
132    #[inline]
133    pub(crate) fn append_position_offset(&self, bone: BoneIndex) -> Vec3A {
134        self.append_position_offsets[bone.as_usize()]
135    }
136
137    #[inline]
138    pub(crate) fn append_rotation(&self, bone: BoneIndex) -> Quat {
139        self.append_rotations[bone.as_usize()]
140    }
141
142    #[inline]
143    pub(crate) fn ik_rotation(&self, bone: BoneIndex) -> Quat {
144        self.ik_rotations[bone.as_usize()]
145    }
146
147    #[inline]
148    pub(crate) fn set_append_position_offset(&mut self, bone: BoneIndex, value: Vec3A) {
149        self.append_position_offsets[bone.as_usize()] = value;
150    }
151
152    #[inline]
153    pub(crate) fn set_append_rotation(&mut self, bone: BoneIndex, value: Quat) {
154        self.append_rotations[bone.as_usize()] = value;
155    }
156
157    #[inline]
158    pub(crate) fn set_ik_rotation(&mut self, bone: BoneIndex, value: Quat) {
159        self.ik_rotations[bone.as_usize()] = value;
160    }
161
162    #[inline]
163    pub(crate) fn set_world_matrix(&mut self, bone: BoneIndex, value: Mat4) {
164        self.world_matrices[bone.as_usize()] = value;
165    }
166
167    #[inline]
168    pub(crate) fn set_skinning_matrix(&mut self, bone: BoneIndex, value: Mat4) {
169        self.skinning_matrices[bone.as_usize()] = value;
170    }
171
172    #[inline]
173    pub fn set_morph_weight(&mut self, morph: MorphIndex, value: f32) {
174        self.morph_weights[morph.as_usize()] = value;
175    }
176
177    #[inline]
178    pub fn morph_weight(&self, morph: MorphIndex) -> f32 {
179        self.morph_weights[morph.as_usize()]
180    }
181
182    #[inline]
183    pub fn morph_weights(&self) -> &[f32] {
184        &self.morph_weights
185    }
186
187    #[inline]
188    pub fn set_ik_enabled(&mut self, ik_index: usize, enabled: bool) {
189        self.ik_enabled[ik_index] = u8::from(enabled);
190    }
191
192    #[inline]
193    pub fn ik_enabled(&self) -> &[u8] {
194        &self.ik_enabled
195    }
196
197    #[inline]
198    pub fn world_matrices(&self) -> &[Mat4] {
199        &self.world_matrices
200    }
201
202    #[inline]
203    pub fn skinning_matrices(&self) -> &[Mat4] {
204        &self.skinning_matrices
205    }
206}