diff options
Diffstat (limited to 'scene')
-rw-r--r-- | scene/2d/light_2d.cpp | 5 | ||||
-rw-r--r-- | scene/2d/light_2d.h | 2 | ||||
-rw-r--r-- | scene/3d/light_3d.cpp | 5 | ||||
-rw-r--r-- | scene/3d/light_3d.h | 2 | ||||
-rw-r--r-- | scene/animation/animation_node_state_machine.cpp | 22 | ||||
-rw-r--r-- | scene/animation/animation_node_state_machine.h | 6 | ||||
-rw-r--r-- | scene/animation/animation_player.cpp | 7 | ||||
-rw-r--r-- | scene/animation/animation_tree.cpp | 55 | ||||
-rw-r--r-- | scene/main/node.cpp | 5 | ||||
-rw-r--r-- | scene/main/node.h | 1 | ||||
-rw-r--r-- | scene/resources/importer_mesh.cpp | 8 | ||||
-rw-r--r-- | scene/resources/mesh.cpp | 11 |
12 files changed, 97 insertions, 32 deletions
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 28d9b284e6..0481a58431 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -30,6 +30,11 @@ #include "light_2d.h" +void Light2D::owner_changed_notify() { + // For cases where owner changes _after_ entering tree (as example, editor editing). + _update_light_visibility(); +} + void Light2D::_update_light_visibility() { if (!is_inside_tree()) { return; diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index f7b1f420e3..a84b6516c0 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -73,6 +73,8 @@ private: void _update_light_visibility(); + virtual void owner_changed_notify() override; + protected: _FORCE_INLINE_ RID _get_light() const { return canvas_light; } void _notification(int p_what); diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index 28614d7cae..6c999d85e2 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -176,6 +176,11 @@ Ref<Texture2D> Light3D::get_projector() const { return projector; } +void Light3D::owner_changed_notify() { + // For cases where owner changes _after_ entering tree (as example, editor editing). + _update_visibility(); +} + void Light3D::_update_visibility() { if (!is_inside_tree()) { return; diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index 383fa644e5..6ff332df5a 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -85,6 +85,8 @@ private: // bind helpers + virtual void owner_changed_notify() override; + protected: RID light; diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 2c7d021427..8dcf538b8f 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -435,7 +435,7 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s // handles start_node: if previous state machine is pointing to a node inside the current state machine, starts the current machine from start_node to prev_local_to if (p_state_machine->start_node == current && p_state_machine->transitions[i].local_from == current) { - if (p_state_machine->prev_state_machine.is_valid()) { + if (p_state_machine->prev_state_machine != nullptr) { Ref<AnimationNodeStateMachinePlayback> prev_playback = p_state_machine->prev_state_machine->get_parameter("playback"); if (prev_playback.is_valid()) { @@ -471,9 +471,9 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s } if (next == p_state_machine->end_node) { - Ref<AnimationNodeStateMachine> prev_state_machine = p_state_machine->prev_state_machine; + AnimationNodeStateMachine *prev_state_machine = p_state_machine->prev_state_machine; - if (prev_state_machine.is_valid()) { + if (prev_state_machine != nullptr) { Ref<AnimationNodeStateMachinePlayback> prev_playback = prev_state_machine->get_parameter("playback"); if (prev_playback.is_valid()) { @@ -655,7 +655,7 @@ void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<Animation if (anodesm.is_valid()) { anodesm->state_machine_name = p_name; - anodesm->prev_state_machine = (Ref<AnimationNodeStateMachine>)this; + anodesm->prev_state_machine = this; } emit_changed(); @@ -821,7 +821,7 @@ void AnimationNodeStateMachine::_rename_transition(const StringName &p_name, con void AnimationNodeStateMachine::get_node_list(List<StringName> *r_nodes) const { List<StringName> nodes; for (const KeyValue<StringName, State> &E : states) { - if (E.key == end_node && !prev_state_machine.is_valid()) { + if (E.key == end_node && prev_state_machine == nullptr) { continue; } @@ -834,7 +834,7 @@ void AnimationNodeStateMachine::get_node_list(List<StringName> *r_nodes) const { } } -Ref<AnimationNodeStateMachine> AnimationNodeStateMachine::get_prev_state_machine() const { +AnimationNodeStateMachine *AnimationNodeStateMachine::get_prev_state_machine() const { return prev_state_machine; } @@ -862,10 +862,10 @@ int AnimationNodeStateMachine::find_transition(const StringName &p_from, const S return -1; } -bool AnimationNodeStateMachine::_can_connect(const StringName &p_name, Vector<Ref<AnimationNodeStateMachine>> p_parents) const { +bool AnimationNodeStateMachine::_can_connect(const StringName &p_name, Vector<AnimationNodeStateMachine *> p_parents) { if (p_parents.is_empty()) { - Ref<AnimationNodeStateMachine> prev = (Ref<AnimationNodeStateMachine>)this; - while (prev.is_valid()) { + AnimationNodeStateMachine *prev = this; + while (prev != nullptr) { p_parents.push_back(prev); prev = prev->prev_state_machine; } @@ -874,7 +874,7 @@ bool AnimationNodeStateMachine::_can_connect(const StringName &p_name, Vector<Re if (states.has(p_name)) { Ref<AnimationNodeStateMachine> anodesm = states[p_name].node; - if (anodesm.is_valid() && p_parents.find(anodesm) != -1) { + if (anodesm.is_valid() && p_parents.find(anodesm.ptr()) != -1) { return false; } @@ -889,7 +889,7 @@ bool AnimationNodeStateMachine::_can_connect(const StringName &p_name, Vector<Re } if (path[0] == "..") { - if (prev_state_machine.is_valid()) { + if (prev_state_machine != nullptr) { return prev_state_machine->_can_connect(name.replace_first("../", ""), p_parents); } } else if (states.has(path[0])) { diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h index 9eeac6a183..20f2d6f858 100644 --- a/scene/animation/animation_node_state_machine.h +++ b/scene/animation/animation_node_state_machine.h @@ -166,7 +166,7 @@ private: StringName playback = "playback"; StringName state_machine_name; - Ref<AnimationNodeStateMachine> prev_state_machine; + AnimationNodeStateMachine *prev_state_machine = nullptr; bool updating_transitions = false; Vector2 graph_offset; @@ -174,7 +174,7 @@ private: void _tree_changed(); void _remove_transition(const Ref<AnimationNodeStateMachineTransition> p_transition); void _rename_transition(const StringName &p_name, const StringName &p_new_name); - bool _can_connect(const StringName &p_name, const Vector<Ref<AnimationNodeStateMachine>> p_parents = Vector<Ref<AnimationNodeStateMachine>>()) const; + bool _can_connect(const StringName &p_name, Vector<AnimationNodeStateMachine *> p_parents = Vector<AnimationNodeStateMachine *>()); StringName _get_shortest_path(const StringName &p_path) const; protected: @@ -221,7 +221,7 @@ public: bool can_edit_node(const StringName &p_name) const; - Ref<AnimationNodeStateMachine> get_prev_state_machine() const; + AnimationNodeStateMachine *get_prev_state_machine() const; void set_graph_offset(const Vector2 &p_offset); Vector2 get_graph_offset() const; diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 5d471c9e84..2afe9ac35f 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -283,6 +283,9 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov setup_pass++; for (int i = 0; i < a->get_track_count(); i++) { + if (!a->track_is_enabled(i)) { + continue; + } p_anim->node_cache.write[i] = nullptr; Ref<Resource> resource; Vector<StringName> leftover_path; @@ -1991,8 +1994,8 @@ Ref<AnimatedValuesBackup> AnimationPlayer::apply_reset(bool p_user_initiated) { Ref<AnimationLibrary> al; al.instantiate(); al->add_animation(SceneStringNames::get_singleton()->RESET, reset_anim); - aux_player->add_animation_library("default", al); - aux_player->set_assigned_animation("default/" + SceneStringNames::get_singleton()->RESET); + aux_player->add_animation_library("", al); + aux_player->set_assigned_animation(SceneStringNames::get_singleton()->RESET); // Forcing the use of the original root because the scene where original player belongs may be not the active one Node *root = get_node(get_root()); Ref<AnimatedValuesBackup> old_values = aux_player->backup_animated_values(root); diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 136285c4dc..bcd49d75fa 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -276,7 +276,7 @@ double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Stri String new_path; AnimationNode *new_parent; - //this is the slowest part of processing, but as strings process in powers of 2, and the paths always exist, it will not result in that many allocations + // This is the slowest part of processing, but as strings process in powers of 2, and the paths always exist, it will not result in that many allocations. if (p_new_parent) { new_parent = p_new_parent; new_path = String(base_path) + String(p_subpath) + "/"; @@ -286,6 +286,9 @@ double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Stri new_path = String(parent->base_path) + String(p_subpath) + "/"; } + // If tracks for blending don't exist for one of the animations, Rest or RESET animation is blended as init animation instead. + // Then, blend weight is 0 means that the init animation blend weight is 1. + // Therefore, the blending process must be executed even if the blend weight is 0. if (!p_seek && p_optimize && !any_valid) { return p_node->_pre_process(new_path, new_parent, state, 0, p_seek, p_seek_root, p_connections); } @@ -965,6 +968,10 @@ void AnimationTree::_process_graph(double p_delta) { #endif // _3D_DISABLED for (int i = 0; i < a->get_track_count(); i++) { + if (!a->track_is_enabled(i)) { + continue; + } + NodePath path = a->track_get_path(i); ERR_CONTINUE(!track_cache.has(path)); @@ -1323,12 +1330,21 @@ void AnimationTree::_process_graph(double p_delta) { if (blend < CMP_EPSILON) { continue; //nothing to blend } - List<int> indices; - a->value_track_get_key_indices(i, time, delta, &indices, pingponged); - for (int &F : indices) { - Variant value = a->track_get_key_value(i, F); + if (seeked) { + int idx = a->track_find_key(i, time); + if (idx < 0) { + continue; + } + Variant value = a->track_get_key_value(i, idx); t->object->set_indexed(t->subpath, value); + } else { + List<int> indices; + a->value_track_get_key_indices(i, time, delta, &indices, pingponged); + for (int &F : indices) { + Variant value = a->track_get_key_value(i, F); + t->object->set_indexed(t->subpath, value); + } } } @@ -1337,20 +1353,27 @@ void AnimationTree::_process_graph(double p_delta) { if (blend < CMP_EPSILON) { continue; //nothing to blend } - if (!seeked && Math::is_zero_approx(delta)) { - continue; - } TrackCacheMethod *t = static_cast<TrackCacheMethod *>(track); - List<int> indices; - - a->method_track_get_key_indices(i, time, delta, &indices, pingponged); - - for (int &F : indices) { - StringName method = a->method_track_get_name(i, F); - Vector<Variant> params = a->method_track_get_params(i, F); + if (seeked) { + int idx = a->track_find_key(i, time); + if (idx < 0) { + continue; + } + StringName method = a->method_track_get_name(i, idx); + Vector<Variant> params = a->method_track_get_params(i, idx); if (can_call) { - _call_object(t->object, method, params, true); + _call_object(t->object, method, params, false); + } + } else { + List<int> indices; + a->method_track_get_key_indices(i, time, delta, &indices, pingponged); + for (int &F : indices) { + StringName method = a->method_track_get_name(i, F); + Vector<Variant> params = a->method_track_get_params(i, F); + if (can_call) { + _call_object(t->object, method, params, true); + } } } } break; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index b5caec3fc3..a30eb036db 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -420,6 +420,9 @@ void Node::move_child_notify(Node *p_child) { // to be used when not wanted } +void Node::owner_changed_notify() { +} + void Node::set_physics_process(bool p_process) { if (data.physics_process == p_process) { return; @@ -1544,6 +1547,8 @@ void Node::_set_owner_nocheck(Node *p_owner) { data.owner = p_owner; data.owner->data.owned.push_back(this); data.OW = data.owner->data.owned.back(); + + owner_changed_notify(); } void Node::_release_unique_name_in_owner() { diff --git a/scene/main/node.h b/scene/main/node.h index 8de6c1ce69..5b7bc0a587 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -208,6 +208,7 @@ protected: virtual void add_child_notify(Node *p_child); virtual void remove_child_notify(Node *p_child); virtual void move_child_notify(Node *p_child); + virtual void owner_changed_notify(); void _propagate_replace_owner(Node *p_owner, Node *p_by_owner); diff --git a/scene/resources/importer_mesh.cpp b/scene/resources/importer_mesh.cpp index 71640357b9..293fdd6f05 100644 --- a/scene/resources/importer_mesh.cpp +++ b/scene/resources/importer_mesh.cpp @@ -331,6 +331,7 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli bool is_uvs_close = (!uvs_ptr || uvs_ptr[j].distance_squared_to(uvs_ptr[idx.second]) < CMP_EPSILON2); bool is_uv2s_close = (!uv2s_ptr || uv2s_ptr[j].distance_squared_to(uv2s_ptr[idx.second]) < CMP_EPSILON2); + ERR_FAIL_INDEX(idx.second, normals.size()); bool is_normals_close = normals[idx.second].dot(n) > normal_merge_threshold; if (is_uvs_close && is_uv2s_close && is_normals_close) { vertex_remap.push_back(idx.first); @@ -1046,6 +1047,10 @@ Error ImporterMesh::lightmap_unwrap_cached(const Transform3D &p_base_transform, PackedVector3Array rnormals = arrays[Mesh::ARRAY_NORMAL]; + if (!rnormals.size()) { + continue; + } + int vertex_ofs = vertices.size() / 3; vertices.resize((vertex_ofs + vc) * 3); @@ -1086,6 +1091,9 @@ Error ImporterMesh::lightmap_unwrap_cached(const Transform3D &p_base_transform, } else { for (int j = 0; j < ic / 3; j++) { + ERR_FAIL_INDEX_V(rindices[j * 3 + 0], rvertices.size(), ERR_INVALID_DATA); + ERR_FAIL_INDEX_V(rindices[j * 3 + 1], rvertices.size(), ERR_INVALID_DATA); + ERR_FAIL_INDEX_V(rindices[j * 3 + 2], rvertices.size(), ERR_INVALID_DATA); Vector3 p0 = transform.xform(rvertices[rindices[j * 3 + 0]]); Vector3 p1 = transform.xform(rvertices[rindices[j * 3 + 1]]); Vector3 p2 = transform.xform(rvertices[rindices[j * 3 + 2]]); diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index b8c83ac89e..3e7b0a2808 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -188,7 +188,10 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { Vector<Vector3> faces; faces.resize(faces_size); + Vector<int32_t> surface_indices; + surface_indices.resize(faces_size / 3); Vector3 *facesw = faces.ptrw(); + int32_t *surface_indicesw = surface_indices.ptrw(); int widx = 0; @@ -210,6 +213,8 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { Vector<Vector3> vertices = a[ARRAY_VERTEX]; const Vector3 *vr = vertices.ptr(); + int32_t from_index = widx / 3; + if (surface_get_format(i) & ARRAY_FORMAT_INDEX) { int ic = surface_get_array_index_len(i); Vector<int> indices = a[ARRAY_INDEX]; @@ -241,6 +246,12 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { } } } + + int32_t to_index = widx / 3; + + for (int j = from_index; j < to_index; j++) { + surface_indicesw[j] = i; + } } triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); |