Untitled diff

Created Diff never expires
39 removals
712 lines
60 additions
733 lines
/************************************************************************************
/************************************************************************************
Copyright : Copyright 2014 Oculus VR, LLC. All Rights reserved.
Copyright : Copyright 2014 Oculus VR, LLC. All Rights reserved.
Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
you may not use the Oculus VR Rift SDK except in compliance with the License,
you may not use the Oculus VR Rift SDK except in compliance with the License,
which is provided at the time of installation or download, or which
which is provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
otherwise accompanies this software in either electronic or hard copy form.
You may obtain a copy of the License at
You may obtain a copy of the License at
http://www.oculusvr.com/licenses/LICENSE-3.2
http://www.oculusvr.com/licenses/LICENSE-3.2
Unless required by applicable law or agreed to in writing, the Oculus VR SDK
Unless required by applicable law or agreed to in writing, the Oculus VR SDK
distributed under the License is distributed on an "AS IS" BASIS,
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
See the License for the specific language governing permissions and
limitations under the License.
limitations under the License.
************************************************************************************/
************************************************************************************/
using System;
using System;
using System.Collections;
using System.Collections;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices;
using System.Linq;
using System.Linq;
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine;
using Ovr;
using Ovr;
/// <summary>
/// <summary>
/// Configuration data for Oculus virtual reality.
/// Configuration data for Oculus virtual reality.
/// </summary>
/// </summary>
public class OVRManager : MonoBehaviour
public class OVRManager : MonoBehaviour
{
{
/// <summary>
/// <summary>
/// Contains information about the user's preferences and body dimensions.
/// Contains information about the user's preferences and body dimensions.
/// </summary>
/// </summary>
public struct Profile
public struct Profile
{
{
public float ipd;
public float ipd;
public float eyeHeight;
public float eyeHeight;
public float eyeDepth;
public float eyeDepth;
public float neckHeight;
public float neckHeight;
}
}
/// <summary>
/// <summary>
/// Gets the singleton instance.
/// Gets the singleton instance.
/// </summary>
/// </summary>
public static OVRManager instance { get; private set; }
public static OVRManager instance { get; private set; }
/// <summary>
/// <summary>
/// Gets a reference to the low-level C API Hmd Wrapper
/// Gets a reference to the low-level C API Hmd Wrapper
/// </summary>
/// </summary>
private static Hmd _capiHmd;
private static Hmd _capiHmd;
public static Hmd capiHmd
public static Hmd capiHmd
{
{
get {
get {
#if !UNITY_ANDROID || UNITY_EDITOR
#if !UNITY_ANDROID || UNITY_EDITOR
if (_capiHmd == null)
if (_capiHmd == null)
{
{
IntPtr hmdPtr = IntPtr.Zero;
IntPtr hmdPtr = IntPtr.Zero;
OVR_GetHMD(ref hmdPtr);
OVR_GetHMD(ref hmdPtr);
_capiHmd = (hmdPtr != IntPtr.Zero) ? new Hmd(hmdPtr) : null;
_capiHmd = (hmdPtr != IntPtr.Zero) ? new Hmd(hmdPtr) : null;
}
}
#else
#else
_capiHmd = null;
_capiHmd = null;
#endif
#endif
return _capiHmd;
return _capiHmd;
}
}
}
}
/// <summary>
/// <summary>
/// Gets a reference to the active OVRDisplay
/// Gets a reference to the active OVRDisplay
/// </summary>
/// </summary>
public static OVRDisplay display { get; private set; }
public static OVRDisplay display { get; private set; }
/// <summary>
/// <summary>
/// Gets a reference to the active OVRTracker
/// Gets a reference to the active OVRTracker
/// </summary>
/// </summary>
public static OVRTracker tracker { get; private set; }
public static OVRTracker tracker { get; private set; }
/// <summary>
/// <summary>
/// Gets the current profile, which contains information about the user's settings and body dimensions.
/// Gets the current profile, which contains information about the user's settings and body dimensions.
/// </summary>
/// </summary>
private static bool _profileIsCached = false;
private static bool _profileIsCached = false;
private static Profile _profile;
private static Profile _profile;
public static Profile profile
public static Profile profile
{
{
get {
get {
if (!_profileIsCached)
if (!_profileIsCached)
{
{
#if !UNITY_ANDROID || UNITY_EDITOR
#if !UNITY_ANDROID || UNITY_EDITOR
float ipd = capiHmd.GetFloat(Hmd.OVR_KEY_IPD, Hmd.OVR_DEFAULT_IPD);
float ipd = capiHmd.GetFloat(Hmd.OVR_KEY_IPD, Hmd.OVR_DEFAULT_IPD);
float eyeHeight = capiHmd.GetFloat(Hmd.OVR_KEY_EYE_HEIGHT, Hmd.OVR_DEFAULT_EYE_HEIGHT);
float eyeHeight = capiHmd.GetFloat(Hmd.OVR_KEY_EYE_HEIGHT, Hmd.OVR_DEFAULT_EYE_HEIGHT);
float[] defaultOffset = new float[] { Hmd.OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL, Hmd.OVR_DEFAULT_NECK_TO_EYE_VERTICAL };
float[] defaultOffset = new float[] { Hmd.OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL, Hmd.OVR_DEFAULT_NECK_TO_EYE_VERTICAL };
float[] neckToEyeOffset = capiHmd.GetFloatArray(Hmd.OVR_KEY_NECK_TO_EYE_DISTANCE, defaultOffset);
float[] neckToEyeOffset = capiHmd.GetFloatArray(Hmd.OVR_KEY_NECK_TO_EYE_DISTANCE, defaultOffset);
float neckHeight = eyeHeight - neckToEyeOffset[1];
float neckHeight = eyeHeight - neckToEyeOffset[1];
_profile = new Profile
_profile = new Profile
{
{
ipd = ipd,
ipd = ipd,
eyeHeight = eyeHeight,
eyeHeight = eyeHeight,
eyeDepth = neckToEyeOffset[0],
eyeDepth = neckToEyeOffset[0],
neckHeight = neckHeight,
neckHeight = neckHeight,
};
};
#else
#else
float ipd = 0.0f;
float ipd = 0.0f;
OVR_GetInterpupillaryDistance(ref ipd);
OVR_GetInterpupillaryDistance(ref ipd);
float eyeHeight = 0.0f;
float eyeHeight = 0.0f;
OVR_GetPlayerEyeHeight(ref eyeHeight);
OVR_GetPlayerEyeHeight(ref eyeHeight);
_profile = new Profile
_profile = new Profile
{
{
ipd = ipd,
ipd = ipd,
eyeHeight = eyeHeight,
eyeHeight = eyeHeight,
eyeDepth = 0f, //TODO
eyeDepth = 0f, //TODO
neckHeight = 0.0f, // TODO
neckHeight = 0.0f, // TODO
};
};
#endif
#endif
_profileIsCached = true;
_profileIsCached = true;
}
}
return _profile;
return _profile;
}
}
}
}
/// <summary>
/// <summary>
/// Occurs when an HMD attached.
/// Occurs when an HMD attached.
/// </summary>
/// </summary>
public static event Action HMDAcquired;
public static event Action HMDAcquired;
/// <summary>
/// <summary>
/// Occurs when an HMD detached.
/// Occurs when an HMD detached.
/// </summary>
/// </summary>
public static event Action HMDLost;
public static event Action HMDLost;
/// <summary>
/// <summary>
/// Occurs when the tracker gained tracking.
/// Occurs when the tracker gained tracking.
/// </summary>
/// </summary>
public static event Action TrackingAcquired;
public static event Action TrackingAcquired;
/// <summary>
/// <summary>
/// Occurs when the tracker lost tracking.
/// Occurs when the tracker lost tracking.
/// </summary>
/// </summary>
public static event Action TrackingLost;
public static event Action TrackingLost;
/// <summary>
/// <summary>
/// Occurs when HSW dismissed.
/// Occurs when HSW dismissed.
/// </summary>
/// </summary>
public static event Action HSWDismissed;
public static event Action HSWDismissed;
/// <summary>
/// <summary>
/// If true, then the Oculus health and safety warning (HSW) is currently visible.
/// If true, then the Oculus health and safety warning (HSW) is currently visible.
/// </summary>
/// </summary>
public static bool isHSWDisplayed
public static bool isHSWDisplayed
{
{
get {
get {
#if !UNITY_ANDROID || UNITY_EDITOR
#if !UNITY_ANDROID || UNITY_EDITOR
return capiHmd.GetHSWDisplayState().Displayed;
return capiHmd.GetHSWDisplayState().Displayed;
#else
#else
return false;
return false;
#endif
#endif
}
}
}
}
/// <summary>
/// <summary>
/// If the HSW has been visible for the necessary amount of time, this will make it disappear.
/// If the HSW has been visible for the necessary amount of time, this will make it disappear.
/// </summary>
/// </summary>
public static void DismissHSWDisplay()
public static void DismissHSWDisplay()
{
{
#if !UNITY_ANDROID || UNITY_EDITOR
#if !UNITY_ANDROID || UNITY_EDITOR
capiHmd.DismissHSWDisplay();
capiHmd.DismissHSWDisplay();
#endif
#endif
}
}
/// <summary>
/// <summary>
/// Gets the current battery level.
/// Gets the current battery level.
/// </summary>
/// </summary>
/// <returns><c>battery level in the range [0.0,1.0]</c>
/// <returns><c>battery level in the range [0.0,1.0]</c>
/// <param name="batteryLevel">Battery level.</param>
/// <param name="batteryLevel">Battery level.</param>
public static float batteryLevel
public static float batteryLevel
{
{
get {
get {
#if !UNITY_ANDROID || UNITY_EDITOR
#if !UNITY_ANDROID || UNITY_EDITOR
return 1.0f;
return 1.0f;
#else
#else
return OVR_GetBatteryLevel();
return OVR_GetBatteryLevel();
#endif
#endif
}
}
}
}
/// <summary>
/// <summary>
/// Gets the current battery temperature.
/// Gets the current battery temperature.
/// </summary>
/// </summary>
/// <returns><c>battery temperature in Celsius</c>
/// <returns><c>battery temperature in Celsius</c>
/// <param name="batteryTemperature">Battery temperature.</param>
/// <param name="batteryTemperature">Battery temperature.</param>
public static float batteryTemperature
public static float batteryTemperature
{
{
get {
get {
#if !UNITY_ANDROID || UNITY_EDITOR
#if !UNITY_ANDROID || UNITY_EDITOR
return 0.0f;
return 0.0f;
#else
#else
return OVR_GetBatteryTemperature();
return OVR_GetBatteryTemperature();
#endif
#endif
}
}
}
}
/// <summary>
/// <summary>
/// Gets the current battery status.
/// Gets the current battery status.
/// </summary>
/// </summary>
/// <returns><c>battery status</c>
/// <returns><c>battery status</c>
/// <param name="batteryStatus">Battery status.</param>
/// <param name="batteryStatus">Battery status.</param>
public static int batteryStatus
public static int batteryStatus
{
{
get {
get {
#if !UNITY_ANDROID || UNITY_EDITOR
#if !UNITY_ANDROID || UNITY_EDITOR
return 0;
return 0;
#else
#else
return OVR_GetBatteryStatus();
return OVR_GetBatteryStatus();
#endif
#endif
}
}
}
}
/// <summary>
/// <summary>
/// Controls the size of the eye textures.
/// Controls the size of the eye textures.
/// Values must be above 0.
/// Values must be above 0.
/// Values below 1 permit sub-sampling for improved performance.
/// Values below 1 permit sub-sampling for improved performance.
/// Values above 1 permit super-sampling for improved sharpness.
/// Values above 1 permit super-sampling for improved sharpness.
/// </summary>
/// </summary>
public float nativeTextureScale = 1.0f;
public float nativeTextureScale = 1.0f;
/// <summary>
/// <summary>
/// Controls the size of the rendering viewport.
/// Controls the size of the rendering viewport.
/// Values must be between 0 and 1.
/// Values must be between 0 and 1.
/// Values below 1 permit dynamic sub-sampling for improved performance.
/// Values below 1 permit dynamic sub-sampling for improved performance.
/// </summary>
/// </summary>
public float virtualTextureScale = 1.0f;
public float virtualTextureScale = 1.0f;
/// <summary>
/// <summary>
/// If true, head tracking will affect the orientation of each OVRCameraRig's cameras.
/// If true, head tracking will affect the orientation of each OVRCameraRig's cameras.
/// </summary>
/// </summary>
public bool usePositionTracking = true;
public bool usePositionTracking = true;
/// <summary>
/// <summary>
/// The format of each eye texture.
/// The format of each eye texture.
/// </summary>
/// </summary>
public RenderTextureFormat eyeTextureFormat = RenderTextureFormat.Default;
public RenderTextureFormat eyeTextureFormat = RenderTextureFormat.Default;
/// <summary>
/// <summary>
/// The depth of each eye texture in bits.
/// The depth of each eye texture in bits.
/// </summary>
/// </summary>
public int eyeTextureDepth = 24;
public int eyeTextureDepth = 24;
/// <summary>
/// <summary>
/// If true, TimeWarp will be used to correct the output of each OVRCameraRig for rotational latency.
/// If true, TimeWarp will be used to correct the output of each OVRCameraRig for rotational latency.
/// </summary>
/// </summary>
public bool timeWarp = true;
public bool timeWarp = true;
/// <summary>
/// <summary>
/// If this is true and TimeWarp is true, each OVRCameraRig will stop tracking and only TimeWarp will respond to head motion.
/// If this is true and TimeWarp is true, each OVRCameraRig will stop tracking and only TimeWarp will respond to head motion.
/// </summary>
/// </summary>
public bool freezeTimeWarp = false;
public bool freezeTimeWarp = false;
/// <summary>
/// <summary>
/// If true, each scene load will cause the head pose to reset.
/// If true, each scene load will cause the head pose to reset.
/// </summary>
/// </summary>
public bool resetTrackerOnLoad = true;
public bool resetTrackerOnLoad = true;
/// <summary>
/// <summary>
/// If true, the eyes see the same image, which is rendered only by the left camera.
/// If true, the eyes see the same image, which is rendered only by the left camera.
/// </summary>
/// </summary>
public bool monoscopic = false;
public bool monoscopic = false;
/// <summary>
/// <summary>
/// True if the current platform supports virtual reality.
/// True if the current platform supports virtual reality.
/// </summary>
/// </summary>
public bool isSupportedPlatform { get; private set; }
public bool isSupportedPlatform { get; private set; }
private static bool usingPositionTracking = false;
private static bool usingPositionTracking = false;
private static bool wasHmdPresent = false;
private static bool wasHmdPresent = false;
private static bool wasPositionTracked = false;
private static bool wasPositionTracked = false;
private static WaitForEndOfFrame waitForEndOfFrame = new WaitForEndOfFrame();
private static WaitForEndOfFrame waitForEndOfFrame = new WaitForEndOfFrame();
#if UNITY_ANDROID && !UNITY_EDITOR
#if UNITY_ANDROID && !UNITY_EDITOR
// Get this from Unity on startup so we can call Activity java functions
// Get this from Unity on startup so we can call Activity java functions
private static bool androidJavaInit = false;
private static bool androidJavaInit = false;
private static AndroidJavaObject activity;
private static AndroidJavaObject activity;
private static AndroidJavaClass javaVrActivityClass;
private static AndroidJavaClass javaVrActivityClass;
internal static int timeWarpViewNumber = 0;
internal static int timeWarpViewNumber = 0;
public static event Action OnCustomPostRender;
public static event Action OnCustomPostRender;
#else
#else
private static bool ovrIsInitialized;
private static bool ovrIsInitialized;
private static bool isQuitting;
private static bool isQuitting;
#endif
#endif
public static bool isPaused
public static bool isPaused
{
{
get { return _isPaused; }
get { return _isPaused; }
set
set
{
{
#if UNITY_ANDROID && !UNITY_EDITOR
#if UNITY_ANDROID && !UNITY_EDITOR
RenderEventType eventType = (value) ? RenderEventType.Pause : RenderEventType.Resume;
RenderEventType eventType = (value) ? RenderEventType.Pause : RenderEventType.Resume;
OVRPluginEvent.Issue(eventType);
OVRPluginEvent.Issue(eventType);
#endif
#endif
_isPaused = value;
_isPaused = value;
}
}
}
}
private static bool _isPaused;
private static bool _isPaused;
#region Unity Messages
#region Unity Messages
private void InternalCheckInit()
{
if (!ovrIsInitialized)
{
OVR_Initialize();
OVRPluginEvent.Issue(RenderEventType.Initialize);
ovrIsInitialized = true;
}
}
private void Awake()
private void Awake()
{
{
// Only allow one instance at runtime.
// Only allow one instance at runtime.
if (instance != null)
if (instance != null)
{
{
enabled = false;
enabled = false;
DestroyImmediate(this);
DestroyImmediate(this);
return;
return;
}
}
instance = this;
instance = this;
#if !UNITY_ANDROID || UNITY_EDITOR
#if !UNITY_ANDROID || UNITY_EDITOR
if (!ovrIsInitialized)
InternalCheckInit();
{
OVR_Initialize();
OVRPluginEvent.Issue(RenderEventType.Initialize);
ovrIsInitialized = true;
}
var netVersion = new System.Version(Ovr.Hmd.OVR_VERSION_STRING);
var netVersion = new System.Version(Ovr.Hmd.OVR_VERSION_STRING);
var ovrVersion = new System.Version(Ovr.Hmd.GetVersionString());
var ovrVersion = new System.Version(Ovr.Hmd.GetVersionString());
if (netVersion > ovrVersion)
if (netVersion > ovrVersion)
Debug.LogWarning("Using an older version of LibOVR.");
Debug.LogWarning("Using an older version of LibOVR.");
#endif
#endif
// Detect whether this platform is a supported platform
// Detect whether this platform is a supported platform
RuntimePlatform currPlatform = Application.platform;
RuntimePlatform currPlatform = Application.platform;
isSupportedPlatform |= currPlatform == RuntimePlatform.Android;
isSupportedPlatform |= currPlatform == RuntimePlatform.Android;
isSupportedPlatform |= currPlatform == RuntimePlatform.LinuxPlayer;
isSupportedPlatform |= currPlatform == RuntimePlatform.LinuxPlayer;
isSupportedPlatform |= currPlatform == RuntimePlatform.OSXEditor;
isSupportedPlatform |= currPlatform == RuntimePlatform.OSXEditor;
isSupportedPlatform |= currPlatform == RuntimePlatform.OSXPlayer;
isSupportedPlatform |= currPlatform == RuntimePlatform.OSXPlayer;
isSupportedPlatform |= currPlatform == RuntimePlatform.WindowsEditor;
isSupportedPlatform |= currPlatform == RuntimePlatform.WindowsEditor;
isSupportedPlatform |= currPlatform == RuntimePlatform.WindowsPlayer;
isSupportedPlatform |= currPlatform == RuntimePlatform.WindowsPlayer;
if (!isSupportedPlatform)
if (!isSupportedPlatform)
{
{
Debug.LogWarning("This platform is unsupported");
Debug.LogWarning("This platform is unsupported");
return;
return;
}
}
#if UNITY_ANDROID && !UNITY_EDITOR
#if UNITY_ANDROID && !UNITY_EDITOR
Application.targetFrameRate = 60;
Application.targetFrameRate = 60;
// don't allow the app to run in the background
// don't allow the app to run in the background
Application.runInBackground = false;
Application.runInBackground = false;
// Disable screen dimming
// Disable screen dimming
Screen.sleepTimeout = SleepTimeout.NeverSleep;
Screen.sleepTimeout = SleepTimeout.NeverSleep;
if (!androidJavaInit)
if (!androidJavaInit)
{
{
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
javaVrActivityClass = new AndroidJavaClass("com.oculusvr.vrlib.VrActivity");
javaVrActivityClass = new AndroidJavaClass("com.oculusvr.vrlib.VrActivity");
// Prepare for the RenderThreadInit()
// Prepare for the RenderThreadInit()
SetInitVariables(activity.GetRawObject(), javaVrActivityClass.GetRawClass());
SetInitVariables(activity.GetRawObject(), javaVrActivityClass.GetRawClass());
androidJavaInit = true;
androidJavaInit = true;
}
}
// We want to set up our touchpad messaging system
// We want to set up our touchpad messaging system
OVRTouchpad.Create();
OVRTouchpad.Create();
// This will trigger the init on the render thread
// This will trigger the init on the render thread
InitRenderThread();
InitRenderThread();
#else
#else
SetEditorPlay(Application.isEditor);
SetEditorPlay(Application.isEditor);
#endif
#endif
if (display == null)
if (display == null)
display = new OVRDisplay();
display = new OVRDisplay();
if (tracker == null)
if (tracker == null)
tracker = new OVRTracker();
tracker = new OVRTracker();
if (resetTrackerOnLoad)
if (resetTrackerOnLoad)
display.RecenterPose();
display.RecenterPose();
// Except for D3D9, SDK rendering forces vsync unless you pass ovrHmdCap_NoVSync to Hmd.SetEnabledCaps().
// Except for D3D9, SDK rendering forces vsync unless you pass ovrHmdCap_NoVSync to Hmd.SetEnabledCaps().
if (timeWarp)
if (timeWarp)
{
{
bool useUnityVSync = SystemInfo.graphicsDeviceVersion.Contains("Direct3D 9");
bool useUnityVSync = SystemInfo.graphicsDeviceVersion.Contains("Direct3D 9");
QualitySettings.vSyncCount = useUnityVSync ? 1 : 0;
QualitySettings.vSyncCount = useUnityVSync ? 1 : 0;
}
}
#if (UNITY_STANDALONE_WIN && (UNITY_4_6 || UNITY_4_5))
#if (UNITY_STANDALONE_WIN && (UNITY_4_6 || UNITY_4_5))
bool unity_4_6 = false;
bool unity_4_6 = false;
bool unity_4_5_2 = false;
bool unity_4_5_2 = false;
bool unity_4_5_3 = false;
bool unity_4_5_3 = false;
bool unity_4_5_4 = false;
bool unity_4_5_4 = false;
bool unity_4_5_5 = false;
bool unity_4_5_5 = false;
#if (UNITY_4_6)
#if (UNITY_4_6)
unity_4_6 = true;
unity_4_6 = true;
#elif (UNITY_4_5_2)
#elif (UNITY_4_5_2)
unity_4_5_2 = true;
unity_4_5_2 = true;
#elif (UNITY_4_5_3)
#elif (UNITY_4_5_3)
unity_4_5_3 = true;
unity_4_5_3 = true;
#elif (UNITY_4_5_4)
#elif (UNITY_4_5_4)
unity_4_5_4 = true;
unity_4_5_4 = true;
#elif (UNITY_4_5_5)
#elif (UNITY_4_5_5)
unity_4_5_5 = true;
unity_4_5_5 = true;
#endif
#endif
// Detect correct Unity releases which contain the fix for D3D11 exclusive mode.
// Detect correct Unity releases which contain the fix for D3D11 exclusive mode.
string version = Application.unityVersion;
string version = Application.unityVersion;
int releaseNumber;
int releaseNumber;
bool releaseNumberFound = Int32.TryParse(Regex.Match(version, @"\d+$").Value, out releaseNumber);
bool releaseNumberFound = Int32.TryParse(Regex.Match(version, @"\d+$").Value, out releaseNumber);
// Exclusive mode was broken for D3D9 in Unity 4.5.2p2 - 4.5.4 and 4.6 builds prior to beta 21
// Exclusive mode was broken for D3D9 in Unity 4.5.2p2 - 4.5.4 and 4.6 builds prior to beta 21
bool unsupportedExclusiveModeD3D9 = (unity_4_6 && version.Last(char.IsLetter) == 'b' && releaseNumberFound && releaseNumber < 21)
bool unsupportedExclusiveModeD3D9 = (unity_4_6 && version.Last(char.IsLetter) == 'b' && releaseNumberFound && releaseNumber < 21)
|| (unity_4_5_2 && version.Last(char.IsLetter) == 'p' && releaseNumberFound && releaseNumber >= 2)
|| (unity_4_5_2 && version.Last(char.IsLetter) == 'p' && releaseNumberFound && releaseNumber >= 2)
|| (unity_4_5_3)
|| (unity_4_5_3)
|| (unity_4_5_4);
|| (unity_4_5_4);
// Exclusive mode was broken for D3D11 in Unity 4.5.2p2 - 4.5.5p2 and 4.6 builds prior to f1
// Exclusive mode was broken for D3D11 in Unity 4.5.2p2 - 4.5.5p2 and 4.6 builds prior to f1
bool unsupportedExclusiveModeD3D11 = (unity_4_6 && version.Last(char.IsLetter) == 'b')
bool unsupportedExclusiveModeD3D11 = (unity_4_6 && version.Last(char.IsLetter) == 'b')
|| (unity_4_5_2 && version.Last(char.IsLetter) == 'p' && releaseNumberFound && releaseNumber >= 2)
|| (unity_4_5_2 && version.Last(char.IsLetter) == 'p' && releaseNumberFound && releaseNumber >= 2)
|| (unity_4_5_3)
|| (unity_4_5_3)
|| (unity_4_5_4)
|| (unity_4_5_4)
|| (unity_4_5_5 && version.Last(char.IsLetter) == 'f')
|| (unity_4_5_5 && version.Last(char.IsLetter) == 'f')
|| (unity_4_5_5 && version.Last(char.IsLetter) == 'p' && releaseNumberFound && releaseNumber < 3);
|| (unity_4_5_5 && version.Last(char.IsLetter) == 'p' && releaseNumberFound && releaseNumber < 3);
if (unsupportedExclusiveModeD3D9 && !display.isDirectMode && SystemInfo.graphicsDeviceVersion.Contains("Direct3D 9"))
if (unsupportedExclusiveModeD3D9 && !display.isDirectMode && SystemInfo.graphicsDeviceVersion.Contains("Direct3D 9"))
{
{
MessageBox(0, "Direct3D 9 extended mode is not supported in this configuration. "
MessageBox(0, "Direct3D 9 extended mode is not supported in this configuration. "
+ "Please use direct display mode, a different graphics API, or rebuild the application with a newer Unity version."
+ "Please use direct display mode, a different graphics API, or rebuild the application with a newer Unity version."
, "VR Configuration Warning", 0);
, "VR Configuration Warning", 0);
}
}
if (unsupportedExclusiveModeD3D11 && !display.isDirectMode && SystemInfo.graphicsDeviceVersion.Contains("Direct3D 11"))
if (unsupportedExclusiveModeD3D11 && !display.isDirectMode && SystemInfo.graphicsDeviceVersion.Contains("Direct3D 11"))
{
{
MessageBox(0, "Direct3D 11 extended mode is not supported in this configuration. "
MessageBox(0, "Direct3D 11 extended mode is not supported in this configuration. "
+ "Please use direct display mode, a different graphics API, or rebuild the application with a newer Unity version."
+ "Please use direct display mode, a different graphics API, or rebuild the application with a newer Unity version."
, "VR Configuration Warning", 0);
, "VR Configuration Warning", 0);
}
}
#endif
#endif
}
}
#if !UNITY_ANDROID || UNITY_EDITOR
#if !UNITY_ANDROID || UNITY_EDITOR
private void OnApplicationQuit()
private void OnApplicationQuit()
{
{
isQuitting = true;
isQuitting = true;
}
}
private bool reCallback = false;
private void OnEnable()
{
InternalCheckInit();
reCallback = true;
}
private void OnDisable()
private void OnDisable()
{
{
if (!isQuitting)
if (!isQuitting)
return;
return;
if (ovrIsInitialized)
if (ovrIsInitialized)
{
{
OVR_Destroy();
OVR_Destroy();
OVRPluginEvent.Issue(RenderEventType.Destroy);
OVRPluginEvent.Issue(RenderEventType.Destroy);
_capiHmd = null;
_capiHmd = null;
ovrIsInitialized = false;
ovrIsInitialized = false;
}
}
}
}
#endif
#endif
private void Start()
private void Start()
{
{
#if !UNITY_ANDROID || UNITY_EDITOR
#if !UNITY_ANDROID || UNITY_EDITOR
Camera cam = GetComponent<Camera>();
Camera cam = GetComponent<Camera>();
if (cam == null)
if (cam == null)
{
{
// Ensure there is a non-RT camera in the scene to force rendering of the left and right eyes.
// Ensure there is a non-RT camera in the scene to force rendering of the left and right eyes.
cam = gameObject.AddComponent<Camera>();
cam = gameObject.AddComponent<Camera>();
cam.cullingMask = 0;
cam.cullingMask = 0;
cam.clearFlags = CameraClearFlags.SolidColor;
cam.clearFlags = CameraClearFlags.SolidColor;
cam.backgroundColor = new Color(0.0f, 0.0f, 0.0f);
cam.backgroundColor = new Color(0.0f, 0.0f, 0.0f);
cam.renderingPath = RenderingPath.Forward;
cam.renderingPath = RenderingPath.Forward;
cam.orthographic = true;
cam.orthographic = true;
cam.useOcclusionCulling = false;
cam.useOcclusionCulling = false;
}
}
#endif
#endif
bool isD3d = SystemInfo.graphicsDeviceVersion.Contains("Direct3D") ||
bool isD3d = SystemInfo.graphicsDeviceVersion.Contains("Direct3D") ||
Application.platform == RuntimePlatform.WindowsEditor &&
Application.platform == RuntimePlatform.WindowsEditor &&
SystemInfo.graphicsDeviceVersion.Contains("emulated");
SystemInfo.graphicsDeviceVersion.Contains("emulated");
display.flipInput = isD3d;
display.flipInput = isD3d;
StartCoroutine(CallbackCoroutine());
}
}
private void Update()
private void Update()
{
{
if (usePositionTracking != usingPositionTracking)
if (ovrIsInitialized) {
{
if (reCallback)
tracker.isEnabled = usePositionTracking;
{
usingPositionTracking = usePositionTracking;
reCallback = false;
}
StartCoroutine(CallbackCoroutine());
}
else
{
if (usePositionTracking != usingPositionTracking)
{
tracker.isEnabled = usePositionTracking;
usingPositionTracking = usePositionTracking;
}
// Dispatch any events.
if (HMDLost != null && wasHmdPresent && !display.isPresent)
HMDLost();
// Dispatch any events.
if (HMDAcquired != null && !wasHmdPresent && display.isPresent)
if (HMDLost != null && wasHmdPresent && !display.isPresent)
HMDAcquired();
HMDLost();
if (HMDAcquired != null && !wasHmdPresent && display.isPresent)
wasHmdPresent = display.isPresent;
HMDAcquired();
wasHmdPresent = display.isPresent;
if (TrackingLost != null && wasPositionTracked && !tracker.isPositionTracked)
TrackingLost();
if (TrackingLost != null && wasPositionTracked && !tracker.isPositionTracked)
if (TrackingAcquired != null && !wasPositionTracked && tracker.isPositionTracked)
TrackingLost();
TrackingAcquired();
wasPositionTracked = tracker.isPositionTracked;
if (isHSWDisplayed && Input.anyKeyDown)
{
DismissHSWDisplay();
if (TrackingAcquired != null && !wasPositionTracked && tracker.isPositionTracked)
if (HSWDismissed != null)
TrackingAcquired();
HSWDismissed();
}
wasPositionTracked = tracker.isPositionTracked;
display.timeWarp = timeWarp;
if (isHSWDisplayed && Input.anyKeyDown)
{
DismissHSWDisplay();
if (HSWDismissed != null)
HSWDismissed();
}
display.timeWarp = timeWarp;
#if (!UNITY_ANDROID || UNITY_EDITOR)
#if (!UNITY_ANDROID || UNITY_EDITOR)
display.Update();
display.Update();
#endif
#endif
}
}
}
}
#if (UNITY_EDITOR_OSX)
#if (UNITY_EDITOR_OSX)
private void OnPreCull() // TODO: Fix Mac Unity Editor memory corruption issue requiring OnPreCull workaround.
private void OnPreCull() // TODO: Fix Mac Unity Editor memory corruption issue requiring OnPreCull workaround.
#else
#else
private void LateUpdate()
private void LateUpdate()
#endif
#endif
{
{
#if (!UNITY_ANDROID || UNITY_EDITOR)
#if (!UNITY_ANDROID || UNITY_EDITOR)
display.BeginFrame();
display.BeginFrame();
#endif
#endif
}
}
private IEnumerator CallbackCoroutine()
private IEnumerator CallbackCoroutine()
{
{
while (true)
while (true)
{
{
yield return waitForEndOfFrame;
yield return waitForEndOfFrame;
#if UNITY_ANDROID && !UNITY_EDITOR
#if UNITY_ANDROID && !UNITY_EDITOR
OVRManager.DoTimeWarp(timeWarpViewNumber);
OVRManager.DoTimeWarp(timeWarpViewNumber);
#else
#else
display.EndFrame();
display.EndFrame();
#endif
#endif
}
}
}
}
#if UNITY_ANDROID && !UNITY_EDITOR
#if UNITY_ANDROID && !UNITY_EDITOR
private void OnPause()
private void OnPause()
{
{
isPaused = true;
isPaused = true;
}
}
private void OnApplicationPause(bool pause)
private void OnApplicationPause(bool pause)
{
{
Debug.Log("OnApplicationPause() " + pause);
Debug.Log("OnApplicationPause() " + pause);
if (pause)
if (pause)
{
{
OnPause();
OnPause();
}
}
else
else
{
{
StartCoroutine(OnResume());
StartCoroutine(OnResume());
}
}
}
}
void OnDisable()
void OnDisable()
{
{
StopAllCoroutines();
StopAllCoroutines();
}
}
private IEnumerator OnResume()
private IEnumerator OnResume()
{
{
yield return null; // delay 1 frame to allow Unity enough time to create the windowSurface
yield return null; // delay 1 frame to allow Unity enough time to create the windowSurface
isPaused = false;
isPaused = false;
}
}
/// <summary>
/// <summary>
/// Leaves the application/game and returns to the launcher/dashboard
/// Leaves the application/game and returns to the launcher/dashboard
/// </summary>
/// </summary>
public void ReturnToLauncher()
public void ReturnToLauncher()
{
{
// show the platform UI quit prompt
// show the platform UI quit prompt
OVRManager.PlatformUIConfirmQuit();
OVRManager.PlatformUIConfirmQuit();
}
}
private void OnPostRender()
private void OnPostRender()
{
{
// Allow custom code to render before we kick off the plugin
// Allow custom code to render before we kick off the plugin
if (OnCustomPostRender != null)
if (OnCustomPostRender != null)
{
{
OnCustomPostRender();
OnCustomPostRender();
}
}
EndEye(OVREye.Left, display.GetEyeTextureId(OVREye.Left));
EndEye(OVREye.Left, display.GetEyeTextureId(OVREye.Left));
EndEye(OVREye.Right, display.GetEyeTextureId(OVREye.Right));
EndEye(OVREye.Right, display.GetEyeTextureId(OVREye.Right));
}
}
#endif
#endif
#endregion
#endregion
public static void SetEditorPlay(bool isEditor)
public static void SetEditorPlay(bool isEditor)
{
{
#if !UNITY_ANDROID || UNITY_EDITOR
#if !UNITY_ANDROID || UNITY_EDITOR
OVR_SetEditorPlay(isEditor);
OVR_SetEditorPlay(isEditor);
#endif
#endif
}
}
public static void SetDistortionCaps(uint distortionCaps)
public static void SetDistortionCaps(uint distortionCaps)
{
{
#if !UNITY_ANDROID || UNITY_EDITOR
#if !UNITY_ANDROID || UNITY_EDITOR
OVR_SetDistortionCaps(distortionCaps);
OVR_SetDistortionCaps(distortionCaps);
#endif
#endif
}
}
public static void SetInitVariables(IntPtr activity, IntPtr vrActivityClass)
public static void SetInitVariables(IntPtr activity, IntPtr vrActivityClass)
{
{
#if UNITY_ANDROID && !UNITY_EDITOR
#if UNITY_ANDROID && !UNITY_EDITOR
OVR_SetInitVariables(activity, vrActivityClass);
OVR_SetInitVariables(activity, vrActivityClass);
#endif
#endif
}
}
public static void PlatformUIConfirmQuit()
public static void PlatformUIConfirmQuit()
{
{
#if UNITY_ANDROID && !UNITY_EDITOR
#if UNITY_ANDROID && !UNITY_EDITOR
OVRPluginEvent.Issue(RenderEventType.PlatformUIConfirmQuit);
OVRPluginEvent.Issue(RenderEventType.PlatformUIConfirmQuit);
#endif
#endif
}
}
public static void PlatformUIGlobalMenu()
public static void PlatformUIGlobalMenu()
{
{
#if UNITY_ANDROID && !UNITY_EDITOR
#if UNITY_ANDROID && !UNITY_EDITOR
OVRPluginEvent.Issue(RenderEventType.PlatformUI);
OVRPluginEvent.Issue(RenderEventType.PlatformUI);
#endif
#endif
}
}
public static void DoTimeWarp(int timeWarpViewNumber)
public static void DoTimeWarp(int timeWarpViewNumber)
{
{
#if UNITY_ANDROID && !UNITY_EDITOR
#if UNITY_ANDROID && !UNITY_EDITOR
OVRPluginEvent.IssueWithData(RenderEventType.TimeWarp, timeWarpViewNumber);
OVRPluginEvent.IssueWithData(RenderEventType.TimeWarp, timeWarpViewNumber);
#endif
#endif
}
}
public static void EndEye(OVREye eye, int eyeTextureId)
public static void EndEye(OVREye eye, int eyeTextureId)
{
{
#if UNITY_ANDROID && !UNITY_EDITOR
#if UNITY_ANDROID && !UNITY_EDITOR
RenderEventType eventType = (eye == OVREye.Left) ?
RenderEventType eventType = (eye == OVREye.Left) ?
RenderEventType.LeftEyeEndFrame :
RenderEventType.LeftEyeEndFrame :
RenderEventType.RightEyeEndFrame;
RenderEventType.RightEyeEndFrame;
OVRPluginEvent.IssueWithData(eventType, eyeTextureId);
OVRPluginEvent.IssueWithData(eventType, eyeTextureId);
#endif
#endif
}
}
public static void InitRenderThread()
public static void InitRenderThread()
{
{
#if UNITY_ANDROID && !UNITY_EDITOR
#if UNITY_ANDROID && !UNITY_EDITOR
OVRPluginEvent.Issue(RenderEventType.InitRenderThread);
OVRPluginEvent.Issue(RenderEventType.InitRenderThread);
#endif
#endif
}
}
private const string LibOVR = "OculusPlugin";
private const string LibOVR = "OculusPlugin";
#if !UNITY_ANDROID || UNITY_EDITOR
#if !UNITY_ANDROID || UNITY_EDITOR
[DllImport(LibOVR, CallingConvention = CallingConvention.Cdecl)]
[DllImport(LibOVR, CallingConvention = CallingConvention.Cdecl)]
private static extern void OVR_GetHMD(ref IntPtr hmdPtr);
private static extern void OVR_GetHMD(ref IntPtr hmdPtr);
[DllImport(LibOVR, CallingConvention = CallingConvention.Cdecl)]
[DllImport(LibOVR, CallingConvention = CallingConvention.Cdecl)]
private static extern void OVR_SetEditorPlay(bool isEditorPlay);
private static extern void OVR_SetEditorPlay(bool isEditorPlay);
[DllImport(LibOVR, CallingConvention = CallingConvention.Cdecl)]
[DllImport(LibOVR, CallingConvention = CallingConvention.Cdecl)]
private static extern void OVR_SetDistortionCaps(uint distortionCaps);
private static extern void OVR_SetDistortionCaps(uint distortionCaps);
[DllImport(LibOVR, CallingConvention = CallingConvention.Cdecl)]
[DllImport(LibOVR, CallingConvention = CallingConvention.Cdecl)]
private static extern void OVR_Initialize();
private static extern void OVR_Initialize();
[DllImport(LibOVR, CallingConvention = CallingConvention.Cdecl)]
[DllImport(LibOVR, CallingConvention = CallingConvention.Cdecl)]
private static extern void OVR_Destroy();
private static extern void OVR_Destroy();
#if UNITY_STANDALONE_WIN
#if UNITY_STANDALONE_WIN
[DllImport("user32", EntryPoint = "MessageBoxA", CharSet = CharSet.Ansi)]
[DllImport("user32", EntryPoint = "MessageBoxA", CharSet = CharSet.Ansi)]
public static extern bool MessageBox(int hWnd,
public static extern bool MessageBox(int hWnd,
[MarshalAs(UnmanagedType.LPStr)]string text,
[MarshalAs(UnmanagedType.LPStr)]string text,
[MarshalAs(UnmanagedType.LPStr)]string caption, uint type);
[MarshalAs(UnmanagedType.LPStr)]string caption, uint type);
#endif
#endif
#else
#else
[DllImport(LibOVR)]
[DllImport(LibOVR)]
private static extern void OVR_SetInitVariables(IntPtr activity, IntPtr vrActivityClass);
private static extern void OVR_SetInitVariables(IntPtr activity, IntPtr vrActivityClass);
[DllImport(LibOVR)]
[DllImport(LibOVR)]
private static extern float OVR_GetBatteryLevel();
private static extern float OVR_GetBatteryLevel();
[DllImport(LibOVR)]
[DllImport(LibOVR)]
private static extern int OVR_GetBatteryStatus();
private static extern int OVR_GetBatteryStatus();
[DllImport(LibOVR)]
[DllImport(LibOVR)]
private static extern float OVR_GetBatteryTemperature();
private static extern float OVR_GetBatteryTemperature();
[DllImport(LibOVR)]
[DllImport(LibOVR)]
private static extern bool OVR_GetPlayerEyeHeight(ref float eyeHeight);
private static extern bool OVR_GetPlayerEyeHeight(ref float eyeHeight);
[DllImport(LibOVR)]
[DllImport(LibOVR)]
private static extern bool OVR_GetInterpupillaryDistance(ref float interpupillaryDistance);
private static extern bool OVR_GetInterpupillaryDistance(ref float interpupillaryDistance);
#endif
#endif
}
}