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}