You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-09 12:50:35 +00:00
Merge pull request #45583 from lawnjelly/optimize_transform_propagate
Optimize transform propagation for hidden 3d objects
This commit is contained in:
@@ -246,10 +246,7 @@ void Spatial::set_transform(const Transform &p_transform) {
|
|||||||
|
|
||||||
void Spatial::set_global_transform(const Transform &p_transform) {
|
void Spatial::set_global_transform(const Transform &p_transform) {
|
||||||
|
|
||||||
Transform xform =
|
Transform xform = (data.parent && !data.toplevel_active) ? data.parent->get_global_transform().affine_inverse() * p_transform : p_transform;
|
||||||
(data.parent && !data.toplevel_active) ?
|
|
||||||
data.parent->get_global_transform().affine_inverse() * p_transform :
|
|
||||||
p_transform;
|
|
||||||
|
|
||||||
set_transform(xform);
|
set_transform(xform);
|
||||||
}
|
}
|
||||||
@@ -541,8 +538,9 @@ void Spatial::show() {
|
|||||||
|
|
||||||
data.visible = true;
|
data.visible = true;
|
||||||
|
|
||||||
if (!is_inside_tree())
|
if (!is_inside_tree()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_propagate_visibility_changed();
|
_propagate_visibility_changed();
|
||||||
}
|
}
|
||||||
@@ -554,8 +552,9 @@ void Spatial::hide() {
|
|||||||
|
|
||||||
data.visible = false;
|
data.visible = false;
|
||||||
|
|
||||||
if (!is_inside_tree())
|
if (!is_inside_tree()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_propagate_visibility_changed();
|
_propagate_visibility_changed();
|
||||||
}
|
}
|
||||||
@@ -834,6 +833,8 @@ Spatial::Spatial() :
|
|||||||
data.visible = true;
|
data.visible = true;
|
||||||
data.disable_scale = false;
|
data.disable_scale = false;
|
||||||
|
|
||||||
|
data.spatial_flags = SPATIAL_FLAG_VI_VISIBLE;
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
data.gizmo_disabled = false;
|
data.gizmo_disabled = false;
|
||||||
data.gizmo_dirty = false;
|
data.gizmo_dirty = false;
|
||||||
|
|||||||
@@ -54,6 +54,15 @@ class Spatial : public Node {
|
|||||||
GDCLASS(Spatial, Node);
|
GDCLASS(Spatial, Node);
|
||||||
OBJ_CATEGORY("3D");
|
OBJ_CATEGORY("3D");
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum SpatialFlags {
|
||||||
|
// this is cached, and only currently kept up to date in visual instances
|
||||||
|
// this is set if a visual instance is
|
||||||
|
// (a) in the tree AND (b) visible via is_visible_in_tree() call
|
||||||
|
SPATIAL_FLAG_VI_VISIBLE = 1 << 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
enum TransformDirty {
|
enum TransformDirty {
|
||||||
DIRTY_NONE = 0,
|
DIRTY_NONE = 0,
|
||||||
DIRTY_VECTORS = 1,
|
DIRTY_VECTORS = 1,
|
||||||
@@ -65,6 +74,9 @@ class Spatial : public Node {
|
|||||||
|
|
||||||
struct Data {
|
struct Data {
|
||||||
|
|
||||||
|
// defined in Spatial::SpatialFlags
|
||||||
|
uint32_t spatial_flags;
|
||||||
|
|
||||||
mutable Transform global_transform;
|
mutable Transform global_transform;
|
||||||
mutable Transform local_transform;
|
mutable Transform local_transform;
|
||||||
mutable Vector3 rotation;
|
mutable Vector3 rotation;
|
||||||
@@ -109,6 +121,16 @@ protected:
|
|||||||
|
|
||||||
_FORCE_INLINE_ void _update_local_transform() const;
|
_FORCE_INLINE_ void _update_local_transform() const;
|
||||||
|
|
||||||
|
uint32_t _get_spatial_flags() const { return data.spatial_flags; }
|
||||||
|
void _replace_spatial_flags(uint32_t p_flags) { data.spatial_flags = p_flags; }
|
||||||
|
void _set_spatial_flag(uint32_t p_flag, bool p_set) {
|
||||||
|
if (p_set) {
|
||||||
|
data.spatial_flags |= p_flag;
|
||||||
|
} else {
|
||||||
|
data.spatial_flags &= ~p_flag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
|
|||||||
@@ -41,11 +41,26 @@ AABB VisualInstance::get_transformed_aabb() const {
|
|||||||
|
|
||||||
void VisualInstance::_update_visibility() {
|
void VisualInstance::_update_visibility() {
|
||||||
|
|
||||||
if (!is_inside_tree())
|
if (!is_inside_tree()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool visible = is_visible_in_tree();
|
||||||
|
|
||||||
|
// keep a quick flag available in each node.
|
||||||
|
// no need to call is_visible_in_tree all over the place,
|
||||||
|
// providing it is propagated with a notification.
|
||||||
|
bool already_visible = (_get_spatial_flags() & SPATIAL_FLAG_VI_VISIBLE) != 0;
|
||||||
|
_set_spatial_flag(SPATIAL_FLAG_VI_VISIBLE, visible);
|
||||||
|
|
||||||
|
// if making visible, make sure the visual server is up to date with the transform
|
||||||
|
if (visible && (!already_visible)) {
|
||||||
|
Transform gt = get_global_transform();
|
||||||
|
VisualServer::get_singleton()->instance_set_transform(instance, gt);
|
||||||
|
}
|
||||||
|
|
||||||
_change_notify("visible");
|
_change_notify("visible");
|
||||||
VS::get_singleton()->instance_set_visible(get_instance(), is_visible_in_tree());
|
VS::get_singleton()->instance_set_visible(get_instance(), visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualInstance::_notification(int p_what) {
|
void VisualInstance::_notification(int p_what) {
|
||||||
@@ -67,8 +82,10 @@ void VisualInstance::_notification(int p_what) {
|
|||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||||
|
|
||||||
|
if (_get_spatial_flags() & SPATIAL_FLAG_VI_VISIBLE) {
|
||||||
Transform gt = get_global_transform();
|
Transform gt = get_global_transform();
|
||||||
VisualServer::get_singleton()->instance_set_transform(instance, gt);
|
VisualServer::get_singleton()->instance_set_transform(instance, gt);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_EXIT_WORLD: {
|
case NOTIFICATION_EXIT_WORLD: {
|
||||||
|
|
||||||
@@ -76,6 +93,10 @@ void VisualInstance::_notification(int p_what) {
|
|||||||
VisualServer::get_singleton()->instance_attach_skeleton(instance, RID());
|
VisualServer::get_singleton()->instance_attach_skeleton(instance, RID());
|
||||||
//VS::get_singleton()->instance_geometry_set_baked_light_sampler(instance, RID() );
|
//VS::get_singleton()->instance_geometry_set_baked_light_sampler(instance, RID() );
|
||||||
|
|
||||||
|
// the vi visible flag is always set to invisible when outside the tree,
|
||||||
|
// so it can detect re-entering the tree and becoming visible, and send
|
||||||
|
// the transform to the visual server
|
||||||
|
_set_spatial_flag(SPATIAL_FLAG_VI_VISIBLE, false);
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_VISIBILITY_CHANGED: {
|
case NOTIFICATION_VISIBILITY_CHANGED: {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user