summaryrefslogtreecommitdiffstats
path: root/scene/3d
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2024-09-17 09:17:35 +0200
committerRémi Verschelde <rverschelde@gmail.com>2024-09-17 09:17:35 +0200
commite72a70de8e7fc64fae7859fe30fffa9732da5602 (patch)
tree96dba1d697bca625d804b073e2d21dba582ecec0 /scene/3d
parent13064c4ac848d7d8207a8a8b0d1eb02db91f9e62 (diff)
parent0468bea899fe4806d8358c1cab078f700ab84d22 (diff)
downloadredot-engine-e72a70de8e7fc64fae7859fe30fffa9732da5602.tar.gz
Merge pull request #87150 from demolke/bones
Add per-bone meta to Skeleton3D
Diffstat (limited to 'scene/3d')
-rw-r--r--scene/3d/skeleton_3d.cpp65
-rw-r--r--scene/3d/skeleton_3d.h9
2 files changed, 74 insertions, 0 deletions
diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp
index c6ece84cdd..db9c4db30d 100644
--- a/scene/3d/skeleton_3d.cpp
+++ b/scene/3d/skeleton_3d.cpp
@@ -103,6 +103,8 @@ bool Skeleton3D::_set(const StringName &p_path, const Variant &p_value) {
set_bone_pose_rotation(which, p_value);
} else if (what == "scale") {
set_bone_pose_scale(which, p_value);
+ } else if (what == "bone_meta") {
+ set_bone_meta(which, path.get_slicec('/', 3), p_value);
#ifndef DISABLE_DEPRECATED
} else if (what == "pose" || what == "bound_children") {
// Kept for compatibility from 3.x to 4.x.
@@ -170,6 +172,8 @@ bool Skeleton3D::_get(const StringName &p_path, Variant &r_ret) const {
r_ret = get_bone_pose_rotation(which);
} else if (what == "scale") {
r_ret = get_bone_pose_scale(which);
+ } else if (what == "bone_meta") {
+ r_ret = get_bone_meta(which, path.get_slicec('/', 3));
} else {
return false;
}
@@ -187,6 +191,11 @@ void Skeleton3D::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::VECTOR3, prep + PNAME("position"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
p_list->push_back(PropertyInfo(Variant::QUATERNION, prep + PNAME("rotation"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
p_list->push_back(PropertyInfo(Variant::VECTOR3, prep + PNAME("scale"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
+
+ for (const KeyValue<StringName, Variant> &K : bones[i].metadata) {
+ PropertyInfo pi = PropertyInfo(bones[i].metadata[K.key].get_type(), prep + PNAME("bone_meta/") + K.key, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR);
+ p_list->push_back(pi);
+ }
}
for (PropertyInfo &E : *p_list) {
@@ -531,6 +540,57 @@ void Skeleton3D::set_bone_name(int p_bone, const String &p_name) {
version++;
}
+Variant Skeleton3D::get_bone_meta(int p_bone, const StringName &p_key) const {
+ const int bone_size = bones.size();
+ ERR_FAIL_INDEX_V(p_bone, bone_size, Variant());
+
+ if (!bones[p_bone].metadata.has(p_key)) {
+ return Variant();
+ }
+ return bones[p_bone].metadata[p_key];
+}
+
+TypedArray<StringName> Skeleton3D::_get_bone_meta_list_bind(int p_bone) const {
+ const int bone_size = bones.size();
+ ERR_FAIL_INDEX_V(p_bone, bone_size, TypedArray<StringName>());
+
+ TypedArray<StringName> _metaret;
+ for (const KeyValue<StringName, Variant> &K : bones[p_bone].metadata) {
+ _metaret.push_back(K.key);
+ }
+ return _metaret;
+}
+
+void Skeleton3D::get_bone_meta_list(int p_bone, List<StringName> *p_list) const {
+ const int bone_size = bones.size();
+ ERR_FAIL_INDEX(p_bone, bone_size);
+
+ for (const KeyValue<StringName, Variant> &K : bones[p_bone].metadata) {
+ p_list->push_back(K.key);
+ }
+}
+
+bool Skeleton3D::has_bone_meta(int p_bone, const StringName &p_key) const {
+ const int bone_size = bones.size();
+ ERR_FAIL_INDEX_V(p_bone, bone_size, false);
+
+ return bones[p_bone].metadata.has(p_key);
+}
+
+void Skeleton3D::set_bone_meta(int p_bone, const StringName &p_key, const Variant &p_value) {
+ const int bone_size = bones.size();
+ ERR_FAIL_INDEX(p_bone, bone_size);
+
+ if (p_value.get_type() == Variant::NIL) {
+ if (bones.write[p_bone].metadata.has(p_key)) {
+ bones.write[p_bone].metadata.erase(p_key);
+ }
+ return;
+ }
+
+ bones.write[p_bone].metadata.insert(p_key, p_value, false);
+}
+
bool Skeleton3D::is_bone_parent_of(int p_bone, int p_parent_bone_id) const {
int parent_of_bone = get_bone_parent(p_bone);
@@ -1014,6 +1074,11 @@ void Skeleton3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_bone_name", "bone_idx"), &Skeleton3D::get_bone_name);
ClassDB::bind_method(D_METHOD("set_bone_name", "bone_idx", "name"), &Skeleton3D::set_bone_name);
+ ClassDB::bind_method(D_METHOD("get_bone_meta", "bone_idx", "key"), &Skeleton3D::get_bone_meta);
+ ClassDB::bind_method(D_METHOD("get_bone_meta_list", "bone_idx"), &Skeleton3D::_get_bone_meta_list_bind);
+ ClassDB::bind_method(D_METHOD("has_bone_meta", "bone_idx", "key"), &Skeleton3D::has_bone_meta);
+ ClassDB::bind_method(D_METHOD("set_bone_meta", "bone_idx", "key", "value"), &Skeleton3D::set_bone_meta);
+
ClassDB::bind_method(D_METHOD("get_concatenated_bone_names"), &Skeleton3D::get_concatenated_bone_names);
ClassDB::bind_method(D_METHOD("get_bone_parent", "bone_idx"), &Skeleton3D::get_bone_parent);
diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h
index a009383f45..07bdeccf2f 100644
--- a/scene/3d/skeleton_3d.h
+++ b/scene/3d/skeleton_3d.h
@@ -116,6 +116,8 @@ private:
}
}
+ HashMap<StringName, Variant> metadata;
+
#ifndef DISABLE_DEPRECATED
Transform3D pose_global_no_override;
real_t global_pose_override_amount = 0.0;
@@ -193,6 +195,7 @@ protected:
void _get_property_list(List<PropertyInfo> *p_list) const;
void _validate_property(PropertyInfo &p_property) const;
void _notification(int p_what);
+ TypedArray<StringName> _get_bone_meta_list_bind(int p_bone) const;
static void _bind_methods();
virtual void add_child_notify(Node *p_child) override;
@@ -238,6 +241,12 @@ public:
void set_motion_scale(float p_motion_scale);
float get_motion_scale() const;
+ // bone metadata
+ Variant get_bone_meta(int p_bone, const StringName &p_key) const;
+ void get_bone_meta_list(int p_bone, List<StringName> *p_list) const;
+ bool has_bone_meta(int p_bone, const StringName &p_key) const;
+ void set_bone_meta(int p_bone, const StringName &p_key, const Variant &p_value);
+
// Posing API
Transform3D get_bone_pose(int p_bone) const;
Vector3 get_bone_pose_position(int p_bone) const;