Heroes_of_Hiis/Assets/Oculus/VR/Scripts/Util/OVRSpectatorModeDomeTest.cs

291 lines
8.8 KiB
C#

/************************************************************************************
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
Your use of this SDK or tool is subject to the Oculus SDK License Agreement, available at
https://developer.oculus.com/licenses/oculussdk/
Unless required by applicable law or agreed to in writing, the Utilities SDK distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
ANY KIND, either express or implied. See the License for the specific language governing
permissions and limitations under the License.
************************************************************************************/
#if UNITY_ANDROID && !UNITY_EDITOR
#define OVR_ANDROID_MRC
#endif
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class OVRSpectatorModeDomeTest : MonoBehaviour {
bool inited = false;
public Camera defaultExternalCamera;
OVRPlugin.Fovf defaultFov;
public Transform SpectatorAnchor;
public Transform Head;
#if OVR_ANDROID_MRC
private OVRPlugin.Media.PlatformCameraMode camMode = OVRPlugin.Media.PlatformCameraMode.Disabled;
private bool readyToSwitch = false;
private Transform SpectatorCamera;
// Dome sphere representation
private float distance = 0.8f;
private float elevation = 0.0f;
private float polar = 90.0f;
private const float distance_near = 0.5f;
private const float distance_far = 1.2f;
private const float elevationLimit = 30.0f;
#endif
// Start is called before the first frame update
void Awake()
{
#if OVR_ANDROID_MRC
OVRPlugin.Media.SetPlatformInitialized();
SpectatorCamera = defaultExternalCamera.transform.parent;
#endif
}
// 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;
#if OVR_ANDROID_MRC
readyToSwitch = true;
#endif
#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;
OVRCameraRig cameraRig = mainCamera.GetComponentInParent<OVRCameraRig>();
if (cameraRig)
{
Transform trackingSpace = cameraRig.trackingSpace;
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();
}
else
{
cameraExtrinsics.RelativePose = OVRPlugin.Posef.identity;
}
if (!OVRPlugin.SetDefaultExternalCamera(cameraName, ref cameraIntrinsics, ref cameraExtrinsics))
{
Debug.LogError("SetDefaultExternalCamera() failed");
}
#endif
}
private void UpdateSpectatorCameraStatus()
{
#if OVR_ANDROID_MRC
// Trigger to switch between 1st person and spectator mode during casting to phone
if (OVRInput.GetDown(OVRInput.Button.PrimaryIndexTrigger) || OVRInput.GetDown(OVRInput.Button.SecondaryIndexTrigger))
{
camMode = OVRPlugin.Media.GetPlatformCameraMode();
if (camMode == OVRPlugin.Media.PlatformCameraMode.Disabled && readyToSwitch)
{
OVRPlugin.Media.SetMrcFrameImageFlipped(false);
OVRPlugin.Media.SetPlatformCameraMode(OVRPlugin.Media.PlatformCameraMode.Initialized);
StartCoroutine(TimerCoroutine());
}
if (camMode == OVRPlugin.Media.PlatformCameraMode.Initialized && readyToSwitch)
{
OVRPlugin.Media.SetMrcFrameImageFlipped(true);
OVRPlugin.Media.SetPlatformCameraMode(OVRPlugin.Media.PlatformCameraMode.Disabled);
StartCoroutine(TimerCoroutine());
}
}
// Keep spectator camera on dome surface
Vector2 axis = OVRInput.Get(OVRInput.Axis2D.SecondaryThumbstick);
if (Mathf.Abs(axis.x) > 0.2f)
{
polar = polar - axis.x * 0.5f;
}
if (Mathf.Abs(axis.y) > 0.2f)
{
elevation = elevation + axis.y * 0.5f;
if (elevation < -90.0f + elevationLimit) elevation = -90.0f + elevationLimit;
if (elevation > 90.0f) elevation = 90.0f;
}
axis = OVRInput.Get(OVRInput.Axis2D.PrimaryThumbstick);
if (Mathf.Abs(axis.y) > 0.1f)
{
distance = axis.y * 0.05f + distance;
if (distance > distance_far) distance = distance_far;
if (distance < distance_near) distance = distance_near;
}
SpectatorCamera.position = SpectatorCameraDomePosition(SpectatorAnchor.position, distance, elevation, polar);
SpectatorCamera.rotation = Quaternion.LookRotation(SpectatorCamera.position - SpectatorAnchor.position);
Head.position = SpectatorAnchor.position;
Head.rotation = SpectatorAnchor.rotation;
#endif
}
Vector3 SpectatorCameraDomePosition(Vector3 spectatorAnchorPosition, float d, float e, float p)
{
float x = d * Mathf.Cos(Mathf.Deg2Rad * e) * Mathf.Cos(Mathf.Deg2Rad * p);
float y = d * Mathf.Sin(Mathf.Deg2Rad * e);
float z = d * Mathf.Cos(Mathf.Deg2Rad * e) * Mathf.Sin(Mathf.Deg2Rad * p);
return new Vector3(x + spectatorAnchorPosition.x, y + spectatorAnchorPosition.y, z + spectatorAnchorPosition.z);
}
IEnumerator TimerCoroutine()
{
#if OVR_ANDROID_MRC
readyToSwitch = false;
#endif
yield return new WaitForSeconds(2);
#if OVR_ANDROID_MRC
readyToSwitch = true;
#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
UpdateSpectatorCameraStatus();
UpdateDefaultExternalCamera();
OVRPlugin.OverrideExternalCameraFov(0, false, new OVRPlugin.Fovf());
OVRPlugin.OverrideExternalCameraStaticPose(0, false, OVRPlugin.Posef.identity);
#endif
}
void OnApplicationPause()
{
#if OVR_ANDROID_MRC
OVRPlugin.Media.SetMrcFrameImageFlipped(true);
OVRPlugin.Media.SetPlatformCameraMode(OVRPlugin.Media.PlatformCameraMode.Disabled);
#endif
}
void OnApplicationQuit()
{
#if OVR_ANDROID_MRC
OVRPlugin.Media.SetMrcFrameImageFlipped(true);
OVRPlugin.Media.SetPlatformCameraMode(OVRPlugin.Media.PlatformCameraMode.Disabled);
#endif
}
}