summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2023-05-23 19:14:34 +0200
committerRémi Verschelde <rverschelde@gmail.com>2023-05-23 19:14:34 +0200
commit4e9e5e85b608f23b5b88c8fa1c0f08678acdc0fe (patch)
tree03185beb2446904f7d705e69acef2679cf02122c
parent8f9e0672fb015b11d8b03a35e077f16e60308042 (diff)
parentf645eee62eadb71721e9d7c2d926fc4293a05c7c (diff)
downloadredot-engine-4e9e5e85b608f23b5b88c8fa1c0f08678acdc0fe.tar.gz
Merge pull request #77307 from 44zb/skeleton-find-bone-performance
Improve `Skeleton3D::find_bone()` performance
-rw-r--r--scene/3d/skeleton_3d.cpp28
-rw-r--r--scene/3d/skeleton_3d.h1
2 files changed, 13 insertions, 16 deletions
diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp
index 3b048dc4f2..32fe15f744 100644
--- a/scene/3d/skeleton_3d.cpp
+++ b/scene/3d/skeleton_3d.cpp
@@ -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;
@@ -400,13 +397,8 @@ 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 {
@@ -414,17 +406,21 @@ String Skeleton3D::get_bone_name(int p_bone) const {
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++;
}
diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h
index 3df909d936..7d4df1d1f2 100644
--- a/scene/3d/skeleton_3d.h
+++ b/scene/3d/skeleton_3d.h
@@ -125,6 +125,7 @@ private:
bool process_order_dirty = false;
Vector<int> parentless_bones;
+ HashMap<String, int> name_to_bone_index;
void _make_dirty();
bool dirty = false;