Skip to content

Commit

Permalink
Merge pull request #77307 from 44zb/skeleton-find-bone-performance
Browse files Browse the repository at this point in the history
Improve `Skeleton3D::find_bone()` performance
  • Loading branch information
akien-mga committed May 23, 2023
2 parents 8f9e067 + f645eee commit 4e9e5e8
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 16 deletions.
28 changes: 12 additions & 16 deletions scene/3d/skeleton_3d.cpp
Expand Up @@ -383,15 +383,12 @@ uint64_t Skeleton3D::get_version() const {
}

void Skeleton3D::add_bone(const String &p_name) {
ERR_FAIL_COND(p_name.is_empty() || p_name.contains(":") || p_name.contains("/"));

for (int i = 0; i < bones.size(); i++) {
ERR_FAIL_COND(bones[i].name == p_name);
}
ERR_FAIL_COND(p_name.is_empty() || p_name.contains(":") || p_name.contains("/") || name_to_bone_index.has(p_name));

Bone b;
b.name = p_name;
bones.push_back(b);
name_to_bone_index.insert(p_name, bones.size() - 1);
process_order_dirty = true;
version++;
rest_dirty = true;
Expand All @@ -400,31 +397,30 @@ void Skeleton3D::add_bone(const String &p_name) {
}

int Skeleton3D::find_bone(const String &p_name) const {
for (int i = 0; i < bones.size(); i++) {
if (bones[i].name == p_name) {
return i;
}
}

return -1;
const int *bone_index_ptr = name_to_bone_index.getptr(p_name);
return bone_index_ptr != nullptr ? *bone_index_ptr : -1;
}

String Skeleton3D::get_bone_name(int p_bone) const {
const int bone_size = bones.size();
ERR_FAIL_INDEX_V(p_bone, bone_size, "");
return bones[p_bone].name;
}

void Skeleton3D::set_bone_name(int p_bone, const String &p_name) {
const int bone_size = bones.size();
ERR_FAIL_INDEX(p_bone, bone_size);

for (int i = 0; i < bone_size; i++) {
if (i != p_bone) {
ERR_FAIL_COND_MSG(bones[i].name == p_name, "Skeleton3D: '" + get_name() + "', bone name: '" + p_name + "' is already exist.");
}
const int *bone_index_ptr = name_to_bone_index.getptr(p_name);
if (bone_index_ptr != nullptr) {
ERR_FAIL_COND_MSG(*bone_index_ptr != p_bone, "Skeleton3D: '" + get_name() + "', bone name: '" + p_name + "' already exists.");
return; // No need to rename, the bone already has the given name.
}

name_to_bone_index.erase(bones[p_bone].name);
bones.write[p_bone].name = p_name;
name_to_bone_index.insert(p_name, p_bone);

version++;
}

Expand Down
1 change: 1 addition & 0 deletions scene/3d/skeleton_3d.h
Expand Up @@ -125,6 +125,7 @@ class Skeleton3D : public Node3D {
bool process_order_dirty = false;

Vector<int> parentless_bones;
HashMap<String, int> name_to_bone_index;

void _make_dirty();
bool dirty = false;
Expand Down

0 comments on commit 4e9e5e8

Please sign in to comment.