105 lines
3.1 KiB
C#
105 lines
3.1 KiB
C#
using Godot;
|
|
|
|
public partial class Main : Node3D
|
|
{
|
|
[Signal]
|
|
public delegate void FocusLostEventHandler();
|
|
|
|
[Signal]
|
|
public delegate void FocusGainedEventHandler();
|
|
|
|
[Signal]
|
|
public delegate void PoseRecenteredEventHandler();
|
|
|
|
[Export]
|
|
public int MaximumRefreshRate { get; set; } = 90;
|
|
|
|
private OpenXRInterface _xrInterface;
|
|
private bool _xrIsFocused;
|
|
|
|
public override void _Ready()
|
|
{
|
|
_xrInterface = (OpenXRInterface)XRServer.FindInterface("OpenXR");
|
|
if (_xrInterface != null && _xrInterface.IsInitialized())
|
|
{
|
|
GD.Print("OpenXR instantiated successfully.");
|
|
Viewport vp = GetViewport();
|
|
vp.UseXR = true;
|
|
DisplayServer.WindowSetVsyncMode(DisplayServer.VSyncMode.Disabled);
|
|
if (RenderingServer.GetRenderingDevice() != null)
|
|
vp.VrsMode = Viewport.VrsModeEnum.XR;
|
|
|
|
_xrInterface.SessionBegun += OnSessionBegun;
|
|
_xrInterface.SessionVisible += OnSessionVisible;
|
|
_xrInterface.SessionFocussed += OnSessionFocussed;
|
|
_xrInterface.SessionStopping += OnSessionStopping;
|
|
_xrInterface.PoseRecentered += OnPoseRecentered;
|
|
}
|
|
else
|
|
{
|
|
GD.PushWarning("OpenXR not instantiated, running in flat preview mode. Check headset and XR runtime.");
|
|
}
|
|
}
|
|
|
|
private void OnSessionBegun()
|
|
{
|
|
float currentRefreshRate = _xrInterface.DisplayRefreshRate;
|
|
GD.Print(currentRefreshRate > 0.0f
|
|
? $"OpenXR: refresh rate reported as {currentRefreshRate}"
|
|
: "OpenXR: no refresh rate given by XR runtime");
|
|
|
|
float newRate = currentRefreshRate;
|
|
var availableRates = _xrInterface.GetAvailableDisplayRefreshRates();
|
|
if (availableRates.Count == 0)
|
|
GD.Print("OpenXR: target does not support refresh rate extension");
|
|
else if (availableRates.Count == 1)
|
|
newRate = (float)availableRates[0];
|
|
else
|
|
{
|
|
foreach (float rate in availableRates)
|
|
{
|
|
if (rate > newRate && rate <= MaximumRefreshRate)
|
|
newRate = rate;
|
|
}
|
|
}
|
|
|
|
if (currentRefreshRate != newRate)
|
|
{
|
|
GD.Print($"OpenXR: setting refresh rate to {newRate}");
|
|
_xrInterface.DisplayRefreshRate = newRate;
|
|
currentRefreshRate = newRate;
|
|
}
|
|
|
|
Engine.PhysicsTicksPerSecond = (int)currentRefreshRate;
|
|
}
|
|
|
|
private void OnSessionVisible()
|
|
{
|
|
if (_xrIsFocused)
|
|
{
|
|
GD.Print("OpenXR lost focus");
|
|
_xrIsFocused = false;
|
|
GetTree().Paused = true;
|
|
EmitSignal(SignalName.FocusLost);
|
|
}
|
|
}
|
|
|
|
private void OnSessionFocussed()
|
|
{
|
|
GD.Print("OpenXR gained focus");
|
|
_xrIsFocused = true;
|
|
GetTree().Paused = false;
|
|
EmitSignal(SignalName.FocusGained);
|
|
}
|
|
|
|
private void OnSessionStopping()
|
|
{
|
|
GD.Print("OpenXR is stopping");
|
|
}
|
|
|
|
private void OnPoseRecentered()
|
|
{
|
|
EmitSignal(SignalName.PoseRecentered);
|
|
}
|
|
}
|