/Open Dive Sensor Secret
Created
May 11, 2015 05:11
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System.Runtime.InteropServices; | |
using System.IO; | |
using System; | |
//Dive Head Tracking | |
// copyright by Shoogee GmbH & Co. KG Refer to LICENCE.txt | |
//[ExecuteInEditMode] | |
public class OpenDiveSensor : MonoBehaviour { | |
// This is used for rotating the camera with another object | |
//for example tilting the camera while going along a racetrack or rollercoaster | |
public bool add_rotation_gameobject=false; | |
public GameObject rotation_gameobject; | |
// mouse emulation | |
public bool emulateMouseInEditor=true; | |
public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 } | |
public RotationAxes axes = RotationAxes.MouseXAndY; | |
public Texture nogyrotexture; | |
/// Offset projection for 2 cameras in VR | |
private float offset =0.0f; | |
private float max_offset=0.002f; | |
//public float max_offcenter_warp=0.1f; | |
public Camera cameraleft; | |
public Camera cameraright; | |
public float zoom=0.1f; | |
private float IPDCorrection=0.0f; | |
private float aspectRatio; | |
public float znear=0.1f; | |
public float zfar=10000.0f; | |
private float time_since_last_fullscreen=0; | |
private int is_tablet; | |
AndroidJavaObject mConfig; | |
AndroidJavaObject mWindowManager; | |
private float q0,q1,q2,q3; | |
private float m0,m1,m2; | |
Quaternion rot; | |
private bool show_gyro_error_message=false; | |
string errormessage; | |
#if UNITY_EDITOR | |
private float sensitivityX = 15F; | |
private float sensitivityY = 15F; | |
private float minimumX = -360F; | |
private float maximumX = 360F; | |
private float minimumY = -90F; | |
private float maximumY = 90F; | |
float rotationY = 0F; | |
#elif UNITY_ANDROID | |
private static AndroidJavaClass javadivepluginclass; | |
private static AndroidJavaClass javaunityplayerclass; | |
private static AndroidJavaObject currentactivity; | |
private static AndroidJavaObject javadiveplugininstance; | |
[DllImport("divesensor")] private static extern void initialize_sensors(); | |
[DllImport("divesensor")] private static extern int get_q(ref float q0,ref float q1,ref float q2,ref float q3); | |
[DllImport("divesensor")] private static extern int get_m(ref float m0,ref float m1,ref float m2); | |
[DllImport("divesensor")] private static extern int get_error(); | |
[DllImport("divesensor")] private static extern void dive_command(string command); | |
#elif UNITY_IPHONE | |
[DllImport("__Internal")] private static extern void initialize_sensors(); | |
[DllImport("__Internal")] private static extern float get_q0(); | |
[DllImport("__Internal")] private static extern float get_q1(); | |
[DllImport("__Internal")] private static extern float get_q2(); | |
[DllImport("__Internal")] private static extern float get_q3(); | |
[DllImport("__Internal")] private static extern void DiveUpdateGyroData(); | |
[DllImport("__Internal")] private static extern int get_q(ref float q0,ref float q1,ref float q2,ref float q3); | |
#endif | |
public static void divecommand(string command){ | |
#if UNITY_EDITOR | |
#elif UNITY_ANDROID | |
dive_command(command); | |
#elif UNITY_IPHONE | |
#endif | |
} | |
public static void setFullscreen(){ | |
#if UNITY_EDITOR | |
#elif UNITY_ANDROID | |
String answer; | |
answer= javadiveplugininstance.Call<string>("setFullscreen"); | |
#elif UNITY_IPHONE | |
#endif | |
return; | |
} | |
void Start () { | |
rot=Quaternion.identity; | |
// Disable screen dimming | |
Screen.sleepTimeout = SleepTimeout.NeverSleep; | |
Application.targetFrameRate = 60; | |
#if UNITY_EDITOR | |
if (rigidbody) | |
rigidbody.freezeRotation = true; | |
#elif UNITY_ANDROID | |
// Java part | |
javadivepluginclass = new AndroidJavaClass("com.shoogee.divejava.divejava") ; | |
javaunityplayerclass= new AndroidJavaClass("com.unity3d.player.UnityPlayer"); | |
currentactivity = javaunityplayerclass.GetStatic<AndroidJavaObject>("currentActivity"); | |
javadiveplugininstance = javadivepluginclass.CallStatic<AndroidJavaObject>("instance"); | |
object[] args={currentactivity}; | |
javadiveplugininstance.Call<string>("set_activity",args); | |
initialize_sensors (); | |
String answer; | |
answer= javadiveplugininstance.Call<string>("initializeDive"); | |
answer= javadiveplugininstance.Call<string>("getDeviceType"); | |
if (answer=="Tablet"){ | |
is_tablet=1; | |
Debug.Log("Dive Unity Tablet Mode activated"); | |
} | |
else{ | |
Debug.Log("Dive Phone Mode activated "+answer); | |
} | |
answer= javadiveplugininstance.Call<string>("setFullscreen"); | |
show_gyro_error_message=true; | |
Network.logLevel = NetworkLogLevel.Full; | |
int err = get_error(); | |
if (err==0){ errormessage=""; | |
show_gyro_error_message=false; | |
} | |
if (err==1){ | |
show_gyro_error_message=true; | |
errormessage="ERROR: Dive needs a Gyroscope and your telephone has none, we are trying to go to Accelerometer compatibility mode. Dont expect too much."; | |
} | |
#elif UNITY_IPHONE | |
initialize_sensors(); | |
#endif | |
float tabletcorrection=-0.028f; | |
//is_tablet=0; | |
if (is_tablet==1) | |
{ | |
Debug.Log ("Is tablet, using tabletcorrection"); | |
IPDCorrection=tabletcorrection; | |
} | |
else | |
{ | |
IPDCorrection=IPDCorrection; | |
} | |
//setIPDCorrection(IPDCorrection); | |
} | |
void Update () { | |
aspectRatio=(Screen.height*2.0f)/Screen.width; | |
setIPDCorrection(IPDCorrection); | |
//Debug.Log ("Divecamera"+cameraleft.aspect+"1/asp "+1/cameraleft.aspect+" Screen Width/Height "+ aspectRatio); | |
#if UNITY_EDITOR | |
#elif UNITY_ANDROID | |
time_since_last_fullscreen+=Time.deltaTime; | |
if (time_since_last_fullscreen >8){ | |
setFullscreen (); | |
time_since_last_fullscreen=0; | |
} | |
get_q(ref q0,ref q1,ref q2,ref q3); | |
//get_m(ref m0,ref m1,ref m2); | |
rot.x=-q2;rot.y=q3;rot.z=-q1;rot.w=q0; | |
if (add_rotation_gameobject){ | |
transform.rotation =rotation_gameobject.transform.rotation* rot; | |
} | |
else | |
{ | |
transform.rotation = rot; | |
if (is_tablet==1)transform.rotation=rot*Quaternion.AngleAxis(90,Vector3.forward); | |
} | |
#elif UNITY_IPHONE | |
DiveUpdateGyroData(); | |
get_q(ref q0,ref q1,ref q2,ref q3); | |
rot.x=-q2; | |
rot.y=q3; | |
rot.z=-q1; | |
rot.w=q0; | |
transform.rotation = rot; | |
if (add_rotation_gameobject){ | |
transform.rotation =rotation_gameobject.transform.rotation* rot; | |
} | |
else | |
{ | |
transform.rotation = rot; | |
if (is_tablet==1)transform.rotation=rot*Quaternion.AngleAxis(90,Vector3.forward); | |
} | |
#endif | |
#if UNITY_EDITOR | |
if (emulateMouseInEditor){ | |
if (axes == RotationAxes.MouseXAndY) | |
{ | |
float rotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityX; | |
rotationY += Input.GetAxis("Mouse Y") * sensitivityY; | |
rotationY = Mathf.Clamp (rotationY, minimumY, maximumY); | |
transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0); | |
} | |
else if (axes == RotationAxes.MouseX) | |
{ | |
transform.Rotate(0, Input.GetAxis("Mouse X") * sensitivityX, 0); | |
} | |
else | |
{ | |
rotationY += Input.GetAxis("Mouse Y") * sensitivityY; | |
rotationY = Mathf.Clamp (rotationY, minimumY, maximumY); | |
transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0); | |
} | |
} | |
#endif | |
} | |
void OnGUI () | |
{ | |
/* if (GUI.Button(new Rect(Screen.width/4-150, Screen.height-100, 300,100), "+IPD")){ | |
Debug.Log("Clicked the button with an image"); | |
IPDCorrection=IPDCorrection+0.01f; | |
setIPDCorrection(IPDCorrection); | |
} | |
if (GUI.Button(new Rect(Screen.width-Screen.width/4-150, Screen.height-100, 300,100), "-IPD")){ | |
Debug.Log("Clicked the button with an image"); | |
IPDCorrection=IPDCorrection-0.01f; | |
setIPDCorrection(IPDCorrection); | |
} | |
*/ | |
if (show_gyro_error_message) | |
{ | |
if(GUI.Button(new Rect(0,0, Screen.width, Screen.height) , "Error: \n\n No Gyro detected \n \n Touch screen to continue anyway")) { | |
show_gyro_error_message=false; | |
} | |
GUI.DrawTexture(new Rect(Screen.width/2-320, Screen.height/2-240, 640, 480), nogyrotexture, ScaleMode.ScaleToFit, true, 0); | |
return; | |
} | |
} | |
void setIPDCorrection(float correction) { | |
// not using camera nearclipplane value because that leads to problems with field of view in different projects | |
cameraleft.projectionMatrix = PerspectiveOffCenter((-zoom+correction)*(znear/0.1f), (zoom+correction)*(znear/0.1f), -zoom*(znear/0.1f)*aspectRatio, zoom*(znear/0.1f)*aspectRatio, znear, zfar);; | |
cameraright.projectionMatrix = PerspectiveOffCenter((-zoom-correction)*(znear/0.1f), (zoom-correction)*(znear/0.1f), -zoom*(znear/0.1f)*aspectRatio, zoom*(znear/0.1f)*aspectRatio, znear, zfar);; | |
} | |
static Matrix4x4 PerspectiveOffCenter(float left, float right, float bottom, float top, float near, float far) { | |
float x = 2.0F * near / (right - left); | |
float y = 2.0F * near / (top - bottom); | |
float a = (right + left) / (right - left); | |
float b = (top + bottom) / (top - bottom); | |
float c = -(far + near) / (far - near); | |
float d = -(2.0F * far * near) / (far - near); | |
float e = -1.0F; | |
Matrix4x4 m = new Matrix4x4(); | |
m[0, 0] = x; | |
m[0, 1] = 0; | |
m[0, 2] = a; | |
m[0, 3] = 0; | |
m[1, 0] = 0; | |
m[1, 1] = y; | |
m[1, 2] = b; | |
m[1, 3] = 0; | |
m[2, 0] = 0; | |
m[2, 1] = 0; | |
m[2, 2] = c; | |
m[2, 3] = d; | |
m[3, 0] = 0; | |
m[3, 1] = 0; | |
m[3, 2] = e; | |
m[3, 3] = 0; | |
return m; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment