Merge pull request #45583 from lawnjelly/optimize_transform_propagate
Optimize transform propagation for hidden 3d objects
This commit is contained in:
commit
f05e068d6c
3 changed files with 54 additions and 10 deletions
|
@ -246,10 +246,7 @@ void Spatial::set_transform(const Transform &p_transform) {
|
|||
|
||||
void Spatial::set_global_transform(const Transform &p_transform) {
|
||||
|
||||
Transform xform =
|
||||
(data.parent && !data.toplevel_active) ?
|
||||
data.parent->get_global_transform().affine_inverse() * p_transform :
|
||||
p_transform;
|
||||
Transform xform = (data.parent && !data.toplevel_active) ? data.parent->get_global_transform().affine_inverse() * p_transform : p_transform;
|
||||
|
||||
set_transform(xform);
|
||||
}
|
||||
|
@ -541,8 +538,9 @@ void Spatial::show() {
|
|||
|
||||
data.visible = true;
|
||||
|
||||
if (!is_inside_tree())
|
||||
if (!is_inside_tree()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_propagate_visibility_changed();
|
||||
}
|
||||
|
@ -554,8 +552,9 @@ void Spatial::hide() {
|
|||
|
||||
data.visible = false;
|
||||
|
||||
if (!is_inside_tree())
|
||||
if (!is_inside_tree()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_propagate_visibility_changed();
|
||||
}
|
||||
|
@ -834,6 +833,8 @@ Spatial::Spatial() :
|
|||
data.visible = true;
|
||||
data.disable_scale = false;
|
||||
|
||||
data.spatial_flags = SPATIAL_FLAG_VI_VISIBLE;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
data.gizmo_disabled = false;
|
||||
data.gizmo_dirty = false;
|
||||
|
|
|
@ -54,6 +54,15 @@ class Spatial : public Node {
|
|||
GDCLASS(Spatial, Node);
|
||||
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 {
|
||||
DIRTY_NONE = 0,
|
||||
DIRTY_VECTORS = 1,
|
||||
|
@ -65,6 +74,9 @@ class Spatial : public Node {
|
|||
|
||||
struct Data {
|
||||
|
||||
// defined in Spatial::SpatialFlags
|
||||
uint32_t spatial_flags;
|
||||
|
||||
mutable Transform global_transform;
|
||||
mutable Transform local_transform;
|
||||
mutable Vector3 rotation;
|
||||
|
@ -109,6 +121,16 @@ protected:
|
|||
|
||||
_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);
|
||||
static void _bind_methods();
|
||||
|
||||
|
|
|
@ -41,11 +41,26 @@ AABB VisualInstance::get_transformed_aabb() const {
|
|||
|
||||
void VisualInstance::_update_visibility() {
|
||||
|
||||
if (!is_inside_tree())
|
||||
if (!is_inside_tree()) {
|
||||
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");
|
||||
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) {
|
||||
|
@ -67,8 +82,10 @@ void VisualInstance::_notification(int p_what) {
|
|||
} break;
|
||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||
|
||||
Transform gt = get_global_transform();
|
||||
VisualServer::get_singleton()->instance_set_transform(instance, gt);
|
||||
if (_get_spatial_flags() & SPATIAL_FLAG_VI_VISIBLE) {
|
||||
Transform gt = get_global_transform();
|
||||
VisualServer::get_singleton()->instance_set_transform(instance, gt);
|
||||
}
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_WORLD: {
|
||||
|
||||
|
@ -76,6 +93,10 @@ void VisualInstance::_notification(int p_what) {
|
|||
VisualServer::get_singleton()->instance_attach_skeleton(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;
|
||||
case NOTIFICATION_VISIBILITY_CHANGED: {
|
||||
|
||||
|
|
Loading…
Reference in a new issue