mirror of
https://github.com/donl/brainvr.git
synced 2026-05-26 22:06:24 -06:00
243 lines
7.6 KiB
C#
243 lines
7.6 KiB
C#
// Copyright 2015 Google Inc. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// 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_EDITOR
|
|
#if UNITY_ANDROID
|
|
#define ANDROID_DEVICE
|
|
#elif UNITY_IPHONE
|
|
#define IPHONE_DEVICE
|
|
#endif
|
|
#endif
|
|
|
|
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
using System.Text.RegularExpressions;
|
|
using System;
|
|
|
|
// Represents a vr device that this plugin interacts with.
|
|
// Please do not interact with this class directly, instead use the interface in Cardboard.cs.
|
|
public abstract class BaseVRDevice {
|
|
private static BaseVRDevice device = null;
|
|
|
|
protected BaseVRDevice() {
|
|
Profile = CardboardProfile.Default.Clone();
|
|
}
|
|
|
|
public CardboardProfile Profile { get; protected set; }
|
|
|
|
public abstract void Init();
|
|
|
|
public virtual bool SupportsNativeDistortionCorrection(List<string> diagnostics) {
|
|
bool support = true;
|
|
if (!SystemInfo.supportsRenderTextures) {
|
|
diagnostics.Add("RenderTexture (Unity Pro feature) is unavailable");
|
|
support = false;
|
|
}
|
|
if (!SupportsUnityRenderEvent()) {
|
|
diagnostics.Add("Unity 4.5+ is needed for UnityRenderEvent");
|
|
support = false;
|
|
}
|
|
return support;
|
|
}
|
|
|
|
public virtual bool SupportsNativeUILayer(List<string> diagnostics) {
|
|
bool support = true;
|
|
if (!SupportsUnityRenderEvent()) {
|
|
diagnostics.Add("Unity 4.5+ is needed for UnityRenderEvent");
|
|
support = false;
|
|
}
|
|
return support;
|
|
}
|
|
|
|
public bool SupportsUnityRenderEvent() {
|
|
bool support = true;
|
|
if (Application.isMobilePlatform) {
|
|
try {
|
|
string version = new Regex(@"(\d+\.\d+)\..*").Replace(Application.unityVersion, "$1");
|
|
if (new Version(version) < new Version("4.5")) {
|
|
support = false;
|
|
}
|
|
} catch {
|
|
Debug.LogWarning("Unable to determine Unity version from: " + Application.unityVersion);
|
|
}
|
|
}
|
|
return support;
|
|
}
|
|
|
|
public virtual RenderTexture CreateStereoScreen() {
|
|
Debug.Log("Creating new default cardboard screen texture.");
|
|
return new RenderTexture(Screen.width, Screen.height, 16, RenderTextureFormat.RGB565);
|
|
}
|
|
|
|
public abstract void SetDistortionCorrectionEnabled(bool enabled);
|
|
public abstract void SetVRModeEnabled(bool enabled);
|
|
public abstract void SetAlignmentMarkerEnabled(bool enabled);
|
|
public abstract void SetSettingsButtonEnabled(bool enabled);
|
|
public abstract void SetNeckModelScale(float scale);
|
|
public abstract void SetAutoDriftCorrectionEnabled(bool enabled);
|
|
|
|
public abstract void SetStereoScreen(RenderTexture stereoScreen);
|
|
|
|
public Pose3D GetHeadPose() {
|
|
return this.headPose;
|
|
}
|
|
protected MutablePose3D headPose = new MutablePose3D();
|
|
|
|
public Pose3D GetEyePose(Cardboard.Eye eye) {
|
|
switch(eye) {
|
|
case Cardboard.Eye.Left:
|
|
return leftEyePose;
|
|
case Cardboard.Eye.Right:
|
|
return rightEyePose;
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
protected MutablePose3D leftEyePose = new MutablePose3D();
|
|
protected MutablePose3D rightEyePose = new MutablePose3D();
|
|
|
|
public Matrix4x4 GetProjection(Cardboard.Eye eye,
|
|
Cardboard.Distortion distortion = Cardboard.Distortion.Distorted) {
|
|
switch(eye) {
|
|
case Cardboard.Eye.Left:
|
|
return distortion == Cardboard.Distortion.Distorted ?
|
|
leftEyeDistortedProjection : leftEyeUndistortedProjection;
|
|
case Cardboard.Eye.Right:
|
|
return distortion == Cardboard.Distortion.Distorted ?
|
|
rightEyeDistortedProjection : rightEyeUndistortedProjection;
|
|
default:
|
|
return Matrix4x4.identity;
|
|
}
|
|
}
|
|
protected Matrix4x4 leftEyeDistortedProjection;
|
|
protected Matrix4x4 rightEyeDistortedProjection;
|
|
protected Matrix4x4 leftEyeUndistortedProjection;
|
|
protected Matrix4x4 rightEyeUndistortedProjection;
|
|
|
|
public Rect GetViewport(Cardboard.Eye eye,
|
|
Cardboard.Distortion distortion = Cardboard.Distortion.Distorted) {
|
|
switch(eye) {
|
|
case Cardboard.Eye.Left:
|
|
return distortion == Cardboard.Distortion.Distorted ?
|
|
leftEyeDistortedViewport : leftEyeUndistortedViewport;
|
|
case Cardboard.Eye.Right:
|
|
return distortion == Cardboard.Distortion.Distorted ?
|
|
rightEyeDistortedViewport : rightEyeUndistortedViewport;
|
|
default:
|
|
return new Rect();
|
|
}
|
|
}
|
|
protected Rect leftEyeDistortedViewport;
|
|
protected Rect rightEyeDistortedViewport;
|
|
protected Rect leftEyeUndistortedViewport;
|
|
protected Rect rightEyeUndistortedViewport;
|
|
|
|
public bool triggered;
|
|
public bool tilted;
|
|
|
|
public abstract void UpdateState();
|
|
|
|
public abstract void UpdateScreenData();
|
|
|
|
public abstract void Recenter();
|
|
|
|
public abstract void PostRender(bool vrMode);
|
|
|
|
public virtual void SetTouchCoordinates(int x, int y) {
|
|
// Do nothing
|
|
}
|
|
|
|
public virtual void OnPause(bool pause) {
|
|
if (!pause) {
|
|
UpdateScreenData();
|
|
}
|
|
}
|
|
|
|
public virtual void OnFocus(bool focus) {
|
|
// Do nothing.
|
|
}
|
|
|
|
public virtual void Reset() {
|
|
Recenter();
|
|
}
|
|
|
|
public virtual void OnApplicationQuit() {
|
|
// Do nothing.
|
|
}
|
|
|
|
public virtual void Destroy() {
|
|
if (device == this) {
|
|
device = null;
|
|
}
|
|
}
|
|
|
|
// Helper functions.
|
|
protected void ComputeEyesFromProfile() {
|
|
// Compute left eye matrices from screen and device params
|
|
Matrix4x4 leftEyeView = Matrix4x4.identity;
|
|
leftEyeView[0, 3] = -Profile.device.lenses.separation / 2;
|
|
leftEyePose.Set(leftEyeView);
|
|
|
|
float[] rect = new float[4];
|
|
Profile.GetLeftEyeVisibleTanAngles(ref rect);
|
|
leftEyeDistortedProjection = MakeProjection(rect[0], rect[1], rect[2], rect[3], 1, 1000);
|
|
Profile.GetLeftEyeNoLensTanAngles(ref rect);
|
|
leftEyeUndistortedProjection = MakeProjection(rect[0], rect[1], rect[2], rect[3], 1, 1000);
|
|
|
|
leftEyeUndistortedViewport = Profile.GetLeftEyeVisibleScreenRect(rect);
|
|
leftEyeDistortedViewport = leftEyeUndistortedViewport;
|
|
|
|
// Right eye matrices same as left ones but for some sign flippage.
|
|
Matrix4x4 rightEyeView = leftEyeView;
|
|
rightEyeView[0, 3] *= -1;
|
|
rightEyePose.Set(rightEyeView);
|
|
|
|
rightEyeDistortedProjection = leftEyeDistortedProjection;
|
|
rightEyeDistortedProjection[0, 2] *= -1;
|
|
rightEyeUndistortedProjection = leftEyeUndistortedProjection;
|
|
rightEyeUndistortedProjection[0, 2] *= -1;
|
|
|
|
rightEyeUndistortedViewport = leftEyeUndistortedViewport;
|
|
rightEyeUndistortedViewport.x = 1 - rightEyeUndistortedViewport.xMax;
|
|
rightEyeDistortedViewport = rightEyeUndistortedViewport;
|
|
}
|
|
|
|
private static Matrix4x4 MakeProjection(float l, float t, float r, float b, float n, float f) {
|
|
Matrix4x4 m = Matrix4x4.zero;
|
|
m[0, 0] = 2 * n / (r - l);
|
|
m[1, 1] = 2 * n / (t - b);
|
|
m[0, 2] = (r + l) / (r - l);
|
|
m[1, 2] = (t + b) / (t - b);
|
|
m[2, 2] = (n + f) / (n - f);
|
|
m[2, 3] = 2 * n * f / (n - f);
|
|
m[3, 2] = -1;
|
|
return m;
|
|
}
|
|
|
|
public static BaseVRDevice GetDevice() {
|
|
if (device == null) {
|
|
#if UNITY_EDITOR
|
|
device = new UnityEditorDevice();
|
|
#elif ANDROID_DEVICE
|
|
//device = new CardboardAndroidDevice();
|
|
device = new AndroidVRDevice();
|
|
#elif IPHONE_DEVICE
|
|
device = new iOSVRDevice();
|
|
#else
|
|
throw new InvalidOperationException();
|
|
#endif
|
|
}
|
|
return device;
|
|
}
|
|
}
|