mirror of
https://github.com/godotengine/godot
synced 2024-09-05 06:58:29 +00:00
Improve XRInterface hooks into rendering
This commit is contained in:
parent
b25c7fef04
commit
98e5cd24db
|
@ -9,46 +9,52 @@
|
|||
<tutorials>
|
||||
</tutorials>
|
||||
<methods>
|
||||
<method name="_commit_views" qualifiers="virtual">
|
||||
<method name="_end_frame" qualifiers="virtual">
|
||||
<return type="void" />
|
||||
<argument index="0" name="render_target" type="RID" />
|
||||
<argument index="1" name="screen_rect" type="Rect2" />
|
||||
<description>
|
||||
Called if interface is active and queues have been submitted.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_get_anchor_detection_is_enabled" qualifiers="virtual const">
|
||||
<return type="bool" />
|
||||
<description>
|
||||
Return [code]true[/code] if anchor detection is enabled for this interface.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_get_camera_feed_id" qualifiers="virtual const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the camera feed id for the [CameraFeed] registered with the [CameraServer] that should be presented as the background on an AR capable device (if applicable).
|
||||
</description>
|
||||
</method>
|
||||
<method name="_get_camera_transform" qualifiers="virtual">
|
||||
<return type="Transform3D" />
|
||||
<description>
|
||||
Returns the [Transform3D] that positions the [XRCamera3D] in the world.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_get_capabilities" qualifiers="virtual const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the capabilities of this interface.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_get_name" qualifiers="virtual const">
|
||||
<return type="StringName" />
|
||||
<description>
|
||||
Returns the name of this interface.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_get_play_area" qualifiers="virtual const">
|
||||
<return type="PackedVector3Array" />
|
||||
<description>
|
||||
Returns an [PackedVector3Array] that denotes the play areas boundaries (if applicable).
|
||||
</description>
|
||||
</method>
|
||||
<method name="_get_play_area_mode" qualifiers="virtual const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the [enum XRInterface.PlayAreaMode] that sets up our play area.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_get_projection_for_view" qualifiers="virtual">
|
||||
|
@ -58,27 +64,32 @@
|
|||
<argument index="2" name="z_near" type="float" />
|
||||
<argument index="3" name="z_far" type="float" />
|
||||
<description>
|
||||
Returns the projection matrix for the given view as a [PackedFloat64Array].
|
||||
</description>
|
||||
</method>
|
||||
<method name="_get_render_target_size" qualifiers="virtual">
|
||||
<return type="Vector2" />
|
||||
<description>
|
||||
Returns the size of our render target for this interface, this overrides the size of the [Viewport] marked as the xr viewport.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_get_suggested_pose_names" qualifiers="virtual const">
|
||||
<return type="PackedStringArray" />
|
||||
<argument index="0" name="tracker_name" type="StringName" />
|
||||
<description>
|
||||
Returns a [PackedStringArray] with pose names configured by this interface. Note that user configuration can override this list.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_get_suggested_tracker_names" qualifiers="virtual const">
|
||||
<return type="PackedStringArray" />
|
||||
<description>
|
||||
Returns a [PackedStringArray] with tracker names configured by this interface. Note that user configuration can override this list.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_get_tracking_status" qualifiers="virtual const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns a [enum XRInterface.TrackingStatus] specifying the current status of our tracking.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_get_transform_for_view" qualifiers="virtual">
|
||||
|
@ -86,50 +97,80 @@
|
|||
<argument index="0" name="view" type="int" />
|
||||
<argument index="1" name="cam_transform" type="Transform3D" />
|
||||
<description>
|
||||
Returns a [Transform3D] for a given view.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_get_view_count" qualifiers="virtual">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the number of views this interface requires, 1 for mono, 2 for stereoscopic.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_initialize" qualifiers="virtual">
|
||||
<return type="bool" />
|
||||
<description>
|
||||
Initializes the interface, returns [code]true[/code] on success.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_is_initialized" qualifiers="virtual const">
|
||||
<return type="bool" />
|
||||
<description>
|
||||
Returns [code]true[/code] if this interface has been initialised.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_notification" qualifiers="virtual">
|
||||
<return type="void" />
|
||||
<argument index="0" name="what" type="int" />
|
||||
<description>
|
||||
Informs the interface of an applicable system notification.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_post_draw_viewport" qualifiers="virtual">
|
||||
<return type="void" />
|
||||
<argument index="0" name="render_target" type="RID" />
|
||||
<argument index="1" name="screen_rect" type="Rect2" />
|
||||
<description>
|
||||
Called after the XR [Viewport] draw logic has completed.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_pre_draw_viewport" qualifiers="virtual">
|
||||
<return type="bool" />
|
||||
<argument index="0" name="render_target" type="RID" />
|
||||
<description>
|
||||
Called if this is our primary [XRInterfaceExtension] before we start processing a [Viewport] for every active XR [Viewport], returns [code]true[/code] if that viewport should be rendered. An XR interface may return [code]false[/code] if the user has taken off their headset and we can pause rendering.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_pre_render" qualifiers="virtual">
|
||||
<return type="void" />
|
||||
<description>
|
||||
Called if this [XRInterfaceExtension] is active before rendering starts, most XR interfaces will sync tracking at this point in time.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_process" qualifiers="virtual">
|
||||
<return type="void" />
|
||||
<description>
|
||||
Called if this [XRInterfaceExtension] is active before our physics and game process is called. most XR interfaces will update its [XRPositionalTracker]s at this point in time.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_set_anchor_detection_is_enabled" qualifiers="virtual">
|
||||
<return type="void" />
|
||||
<argument index="0" name="enabled" type="bool" />
|
||||
<description>
|
||||
Enables anchor detection on this interface if supported.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_set_play_area_mode" qualifiers="virtual const">
|
||||
<return type="bool" />
|
||||
<argument index="0" name="mode" type="int" />
|
||||
<description>
|
||||
Set the play area mode for this interface.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_supports_play_area_mode" qualifiers="virtual const">
|
||||
<return type="bool" />
|
||||
<argument index="0" name="mode" type="int" enum="XRInterface.PlayAreaMode" />
|
||||
<description>
|
||||
Returns [code]true[/code] if this interface supports this play area mode.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_trigger_haptic_pulse" qualifiers="virtual">
|
||||
|
@ -141,11 +182,13 @@
|
|||
<argument index="4" name="duration_sec" type="float" />
|
||||
<argument index="5" name="delay_sec" type="float" />
|
||||
<description>
|
||||
Triggers a haptic pulse to be emitted on the specified tracker.
|
||||
</description>
|
||||
</method>
|
||||
<method name="_uninitialize" qualifiers="virtual">
|
||||
<return type="void" />
|
||||
<description>
|
||||
Uninitialize the interface.
|
||||
</description>
|
||||
</method>
|
||||
<method name="add_blit">
|
||||
|
@ -169,6 +212,7 @@
|
|||
<return type="RID" />
|
||||
<argument index="0" name="render_target" type="RID" />
|
||||
<description>
|
||||
Returns a valid [RID] for a texture to which we should render the current frame if supported by the interface.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
|
|
|
@ -69,24 +69,6 @@
|
|||
Returns a list of available interfaces the ID and name of each interface.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_last_commit_usec">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the absolute timestamp (in μs) of the last [XRServer] commit of the AR/VR eyes to [RenderingServer]. The value comes from an internal call to [method Time.get_ticks_usec].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_last_frame_usec">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the duration (in μs) of the last frame. This is computed as the difference between [method get_last_commit_usec] and [method get_last_process_usec] when committing.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_last_process_usec">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the absolute timestamp (in μs) of the last [XRServer] process callback. The value comes from an internal call to [method Time.get_ticks_usec].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_reference_frame" qualifiers="const">
|
||||
<return type="Transform3D" />
|
||||
<description>
|
||||
|
|
|
@ -463,7 +463,7 @@ CameraMatrix MobileVRInterface::get_projection_for_view(uint32_t p_view, double
|
|||
return eye;
|
||||
};
|
||||
|
||||
Vector<BlitToScreen> MobileVRInterface::commit_views(RID p_render_target, const Rect2 &p_screen_rect) {
|
||||
Vector<BlitToScreen> MobileVRInterface::post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
Vector<BlitToScreen> blit_to_screen;
|
||||
|
|
|
@ -151,7 +151,7 @@ public:
|
|||
virtual Transform3D get_camera_transform() override;
|
||||
virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override;
|
||||
virtual CameraMatrix get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override;
|
||||
virtual Vector<BlitToScreen> commit_views(RID p_render_target, const Rect2 &p_screen_rect) override;
|
||||
virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) override;
|
||||
|
||||
virtual void process() override;
|
||||
|
||||
|
|
|
@ -385,7 +385,7 @@ CameraMatrix WebXRInterfaceJS::get_projection_for_view(uint32_t p_view, double p
|
|||
return eye;
|
||||
}
|
||||
|
||||
Vector<BlitToScreen> WebXRInterfaceJS::commit_views(RID p_render_target, const Rect2 &p_screen_rect) {
|
||||
Vector<BlitToScreen> WebXRInterfaceJS::post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) {
|
||||
Vector<BlitToScreen> blit_to_screen;
|
||||
|
||||
if (!initialized) {
|
||||
|
|
|
@ -88,7 +88,7 @@ public:
|
|||
virtual Transform3D get_camera_transform() override;
|
||||
virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override;
|
||||
virtual CameraMatrix get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override;
|
||||
virtual Vector<BlitToScreen> commit_views(RID p_render_target, const Rect2 &p_screen_rect) override;
|
||||
virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) override;
|
||||
|
||||
virtual void process() override;
|
||||
|
||||
|
|
|
@ -549,8 +549,13 @@ void RendererViewport::draw_viewports() {
|
|||
// get our xr interface in case we need it
|
||||
Ref<XRInterface> xr_interface;
|
||||
|
||||
if (XRServer::get_singleton() != nullptr) {
|
||||
xr_interface = XRServer::get_singleton()->get_primary_interface();
|
||||
XRServer *xr_server = XRServer::get_singleton();
|
||||
if (xr_server != nullptr) {
|
||||
// let our XR server know we're about to render our frames so we can get our frame timing
|
||||
xr_server->pre_render();
|
||||
|
||||
// retrieve the interface responsible for rendering
|
||||
xr_interface = xr_server->get_primary_interface();
|
||||
}
|
||||
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
|
@ -582,19 +587,26 @@ void RendererViewport::draw_viewports() {
|
|||
|
||||
bool visible = vp->viewport_to_screen_rect != Rect2();
|
||||
|
||||
if (vp->use_xr && xr_interface.is_valid()) {
|
||||
visible = true; // XR viewport is always visible regardless of update mode, output is sent to HMD.
|
||||
if (vp->use_xr) {
|
||||
if (xr_interface.is_valid()) {
|
||||
// Override our size, make sure it matches our required size and is created as a stereo target
|
||||
Size2 xr_size = xr_interface->get_render_target_size();
|
||||
|
||||
// Override our size, make sure it matches our required size and is created as a stereo target
|
||||
Size2 xr_size = xr_interface->get_render_target_size();
|
||||
// Would have been nice if we could call viewport_set_size here,
|
||||
// but alas that takes our RID and we now have our pointer,
|
||||
// also we only check if view_count changes in render_target_set_size so we need to call that for this to reliably change
|
||||
vp->occlusion_buffer_dirty = vp->occlusion_buffer_dirty || (vp->size != xr_size);
|
||||
vp->size = xr_size;
|
||||
uint32_t view_count = xr_interface->get_view_count();
|
||||
RSG::storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y, view_count);
|
||||
|
||||
// Would have been nice if we could call viewport_set_size here,
|
||||
// but alas that takes our RID and we now have our pointer,
|
||||
// also we only check if view_count changes in render_target_set_size so we need to call that for this to reliably change
|
||||
vp->occlusion_buffer_dirty = vp->occlusion_buffer_dirty || (vp->size != xr_size);
|
||||
vp->size = xr_size;
|
||||
uint32_t view_count = xr_interface->get_view_count();
|
||||
RSG::storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y, view_count);
|
||||
// Inform xr interface we're about to render its viewport, if this returns false we don't render
|
||||
visible = xr_interface->pre_draw_viewport(vp->render_target);
|
||||
} else {
|
||||
// don't render anything
|
||||
visible = false;
|
||||
vp->size = Size2();
|
||||
}
|
||||
}
|
||||
|
||||
if (vp->update_mode == RS::VIEWPORT_UPDATE_ALWAYS || vp->update_mode == RS::VIEWPORT_UPDATE_ONCE) {
|
||||
|
@ -647,7 +659,7 @@ void RendererViewport::draw_viewports() {
|
|||
// measure
|
||||
|
||||
// commit our eyes
|
||||
Vector<BlitToScreen> blits = xr_interface->commit_views(vp->render_target, vp->viewport_to_screen_rect);
|
||||
Vector<BlitToScreen> blits = xr_interface->post_draw_viewport(vp->render_target, vp->viewport_to_screen_rect);
|
||||
if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID && blits.size() > 0) {
|
||||
if (!blit_to_screen_list.has(vp->viewport_to_screen)) {
|
||||
blit_to_screen_list[vp->viewport_to_screen] = Vector<BlitToScreen>();
|
||||
|
@ -657,9 +669,6 @@ void RendererViewport::draw_viewports() {
|
|||
blit_to_screen_list[vp->viewport_to_screen].push_back(blits[b]);
|
||||
}
|
||||
}
|
||||
|
||||
// and for our frame timing, mark when we've finished committing our eyes
|
||||
XRServer::get_singleton()->_mark_commit();
|
||||
} else {
|
||||
RSG::storage->render_target_set_external_texture(vp->render_target, 0);
|
||||
|
||||
|
|
|
@ -93,6 +93,12 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
|
|||
|
||||
RSG::rasterizer->end_frame(p_swap_buffers);
|
||||
|
||||
XRServer *xr_server = XRServer::get_singleton();
|
||||
if (xr_server != nullptr) {
|
||||
// let our XR server know we're done so we can get our frame timing
|
||||
xr_server->end_frame();
|
||||
}
|
||||
|
||||
RSG::canvas->update_visibility_notifiers();
|
||||
RSG::scene->update_visibility_notifiers();
|
||||
|
||||
|
|
|
@ -168,8 +168,5 @@ XRInterface::TrackingStatus XRInterface::get_tracking_status() const {
|
|||
return XR_UNKNOWN_TRACKING;
|
||||
}
|
||||
|
||||
void XRInterface::notification(int p_what) {
|
||||
}
|
||||
|
||||
void XRInterface::trigger_haptic_pulse(const String &p_action_name, const StringName &p_tracker_name, double p_frequency, double p_amplitude, double p_duration_sec, double p_delay_sec) {
|
||||
}
|
||||
|
|
|
@ -123,10 +123,13 @@ public:
|
|||
|
||||
// note, external color/depth/vrs texture support will be added here soon.
|
||||
|
||||
virtual Vector<BlitToScreen> commit_views(RID p_render_target, const Rect2 &p_screen_rect) = 0; /* commit rendered views to the XR interface */
|
||||
|
||||
virtual void process() = 0;
|
||||
virtual void notification(int p_what);
|
||||
virtual void pre_render(){};
|
||||
virtual bool pre_draw_viewport(RID p_render_target) { return true; }; /* inform XR interface we are about to start our viewport draw process */
|
||||
virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) = 0; /* inform XR interface we finished our viewport draw process */
|
||||
virtual void end_frame(){};
|
||||
|
||||
virtual void notification(int p_what){};
|
||||
|
||||
XRInterface();
|
||||
~XRInterface();
|
||||
|
|
|
@ -52,9 +52,12 @@ void XRInterfaceExtension::_bind_methods() {
|
|||
GDVIRTUAL_BIND(_get_transform_for_view, "view", "cam_transform");
|
||||
GDVIRTUAL_BIND(_get_projection_for_view, "view", "aspect", "z_near", "z_far");
|
||||
|
||||
GDVIRTUAL_BIND(_commit_views, "render_target", "screen_rect");
|
||||
|
||||
GDVIRTUAL_BIND(_process);
|
||||
GDVIRTUAL_BIND(_pre_render);
|
||||
GDVIRTUAL_BIND(_pre_draw_viewport, "render_target");
|
||||
GDVIRTUAL_BIND(_post_draw_viewport, "render_target", "screen_rect");
|
||||
GDVIRTUAL_BIND(_end_frame);
|
||||
|
||||
GDVIRTUAL_BIND(_notification, "what");
|
||||
|
||||
/** input and output **/
|
||||
|
@ -274,7 +277,7 @@ CameraMatrix XRInterfaceExtension::get_projection_for_view(uint32_t p_view, doub
|
|||
void XRInterfaceExtension::add_blit(RID p_render_target, Rect2 p_src_rect, Rect2i p_dst_rect, bool p_use_layer, uint32_t p_layer, bool p_apply_lens_distortion, Vector2 p_eye_center, double p_k1, double p_k2, double p_upscale, double p_aspect_ratio) {
|
||||
BlitToScreen blit;
|
||||
|
||||
ERR_FAIL_COND_MSG(!can_add_blits, "add_blit can only be called from an XR plugin from within _commit_views!");
|
||||
ERR_FAIL_COND_MSG(!can_add_blits, "add_blit can only be called from an XR plugin from within _post_draw_viewport!");
|
||||
|
||||
blit.render_target = p_render_target;
|
||||
blit.src_rect = p_src_rect;
|
||||
|
@ -293,12 +296,31 @@ void XRInterfaceExtension::add_blit(RID p_render_target, Rect2 p_src_rect, Rect2
|
|||
blits.push_back(blit);
|
||||
}
|
||||
|
||||
Vector<BlitToScreen> XRInterfaceExtension::commit_views(RID p_render_target, const Rect2 &p_screen_rect) {
|
||||
void XRInterfaceExtension::process() {
|
||||
GDVIRTUAL_CALL(_process);
|
||||
}
|
||||
|
||||
void XRInterfaceExtension::pre_render() {
|
||||
GDVIRTUAL_CALL(_pre_render);
|
||||
}
|
||||
|
||||
bool XRInterfaceExtension::pre_draw_viewport(RID p_render_target) {
|
||||
bool do_render = true;
|
||||
|
||||
if (GDVIRTUAL_CALL(_pre_draw_viewport, p_render_target, do_render)) {
|
||||
return do_render;
|
||||
} else {
|
||||
// if not implemented we're returning true
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Vector<BlitToScreen> XRInterfaceExtension::post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) {
|
||||
// This is just so our XR plugin can add blits...
|
||||
blits.clear();
|
||||
can_add_blits = true;
|
||||
|
||||
if (GDVIRTUAL_CALL(_commit_views, p_render_target, p_screen_rect)) {
|
||||
if (GDVIRTUAL_CALL(_post_draw_viewport, p_render_target, p_screen_rect)) {
|
||||
return blits;
|
||||
}
|
||||
|
||||
|
@ -306,8 +328,8 @@ Vector<BlitToScreen> XRInterfaceExtension::commit_views(RID p_render_target, con
|
|||
return blits;
|
||||
}
|
||||
|
||||
void XRInterfaceExtension::process() {
|
||||
GDVIRTUAL_CALL(_process);
|
||||
void XRInterfaceExtension::end_frame() {
|
||||
GDVIRTUAL_CALL(_end_frame);
|
||||
}
|
||||
|
||||
void XRInterfaceExtension::notification(int p_what) {
|
||||
|
|
|
@ -109,13 +109,20 @@ public:
|
|||
GDVIRTUAL4R(PackedFloat64Array, _get_projection_for_view, uint32_t, double, double, double);
|
||||
|
||||
void add_blit(RID p_render_target, Rect2 p_src_rect, Rect2i p_dst_rect, bool p_use_layer = false, uint32_t p_layer = 0, bool p_apply_lens_distortion = false, Vector2 p_eye_center = Vector2(), double p_k1 = 0.0, double p_k2 = 0.0, double p_upscale = 1.0, double p_aspect_ratio = 1.0);
|
||||
virtual Vector<BlitToScreen> commit_views(RID p_render_target, const Rect2 &p_screen_rect) override;
|
||||
GDVIRTUAL2(_commit_views, RID, const Rect2 &);
|
||||
|
||||
virtual void process() override;
|
||||
virtual void pre_render() override;
|
||||
virtual bool pre_draw_viewport(RID p_render_target) override;
|
||||
virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) override;
|
||||
virtual void end_frame() override;
|
||||
virtual void notification(int p_what) override;
|
||||
|
||||
GDVIRTUAL0(_process);
|
||||
GDVIRTUAL0(_pre_render);
|
||||
GDVIRTUAL1R(bool, _pre_draw_viewport, RID);
|
||||
GDVIRTUAL2(_post_draw_viewport, RID, const Rect2 &);
|
||||
GDVIRTUAL0(_end_frame);
|
||||
|
||||
GDVIRTUAL1(_notification, int);
|
||||
|
||||
/* access to some internals we need */
|
||||
|
|
|
@ -65,10 +65,6 @@ void XRServer::_bind_methods() {
|
|||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "primary_interface"), "set_primary_interface", "get_primary_interface");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_last_process_usec"), &XRServer::get_last_process_usec);
|
||||
ClassDB::bind_method(D_METHOD("get_last_commit_usec"), &XRServer::get_last_commit_usec);
|
||||
ClassDB::bind_method(D_METHOD("get_last_frame_usec"), &XRServer::get_last_frame_usec);
|
||||
|
||||
BIND_ENUM_CONSTANT(TRACKER_HEAD);
|
||||
BIND_ENUM_CONSTANT(TRACKER_CONTROLLER);
|
||||
BIND_ENUM_CONSTANT(TRACKER_BASESTATION);
|
||||
|
@ -351,24 +347,9 @@ PackedStringArray XRServer::get_suggested_pose_names(const StringName &p_tracker
|
|||
return arr;
|
||||
}
|
||||
|
||||
uint64_t XRServer::get_last_process_usec() {
|
||||
return last_process_usec;
|
||||
};
|
||||
|
||||
uint64_t XRServer::get_last_commit_usec() {
|
||||
return last_commit_usec;
|
||||
};
|
||||
|
||||
uint64_t XRServer::get_last_frame_usec() {
|
||||
return last_frame_usec;
|
||||
};
|
||||
|
||||
void XRServer::_process() {
|
||||
/* called from renderer_viewport.draw_viewports right before we start drawing our viewports */
|
||||
|
||||
/* mark for our frame timing */
|
||||
last_process_usec = OS::get_singleton()->get_ticks_usec();
|
||||
|
||||
/* process all active interfaces */
|
||||
for (int i = 0; i < interfaces.size(); i++) {
|
||||
if (!interfaces[i].is_valid()) {
|
||||
|
@ -379,13 +360,32 @@ void XRServer::_process() {
|
|||
};
|
||||
};
|
||||
|
||||
void XRServer::_mark_commit() {
|
||||
/* time this */
|
||||
last_commit_usec = OS::get_singleton()->get_ticks_usec();
|
||||
void XRServer::pre_render() {
|
||||
// called from RendererViewport.draw_viewports right before we start drawing our viewports
|
||||
// note that we can have multiple interfaces active if we have interfaces that purely handle tracking
|
||||
|
||||
/* now store our difference as we may overwrite last_process_usec before this is accessed */
|
||||
last_frame_usec = last_commit_usec - last_process_usec;
|
||||
};
|
||||
// process all active interfaces
|
||||
for (int i = 0; i < interfaces.size(); i++) {
|
||||
if (!interfaces[i].is_valid()) {
|
||||
// ignore, not a valid reference
|
||||
} else if (interfaces[i]->is_initialized()) {
|
||||
interfaces.write[i]->pre_render();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
void XRServer::end_frame() {
|
||||
// called from RenderingServerDefault after Vulkan queues have been submitted
|
||||
|
||||
// process all active interfaces
|
||||
for (int i = 0; i < interfaces.size(); i++) {
|
||||
if (!interfaces[i].is_valid()) {
|
||||
// ignore, not a valid reference
|
||||
} else if (interfaces[i]->is_initialized()) {
|
||||
interfaces.write[i]->end_frame();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
XRServer::XRServer() {
|
||||
singleton = this;
|
||||
|
|
|
@ -84,10 +84,6 @@ private:
|
|||
Transform3D world_origin; /* our world origin point, maps a location in our virtual world to the origin point in our real world tracking volume */
|
||||
Transform3D reference_frame; /* our reference frame */
|
||||
|
||||
uint64_t last_process_usec; /* for frame timing, usec when we did our processing */
|
||||
uint64_t last_commit_usec; /* for frame timing, usec when we finished committing both eyes */
|
||||
uint64_t last_frame_usec; /* time it took between process and committing, we should probably average this over the last x frames */
|
||||
|
||||
protected:
|
||||
static XRServer *singleton;
|
||||
|
||||
|
@ -175,12 +171,16 @@ public:
|
|||
PackedStringArray get_suggested_pose_names(const StringName &p_tracker_name) const;
|
||||
// Q: Should we add get_suggested_input_names and get_suggested_haptic_names even though we don't use them for the IDE?
|
||||
|
||||
uint64_t get_last_process_usec();
|
||||
uint64_t get_last_commit_usec();
|
||||
uint64_t get_last_frame_usec();
|
||||
|
||||
// Process is called before we handle our physics process and game process. This is where our interfaces will update controller data and such.
|
||||
void _process();
|
||||
void _mark_commit();
|
||||
|
||||
// Pre-render is called right before we're rendering our viewports.
|
||||
// This is where interfaces such as OpenVR and OpenXR will update positioning data.
|
||||
// Many of these interfaces will also do a predictive sync which ensures we run at a steady framerate.
|
||||
void pre_render();
|
||||
|
||||
// End-frame is called right after Godot has finished its rendering bits.
|
||||
void end_frame();
|
||||
|
||||
XRServer();
|
||||
~XRServer();
|
||||
|
|
Loading…
Reference in a new issue