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}