diff options
Diffstat (limited to 'scene/3d/skeleton_3d.cpp')
-rw-r--r-- | scene/3d/skeleton_3d.cpp | 137 |
1 files changed, 47 insertions, 90 deletions
diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 973822653a..7516cf95b0 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -67,39 +67,37 @@ SkinReference::~SkinReference() { } bool Skeleton3D::_set(const StringName &p_path, const Variant &p_value) { - String path = p_path; - if (!path.begins_with("bones/")) + if (!path.begins_with("bones/")) { return false; + } int which = path.get_slicec('/', 1).to_int(); String what = path.get_slicec('/', 2); if (which == bones.size() && what == "name") { - add_bone(p_value); return true; } ERR_FAIL_INDEX_V(which, bones.size(), false); - if (what == "parent") + if (what == "parent") { set_bone_parent(which, p_value); - else if (what == "rest") + } else if (what == "rest") { set_bone_rest(which, p_value); - else if (what == "enabled") + } else if (what == "enabled") { set_bone_enabled(which, p_value); - else if (what == "pose") + } else if (what == "pose") { set_bone_pose(which, p_value); - else if (what == "bound_children") { + } else if (what == "bound_children") { Array children = p_value; if (is_inside_tree()) { bones.write[which].nodes_bound.clear(); for (int i = 0; i < children.size(); i++) { - NodePath npath = children[i]; ERR_CONTINUE(npath.operator String() == ""); Node *node = get_node(npath); @@ -115,32 +113,31 @@ bool Skeleton3D::_set(const StringName &p_path, const Variant &p_value) { } bool Skeleton3D::_get(const StringName &p_path, Variant &r_ret) const { - String path = p_path; - if (!path.begins_with("bones/")) + if (!path.begins_with("bones/")) { return false; + } int which = path.get_slicec('/', 1).to_int(); String what = path.get_slicec('/', 2); ERR_FAIL_INDEX_V(which, bones.size(), false); - if (what == "name") + if (what == "name") { r_ret = get_bone_name(which); - else if (what == "parent") + } else if (what == "parent") { r_ret = get_bone_parent(which); - else if (what == "rest") + } else if (what == "rest") { r_ret = get_bone_rest(which); - else if (what == "enabled") + } else if (what == "enabled") { r_ret = is_bone_enabled(which); - else if (what == "pose") + } else if (what == "pose") { r_ret = get_bone_pose(which); - else if (what == "bound_children") { + } else if (what == "bound_children") { Array children; for (const List<ObjectID>::Element *E = bones[which].nodes_bound.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->get()); ERR_CONTINUE(!obj); Node *node = Object::cast_to<Node>(obj); @@ -150,15 +147,15 @@ bool Skeleton3D::_get(const StringName &p_path, Variant &r_ret) const { } r_ret = children; - } else + } else { return false; + } return true; } -void Skeleton3D::_get_property_list(List<PropertyInfo> *p_list) const { +void Skeleton3D::_get_property_list(List<PropertyInfo> *p_list) const { for (int i = 0; i < bones.size(); i++) { - String prep = "bones/" + itos(i) + "/"; p_list->push_back(PropertyInfo(Variant::STRING, prep + "name")); p_list->push_back(PropertyInfo(Variant::INT, prep + "parent", PROPERTY_HINT_RANGE, "-1," + itos(bones.size() - 1) + ",1")); @@ -170,9 +167,9 @@ void Skeleton3D::_get_property_list(List<PropertyInfo> *p_list) const { } void Skeleton3D::_update_process_order() { - - if (!process_order_dirty) + if (!process_order_dirty) { return; + } Bone *bonesptr = bones.ptrw(); int len = bones.size(); @@ -180,7 +177,6 @@ void Skeleton3D::_update_process_order() { process_order.resize(len); int *order = process_order.ptrw(); for (int i = 0; i < len; i++) { - if (bonesptr[i].parent >= len) { //validate this just in case ERR_PRINT("Bone " + itos(i) + " has invalid parent: " + itos(bonesptr[i].parent)); @@ -197,8 +193,9 @@ void Skeleton3D::_update_process_order() { bool swapped = false; for (int i = 0; i < len; i++) { int parent_idx = bonesptr[order[i]].parent; - if (parent_idx < 0) + if (parent_idx < 0) { continue; //do nothing because it has no parent + } //swap indices int parent_order = bonesptr[parent_idx].sort_index; if (parent_order > i) { @@ -210,8 +207,9 @@ void Skeleton3D::_update_process_order() { } } - if (!swapped) + if (!swapped) { break; + } pass_count++; } @@ -223,11 +221,8 @@ void Skeleton3D::_update_process_order() { } void Skeleton3D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_UPDATE_SKELETON: { - RenderingServer *vs = RenderingServer::get_singleton(); Bone *bonesptr = bones.ptrw(); int len = bones.size(); @@ -237,7 +232,6 @@ void Skeleton3D::_notification(int p_what) { const int *order = process_order.ptr(); for (int i = 0; i < len; i++) { - Bone &b = bonesptr[order[i]]; if (b.global_pose_override_amount >= 0.999) { @@ -245,50 +239,38 @@ void Skeleton3D::_notification(int p_what) { } else { if (b.disable_rest) { if (b.enabled) { - Transform pose = b.pose; if (b.custom_pose_enable) { pose = b.custom_pose * pose; } if (b.parent >= 0) { - b.pose_global = bonesptr[b.parent].pose_global * pose; } else { - b.pose_global = pose; } } else { - if (b.parent >= 0) { - b.pose_global = bonesptr[b.parent].pose_global; } else { - b.pose_global = Transform(); } } } else { if (b.enabled) { - Transform pose = b.pose; if (b.custom_pose_enable) { pose = b.custom_pose * pose; } if (b.parent >= 0) { - b.pose_global = bonesptr[b.parent].pose_global * (b.rest * pose); } else { - b.pose_global = b.rest * pose; } } else { - if (b.parent >= 0) { - b.pose_global = bonesptr[b.parent].pose_global * b.rest; } else { - b.pose_global = b.rest; } } @@ -304,7 +286,6 @@ void Skeleton3D::_notification(int p_what) { } for (List<ObjectID>::Element *E = b.nodes_bound.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->get()); ERR_CONTINUE(!obj); Node3D *sp = Object::cast_to<Node3D>(obj); @@ -315,7 +296,6 @@ void Skeleton3D::_notification(int p_what) { //update skins for (Set<SkinReference *>::Element *E = skin_bindings.front(); E; E = E->next()) { - const Skin *skin = E->get()->skin.operator->(); RID skeleton = E->get()->skeleton; uint32_t bind_count = skin->get_bind_count(); @@ -328,7 +308,6 @@ void Skeleton3D::_notification(int p_what) { } if (E->get()->skeleton_version != version) { - for (uint32_t i = 0; i < bind_count; i++) { StringName bind_name = skin->get_bind_name(i); @@ -405,7 +384,6 @@ void Skeleton3D::clear_bones_global_pose_override() { } void Skeleton3D::set_bone_global_pose_override(int p_bone, const Transform &p_pose, float p_amount, bool p_persistent) { - ERR_FAIL_INDEX(p_bone, bones.size()); bones.write[p_bone].global_pose_override_amount = p_amount; bones.write[p_bone].global_pose_override = p_pose; @@ -414,20 +392,18 @@ void Skeleton3D::set_bone_global_pose_override(int p_bone, const Transform &p_po } Transform Skeleton3D::get_bone_global_pose(int p_bone) const { - ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform()); - if (dirty) + if (dirty) { const_cast<Skeleton3D *>(this)->notification(NOTIFICATION_UPDATE_SKELETON); + } return bones[p_bone].pose_global; } // skeleton creation api void Skeleton3D::add_bone(const String &p_name) { - ERR_FAIL_COND(p_name == "" || p_name.find(":") != -1 || p_name.find("/") != -1); for (int i = 0; i < bones.size(); i++) { - ERR_FAIL_COND(bones[i].name == p_name); } @@ -439,43 +415,42 @@ void Skeleton3D::add_bone(const String &p_name) { _make_dirty(); update_gizmo(); } -int Skeleton3D::find_bone(const String &p_name) const { +int Skeleton3D::find_bone(const String &p_name) const { for (int i = 0; i < bones.size(); i++) { - - if (bones[i].name == p_name) + if (bones[i].name == p_name) { return i; + } } return -1; } -String Skeleton3D::get_bone_name(int p_bone) const { +String Skeleton3D::get_bone_name(int p_bone) const { ERR_FAIL_INDEX_V(p_bone, bones.size(), ""); return bones[p_bone].name; } bool Skeleton3D::is_bone_parent_of(int p_bone, int p_parent_bone_id) const { - int parent_of_bone = get_bone_parent(p_bone); - if (-1 == parent_of_bone) + if (-1 == parent_of_bone) { return false; + } - if (parent_of_bone == p_parent_bone_id) + if (parent_of_bone == p_parent_bone_id) { return true; + } return is_bone_parent_of(parent_of_bone, p_parent_bone_id); } int Skeleton3D::get_bone_count() const { - return bones.size(); } void Skeleton3D::set_bone_parent(int p_bone, int p_parent) { - ERR_FAIL_INDEX(p_bone, bones.size()); ERR_FAIL_COND(p_parent != -1 && (p_parent < 0)); @@ -485,7 +460,6 @@ void Skeleton3D::set_bone_parent(int p_bone, int p_parent) { } void Skeleton3D::unparent_bone_and_rest(int p_bone) { - ERR_FAIL_INDEX(p_bone, bones.size()); _update_process_order(); @@ -503,80 +477,73 @@ void Skeleton3D::unparent_bone_and_rest(int p_bone) { } void Skeleton3D::set_bone_disable_rest(int p_bone, bool p_disable) { - ERR_FAIL_INDEX(p_bone, bones.size()); bones.write[p_bone].disable_rest = p_disable; } bool Skeleton3D::is_bone_rest_disabled(int p_bone) const { - ERR_FAIL_INDEX_V(p_bone, bones.size(), false); return bones[p_bone].disable_rest; } int Skeleton3D::get_bone_parent(int p_bone) const { - ERR_FAIL_INDEX_V(p_bone, bones.size(), -1); return bones[p_bone].parent; } void Skeleton3D::set_bone_rest(int p_bone, const Transform &p_rest) { - ERR_FAIL_INDEX(p_bone, bones.size()); bones.write[p_bone].rest = p_rest; _make_dirty(); } -Transform Skeleton3D::get_bone_rest(int p_bone) const { +Transform Skeleton3D::get_bone_rest(int p_bone) const { ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform()); return bones[p_bone].rest; } void Skeleton3D::set_bone_enabled(int p_bone, bool p_enabled) { - ERR_FAIL_INDEX(p_bone, bones.size()); bones.write[p_bone].enabled = p_enabled; _make_dirty(); } -bool Skeleton3D::is_bone_enabled(int p_bone) const { +bool Skeleton3D::is_bone_enabled(int p_bone) const { ERR_FAIL_INDEX_V(p_bone, bones.size(), false); return bones[p_bone].enabled; } void Skeleton3D::bind_child_node_to_bone(int p_bone, Node *p_node) { - ERR_FAIL_NULL(p_node); ERR_FAIL_INDEX(p_bone, bones.size()); ObjectID id = p_node->get_instance_id(); for (const List<ObjectID>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) { - - if (E->get() == id) + if (E->get() == id) { return; // already here + } } bones.write[p_bone].nodes_bound.push_back(id); } -void Skeleton3D::unbind_child_node_from_bone(int p_bone, Node *p_node) { +void Skeleton3D::unbind_child_node_from_bone(int p_bone, Node *p_node) { ERR_FAIL_NULL(p_node); ERR_FAIL_INDEX(p_bone, bones.size()); ObjectID id = p_node->get_instance_id(); bones.write[p_bone].nodes_bound.erase(id); } -void Skeleton3D::get_bound_child_nodes_to_bone(int p_bone, List<Node *> *p_bound) const { +void Skeleton3D::get_bound_child_nodes_to_bone(int p_bone, List<Node *> *p_bound) const { ERR_FAIL_INDEX(p_bone, bones.size()); for (const List<ObjectID>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->get()); ERR_CONTINUE(!obj); p_bound->push_back(Object::cast_to<Node>(obj)); @@ -584,7 +551,6 @@ void Skeleton3D::get_bound_child_nodes_to_bone(int p_bone, List<Node *> *p_bound } void Skeleton3D::clear_bones() { - bones.clear(); process_order_dirty = true; version++; @@ -594,7 +560,6 @@ void Skeleton3D::clear_bones() { // posing api void Skeleton3D::set_bone_pose(int p_bone, const Transform &p_pose) { - ERR_FAIL_INDEX(p_bone, bones.size()); bones.write[p_bone].pose = p_pose; @@ -602,14 +567,13 @@ void Skeleton3D::set_bone_pose(int p_bone, const Transform &p_pose) { _make_dirty(); } } -Transform Skeleton3D::get_bone_pose(int p_bone) const { +Transform Skeleton3D::get_bone_pose(int p_bone) const { ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform()); return bones[p_bone].pose; } void Skeleton3D::set_bone_custom_pose(int p_bone, const Transform &p_custom_pose) { - ERR_FAIL_INDEX(p_bone, bones.size()); //ERR_FAIL_COND( !is_inside_scene() ); @@ -620,15 +584,14 @@ void Skeleton3D::set_bone_custom_pose(int p_bone, const Transform &p_custom_pose } Transform Skeleton3D::get_bone_custom_pose(int p_bone) const { - ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform()); return bones[p_bone].custom_pose; } void Skeleton3D::_make_dirty() { - - if (dirty) + if (dirty) { return; + } MessageQueue::get_singleton()->push_notification(this, NOTIFICATION_UPDATE_SKELETON); dirty = true; @@ -641,7 +604,6 @@ int Skeleton3D::get_process_order(int p_idx) { } void Skeleton3D::localize_rests() { - _update_process_order(); for (int i = bones.size() - 1; i >= 0; i--) { @@ -729,14 +691,14 @@ void Skeleton3D::_rebuild_physical_bones_cache() { PhysicalBone3D *parent_pb = _get_physical_bone_parent(i); if (parent_pb != bones[i].physical_bone) { bones.write[i].cache_parent_physical_bone = parent_pb; - if (bones[i].physical_bone) + if (bones[i].physical_bone) { bones[i].physical_bone->_on_bone_parent_changed(); + } } } } void _pb_stop_simulation(Node *p_node) { - for (int i = p_node->get_child_count() - 1; 0 <= i; --i) { _pb_stop_simulation(p_node->get_child(i)); } @@ -755,7 +717,6 @@ void Skeleton3D::physical_bones_stop_simulation() { } void _pb_start_simulation(const Skeleton3D *p_skeleton, Node *p_node, const Vector<int> &p_sim_bones) { - for (int i = p_node->get_child_count() - 1; 0 <= i; --i) { _pb_start_simulation(p_skeleton, p_node->get_child(i), p_sim_bones); } @@ -782,8 +743,9 @@ void Skeleton3D::physical_bones_start_simulation_on(const TypedArray<StringName> int c = 0; for (int i = sim_bones.size() - 1; 0 <= i; --i) { int bone_id = find_bone(p_bones[i]); - if (bone_id != -1) + if (bone_id != -1) { sim_bones.write[c++] = bone_id; + } } sim_bones.resize(c); } @@ -792,7 +754,6 @@ void Skeleton3D::physical_bones_start_simulation_on(const TypedArray<StringName> } void _physical_bones_add_remove_collision_exception(bool p_add, Node *p_node, RID p_exception) { - for (int i = p_node->get_child_count() - 1; 0 <= i; --i) { _physical_bones_add_remove_collision_exception(p_add, p_node->get_child(i), p_exception); } @@ -822,7 +783,6 @@ void Skeleton3D::_skin_changed() { } Ref<SkinReference> Skeleton3D::register_skin(const Ref<Skin> &p_skin) { - for (Set<SkinReference *>::Element *E = skin_bindings.front(); E; E = E->next()) { if (E->get()->skin == p_skin) { return Ref<SkinReference>(E->get()); @@ -883,7 +843,6 @@ Ref<SkinReference> Skeleton3D::register_skin(const Ref<Skin> &p_skin) { } void Skeleton3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("add_bone", "name"), &Skeleton3D::add_bone); ClassDB::bind_method(D_METHOD("find_bone", "name"), &Skeleton3D::find_bone); ClassDB::bind_method(D_METHOD("get_bone_name", "bone_idx"), &Skeleton3D::get_bone_name); @@ -938,7 +897,6 @@ void Skeleton3D::_bind_methods() { } Skeleton3D::Skeleton3D() { - animate_physical_bones = true; dirty = false; version = 1; @@ -946,7 +904,6 @@ Skeleton3D::Skeleton3D() { } Skeleton3D::~Skeleton3D() { - //some skins may remain bound for (Set<SkinReference *>::Element *E = skin_bindings.front(); E; E = E->next()) { E->get()->skeleton_node = nullptr; |