Skip to content

Commit 6784e2d

Browse files
committed
OpenXR: Adding support for the render model extension
1 parent a26e559 commit 6784e2d

19 files changed

+1849
-1
lines changed

doc/classes/ProjectSettings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3443,6 +3443,10 @@
34433443
If [code]true[/code], support for the unobstructed data source is requested. If supported, you will receive hand tracking data based on the actual finger positions of the user often determined by optical tracking.
34443444
[b]Note:[/b] This requires the OpenXR data source extension and unobstructed handtracking to be supported by the XR runtime. If not supported this setting will be ignored. [member xr/openxr/extensions/hand_tracking] must be enabled for this setting to be used.
34453445
</member>
3446+
<member name="xr/openxr/extensions/render_model" type="bool" setter="" getter="" default="false">
3447+
If true we enable the render model extension if available.
3448+
[b]Note:[/b] This relates to the core OpenXR render model extension and has no relation to any vendor render model extensions.
3449+
</member>
34463450
<member name="xr/openxr/form_factor" type="int" setter="" getter="" default="&quot;0&quot;">
34473451
Specify whether OpenXR should be configured for an HMD or a hand held device.
34483452
</member>

main/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2773,6 +2773,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
27732773
GLOBAL_DEF_BASIC("xr/openxr/extensions/hand_tracking_controller_data_source", false); // XR_HAND_TRACKING_DATA_SOURCE_CONTROLLER_EXT
27742774
GLOBAL_DEF_RST_BASIC("xr/openxr/extensions/hand_interaction_profile", false);
27752775
GLOBAL_DEF_RST_BASIC("xr/openxr/extensions/eye_gaze_interaction", false);
2776+
GLOBAL_DEF_BASIC("xr/openxr/extensions/render_model", false);
27762777

27772778
// OpenXR Binding modifier settings
27782779
GLOBAL_DEF_BASIC("xr/openxr/binding_modifiers/analog_threshold", false);

modules/openxr/config.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ def get_doc_classes():
4040
"OpenXRBindingModifierEditor",
4141
"OpenXRHapticBase",
4242
"OpenXRHapticVibration",
43+
"OpenXRRenderModelExtension",
44+
"OpenXRRenderModel",
45+
"OpenXRRenderModels",
4346
]
4447

4548

modules/openxr/doc_classes/OpenXRExtensionWrapper.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@
185185
Called when the OpenXR session state is changed to visible. This means OpenXR is now ready to receive frames.
186186
</description>
187187
</method>
188+
<method name="_on_sync_actions" qualifiers="virtual">
189+
<return type="void" />
190+
<description>
191+
Called when OpenXR has performed its action sync.
192+
</description>
193+
</method>
188194
<method name="_on_viewport_composition_layer_destroyed" qualifiers="virtual">
189195
<return type="void" />
190196
<param index="0" name="layer" type="const void*" />
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<class name="OpenXRRenderModel" inherits="Node3D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
3+
<brief_description>
4+
This node will display an OpenXR render model.
5+
</brief_description>
6+
<description>
7+
This node will display an OpenXR render model by accessing the associated GLTF and processes all animation data (if supported by the XR runtime).
8+
In OpenXR we are not provided with enough information about the hardware used by the user. While it can be somewhat inferred by the bound action map profile, this is a dangerous approach as the user may be using hardware not known to you at time of development and OpenXR will simply simulate an available interaction profile.
9+
Render models were introduced to allow you to show the correct model for the controller (or other device) the user has in hand.
10+
</description>
11+
<tutorials>
12+
</tutorials>
13+
<methods>
14+
<method name="get_toplevel_path" qualifiers="const">
15+
<return type="String" />
16+
<description>
17+
Returns the top level path related to this render model.
18+
</description>
19+
</method>
20+
</methods>
21+
<members>
22+
<member name="render_model" type="RID" setter="set_render_model" getter="get_render_model" default="RID()">
23+
The render model rid for the render model to load, as returned by [method OpenXRRenderModelExtension.render_model_create] or [method OpenXRRenderModelExtension.render_model_get_all].
24+
</member>
25+
</members>
26+
<signals>
27+
<signal name="render_model_toplevel_path_changed">
28+
<description>
29+
Informs that the top level path of this render model has changed.
30+
</description>
31+
</signal>
32+
</signals>
33+
</class>
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<class name="OpenXRRenderModelExtension" inherits="OpenXRExtensionWrapper" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
3+
<brief_description>
4+
</brief_description>
5+
<description>
6+
</description>
7+
<tutorials>
8+
</tutorials>
9+
<methods>
10+
<method name="is_active" qualifiers="const">
11+
<return type="bool" />
12+
<description>
13+
Returns [code]true[/code] if OpenXR's render model extension is supported and enabled.
14+
[b]Note:[/b] This only returns a valid value after OpenXR has been initialized.
15+
</description>
16+
</method>
17+
<method name="render_model_create">
18+
<return type="RID" />
19+
<param index="0" name="render_model_id" type="int" />
20+
<description>
21+
Creates a render model object within OpenXR using a render model id.
22+
[b]Note:[/b] This function is exposed for dependent OpenXR extensions that provide render model ids to be used with the render model extension.
23+
</description>
24+
</method>
25+
<method name="render_model_destroy">
26+
<return type="void" />
27+
<param index="0" name="render_model" type="RID" />
28+
<description>
29+
Destroys a render model object within OpenXR that was previously created with [method render_model_create].
30+
[b]Note:[/b] This function is exposed for dependent OpenXR extensions that provide render model ids to be used with the render model extension.
31+
</description>
32+
</method>
33+
<method name="render_model_get_all">
34+
<return type="RID[]" />
35+
<description>
36+
Returns an array of all currently active render models registered with this extension.
37+
</description>
38+
</method>
39+
<method name="render_model_get_animatable_node_count" qualifiers="const">
40+
<return type="int" />
41+
<param index="0" name="render_model" type="RID" />
42+
<description>
43+
Returns the number of animatable nodes this render model has.
44+
</description>
45+
</method>
46+
<method name="render_model_get_animatable_node_name" qualifiers="const">
47+
<return type="String" />
48+
<param index="0" name="render_model" type="RID" />
49+
<param index="1" name="index" type="int" />
50+
<description>
51+
Returns the name of the given animatable node.
52+
</description>
53+
</method>
54+
<method name="render_model_get_animatable_node_transform" qualifiers="const">
55+
<return type="Transform3D" />
56+
<param index="0" name="render_model" type="RID" />
57+
<param index="1" name="index" type="int" />
58+
<description>
59+
Returns the current local transform for an animatable node. This is updated every frame.
60+
</description>
61+
</method>
62+
<method name="render_model_get_confidence" qualifiers="const">
63+
<return type="int" enum="XRPose.TrackingConfidence" />
64+
<param index="0" name="render_model" type="RID" />
65+
<description>
66+
Returns the tracking confidence of the tracking data for the render model.
67+
</description>
68+
</method>
69+
<method name="render_model_get_root_transform" qualifiers="const">
70+
<return type="Transform3D" />
71+
<param index="0" name="render_model" type="RID" />
72+
<description>
73+
Returns the root transform of a render model. This is the tracked position relative to our [XROrigin3D] node.
74+
</description>
75+
</method>
76+
<method name="render_model_get_subaction_paths">
77+
<return type="PackedStringArray" />
78+
<param index="0" name="render_model" type="RID" />
79+
<description>
80+
Returns a list of active subaction paths for this [param render_model].
81+
[b]Note:[/b] if different devices are bound to your actions than available in suggested interaction bindings, this information shows path related to the interaction bindings being mimicked by that device.
82+
</description>
83+
</method>
84+
<method name="render_model_get_top_level_path" qualifiers="const">
85+
<return type="String" />
86+
<param index="0" name="render_model" type="RID" />
87+
<description>
88+
Returns the top level path associated with this [param render_model]. If provided this identifies whether the render model is associated with the players hands or other body part.
89+
</description>
90+
</method>
91+
<method name="render_model_is_animatable_node_visible" qualifiers="const">
92+
<return type="bool" />
93+
<param index="0" name="render_model" type="RID" />
94+
<param index="1" name="index" type="int" />
95+
<description>
96+
Returns [code]true[/code] if this animatable node should be visible.
97+
</description>
98+
</method>
99+
<method name="render_model_new_scene_instance" qualifiers="const">
100+
<return type="Node3D" />
101+
<param index="0" name="render_model" type="RID" />
102+
<description>
103+
Returns an instance of a subscene that contains all [MeshInstance3D] nodes that allow you to visualize the render model.
104+
</description>
105+
</method>
106+
</methods>
107+
<signals>
108+
<signal name="render_model_added">
109+
<param index="0" name="render_model" type="RID" />
110+
<description>
111+
Informs that a new render model was added.
112+
</description>
113+
</signal>
114+
<signal name="render_model_removed">
115+
<param index="0" name="render_model" type="RID" />
116+
<description>
117+
Informs that a render model was removed.
118+
</description>
119+
</signal>
120+
<signal name="render_model_toplevel_path_changed">
121+
<param index="0" name="render_model" type="RID" />
122+
<description>
123+
Informs that the top level path associated with a render model changed.
124+
</description>
125+
</signal>
126+
</signals>
127+
</class>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<class name="OpenXRRenderModels" inherits="Node3D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
3+
<brief_description>
4+
Helper node that will automatically manage displaying render models.
5+
</brief_description>
6+
<description>
7+
This helper node will automatically manage displaying render models. It will create new [OpenXRRenderModel] nodes as controllers and other hand held devices are detected, and remove those nodes when they are deactivated.
8+
[b]Note:[/b] If you want more control over this logic you can alternatively call [method OpenXRRenderModelExtension.render_model_get_all] to obtain a list of active render model IDs and create [OpenXRRenderModel] instances for each render model id provided.
9+
</description>
10+
<tutorials>
11+
</tutorials>
12+
<members>
13+
<member name="make_local_to_pose" type="String" setter="set_make_local_to_pose" getter="get_make_local_to_pose" default="&quot;&quot;">
14+
Position render models local to this pose (this will adjust the position of the render models container node).
15+
</member>
16+
<member name="tracker" type="int" setter="set_tracker" getter="get_tracker" default="0">
17+
Limits render models to the specified tracker. Include: 0 = All render models, 1 = Render models not related to a tracker, 2 = Render models related to the left hand tracker, 3 = Render models related to the right hand tracker.
18+
</member>
19+
</members>
20+
<signals>
21+
<signal name="render_model_added">
22+
<param index="0" name="render_model" type="OpenXRRenderModel" />
23+
<description>
24+
Informs that a render model node was added as a child to this node.
25+
</description>
26+
</signal>
27+
<signal name="render_model_removed">
28+
<param index="0" name="render_model" type="OpenXRRenderModel" />
29+
<description>
30+
Informs that a render model child node is about to be removed from this node.
31+
</description>
32+
</signal>
33+
</signals>
34+
</class>

modules/openxr/extensions/openxr_extension_wrapper.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ void OpenXRExtensionWrapper::_bind_methods() {
5555
GDVIRTUAL_BIND(_on_instance_destroyed);
5656
GDVIRTUAL_BIND(_on_session_created, "session");
5757
GDVIRTUAL_BIND(_on_process);
58+
GDVIRTUAL_BIND(_on_sync_actions);
5859
GDVIRTUAL_BIND(_on_pre_render);
5960
GDVIRTUAL_BIND(_on_main_swapchains_created);
6061
GDVIRTUAL_BIND(_on_pre_draw_viewport, "viewport");
@@ -252,6 +253,10 @@ void OpenXRExtensionWrapper::on_process() {
252253
GDVIRTUAL_CALL(_on_process);
253254
}
254255

256+
void OpenXRExtensionWrapper::on_sync_actions() {
257+
GDVIRTUAL_CALL(_on_sync_actions);
258+
}
259+
255260
void OpenXRExtensionWrapper::on_pre_render() {
256261
GDVIRTUAL_CALL(_on_pre_render);
257262
}

modules/openxr/extensions/openxr_extension_wrapper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ class OpenXRExtensionWrapper : public Object {
120120
// this happens right before physics process and normal processing is run.
121121
// This is when controller data is queried and made available to game logic.
122122
virtual void on_process();
123+
virtual void on_sync_actions(); // `on_sync_actions` is called right after we sync our action sets.
123124
virtual void on_pre_render(); // `on_pre_render` is called right before we start rendering our XR viewports.
124125
virtual void on_main_swapchains_created(); // `on_main_swapchains_created` is called right after our main swapchains are (re)created.
125126
virtual void on_pre_draw_viewport(RID p_render_target); // `on_pre_draw_viewport` is called right before we start rendering this viewport
@@ -131,6 +132,7 @@ class OpenXRExtensionWrapper : public Object {
131132
GDVIRTUAL0(_on_instance_destroyed);
132133
GDVIRTUAL1(_on_session_created, uint64_t);
133134
GDVIRTUAL0(_on_process);
135+
GDVIRTUAL0(_on_sync_actions);
134136
GDVIRTUAL0(_on_pre_render);
135137
GDVIRTUAL0(_on_main_swapchains_created);
136138
GDVIRTUAL0(_on_session_destroyed);

0 commit comments

Comments
 (0)