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(crate) fn append_position_offset(&self, bone: BoneIndex) -> Vec3A {
99        self.append_position_offsets[bone.as_usize()]
100    }
101
102    #[inline]
103    pub(crate) fn append_rotation(&self, bone: BoneIndex) -> Quat {
104        self.append_rotations[bone.as_usize()]
105    }
106
107    #[inline]
108    pub(crate) fn ik_rotation(&self, bone: BoneIndex) -> Quat {
109        self.ik_rotations[bone.as_usize()]
110    }
111
112    #[inline]
113    pub(crate) fn set_append_position_offset(&mut self, bone: BoneIndex, value: Vec3A) {
114        self.append_position_offsets[bone.as_usize()] = value;
115    }
116
117    #[inline]
118    pub(crate) fn set_append_rotation(&mut self, bone: BoneIndex, value: Quat) {
119        self.append_rotations[bone.as_usize()] = value;
120    }
121
122    #[inline]
123    pub(crate) fn set_ik_rotation(&mut self, bone: BoneIndex, value: Quat) {
124        self.ik_rotations[bone.as_usize()] = value;
125    }
126
127    #[inline]
128    pub(crate) fn set_world_matrix(&mut self, bone: BoneIndex, value: Mat4) {
129        self.world_matrices[bone.as_usize()] = value;
130    }
131
132    #[inline]
133    pub(crate) fn set_skinning_matrix(&mut self, bone: BoneIndex, value: Mat4) {
134        self.skinning_matrices[bone.as_usize()] = value;
135    }
136
137    #[inline]
138    pub fn set_morph_weight(&mut self, morph: MorphIndex, value: f32) {
139        self.morph_weights[morph.as_usize()] = value;
140    }
141
142    #[inline]
143    pub fn morph_weight(&self, morph: MorphIndex) -> f32 {
144        self.morph_weights[morph.as_usize()]
145    }
146
147    #[inline]
148    pub fn morph_weights(&self) -> &[f32] {
149        &self.morph_weights
150    }
151
152    #[inline]
153    pub fn set_ik_enabled(&mut self, ik_index: usize, enabled: bool) {
154        self.ik_enabled[ik_index] = u8::from(enabled);
155    }
156
157    #[inline]
158    pub fn ik_enabled(&self) -> &[u8] {
159        &self.ik_enabled
160    }
161
162    #[inline]
163    pub fn world_matrices(&self) -> &[Mat4] {
164        &self.world_matrices
165    }
166
167    #[inline]
168    pub fn skinning_matrices(&self) -> &[Mat4] {
169        &self.skinning_matrices
170    }
171}