Improve performance of `Skeleton3D::force_update_bone_children_transforms`

This commit is contained in:
detomon 2024-09-27 09:04:57 +02:00
parent efd0e9df74
commit 1e479b0294
2 changed files with 10 additions and 15 deletions

View File

@ -471,6 +471,7 @@ void Skeleton3D::_make_modifiers_dirty() {
} }
void Skeleton3D::_update_bones_nested_set() { void Skeleton3D::_update_bones_nested_set() {
nested_set_offset_to_bone_index.resize(bones.size());
bone_global_pose_dirty.resize(bones.size()); bone_global_pose_dirty.resize(bones.size());
_make_bone_global_poses_dirty(); _make_bone_global_poses_dirty();
@ -490,6 +491,7 @@ int Skeleton3D::_update_bone_nested_set(int p_bone, int p_offset) {
span += subspan; span += subspan;
} }
nested_set_offset_to_bone_index[p_offset] = p_bone;
bones.write[p_bone].nested_set_offset = p_offset; bones.write[p_bone].nested_set_offset = p_offset;
bones.write[p_bone].nested_set_span = span; bones.write[p_bone].nested_set_span = span;
@ -1056,14 +1058,14 @@ void Skeleton3D::force_update_bone_children_transforms(int p_bone_idx) {
ERR_FAIL_INDEX(p_bone_idx, bone_size); ERR_FAIL_INDEX(p_bone_idx, bone_size);
Bone *bonesptr = bones.ptrw(); Bone *bonesptr = bones.ptrw();
thread_local LocalVector<int> bones_to_process;
bones_to_process.clear();
bones_to_process.push_back(p_bone_idx);
uint32_t index = 0; // Loop through nested set.
while (index < bones_to_process.size()) { for (int offset = 0; offset < bone_size; offset++) {
int current_bone_idx = bones_to_process[index]; if (!bone_global_pose_dirty[offset]) {
continue;
}
int current_bone_idx = nested_set_offset_to_bone_index[offset];
Bone &b = bonesptr[current_bone_idx]; Bone &b = bonesptr[current_bone_idx];
bool bone_enabled = b.enabled && !show_rest_only; bool bone_enabled = b.enabled && !show_rest_only;
@ -1110,15 +1112,7 @@ void Skeleton3D::force_update_bone_children_transforms(int p_bone_idx) {
} }
#endif // _DISABLE_DEPRECATED #endif // _DISABLE_DEPRECATED
bone_global_pose_dirty[b.nested_set_offset] = false; bone_global_pose_dirty[offset] = false;
// Add the bone's children to the list of bones to be processed.
int child_bone_size = b.child_bones.size();
for (int i = 0; i < child_bone_size; i++) {
bones_to_process.push_back(b.child_bones[i]);
}
index++;
} }
} }

View File

@ -186,6 +186,7 @@ private:
LocalVector<BonePoseBackup> bones_backup; LocalVector<BonePoseBackup> bones_backup;
// Global bone pose calculation. // Global bone pose calculation.
LocalVector<int> nested_set_offset_to_bone_index; // Map from Bone::nested_set_offset to bone index.
LocalVector<bool> bone_global_pose_dirty; // Indexable with Bone::nested_set_offset. LocalVector<bool> bone_global_pose_dirty; // Indexable with Bone::nested_set_offset.
void _update_bones_nested_set(); void _update_bones_nested_set();
int _update_bone_nested_set(int p_bone, int p_offset); int _update_bone_nested_set(int p_bone, int p_offset);