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}