summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/light_2d.cpp5
-rw-r--r--scene/2d/light_2d.h2
-rw-r--r--scene/3d/light_3d.cpp5
-rw-r--r--scene/3d/light_3d.h2
-rw-r--r--scene/animation/animation_node_state_machine.cpp22
-rw-r--r--scene/animation/animation_node_state_machine.h6
-rw-r--r--scene/animation/animation_player.cpp7
-rw-r--r--scene/animation/animation_tree.cpp55
-rw-r--r--scene/main/node.cpp5
-rw-r--r--scene/main/node.h1
-rw-r--r--scene/resources/importer_mesh.cpp8
-rw-r--r--scene/resources/mesh.cpp11
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));