229 lines
8.0 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using Unity.XR.CoreUtils;
using UnityEngine.XR;
namespace Unity.XR.OpenXR.Features.PICOSupport
{
public class PICOManager : MonoBehaviour
{
private const string TAG = "[PICOManager]";
private static PICOManager instance = null;
private Camera[] eyeCamera;
private XROrigin _xrOrigin;
private XROrigin _xrOriginT;
static List<XRInputSubsystem> s_InputSubsystems = new List<XRInputSubsystem>();
private float cameraYOffset;
private float cameraY;
private bool isTrackingOriginMode = false;
private TrackingOriginModeFlags currentTrackingOriginMode = TrackingOriginModeFlags.Unknown;
private Vector3 _xrOriginPos = Vector3.zero;
private Vector3 _xrOriginTPos = Vector3.zero;
private Quaternion _xrOriginRot = Quaternion.identity;
private Quaternion _xrOriginTRot = Quaternion.identity;
private static GameObject local = null;
private Vector3 lastOriginPos = Vector3.zero;
private Quaternion lastOriginRot = Quaternion.identity;
private Vector3 lastOriginTPos = Vector3.zero;
private Quaternion lastOriginTRot = Quaternion.identity;
public static PICOManager Instance
{
get
{
if (instance == null)
{
instance = FindObjectOfType<PICOManager>();
if (instance == null)
{
XROrigin origin = Camera.main.transform.GetComponentInParent<XROrigin>();
if (origin != null)
{
instance = origin.gameObject.AddComponent<PICOManager>();
}
else
{
GameObject go = new GameObject("[PICOManager]");
DontDestroyOnLoad(go);
instance = go.AddComponent<PICOManager>();
}
}
}
return instance;
}
}
void Awake()
{
eyeCamera = new Camera[3];
Camera[] cam = gameObject.GetComponentsInChildren<Camera>();
for (int i = 0; i < cam.Length; i++)
{
if (cam[i].stereoTargetEye == StereoTargetEyeMask.Both && cam[i] == Camera.main)
{
eyeCamera[0] = cam[i];
}
else if (cam[i].stereoTargetEye == StereoTargetEyeMask.Left)
{
eyeCamera[1] = cam[i];
}
else if (cam[i].stereoTargetEye == StereoTargetEyeMask.Right)
{
eyeCamera[2] = cam[i];
}
}
_xrOrigin = gameObject.GetComponent<XROrigin>();
if (_xrOrigin != null)
{
_xrOriginPos = new Vector3(Camera.main.transform.position.x, _xrOrigin.transform.position.y, Camera.main.transform.position.z);
cameraYOffset = _xrOrigin.CameraYOffset;
}
_xrOriginRot = Camera.main.transform.parent.rotation;
cameraY = this.transform.position.y;
if (local == null)
{
local = new GameObject();
}
}
public float getCameraYOffset()
{
if (currentTrackingOriginMode == TrackingOriginModeFlags.Floor)
{
return cameraY;
}
return cameraY + cameraYOffset;
}
private void Update()
{
if (!isTrackingOriginMode)
{
XRInputSubsystem subsystem = null;
SubsystemManager.GetInstances(s_InputSubsystems);
if (s_InputSubsystems.Count > 0)
{
subsystem = s_InputSubsystems[0];
}
var mCurrentTrackingOriginMode = subsystem?.GetTrackingOriginMode();
if (mCurrentTrackingOriginMode != null)
{
isTrackingOriginMode = true;
currentTrackingOriginMode = (TrackingOriginModeFlags)mCurrentTrackingOriginMode;
}
}
}
private void OnEnable()
{
if (Camera.main.gameObject.GetComponent<CompositeLayerManager>() == null)
{
Camera.main.gameObject.AddComponent<CompositeLayerManager>();
}
foreach (var layer in CompositeLayerFeature.Instances)
{
if (eyeCamera[0] != null && eyeCamera[0].enabled)
{
layer.RefreshCamera(eyeCamera[0], eyeCamera[0]);
}
else if (eyeCamera[1] != null && eyeCamera[1].enabled)
{
layer.RefreshCamera(eyeCamera[1], eyeCamera[2]);
}
}
}
public Camera[] GetEyeCamera()
{
return eyeCamera;
}
public float GetOriginY()
{
return _xrOrigin.transform.position.y;
}
public bool GetOrigin(ref Vector3 pos, ref Quaternion rotation, ref Transform origin)
{
Transform transform = local.GetComponent<Transform>();
transform.rotation = Quaternion.identity;
origin = transform;
XROrigin xrOrigin = FindObjectOfType<XROrigin>();
if (!xrOrigin)
{
PLog.e(TAG + $" xrOrigin is false!");
pos = Vector3.zero;
rotation = Quaternion.identity;
return false;
}
if (xrOrigin == _xrOrigin)
{
if (xrOrigin.transform.position != lastOriginPos || xrOrigin.transform.rotation != lastOriginRot)
{
_xrOriginPos.x = Camera.main.transform.position.x;
_xrOriginPos.y = xrOrigin.transform.position.y;
_xrOriginPos.z = Camera.main.transform.position.z;
_xrOriginRot = Camera.main.transform.parent.rotation;
lastOriginPos = xrOrigin.transform.position;
lastOriginRot = xrOrigin.transform.rotation;
}
pos = _xrOriginPos;
rotation = _xrOriginRot;
return true;
}
else if (xrOrigin == _xrOriginT)
{
if (xrOrigin.transform.position != lastOriginTPos || xrOrigin.transform.rotation != lastOriginTRot)
{
_xrOriginTPos.x = Camera.main.transform.position.x;
_xrOriginTPos.y = xrOrigin.transform.position.y;
_xrOriginTPos.z = Camera.main.transform.position.z;
_xrOriginTRot = Camera.main.transform.parent.rotation;
lastOriginTPos = xrOrigin.transform.position;
lastOriginTRot = xrOrigin.transform.rotation;
}
pos = _xrOriginTPos;
rotation = _xrOriginTRot;
return true;
}
_xrOriginT = xrOrigin;
_xrOriginTPos = new Vector3(Camera.main.transform.parent.position.x, xrOrigin.transform.position.y, Camera.main.transform.parent.position.z);
_xrOriginTRot = Camera.main.transform.parent.rotation;
pos = _xrOriginTPos;
rotation = _xrOriginTRot;
return true;
}
public float GetRefreshRate()
{
float i = -1;
DisplayRefreshRateFeature.GetDisplayRefreshRate(ref i);
return i;
}
public XrExtent2Df GetReferenceSpaceBoundsRect()
{
XrExtent2Df extent2D = new XrExtent2Df();
OpenXRExtensions.GetReferenceSpaceBoundsRect(XrReferenceSpaceType.Stage, ref extent2D);
return extent2D;
}
}
}