#if UNITY_ANDROID && !UNITY_EDITOR #define OVR_ANDROID_MRC #endif using System.Collections; using System.Collections.Generic; using UnityEngine; namespace MRCHelpers { /// /// Triggers the Oculus MRC tracking engine if the scene uses the XR Interaction Toolkit. /// The code is modified from the file OVRMixedRealityCaptureTest in Oculus plugin /// public class OVRMixedRealityCaptureTestMod : MonoBehaviour { bool inited = false; public Camera defaultExternalCamera; OVRPlugin.Fovf defaultFov; // Use this for initialization void Start() { #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || OVR_ANDROID_MRC if (!defaultExternalCamera) { Debug.LogWarning("defaultExternalCamera undefined"); } #if !OVR_ANDROID_MRC // On Quest, we enable MRC automatically through the configuration if (!OVRManager.instance.enableMixedReality) { OVRManager.instance.enableMixedReality = true; } #endif #endif } void Initialize() { #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || OVR_ANDROID_MRC if (inited) return; #if OVR_ANDROID_MRC if (!OVRPlugin.Media.GetInitialized()) return; #else if (!OVRPlugin.IsMixedRealityInitialized()) return; #endif OVRPlugin.ResetDefaultExternalCamera(); Debug.LogFormat("GetExternalCameraCount before adding manual external camera {0}", OVRPlugin.GetExternalCameraCount()); UpdateDefaultExternalCamera(); Debug.LogFormat("GetExternalCameraCount after adding manual external camera {0}", OVRPlugin.GetExternalCameraCount()); // obtain default FOV { OVRPlugin.CameraIntrinsics cameraIntrinsics; OVRPlugin.CameraExtrinsics cameraExtrinsics; OVRPlugin.GetMixedRealityCameraInfo(0, out cameraExtrinsics, out cameraIntrinsics); defaultFov = cameraIntrinsics.FOVPort; } inited = true; #endif } void UpdateDefaultExternalCamera() { #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || OVR_ANDROID_MRC // always build a 1080p external camera const int cameraPixelWidth = 1920; const int cameraPixelHeight = 1080; const float cameraAspect = (float)cameraPixelWidth / cameraPixelHeight; string cameraName = "UnityExternalCamera"; OVRPlugin.CameraIntrinsics cameraIntrinsics = new OVRPlugin.CameraIntrinsics(); OVRPlugin.CameraExtrinsics cameraExtrinsics = new OVRPlugin.CameraExtrinsics(); // intrinsics cameraIntrinsics.IsValid = OVRPlugin.Bool.True; cameraIntrinsics.LastChangedTimeSeconds = Time.time; float vFov = defaultExternalCamera.fieldOfView * Mathf.Deg2Rad; float hFov = Mathf.Atan(Mathf.Tan(vFov * 0.5f) * cameraAspect) * 2.0f; OVRPlugin.Fovf fov = new OVRPlugin.Fovf(); fov.UpTan = fov.DownTan = Mathf.Tan(vFov * 0.5f); fov.LeftTan = fov.RightTan = Mathf.Tan(hFov * 0.5f); cameraIntrinsics.FOVPort = fov; cameraIntrinsics.VirtualNearPlaneDistanceMeters = defaultExternalCamera.nearClipPlane; cameraIntrinsics.VirtualFarPlaneDistanceMeters = defaultExternalCamera.farClipPlane; cameraIntrinsics.ImageSensorPixelResolution.w = cameraPixelWidth; cameraIntrinsics.ImageSensorPixelResolution.h = cameraPixelHeight; // extrinsics cameraExtrinsics.IsValid = OVRPlugin.Bool.True; cameraExtrinsics.LastChangedTimeSeconds = Time.time; cameraExtrinsics.CameraStatusData = OVRPlugin.CameraStatus.CameraStatus_Calibrated; cameraExtrinsics.AttachedToNode = OVRPlugin.Node.None; Camera mainCamera = Camera.main; Transform trackingSpace = Camera.main.transform.parent; OVRPose trackingSpacePose = trackingSpace.ToOVRPose(false); OVRPose cameraPose = defaultExternalCamera.transform.ToOVRPose(false); OVRPose relativePose = trackingSpacePose.Inverse() * cameraPose; #if OVR_ANDROID_MRC OVRPose stageToLocalPose = OVRPlugin.GetTrackingTransformRelativePose(OVRPlugin.TrackingOrigin.Stage).ToOVRPose(); OVRPose localToStagePose = stageToLocalPose.Inverse(); relativePose = localToStagePose * relativePose; #endif cameraExtrinsics.RelativePose = relativePose.ToPosef(); if (!OVRPlugin.SetDefaultExternalCamera(cameraName, ref cameraIntrinsics, ref cameraExtrinsics)) { Debug.LogError("SetDefaultExternalCamera() failed"); } #endif } // Update is called once per frame void Update() { #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || OVR_ANDROID_MRC if (!inited) { Initialize(); return; } if (!defaultExternalCamera) { return; } #if OVR_ANDROID_MRC if (!OVRPlugin.Media.GetInitialized()) { return; } #else if (!OVRPlugin.IsMixedRealityInitialized()) { return; } #endif UpdateDefaultExternalCamera(); OVRPlugin.OverrideExternalCameraFov(0, false, new OVRPlugin.Fovf()); OVRPlugin.OverrideExternalCameraStaticPose(0, false, OVRPlugin.Posef.identity); #endif } } }