Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions scene/main/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1951,6 +1951,28 @@ Node *Node::get_child(int p_index, bool p_include_internal) const {
}
}

void Node::get_children_fast(LocalVector<Node *> &r_children, bool p_include_internal) const {
r_children.clear();
ERR_THREAD_GUARD
_update_children_cache();

if (p_include_internal) {
uint32_t num_children = data.children_cache.size();
r_children.resize(num_children);
for (uint32_t n = 0; n < num_children; n++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe worth tring a memcpy here, it would have a very good chance of using SIMD for the copy.

r_children[n] = data.children_cache[n];
}
} else {
uint32_t num_children = data.children_cache.size() - data.internal_children_front_count_cache - data.internal_children_back_count_cache;
r_children.resize(num_children);
uint32_t internal_count = data.internal_children_front_count_cache;

for (uint32_t n = 0; n < num_children; n++) {
r_children[n] = data.children_cache[n + internal_count];
}
}
}

TypedArray<Node> Node::get_children(bool p_include_internal) const {
ERR_THREAD_GUARD_V(TypedArray<Node>());
TypedArray<Node> arr;
Expand Down
1 change: 1 addition & 0 deletions scene/main/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ class Node : public Object {
int get_child_count(bool p_include_internal = true) const;
Node *get_child(int p_index, bool p_include_internal = true) const;
TypedArray<Node> get_children(bool p_include_internal = true) const;
void get_children_fast(LocalVector<Node *> &r_children, bool p_include_internal = true) const;
bool has_node(const NodePath &p_path) const;
Node *get_node(const NodePath &p_path) const;
Node *get_node_or_null(const NodePath &p_path) const;
Expand Down
13 changes: 9 additions & 4 deletions scene/main/scene_tree_fti.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,12 +318,17 @@ void SceneTreeFTI::_update_dirty_nodes(Node *p_node, uint32_t p_current_frame, f
return;
}

// Godot 4.x is very inefficient at getting children
// via get_child_count() and get_child(), so we use
// a fast version.
p_node->get_children_fast(data.temp_child_list);

// Not a Node3D.
// Could be e.g. a viewport or something
// so we should still recurse to children.
if (!s) {
for (int n = 0; n < p_node->get_child_count(); n++) {
_update_dirty_nodes(p_node->get_child(n), p_current_frame, p_interpolation_fraction, p_active, nullptr, p_depth + 1);
for (uint32_t n = 0; n < data.temp_child_list.size(); n++) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be changed to range loop.

_update_dirty_nodes(data.temp_child_list[n], p_current_frame, p_interpolation_fraction, p_active, nullptr, p_depth + 1);
}
return;
}
Expand Down Expand Up @@ -424,8 +429,8 @@ void SceneTreeFTI::_update_dirty_nodes(Node *p_node, uint32_t p_current_frame, f
s->_clear_dirty_bits(Node3D::DIRTY_GLOBAL_INTERPOLATED_TRANSFORM);

// Recurse to children.
for (int n = 0; n < p_node->get_child_count(); n++) {
_update_dirty_nodes(p_node->get_child(n), p_current_frame, p_interpolation_fraction, p_active, s->data.fti_global_xform_interp_set ? &s->data.global_transform_interpolated : &s->data.global_transform, p_depth + 1);
for (uint32_t n = 0; n < data.temp_child_list.size(); n++) {
_update_dirty_nodes(data.temp_child_list[n], p_current_frame, p_interpolation_fraction, p_active, s->data.fti_global_xform_interp_set ? &s->data.global_transform_interpolated : &s->data.global_transform, p_depth + 1);
}
}

Expand Down
2 changes: 2 additions & 0 deletions scene/main/scene_tree_fti.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ class SceneTreeFTI {
Mutex mutex;

bool debug = false;

LocalVector<Node *> temp_child_list;
} data;

void _update_dirty_nodes(Node *p_node, uint32_t p_current_frame, float p_interpolation_fraction, bool p_active, const Transform3D *p_parent_global_xform = nullptr, int p_depth = 0);
Expand Down