Skip to content

Commit 87fc625

Browse files
committed
Support composition layers anywhere in the tree
1 parent 63227bb commit 87fc625

File tree

3 files changed

+42
-12
lines changed

3 files changed

+42
-12
lines changed

modules/openxr/extensions/openxr_composition_layer_extension.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,16 @@ void OpenXRCompositionLayerExtension::CompositionLayer::set_alpha_blend(bool p_a
282282
}
283283

284284
void OpenXRCompositionLayerExtension::CompositionLayer::set_transform(const Transform3D &p_transform) {
285+
// Convert world transform into play/reference space.
285286
Transform3D reference_frame = XRServer::get_singleton()->get_reference_frame();
286287
Transform3D transform = reference_frame.inverse() * p_transform;
287288
Quaternion quat(transform.basis.orthonormalized());
288289

290+
// Prevent invalid quaternion
291+
if (Math::is_zero_approx(quat.length())) {
292+
quat = Quaternion(); // identity quaternion
293+
}
294+
289295
XrPosef pose = {
290296
{ (float)quat.x, (float)quat.y, (float)quat.z, (float)quat.w },
291297
{ (float)transform.origin.x, (float)transform.origin.y, (float)transform.origin.z }

modules/openxr/scene/openxr_composition_layer.cpp

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ OpenXRCompositionLayer::OpenXRCompositionLayer() {
6666
XRServer::get_singleton()->connect("reference_frame_changed", callable_mp(this, &OpenXRCompositionLayer::update_transform));
6767

6868
set_process_internal(true);
69-
set_notify_local_transform(true);
69+
set_notify_transform(true);
7070

7171
if (Engine::get_singleton()->is_editor_hint()) {
7272
// In the editor, create the fallback right away.
@@ -196,7 +196,7 @@ bool OpenXRCompositionLayer::_should_use_fallback_node() {
196196
if (Engine::get_singleton()->is_editor_hint() || openxr_api == nullptr) {
197197
return true;
198198
} else if (openxr_session_running) {
199-
return enable_hole_punch || (!is_natively_supported() && !use_android_surface);
199+
return enable_hole_punch || !is_natively_supported();
200200
}
201201
return false;
202202
}
@@ -245,7 +245,7 @@ void OpenXRCompositionLayer::_clear_composition_layer() {
245245
}
246246

247247
void OpenXRCompositionLayer::_viewport_size_changed() {
248-
if (layer_viewport && openxr_session_running && composition_layer_extension && is_natively_supported() && is_visible() && is_inside_tree()) {
248+
if (layer_viewport && openxr_session_running && composition_layer_extension && is_natively_supported() && is_visible_in_tree() && is_inside_tree()) {
249249
composition_layer_extension->composition_layer_set_viewport(composition_layer, layer_viewport->get_viewport_rid(), layer_viewport->get_size());
250250
}
251251
}
@@ -270,7 +270,13 @@ void OpenXRCompositionLayer::_on_openxr_session_stopping() {
270270

271271
void OpenXRCompositionLayer::update_transform() {
272272
if (composition_layer_extension) {
273-
composition_layer_extension->composition_layer_set_transform(composition_layer, get_transform());
273+
Transform3D xf;
274+
if (Object::cast_to<XROrigin3D>(get_parent()) != nullptr) {
275+
xf = get_transform();
276+
} else {
277+
xf = get_global_transform();
278+
}
279+
composition_layer_extension->composition_layer_set_transform(composition_layer, xf);
274280
}
275281
}
276282

@@ -279,7 +285,7 @@ void OpenXRCompositionLayer::update_fallback_mesh() {
279285
}
280286

281287
bool OpenXRCompositionLayer::_should_register() {
282-
return !registered && openxr_session_running && is_inside_tree() && is_visible() && is_natively_supported();
288+
return !registered && openxr_session_running && is_inside_tree() && is_visible_in_tree() && is_natively_supported();
283289
}
284290

285291
bool OpenXRCompositionLayer::is_viewport_in_use(SubViewport *p_viewport) {
@@ -325,7 +331,8 @@ void OpenXRCompositionLayer::set_layer_viewport(SubViewport *p_viewport) {
325331

326332
if (fallback) {
327333
_reset_fallback_material();
328-
} else if (openxr_session_running && composition_layer_extension && is_visible() && is_inside_tree()) {
334+
}
335+
if (openxr_session_running && composition_layer_extension && is_visible_in_tree() && is_inside_tree() && is_natively_supported()) {
329336
if (layer_viewport) {
330337
composition_layer_extension->composition_layer_set_viewport(composition_layer, layer_viewport->get_viewport_rid(), layer_viewport->get_size());
331338
} else {
@@ -676,22 +683,22 @@ void OpenXRCompositionLayer::_notification(int p_what) {
676683
} break;
677684
case NOTIFICATION_VISIBILITY_CHANGED: {
678685
if (is_natively_supported() && openxr_session_running && is_inside_tree()) {
679-
if (is_visible()) {
686+
if (is_visible_in_tree()) {
680687
_setup_composition_layer();
681688
} else {
682689
_clear_composition_layer();
683690
}
684691
}
685692
update_configuration_warnings();
686693
} break;
687-
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
694+
case NOTIFICATION_TRANSFORM_CHANGED: {
688695
update_transform();
689696
update_configuration_warnings();
690697
} break;
691698
case NOTIFICATION_ENTER_TREE: {
692699
if (layer_viewport && is_viewport_in_use(layer_viewport)) {
693700
_clear_composition_layer();
694-
} else if (openxr_session_running && is_visible()) {
701+
} else if (openxr_session_running && is_visible_in_tree()) {
695702
_setup_composition_layer();
696703
}
697704
} break;
@@ -756,13 +763,27 @@ void OpenXRCompositionLayer::_validate_property(PropertyInfo &p_property) const
756763
}
757764
}
758765

766+
XROrigin3D *OpenXRCompositionLayer::_get_xrorigin3d_ancestor() const {
767+
Node *parent = get_parent();
768+
while (parent != nullptr) {
769+
XROrigin3D *origin = Object::cast_to<XROrigin3D>(parent);
770+
if (origin != nullptr) {
771+
return origin;
772+
}
773+
774+
parent = parent->get_parent();
775+
}
776+
777+
return nullptr;
778+
}
779+
759780
PackedStringArray OpenXRCompositionLayer::get_configuration_warnings() const {
760781
PackedStringArray warnings = Node3D::get_configuration_warnings();
761782

762-
if (is_visible() && is_inside_tree()) {
763-
XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
783+
if (is_visible_in_tree() && is_inside_tree()) {
784+
XROrigin3D *origin = _get_xrorigin3d_ancestor();
764785
if (origin == nullptr) {
765-
warnings.push_back(RTR("OpenXR composition layers must have an XROrigin3D node as their parent."));
786+
warnings.push_back(RTR("OpenXR composition layers must have an XROrigin3D node as their ancestor."));
766787
}
767788
}
768789

modules/openxr/scene/openxr_composition_layer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class Mesh;
4040
class OpenXRAPI;
4141
class OpenXRCompositionLayerExtension;
4242
class SubViewport;
43+
class XROrigin3D;
4344

4445
class OpenXRCompositionLayer : public Node3D {
4546
GDCLASS(OpenXRCompositionLayer, Node3D);
@@ -117,6 +118,8 @@ class OpenXRCompositionLayer : public Node3D {
117118

118119
void _viewport_size_changed();
119120

121+
XROrigin3D *_get_xrorigin3d_ancestor() const;
122+
120123
protected:
121124
OpenXRAPI *openxr_api = nullptr;
122125
OpenXRCompositionLayerExtension *composition_layer_extension = nullptr;

0 commit comments

Comments
 (0)