mixedreality/com.microsoft.mixedreality..../Runtime/Subsystems/SessionSubsystem.cs

173 lines
7.3 KiB
C#

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Collections.Generic;
using Unity.Collections;
using UnityEngine;
using UnityEngine.Scripting;
using UnityEngine.XR.ARSubsystems;
namespace Microsoft.MixedReality.OpenXR
{
[Preserve]
internal class SessionSubsystem : XRSessionSubsystem
{
public const string Id = "OpenXR Session";
private class OpenXRProvider : Provider
{
private readonly Guid m_sessionGuid;
private readonly Feature m_allSupportedFeatures = Feature.AnyTrackingMode | Feature.PlaneTracking | Feature.Raycast | Feature.Meshing;
// The requested features, excluding the requested tracking mode
private readonly Feature m_requestedBaseFeatures = Feature.PlaneTracking | Feature.Raycast | Feature.Meshing;
private Feature m_requestedTrackingMode = Feature.PositionAndRotation;
private NativeSpaceLocationFlags m_trackingStateFlags;
public OpenXRProvider()
{
m_sessionGuid = Guid.NewGuid();
}
public override void Start() { }
public override void Stop() { }
public override void Destroy() { }
public override Feature currentTrackingMode
{
get
{
if (!m_trackingStateFlags.HasFlag(NativeSpaceLocationFlags.OrientationValid) ||
!m_trackingStateFlags.HasFlag(NativeSpaceLocationFlags.PositionValid))
return Feature.None;
if (!m_trackingStateFlags.HasFlag(NativeSpaceLocationFlags.PositionTracked))
return Feature.RotationOnly;
return Feature.PositionAndRotation;
}
}
public override Feature requestedTrackingMode
{
get => m_requestedTrackingMode;
set
{
if (m_requestedTrackingMode != Feature.PositionAndRotation && m_requestedTrackingMode != Feature.RotationOnly)
{
Debug.Log("Session supported requested tracking modes are PositionAndRotation and RotationOnly.");
return;
}
m_requestedTrackingMode = value;
}
}
public override TrackingState trackingState
{
get
{
if (!m_trackingStateFlags.HasFlag(NativeSpaceLocationFlags.PositionValid) ||
!m_trackingStateFlags.HasFlag(NativeSpaceLocationFlags.OrientationValid))
return TrackingState.None;
if (m_trackingStateFlags.HasFlag(NativeSpaceLocationFlags.All))
return TrackingState.Tracking;
return TrackingState.Limited;
}
}
public override NotTrackingReason notTrackingReason
{
get
{
if (!m_trackingStateFlags.HasFlag(NativeSpaceLocationFlags.PositionValid) ||
!m_trackingStateFlags.HasFlag(NativeSpaceLocationFlags.OrientationValid))
return NotTrackingReason.Initializing;
if (m_trackingStateFlags.HasFlag(NativeSpaceLocationFlags.All))
return NotTrackingReason.None;
return NotTrackingReason.Relocalizing;
}
}
public override bool matchFrameRateEnabled { get => false; }
public override bool matchFrameRateRequested { get => false; }
public override int frameRate { get => 0; } // Framerate is not supported unless matchFrameRateEnabled = true
public override Feature requestedFeatures { get => m_requestedBaseFeatures | m_requestedTrackingMode; }
public override IntPtr nativePtr { get => IntPtr.Zero; }
public override Guid sessionId { get => m_sessionGuid; }
/// <summary>
/// Get the session's availability, such as whether the platform supports XR.
/// SessionAvailability.None: "Default value. The availability is unknown."
/// SessionAvailability.Supported: "The current device is AR capable (but might require a software update)."
/// SessionAvailability.Installed: "The required AR software is installed on the device."
/// </summary>
public override Promise<SessionAvailability> GetAvailabilityAsync()
{
if (OpenXRContext.Current.SystemId != 0)
{
return Promise<SessionAvailability>.CreateResolvedPromise(SessionAvailability.Supported | SessionAvailability.Installed);
}
return Promise<SessionAvailability>.CreateResolvedPromise(SessionAvailability.None);
}
public override NativeArray<ConfigurationDescriptor> GetConfigurationDescriptors(Allocator allocator)
{
// Sessions may have multiple 'modes' of operation, each with a different set of capabilities.
// Our session only has one such mode, so this array will always be one ConfigurationDescriptor long.
var nativeArray = new NativeArray<ConfigurationDescriptor>(1, allocator, NativeArrayOptions.UninitializedMemory);
nativeArray[0] = new ConfigurationDescriptor(IntPtr.Zero, m_allSupportedFeatures, 0);
return nativeArray;
}
public override void OnApplicationPause() { }
public override void OnApplicationResume() { }
// Only one configuration is supported, so the configuration settings can be inferred in the standard update.
public override void Update(XRSessionUpdateParams updateParams, Configuration configuration) => Update(updateParams);
public override void Update(XRSessionUpdateParams updateParams)
{
m_trackingStateFlags = NativeLib.GetPrimaryViewTrackingState();
}
}
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
static void RegisterDescriptor()
{
XRSessionSubsystemDescriptor.RegisterDescriptor(new XRSessionSubsystemDescriptor.Cinfo
{
id = Id,
providerType = typeof(SessionSubsystem.OpenXRProvider),
subsystemTypeOverride = typeof(SessionSubsystem),
supportsInstall = false,
supportsMatchFrameRate = false
});
}
};
internal class SessionSubsystemController : SubsystemController
{
private static List<XRSessionSubsystemDescriptor> s_SessionDescriptors = new List<XRSessionSubsystemDescriptor>();
public SessionSubsystemController(IOpenXRContext context) : base(context)
{
}
public override void OnSubsystemCreate(ISubsystemPlugin plugin)
{
plugin.CreateSubsystem<XRSessionSubsystemDescriptor, XRSessionSubsystem>(s_SessionDescriptors, SessionSubsystem.Id);
}
public override void OnSubsystemDestroy(ISubsystemPlugin plugin)
{
plugin.DestroySubsystem<XRSessionSubsystem>();
}
}
}