Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/scene/main/scene_tree_fti.h
9903 views
1
/**************************************************************************/
2
/* scene_tree_fti.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "core/os/mutex.h"
34
#include "core/templates/local_vector.h"
35
36
class Node3D;
37
class Node;
38
struct Transform3D;
39
class SceneTreeFTITests;
40
41
#ifdef DEV_ENABLED
42
// Uncomment this to verify traversal method results.
43
// #define GODOT_SCENE_TREE_FTI_VERIFY
44
#endif
45
46
#ifdef _3D_DISABLED
47
// Stubs
48
class SceneTreeFTI {
49
public:
50
void frame_update(Node *p_root, bool p_frame_start) {}
51
void tick_update() {}
52
void set_enabled(Node *p_root, bool p_enabled) {}
53
bool is_enabled() const { return false; }
54
55
void node_3d_notify_changed(Node3D &r_node, bool p_transform_changed) {}
56
void node_3d_notify_delete(Node3D *p_node) {}
57
void node_3d_request_reset(Node3D *p_node) {}
58
};
59
#else
60
61
// Important.
62
// This class uses raw pointers, so it is essential that on deletion, this class is notified
63
// so that any references can be cleared up to prevent dangling pointer access.
64
65
// This class can be used from a custom SceneTree.
66
67
// Note we could potentially make SceneTreeFTI static / global to avoid the lookup through scene tree,
68
// but this covers the custom case of multiple scene trees.
69
70
class SceneTreeFTI {
71
friend class SceneTreeFTITests;
72
73
enum TraversalMode : unsigned {
74
TM_DEFAULT,
75
TM_LEGACY,
76
TM_DEBUG,
77
};
78
79
struct Data {
80
static const uint32_t scene_tree_depth_limit = 32;
81
82
// Prev / Curr lists of Node3Ds having local xforms pumped.
83
LocalVector<Node3D *> tick_xform_list[2];
84
85
// The frame lists are changed nodes that need to start traversal,
86
// either longterm (on the tick list) or single frame forced.
87
LocalVector<Node3D *> frame_xform_list;
88
LocalVector<Node3D *> frame_xform_list_forced;
89
90
// Prev / Curr lists of Node3Ds having actively interpolated properties.
91
LocalVector<Node3D *> tick_property_list[2];
92
93
LocalVector<Node3D *> frame_property_list;
94
LocalVector<Node3D *> request_reset_list;
95
LocalVector<Node3D *> dirty_node_depth_lists[scene_tree_depth_limit];
96
97
// When we are using two alternating lists,
98
// which one is current.
99
uint32_t mirror = 0;
100
101
// Global on / off switch for SceneTreeFTI.
102
bool enabled = false;
103
104
// Whether we are in physics ticks, or in a frame.
105
bool in_frame = false;
106
107
// Updating at the start of the frame, or the end on second pass.
108
bool frame_start = true;
109
110
Mutex mutex;
111
112
TraversalMode traversal_mode = TM_DEFAULT;
113
bool use_optimized_traversal_method = true;
114
115
// DEBUGGING
116
bool periodic_debug_log = false;
117
uint32_t debug_node_count = 0;
118
uint32_t debug_nodes_processed = 0;
119
120
} data;
121
122
#ifdef GODOT_SCENE_TREE_FTI_VERIFY
123
SceneTreeFTITests *_tests = nullptr;
124
#endif
125
126
void _update_dirty_nodes(Node *p_node, uint32_t p_current_half_frame, float p_interpolation_fraction, bool p_active, const Transform3D *p_parent_global_xform = nullptr, int p_depth = 0);
127
void _update_request_resets();
128
129
void _reset_flags(Node *p_node);
130
void _reset_node3d_flags(Node3D &r_node);
131
void _node_3d_notify_set_xform(Node3D &r_node);
132
void _node_3d_notify_set_property(Node3D &r_node);
133
134
void _node_add_to_frame_list(Node3D &r_node, bool p_forced);
135
void _node_remove_from_frame_list(Node3D &r_node, bool p_forced);
136
137
void _create_depth_lists();
138
void _clear_depth_lists();
139
140
public:
141
// Hottest function, allow inlining the data.enabled check.
142
void node_3d_notify_changed(Node3D &r_node, bool p_transform_changed) {
143
if (!data.enabled) {
144
return;
145
}
146
MutexLock(data.mutex);
147
148
if (p_transform_changed) {
149
_node_3d_notify_set_xform(r_node);
150
} else {
151
_node_3d_notify_set_property(r_node);
152
}
153
}
154
155
void node_3d_request_reset(Node3D *p_node);
156
void node_3d_notify_delete(Node3D *p_node);
157
158
// Calculate interpolated xforms, send to visual server.
159
void frame_update(Node *p_root, bool p_frame_start);
160
161
// Update local xform pumps.
162
void tick_update();
163
164
void set_enabled(Node *p_root, bool p_enabled);
165
bool is_enabled() const { return data.enabled; }
166
167
void set_debug_next_frame() { data.periodic_debug_log = true; }
168
169
SceneTreeFTI();
170
~SceneTreeFTI();
171
};
172
173
#endif // ndef _3D_DISABLED
174
175