diff --git a/Assets/LeapMotionModules/Android/Cardboard.meta b/Assets/LeapMotionModules/Android/Cardboard.meta new file mode 100644 index 0000000000..58bc9a320c --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 245d72dce09e44c03b4205ac57ceca0c +folderAsset: yes +timeCreated: 1465258422 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR.meta new file mode 100644 index 0000000000..a2069f4497 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 01bd37f55554b4411813312753a2063c +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Distortion.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Distortion.meta new file mode 100644 index 0000000000..e00d7e281c --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Distortion.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 62f21f05848ab49dab5437386c77527a +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Distortion/GvrDistortion.cginc b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Distortion/GvrDistortion.cginc new file mode 100644 index 0000000000..818ac942de --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Distortion/GvrDistortion.cginc @@ -0,0 +1,92 @@ +// 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. + + +// To use in a surface shader, add the following text to the code: +// +// #pragma surface ... vertex:vert <-- add "vertex:vert" to this line +// #pragma multi_compile __ GVR_DISTORTION <-- copy the next 5 lines +// #include "GvrDistortion.cginc" +// void vert (inout appdata_base v) { +// v.vertex = undistortSurface(v.vertex); +// } + +// To use in a vertex shader, modify it as follows: +// +// #pragma multi_compile __ GVR_DISTORTION <-- add these 2 lines +// #include "GvrDistortion.cginc" +// +// v2f vert (appdata_blah v) { +// v2f o; +// o.vertex = undistortVertex(v.vertex); <-- replace "mul(UNITY_MATRIX_MVP, v.vertex)" +// ... +// return o; +// } + +#if defined(GVR_DISTORTION) + +float4x4 _Undistortion; +float _MaxRadSq; +float _NearClip; +float4x4 _RealProjection; +float4x4 _FixProjection; + +float distortionFactor(float rSquared) { + float ret = 0.0; + ret = rSquared * (ret + _Undistortion[1][1]); + ret = rSquared * (ret + _Undistortion[0][1]); + ret = rSquared * (ret + _Undistortion[3][0]); + ret = rSquared * (ret + _Undistortion[2][0]); + ret = rSquared * (ret + _Undistortion[1][0]); + ret = rSquared * (ret + _Undistortion[0][0]); + return ret + 1.0; +} + +// Convert point from world space to undistorted camera space. +float4 undistort(float4 pos) { + // Go to camera space. + pos = mul(UNITY_MATRIX_MV, pos); + if (pos.z <= -_NearClip) { // Reminder: Forward is -Z. + // Undistort the point's coordinates in XY. + float r2 = clamp(dot(pos.xy, pos.xy) / (pos.z*pos.z), 0, _MaxRadSq); + pos.xy *= distortionFactor(r2); + } + return pos; +} + +// Multiply by no-lens projection matrix after undistortion. +float4 undistortVertex(float4 pos) { + return mul(_RealProjection, undistort(pos)); +} + +// Surface shader hides away the MVP multiplication, so we have +// to multiply by _FixProjection = inverse(MVP)*_RealProjection. +float4 undistortSurface(float4 pos) { + return mul(_FixProjection, undistort(pos)); +} + +#else +// Distortion disabled. + +// Just do the standard MVP transform. +float4 undistortVertex(float4 pos) { + return mul(UNITY_MATRIX_MVP, pos); +} + +// Surface shader hides away the MVP multiplication, so just return pos. +float4 undistortSurface(float4 pos) { + return pos; +} + +#endif diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Distortion/GvrDistortion.cginc.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Distortion/GvrDistortion.cginc.meta new file mode 100644 index 0000000000..c1c59d4834 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Distortion/GvrDistortion.cginc.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 2c745b211b2a34eb290d759affc53a92 +ShaderImporter: + defaultTextures: [] + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor.meta new file mode 100644 index 0000000000..eb372998d3 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 7c98c5ffcf17d49fc88af4e1d260f2cb +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrAudioListenerEditor.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrAudioListenerEditor.cs new file mode 100644 index 0000000000..aa7a270fe1 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrAudioListenerEditor.cs @@ -0,0 +1,67 @@ +// Copyright 2016 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. + +using UnityEngine; +using UnityEditor; +using System.Collections; + +/// A custom editor for properties on the GvrAudioListener script. This appears in the Inspector +/// window of a GvrAudioListener object. +[CustomEditor(typeof(GvrAudioListener))] +public class GvrAudioListenerEditor : Editor { + private SerializedProperty globalGainDb = null; + private SerializedProperty occlusionMask = null; + private SerializedProperty quality = null; + private SerializedProperty worldScale = null; + + private GUIContent globalGainLabel = new GUIContent("Global Gain (dB)", + "Sets the global gain of the system. Can be used to adjust the overall output volume."); + private GUIContent occlusionMaskLabel = new GUIContent("Occlusion Mask", + "Sets the global layer mask for occlusion detection."); + private GUIContent qualityLabel = new GUIContent("Quality", + "Sets the quality mode in which the spatial audio will be rendered. " + + "Higher quality modes allow for increased fidelity at the cost of greater CPU usage."); + private GUIContent worldScaleLabel = new GUIContent("World Scale", + "Sets the ratio between game units and real world units (meters)."); + + void OnEnable () { + globalGainDb = serializedObject.FindProperty("globalGainDb"); + occlusionMask = serializedObject.FindProperty("occlusionMask"); + quality = serializedObject.FindProperty("quality"); + worldScale = serializedObject.FindProperty("worldScale"); + } + + /// @cond + public override void OnInspectorGUI () { + serializedObject.Update(); + + // Rendering quality can only be modified through the Inspector in Edit mode. + GUI.enabled = !EditorApplication.isPlaying; + EditorGUILayout.PropertyField(quality, qualityLabel); + GUI.enabled = true; + + EditorGUILayout.Separator(); + + EditorGUILayout.Slider(globalGainDb, GvrAudio.minGainDb, GvrAudio.maxGainDb, globalGainLabel); + EditorGUILayout.Slider(worldScale, GvrAudio.minWorldScale, GvrAudio.maxWorldScale, + worldScaleLabel); + + EditorGUILayout.Separator(); + + EditorGUILayout.PropertyField(occlusionMask, occlusionMaskLabel); + + serializedObject.ApplyModifiedProperties(); + } + /// @endcond +} diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrAudioListenerEditor.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrAudioListenerEditor.cs.meta new file mode 100644 index 0000000000..bd08b2049f --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrAudioListenerEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 846f7b1b78d8e4eb2a0db361797b6e76 +timeCreated: 1447979035 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrAudioRoomEditor.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrAudioRoomEditor.cs new file mode 100644 index 0000000000..51b4a20aa2 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrAudioRoomEditor.cs @@ -0,0 +1,108 @@ +// Copyright 2016 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. + +using UnityEngine; +using UnityEditor; +using System.Collections; + +/// A custom editor for properties on the GvrAudioRoom script. This appears in the Inspector window +/// of a GvrAudioRoom object. +[CustomEditor(typeof(GvrAudioRoom))] +[CanEditMultipleObjects] +public class GvrAudioRoomEditor : Editor { + private SerializedProperty leftWall = null; + private SerializedProperty rightWall = null; + private SerializedProperty floor = null; + private SerializedProperty ceiling = null; + private SerializedProperty backWall = null; + private SerializedProperty frontWall = null; + private SerializedProperty reflectivity = null; + private SerializedProperty reverbGainDb = null; + private SerializedProperty reverbBrightness = null; + private SerializedProperty reverbTime = null; + private SerializedProperty size = null; + + private GUIContent surfaceMaterialsLabel = new GUIContent("Surface Materials", + "Room surface materials to calculate the acoustic properties of the room."); + private GUIContent surfaceMaterialLabel = new GUIContent("Surface Material", + "Surface material used to calculate the acoustic properties of the room."); + private GUIContent reflectivityLabel = new GUIContent("Reflectivity", + "Adjusts what proportion of the direct sound is reflected back by each surface, after an " + + "appropriate delay. Reverberation is unaffected by this setting."); + private GUIContent reverbGainLabel = new GUIContent("Gain (dB)", + "Applies a gain adjustment to the reverberation in the room. The default value will leave " + + "reverb unaffected."); + private GUIContent reverbPropertiesLabel = new GUIContent("Reverb Properties", + "Parameters to adjust the reverb properties of the room."); + private GUIContent reverbBrightnessLabel = new GUIContent("Brightness", + "Adjusts the balance between high and low frequencies in the reverb."); + private GUIContent reverbTimeLabel = new GUIContent("Time", + "Adjusts the overall duration of the reverb by a positive scaling factor."); + private GUIContent sizeLabel = new GUIContent("Size", "Sets the room dimensions."); + + void OnEnable () { + leftWall = serializedObject.FindProperty("leftWall"); + rightWall = serializedObject.FindProperty("rightWall"); + floor = serializedObject.FindProperty("floor"); + ceiling = serializedObject.FindProperty("ceiling"); + backWall = serializedObject.FindProperty("backWall"); + frontWall = serializedObject.FindProperty("frontWall"); + reflectivity = serializedObject.FindProperty("reflectivity"); + reverbGainDb = serializedObject.FindProperty("reverbGainDb"); + reverbBrightness = serializedObject.FindProperty("reverbBrightness"); + reverbTime = serializedObject.FindProperty("reverbTime"); + size = serializedObject.FindProperty("size"); + } + + /// @cond + public override void OnInspectorGUI () { + serializedObject.Update(); + + EditorGUILayout.LabelField(surfaceMaterialsLabel); + ++EditorGUI.indentLevel; + DrawSurfaceMaterial(leftWall); + DrawSurfaceMaterial(rightWall); + DrawSurfaceMaterial(floor); + DrawSurfaceMaterial(ceiling); + DrawSurfaceMaterial(backWall); + DrawSurfaceMaterial(frontWall); + --EditorGUI.indentLevel; + + EditorGUILayout.Separator(); + + EditorGUILayout.Slider(reflectivity, 0.0f, GvrAudio.maxReflectivity, reflectivityLabel); + + EditorGUILayout.Separator(); + + EditorGUILayout.LabelField(reverbPropertiesLabel); + ++EditorGUI.indentLevel; + EditorGUILayout.Slider(reverbGainDb, GvrAudio.minGainDb, GvrAudio.maxGainDb, reverbGainLabel); + EditorGUILayout.Slider(reverbBrightness, GvrAudio.minReverbBrightness, + GvrAudio.maxReverbBrightness, reverbBrightnessLabel); + EditorGUILayout.Slider(reverbTime, 0.0f, GvrAudio.maxReverbTime, reverbTimeLabel); + --EditorGUI.indentLevel; + + EditorGUILayout.Separator(); + + EditorGUILayout.PropertyField(size, sizeLabel); + + serializedObject.ApplyModifiedProperties(); + } + /// @endcond + + private void DrawSurfaceMaterial (SerializedProperty surfaceMaterial) { + surfaceMaterialLabel.text = surfaceMaterial.displayName; + EditorGUILayout.PropertyField(surfaceMaterial, surfaceMaterialLabel); + } +} diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrAudioRoomEditor.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrAudioRoomEditor.cs.meta new file mode 100644 index 0000000000..9f865a2454 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrAudioRoomEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2e20199949e8e4ecd992d68cf09fc902 +timeCreated: 1447979493 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrViewerEditor.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrViewerEditor.cs new file mode 100644 index 0000000000..d05fc37229 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrViewerEditor.cs @@ -0,0 +1,133 @@ +// Copyright 2014 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. + +using UnityEngine; +using UnityEditor; +using UnityEditor.Callbacks; +#if UNITY_IOS +using UnityEditor.iOS.Xcode; +#endif + +/// A custom editor for properties on the GvrViewer script. This appears in the +/// Inspector window of a GvrViewer object. Its purpose is to allow changing the +/// `GvrViewer.Instance` object's properties from their default values. +[CustomEditor(typeof(GvrViewer))] +public class GvrViewerEditor : Editor { + GUIContent vrModeLabel = new GUIContent("VR Mode Enabled", + "Sets whether VR mode is enabled."); + + GUIContent distortionCorrectionLabel = new GUIContent("Distortion Correction", + "The distortion correction method performed by the SDK."); + + GUIContent stereoScreenScale = new GUIContent("Stereo Screen Scale", + "The screen resolution is multiplied by this value when creating the " + + "RenderTexture for the stereo screen."); + + GUIContent autoDriftCorrectionLabel = new GUIContent("Auto Drift Correction", + "When enabled, drift in the gyro readings is estimated and removed."); + + GUIContent neckModelScaleLabel = new GUIContent("Neck Model Scale", + "The scale factor of the builtin neck model [0..1]. To disable, set to 0."); + + GUIContent alignmentMarkerLabel = new GUIContent("Alignment Marker", + "Whether to draw the alignment marker. The marker is a vertical line that splits " + + "the viewport in half, designed to help users align the screen with the viewer."); + + GUIContent settingsButtonLabel = new GUIContent("Settings Button", + "Whether to draw the settings button. The settings button allows the " + + "user to pair their phone with a specific Cardboard viewer model"); + + GUIContent backButtonLabel = new GUIContent("Back Button", + "Whether to draw the onscreen Back Button."); + + GUIContent editorSettingsLabel = new GUIContent("Unity Editor Emulation Settings", + "Controls for the in-editor emulation of a Cardboard viewer."); + + GUIContent autoUntiltHeadLabel = new GUIContent("Auto Untilt Head", + "When enabled, just release Ctrl to untilt the head."); + + GUIContent screenSizeLabel = new GUIContent("Screen Size", + "The screen size to emulate."); + + GUIContent viewerTypeLabel = new GUIContent("Viewer Type", + "The viewer type to emulate."); + + /// @cond HIDDEN + public override void OnInspectorGUI() { + GUI.changed = false; + + GUIStyle headingStyle = new GUIStyle(GUI.skin.label); + headingStyle.fontStyle = FontStyle.Bold; + + GvrViewer gvrViewer = (GvrViewer)target; + + EditorGUILayout.LabelField("General Settings", headingStyle); + gvrViewer.VRModeEnabled = + EditorGUILayout.Toggle(vrModeLabel, gvrViewer.VRModeEnabled); + gvrViewer.DistortionCorrection = (GvrViewer.DistortionCorrectionMethod) + EditorGUILayout.EnumPopup(distortionCorrectionLabel, gvrViewer.DistortionCorrection); + float oldScale = gvrViewer.StereoScreenScale; + float newScale = EditorGUILayout.Slider(stereoScreenScale, oldScale, 0.25f, 2.0f); + if (!Mathf.Approximately(newScale, oldScale)) { + gvrViewer.StereoScreenScale = newScale; + } + gvrViewer.NeckModelScale = + EditorGUILayout.Slider(neckModelScaleLabel, gvrViewer.NeckModelScale, 0, 1); + gvrViewer.AutoDriftCorrection = + EditorGUILayout.Toggle(autoDriftCorrectionLabel, gvrViewer.AutoDriftCorrection); + + EditorGUILayout.Separator(); + + EditorGUILayout.LabelField("UI Layer Settings", headingStyle); + gvrViewer.EnableAlignmentMarker = + EditorGUILayout.Toggle(alignmentMarkerLabel, gvrViewer.EnableAlignmentMarker); + gvrViewer.EnableSettingsButton = + EditorGUILayout.Toggle(settingsButtonLabel, gvrViewer.EnableSettingsButton); + gvrViewer.BackButtonMode = (GvrViewer.BackButtonModes) + EditorGUILayout.EnumPopup(backButtonLabel, gvrViewer.BackButtonMode); + + EditorGUILayout.Separator(); + + EditorGUILayout.LabelField(editorSettingsLabel, headingStyle); + gvrViewer.autoUntiltHead = + EditorGUILayout.Toggle(autoUntiltHeadLabel, gvrViewer.autoUntiltHead); + gvrViewer.ScreenSize = (GvrProfile.ScreenSizes) + EditorGUILayout.EnumPopup(screenSizeLabel, gvrViewer.ScreenSize); + gvrViewer.ViewerType = (GvrProfile.ViewerTypes) + EditorGUILayout.EnumPopup(viewerTypeLabel, gvrViewer.ViewerType); + + if (GUI.changed) { + EditorUtility.SetDirty(gvrViewer); + } + } + +#if UNITY_IOS + // Add -ObjC to the Xcode project's linker flags, since our native iOS code + // requires it. Also add required frameworks. + [PostProcessBuild(100)] + public static void OnPostProcessBuild(BuildTarget platform, string projectPath) { + if (platform != BuildTarget.iOS) { + return; + } + string pbxFile = PBXProject.GetPBXProjectPath(projectPath); + PBXProject pbxProject = new PBXProject(); + pbxProject.ReadFromFile(pbxFile); + string target = pbxProject.TargetGuidByName(PBXProject.GetUnityTargetName()); + pbxProject.AddFrameworkToProject(target, "Security.framework", false); + pbxProject.AddFrameworkToProject(target, "GLKit.framework", false); + pbxProject.AddBuildProperty(target, "OTHER_LDFLAGS", "-ObjC"); + pbxProject.WriteToFile(pbxFile); + } +#endif +} diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrViewerEditor.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrViewerEditor.cs.meta new file mode 100644 index 0000000000..34dca83002 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/GvrViewerEditor.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ed7a9fc9a5d44422b99d0a825d3cbf1e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/StereoControllerEditor.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/StereoControllerEditor.cs new file mode 100644 index 0000000000..7cfd753307 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/StereoControllerEditor.cs @@ -0,0 +1,111 @@ +// Copyright 2014 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. + +using UnityEngine; +using UnityEditor; +using System.Collections; +using System.Linq; + +/// A custom editor for the StereoController script. It exists to add the _Update +/// Stereo Cameras_ button to the StereoController's Inspector window, and to the +/// corresponding main menu entry and Camera context menu command. The usage of the +/// these actions is described in StereoController. +[CustomEditor(typeof(StereoController))] +public class StereoControllerEditor : Editor { + /// Name of button, and part of "Undo ..." message. + public const string ACTION_NAME = "Update Stereo Cameras"; + + private GUIContent updateButton = + new GUIContent(ACTION_NAME, "Copy all Camera settings to the stereo cameras."); + + /// @cond HIDDEN + public override void OnInspectorGUI() { + DrawDefaultInspector(); + GUILayout.BeginHorizontal(GUILayout.ExpandHeight(false)); + GUILayout.FlexibleSpace(); + if (GUILayout.Button(updateButton, GUILayout.ExpandWidth(false))) { + var controller = (StereoController)target; + DoUpdateStereoCameras(controller.gameObject); + } + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal(); + } + + [MenuItem("Component/GoogleVR/Update Stereo Cameras", true, 40)] + public static bool CanUpdateStereoCameras() { + // Make sure all selected items have valid cameras. + return Selection.gameObjects.Where(go => CanUpdateStereoCameras(go)).Count() + == Selection.gameObjects.Length; + } + + [MenuItem("CONTEXT/Camera/Update Stereo Cameras", true, 41)] + public static bool CanUpdateStereoCamerasContext(MenuCommand command) { + var camera = (Camera)command.context; + return CanUpdateStereoCameras(camera.gameObject); + } + + [MenuItem("Component/GoogleVR/Update Stereo Cameras", false, 42)] + public static void UpdateStereoCameras() { + foreach (var go in Selection.gameObjects) { + DoUpdateStereoCameras(go); + } + } + + [MenuItem("CONTEXT/Camera/Update Stereo Cameras", false, 43)] + public static void UpdateStereoCamerasContext(MenuCommand command) { + var camera = (Camera)command.context; + DoUpdateStereoCameras(camera.gameObject); + } + /// @endcond + + private static bool CanUpdateStereoCameras(GameObject go) { + return go != null && + go.hideFlags == HideFlags.None && + go.GetComponent() != null && + go.GetComponent() == null; + } + + private static void DoUpdateStereoCameras(GameObject go) { + // Make sure there is a StereoController. + var controller = go.GetComponent(); + if (controller == null) { + controller = go.AddComponent(); + Undo.RegisterCreatedObjectUndo(controller, ACTION_NAME); + } + + // Remember current state of stereo rig. + bool hadHead = controller.Head != null; + bool hadEyes = controller.Eyes.Length > 0; + + controller.AddStereoRig(); + + // Support undo... + + // Head. + var head = go.GetComponent(); + if (head != null && !hadHead) { + Undo.RegisterCreatedObjectUndo(head, ACTION_NAME); + } + + // Eyes. Synchronizes them with controller's camera too. + foreach (var eye in controller.Eyes) { + if (!hadEyes) { + Undo.RegisterCreatedObjectUndo(eye.gameObject, ACTION_NAME); + } else { + Undo.RecordObject(eye.GetComponent(), ACTION_NAME); + eye.CopyCameraAndMakeSideBySide(controller); + } + } + } +} diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/StereoControllerEditor.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/StereoControllerEditor.cs.meta new file mode 100644 index 0000000000..3ff7e251d4 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Editor/StereoControllerEditor.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 05c5a7cf1f7ca4a0db9fef203f559380 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/LICENSE b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/LICENSE new file mode 100644 index 0000000000..59572ce00b --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/LICENSE @@ -0,0 +1,267 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + +==================================================================================== + +The file GoogleVR/Scripts/GazeInputModule.cs is licensed as follows: + +The MIT License (MIT) + +Copyright (c) 2014, Unity Technologies & Google, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +==================================================================================== + +The file Assets/Plugins/Google.ProtocolBuffers.dll is licensed as follows: + +Protocol Buffers - Google's data interchange format +Copyright 2008-2010 Google Inc. All rights reserved. +http://github.com/jskeet/dotnet-protobufs/ +Original C++/Java/Python code: +http://code.google.com/p/protobuf/ + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/LICENSE.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/LICENSE.meta new file mode 100644 index 0000000000..f15b72bba5 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/LICENSE.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: 0ae37b2426f844468ab02f411263ae0d +DefaultImporter: + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Prefabs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Prefabs.meta new file mode 100644 index 0000000000..05811f5ea7 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Prefabs.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 80e6cdf429de247a792161c31b9b2ce2 +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Prefabs/GvrMain.prefab b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Prefabs/GvrMain.prefab new file mode 100644 index 0000000000..ce41e30d18 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Prefabs/GvrMain.prefab @@ -0,0 +1,598 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &100000 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400000} + - 20: {fileID: 2000000} + - 124: {fileID: 12400000} + - 114: {fileID: 11400002} + m_Layer: 0 + m_Name: Main Camera Right + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &100002 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400002} + - 20: {fileID: 2000002} + - 124: {fileID: 12400002} + - 114: {fileID: 11400004} + m_Layer: 0 + m_Name: Main Camera Left + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &100004 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400004} + - 114: {fileID: 11400012} + m_Layer: 0 + m_Name: GvrMain + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &100006 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400006} + - 20: {fileID: 2000004} + - 124: {fileID: 12400004} + - 92: {fileID: 9200004} + - 81: {fileID: 8100000} + - 114: {fileID: 11400006} + - 114: {fileID: 11400000} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &100008 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 400008} + - 114: {fileID: 11400008} + m_Layer: 0 + m_Name: Head + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &150430 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 450430} + m_Layer: 0 + m_Name: Stereo Render + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &150432 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 450432} + - 20: {fileID: 2050432} + - 92: {fileID: 9250434} + - 114: {fileID: 11450432} + m_Layer: 0 + m_Name: PostRender + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &150434 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 450434} + - 20: {fileID: 2050434} + - 114: {fileID: 11450434} + m_Layer: 0 + m_Name: PreRender + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &400000 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: .0299999993, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 400006} + m_RootOrder: 1 +--- !u!4 &400002 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100002} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -.0299999993, y: -0, z: -0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 400006} + m_RootOrder: 0 +--- !u!4 &400004 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100004} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 400008} + - {fileID: 450430} + m_Father: {fileID: 0} + m_RootOrder: 0 +--- !u!4 &400006 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 400002} + - {fileID: 400000} + m_Father: {fileID: 400008} + m_RootOrder: 0 +--- !u!4 &400008 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100008} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 400006} + m_Father: {fileID: 400004} + m_RootOrder: 0 +--- !u!4 &450430 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 150430} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 450434} + - {fileID: 450432} + m_Father: {fileID: 400004} + m_RootOrder: 1 +--- !u!4 &450432 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 150432} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 450430} + m_RootOrder: 1 +--- !u!4 &450434 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 150434} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 450430} + m_RootOrder: 0 +--- !u!20 &2000000 +Camera: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Enabled: 0 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: .192156866, g: .301960796, b: .474509805, a: 1} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: .5 + y: 0 + width: .5 + height: 1 + near clip plane: .300000012 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: .0219999999 + m_StereoMirrorMode: 0 +--- !u!20 &2000002 +Camera: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100002} + m_Enabled: 0 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: .192156866, g: .301960796, b: .474509805, a: 1} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: .5 + height: 1 + near clip plane: .300000012 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: .0219999999 + m_StereoMirrorMode: 0 +--- !u!20 &2000004 +Camera: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: .192156866, g: .301960796, b: .474509805, a: 1} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: .300000012 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: .0219999999 + m_StereoMirrorMode: 0 +--- !u!20 &2050432 +Camera: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 150432} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 3 + m_BackGroundColor: {r: 1, g: 0, b: 1, a: 1} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: .300000012 + far clip plane: 1000 + field of view: 60 + orthographic: 1 + orthographic size: .5 + m_Depth: 100 + m_CullingMask: + serializedVersion: 2 + m_Bits: 0 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 0 + m_OcclusionCulling: 0 + m_StereoConvergence: 10 + m_StereoSeparation: .0219999999 + m_StereoMirrorMode: 0 +--- !u!20 &2050434 +Camera: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 150434} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0, g: 0, b: 0, a: 1} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: .300000012 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -100 + m_CullingMask: + serializedVersion: 2 + m_Bits: 0 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 0 + m_OcclusionCulling: 0 + m_StereoConvergence: 10 + m_StereoSeparation: .0219999999 + m_StereoMirrorMode: 0 +--- !u!81 &8100000 +AudioListener: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + m_Enabled: 1 +--- !u!92 &9200004 +Behaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + m_Enabled: 1 +--- !u!92 &9250434 +Behaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 150432} + m_Enabled: 1 +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b1156c073149742478887bb24456f32d, type: 3} + m_Name: + m_EditorClassIdentifier: + globalGainDb: 0 + worldScale: 1 + occlusionMask: + serializedVersion: 2 + m_Bits: 4294967295 + quality: 2 +--- !u!114 &11400002 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5c9cfdc6c389e2742aa40f991195d828, type: 3} + m_Name: + m_EditorClassIdentifier: + eye: 1 + toggleCullingMask: + serializedVersion: 2 + m_Bits: 0 +--- !u!114 &11400004 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100002} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5c9cfdc6c389e2742aa40f991195d828, type: 3} + m_Name: + m_EditorClassIdentifier: + eye: 0 + toggleCullingMask: + serializedVersion: 2 + m_Bits: 0 +--- !u!114 &11400006 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b6788e8e1b3f7447db6657ef0959d3ce, type: 3} + m_Name: + m_EditorClassIdentifier: + directRender: 1 + keepStereoUpdated: 0 + stereoMultiplier: 1 + matchMonoFOV: 0 + matchByZoom: 0 + centerOfInterest: {fileID: 0} + radiusOfInterest: 0 + checkStereoComfort: 1 + stereoAdjustSmoothing: .100000001 + screenParallax: 0 + stereoPaddingX: 0 + stereoPaddingY: 0 +--- !u!114 &11400008 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100008} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f1578549c7fcc4f6fa1b063992091672, type: 3} + m_Name: + m_EditorClassIdentifier: + trackRotation: 1 + trackPosition: 1 + target: {fileID: 0} + updateEarly: 0 +--- !u!114 &11400012 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100004} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a40b544b8c3553c40852ae7ad35a9343, type: 3} + m_Name: + m_EditorClassIdentifier: + vrModeEnabled: 1 + distortionCorrection: 2 + enableAlignmentMarker: 1 + enableSettingsButton: 1 + backButtonMode: 1 + neckModelScale: 1 + autoDriftCorrection: 1 + electronicDisplayStabilization: 0 + autoUntiltHead: 1 + UseUnityRemoteInput: 0 + screenSize: 0 + deviceType: 1 + stereoScreenScale: 1 +--- !u!114 &11450432 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 150432} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3995cc6db284649a793472ad14b220f6, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &11450434 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 150434} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 20fb7fbcfb2e642bba6211eb9ea19962, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!124 &12400000 +Behaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100000} + m_Enabled: 1 +--- !u!124 &12400002 +Behaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100002} + m_Enabled: 1 +--- !u!124 &12400004 +Behaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 100006} + m_Enabled: 1 +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 100004} + m_IsPrefabParent: 1 diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Prefabs/GvrMain.prefab.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Prefabs/GvrMain.prefab.meta new file mode 100644 index 0000000000..c0097de42c --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Prefabs/GvrMain.prefab.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: b8b03d395f5734e98af91ccf44f9bf47 +NativeFormatImporter: + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/README b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/README new file mode 100644 index 0000000000..ef653883b0 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/README @@ -0,0 +1,10 @@ +Google VR SDK for Unity + +This SDK provides Android and iOS developers with the easiest way to add +Google VR support to their Unity projects. + +Please visit https://developers.google.com/vr/unity for the latest +version of this SDK. + +Please visit https://developers.google.com/vr/unity/release-notes +for the latest issues and news relating to this SDK. diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/README.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/README.meta new file mode 100644 index 0000000000..c2d962f9a1 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/README.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: de961e46abe24453a81bf1c8576885b3 +DefaultImporter: + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Resources.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Resources.meta new file mode 100644 index 0000000000..ca0abf95bc --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Resources.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: c5cce34e4c5954a0b8bdf30ff6a18430 +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Resources/SolidColor.shader b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Resources/SolidColor.shader new file mode 100644 index 0000000000..4ec7ea8114 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Resources/SolidColor.shader @@ -0,0 +1,26 @@ +// 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. + +Shader "GoogleVR/SolidColor" { + Properties { + _Color ("Main Color", COLOR) = (1,1,1,1) + } + SubShader { + Pass { + ZWrite Off + ZTest Always + Color [_Color] + } + } +} \ No newline at end of file diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Resources/SolidColor.shader.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Resources/SolidColor.shader.meta new file mode 100644 index 0000000000..651954caa6 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Resources/SolidColor.shader.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: beaebe8e7b47e4c0b93b51fad8fb14a2 +ShaderImporter: + defaultTextures: [] + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Resources/UnlitTexture.shader b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Resources/UnlitTexture.shader new file mode 100644 index 0000000000..5aa9748d74 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Resources/UnlitTexture.shader @@ -0,0 +1,66 @@ +// Copyright 2016 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. + +Shader "GoogleVR/UnlitTexture" { + Properties { + _Color ("Color", Color) = (1,1,1,1) + _MainTex ("Texture", 2D) = "white" {} + } + SubShader { + Tags { "RenderType"="Opaque" } + Cull Off + Blend Off + ZTest Always + ZWrite Off + Lighting Off + Fog {Mode Off} + + Pass { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "UnityCG.cginc" + + struct appdata { + float4 vertex : POSITION; + float4 color : COLOR; + float2 uv : TEXCOORD0; + }; + + struct v2f { + float2 uv : TEXCOORD0; + float4 color : COLOR; + float4 vertex : SV_POSITION; + }; + + sampler2D _MainTex; + float4 _MainTex_ST; + float4 _Color; + + v2f vert (appdata v) { + v2f o; + o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); + o.color = v.color; + o.uv = TRANSFORM_TEX(v.uv, _MainTex); + return o; + } + + fixed4 frag (v2f i) : COLOR { + return tex2D(_MainTex, i.uv) * i.color * _Color; + } + ENDCG + } + } +} diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Resources/UnlitTexture.shader.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Resources/UnlitTexture.shader.meta new file mode 100644 index 0000000000..9b3507d220 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Resources/UnlitTexture.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 67ee2e53086414fbbab2a5edbd544629 +timeCreated: 1457591523 +licenseType: Pro +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts.meta new file mode 100644 index 0000000000..dc4cc2ea5f --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 5f01aa5c8e7de4973aa7785e6b4dc993 +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio.meta new file mode 100644 index 0000000000..9861951b41 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 373d3ea6bc95c4fc78ad9bd3da8dec22 +folderAsset: yes +timeCreated: 1448875499 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudio.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudio.cs new file mode 100644 index 0000000000..bc2efab861 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudio.cs @@ -0,0 +1,367 @@ +// Copyright 2016 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. + +using UnityEngine; +using System; +using System.Collections; +using System.IO; +using System.Runtime.InteropServices; + +/// This is the main GVR audio class that communicates with the native code implementation of +/// the audio system. Native functions of the system can only be called through this class to +/// preserve the internal system functionality. Public function calls are *not* thread-safe. +public static class GvrAudio { + /// Audio system rendering quality. + public enum Quality { + Stereo = 0, /// Stereo-only rendering + Low = 1, /// Low quality binaural rendering (first-order HRTF) + High = 2 /// High quality binaural rendering (third-order HRTF) + } + + /// System sampling rate. + public static int SampleRate { + get { return sampleRate; } + } + private static int sampleRate = -1; + + /// System number of output channels. + public static int NumChannels { + get { return numChannels; } + } + private static int numChannels = -1; + + /// System number of frames per buffer. + public static int FramesPerBuffer { + get { return framesPerBuffer; } + } + private static int framesPerBuffer = -1; + + /// Initializes the audio system with the current audio configuration. + /// @note This should only be called from the main Unity thread. + public static void Initialize (GvrAudioListener listener, Quality quality) { + if (!initialized) { +#if !UNITY_EDITOR && UNITY_ANDROID + SetApplicationState(); +#endif + // Initialize the audio system. + AudioConfiguration config = AudioSettings.GetConfiguration(); + sampleRate = config.sampleRate; + numChannels = (int)config.speakerMode; + framesPerBuffer = config.dspBufferSize; + if (numChannels != (int)AudioSpeakerMode.Stereo) { + Debug.LogError("Only 'Stereo' speaker mode is supported by GVR Audio."); + return; + } + Initialize(quality, sampleRate, numChannels, framesPerBuffer); + listenerTransform = listener.transform; + + initialized = true; + } else if (listener.transform != listenerTransform) { + Debug.LogError("Only one GvrAudioListener component is allowed in the scene."); + GvrAudioListener.Destroy(listener); + } + } + + /// Shuts down the audio system. + /// @note This should only be called from the main Unity thread. + public static void Shutdown (GvrAudioListener listener) { + if (initialized && listener.transform == listenerTransform) { + initialized = false; + + Shutdown(); + sampleRate = -1; + numChannels = -1; + framesPerBuffer = -1; + } + } + + /// Updates the audio listener. + /// @note This should only be called from the main Unity thread. + public static void UpdateAudioListener (float globalGainDb, LayerMask occlusionMask, + float worldScale) { + if (initialized) { + occlusionMaskValue = occlusionMask.value; + worldScaleInverse = 1.0f / worldScale; + float globalGain = ConvertAmplitudeFromDb(globalGainDb); + Vector3 position = listenerTransform.position; + Quaternion rotation = listenerTransform.rotation; + ConvertAudioTransformFromUnity(ref position, ref rotation); + // Pass listener properties to the system. + SetListenerGain(globalGain); + SetListenerTransform(position.x, position.y, position.z, rotation.x, rotation.y, rotation.z, + rotation.w); + } + } + + /// Creates a new audio source with a unique id. + /// @note This should only be called from the main Unity thread. + public static int CreateAudioSource (bool hrtfEnabled) { + int sourceId = -1; + if (initialized) { + sourceId = CreateSource(hrtfEnabled); + } + return sourceId; + } + + /// Destroys the audio source with given |id|. + /// @note This should only be called from the main Unity thread. + public static void DestroyAudioSource (int id) { + if (initialized) { + DestroySource(id); + } + } + + /// Updates the audio source with given |id| and its properties. + /// @note This should only be called from the main Unity thread. + public static void UpdateAudioSource (int id, Transform transform, bool bypassRoomEffects, + float gainDb, float spread, AudioRolloffMode rolloffMode, + float minDistance, float maxDistance, float alpha, + float sharpness, float occlusion) { + if (initialized) { + float gain = ConvertAmplitudeFromDb(gainDb); + Vector3 position = transform.position; + Quaternion rotation = transform.rotation; + ConvertAudioTransformFromUnity(ref position, ref rotation); + float spreadRad = Mathf.Deg2Rad * spread; + // Pass the source properties to the audio system. + SetSourceBypassRoomEffects(id, bypassRoomEffects); + SetSourceDirectivity(id, alpha, sharpness); + SetSourceGain(id, gain); + SetSourceOcclusionIntensity(id, occlusion); + if (rolloffMode != AudioRolloffMode.Custom) { + float maxDistanceScaled = worldScaleInverse * maxDistance; + float minDistanceScaled = worldScaleInverse * minDistance; + SetSourceDistanceAttenuationMethod(id, rolloffMode, minDistanceScaled, maxDistanceScaled); + } + SetSourceSpread(id, spreadRad); + SetSourceTransform(id, position.x, position.y, position.z, rotation.x, rotation.y, rotation.z, + rotation.w); + } + } + + /// Creates a new room with a unique id. + /// @note This should only be called from the main Unity thread. + public static int CreateAudioRoom () { + int roomId = -1; + if (initialized) { + roomId = CreateRoom(); + } + return roomId; + } + + /// Destroys the room with given |id|. + /// @note This should only be called from the main Unity thread. + public static void DestroyAudioRoom (int id) { + if (initialized) { + DestroyRoom(id); + } + } + + /// Updates the room effects of the environment with given |room| properties. + /// @note This should only be called from the main Unity thread. + public static void UpdateAudioRoom (int id, Transform transform, + GvrAudioRoom.SurfaceMaterial[] materials, float reflectivity, + float reverbGainDb, float reverbBrightness, float reverbTime, + Vector3 size) { + if (initialized) { + // Update room transform. + Vector3 position = transform.position; + Quaternion rotation = transform.rotation; + Vector3 scale = Vector3.Scale(size, transform.lossyScale); + scale = worldScaleInverse * new Vector3(Mathf.Abs(scale.x), Mathf.Abs(scale.y), + Mathf.Abs(scale.z)); + ConvertAudioTransformFromUnity(ref position, ref rotation); + float reverbGain = ConvertAmplitudeFromDb(reverbGainDb); + SetRoomProperties(id, position.x, position.y, position.z, rotation.x, rotation.y, rotation.z, + rotation.w, scale.x, scale.y, scale.z, materials, reflectivity, reverbGain, + reverbBrightness, reverbTime); + } + } + + /// Computes the occlusion intensity of a given |source| using point source detection. + /// @note This should only be called from the main Unity thread. + public static float ComputeOcclusion (Transform sourceTransform) { + float occlusion = 0.0f; + if (initialized) { + Vector3 listenerPosition = listenerTransform.position; + Vector3 sourceFromListener = sourceTransform.position - listenerPosition; + RaycastHit[] hits = Physics.RaycastAll(listenerPosition, sourceFromListener, + sourceFromListener.magnitude, occlusionMaskValue); + foreach (RaycastHit hit in hits) { + if (hit.transform != listenerTransform && hit.transform != sourceTransform) { + occlusion += 1.0f; + } + } + } + return occlusion; + } + + /// Generates a set of points to draw a 2D polar pattern. + public static Vector2[] Generate2dPolarPattern (float alpha, float order, int resolution) { + Vector2[] points = new Vector2[resolution]; + float interval = 2.0f * Mathf.PI / resolution; + for (int i = 0; i < resolution; ++i) { + float theta = i * interval; + // Magnitude |r| for |theta| in radians. + float r = Mathf.Pow(Mathf.Abs((1 - alpha) + alpha * Mathf.Cos(theta)), order); + points[i] = new Vector2(r * Mathf.Sin(theta), r * Mathf.Cos(theta)); + } + return points; + } + + /// Minimum distance threshold between |minDistance| and |maxDistance|. + public const float distanceEpsilon = 0.01f; + + /// Max distance limit that can be set for volume rolloff. + public const float maxDistanceLimit = 1000000.0f; + + /// Min distance limit that can be set for volume rolloff. + public const float minDistanceLimit = 990099.0f; + + /// Maximum allowed gain value in decibels. + public const float maxGainDb = 24.0f; + + /// Minimum allowed gain value in decibels. + public const float minGainDb = -24.0f; + + /// Maximum allowed real world scale with respect to Unity. + public const float maxWorldScale = 1000.0f; + + /// Minimum allowed real world scale with respect to Unity. + public const float minWorldScale = 0.001f; + + /// Maximum allowed reverb brightness modifier value. + public const float maxReverbBrightness = 1.0f; + + /// Minimum allowed reverb brightness modifier value. + public const float minReverbBrightness = -1.0f; + + /// Maximum allowed reverb time modifier value. + public const float maxReverbTime = 3.0f; + + /// Maximum allowed reflectivity multiplier of a room surface material. + public const float maxReflectivity = 2.0f; + + /// Source occlusion detection rate in seconds. + public const float occlusionDetectionInterval = 0.2f; + + /// Number of surfaces in a room. + public const int numRoomSurfaces = 6; + + /// Converts given |db| value to its amplitude equivalent where 'dB = 20 * log10(amplitude)'. + private static float ConvertAmplitudeFromDb (float db) { + return Mathf.Pow(10.0f, 0.05f * db); + } + + // Converts given |position| and |rotation| from Unity space to audio space. + private static void ConvertAudioTransformFromUnity (ref Vector3 position, + ref Quaternion rotation) { + pose.SetRightHanded(Matrix4x4.TRS(position, rotation, Vector3.one)); + position = pose.Position * worldScaleInverse; + rotation = pose.Orientation; + } + + // Denotes whether the system is initialized properly. + private static bool initialized = false; + + // Listener transform. + private static Transform listenerTransform = null; + + // Occlusion layer mask. + private static int occlusionMaskValue = -1; + + // 3D pose instance to be used in transform space conversion. + private static MutablePose3D pose = new MutablePose3D(); + + // Inverted world scale. + private static float worldScaleInverse = 1.0f; + +#if !UNITY_EDITOR && UNITY_ANDROID + private const string GvrAudioClass = "com.google.vr.audio.unity.GvrAudio"; + + private static void SetApplicationState() { + using (var gvrAudioClass = Gvr.Internal.BaseAndroidDevice.GetClass(GvrAudioClass)) { + Gvr.Internal.BaseAndroidDevice.CallStaticMethod(gvrAudioClass, "setUnityApplicationState"); + } + } +#endif + +#if UNITY_IOS + private const string pluginName = "__Internal"; +#else + private const string pluginName = "audioplugingvrunity"; +#endif + + [DllImport(pluginName)] + private static extern void SetListenerGain (float gain); + + [DllImport(pluginName)] + private static extern void SetListenerTransform (float px, float py, float pz, float qx, float qy, + float qz, float qw); + + // Source handlers. + [DllImport(pluginName)] + private static extern int CreateSource (bool enableHrtf); + + [DllImport(pluginName)] + private static extern void DestroySource (int sourceId); + + [DllImport(pluginName)] + private static extern void SetSourceBypassRoomEffects (int sourceId, bool bypassRoomEffects); + + [DllImport(pluginName)] + private static extern void SetSourceDirectivity (int sourceId, float alpha, float order); + + [DllImport(pluginName)] + private static extern void SetSourceDistanceAttenuationMethod (int sourceId, + AudioRolloffMode rolloffMode, + float minDistance, + float maxDistance); + + [DllImport(pluginName)] + private static extern void SetSourceGain (int sourceId, float gain); + + [DllImport(pluginName)] + private static extern void SetSourceOcclusionIntensity (int sourceId, float intensity); + + [DllImport(pluginName)] + private static extern void SetSourceSpread (int sourceId, float spreadRad); + + [DllImport(pluginName)] + private static extern void SetSourceTransform (int sourceId, float px, float py, float pz, + float qx, float qy, float qz, float qw); + + // Room handlers. + [DllImport(pluginName)] + private static extern int CreateRoom (); + + [DllImport(pluginName)] + private static extern void DestroyRoom (int roomId); + + [DllImport(pluginName)] + private static extern void SetRoomProperties (int roomId, float px, float py, float pz, float qx, + float qy, float qz, float qw, float dx, float dy, + float dz, + GvrAudioRoom.SurfaceMaterial[] materialNames, + float reflectionScalar, float reverbGain, + float reverbBrightness, float reverbTime); + + // System handlers. + [DllImport(pluginName)] + private static extern void Initialize (Quality quality, int sampleRate, int numChannels, + int framesPerBuffer); + + [DllImport(pluginName)] + private static extern void Shutdown (); +} diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudio.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudio.cs.meta new file mode 100644 index 0000000000..094009bbb3 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudio.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 84ad368148aad42938b2fdb28552e8ac +timeCreated: 1447961130 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudioListener.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudioListener.cs new file mode 100644 index 0000000000..f31ac8acde --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudioListener.cs @@ -0,0 +1,52 @@ +// Copyright 2016 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. + +using UnityEngine; +using System.Collections; + +/// GVR audio listener component that enhances AudioListener to provide advanced spatial audio +/// features. +/// +/// There should be only one instance of this which is attached to the AudioListener's game object. +[AddComponentMenu("GoogleVR/Audio/GvrAudioListener")] +public class GvrAudioListener : MonoBehaviour { + /// Global gain in decibels to be applied to the processed output. + public float globalGainDb = 0.0f; + + /// Global scale of the real world with respect to the Unity environment. + public float worldScale = 1.0f; + + /// Global layer mask to be used in occlusion detection. + public LayerMask occlusionMask = -1; + + /// Audio rendering quality of the system. + [SerializeField] + private GvrAudio.Quality quality = GvrAudio.Quality.High; + + void Awake () { + GvrAudio.Initialize(this, quality); + } + + void OnEnable () { + GvrAudio.UpdateAudioListener(globalGainDb, occlusionMask, worldScale); + } + + void OnDestroy () { + GvrAudio.Shutdown(this); + } + + void Update () { + GvrAudio.UpdateAudioListener(globalGainDb, occlusionMask, worldScale); + } +} diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudioListener.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudioListener.cs.meta new file mode 100644 index 0000000000..f1764fcee0 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudioListener.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b1156c073149742478887bb24456f32d +timeCreated: 1447961345 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudioRoom.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudioRoom.cs new file mode 100644 index 0000000000..c0400a077e --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudioRoom.cs @@ -0,0 +1,140 @@ +// Copyright 2016 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. + +using UnityEngine; +using System.Collections; + +/// GVR audio room component that simulates environmental effects of a room with respect to the +/// properties of the attached game object. +[AddComponentMenu("GoogleVR/Audio/GvrAudioRoom")] +public class GvrAudioRoom : MonoBehaviour { + /// Material type that determines the acoustic properties of a room surface. + public enum SurfaceMaterial { + Transparent = 0, + AcousticCeilingTiles = 1, + BrickBare = 2, + BrickPainted = 3, + ConcreteBlockCoarse = 4, + ConcreteBlockPainted = 5, + CurtainHeavy = 6, + FiberglassInsulation = 7, + GlassThin = 8, + GlassThick = 9, + Grass = 10, + LinoleumOnConcrete = 11, + Marble = 12, + ParquetOnConcrete = 13, + PlasterRough = 14, + PlasterSmooth = 15, + PlywoodPanel = 16, + PolishedConcreteOrTile = 17, + Sheetrock = 18, + WaterOrIceSurface = 19, + WoodCeiling = 20, + WoodPanel = 21 + } + + /// Room surface material in negative x direction. + public SurfaceMaterial leftWall = SurfaceMaterial.ConcreteBlockCoarse; + + /// Room surface material in positive x direction. + public SurfaceMaterial rightWall = SurfaceMaterial.ConcreteBlockCoarse; + + /// Room surface material in negative y direction. + public SurfaceMaterial floor = SurfaceMaterial.ParquetOnConcrete; + + /// Room surface material in positive y direction. + public SurfaceMaterial ceiling = SurfaceMaterial.PlasterRough; + + /// Room surface material in negative z direction. + public SurfaceMaterial backWall = SurfaceMaterial.ConcreteBlockCoarse; + + /// Room surface material in positive z direction. + public SurfaceMaterial frontWall = SurfaceMaterial.ConcreteBlockCoarse; + + /// Reflectivity scalar for each surface of the room. + public float reflectivity = 1.0f; + + /// Reverb gain modifier in decibels. + public float reverbGainDb = 0.0f; + + /// Reverb brightness modifier. + public float reverbBrightness = 0.0f; + + /// Reverb time modifier. + public float reverbTime = 1.0f; + + /// Size of the room (normalized with respect to scale of the game object). + public Vector3 size = Vector3.one; + + /// Unique room id. + private int id = -1; + + /// Surface materials holder. + private SurfaceMaterial[] surfaceMaterials = null; + + void Awake () { + surfaceMaterials = new SurfaceMaterial[GvrAudio.numRoomSurfaces]; + } + + void OnEnable () { + InitializeRoom(); + } + + void Start () { + InitializeRoom(); + } + + void OnDisable () { + ShutdownRoom(); + } + + void Update () { + GvrAudio.UpdateAudioRoom(id, transform, GetSurfaceMaterials(), reflectivity, reverbGainDb, + reverbBrightness, reverbTime, size); + } + + /// Returns a list of surface materials of the room. + public SurfaceMaterial[] GetSurfaceMaterials () { + surfaceMaterials[0] = leftWall; + surfaceMaterials[1] = rightWall; + surfaceMaterials[2] = floor; + surfaceMaterials[3] = ceiling; + surfaceMaterials[4] = backWall; + surfaceMaterials[5] = frontWall; + return surfaceMaterials; + } + + private void InitializeRoom () { + if (id < 0) { + id = GvrAudio.CreateAudioRoom(); + GvrAudio.UpdateAudioRoom(id, transform, GetSurfaceMaterials(), reflectivity, reverbGainDb, + reverbBrightness, reverbTime, size); + } + } + + private void ShutdownRoom () { + if (id >= 0) { + GvrAudio.DestroyAudioRoom(id); + id = -1; + } + } + + void OnDrawGizmosSelected () { + // Draw shoebox model wireframe of the room. + Gizmos.color = Color.yellow; + Gizmos.matrix = transform.localToWorldMatrix; + Gizmos.DrawWireCube(Vector3.zero, size); + } +} diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudioRoom.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudioRoom.cs.meta new file mode 100644 index 0000000000..08c8c6e813 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Audio/GvrAudioRoom.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1d2722c2401e34d51bf5b473ef7aeefb +timeCreated: 1447961354 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrEye.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrEye.cs new file mode 100644 index 0000000000..8542515fff --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrEye.cs @@ -0,0 +1,317 @@ +// Copyright 2014 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. + +using UnityEngine; + +/// Controls one camera of a stereo pair. Each frame, it mirrors the settings of +/// the parent mono Camera, and then sets up side-by-side stereo with +/// the view and projection matrices from the GvrViewer.EyeView and GvrViewer.Projection. +/// The render output is directed to the GvrViewer.StereoScreen render texture, either +/// to the left half or right half depending on the chosen eye. +/// +/// To enable a stereo camera pair, enable the parent mono camera and set +/// GvrViewer.vrModeEnabled = true. +/// +/// @note If you programmatically change the set of GvrEyes belonging to a +/// StereoController, be sure to call StereoController::InvalidateEyes on it +/// in order to reset its cache. +[RequireComponent(typeof(Camera))] +[AddComponentMenu("GoogleVR/GvrEye")] +public class GvrEye : MonoBehaviour { + /// Whether this is the left eye or the right eye. + /// Determines which stereo eye to render, that is, which `EyeOffset` and + /// `Projection` matrix to use and which half of the screen to render to. + public GvrViewer.Eye eye; + + /// Allows you to flip on or off specific culling mask layers for just this + /// eye. The mask is a toggle: The eye's culling mask is first copied from + /// the parent mono camera, and then the layers specified here are flipped. + /// Each eye has its own toggle mask. + [Tooltip("Culling mask layers that this eye should toggle relative to the parent camera.")] + public LayerMask toggleCullingMask = 0; + + /// The StereoController in charge of this eye (and whose mono camera + /// we will copy settings from). + public StereoController Controller { + // This property is set up to work both in editor and in player. + get { + if (transform.parent == null) { // Should not happen. + return null; + } + if ((Application.isEditor && !Application.isPlaying) || controller == null) { + // Go find our controller. + return transform.parent.GetComponentInParent(); + } + return controller; + } + } + + /// Returns the closest ancestor GvrHead. + /// @note Uses GetComponentInParent(), so the result will be null if no active ancestor is found. + public GvrHead Head { + get { + return GetComponentInParent(); + } + } + + private StereoController controller; + private StereoRenderEffect stereoEffect; + private Camera monoCamera; + private Matrix4x4 realProj; + private float interpPosition = 1; + + // Convenient accessor to the camera component used throughout this script. + public Camera cam { get; private set; } + + void Awake() { + cam = GetComponent(); + } + + void Start() { + var ctlr = Controller; + if (ctlr == null) { + Debug.LogError("GvrEye must be child of a StereoController."); + enabled = false; + return; + } + // Save reference to the found controller and it's camera. + controller = ctlr; + monoCamera = controller.GetComponent(); + UpdateStereoValues(); + } + + private void FixProjection(ref Matrix4x4 proj) { + // Adjust for non-fullscreen camera. GvrViewer assumes fullscreen, + // so the aspect ratio might not match. + proj[0, 0] *= cam.rect.height / cam.rect.width / 2; + + // GvrViewer had to pass "nominal" values of near/far to the native layer, which + // we fix here to match our mono camera's specific values. + float near = monoCamera.nearClipPlane; + float far = monoCamera.farClipPlane; + proj[2, 2] = (near + far) / (near - far); + proj[2, 3] = 2 * near * far / (near - far); + } + + private Rect FixViewport(Rect rect) { + // We are rendering straight to the screen. Use the reported rect that is visible + // through the device's lenses. + Rect view = GvrViewer.Instance.Viewport(eye); + if (eye == GvrViewer.Eye.Right) { + rect.x -= 0.5f; + } + rect.width *= 2 * view.width; + rect.x = view.x + 2 * rect.x * view.width; + rect.height *= view.height; + rect.y = view.y + rect.y * view.height; + if (Application.isEditor) { + // The Game window's aspect ratio may not match the fake device parameters. + float realAspect = (float)Screen.width / Screen.height; + float fakeAspect = GvrViewer.Instance.Profile.screen.width / GvrViewer.Instance.Profile.screen.height; + float aspectComparison = fakeAspect / realAspect; + if (aspectComparison < 1) { + rect.width *= aspectComparison; + rect.x *= aspectComparison; + rect.x += (1 - aspectComparison) / 2; + } else { + rect.height /= aspectComparison; + rect.y /= aspectComparison; + } + } + return rect; + } + + public void UpdateStereoValues() { + Matrix4x4 proj = GvrViewer.Instance.Projection(eye); + realProj = GvrViewer.Instance.Projection(eye, GvrViewer.Distortion.Undistorted); + + CopyCameraAndMakeSideBySide(controller, proj[0, 2], proj[1, 2]); + + // Fix aspect ratio and near/far clipping planes. + FixProjection(ref proj); + FixProjection(ref realProj); + + // Zoom the stereo cameras if requested. + float lerp = Mathf.Clamp01(controller.matchByZoom) * Mathf.Clamp01(controller.matchMonoFOV); + // Lerping the reciprocal of proj(1,1), so zoom is linear in frustum height not the depth. + float monoProj11 = monoCamera.projectionMatrix[1, 1]; + float zoom = 1 / Mathf.Lerp(1 / proj[1, 1], 1 / monoProj11, lerp) / proj[1, 1]; + proj[0, 0] *= zoom; + proj[1, 1] *= zoom; + + // Set the eye camera's projection for rendering. + cam.projectionMatrix = proj; + if (Application.isEditor) { + // So you can see the approximate frustum in the Scene view when the camera is selected. + cam.fieldOfView = 2 * Mathf.Atan(1 / proj[1, 1]) * Mathf.Rad2Deg; + } + + // Draw to the mono camera's target, or the stereo screen. + cam.targetTexture = monoCamera.targetTexture ?? GvrViewer.Instance.StereoScreen; + if (cam.targetTexture == null) { + // When drawing straight to screen, account for lens FOV limits. + // Note: do this after all calls to FixProjection() which needs the unfixed rect. + cam.rect = FixViewport(cam.rect); + } + } + + private void SetupStereo() { + GvrViewer.Instance.UpdateState(); + + // Will need to update view transform if there is a COI, or if there is a remnant of + // prior stereo-adjustment smoothing to finish off. + bool haveCOI = controller.centerOfInterest != null + && controller.centerOfInterest.gameObject.activeInHierarchy; + bool updatePosition = haveCOI || interpPosition < 1; + + if (controller.keepStereoUpdated || GvrViewer.Instance.ProfileChanged + || cam.targetTexture == null && GvrViewer.Instance.StereoScreen != null) { + // Set projection and viewport. + UpdateStereoValues(); + // Also view transform. + updatePosition = true; + } + + if (updatePosition) { + // Set view transform. + float proj11 = cam.projectionMatrix[1, 1]; + float zScale = transform.lossyScale.z; + Vector3 eyePos = controller.ComputeStereoEyePosition(eye, proj11, zScale); + // Apply smoothing only if updating position every frame. + interpPosition = controller.keepStereoUpdated || haveCOI ? + Time.deltaTime / (controller.stereoAdjustSmoothing + Time.deltaTime) : 1; + transform.localPosition = Vector3.Lerp(transform.localPosition, eyePos, interpPosition); + } + + // Pass necessary information to any shaders doing distortion correction. + if (GvrViewer.Instance.DistortionCorrection == GvrViewer.DistortionCorrectionMethod.None) { + // Correction matrix for use in surface shaders that do vertex warping for distortion. + // Have to compute it every frame because cameraToWorldMatrix is changing constantly. + var fixProj = cam.cameraToWorldMatrix * + Matrix4x4.Inverse(cam.projectionMatrix) * + realProj; + Shader.SetGlobalMatrix("_RealProjection", realProj); + Shader.SetGlobalMatrix("_FixProjection", fixProj); + Shader.EnableKeyword("GVR_DISTORTION"); + } + Shader.SetGlobalFloat("_NearClip", cam.nearClipPlane); + } + + void OnPreCull() { + if (!GvrViewer.Instance.VRModeEnabled || !monoCamera.enabled) { + // Keep stereo enabled flag in sync with parent mono camera. + cam.enabled = false; + return; + } + SetupStereo(); + if (!controller.directRender && GvrViewer.Instance.StereoScreen != null) { + // Some image effects clobber the whole screen. Add a final image effect to the chain + // which restores side-by-side stereo. + stereoEffect = GetComponent(); + if (stereoEffect == null) { + stereoEffect = gameObject.AddComponent(); + } + stereoEffect.enabled = true; + } else if (stereoEffect != null) { + // Don't need the side-by-side image effect. + stereoEffect.enabled = false; + } + } + + void OnPostRender() { + Shader.DisableKeyword("GVR_DISTORTION"); + } + + /// Helper to copy camera settings from the controller's mono camera. Used in SetupStereo() and + /// in the custom editor for StereoController. The parameters parx and pary, if not left at + /// default, should come from a projection matrix returned by the SDK. They affect the apparent + /// depth of the camera's window. See SetupStereo(). + public void CopyCameraAndMakeSideBySide(StereoController controller, + float parx = 0, float pary = 0) { +#if UNITY_EDITOR + // Member variable 'cam' not always initialized when this method called in Editor. + // So, we'll just make a local of the same name. + var cam = GetComponent(); +#endif + // Same for controller's camera, but it can happen at runtime too (via AddStereoRig on + // StereoController). + var monoCamera = + controller == this.controller ? this.monoCamera : controller.GetComponent(); + + float ipd = GvrProfile.Default.viewer.lenses.separation * controller.stereoMultiplier; + Vector3 localPosition = Application.isPlaying ? + transform.localPosition : (eye == GvrViewer.Eye.Left ? -ipd/2 : ipd/2) * Vector3.right;; + + // Sync the camera properties. + cam.CopyFrom(monoCamera); + cam.cullingMask ^= toggleCullingMask.value; + + // Not sure why we have to do this, but if we don't then switching between drawing to + // the main screen or to the stereo rendertexture acts very strangely. + cam.depth = monoCamera.depth; + + // Reset transform, which was clobbered by the CopyFrom() call. + // Since we are a child of the mono camera, we inherit its transform already. + transform.localPosition = localPosition; + transform.localRotation = Quaternion.identity; + transform.localScale = Vector3.one; + + Skybox monoCameraSkybox = monoCamera.GetComponent(); + Skybox customSkybox = GetComponent(); + if(monoCameraSkybox != null) { + if (customSkybox == null) { + customSkybox = gameObject.AddComponent(); + } + customSkybox.material = monoCameraSkybox.material; + } else if (customSkybox != null) { + Destroy(customSkybox); + } + + // Set up side-by-side stereo. + // Note: The code is written this way so that non-fullscreen cameras + // (PIP: picture-in-picture) still work in stereo. Even if the PIP's content is + // not going to be in stereo, the PIP itself still has to be rendered in both eyes. + Rect rect = cam.rect; + + // Move away from edges if padding requested. Some HMDs make the edges of the + // screen a bit hard to see. + Vector2 center = rect.center; + center.x = Mathf.Lerp(center.x, 0.5f, Mathf.Clamp01(controller.stereoPaddingX)); + center.y = Mathf.Lerp(center.y, 0.5f, Mathf.Clamp01(controller.stereoPaddingY)); + rect.center = center; + + // Semi-hacky aspect ratio adjustment because the screen is only half as wide due + // to side-by-side stereo, to make sure the PIP width fits. + float width = Mathf.SmoothStep(-0.5f, 0.5f, (rect.width + 1) / 2); + rect.x += (rect.width - width) / 2; + rect.width = width; + + // Divide the outside region of window proportionally in each half of the screen. + rect.x *= (0.5f - rect.width) / (1 - rect.width); + if (eye == GvrViewer.Eye.Right) { + rect.x += 0.5f; // Move to right half of the screen. + } + + // Adjust the window for requested parallax. This affects the apparent depth of the + // window in the main camera's screen. Useful for PIP windows only, where rect.width < 1. + float parallax = Mathf.Clamp01(controller.screenParallax); + if (monoCamera.rect.width < 1 && parallax > 0) { + // Note: parx and pary are signed, with opposite signs in each eye. + rect.x -= parx / 4 * parallax; // Extra factor of 1/2 because of side-by-side stereo. + rect.y -= pary / 2 * parallax; + } + + cam.rect = rect; + } +} diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrEye.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrEye.cs.meta new file mode 100644 index 0000000000..d4c4a0ada0 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrEye.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5c9cfdc6c389e2742aa40f991195d828 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrHead.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrHead.cs new file mode 100644 index 0000000000..277b562bdf --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrHead.cs @@ -0,0 +1,130 @@ +// Copyright 2014 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. + +using UnityEngine; + +/// This script provides head tracking support for a camera. +/// +/// Attach this script to any game object that should match the user's head motion. +/// By default, it continuously updates the local transform to GvrViewer.HeadView. +/// A target object may be specified to provide an alternate reference frame for the motion. +/// +/// This script will typically be attached directly to a _Camera_ object, or to its +/// parent if you need to offset the camera from the origin. +/// Alternatively it can be inserted as a child of the _Camera_ but parent of the +/// GvrEye camera. Do this if you already have steering logic driving the +/// mono Camera and wish to have the user's head motion be relative to that. Note +/// that in the latter setup, head tracking is visible only when VR Mode is enabled. +/// +/// In some cases you may need two instances of GvrHead, referring to two +/// different targets (one of which may be the parent), in order to split where +/// the rotation is applied from where the positional offset is applied. Use the +/// #trackRotation and #trackPosition properties in this case. +[AddComponentMenu("GoogleVR/GvrHead")] +public class GvrHead : MonoBehaviour { + /// Determines whether to apply the user's head rotation to this gameobject's + /// orientation. True means to update the gameobject's orientation with the + /// user's head rotation, and false means don't modify the gameobject's orientation. + public bool trackRotation = true; + + /// Determines whether to apply ther user's head offset to this gameobject's + /// position. True means to update the gameobject's position with the user's head offset, + /// and false means don't modify the gameobject's position. + public bool trackPosition = true; + + /// The user's head motion will be applied in this object's reference frame + /// instead of the head object's parent. A good use case is for head-based + /// steering. Normally, turning the parent object (i.e. the body or vehicle) + /// towards the direction the user is looking would carry the head along with it, + /// thus creating a positive feedback loop. Use an external target object as a + /// fixed point of reference for the direction the user is looking. Often, the + /// grandparent or higher ancestor is a suitable target. + public Transform target; + + /// Determines whether the head tracking is applied during `LateUpdate()` or + /// `Update()`. The default is false, which means it is applied during `LateUpdate()` + /// to reduce latency. + /// + /// However, some scripts may need to use the camera's direction to affect the gameplay, + /// e.g by casting rays or steering a vehicle, during the `LateUpdate()` phase. + /// This can cause an annoying jitter because Unity, during this `LateUpdate()` + /// phase, will update the head object first on some frames but second on others. + /// If this is the case for your game, try switching the head to apply head tracking + /// during `Update()` by setting this to true. + public bool updateEarly = false; + + /// Returns a ray based on the heads position and forward direction, after making + /// sure the transform is up to date. Use to raycast into the scene to determine + /// objects that the user is looking at. + public Ray Gaze { + get { + UpdateHead(); + return new Ray(transform.position, transform.forward); + } + } + + public delegate void HeadUpdatedDelegate(GameObject head); + + /// Called after the head pose has been updated with the latest sensor data. + public event HeadUpdatedDelegate OnHeadUpdated; + + void Awake() { + GvrViewer.Create(); + } + + private bool updated; + + void Update() { + updated = false; // OK to recompute head pose. + if (updateEarly) { + UpdateHead(); + } + } + + // Normally, update head pose now. + void LateUpdate() { + UpdateHead(); + } + + // Compute new head pose. + private void UpdateHead() { + if (updated) { // Only one update per frame, please. + return; + } + updated = true; + GvrViewer.Instance.UpdateState(); + + if (trackRotation) { + var rot = GvrViewer.Instance.HeadPose.Orientation; + if (target == null) { + transform.localRotation = rot; + } else { + transform.rotation = target.rotation * rot; + } + } + + if (trackPosition) { + Vector3 pos = GvrViewer.Instance.HeadPose.Position; + if (target == null) { + transform.localPosition = pos; + } else { + transform.position = target.position + target.rotation * pos; + } + } + + if (OnHeadUpdated != null) { + OnHeadUpdated(gameObject); + } + } +} diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrHead.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrHead.cs.meta new file mode 100644 index 0000000000..3c36e85d9c --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrHead.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f1578549c7fcc4f6fa1b063992091672 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrPostRender.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrPostRender.cs new file mode 100644 index 0000000000..3f51dac835 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrPostRender.cs @@ -0,0 +1,348 @@ +// 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. + +using UnityEngine; + +/// Performs distortion correction on the rendered stereo screen. This script +/// and GvrPreRender work together to draw the whole screen in VR Mode. +/// There should be exactly one of each component in any GVR-enabled scene. It +/// is part of the _GvrCamera_ prefab, which is included in +/// _GvrMain_. The GvrViewer script will create one at runtime if the +/// scene doesn't already have it, so generally it is not necessary to manually +/// add it unless you wish to edit the Camera component that it controls. +/// +/// In the Unity editor, this script also draws the analog of the UI layer on +/// the phone (alignment marker, settings gear, etc). +[RequireComponent(typeof(Camera))] +[AddComponentMenu("GoogleVR/GvrPostRender")] +public class GvrPostRender : MonoBehaviour { + + // Convenient accessor to the camera component used through this script. + public Camera cam { get; private set; } + + // Distortion mesh parameters. + + // Size of one eye's distortion mesh grid. The whole mesh is two of these grids side by side. + private const int kMeshWidth = 40; + private const int kMeshHeight = 40; + // Whether to apply distortion in the grid coordinates or in the texture coordinates. + private const bool kDistortVertices = true; + + private Mesh distortionMesh; + private Material meshMaterial; + + // UI Layer parameters. + private Material uiMaterial; + private float centerWidthPx; + private float buttonWidthPx; + private float xScale; + private float yScale; + private Matrix4x4 xfm; + + void Reset() { +#if UNITY_EDITOR + // Member variable 'cam' not always initialized when this method called in Editor. + // So, we'll just make a local of the same name. + var cam = GetComponent(); +#endif + cam.clearFlags = CameraClearFlags.Depth; + cam.backgroundColor = Color.magenta; // Should be noticeable if the clear flags change. + cam.orthographic = true; + cam.orthographicSize = 0.5f; + cam.cullingMask = 0; + cam.useOcclusionCulling = false; + cam.depth = 100; + } + + void Awake() { + cam = GetComponent(); + Reset(); + meshMaterial = new Material(Shader.Find("GoogleVR/UnlitTexture")); + uiMaterial = new Material(Shader.Find("GoogleVR/SolidColor")); + uiMaterial.color = new Color(0.8f, 0.8f, 0.8f); + if (!Application.isEditor) { + ComputeUIMatrix(); + } + } + +#if UNITY_EDITOR + private float aspectComparison; + + void OnPreCull() { + // The Game window's aspect ratio may not match the fake device parameters. + float realAspect = (float)Screen.width / Screen.height; + float fakeAspect = GvrViewer.Instance.Profile.screen.width / GvrViewer.Instance.Profile.screen.height; + aspectComparison = fakeAspect / realAspect; + cam.orthographicSize = 0.5f * Mathf.Max(1, aspectComparison); + } +#endif + + void OnRenderObject() { + if (Camera.current != cam) + return; + GvrViewer.Instance.UpdateState(); + var correction = GvrViewer.Instance.DistortionCorrection; + RenderTexture stereoScreen = GvrViewer.Instance.StereoScreen; + if (stereoScreen == null || correction == GvrViewer.DistortionCorrectionMethod.None) { + return; + } + if (correction == GvrViewer.DistortionCorrectionMethod.Native + && GvrViewer.Instance.NativeDistortionCorrectionSupported) { + GvrViewer.Instance.PostRender(stereoScreen); + } else { + if (distortionMesh == null || GvrViewer.Instance.ProfileChanged) { + RebuildDistortionMesh(); + } + meshMaterial.mainTexture = stereoScreen; + meshMaterial.SetPass(0); + Graphics.DrawMeshNow(distortionMesh, transform.position, transform.rotation); + } + stereoScreen.DiscardContents(); + if (!GvrViewer.Instance.NativeUILayerSupported && GvrViewer.Instance.UILayerEnabled) { + DrawUILayer(); + } + } + + private void RebuildDistortionMesh() { + distortionMesh = new Mesh(); + Vector3[] vertices; + Vector2[] tex; + ComputeMeshPoints(kMeshWidth, kMeshHeight, kDistortVertices, out vertices, out tex); + int[] indices = ComputeMeshIndices(kMeshWidth, kMeshHeight, kDistortVertices); + Color[] colors = ComputeMeshColors(kMeshWidth, kMeshHeight, tex, indices, kDistortVertices); + distortionMesh.vertices = vertices; + distortionMesh.uv = tex; + distortionMesh.colors = colors; + distortionMesh.triangles = indices; + distortionMesh.Optimize(); + distortionMesh.UploadMeshData(true); + } + + private static void ComputeMeshPoints(int width, int height, bool distortVertices, + out Vector3[] vertices, out Vector2[] tex) { + float[] lensFrustum = new float[4]; + float[] noLensFrustum = new float[4]; + Rect viewport; + GvrProfile profile = GvrViewer.Instance.Profile; + profile.GetLeftEyeVisibleTanAngles(lensFrustum); + profile.GetLeftEyeNoLensTanAngles(noLensFrustum); + viewport = profile.GetLeftEyeVisibleScreenRect(noLensFrustum); + vertices = new Vector3[2 * width * height]; + tex = new Vector2[2 * width * height]; + for (int e = 0, vidx = 0; e < 2; e++) { + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++, vidx++) { + float u = (float)i / (width - 1); + float v = (float)j / (height - 1); + float s, t; // The texture coordinates in StereoScreen to read from. + if (distortVertices) { + // Grid points regularly spaced in StreoScreen, and barrel distorted in the mesh. + s = u; + t = v; + float x = Mathf.Lerp(lensFrustum[0], lensFrustum[2], u); + float y = Mathf.Lerp(lensFrustum[3], lensFrustum[1], v); + float d = Mathf.Sqrt(x * x + y * y); + float r = profile.viewer.distortion.distortInv(d); + float p = x * r / d; + float q = y * r / d; + u = (p - noLensFrustum[0]) / (noLensFrustum[2] - noLensFrustum[0]); + v = (q - noLensFrustum[3]) / (noLensFrustum[1] - noLensFrustum[3]); + } else { + // Grid points regularly spaced in the mesh, and pincushion distorted in + // StereoScreen. + float p = Mathf.Lerp(noLensFrustum[0], noLensFrustum[2], u); + float q = Mathf.Lerp(noLensFrustum[3], noLensFrustum[1], v); + float r = Mathf.Sqrt(p * p + q * q); + float d = profile.viewer.distortion.distort(r); + float x = p * d / r; + float y = q * d / r; + s = Mathf.Clamp01((x - lensFrustum[0]) / (lensFrustum[2] - lensFrustum[0])); + t = Mathf.Clamp01((y - lensFrustum[3]) / (lensFrustum[1] - lensFrustum[3])); + } + // Convert u,v to mesh screen coordinates. + float aspect = profile.screen.width / profile.screen.height; + u = (viewport.x + u * viewport.width - 0.5f) * aspect; + v = viewport.y + v * viewport.height - 0.5f; + vertices[vidx] = new Vector3(u, v, 1); + // Adjust s to account for left/right split in StereoScreen. + s = (s + e) / 2; + tex[vidx] = new Vector2(s, t); + } + } + float w = lensFrustum[2] - lensFrustum[0]; + lensFrustum[0] = -(w + lensFrustum[0]); + lensFrustum[2] = w - lensFrustum[2]; + w = noLensFrustum[2] - noLensFrustum[0]; + noLensFrustum[0] = -(w + noLensFrustum[0]); + noLensFrustum[2] = w - noLensFrustum[2]; + viewport.x = 1 - (viewport.x + viewport.width); + } + } + + private static Color[] ComputeMeshColors(int width, int height, Vector2[] tex, int[] indices, + bool distortVertices) { + Color[] colors = new Color[2 * width * height]; + for (int e = 0, vidx = 0; e < 2; e++) { + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++, vidx++) { + colors[vidx] = Color.white; + if (distortVertices) { + if (i == 0 || j == 0 || i == (width - 1) || j == (height - 1)) { + colors[vidx] = Color.black; + } + } else { + Vector2 t = tex[vidx]; + t.x = Mathf.Abs(t.x * 2 - 1); + if (t.x <= 0 || t.y <= 0 || t.x >= 1 || t.y >= 1) { + colors[vidx] = Color.black; + } + } + } + } + } + return colors; + } + + private static int[] ComputeMeshIndices(int width, int height, bool distortVertices) { + int[] indices = new int[2 * (width - 1) * (height - 1) * 6]; + int halfwidth = width / 2; + int halfheight = height / 2; + for (int e = 0, vidx = 0, iidx = 0; e < 2; e++) { + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++, vidx++) { + if (i == 0 || j == 0) + continue; + // Build a quad. Lower right and upper left quadrants have quads with the triangle + // diagonal flipped to get the vignette to interpolate correctly. + if ((i <= halfwidth) == (j <= halfheight)) { + // Quad diagonal lower left to upper right. + indices[iidx++] = vidx; + indices[iidx++] = vidx - width; + indices[iidx++] = vidx - width - 1; + indices[iidx++] = vidx - width - 1; + indices[iidx++] = vidx - 1; + indices[iidx++] = vidx; + } else { + // Quad diagonal upper left to lower right. + indices[iidx++] = vidx - 1; + indices[iidx++] = vidx; + indices[iidx++] = vidx - width; + indices[iidx++] = vidx - width; + indices[iidx++] = vidx - width - 1; + indices[iidx++] = vidx - 1; + } + } + } + } + return indices; + } + + private void DrawUILayer() { + bool vrMode = GvrViewer.Instance.VRModeEnabled; + if (Application.isEditor) { + ComputeUIMatrix(); + } + uiMaterial.SetPass(0); + if (vrMode && GvrViewer.Instance.EnableSettingsButton) { + DrawSettingsButton(); + } + if (vrMode && GvrViewer.Instance.EnableAlignmentMarker) { + DrawAlignmentMarker(); + } + if (GvrViewer.Instance.BackButtonMode == GvrViewer.BackButtonModes.On + || vrMode && GvrViewer.Instance.BackButtonMode == GvrViewer.BackButtonModes.OnlyInVR) { + DrawVRBackButton(); + } + } + + // The gear has 6 identical sections, each spanning 60 degrees. + private const float kAnglePerGearSection = 60; + + // Half-angle of the span of the outer rim. + private const float kOuterRimEndAngle = 12; + + // Angle between the middle of the outer rim and the start of the inner rim. + private const float kInnerRimBeginAngle = 20; + + // Distance from center to outer rim, normalized so that the entire model + // fits in a [-1, 1] x [-1, 1] square. + private const float kOuterRadius = 1; + + // Distance from center to depressed rim, in model units. + private const float kMiddleRadius = 0.75f; + + // Radius of the inner hollow circle, in model units. + private const float kInnerRadius = 0.3125f; + + // Center line thickness in DP. + private const float kCenterLineThicknessDp = 4; + + // Button width in DP. + private const int kButtonWidthDp = 28; + + // Factor to scale the touch area that responds to the touch. + private const float kTouchSlopFactor = 1.5f; + + private static readonly float[] Angles = { + 0, kOuterRimEndAngle, kInnerRimBeginAngle, + kAnglePerGearSection - kInnerRimBeginAngle, kAnglePerGearSection - kOuterRimEndAngle + }; + + private void ComputeUIMatrix() { + centerWidthPx = kCenterLineThicknessDp / 160.0f * Screen.dpi / 2; + buttonWidthPx = kButtonWidthDp / 160.0f * Screen.dpi / 2; + xScale = buttonWidthPx / Screen.width; + yScale = buttonWidthPx / Screen.height; + xfm = Matrix4x4.TRS(new Vector3(0.5f, yScale, 0), Quaternion.identity, + new Vector3(xScale, yScale, 1)); + } + + private void DrawSettingsButton() { + GL.PushMatrix(); + GL.LoadOrtho(); + GL.MultMatrix(xfm); + GL.Begin(GL.TRIANGLE_STRIP); + for (int i = 0, n = Angles.Length * 6; i <= n; i++) { + float theta = (i / Angles.Length) * kAnglePerGearSection + Angles[i % Angles.Length]; + float angle = (90 - theta) * Mathf.Deg2Rad; + float x = Mathf.Cos(angle); + float y = Mathf.Sin(angle); + float mod = Mathf.PingPong(theta, kAnglePerGearSection / 2); + float lerp = (mod - kOuterRimEndAngle) / (kInnerRimBeginAngle - kOuterRimEndAngle); + float r = Mathf.Lerp(kOuterRadius, kMiddleRadius, lerp); + GL.Vertex3(kInnerRadius * x, kInnerRadius * y, 0); + GL.Vertex3(r * x, r * y, 0); + } + GL.End(); + GL.PopMatrix(); + } + + private void DrawAlignmentMarker() { + int x = Screen.width / 2; + int w = (int)centerWidthPx; + int h = (int)(2 * kTouchSlopFactor * buttonWidthPx); + GL.PushMatrix(); + GL.LoadPixelMatrix(0, Screen.width, 0, Screen.height); + GL.Begin(GL.QUADS); + GL.Vertex3(x - w, h, 0); + GL.Vertex3(x - w, Screen.height - h, 0); + GL.Vertex3(x + w, Screen.height - h, 0); + GL.Vertex3(x + w, h, 0); + GL.End(); + GL.PopMatrix(); + } + + private void DrawVRBackButton() { + } +} diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrPostRender.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrPostRender.cs.meta new file mode 100644 index 0000000000..0215d35335 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrPostRender.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3995cc6db284649a793472ad14b220f6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrPreRender.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrPreRender.cs new file mode 100644 index 0000000000..69f68f89d2 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrPreRender.cs @@ -0,0 +1,84 @@ +// 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. + +using UnityEngine; + +/// Clears the entire screen. This script and GvrPostRender work together +/// to draw the whole screen in VR Mode. There should be exactly one of each +/// component in any GVR-enabled scene. It is part of the _GvrCamera_ +/// prefab, which is included in _GvrMain_. The GvrViewer script will +/// create one at runtime if the scene doesn't already have it, so generally +/// it is not necessary to manually add it unless you wish to edit the _Camera_ +/// component that it controls. +[RequireComponent(typeof(Camera))] +[AddComponentMenu("GoogleVR/GvrPreRender")] +public class GvrPreRender : MonoBehaviour { + + public Camera cam { get; private set; } + + void Awake() { + cam = GetComponent(); + } + + void Start() { + // Ensure distortion shader variables are initialized, because we can't count on + // getting a ProfileChanged event on the first frame rendered. + SetShaderGlobals(); + } + + void Reset() { +#if UNITY_EDITOR + // Member variable 'cam' not always initialized when this method called in Editor. + // So, we'll just make a local of the same name. + var cam = GetComponent(); +#endif + cam.clearFlags = CameraClearFlags.SolidColor; + cam.backgroundColor = Color.black; + cam.cullingMask = 0; + cam.useOcclusionCulling = false; + cam.depth = -100; + } + + void OnPreCull() { + GvrViewer.Instance.UpdateState(); + if (GvrViewer.Instance.ProfileChanged) { + SetShaderGlobals(); + } + cam.clearFlags = GvrViewer.Instance.VRModeEnabled ? + CameraClearFlags.SolidColor : CameraClearFlags.Nothing; + } + + private void SetShaderGlobals() { + // For any shaders that want to use these numbers for distortion correction. But only + // if distortion correction is needed, yet not already being handled by another method. + if (GvrViewer.Instance.VRModeEnabled + && GvrViewer.Instance.DistortionCorrection == GvrViewer.DistortionCorrectionMethod.None) { + GvrProfile p = GvrViewer.Instance.Profile; + // Distortion vertex shader currently setup for only 6 coefficients. + if (p.viewer.inverse.Coef.Length > 6) { + Debug.LogWarning("Inverse distortion correction has more than 6 coefficents. " + + "Shader only supports 6."); + } + Matrix4x4 mat = new Matrix4x4() {}; + for (int i=0; i=0; j--) { + ret = r2 * (ret + coef[j]); + } + return (ret + 1) * r; + } + + public float distortInv(float radius) { + // Secant method. + float r0 = 0; + float r1 = 1; + float dr0 = radius - distort(r0); + while (Mathf.Abs(r1 - r0) > 0.0001f) { + float dr1 = radius - distort(r1); + float r2 = r1 - dr1 * ((r1 - r0) / (dr1 - dr0)); + r0 = r1; + r1 = r2; + dr0 = dr1; + } + return r1; + } + } + + /// Information about a particular device, including specfications on its lenses, FOV, + /// and distortion and inverse distortion coefficients. + [System.Serializable] + public struct Viewer { + public Lenses lenses; + public MaxFOV maxFOV; + public Distortion distortion; + public Distortion inverse; + } + + /// Screen parameters of a Cardboard device. + public Screen screen; + + /// Viewer parameters of a Cardboard device. + public Viewer viewer; + + /// The vertical offset of the lens centers from the screen center. + public float VerticalLensOffset { + get { + return (viewer.lenses.offset - screen.border - screen.height/2) * viewer.lenses.alignment; + } + } + + /// Some known screen profiles. + public enum ScreenSizes { + Nexus5, + Nexus6, + GalaxyS6, + GalaxyNote4, + LGG3, + iPhone4, + iPhone5, + iPhone6, + iPhone6p, + }; + + /// Parameters for a Nexus 5 device. + public static readonly Screen Nexus5 = new Screen { + width = 0.110f, + height = 0.062f, + border = 0.004f + }; + + /// Parameters for a Nexus 6 device. + public static readonly Screen Nexus6 = new Screen { + width = 0.133f, + height = 0.074f, + border = 0.004f + }; + + /// Parameters for a Galaxy S6 device. + public static readonly Screen GalaxyS6 = new Screen { + width = 0.114f, + height = 0.0635f, + border = 0.0035f + }; + + /// Parameters for a Galaxy Note4 device. + public static readonly Screen GalaxyNote4 = new Screen { + width = 0.125f, + height = 0.0705f, + border = 0.0045f + }; + + /// Parameters for a LG G3 device. + public static readonly Screen LGG3 = new Screen { + width = 0.121f, + height = 0.068f, + border = 0.003f + }; + + /// Parameters for an iPhone 4 device. + public static readonly Screen iPhone4 = new Screen { + width = 0.075f, + height = 0.050f, + border = 0.0045f + }; + + /// Parameters for an iPhone 5 device. + public static readonly Screen iPhone5 = new Screen { + width = 0.089f, + height = 0.050f, + border = 0.0045f + }; + + /// Parameters for an iPhone 6 device. + public static readonly Screen iPhone6 = new Screen { + width = 0.104f, + height = 0.058f, + border = 0.005f + }; + + /// Parameters for an iPhone 6p device. + public static readonly Screen iPhone6p = new Screen { + width = 0.112f, + height = 0.068f, + border = 0.005f + }; + + /// Some known Cardboard device profiles. + public enum ViewerTypes { + CardboardJun2014, + CardboardMay2015, + GoggleTechC1Glass, + }; + + /// Parameters for a Cardboard v1. + public static readonly Viewer CardboardJun2014 = new Viewer { + lenses = { + separation = 0.060f, + offset = 0.035f, + screenDistance = 0.042f, + alignment = Lenses.AlignBottom, + }, + maxFOV = { + outer = 40.0f, + inner = 40.0f, + upper = 40.0f, + lower = 40.0f + }, + distortion = { + Coef = new [] { 0.441f, 0.156f }, + }, + inverse = ApproximateInverse(new [] { 0.441f, 0.156f }) + }; + + /// Parameters for a Cardboard v2. + public static readonly Viewer CardboardMay2015 = new Viewer { + lenses = { + separation = 0.064f, + offset = 0.035f, + screenDistance = 0.039f, + alignment = Lenses.AlignBottom, + }, + maxFOV = { + outer = 60.0f, + inner = 60.0f, + upper = 60.0f, + lower = 60.0f + }, + distortion = { + Coef = new [] { 0.34f, 0.55f }, + }, + inverse = ApproximateInverse(new [] { 0.34f, 0.55f }) + }; + + /// Parameters for a Go4D C1-Glass. + public static readonly Viewer GoggleTechC1Glass = new Viewer { + lenses = { + separation = 0.065f, + offset = 0.036f, + screenDistance = 0.058f, + alignment = Lenses.AlignBottom, + }, + maxFOV = { + outer = 50.0f, + inner = 50.0f, + upper = 50.0f, + lower = 50.0f + }, + distortion = { + Coef = new [] { 0.3f, 0 }, + }, + inverse = ApproximateInverse(new [] { 0.3f, 0 }) + }; + + /// Nexus 5 in a Cardboard v1. + public static readonly GvrProfile Default = new GvrProfile { + screen = Nexus5, + viewer = CardboardJun2014 + }; + + /// Returns a profile with the given parameters. + public static GvrProfile GetKnownProfile(ScreenSizes screenSize, ViewerTypes deviceType) { + Screen screen; + switch (screenSize) { + case ScreenSizes.Nexus6: + screen = Nexus6; + break; + case ScreenSizes.GalaxyS6: + screen = GalaxyS6; + break; + case ScreenSizes.GalaxyNote4: + screen = GalaxyNote4; + break; + case ScreenSizes.LGG3: + screen = LGG3; + break; + case ScreenSizes.iPhone4: + screen = iPhone4; + break; + case ScreenSizes.iPhone5: + screen = iPhone5; + break; + case ScreenSizes.iPhone6: + screen = iPhone6; + break; + case ScreenSizes.iPhone6p: + screen = iPhone6p; + break; + default: + screen = Nexus5; + break; + } + Viewer device; + switch (deviceType) { + case ViewerTypes.CardboardMay2015: + device = CardboardMay2015; + break; + case ViewerTypes.GoggleTechC1Glass: + device = GoggleTechC1Glass; + break; + default: + device = CardboardJun2014; + break; + } + return new GvrProfile { screen = screen, viewer = device }; + } + + /// Calculates the tan-angles from the maximum FOV for the left eye for the + /// current device and screen parameters. + public void GetLeftEyeVisibleTanAngles(float[] result) { + // Tan-angles from the max FOV. + float fovLeft = Mathf.Tan(-viewer.maxFOV.outer * Mathf.Deg2Rad); + float fovTop = Mathf.Tan(viewer.maxFOV.upper * Mathf.Deg2Rad); + float fovRight = Mathf.Tan(viewer.maxFOV.inner * Mathf.Deg2Rad); + float fovBottom = Mathf.Tan(-viewer.maxFOV.lower * Mathf.Deg2Rad); + // Viewport size. + float halfWidth = screen.width / 4; + float halfHeight = screen.height / 2; + // Viewport center, measured from left lens position. + float centerX = viewer.lenses.separation / 2 - halfWidth; + float centerY = -VerticalLensOffset; + float centerZ = viewer.lenses.screenDistance; + // Tan-angles of the viewport edges, as seen through the lens. + float screenLeft = viewer.distortion.distort((centerX - halfWidth) / centerZ); + float screenTop = viewer.distortion.distort((centerY + halfHeight) / centerZ); + float screenRight = viewer.distortion.distort((centerX + halfWidth) / centerZ); + float screenBottom = viewer.distortion.distort((centerY - halfHeight) / centerZ); + // Compare the two sets of tan-angles and take the value closer to zero on each side. + result[0] = Math.Max(fovLeft, screenLeft); + result[1] = Math.Min(fovTop, screenTop); + result[2] = Math.Min(fovRight, screenRight); + result[3] = Math.Max(fovBottom, screenBottom); + } + + /// Calculates the tan-angles from the maximum FOV for the left eye for the + /// current device and screen parameters, assuming no lenses. + public void GetLeftEyeNoLensTanAngles(float[] result) { + // Tan-angles from the max FOV. + float fovLeft = viewer.distortion.distortInv(Mathf.Tan(-viewer.maxFOV.outer * Mathf.Deg2Rad)); + float fovTop = viewer.distortion.distortInv(Mathf.Tan(viewer.maxFOV.upper * Mathf.Deg2Rad)); + float fovRight = viewer.distortion.distortInv(Mathf.Tan(viewer.maxFOV.inner * Mathf.Deg2Rad)); + float fovBottom = viewer.distortion.distortInv(Mathf.Tan(-viewer.maxFOV.lower * Mathf.Deg2Rad)); + // Viewport size. + float halfWidth = screen.width / 4; + float halfHeight = screen.height / 2; + // Viewport center, measured from left lens position. + float centerX = viewer.lenses.separation / 2 - halfWidth; + float centerY = -VerticalLensOffset; + float centerZ = viewer.lenses.screenDistance; + // Tan-angles of the viewport edges, as seen through the lens. + float screenLeft = (centerX - halfWidth) / centerZ; + float screenTop = (centerY + halfHeight) / centerZ; + float screenRight = (centerX + halfWidth) / centerZ; + float screenBottom = (centerY - halfHeight) / centerZ; + // Compare the two sets of tan-angles and take the value closer to zero on each side. + result[0] = Math.Max(fovLeft, screenLeft); + result[1] = Math.Min(fovTop, screenTop); + result[2] = Math.Min(fovRight, screenRight); + result[3] = Math.Max(fovBottom, screenBottom); + } + + /// Calculates the screen rectangle visible from the left eye for the + /// current device and screen parameters. + public Rect GetLeftEyeVisibleScreenRect(float[] undistortedFrustum) { + float dist = viewer.lenses.screenDistance; + float eyeX = (screen.width - viewer.lenses.separation) / 2; + float eyeY = VerticalLensOffset + screen.height / 2; + float left = (undistortedFrustum[0] * dist + eyeX) / screen.width; + float top = (undistortedFrustum[1] * dist + eyeY) / screen.height; + float right = (undistortedFrustum[2] * dist + eyeX) / screen.width; + float bottom = (undistortedFrustum[3] * dist + eyeY) / screen.height; + return new Rect(left, bottom, right - left, top - bottom); + } + + public static float GetMaxRadius(float[] tanAngleRect) { + float x = Mathf.Max(Mathf.Abs(tanAngleRect[0]), Mathf.Abs(tanAngleRect[2])); + float y = Mathf.Max(Mathf.Abs(tanAngleRect[1]), Mathf.Abs(tanAngleRect[3])); + return Mathf.Sqrt(x * x + y * y); + } + + // Solves a small linear equation via destructive gaussian + // elimination and back substitution. This isn't generic numeric + // code, it's just a quick hack to work with the generally + // well-behaved symmetric matrices for least-squares fitting. + // Not intended for reuse. + // + // @param a Input positive definite symmetrical matrix. Destroyed + // during calculation. + // @param y Input right-hand-side values. Destroyed during calculation. + // @return Resulting x value vector. + // + private static double[] solveLinear(double[,] a, double[] y) { + int n = a.GetLength(0); + + // Gaussian elimination (no row exchange) to triangular matrix. + // The input matrix is a A^T A product which should be a positive + // definite symmetrical matrix, and if I remember my linear + // algebra right this implies that the pivots will be nonzero and + // calculations sufficiently accurate without needing row + // exchange. + for (int j = 0; j < n - 1; ++j) { + for (int k = j + 1; k < n; ++k) { + double p = a[k, j] / a[j, j]; + for (int i = j + 1; i < n; ++i) { + a[k, i] -= p * a[j, i]; + } + y[k] -= p * y[j]; + } + } + // From this point on, only the matrix elements a[j][i] with i>=j are + // valid. The elimination doesn't fill in eliminated 0 values. + + double[] x = new double[n]; + + // Back substitution. + for (int j = n - 1; j >= 0; --j) { + double v = y[j]; + for (int i = j + 1; i < n; ++i) { + v -= a[j, i] * x[i]; + } + x[j] = v / a[j, j]; + } + + return x; + } + + // Solves a least-squares matrix equation. Given the equation A * x = y, calculate the + // least-square fit x = inverse(A * transpose(A)) * transpose(A) * y. The way this works + // is that, while A is typically not a square matrix (and hence not invertible), A * transpose(A) + // is always square. That is: + // A * x = y + // transpose(A) * (A * x) = transpose(A) * y <- multiply both sides by transpose(A) + // (transpose(A) * A) * x = transpose(A) * y <- associativity + // x = inverse(transpose(A) * A) * transpose(A) * y <- solve for x + // Matrix A's row count (first index) must match y's value count. A's column count (second index) + // determines the length of the result vector x. + private static double[] solveLeastSquares(double[,] matA, double[] vecY) { + int numSamples = matA.GetLength(0); + int numCoefficients = matA.GetLength(1); + if (numSamples != vecY.Length) { + Debug.LogError("Matrix / vector dimension mismatch"); + return null; + } + + // Calculate transpose(A) * A + double[,] matATA = new double[numCoefficients, numCoefficients]; + for (int k = 0; k < numCoefficients; ++k) { + for (int j = 0; j < numCoefficients; ++j) { + double sum = 0.0; + for (int i = 0; i < numSamples; ++i) { + sum += matA[i, j] * matA[i, k]; + } + matATA[j, k] = sum; + } + } + + // Calculate transpose(A) * y + double[] vecATY = new double[numCoefficients]; + for (int j = 0; j < numCoefficients; ++j) { + double sum = 0.0; + for (int i = 0; i < numSamples; ++i) { + sum += matA[i, j] * vecY[i]; + } + vecATY[j] = sum; + } + + // Now solve (A * transpose(A)) * x = transpose(A) * y. + return solveLinear(matATA, vecATY); + } + + /// Calculates an approximate inverse to the given radial distortion parameters. + public static Distortion ApproximateInverse(float[] coef, float maxRadius = 1, + int numSamples = 100) { + return ApproximateInverse(new Distortion { Coef=coef }, maxRadius, numSamples); + } + + /// Calculates an approximate inverse to the given radial distortion parameters. + public static Distortion ApproximateInverse(Distortion distort, float maxRadius = 1, + int numSamples = 100) { + const int numCoefficients = 6; + + // R + K1*R^3 + K2*R^5 = r, with R = rp = distort(r) + // Repeating for numSamples: + // [ R0^3, R0^5 ] * [ K1 ] = [ r0 - R0 ] + // [ R1^3, R1^5 ] [ K2 ] [ r1 - R1 ] + // [ R2^3, R2^5 ] [ r2 - R2 ] + // [ etc... ] [ etc... ] + // That is: + // matA * [K1, K2] = y + // Solve: + // [K1, K2] = inverse(transpose(matA) * matA) * transpose(matA) * y + double[,] matA = new double[numSamples, numCoefficients]; + double[] vecY = new double[numSamples]; + for (int i = 0; i < numSamples; ++i) { + float r = maxRadius * (i + 1) / (float) numSamples; + double rp = distort.distort(r); + double v = rp; + for (int j = 0; j < numCoefficients; ++j) { + v *= rp * rp; + matA[i, j] = v; + } + vecY[i] = r - rp; + } + double[] vecK = solveLeastSquares(matA, vecY); + // Convert to float for use in a fresh Distortion object. + float[] coefficients = new float[vecK.Length]; + for (int i = 0; i < vecK.Length; ++i) { + coefficients[i] = (float) vecK[i]; + } + return new Distortion { Coef = coefficients }; + } +} +/// @endcond diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrProfile.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrProfile.cs.meta new file mode 100644 index 0000000000..e4dc3bd88b --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrProfile.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2cc48090f46d244bba130fef5ad58876 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrViewer.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrViewer.cs new file mode 100644 index 0000000000..3aa40b68ef --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrViewer.cs @@ -0,0 +1,659 @@ +// Copyright 2014 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. + +using UnityEngine; +using System; +using System.Collections.Generic; + +using Gvr.Internal; + +/// The GvrViewer object communicates with the head-mounted display. +/// Is is repsonsible for: +/// - Querying the device for viewing parameters +/// - Retrieving the latest head tracking data +/// - Providing the rendered scene to the device for distortion correction (optional) +/// +/// There should only be one of these in a scene. An instance will be generated automatically +/// by this script at runtime, or you can add one via the Editor if you wish to customize +/// its starting properties. +[AddComponentMenu("GoogleVR/GvrViewer")] +public class GvrViewer : MonoBehaviour { + public const string GVR_SDK_VERSION = "0.8"; + + /// The singleton instance of the GvrViewer class. + public static GvrViewer Instance { + get { +#if UNITY_EDITOR + if (instance == null && !Application.isPlaying) { + instance = UnityEngine.Object.FindObjectOfType(); + } +#endif + if (instance == null) { + Debug.LogError("No GvrViewer instance found. Ensure one exists in the scene, or call " + + "GvrViewer.Create() at startup to generate one.\n" + + "If one does exist but hasn't called Awake() yet, " + + "then this error is due to order-of-initialization.\n" + + "In that case, consider moving " + + "your first reference to GvrViewer.Instance to a later point in time.\n" + + "If exiting the scene, this indicates that the GvrViewer object has already " + + "been destroyed."); + } + return instance; + } + } + private static GvrViewer instance = null; + + /// Generate a GvrViewer instance. Takes no action if one already exists. + public static void Create() { + if (instance == null && UnityEngine.Object.FindObjectOfType() == null) { + Debug.Log("Creating GvrViewer object"); + var go = new GameObject("GvrViewer", typeof(GvrViewer)); + go.transform.localPosition = Vector3.zero; + // sdk will be set by Awake(). + } + } + + /// The StereoController instance attached to the main camera, or null if there is none. + /// @note Cached for performance. + public static StereoController Controller { + get { + Camera camera = Camera.main; + // Cache for performance, if possible. + if (camera != currentMainCamera || currentController == null) { + currentMainCamera = camera; + currentController = camera.GetComponent(); + } + return currentController; + } + } + private static Camera currentMainCamera; + private static StereoController currentController; + + /// @cond + public bool UILayerEnabled { + get { + return uiLayerEnabled; + } + private set { + if (value != uiLayerEnabled && device != null) { + device.SetUILayerEnabled(value); + } + uiLayerEnabled = value; + } + } + // Not serialized. + private bool uiLayerEnabled = false; + /// @endcond + + /// Determine whether the scene renders in stereo or mono. + /// _True_ means to render in stereo, and _false_ means to render in mono. + public bool VRModeEnabled { + get { + return vrModeEnabled; + } + set { + if (value != vrModeEnabled && device != null) { + device.SetVRModeEnabled(value); + } + vrModeEnabled = value; + } + } + [SerializeField] + private bool vrModeEnabled = true; + + /// Methods for performing lens distortion correction. + public enum DistortionCorrectionMethod { + None, /// No distortion correction + Native, /// Use the native C++ plugin + Unity, /// Perform distortion correction in Unity (recommended) + } + + /// Determines the distortion correction method used by the SDK to render the + /// #StereoScreen texture on the phone. If _Native_ is selected but not supported + /// by the device, the _Unity_ method will be used instead. + public DistortionCorrectionMethod DistortionCorrection { + get { + return distortionCorrection; + } + set { + if (device != null && device.RequiresNativeDistortionCorrection()) { + value = DistortionCorrectionMethod.Native; + } + if (value != distortionCorrection && device != null) { + device.SetDistortionCorrectionEnabled(value == DistortionCorrectionMethod.Native + && NativeDistortionCorrectionSupported); + device.UpdateScreenData(); + } + distortionCorrection = value; + } + } + [SerializeField] + private DistortionCorrectionMethod distortionCorrection = DistortionCorrectionMethod.Unity; + + /// Enables or disables the vertical line rendered between the stereo views to + /// help the user align the viewer to the phone's screen. + public bool EnableAlignmentMarker { + get { + return enableAlignmentMarker; + } + set { + if (value != enableAlignmentMarker && device != null) { + device.SetAlignmentMarkerEnabled(value); + } + enableAlignmentMarker = value; + } + } + [SerializeField] + private bool enableAlignmentMarker = true; + + /// Enables or disables the Cardboard settings button. It appears as a gear icon + /// in the blank space between the stereo views. The settings button opens the + /// Google Cardboard app to allow the user to configure their individual settings + /// and Cardboard headset parameters. + public bool EnableSettingsButton { + get { + return enableSettingsButton; + } + set { + if (value != enableSettingsButton && device != null) { + device.SetSettingsButtonEnabled(value); + } + enableSettingsButton = value; + } + } + [SerializeField] + private bool enableSettingsButton = true; + + /// Display modes for the VR "Back Button". + public enum BackButtonModes { + Off, /// Always off + OnlyInVR, /// On in VR Mode, otherwise off + On /// Always on + } + + /// Whether to show the onscreen analog of the (Android) Back Button. + public BackButtonModes BackButtonMode { + get { + return backButtonMode; + } + set { + if (value != backButtonMode && device != null) { + device.SetVRBackButtonEnabled(value != BackButtonModes.Off); + device.SetShowVrBackButtonOnlyInVR(value == BackButtonModes.OnlyInVR); + } + backButtonMode = value; + } + } + [SerializeField] + private BackButtonModes backButtonMode = BackButtonModes.OnlyInVR; + + /// The native SDK will apply a neck offset to the head tracking, resulting in + /// a more realistic model of a person's head position. This control determines + /// the scale factor of the offset. To turn off the neck model, set it to 0, and + /// to turn it all on, set to 1. Intermediate values can be used to animate from + /// on to off or vice versa. + public float NeckModelScale { + get { + return neckModelScale; + } + set { + value = Mathf.Clamp01(value); + if (!Mathf.Approximately(value, neckModelScale) && device != null) { + device.SetNeckModelScale(value); + } + neckModelScale = value; + } + } + [SerializeField] + private float neckModelScale = 0.0f; + + /// When enabled, drift in the gyro readings is estimated and removed. + public bool AutoDriftCorrection { + get { + return autoDriftCorrection; + } + set { + if (value != autoDriftCorrection && device != null) { + device.SetAutoDriftCorrectionEnabled(value); + } + autoDriftCorrection = value; + } + } + [SerializeField] + private bool autoDriftCorrection = true; + + /// @cond + public bool ElectronicDisplayStabilization { + get { + return electronicDisplayStabilization; + } + set { + if (value != electronicDisplayStabilization && device != null) { + device.SetElectronicDisplayStabilizationEnabled(value); + } + electronicDisplayStabilization = value; + } + } + [SerializeField] + private bool electronicDisplayStabilization = false; + /// @endcond + +#if UNITY_EDITOR + /// Restores level head tilt in when playing in the Unity Editor after you + /// release the Ctrl key. + public bool autoUntiltHead = true; + + /// @cond + /// Use unity remote as the input source. + [HideInInspector] + public bool UseUnityRemoteInput = false; + /// @endcond + + /// The screen size to emulate when testing in the Unity Editor. + public GvrProfile.ScreenSizes ScreenSize { + get { + return screenSize; + } + set { + if (value != screenSize) { + screenSize = value; + if (device != null) { + device.UpdateScreenData(); + } + } + } + } + [SerializeField] + private GvrProfile.ScreenSizes screenSize = GvrProfile.ScreenSizes.Nexus5; + + /// The viewer type to emulate when testing in the Unity Editor. + public GvrProfile.ViewerTypes ViewerType { + get { + return viewerType; + } + set { + if (value != viewerType) { + viewerType = value; + if (device != null) { + device.UpdateScreenData(); + } + } + } + } + [SerializeField] + private GvrProfile.ViewerTypes viewerType = GvrProfile.ViewerTypes.CardboardMay2015; +#endif + + // The VR device that will be providing input data. + private static BaseVRDevice device; + + /// Whether native distortion correction functionality is supported by the VR device. + public bool NativeDistortionCorrectionSupported { get; private set; } + + /// Whether the VR device supports showing a native UI layer, for example for settings. + public bool NativeUILayerSupported { get; private set; } + + /// Scales the resolution of the #StereoScreen. Set to less than 1.0 to increase + /// rendering speed while decreasing sharpness, or greater than 1.0 to do the + /// opposite. + public float StereoScreenScale { + get { + return stereoScreenScale; + } + set { + value = Mathf.Clamp(value, 0.1f, 10.0f); // Sanity. + if (stereoScreenScale != value) { + stereoScreenScale = value; + StereoScreen = null; + } + } + } + [SerializeField] + private float stereoScreenScale = 1; + + /// The texture that Unity renders the scene to. After the frame has been rendered, + /// this texture is drawn to the screen with a lens distortion correction effect. + /// The texture size is based on the size of the screen, the lens distortion + /// parameters, and the #StereoScreenScale factor. + public RenderTexture StereoScreen { + get { + // Don't need it except for distortion correction. + if (distortionCorrection == DistortionCorrectionMethod.None || !vrModeEnabled) { + return null; + } + if (stereoScreen == null) { + // Create on demand. + StereoScreen = device.CreateStereoScreen(); // Note: uses set{} + } + return stereoScreen; + } + set { + if (value == stereoScreen) { + return; + } + if (stereoScreen != null) { + stereoScreen.Release(); + } + stereoScreen = value; + if (OnStereoScreenChanged != null) { + OnStereoScreenChanged(stereoScreen); + } + } + } + private static RenderTexture stereoScreen = null; + + /// A callback for notifications that the StereoScreen property has changed. + public delegate void StereoScreenChangeDelegate(RenderTexture newStereoScreen); + + /// Emitted when the StereoScreen property has changed. + public event StereoScreenChangeDelegate OnStereoScreenChanged; + + /// Describes the current device, including phone screen. + public GvrProfile Profile { + get { + return device.Profile; + } + } + + /// Distinguish the stereo eyes. + public enum Eye { + Left, /// The left eye + Right, /// The right eye + Center /// The "center" eye (unused) + } + + /// When retrieving the #Projection and #Viewport properties, specifies + /// whether you want the values as seen through the viewer's lenses (`Distorted`) or + /// as if no lenses were present (`Undistorted`). + public enum Distortion { + Distorted, /// Viewing through the lenses + Undistorted /// No lenses + } + + /// The transformation of head from origin in the tracking system. + public Pose3D HeadPose { + get { + return device.GetHeadPose(); + } + } + + /// The transformation from head to eye. + public Pose3D EyePose(Eye eye) { + return device.GetEyePose(eye); + } + + /// The projection matrix for a given eye. + /// This matrix is an off-axis perspective projection with near and far + /// clipping planes of 1m and 1000m, respectively. The GvrEye script + /// takes care of adjusting the matrix for its particular camera. + public Matrix4x4 Projection(Eye eye, Distortion distortion = Distortion.Distorted) { + return device.GetProjection(eye, distortion); + } + + /// The screen space viewport that the camera for the specified eye should render into. + /// In the _Distorted_ case, this will be either the left or right half of the `StereoScreen` + /// render texture. In the _Undistorted_ case, it refers to the actual rectangle on the + /// screen that the eye can see. + public Rect Viewport(Eye eye, Distortion distortion = Distortion.Distorted) { + return device.GetViewport(eye, distortion); + } + + /// The distance range from the viewer in user-space meters where objects may be viewed + /// comfortably in stereo. If the center of interest falls outside this range, the stereo + /// eye separation should be adjusted to keep the onscreen disparity within the limits set + /// by this range. StereoController will handle this if the _checkStereoComfort_ is + /// enabled. + public Vector2 ComfortableViewingRange { + get { + return defaultComfortableViewingRange; + } + } + private readonly Vector2 defaultComfortableViewingRange = new Vector2(0.4f, 100000.0f); + + /// @cond + // Optional. Set to a URI obtained from the Google Cardboard profile generator at + // https://www.google.com/get/cardboard/viewerprofilegenerator/ + // Example: Cardboard I/O 2015 viewer profile + //public Uri DefaultDeviceProfile = new Uri("http://google.com/cardboard/cfg?p=CgZHb29nbGUSEkNhcmRib2FyZCBJL08gMjAxNR0J-SA9JQHegj0qEAAAcEIAAHBCAABwQgAAcEJYADUpXA89OghX8as-YrENP1AAYAM"); + public Uri DefaultDeviceProfile = null; + /// @endcond + + private void InitDevice() { + if (device != null) { + device.Destroy(); + } + device = BaseVRDevice.GetDevice(); + device.Init(); + + List diagnostics = new List(); + NativeDistortionCorrectionSupported = device.SupportsNativeDistortionCorrection(diagnostics); + if (diagnostics.Count > 0) { + Debug.LogWarning("Built-in distortion correction disabled. Causes: [" + + String.Join("; ", diagnostics.ToArray()) + "]"); + } + diagnostics.Clear(); + NativeUILayerSupported = device.SupportsNativeUILayer(diagnostics); + if (diagnostics.Count > 0) { + Debug.LogWarning("Built-in UI layer disabled. Causes: [" + + String.Join("; ", diagnostics.ToArray()) + "]"); + } + + if (DefaultDeviceProfile != null) { + device.SetDefaultDeviceProfile(DefaultDeviceProfile); + } + + device.SetAlignmentMarkerEnabled(enableAlignmentMarker); + device.SetSettingsButtonEnabled(enableSettingsButton); + device.SetVRBackButtonEnabled(backButtonMode != BackButtonModes.Off); + device.SetShowVrBackButtonOnlyInVR(backButtonMode == BackButtonModes.OnlyInVR); + device.SetDistortionCorrectionEnabled(distortionCorrection == DistortionCorrectionMethod.Native + && NativeDistortionCorrectionSupported); + device.SetNeckModelScale(neckModelScale); + device.SetAutoDriftCorrectionEnabled(autoDriftCorrection); + device.SetElectronicDisplayStabilizationEnabled(electronicDisplayStabilization); + + device.SetVRModeEnabled(vrModeEnabled); + + device.UpdateScreenData(); + } + + /// @note Each scene load causes an OnDestroy of the current SDK, followed + /// by and Awake of a new one. That should not cause the underlying native + /// code to hiccup. Exception: developer may call Application.DontDestroyOnLoad + /// on the SDK if they want it to survive across scene loads. + void Awake() { + if (instance == null) { + instance = this; + } + if (instance != this) { + Debug.LogError("There must be only one GvrViewer object in a scene."); + UnityEngine.Object.DestroyImmediate(this); + return; + } +#if UNITY_IOS + Application.targetFrameRate = 60; +#endif + // Prevent the screen from dimming / sleeping + Screen.sleepTimeout = SleepTimeout.NeverSleep; + InitDevice(); + StereoScreen = null; + AddPrePostRenderStages(); + } + + void Start() { + UILayerEnabled = true; + } + + void AddPrePostRenderStages() { + var preRender = UnityEngine.Object.FindObjectOfType(); + if (preRender == null) { + var go = new GameObject("PreRender", typeof(GvrPreRender)); + go.SendMessage("Reset"); + go.transform.parent = transform; + } + var postRender = UnityEngine.Object.FindObjectOfType(); + if (postRender == null) { + var go = new GameObject("PostRender", typeof(GvrPostRender)); + go.SendMessage("Reset"); + go.transform.parent = transform; + } + } + + /// Emitted whenever a trigger occurs. + public event Action OnTrigger; + + /// Emitted whenever the viewer is tilted on its side. + public event Action OnTilt; + + /// Emitted whenever the app should respond to a possible change in the device viewer + /// profile, that is, the QR code scanned by the user. + public event Action OnProfileChange; + + /// Emitted whenever the user presses the "VR Back Button". + public event Action OnBackButton; + + /// Whether the viewer's trigger was pulled. True for exactly one complete frame + /// after each pull. + public bool Triggered { get; private set; } + + /// Whether the viewer was tilted on its side. True for exactly one complete frame + /// after each tilt. Whether and how to respond to this event is up to the app. + public bool Tilted { get; private set; } + + /// Whether the viewer profile has possibly changed. This is meant to indicate + /// that a new QR code has been scanned, although currently it is actually set any time the + /// application is unpaused, whether it was due to a profile change or not. True for one + /// frame. + public bool ProfileChanged { get; private set; } + + /// Whether the user has pressed the "VR Back Button", which on Android should be treated the + /// same as the normal system Back Button, although you can respond to either however you want + /// in your app. + public bool BackButtonPressed { get; private set; } + + // Only call device.UpdateState() once per frame. + private int updatedToFrame = 0; + + /// Reads the latest tracking data from the phone. This must be + /// called before accessing any of the poses and matrices above. + /// + /// Multiple invocations per frame are OK: Subsequent calls merely yield the + /// cached results of the first call. To minimize latency, it should be first + /// called later in the frame (for example, in `LateUpdate`) if possible. + public void UpdateState() { + if (updatedToFrame != Time.frameCount) { + updatedToFrame = Time.frameCount; + device.UpdateState(); + + if (device.profileChanged) { + if (distortionCorrection != DistortionCorrectionMethod.Native + && device.RequiresNativeDistortionCorrection()) { + DistortionCorrection = DistortionCorrectionMethod.Native; + } + if (stereoScreen != null + && device.ShouldRecreateStereoScreen(stereoScreen.width, stereoScreen.height)) { + StereoScreen = null; + } + } + + DispatchEvents(); + } + } + + private void DispatchEvents() { + // Update flags first by copying from device and other inputs. + Triggered = device.triggered || Input.GetMouseButtonDown(0); + Tilted = device.tilted; + ProfileChanged = device.profileChanged; + BackButtonPressed = device.backButtonPressed || Input.GetKeyDown(KeyCode.Escape); + // Reset device flags. + device.triggered = false; + device.tilted = false; + device.profileChanged = false; + device.backButtonPressed = false; + // All flags updated. Now emit events. + if (Tilted && OnTilt != null) { + OnTilt(); + } + if (Triggered && OnTrigger != null) { + OnTrigger(); + } + if (ProfileChanged && OnProfileChange != null) { + OnProfileChange(); + } + if (BackButtonPressed && OnBackButton != null) { + OnBackButton(); + } + } + + /// Presents the #StereoScreen to the device for distortion correction and display. + /// @note This function is only used if #DistortionCorrection is set to _Native_, + /// and it only has an effect if the device supports it. + public void PostRender(RenderTexture stereoScreen) { + if (NativeDistortionCorrectionSupported && stereoScreen != null && stereoScreen.IsCreated()) { + device.PostRender(stereoScreen); + } + } + + /// Resets the tracker so that the user's current direction becomes forward. + public void Recenter() { + device.Recenter(); + } + + /// Launch the device pairing and setup dialog. + public void ShowSettingsDialog() { + device.ShowSettingsDialog(); + } + + void OnEnable() { +#if UNITY_EDITOR + // This can happen if you edit code while the editor is in Play mode. + if (device == null) { + InitDevice(); + } +#endif + device.OnPause(false); + } + + void OnDisable() { + device.OnPause(true); + } + + void OnApplicationPause(bool pause) { + device.OnPause(pause); + } + + void OnApplicationFocus(bool focus) { + device.OnFocus(focus); + } + + void OnLevelWasLoaded(int level) { + device.OnLevelLoaded(level); + } + + void OnApplicationQuit() { + device.OnApplicationQuit(); + } + + void OnDestroy() { + VRModeEnabled = false; + UILayerEnabled = false; + if (device != null) { + device.Destroy(); + } + if (instance == this) { + instance = null; + } + } +} diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrViewer.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrViewer.cs.meta new file mode 100644 index 0000000000..c383ca515e --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/GvrViewer.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a40b544b8c3553c40852ae7ad35a9343 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Pose3D.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Pose3D.cs new file mode 100644 index 0000000000..5c387a6884 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Pose3D.cs @@ -0,0 +1,89 @@ +// Copyright 2014 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. +using UnityEngine; + +/// @cond +/// Encapsulates a rotation and a translation. This is a convenience class that allows +/// construction and value access either by Matrix4x4 or Quaternion + Vector3 types. +public class Pose3D { + /// Right-handed to left-handed matrix converter (and vice versa). + protected static readonly Matrix4x4 flipZ = Matrix4x4.Scale(new Vector3(1, 1, -1)); + + /// The translation component of the pose. + public Vector3 Position { get; protected set; } + + /// The rotation component of the pose. + public Quaternion Orientation { get; protected set; } + + /// The pose as a matrix in Unity gameobject convention (left-handed). + public Matrix4x4 Matrix { get; protected set; } + + /// The pose as a matrix in right-handed coordinates. + public Matrix4x4 RightHandedMatrix { + get { + return flipZ * Matrix * flipZ; + } + } + + /// Default constructor. + /// Initializes position to the origin and orientation to the identity rotation. + public Pose3D() { + Position = Vector3.zero; + Orientation = Quaternion.identity; + Matrix = Matrix4x4.identity; + } + + /// Constructor that takes a Vector3 and a Quaternion. + public Pose3D(Vector3 position, Quaternion orientation) { + Set(position, orientation); + } + + /// Constructor that takes a Matrix4x4. + public Pose3D(Matrix4x4 matrix) { + Set(matrix); + } + + protected void Set(Vector3 position, Quaternion orientation) { + Position = position; + Orientation = orientation; + Matrix = Matrix4x4.TRS(position, orientation, Vector3.one); + } + + protected void Set(Matrix4x4 matrix) { + Matrix = matrix; + Position = matrix.GetColumn(3); + Orientation = Quaternion.LookRotation(matrix.GetColumn(2), matrix.GetColumn(1)); + } +} +/// @endcond + +/// @cond +/// Mutable version of Pose3D. +public class MutablePose3D : Pose3D { + /// Sets the position and orientation from a Vector3 + Quaternion. + public new void Set(Vector3 position, Quaternion orientation) { + base.Set(position, orientation); + } + + /// Sets the position and orientation from a Matrix4x4. + public new void Set(Matrix4x4 matrix) { + base.Set(matrix); + } + + /// Sets the position and orientation from a right-handed Matrix4x4. + public void SetRightHanded(Matrix4x4 matrix) { + Set(flipZ * matrix * flipZ); + } +} +/// @endcond diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Pose3D.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Pose3D.cs.meta new file mode 100644 index 0000000000..673b8ee614 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/Pose3D.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d6dc4d56dabb6444a8fda878f2e8acc1 +timeCreated: 1428963852 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/StereoController.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/StereoController.cs new file mode 100644 index 0000000000..46aa9f024b --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/StereoController.cs @@ -0,0 +1,362 @@ +// Copyright 2014 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. + +using UnityEngine; +using System.Collections; +using System.Linq; + +/// Controls a pair of GvrEye objects that will render the stereo view +/// of the camera this script is attached to. +/// +/// This script must be added to any camera that should render stereo when the app +/// is in VR Mode. This includes picture-in-picture windows, whether their contents +/// are in stereo or not: the window itself must be twinned for stereo, regardless. +/// +/// For each frame, StereoController decides whether to render via the camera it +/// is attached to (the _mono_ camera) or the stereo eyes that it controls (see +/// GvrEye). You control this decision for all cameras at once by setting +/// the value of GvrViewer#VRModeEnabled. +/// +/// For technical reasons, the mono camera remains enabled for the initial portion of +/// the frame. It is disabled only when rendering begins in `OnPreCull()`, and is +/// reenabled again at the end of the frame. This allows 3rd party scripts that use +/// `Camera.main`, for example, to refer the the mono camera even when VR Mode is +/// enabled. +/// +/// At startup the script ensures it has a full stereo rig, which consists of two +/// child cameras with GvrEye scripts attached, and a GvrHead script +/// somewhere in the hierarchy of parents and children for head tracking. The rig +/// is created if necessary, the GvrHead being attached to the controller +/// itself. The child camera settings are then cloned or updated from the mono +/// camera. +/// +/// It is permissible for a StereoController to contain another StereoController +/// as a child. In this case, a GvrEye is controlled by its closest +/// StereoController parent. +/// +/// The Inspector panel for this script includes a button _Update Stereo Cameras_. +/// This performs the same action as described above for startup, but in the Editor. +/// Use this to generate the rig if you intend to customize it. This action is also +/// available via _Component -> GVR -> Update Stereo Cameras_ in the Editor’s +/// main menu, and in the context menu for the `Camera` component. +[RequireComponent(typeof(Camera))] +[AddComponentMenu("GoogleVR/StereoController")] +public class StereoController : MonoBehaviour { + /// Whether to draw directly to the output window (_true_), or to an offscreen buffer + /// first and then blit (_false_). If you wish to use Deferred Rendering or any + /// Image Effects in stereo, turn this option off. A common symptom that indicates + /// you should do so is when one of the eyes is spread across the entire screen. + [Tooltip("Whether to draw directly to the output window (true), or " + + "to an offscreen buffer first and then blit (false). Image " + + " Effects and Deferred Lighting may only work if set to false.")] + public bool directRender = true; + + /// When enabled, UpdateStereoValues() is called every frame to keep the stereo cameras + /// completely synchronized with both the mono camera and the device profile. When + /// disabled, you must call UpdateStereoValues() whenever you make a change to the mono + /// camera that should be mirrored to the stereo cameras. Changes to the device profile + /// are handled automatically. It is better for performance to leave this option disabled + /// whenever possible. Good use cases for enabling it are when animating values on the + /// mono camera (like background color), or during development to debug camera synchronization + /// issues. + [Tooltip("When enabled, UpdateStereoValues() is called every frame to keep the stereo cameras " + + "completely synchronized with both the mono camera and the device profile. It is " + + "better for performance to leave this option disabled whenever possible.")] + public bool keepStereoUpdated = false; + + /// Adjusts the level of stereopsis for this stereo rig. + /// @note This parameter is not the virtual size of the head -- use a scale + /// on the head game object for that. Instead, it is a control on eye vergence, + /// or rather, how cross-eyed or not the stereo rig is. Set to 0 to turn + /// off stereo in this rig independently of any others. + [Tooltip("Set the stereo level for this camera.")] + [Range(0,1)] + public float stereoMultiplier = 1.0f; + + /// The stereo cameras by default use the actual optical FOV of the VR device, + /// because otherwise the match between head motion and scene motion is broken, which + /// impacts the virtual reality effect. However, in some cases it is desirable to + /// adjust the FOV anyway, for special effects or artistic reasons. But in no case + /// should the FOV be allowed to remain very different from the true optical FOV for + /// very long, or users will experience discomfort. + /// + /// This value determines how much to match the mono camera's field of view. This is + /// a fraction: 0 means no matching, 1 means full matching, and values in between are + /// compromises. Reasons for not matching 100% would include preserving some VR-ness, + /// and that due to the lens distortion the edges of the view are not as easily seen as + /// when the phone is not in VR-mode. + /// + /// Another use for this variable is to preserve scene composition against differences + /// in the optical FOV of various viewer models. In all cases, this value simply + /// lets the mono camera have some control over the scene in VR mode, like it does in + /// non-VR mode. + [Tooltip("How much to adjust the stereo field of view to match this camera.")] + [Range(0,1)] + public float matchMonoFOV = 0; + + /// Determines the method by which the stereo cameras' FOVs are matched to the mono + /// camera's FOV (assuming #matchMonoFOV is not 0). The default is to move the stereo + /// cameras (#matchByZoom = 0), with the option to instead do a simple camera zoom + /// (#matchByZoom = 1). In-between values yield a mix of the two behaviors. + /// + /// It is not recommended to use simple zooming for typical scene composition, as it + /// conflicts with the VR need to match the user's head motion with the corresponding + /// scene motion. This should be reserved for special effects such as when the player + /// views the scene through a telescope or other magnifier (and thus the player knows + /// that VR is going to be affected), or similar situations. + /// + /// @note Matching by moving the eyes requires that the #centerOfInterest object + /// be non-null, or there will be no effect. + [Tooltip("Whether to adjust FOV by moving the eyes (0) or simply zooming (1).")] + [Range(0,1)] + public float matchByZoom = 0; + + /// Matching the mono camera's field of view in stereo by moving the eyes requires + /// a designated "center of interest". This is either a point in space (an empty + /// gameobject) you place in the scene as a sort of "3D cursor", or an actual scene + /// entity which the player is likely to be focussed on. + /// + /// The FOV adjustment is done by moving the eyes toward or away from the COI + /// so that it appears to have the same size on screen as it would in the mono + /// camera. This is disabled if the COI is null. + [Tooltip("Object or point where field of view matching is done.")] + public Transform centerOfInterest; + + /// The #centerOfInterest is generally meant to be just a point in space, like a 3D cursor. + /// Occasionally, you will want it to be an actual object with size. Set this + /// to the approximate radius of the object to help the FOV-matching code + /// compensate for the object's horizon when it is close to the camera. + [Tooltip("If COI is an object, its approximate size.")] + public float radiusOfInterest = 0; + + /// If true, check that the #centerOfInterest is between the min and max comfortable + /// viewing distances (see GvrViewer.cs), or else adjust the stereo multiplier to + /// compensate. If the COI has a radius, then the near side is checked. COI must + /// be non-null for this setting to have any effect. + [Tooltip("Adjust stereo level when COI gets too close or too far.")] + public bool checkStereoComfort = true; + + /// Smoothes the changes to the stereo camera FOV and position based on #centerOfInterest + /// and #checkStereoComfort. + [Tooltip("Smoothing factor to use when adjusting stereo for COI and comfort.")] + [Range(0,1)] + public float stereoAdjustSmoothing = 0.1f; + + /// For picture-in-picture cameras that don't fill the entire screen, + /// set the virtual depth of the window itself. A value of 0 means + /// zero parallax, which is fairly close. A value of 1 means "full" + /// parallax, which is equal to the interpupillary distance and equates + /// to an infinitely distant window. This does not affect the actual + /// screen size of the the window (in pixels), only the stereo separation + /// of the left and right images. + [Tooltip("Adjust the virtual depth of this camera's window (picture-in-picture only).")] + [Range(0,1)] + public float screenParallax = 0; + + /// For picture-in-picture cameras, move the window away from the edges + /// in VR Mode to make it easier to see. The optics of HMDs make the screen + /// edges hard to see sometimes, so you can use this to keep the PIP visible + /// whether in VR Mode or not. The x value is the fraction of the screen along + /// either side to pad. + [Tooltip("Move the camera window horizontally towards the center of the screen (PIP only).")] + [Range(0,1)] + public float stereoPaddingX = 0; + + /// For picture-in-picture cameras, move the window away from the edges + /// in VR Mode to make it easier to see. The optics of HMDs make the screen + /// edges hard to see sometimes, so you can use this to keep the PIP visible + /// whether in VR Mode or not. The y value is for the top and bottom of the screen to pad. + [Tooltip("Move the camera window vertically towards the center of the screen (PIP only).")] + [Range(0,1)] + public float stereoPaddingY = 0; + + // Flags whether we rendered in stereo for this frame. + private bool renderedStereo = false; + +#if !UNITY_EDITOR + // Cache for speed, except in editor (don't want to get out of sync with the scene). + private GvrEye[] eyes; + private GvrHead head; +#endif + + /// Returns an array of stereo cameras that are controlled by this instance of + /// the script. + /// @note This array is cached for speedier access. Call + /// InvalidateEyes if it is ever necessary to reset the cache. + public GvrEye[] Eyes { + get { +#if UNITY_EDITOR + GvrEye[] eyes = null; // Local variable rather than member, so as not to cache. +#endif + if (eyes == null) { + eyes = GetComponentsInChildren(true) + .Where(eye => eye.Controller == this) + .ToArray(); + } + return eyes; + } + } + + /// Returns the nearest GvrHead that affects our eyes. + /// @note Cached for speed. Call InvalidateEyes to clear the cache. + public GvrHead Head { + get { +#if UNITY_EDITOR + GvrHead head = null; // Local variable rather than member, so as not to cache. +#endif + if (head == null) { + head = Eyes.Select(eye => eye.Head).FirstOrDefault(); + } + return head; + } + } + + /// Clear the cached array of GvrEye children, as well as the GvrHead that controls + /// their gaze. + /// @note Be sure to call this if you programmatically change the set of GvrEye children + /// managed by this StereoController. + public void InvalidateEyes() { +#if !UNITY_EDITOR + eyes = null; + head = null; +#endif + } + + /// Updates the stereo cameras from the mono camera every frame. This includes all Camera + /// component values such as background color, culling mask, viewport rect, and so on. Also, + /// it includes updating the viewport rect and projection matrix for side-by-side stereo, plus + /// applying any adjustments for center of interest and stereo comfort. + public void UpdateStereoValues() { + GvrEye[] eyes = Eyes; + for (int i = 0, n = eyes.Length; i < n; i++) { + eyes[i].UpdateStereoValues(); + } + } + + public Camera cam { get; private set; } + + void Awake() { + GvrViewer.Create(); + cam = GetComponent(); + AddStereoRig(); + } + + /// Helper routine for creation of a stereo rig. Used by the + /// custom editor for this class, or to build the rig at runtime. + public void AddStereoRig() { + // Simplistic test if rig already exists. + // Note: Do not use Eyes property, because it caches the result before we have created the rig. + var eyes = GetComponentsInChildren(true).Where(eye => eye.Controller == this); + if (eyes.Any()) { + return; + } + CreateEye(GvrViewer.Eye.Left); + CreateEye(GvrViewer.Eye.Right); + if (Head == null) { + var head = gameObject.AddComponent(); + // Don't track position for dynamically added Head components, or else + // you may unexpectedly find your camera pinned to the origin. + head.trackPosition = false; + } + } + + // Helper routine for creation of a stereo eye. + private void CreateEye(GvrViewer.Eye eye) { + string nm = name + (eye == GvrViewer.Eye.Left ? " Left" : " Right"); + GameObject go = new GameObject(nm); + go.transform.SetParent(transform, false); + go.AddComponent().enabled = false; + var GvrEye = go.AddComponent(); + GvrEye.eye = eye; + GvrEye.CopyCameraAndMakeSideBySide(this); + } + + /// Compute the position of one of the stereo eye cameras. Accounts for both + /// FOV matching and stereo comfort, if those features are enabled. The input is + /// the [1,1] entry of the eye camera's projection matrix, representing the vertical + /// field of view, and the overall scale being applied to the Z axis. Returns the + /// position of the stereo eye camera in local coordinates. + public Vector3 ComputeStereoEyePosition(GvrViewer.Eye eye, float proj11, float zScale) { + if (centerOfInterest == null || !centerOfInterest.gameObject.activeInHierarchy) { + return GvrViewer.Instance.EyePose(eye).Position * stereoMultiplier; + } + + // Distance of COI relative to head. + float distance = centerOfInterest != null ? + (centerOfInterest.position - transform.position).magnitude : 0; + + // Size of the COI, clamped to [0..distance] for mathematical sanity in following equations. + float radius = Mathf.Clamp(radiusOfInterest, 0, distance); + + // Move the eye so that COI has about the same size onscreen as in the mono camera FOV. + // The radius affects the horizon location, which is where the screen-size matching has to + // occur. + float scale = proj11 / cam.projectionMatrix[1, 1]; // vertical FOV + float offset = + Mathf.Sqrt(radius * radius + (distance * distance - radius * radius) * scale * scale); + float eyeOffset = (distance - offset) * Mathf.Clamp01(matchMonoFOV) / zScale; + + float ipdScale = stereoMultiplier; + if (checkStereoComfort) { + // Manage IPD scale based on the distance to the COI. + float minComfort = GvrViewer.Instance.ComfortableViewingRange.x; + float maxComfort = GvrViewer.Instance.ComfortableViewingRange.y; + if (minComfort < maxComfort) { // Sanity check. + // If closer than the minimum comfort distance, IPD is scaled down. + // If farther than the maximum comfort distance, IPD is scaled up. + // The result is that parallax is clamped within a reasonable range. + float minDistance = (distance - radius) / zScale - eyeOffset; + ipdScale *= minDistance / Mathf.Clamp(minDistance, minComfort, maxComfort); + } + } + + return ipdScale * GvrViewer.Instance.EyePose(eye).Position + eyeOffset * Vector3.forward; + } + + void OnEnable() { + StartCoroutine("EndOfFrame"); + } + + void OnDisable() { + StopCoroutine("EndOfFrame"); + } + + void OnPreCull() { + if (GvrViewer.Instance.VRModeEnabled) { + // Activate the eyes under our control. + GvrEye[] eyes = Eyes; + for (int i = 0, n = eyes.Length; i < n; i++) { + eyes[i].cam.enabled = true; + } + // Turn off the mono camera so it doesn't waste time rendering. Remember to reenable. + // @note The mono camera is left on from beginning of frame till now in order that other game + // logic (e.g. referring to Camera.main) continues to work as expected. + cam.enabled = false; + renderedStereo = true; + } else { + GvrViewer.Instance.UpdateState(); + } + } + + IEnumerator EndOfFrame() { + while (true) { + // If *we* turned off the mono cam, turn it back on for next frame. + if (renderedStereo) { + cam.enabled = true; + renderedStereo = false; + } + yield return new WaitForEndOfFrame(); + } + } +} diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/StereoController.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/StereoController.cs.meta new file mode 100644 index 0000000000..0ec3e48e9a --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/StereoController.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b6788e8e1b3f7447db6657ef0959d3ce +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/StereoRenderEffect.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/StereoRenderEffect.cs new file mode 100644 index 0000000000..f113309056 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/StereoRenderEffect.cs @@ -0,0 +1,52 @@ +// 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. + +using UnityEngine; + +/// @cond +[RequireComponent(typeof(Camera))] +[AddComponentMenu("GoogleVR/StereoRenderEffect")] +public class StereoRenderEffect : MonoBehaviour { + private Material material; + + private Camera cam; + + private static readonly Rect fullRect = new Rect(0, 0, 1, 1); + + void Awake() { + cam = GetComponent(); + } + + void Start() { + material = new Material(Shader.Find("GoogleVR/UnlitTexture")); + } + + void OnRenderImage(RenderTexture source, RenderTexture dest) { + GL.PushMatrix(); + int width = dest ? dest.width : Screen.width; + int height = dest ? dest.height : Screen.height; + GL.LoadPixelMatrix(0, width, height, 0); + // Camera rects are in screen coordinates (bottom left is origin), but DrawTexture takes a + // rect in GUI coordinates (top left is origin). + Rect blitRect = cam.pixelRect; + blitRect.y = height - blitRect.height - blitRect.y; + RenderTexture oldActive = RenderTexture.active; + RenderTexture.active = dest; + Graphics.DrawTexture(blitRect, source, fullRect, 0, 0, 0, 0, Color.white, material); + RenderTexture.active = oldActive; + GL.PopMatrix(); + } +} +/// @endcond + diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/StereoRenderEffect.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/StereoRenderEffect.cs.meta new file mode 100644 index 0000000000..662f6842eb --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/StereoRenderEffect.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 89c49a017c128489588ad11b3fd1a2dc +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices.meta new file mode 100644 index 0000000000..1d94c834db --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 3fc5956d227e846e19090513e884a2b2 +folderAsset: yes +timeCreated: 1427095578 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/AndroidDevice.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/AndroidDevice.cs new file mode 100644 index 0000000000..24f7c0eb08 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/AndroidDevice.cs @@ -0,0 +1,83 @@ +// 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_ANDROID + +using UnityEngine; + +/// @cond +namespace Gvr.Internal { + public class AndroidDevice : GvrDevice { + private const string ActivityListenerClass = + "com.google.vr.platform.unity.UnityVrActivityListener"; + + private static AndroidJavaObject activityListener; + + public override void Init() { + SetApplicationState(); + base.Init(); + ConnectToActivity(); + } + + protected override void ConnectToActivity() { + base.ConnectToActivity(); + if (androidActivity != null && activityListener == null) { + activityListener = Create(ActivityListenerClass); + } + } + + public override void SetUILayerEnabled(bool enabled) { + CallObjectMethod(activityListener, "setUILayerEnabled", enabled); + } + + public override void SetVRModeEnabled(bool enabled) { + CallObjectMethod(activityListener, "setVRModeEnabled", enabled); + } + + public override void SetSettingsButtonEnabled(bool enabled) { + CallObjectMethod(activityListener, "setSettingsButtonEnabled", enabled); + } + + public override void SetAlignmentMarkerEnabled(bool enabled) { + CallObjectMethod(activityListener, "setAlignmentMarkerEnabled", enabled); + } + + public override void SetVRBackButtonEnabled(bool enabled) { + CallObjectMethod(activityListener, "setVRBackButtonEnabled", enabled); + } + + public override void SetShowVrBackButtonOnlyInVR(bool only) { + CallObjectMethod(activityListener, "setShowVrBackButtonOnlyInVR", only); + } + + public override void ShowSettingsDialog() { + CallObjectMethod(activityListener, "launchConfigureActivity"); + } + + public override void OnPause(bool pause) { + base.OnPause(pause); + CallObjectMethod(activityListener, "onPause", pause); + } + + private void SetApplicationState() { + if (activityListener == null) { + using (var listenerClass = GetClass(ActivityListenerClass)) { + CallStaticMethod(listenerClass, "setUnityApplicationState"); + } + } + } + } +} +/// @endcond + +#endif diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/AndroidDevice.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/AndroidDevice.cs.meta new file mode 100644 index 0000000000..0c3c27f4fd --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/AndroidDevice.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 41679d3338266415f88d226e6bf3d0be +timeCreated: 1435273491 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/BaseAndroidDevice.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/BaseAndroidDevice.cs new file mode 100644 index 0000000000..d51f9128ed --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/BaseAndroidDevice.cs @@ -0,0 +1,121 @@ +// 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_ANDROID + +using UnityEngine; + +/// @cond +namespace Gvr.Internal { + public abstract class BaseAndroidDevice : BaseVRDevice { + protected AndroidJavaObject androidActivity; + + public override void Destroy() { + if (androidActivity != null) { + androidActivity.Dispose(); + androidActivity = null; + } + base.Destroy(); + } + + protected virtual void ConnectToActivity() { + try { + using (AndroidJavaClass player = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { + androidActivity = player.GetStatic("currentActivity"); + } + } catch (AndroidJavaException e) { + androidActivity = null; + Debug.LogError("Exception while connecting to the Activity: " + e); + } + } + + public static AndroidJavaClass GetClass(string className) { + try { + return new AndroidJavaClass(className); + } catch (AndroidJavaException e) { + Debug.LogError("Exception getting class " + className + ": " + e); + return null; + } + } + + public static AndroidJavaObject Create(string className, params object[] args) { + try { + return new AndroidJavaObject(className, args); + } catch (AndroidJavaException e) { + Debug.LogError("Exception creating object " + className + ": " + e); + return null; + } + } + + public static bool CallStaticMethod(AndroidJavaObject jo, string name, params object[] args) { + if (jo == null) { + Debug.LogError("Object is null when calling static method " + name); + return false; + } + try { + jo.CallStatic(name, args); + return true; + } catch (AndroidJavaException e) { + Debug.LogError("Exception calling static method " + name + ": " + e); + return false; + } + } + + public static bool CallObjectMethod(AndroidJavaObject jo, string name, params object[] args) { + if (jo == null) { + Debug.LogError("Object is null when calling method " + name); + return false; + } + try { + jo.Call(name, args); + return true; + } catch (AndroidJavaException e) { + Debug.LogError("Exception calling method " + name + ": " + e); + return false; + } + } + + public static bool CallStaticMethod(ref T result, AndroidJavaObject jo, string name, + params object[] args) { + if (jo == null) { + Debug.LogError("Object is null when calling static method " + name); + return false; + } + try { + result = jo.CallStatic(name, args); + return true; + } catch (AndroidJavaException e) { + Debug.LogError("Exception calling static method " + name + ": " + e); + return false; + } + } + + public static bool CallObjectMethod(ref T result, AndroidJavaObject jo, string name, + params object[] args) { + if (jo == null) { + Debug.LogError("Object is null when calling method " + name); + return false; + } + try { + result = jo.Call(name, args); + return true; + } catch (AndroidJavaException e) { + Debug.LogError("Exception calling method " + name + ": " + e); + return false; + } + } + } +} +/// @endcond + +#endif diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/BaseAndroidDevice.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/BaseAndroidDevice.cs.meta new file mode 100644 index 0000000000..25edbc4ca7 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/BaseAndroidDevice.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b19e0579f891c45dc9c0d95559907f46 +timeCreated: 1435273491 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/BaseVRDevice.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/BaseVRDevice.cs new file mode 100644 index 0000000000..44026b3ffd --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/BaseVRDevice.cs @@ -0,0 +1,258 @@ +// 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; + +/// @cond +namespace Gvr.Internal { + // Represents a vr device that this plugin interacts with. + public abstract class BaseVRDevice { + private static BaseVRDevice device = null; + + protected BaseVRDevice() { + Profile = GvrProfile.Default.Clone(); + } + + public GvrProfile Profile { get; protected set; } + + public abstract void Init(); + + public abstract void SetUILayerEnabled(bool enabled); + public abstract void SetVRModeEnabled(bool enabled); + public abstract void SetDistortionCorrectionEnabled(bool enabled); + + public abstract void SetSettingsButtonEnabled(bool enabled); + public abstract void SetAlignmentMarkerEnabled(bool enabled); + public abstract void SetVRBackButtonEnabled(bool enabled); + public abstract void SetShowVrBackButtonOnlyInVR(bool only); + + public abstract void SetNeckModelScale(float scale); + public abstract void SetAutoDriftCorrectionEnabled(bool enabled); + public abstract void SetElectronicDisplayStabilizationEnabled(bool enabled); + + public virtual bool SupportsNativeDistortionCorrection(List diagnostics) { + return true; + } + + public virtual bool RequiresNativeDistortionCorrection() { + return leftEyeOrientation != 0 || rightEyeOrientation != 0; + } + + public virtual bool SupportsNativeUILayer(List diagnostics) { + return true; + } + + public virtual bool ShouldRecreateStereoScreen(int curWidth, int curHeight) { + return this.RequiresNativeDistortionCorrection() + && (curWidth != (int)recommendedTextureSize[0] + || curHeight != (int)recommendedTextureSize[1]); + } + + public virtual RenderTexture CreateStereoScreen() { + float scale = GvrViewer.Instance.StereoScreenScale; + int width = Mathf.RoundToInt(Screen.width * scale); + int height = Mathf.RoundToInt(Screen.height * scale); + if (this.RequiresNativeDistortionCorrection()) { + width = (int)recommendedTextureSize[0]; + height = (int)recommendedTextureSize[1]; + } + //Debug.Log("Creating new default stereo screen texture " + // + width+ "x" + height + "."); + var rt = new RenderTexture(width, height, 24, RenderTextureFormat.Default); + rt.anisoLevel = 0; + rt.antiAliasing = Mathf.Max(QualitySettings.antiAliasing, 1); + return rt; + } + + // Returns true if the URI was set as the device profile, else false. A default URI + // is only accepted if the user has not scanned a QR code already. + public virtual bool SetDefaultDeviceProfile(Uri uri) { + return false; + } + + public virtual void ShowSettingsDialog() { + // Do nothing. + } + + public Pose3D GetHeadPose() { + return this.headPose; + } + protected MutablePose3D headPose = new MutablePose3D(); + + public Pose3D GetEyePose(GvrViewer.Eye eye) { + switch(eye) { + case GvrViewer.Eye.Left: + return leftEyePose; + case GvrViewer.Eye.Right: + return rightEyePose; + default: + return null; + } + } + protected MutablePose3D leftEyePose = new MutablePose3D(); + protected MutablePose3D rightEyePose = new MutablePose3D(); + + public Matrix4x4 GetProjection(GvrViewer.Eye eye, + GvrViewer.Distortion distortion = GvrViewer.Distortion.Distorted) { + switch(eye) { + case GvrViewer.Eye.Left: + return distortion == GvrViewer.Distortion.Distorted ? + leftEyeDistortedProjection : leftEyeUndistortedProjection; + case GvrViewer.Eye.Right: + return distortion == GvrViewer.Distortion.Distorted ? + rightEyeDistortedProjection : rightEyeUndistortedProjection; + default: + return Matrix4x4.identity; + } + } + protected Matrix4x4 leftEyeDistortedProjection; + protected Matrix4x4 rightEyeDistortedProjection; + protected Matrix4x4 leftEyeUndistortedProjection; + protected Matrix4x4 rightEyeUndistortedProjection; + + public Rect GetViewport(GvrViewer.Eye eye, + GvrViewer.Distortion distortion = GvrViewer.Distortion.Distorted) { + switch(eye) { + case GvrViewer.Eye.Left: + return distortion == GvrViewer.Distortion.Distorted ? + leftEyeDistortedViewport : leftEyeUndistortedViewport; + case GvrViewer.Eye.Right: + return distortion == GvrViewer.Distortion.Distorted ? + rightEyeDistortedViewport : rightEyeUndistortedViewport; + default: + return new Rect(); + } + } + protected Rect leftEyeDistortedViewport; + protected Rect rightEyeDistortedViewport; + protected Rect leftEyeUndistortedViewport; + protected Rect rightEyeUndistortedViewport; + + protected Vector2 recommendedTextureSize; + protected int leftEyeOrientation; + protected int rightEyeOrientation; + + public bool triggered; + public bool tilted; + public bool profileChanged; + public bool backButtonPressed; + + public abstract void UpdateState(); + + public abstract void UpdateScreenData(); + + public abstract void Recenter(); + + public abstract void PostRender(RenderTexture stereoScreen); + + public virtual void OnPause(bool pause) { + if (!pause) { + UpdateScreenData(); + } + } + + public virtual void OnFocus(bool focus) { + // Do nothing. + } + + public virtual void OnLevelLoaded(int level) { + // Do nothing. + } + + 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.viewer.lenses.separation / 2; + leftEyePose.Set(leftEyeView); + + float[] rect = new float[4]; + Profile.GetLeftEyeVisibleTanAngles(rect); + leftEyeDistortedProjection = MakeProjection(rect[0], rect[1], rect[2], rect[3], 1, 1000); + Profile.GetLeftEyeNoLensTanAngles(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; + + float width = Screen.width * (leftEyeUndistortedViewport.width+rightEyeDistortedViewport.width); + float height = Screen.height * Mathf.Max(leftEyeUndistortedViewport.height, + rightEyeUndistortedViewport.height); + recommendedTextureSize = new Vector2(width, height); + } + + 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 EditorDevice(); +#elif ANDROID_DEVICE + device = new AndroidDevice(); +#elif IPHONE_DEVICE + device = new iOSDevice(); +#else + throw new InvalidOperationException("Unsupported device."); +#endif + } + return device; + } + } +} +/// @endcond + diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/BaseVRDevice.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/BaseVRDevice.cs.meta new file mode 100644 index 0000000000..04995c2c29 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/BaseVRDevice.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 793ce984b7b0b468c98791a4649eaa03 +timeCreated: 1427095578 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/EditorDevice.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/EditorDevice.cs new file mode 100644 index 0000000000..185cd25a72 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/EditorDevice.cs @@ -0,0 +1,124 @@ +// 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 + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; + +/// @cond +namespace Gvr.Internal { + // Sends simulated values for use when testing within the Unity Editor. + public class EditorDevice : BaseVRDevice { + // Simulated neck model. Vector from the neck pivot point to the point between the eyes. + private static readonly Vector3 neckOffset = new Vector3(0, 0.075f, 0.08f); + + // Use mouse to emulate head in the editor. + private float mouseX = 0; + private float mouseY = 0; + private float mouseZ = 0; + + public override void Init() { + Input.gyro.enabled = true; + } + + public override bool SupportsNativeDistortionCorrection(List diagnostics) { + return false; // No need for diagnostic message. + } + + public override bool SupportsNativeUILayer(List diagnostics) { + return false; // No need for diagnostic message. + } + + // Since we can check all these settings by asking Gvr.Instance, no need + // to keep a separate copy here. + public override void SetUILayerEnabled(bool enabled) {} + public override void SetVRModeEnabled(bool enabled) {} + public override void SetDistortionCorrectionEnabled(bool enabled) {} + public override void SetSettingsButtonEnabled(bool enabled) {} + public override void SetAlignmentMarkerEnabled(bool enabled) {} + public override void SetVRBackButtonEnabled(bool enabled) {} + public override void SetShowVrBackButtonOnlyInVR(bool only) {} + public override void SetNeckModelScale(float scale) {} + public override void SetAutoDriftCorrectionEnabled(bool enabled) {} + public override void SetElectronicDisplayStabilizationEnabled(bool enabled) {} + + private Quaternion initialRotation = Quaternion.identity; + + private bool remoteCommunicating = false; + private bool RemoteCommunicating { + get { + if (!remoteCommunicating) { + remoteCommunicating = EditorApplication.isRemoteConnected; + } + return remoteCommunicating; + } + } + + public override void UpdateState() { + Quaternion rot; + if (GvrViewer.Instance.UseUnityRemoteInput && RemoteCommunicating) { + var att = Input.gyro.attitude * initialRotation; + att = new Quaternion(att.x, att.y, -att.z, -att.w); + rot = Quaternion.Euler(90, 0, 0) * att; + } else { + bool rolled = false; + if (Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt)) { + mouseX += Input.GetAxis("Mouse X") * 5; + if (mouseX <= -180) { + mouseX += 360; + } else if (mouseX > 180) { + mouseX -= 360; + } + mouseY -= Input.GetAxis("Mouse Y") * 2.4f; + mouseY = Mathf.Clamp(mouseY, -85, 85); + } else if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) { + rolled = true; + mouseZ += Input.GetAxis("Mouse X") * 5; + mouseZ = Mathf.Clamp(mouseZ, -85, 85); + } + if (!rolled && GvrViewer.Instance.autoUntiltHead) { + // People don't usually leave their heads tilted to one side for long. + mouseZ = Mathf.Lerp(mouseZ, 0, Time.deltaTime / (Time.deltaTime + 0.1f)); + } + rot = Quaternion.Euler(mouseY, mouseX, mouseZ); + } + var neck = (rot * neckOffset - neckOffset.y * Vector3.up) * GvrViewer.Instance.NeckModelScale; + headPose.Set(neck, rot); + + triggered = Input.GetMouseButtonDown(0); + tilted = Input.GetKeyUp(KeyCode.Escape); + } + + public override void PostRender(RenderTexture stereoScreen) { + // Do nothing. + } + + public override void UpdateScreenData() { + Profile = GvrProfile.GetKnownProfile(GvrViewer.Instance.ScreenSize, GvrViewer.Instance.ViewerType); + ComputeEyesFromProfile(); + profileChanged = true; + } + + public override void Recenter() { + mouseX = mouseZ = 0; // Do not reset pitch, which is how it works on the phone. + if (RemoteCommunicating) { + //initialRotation = Quaternion.Inverse(Input.gyro.attitude); + } + } + } +} +/// @endcond + +#endif diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/EditorDevice.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/EditorDevice.cs.meta new file mode 100644 index 0000000000..2e4089282f --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/EditorDevice.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 76756f042eedf44cdabdc071ded363bf +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/GvrDevice.cs b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/GvrDevice.cs new file mode 100644 index 0000000000..86ad42b9c6 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/GvrDevice.cs @@ -0,0 +1,246 @@ +// 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. + +using UnityEngine; +using System.Runtime.InteropServices; + +/// @cond +namespace Gvr.Internal { + public abstract class GvrDevice : +#if UNITY_ANDROID + BaseAndroidDevice +#else + BaseVRDevice +#endif + { + // A relatively unique id to use when calling our C++ native render plugin. + private const int kRenderEvent = 0x47554342; + + // Event IDs sent up from native layer. Bit flags. + // Keep in sync with the corresponding declaration in unity.h. + private const int kTriggered = 1 << 0; + private const int kTilted = 1 << 1; + private const int kProfileChanged = 1 << 2; + private const int kVRBackButtonPressed = 1 << 3; + + private float[] headData = new float[16]; + private float[] viewData = new float[16 * 6 + 12]; + private float[] profileData = new float[13]; + + private Matrix4x4 headView = new Matrix4x4(); + private Matrix4x4 leftEyeView = new Matrix4x4(); + private Matrix4x4 rightEyeView = new Matrix4x4(); + + protected bool debugDisableNativeProjections = false; + protected bool debugDisableNativeUILayer = false; + + public override void SetDistortionCorrectionEnabled(bool enabled) { + EnableDistortionCorrection(enabled); + } + + public override void SetNeckModelScale(float scale) { + SetNeckModelFactor(scale); + } + + public override void SetAutoDriftCorrectionEnabled(bool enabled) { + EnableAutoDriftCorrection(enabled); + } + + public override void SetElectronicDisplayStabilizationEnabled(bool enabled) { + EnableElectronicDisplayStabilization(enabled); + } + + public override bool SetDefaultDeviceProfile(System.Uri uri) { + byte[] profile = System.Text.Encoding.UTF8.GetBytes(uri.ToString()); + return SetDefaultProfile(profile, profile.Length); + } + + public override void Init() { + // Start will send a log event, so SetUnityVersion first. + byte[] version = System.Text.Encoding.UTF8.GetBytes(Application.unityVersion); + SetUnityVersion(version, version.Length); + Start(); + } + + public override void UpdateState() { + ProcessEvents(); + GetHeadPose(headData); + ExtractMatrix(ref headView, headData); + headPose.SetRightHanded(headView.inverse); + } + + public override void UpdateScreenData() { + UpdateProfile(); + if (debugDisableNativeProjections) { + ComputeEyesFromProfile(); + } else { + UpdateView(); + } + profileChanged = true; + } + + public override void Recenter() { + ResetHeadTracker(); + } + + public override void PostRender(RenderTexture stereoScreen) { + SetTextureId((int)stereoScreen.GetNativeTexturePtr()); + GL.IssuePluginEvent(kRenderEvent); + } + + public override void OnPause(bool pause) { + if (pause) { + Pause(); + } else { + Resume(); + } + } + + public override void OnApplicationQuit() { + Stop(); + base.OnApplicationQuit(); + } + + private void UpdateView() { + GetViewParameters(viewData); + int j = 0; + + j = ExtractMatrix(ref leftEyeView, viewData, j); + j = ExtractMatrix(ref rightEyeView, viewData, j); + leftEyePose.SetRightHanded(leftEyeView.inverse); + rightEyePose.SetRightHanded(rightEyeView.inverse); + + j = ExtractMatrix(ref leftEyeDistortedProjection, viewData, j); + j = ExtractMatrix(ref rightEyeDistortedProjection, viewData, j); + j = ExtractMatrix(ref leftEyeUndistortedProjection, viewData, j); + j = ExtractMatrix(ref rightEyeUndistortedProjection, viewData, j); + + leftEyeUndistortedViewport.Set(viewData[j], viewData[j+1], viewData[j+2], viewData[j+3]); + leftEyeDistortedViewport = leftEyeUndistortedViewport; + j += 4; + + rightEyeUndistortedViewport.Set(viewData[j], viewData[j+1], viewData[j+2], viewData[j+3]); + rightEyeDistortedViewport = rightEyeUndistortedViewport; + j += 4; + + leftEyeOrientation = (int)viewData[j]; + rightEyeOrientation = (int)viewData[j+1]; + j += 2; + + recommendedTextureSize = new Vector2(viewData[j], viewData[j+1]); + j += 2; + } + + private void UpdateProfile() { + GetProfile(profileData); + GvrProfile.Viewer device = new GvrProfile.Viewer(); + GvrProfile.Screen screen = new GvrProfile.Screen(); + device.maxFOV.outer = profileData[0]; + device.maxFOV.upper = profileData[1]; + device.maxFOV.inner = profileData[2]; + device.maxFOV.lower = profileData[3]; + screen.width = profileData[4]; + screen.height = profileData[5]; + screen.border = profileData[6]; + device.lenses.separation = profileData[7]; + device.lenses.offset = profileData[8]; + device.lenses.screenDistance = profileData[9]; + device.lenses.alignment = (int)profileData[10]; + device.distortion.Coef = new [] { profileData[11], profileData[12] }; + Profile.screen = screen; + Profile.viewer = device; + + float[] rect = new float[4]; + Profile.GetLeftEyeNoLensTanAngles(rect); + float maxRadius = GvrProfile.GetMaxRadius(rect); + Profile.viewer.inverse = GvrProfile.ApproximateInverse( + Profile.viewer.distortion, maxRadius); + } + + private static int ExtractMatrix(ref Matrix4x4 mat, float[] data, int i = 0) { + // Matrices returned from our native layer are in row-major order. + for (int r = 0; r < 4; r++) { + for (int c = 0; c < 4; c++, i++) { + mat[r, c] = data[i]; + } + } + return i; + } + + protected virtual void ProcessEvents() { + int flags = GetEventFlags(); + triggered = ((flags & kTriggered) != 0); + tilted = ((flags & kTilted) != 0); + backButtonPressed = ((flags & kVRBackButtonPressed) != 0); + if ((flags & kProfileChanged) != 0) { + UpdateScreenData(); + } + } + +#if UNITY_IOS + private const string dllName = "__Internal"; +#else + private const string dllName = "gvrunity"; +#endif + + [DllImport(dllName)] + private static extern void Start(); + + [DllImport(dllName)] + private static extern void SetTextureId(int id); + + [DllImport(dllName)] + private static extern bool SetDefaultProfile(byte[] uri, int size); + + [DllImport(dllName)] + private static extern void SetUnityVersion(byte[] version_str, int version_length); + + [DllImport(dllName)] + private static extern void EnableDistortionCorrection(bool enable); + + [DllImport(dllName)] + private static extern void EnableAutoDriftCorrection(bool enable); + + [DllImport(dllName)] + private static extern void EnableElectronicDisplayStabilization(bool enable); + + [DllImport(dllName)] + private static extern void SetNeckModelFactor(float factor); + + [DllImport(dllName)] + private static extern void ResetHeadTracker(); + + [DllImport(dllName)] + private static extern int GetEventFlags(); + + [DllImport(dllName)] + private static extern void GetProfile(float[] profile); + + [DllImport(dllName)] + private static extern void GetHeadPose(float[] pose); + + [DllImport(dllName)] + private static extern void GetViewParameters(float[] viewParams); + + [DllImport(dllName)] + private static extern void Pause(); + + [DllImport(dllName)] + private static extern void Resume(); + + [DllImport(dllName)] + private static extern void Stop(); + } +} +/// @endcond diff --git a/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/GvrDevice.cs.meta b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/GvrDevice.cs.meta new file mode 100644 index 0000000000..136373d18f --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/GoogleVR/Scripts/VRDevices/GvrDevice.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3f9c4177b68054245a3e636a43bd364b +timeCreated: 1435273491 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins.meta new file mode 100644 index 0000000000..c03438f5ec --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 471d642390e2e4df5a686915f068dd26 +folderAsset: yes +timeCreated: 1465332980 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/Android.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android.meta similarity index 100% rename from Assets/Plugins/Android.meta rename to Assets/LeapMotionModules/Android/Cardboard/Plugins/Android.meta diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/AndroidManifest.xml b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/AndroidManifest.xml new file mode 100644 index 0000000000..37c20d5a88 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/AndroidManifest.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/AndroidManifest.xml.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/AndroidManifest.xml.meta new file mode 100644 index 0000000000..4446531011 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/AndroidManifest.xml.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 994f4c39b39b64b46bf40f48893781d0 +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/Android/Assets.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/Assets.meta similarity index 100% rename from Assets/Plugins/Android/Assets.meta rename to Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/Assets.meta diff --git a/Assets/Plugins/Android/Assets/README.txt b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/Assets/README.txt similarity index 100% rename from Assets/Plugins/Android/Assets/README.txt rename to Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/Assets/README.txt diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/Assets/README.txt.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/Assets/README.txt.meta new file mode 100644 index 0000000000..66a3c13c90 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/Assets/README.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 562c5f97826aa4c3fb94fef6911b64bb +timeCreated: 1464992762 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/gvr_android_common.aar b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/gvr_android_common.aar new file mode 100644 index 0000000000..c16ffdbbb2 Binary files /dev/null and b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/gvr_android_common.aar differ diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/gvr_android_common.aar.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/gvr_android_common.aar.meta new file mode 100644 index 0000000000..9a45d3b78e --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/gvr_android_common.aar.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: 7aa94195d1a9f47abb6e23db60b9eedc +timeCreated: 1463513187 +licenseType: Pro +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + platformData: + Any: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/gvr_audio.jar b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/gvr_audio.jar new file mode 100644 index 0000000000..7ee3d887ae Binary files /dev/null and b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/gvr_audio.jar differ diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/gvr_audio.jar.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/gvr_audio.jar.meta new file mode 100644 index 0000000000..85c05ad426 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/gvr_audio.jar.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: 285a1f2d044a9412e9b0db9483971715 +timeCreated: 1463513186 +licenseType: Pro +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + platformData: + Any: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs.meta new file mode 100644 index 0000000000..1e40df7a45 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 3440bac22407f4fb0a94e9bbfb584f23 +folderAsset: yes +timeCreated: 1463513163 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/armeabi-v7a.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/armeabi-v7a.meta new file mode 100644 index 0000000000..cbfe1d02fc --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/armeabi-v7a.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2bc287f98c215414aa3ada3c55b7cc65 +folderAsset: yes +timeCreated: 1463513163 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/armeabi-v7a/libaudioplugingvrunity.so b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/armeabi-v7a/libaudioplugingvrunity.so new file mode 100644 index 0000000000..049da6d94b Binary files /dev/null and b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/armeabi-v7a/libaudioplugingvrunity.so differ diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/armeabi-v7a/libaudioplugingvrunity.so.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/armeabi-v7a/libaudioplugingvrunity.so.meta new file mode 100644 index 0000000000..0a22201d92 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/armeabi-v7a/libaudioplugingvrunity.so.meta @@ -0,0 +1,50 @@ +fileFormatVersion: 2 +guid: a8af10a6d40fa45408b7d4875d8f435c +timeCreated: 1463513188 +licenseType: Pro +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 1 + platformData: + Android: + enabled: 0 + settings: + CPU: ARMv7 + Any: + enabled: 1 + settings: {} + Editor: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + Linux: + enabled: 0 + settings: + CPU: x86 + Linux64: + enabled: 0 + settings: + CPU: x86_64 + OSXIntel: + enabled: 0 + settings: + CPU: AnyCPU + OSXIntel64: + enabled: 0 + settings: + CPU: AnyCPU + Win: + enabled: 0 + settings: + CPU: AnyCPU + Win64: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/armeabi-v7a/libgvrunity.so b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/armeabi-v7a/libgvrunity.so new file mode 100644 index 0000000000..4a6f207775 Binary files /dev/null and b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/armeabi-v7a/libgvrunity.so differ diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/armeabi-v7a/libgvrunity.so.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/armeabi-v7a/libgvrunity.so.meta new file mode 100644 index 0000000000..f5caa84f41 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/armeabi-v7a/libgvrunity.so.meta @@ -0,0 +1,50 @@ +fileFormatVersion: 2 +guid: 72170fc775c4c4b399c39cd24bbec001 +timeCreated: 1463513187 +licenseType: Pro +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + platformData: + Android: + enabled: 0 + settings: + CPU: ARMv7 + Any: + enabled: 1 + settings: {} + Editor: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + Linux: + enabled: 0 + settings: + CPU: x86 + Linux64: + enabled: 0 + settings: + CPU: x86_64 + OSXIntel: + enabled: 0 + settings: + CPU: AnyCPU + OSXIntel64: + enabled: 0 + settings: + CPU: AnyCPU + Win: + enabled: 0 + settings: + CPU: AnyCPU + Win64: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/x86.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/x86.meta new file mode 100644 index 0000000000..6bbbfb6850 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/x86.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 35d1040ba226446aea9ad6cc95955a56 +folderAsset: yes +timeCreated: 1463513163 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/x86/libaudioplugingvrunity.so b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/x86/libaudioplugingvrunity.so new file mode 100644 index 0000000000..8b6aabcbda Binary files /dev/null and b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/x86/libaudioplugingvrunity.so differ diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/x86/libaudioplugingvrunity.so.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/x86/libaudioplugingvrunity.so.meta new file mode 100644 index 0000000000..eb89e386cd --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/x86/libaudioplugingvrunity.so.meta @@ -0,0 +1,50 @@ +fileFormatVersion: 2 +guid: 2ad75fe77e8ae425bb9c37405fc4f5b7 +timeCreated: 1463513186 +licenseType: Pro +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 1 + platformData: + Android: + enabled: 0 + settings: + CPU: x86 + Any: + enabled: 1 + settings: {} + Editor: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + Linux: + enabled: 0 + settings: + CPU: x86 + Linux64: + enabled: 0 + settings: + CPU: x86_64 + OSXIntel: + enabled: 0 + settings: + CPU: AnyCPU + OSXIntel64: + enabled: 0 + settings: + CPU: AnyCPU + Win: + enabled: 0 + settings: + CPU: AnyCPU + Win64: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/x86/libgvrunity.so b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/x86/libgvrunity.so new file mode 100644 index 0000000000..632efde51d Binary files /dev/null and b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/x86/libgvrunity.so differ diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/x86/libgvrunity.so.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/x86/libgvrunity.so.meta new file mode 100644 index 0000000000..f84fb86bcd --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/libs/x86/libgvrunity.so.meta @@ -0,0 +1,50 @@ +fileFormatVersion: 2 +guid: 091b2303040a04c71b4c7932ba4f3d94 +timeCreated: 1463513186 +licenseType: Pro +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + platformData: + Android: + enabled: 0 + settings: + CPU: x86 + Any: + enabled: 1 + settings: {} + Editor: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + Linux: + enabled: 0 + settings: + CPU: x86 + Linux64: + enabled: 0 + settings: + CPU: x86_64 + OSXIntel: + enabled: 0 + settings: + CPU: AnyCPU + OSXIntel64: + enabled: 0 + settings: + CPU: AnyCPU + Win: + enabled: 0 + settings: + CPU: AnyCPU + Win64: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/unitygvractivity.aar b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/unitygvractivity.aar new file mode 100644 index 0000000000..c159bbffa8 Binary files /dev/null and b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/unitygvractivity.aar differ diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/unitygvractivity.aar.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/unitygvractivity.aar.meta new file mode 100644 index 0000000000..c14f942143 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/Android/unitygvractivity.aar.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: 4d05cfb524c2a406987a1717161ef88c +timeCreated: 1463513186 +licenseType: Pro +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + platformData: + Any: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86.meta new file mode 100644 index 0000000000..4e7535539a --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ec0c76f54866a472c99de063391b9ebe +folderAsset: yes +timeCreated: 1465332995 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86/audioplugingvrunity.dll b/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86/audioplugingvrunity.dll new file mode 100644 index 0000000000..a8abbb602e Binary files /dev/null and b/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86/audioplugingvrunity.dll differ diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86/audioplugingvrunity.dll.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86/audioplugingvrunity.dll.meta new file mode 100644 index 0000000000..3267bf33bc --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86/audioplugingvrunity.dll.meta @@ -0,0 +1,65 @@ +fileFormatVersion: 2 +guid: 02e3e944dc9eeaa41bbcaa1372a77ecc +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 1 + platformData: + Android: + enabled: 0 + settings: + CPU: AnyCPU + Any: + enabled: 0 + settings: {} + Editor: + enabled: 1 + settings: + CPU: x86 + DefaultValueInitialized: true + OS: Windows + Linux: + enabled: 1 + settings: + CPU: x86 + Linux64: + enabled: 1 + settings: + CPU: None + LinuxUniversal: + enabled: 1 + settings: + CPU: AnyCPU + OSXIntel: + enabled: 1 + settings: + CPU: AnyCPU + OSXIntel64: + enabled: 1 + settings: + CPU: None + OSXUniversal: + enabled: 1 + settings: + CPU: AnyCPU + SamsungTV: + enabled: 0 + settings: + STV_MODEL: STANDARD_13 + Win: + enabled: 1 + settings: + CPU: AnyCPU + Win64: + enabled: 0 + settings: + CPU: None + iOS: + enabled: 0 + settings: + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86_64.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86_64.meta new file mode 100644 index 0000000000..300e80da68 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86_64.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: d9d7f3d3606714e0690caae4fc7266b0 +folderAsset: yes +timeCreated: 1465333011 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86_64/audioplugingvrunity.bundle b/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86_64/audioplugingvrunity.bundle new file mode 100644 index 0000000000..ec4d18fe07 Binary files /dev/null and b/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86_64/audioplugingvrunity.bundle differ diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86_64/audioplugingvrunity.bundle.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86_64/audioplugingvrunity.bundle.meta new file mode 100644 index 0000000000..7b8730d918 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86_64/audioplugingvrunity.bundle.meta @@ -0,0 +1,68 @@ +fileFormatVersion: 2 +guid: 35720a8a08c674133815d46f8d3ad66a +folderAsset: yes +timeCreated: 1462387242 +licenseType: Pro +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 1 + platformData: + Android: + enabled: 0 + settings: + CPU: AnyCPU + Any: + enabled: 0 + settings: {} + Editor: + enabled: 1 + settings: + CPU: x86_64 + DefaultValueInitialized: true + OS: OSX + Linux: + enabled: 0 + settings: + CPU: None + Linux64: + enabled: 1 + settings: + CPU: x86_64 + LinuxUniversal: + enabled: 0 + settings: + CPU: x86_64 + OSXIntel: + enabled: 0 + settings: + CPU: None + OSXIntel64: + enabled: 1 + settings: + CPU: AnyCPU + OSXUniversal: + enabled: 0 + settings: + CPU: x86_64 + SamsungTV: + enabled: 0 + settings: + STV_MODEL: STANDARD_13 + Win: + enabled: 0 + settings: + CPU: None + Win64: + enabled: 1 + settings: + CPU: AnyCPU + iOS: + enabled: 0 + settings: + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86_64/audioplugingvrunity.dll b/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86_64/audioplugingvrunity.dll new file mode 100644 index 0000000000..6f718e8d75 Binary files /dev/null and b/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86_64/audioplugingvrunity.dll differ diff --git a/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86_64/audioplugingvrunity.dll.meta b/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86_64/audioplugingvrunity.dll.meta new file mode 100644 index 0000000000..73704ca14b --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Plugins/x86_64/audioplugingvrunity.dll.meta @@ -0,0 +1,65 @@ +fileFormatVersion: 2 +guid: ade233c5581dc6c4c867cda4d0185ff9 +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 1 + platformData: + Android: + enabled: 0 + settings: + CPU: AnyCPU + Any: + enabled: 0 + settings: {} + Editor: + enabled: 1 + settings: + CPU: x86_64 + DefaultValueInitialized: true + OS: Windows + Linux: + enabled: 0 + settings: + CPU: None + Linux64: + enabled: 1 + settings: + CPU: x86_64 + LinuxUniversal: + enabled: 0 + settings: + CPU: x86_64 + OSXIntel: + enabled: 0 + settings: + CPU: None + OSXIntel64: + enabled: 1 + settings: + CPU: AnyCPU + OSXUniversal: + enabled: 0 + settings: + CPU: x86_64 + SamsungTV: + enabled: 0 + settings: + STV_MODEL: STANDARD_13 + Win: + enabled: 0 + settings: + CPU: None + Win64: + enabled: 1 + settings: + CPU: AnyCPU + iOS: + enabled: 0 + settings: + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Scenes.meta b/Assets/LeapMotionModules/Android/Cardboard/Scenes.meta new file mode 100644 index 0000000000..82401eda3e --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Scenes.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b6aa69733f3844beab53ea67e597b346 +folderAsset: yes +timeCreated: 1465258422 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LeapMotionModules/Android/Cardboard/Scenes/Leap_Hands_Demo_HMD.unity b/Assets/LeapMotionModules/Android/Cardboard/Scenes/Leap_Hands_Demo_HMD.unity new file mode 100644 index 0000000000..98a6c2b685 --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Scenes/Leap_Hands_Demo_HMD.unity @@ -0,0 +1,2612 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +SceneSettings: + m_ObjectHideFlags: 0 + m_PVSData: + m_PVSObjectsArray: [] + m_PVSPortalsArray: [] + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 6 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 6 + m_GIWorkflowMode: 0 + m_LightmapsMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 3 + m_Resolution: 2 + m_BakeResolution: 40 + m_TextureWidth: 1024 + m_TextureHeight: 1024 + m_AOMaxDistance: 1 + m_Padding: 2 + m_CompAOExponent: 0 + m_LightmapParameters: {fileID: 0} + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherRayCount: 1024 + m_ReflectionCompression: 2 + m_LightingDataAsset: {fileID: 0} + m_RuntimeCPUUsage: 25 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + accuratePlacement: 0 + minRegionArea: 2 + cellSize: 0.16666667 + manualCellSize: 0 + m_NavMeshData: {fileID: 0} +--- !u!1001 &53553402 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 593869533} + m_Modifications: + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_LocalPosition.z + value: 0.6 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_RootOrder + value: 2 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_AnchoredPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_AnchoredPosition.y + value: -0.2 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_SizeDelta.x + value: 100 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_SizeDelta.y + value: 100 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_AnchorMin.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_AnchorMin.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_AnchorMax.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_AnchorMax.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_Pivot.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_Pivot.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_LocalScale.x + value: 0.0667 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_LocalScale.y + value: 0.0667 + objectReference: {fileID: 0} + - target: {fileID: 22444642, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_LocalScale.z + value: 0.0667 + objectReference: {fileID: 0} + - target: {fileID: 22332184, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_RenderMode + value: 2 + objectReference: {fileID: 0} + - target: {fileID: 11405556, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: frameRateText + value: + objectReference: {fileID: 53553404} + - target: {fileID: 22332184, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_Camera + value: + objectReference: {fileID: 593869534} + - target: {fileID: 22332184, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_PlaneDistance + value: 10 + objectReference: {fileID: 0} + - target: {fileID: 22462300, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_AnchoredPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 22462300, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_LocalPosition.z + value: -1 + objectReference: {fileID: 0} + - target: {fileID: 11405556, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: Provider + value: + objectReference: {fileID: 506451037} + - target: {fileID: 22462300, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_SizeDelta.x + value: 160 + objectReference: {fileID: 0} + - target: {fileID: 22462300, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_SizeDelta.y + value: 30 + objectReference: {fileID: 0} + - target: {fileID: 22462300, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_LocalScale.x + value: 0.05 + objectReference: {fileID: 0} + - target: {fileID: 22462300, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_LocalScale.y + value: 0.05 + objectReference: {fileID: 0} + - target: {fileID: 22462300, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_LocalScale.z + value: 0.05 + objectReference: {fileID: 0} + - target: {fileID: 22462300, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + propertyPath: m_AnchoredPosition.x + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 100100000, guid: 81a58ec9c7a7a4fababa39069949658f, type: 2} + m_IsPrefabParent: 0 +--- !u!114 &53553404 stripped +MonoBehaviour: + m_PrefabParentObject: {fileID: 11458478, guid: 81a58ec9c7a7a4fababa39069949658f, + type: 2} + m_PrefabInternal: {fileID: 53553402} + m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} +--- !u!1001 &170358228 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 492352490} + m_Modifications: + - target: {fileID: 475100, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 475100, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 475100, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 475100, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.x + value: 0.00000011518241 + objectReference: {fileID: 0} + - target: {fileID: 475100, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.y + value: 0.70722896 + objectReference: {fileID: 0} + - target: {fileID: 475100, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.z + value: 0.7069846 + objectReference: {fileID: 0} + - target: {fileID: 475100, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.w + value: -0.00000011522223 + objectReference: {fileID: 0} + - target: {fileID: 475100, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_RootOrder + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 445960, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.x + value: -0.068455175 + objectReference: {fileID: 0} + - target: {fileID: 445960, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.y + value: -0.06767921 + objectReference: {fileID: 0} + - target: {fileID: 445960, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9898138 + objectReference: {fileID: 0} + - target: {fileID: 445960, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.w + value: 0.10489064 + objectReference: {fileID: 0} + - target: {fileID: 445960, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.x + value: 0.09995664 + objectReference: {fileID: 0} + - target: {fileID: 445960, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.y + value: 0.11906842 + objectReference: {fileID: 0} + - target: {fileID: 445960, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.z + value: 0.037580784 + objectReference: {fileID: 0} + - target: {fileID: 428954, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.x + value: -0.068455175 + objectReference: {fileID: 0} + - target: {fileID: 428954, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.y + value: -0.06767921 + objectReference: {fileID: 0} + - target: {fileID: 428954, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9898138 + objectReference: {fileID: 0} + - target: {fileID: 428954, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.w + value: 0.10489064 + objectReference: {fileID: 0} + - target: {fileID: 428954, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.x + value: 0.104022 + objectReference: {fileID: 0} + - target: {fileID: 428954, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.y + value: 0.12403931 + objectReference: {fileID: 0} + - target: {fileID: 428954, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.z + value: 0.07046974 + objectReference: {fileID: 0} + - target: {fileID: 499498, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.x + value: -0.068455175 + objectReference: {fileID: 0} + - target: {fileID: 499498, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.y + value: -0.06767921 + objectReference: {fileID: 0} + - target: {fileID: 499498, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9898138 + objectReference: {fileID: 0} + - target: {fileID: 499498, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.w + value: 0.10489064 + objectReference: {fileID: 0} + - target: {fileID: 499498, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.x + value: 0.1066273 + objectReference: {fileID: 0} + - target: {fileID: 499498, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.y + value: 0.1272249 + objectReference: {fileID: 0} + - target: {fileID: 499498, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.z + value: 0.09154673 + objectReference: {fileID: 0} + - target: {fileID: 424738, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.x + value: 0.3575552 + objectReference: {fileID: 0} + - target: {fileID: 424738, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.y + value: -0.019904895 + objectReference: {fileID: 0} + - target: {fileID: 424738, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.z + value: -0.7650836 + objectReference: {fileID: 0} + - target: {fileID: 424738, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.w + value: -0.5351684 + objectReference: {fileID: 0} + - target: {fileID: 424738, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.x + value: 0.048510175 + objectReference: {fileID: 0} + - target: {fileID: 424738, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.y + value: 0.13554817 + objectReference: {fileID: 0} + - target: {fileID: 424738, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.z + value: -0.035985824 + objectReference: {fileID: 0} + - target: {fileID: 467128, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.x + value: 0.3575552 + objectReference: {fileID: 0} + - target: {fileID: 467128, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.y + value: -0.019904895 + objectReference: {fileID: 0} + - target: {fileID: 467128, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.z + value: -0.7650836 + objectReference: {fileID: 0} + - target: {fileID: 467128, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.w + value: -0.5351684 + objectReference: {fileID: 0} + - target: {fileID: 467128, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.x + value: 0.02805863 + objectReference: {fileID: 0} + - target: {fileID: 467128, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.y + value: 0.15161814 + objectReference: {fileID: 0} + - target: {fileID: 467128, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.z + value: -0.0070667677 + objectReference: {fileID: 0} + - target: {fileID: 481326, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.x + value: 0.3575552 + objectReference: {fileID: 0} + - target: {fileID: 481326, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.y + value: -0.019904895 + objectReference: {fileID: 0} + - target: {fileID: 481326, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.z + value: -0.7650836 + objectReference: {fileID: 0} + - target: {fileID: 481326, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.w + value: -0.5351684 + objectReference: {fileID: 0} + - target: {fileID: 481326, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.x + value: 0.014061448 + objectReference: {fileID: 0} + - target: {fileID: 481326, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.y + value: 0.1626165 + objectReference: {fileID: 0} + - target: {fileID: 481326, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.z + value: 0.012725628 + objectReference: {fileID: 0} + - target: {fileID: 414404, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.x + value: 0.009242237 + objectReference: {fileID: 0} + - target: {fileID: 414404, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.y + value: -0.07527786 + objectReference: {fileID: 0} + - target: {fileID: 414404, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.z + value: -0.99437046 + objectReference: {fileID: 0} + - target: {fileID: 414404, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.w + value: 0.07399489 + objectReference: {fileID: 0} + - target: {fileID: 414404, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.x + value: 0.07655247 + objectReference: {fileID: 0} + - target: {fileID: 414404, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.y + value: 0.11931021 + objectReference: {fileID: 0} + - target: {fileID: 414404, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.z + value: 0.04531038 + objectReference: {fileID: 0} + - target: {fileID: 451232, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.x + value: 0.009242237 + objectReference: {fileID: 0} + - target: {fileID: 451232, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.y + value: -0.07527786 + objectReference: {fileID: 0} + - target: {fileID: 451232, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.z + value: -0.99437046 + objectReference: {fileID: 0} + - target: {fileID: 451232, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.w + value: 0.07399489 + objectReference: {fileID: 0} + - target: {fileID: 451232, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.x + value: 0.07550507 + objectReference: {fileID: 0} + - target: {fileID: 451232, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.y + value: 0.124573335 + objectReference: {fileID: 0} + - target: {fileID: 451232, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.z + value: 0.08038221 + objectReference: {fileID: 0} + - target: {fileID: 424054, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.x + value: 0.009242237 + objectReference: {fileID: 0} + - target: {fileID: 424054, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.y + value: -0.07527786 + objectReference: {fileID: 0} + - target: {fileID: 424054, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.z + value: -0.99437046 + objectReference: {fileID: 0} + - target: {fileID: 424054, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.w + value: 0.07399489 + objectReference: {fileID: 0} + - target: {fileID: 424054, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.x + value: 0.0748596 + objectReference: {fileID: 0} + - target: {fileID: 424054, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.y + value: 0.12781681 + objectReference: {fileID: 0} + - target: {fileID: 424054, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.z + value: 0.10199567 + objectReference: {fileID: 0} + - target: {fileID: 450638, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.x + value: -0.13843814 + objectReference: {fileID: 0} + - target: {fileID: 450638, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.y + value: -0.029145602 + objectReference: {fileID: 0} + - target: {fileID: 450638, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9739429 + objectReference: {fileID: 0} + - target: {fileID: 450638, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.w + value: 0.17725909 + objectReference: {fileID: 0} + - target: {fileID: 450638, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.x + value: 0.11958266 + objectReference: {fileID: 0} + - target: {fileID: 450638, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.y + value: 0.12173278 + objectReference: {fileID: 0} + - target: {fileID: 450638, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.z + value: 0.025443438 + objectReference: {fileID: 0} + - target: {fileID: 406836, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.x + value: -0.13843814 + objectReference: {fileID: 0} + - target: {fileID: 406836, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.y + value: -0.029145602 + objectReference: {fileID: 0} + - target: {fileID: 406836, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9739429 + objectReference: {fileID: 0} + - target: {fileID: 406836, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.w + value: 0.17725909 + objectReference: {fileID: 0} + - target: {fileID: 406836, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.x + value: 0.1261761 + objectReference: {fileID: 0} + - target: {fileID: 406836, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.y + value: 0.124424055 + objectReference: {fileID: 0} + - target: {fileID: 406836, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.z + value: 0.049850702 + objectReference: {fileID: 0} + - target: {fileID: 403052, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.x + value: -0.13843814 + objectReference: {fileID: 0} + - target: {fileID: 403052, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.y + value: -0.029145602 + objectReference: {fileID: 0} + - target: {fileID: 403052, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9739429 + objectReference: {fileID: 0} + - target: {fileID: 403052, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.w + value: 0.17725909 + objectReference: {fileID: 0} + - target: {fileID: 403052, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.x + value: 0.13059376 + objectReference: {fileID: 0} + - target: {fileID: 403052, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.y + value: 0.12622723 + objectReference: {fileID: 0} + - target: {fileID: 403052, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.z + value: 0.066203795 + objectReference: {fileID: 0} + - target: {fileID: 430274, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.x + value: 0.08401716 + objectReference: {fileID: 0} + - target: {fileID: 430274, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.y + value: -0.074111834 + objectReference: {fileID: 0} + - target: {fileID: 430274, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9936847 + objectReference: {fileID: 0} + - target: {fileID: 430274, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.w + value: -0.0062662777 + objectReference: {fileID: 0} + - target: {fileID: 430274, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.x + value: 0.053516097 + objectReference: {fileID: 0} + - target: {fileID: 430274, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.y + value: 0.12095049 + objectReference: {fileID: 0} + - target: {fileID: 437978, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.x + value: 0.08401716 + objectReference: {fileID: 0} + - target: {fileID: 437978, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.y + value: -0.074111834 + objectReference: {fileID: 0} + - target: {fileID: 437978, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9936847 + objectReference: {fileID: 0} + - target: {fileID: 437978, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.w + value: -0.0062662777 + objectReference: {fileID: 0} + - target: {fileID: 437978, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.x + value: 0.04835544 + objectReference: {fileID: 0} + - target: {fileID: 437978, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.y + value: 0.12556091 + objectReference: {fileID: 0} + - target: {fileID: 441686, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.x + value: 0.08401716 + objectReference: {fileID: 0} + - target: {fileID: 441686, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.y + value: -0.074111834 + objectReference: {fileID: 0} + - target: {fileID: 441686, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9936847 + objectReference: {fileID: 0} + - target: {fileID: 441686, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalRotation.w + value: -0.0062662777 + objectReference: {fileID: 0} + - target: {fileID: 441686, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.y + value: 0.1283942 + objectReference: {fileID: 0} + - target: {fileID: 13649788, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Height + value: 0.291 + objectReference: {fileID: 0} + - target: {fileID: 13620250, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Height + value: 0.034330003 + objectReference: {fileID: 0} + - target: {fileID: 13659560, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Height + value: 0.054220006 + objectReference: {fileID: 0} + - target: {fileID: 13631504, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Height + value: 0.023820002 + objectReference: {fileID: 0} + - target: {fileID: 13694622, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Height + value: 0.023960002 + objectReference: {fileID: 0} + - target: {fileID: 13668516, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Height + value: 0.052630004 + objectReference: {fileID: 0} + - target: {fileID: 13686906, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Height + value: 0.025400002 + objectReference: {fileID: 0} + - target: {fileID: 13666838, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Height + value: 0.047780003 + objectReference: {fileID: 0} + - target: {fileID: 13660160, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Height + value: 0.049370002 + objectReference: {fileID: 0} + - target: {fileID: 13652564, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Height + value: 0.039570004 + objectReference: {fileID: 0} + - target: {fileID: 13663724, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Height + value: 0.040740006 + objectReference: {fileID: 0} + - target: {fileID: 13664198, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Height + value: 0.02611 + objectReference: {fileID: 0} + - target: {fileID: 13636776, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Height + value: 0.02967 + objectReference: {fileID: 0} + - target: {fileID: 13626790, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Height + value: 0.03365 + objectReference: {fileID: 0} + - target: {fileID: 13662386, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Height + value: 0.0253 + objectReference: {fileID: 0} + - target: {fileID: 13639576, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Height + value: 0.03038 + objectReference: {fileID: 0} + - target: {fileID: 441686, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.z + value: 0.091460384 + objectReference: {fileID: 0} + - target: {fileID: 437978, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.z + value: 0.07283985 + objectReference: {fileID: 0} + - target: {fileID: 430274, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.z + value: 0.042540044 + objectReference: {fileID: 0} + - target: {fileID: 196280, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_IsActive + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 5433484, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5461410, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5460244, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5464900, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5417756, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5406218, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5401624, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5400048, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5490258, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5491518, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5424522, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5461952, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5410256, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5460242, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5499686, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5476046, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5413384, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 446982, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 446982, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 441686, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalPosition.x + value: 0.045183994 + objectReference: {fileID: 0} + - target: {fileID: 441686, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 441686, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 437978, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 437978, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 430274, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 430274, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 403052, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 403052, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 406836, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 406836, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 450638, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 450638, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 424054, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 424054, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 451232, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 451232, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 414404, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 414404, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 467128, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 467128, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 424738, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 424738, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 499498, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 499498, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 445960, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 445960, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 481326, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 481326, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 428954, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 428954, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 475100, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalEulerAnglesHint.x + value: -89.980194 + objectReference: {fileID: 0} + - target: {fileID: 475100, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalEulerAnglesHint.y + value: -540 + objectReference: {fileID: 0} + - target: {fileID: 13694622, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13686906, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13668516, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13666838, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13664198, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13663724, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13662386, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13660160, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13659560, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13652564, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13649788, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Radius + value: 0.0205 + objectReference: {fileID: 0} + - target: {fileID: 13639576, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13636776, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13631504, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13626790, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13620250, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 499498, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 481326, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 467128, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 451232, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 450638, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 446982, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 445960, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 441686, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 437978, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 430274, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 428954, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 424738, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 424054, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 414404, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 406836, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 403052, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 100100000, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + m_IsPrefabParent: 0 +--- !u!4 &170358229 stripped +Transform: + m_PrefabParentObject: {fileID: 475100, guid: 23f2cce114628a448bfeaae171b4c0c0, type: 2} + m_PrefabInternal: {fileID: 170358228} +--- !u!114 &170358230 stripped +MonoBehaviour: + m_PrefabParentObject: {fileID: 11422472, guid: 23f2cce114628a448bfeaae171b4c0c0, + type: 2} + m_PrefabInternal: {fileID: 170358228} + m_Script: {fileID: 11500000, guid: 9ea79be653ce14db8969d7225d95ec6c, type: 3} +--- !u!1001 &330581568 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 506451036} + m_Modifications: + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.size + value: 52 + objectReference: {fileID: 0} + - target: {fileID: 464466, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 464466, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 464466, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 464466, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 464466, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 464466, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 464466, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 464466, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: m_RootOrder + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _sphereMesh + value: + objectReference: {fileID: 4300000, guid: d3c658b9d2d991e49944fe238fc8b166, type: 3} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _showArm + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: handedness + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 188576, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: m_IsActive + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _cylinderResolution + value: 12 + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[0] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[1] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[2] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[3] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[4] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[5] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[6] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[7] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[8] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[9] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[10] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[11] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[12] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[13] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[14] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[15] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[16] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[17] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[18] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[19] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[20] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[21] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[22] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[23] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[24] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[25] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[26] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[27] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[28] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[29] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[30] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[31] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[32] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[33] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[34] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[35] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[36] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[37] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[38] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[39] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[40] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[41] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[42] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[43] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[44] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[45] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[46] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[47] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[48] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[49] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[50] + value: + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: _serializedTransforms.Array.data[51] + value: + objectReference: {fileID: 0} + - target: {fileID: 464466, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 100100000, guid: 869d20cdda15af24aab9e72b5f2eec78, type: 2} + m_IsPrefabParent: 0 +--- !u!114 &330581569 stripped +MonoBehaviour: + m_PrefabParentObject: {fileID: 11407378, guid: 869d20cdda15af24aab9e72b5f2eec78, + type: 2} + m_PrefabInternal: {fileID: 330581568} + m_Script: {fileID: 11500000, guid: a04122797dd84ca43a07055f12d91e0f, type: 3} +--- !u!1 &492352489 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 4 + m_Component: + - 4: {fileID: 492352490} + m_Layer: 0 + m_Name: PhysicsModels + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &492352490 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 492352489} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0.03, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 170358229} + - {fileID: 1434188112} + m_Father: {fileID: 593869532} + m_RootOrder: 1 +--- !u!1001 &506451035 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 593869532} + m_Modifications: + - target: {fileID: 11406336, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: ModelPool.Array.size + value: 2 + objectReference: {fileID: 0} + - target: {fileID: 432918, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: m_LocalPosition.x + value: 0.03 + objectReference: {fileID: 0} + - target: {fileID: 432918, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 432918, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 432918, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: m_LocalRotation.x + value: 0.000000115202326 + objectReference: {fileID: 0} + - target: {fileID: 432918, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: m_LocalRotation.y + value: -0.7071067 + objectReference: {fileID: 0} + - target: {fileID: 432918, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: m_LocalRotation.z + value: -0.7071068 + objectReference: {fileID: 0} + - target: {fileID: 432918, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: m_LocalRotation.w + value: -0.00000011520231 + objectReference: {fileID: 0} + - target: {fileID: 432918, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: m_RootOrder + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 11435192, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: _temporalWarping + value: + objectReference: {fileID: 0} + - target: {fileID: 11435192, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: _isHeadMounted + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11435192, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: _overrideDeviceType + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11435192, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: _useInterpolation + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11406336, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: ModelPool.Array.data[0].LeftModel + value: + objectReference: {fileID: 330581569} + - target: {fileID: 11406336, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: ModelPool.Array.data[0].RightModel + value: + objectReference: {fileID: 1090512414} + - target: {fileID: 166326, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: m_IsActive + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11406336, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: ModelPool.Array.data[1].LeftModel + value: + objectReference: {fileID: 170358230} + - target: {fileID: 11406336, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: ModelPool.Array.data[1].RightModel + value: + objectReference: {fileID: 1434188113} + - target: {fileID: 11406336, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: ModelPool.Array.data[0].GroupName + value: Graphics_Hands + objectReference: {fileID: 0} + - target: {fileID: 11406336, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: ModelPool.Array.data[1].GroupName + value: Physics_Hands + objectReference: {fileID: 0} + - target: {fileID: 11406336, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: ModelPool.Array.data[0].IsEnabled + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11406336, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: ModelPool.Array.data[0].CanDuplicate + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11406336, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: ModelPool.Array.data[1].IsEnabled + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11406336, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: ModelPool.Array.data[1].CanDuplicate + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 432918, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 100100000, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + m_IsPrefabParent: 0 +--- !u!4 &506451036 stripped +Transform: + m_PrefabParentObject: {fileID: 432918, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, type: 2} + m_PrefabInternal: {fileID: 506451035} +--- !u!114 &506451037 stripped +MonoBehaviour: + m_PrefabParentObject: {fileID: 11435192, guid: b9c7aaf0d314cb847a3b2a20e893f1b6, + type: 2} + m_PrefabInternal: {fileID: 506451035} + m_Script: {fileID: 11500000, guid: 025cc0fa7b46aa541aba29d28d35ac09, type: 3} +--- !u!1001 &593869531 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 400004, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400004, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400004, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400004, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400004, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400004, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 400004, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 400004, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + propertyPath: m_RootOrder + value: 2 + objectReference: {fileID: 0} + - target: {fileID: 2000004, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + propertyPath: field of view + value: 169 + objectReference: {fileID: 0} + - target: {fileID: 2000004, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + propertyPath: near clip plane + value: 0.01 + objectReference: {fileID: 0} + - target: {fileID: 2000002, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + propertyPath: field of view + value: 169 + objectReference: {fileID: 0} + - target: {fileID: 2000002, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + propertyPath: near clip plane + value: 0.01 + objectReference: {fileID: 0} + - target: {fileID: 2000000, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + propertyPath: field of view + value: 169 + objectReference: {fileID: 0} + - target: {fileID: 2000000, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + propertyPath: near clip plane + value: 0.01 + objectReference: {fileID: 0} + - target: {fileID: 400006, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 100100000, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + m_IsPrefabParent: 0 +--- !u!4 &593869532 stripped +Transform: + m_PrefabParentObject: {fileID: 400002, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + m_PrefabInternal: {fileID: 593869531} +--- !u!4 &593869533 stripped +Transform: + m_PrefabParentObject: {fileID: 400006, guid: b8b03d395f5734e98af91ccf44f9bf47, type: 2} + m_PrefabInternal: {fileID: 593869531} +--- !u!20 &593869534 stripped +Camera: + m_PrefabParentObject: {fileID: 2000004, guid: b8b03d395f5734e98af91ccf44f9bf47, + type: 2} + m_PrefabInternal: {fileID: 593869531} +--- !u!1001 &1090512413 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 506451036} + m_Modifications: + - target: {fileID: 464466, guid: 39d18871c11b53c4082d8202e3db68a3, type: 2} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 464466, guid: 39d18871c11b53c4082d8202e3db68a3, type: 2} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 464466, guid: 39d18871c11b53c4082d8202e3db68a3, type: 2} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 464466, guid: 39d18871c11b53c4082d8202e3db68a3, type: 2} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 464466, guid: 39d18871c11b53c4082d8202e3db68a3, type: 2} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 464466, guid: 39d18871c11b53c4082d8202e3db68a3, type: 2} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 464466, guid: 39d18871c11b53c4082d8202e3db68a3, type: 2} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 464466, guid: 39d18871c11b53c4082d8202e3db68a3, type: 2} + propertyPath: m_RootOrder + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11407378, guid: 39d18871c11b53c4082d8202e3db68a3, type: 2} + propertyPath: _sphereMesh + value: + objectReference: {fileID: 4300000, guid: d3c658b9d2d991e49944fe238fc8b166, type: 3} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 100100000, guid: 39d18871c11b53c4082d8202e3db68a3, type: 2} + m_IsPrefabParent: 0 +--- !u!114 &1090512414 stripped +MonoBehaviour: + m_PrefabParentObject: {fileID: 11407378, guid: 39d18871c11b53c4082d8202e3db68a3, + type: 2} + m_PrefabInternal: {fileID: 1090512413} + m_Script: {fileID: 11500000, guid: a04122797dd84ca43a07055f12d91e0f, type: 3} +--- !u!1001 &1434188111 +Prefab: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 492352490} + m_Modifications: + - target: {fileID: 415952, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 415952, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 415952, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 415952, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.x + value: 0.000000115202326 + objectReference: {fileID: 0} + - target: {fileID: 415952, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.y + value: -0.7071067 + objectReference: {fileID: 0} + - target: {fileID: 415952, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.z + value: -0.7071068 + objectReference: {fileID: 0} + - target: {fileID: 415952, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.w + value: -0.00000011520231 + objectReference: {fileID: 0} + - target: {fileID: 415952, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_RootOrder + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 13653358, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Radius + value: 0.0205 + objectReference: {fileID: 0} + - target: {fileID: 13653358, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Height + value: 0.29099998 + objectReference: {fileID: 0} + - target: {fileID: 13611584, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13611584, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Height + value: 0.03433 + objectReference: {fileID: 0} + - target: {fileID: 13665176, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13665176, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Height + value: 0.05422 + objectReference: {fileID: 0} + - target: {fileID: 13618002, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13618002, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Height + value: 0.023819998 + objectReference: {fileID: 0} + - target: {fileID: 13675550, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13675550, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Height + value: 0.023959998 + objectReference: {fileID: 0} + - target: {fileID: 13609178, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13609178, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Height + value: 0.03365 + objectReference: {fileID: 0} + - target: {fileID: 13621156, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13621156, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Height + value: 0.02967 + objectReference: {fileID: 0} + - target: {fileID: 13642902, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13642902, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Height + value: 0.05263 + objectReference: {fileID: 0} + - target: {fileID: 13695480, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13695480, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Height + value: 0.025399998 + objectReference: {fileID: 0} + - target: {fileID: 13643808, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13643808, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Height + value: 0.047779996 + objectReference: {fileID: 0} + - target: {fileID: 13640252, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13640252, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Height + value: 0.04937 + objectReference: {fileID: 0} + - target: {fileID: 13661254, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13661254, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Height + value: 0.03038 + objectReference: {fileID: 0} + - target: {fileID: 13604654, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13604654, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Height + value: 0.0253 + objectReference: {fileID: 0} + - target: {fileID: 13638526, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13638526, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Height + value: 0.03957 + objectReference: {fileID: 0} + - target: {fileID: 13630498, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13630498, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Height + value: 0.040740002 + objectReference: {fileID: 0} + - target: {fileID: 13600456, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Radius + value: 0.004 + objectReference: {fileID: 0} + - target: {fileID: 13600456, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Height + value: 0.02611 + objectReference: {fileID: 0} + - target: {fileID: 452704, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.x + value: -0.08401716 + objectReference: {fileID: 0} + - target: {fileID: 452704, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9936847 + objectReference: {fileID: 0} + - target: {fileID: 452704, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.y + value: 0.12839419 + objectReference: {fileID: 0} + - target: {fileID: 452704, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.z + value: 0.09146037 + objectReference: {fileID: 0} + - target: {fileID: 433670, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.x + value: -0.08401716 + objectReference: {fileID: 0} + - target: {fileID: 433670, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9936847 + objectReference: {fileID: 0} + - target: {fileID: 433670, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.x + value: -0.04835544 + objectReference: {fileID: 0} + - target: {fileID: 433670, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.y + value: 0.1255609 + objectReference: {fileID: 0} + - target: {fileID: 433670, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.z + value: 0.072839834 + objectReference: {fileID: 0} + - target: {fileID: 484030, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.x + value: -0.08401716 + objectReference: {fileID: 0} + - target: {fileID: 484030, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9936847 + objectReference: {fileID: 0} + - target: {fileID: 484030, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.x + value: -0.0535161 + objectReference: {fileID: 0} + - target: {fileID: 484030, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.y + value: 0.120950475 + objectReference: {fileID: 0} + - target: {fileID: 484030, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.z + value: 0.042540032 + objectReference: {fileID: 0} + - target: {fileID: 483186, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.x + value: 0.13843812 + objectReference: {fileID: 0} + - target: {fileID: 483186, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.y + value: -0.029145662 + objectReference: {fileID: 0} + - target: {fileID: 483186, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9739429 + objectReference: {fileID: 0} + - target: {fileID: 483186, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.w + value: -0.17725918 + objectReference: {fileID: 0} + - target: {fileID: 483186, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.x + value: -0.13059378 + objectReference: {fileID: 0} + - target: {fileID: 483186, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.y + value: 0.12622723 + objectReference: {fileID: 0} + - target: {fileID: 483186, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.z + value: 0.06620378 + objectReference: {fileID: 0} + - target: {fileID: 478232, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.x + value: 0.13843812 + objectReference: {fileID: 0} + - target: {fileID: 478232, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.y + value: -0.029145662 + objectReference: {fileID: 0} + - target: {fileID: 478232, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9739429 + objectReference: {fileID: 0} + - target: {fileID: 478232, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.w + value: -0.17725918 + objectReference: {fileID: 0} + - target: {fileID: 478232, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.x + value: -0.12617612 + objectReference: {fileID: 0} + - target: {fileID: 478232, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.y + value: 0.12442405 + objectReference: {fileID: 0} + - target: {fileID: 478232, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.z + value: 0.049850687 + objectReference: {fileID: 0} + - target: {fileID: 494458, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.x + value: 0.13843812 + objectReference: {fileID: 0} + - target: {fileID: 494458, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.y + value: -0.029145662 + objectReference: {fileID: 0} + - target: {fileID: 494458, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9739429 + objectReference: {fileID: 0} + - target: {fileID: 494458, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.w + value: -0.17725918 + objectReference: {fileID: 0} + - target: {fileID: 494458, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.x + value: -0.119582675 + objectReference: {fileID: 0} + - target: {fileID: 494458, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.y + value: 0.121732764 + objectReference: {fileID: 0} + - target: {fileID: 494458, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.z + value: 0.025443427 + objectReference: {fileID: 0} + - target: {fileID: 445228, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.x + value: -0.009242244 + objectReference: {fileID: 0} + - target: {fileID: 445228, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.y + value: -0.07527786 + objectReference: {fileID: 0} + - target: {fileID: 445228, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.z + value: -0.99437046 + objectReference: {fileID: 0} + - target: {fileID: 445228, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.w + value: -0.07399498 + objectReference: {fileID: 0} + - target: {fileID: 445228, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.x + value: -0.07485961 + objectReference: {fileID: 0} + - target: {fileID: 445228, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.y + value: 0.1278168 + objectReference: {fileID: 0} + - target: {fileID: 445228, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.z + value: 0.10199565 + objectReference: {fileID: 0} + - target: {fileID: 434850, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.x + value: -0.009242244 + objectReference: {fileID: 0} + - target: {fileID: 434850, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.y + value: -0.07527786 + objectReference: {fileID: 0} + - target: {fileID: 434850, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.z + value: -0.99437046 + objectReference: {fileID: 0} + - target: {fileID: 434850, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.w + value: -0.07399498 + objectReference: {fileID: 0} + - target: {fileID: 434850, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.x + value: -0.07550508 + objectReference: {fileID: 0} + - target: {fileID: 434850, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.y + value: 0.12457331 + objectReference: {fileID: 0} + - target: {fileID: 434850, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.z + value: 0.0803822 + objectReference: {fileID: 0} + - target: {fileID: 467038, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.x + value: -0.009242244 + objectReference: {fileID: 0} + - target: {fileID: 467038, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.y + value: -0.07527786 + objectReference: {fileID: 0} + - target: {fileID: 467038, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.z + value: -0.99437046 + objectReference: {fileID: 0} + - target: {fileID: 467038, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.w + value: -0.07399498 + objectReference: {fileID: 0} + - target: {fileID: 467038, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.x + value: -0.07655248 + objectReference: {fileID: 0} + - target: {fileID: 467038, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.y + value: 0.1193102 + objectReference: {fileID: 0} + - target: {fileID: 467038, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.z + value: 0.04531037 + objectReference: {fileID: 0} + - target: {fileID: 407702, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.x + value: -0.35755518 + objectReference: {fileID: 0} + - target: {fileID: 407702, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.y + value: -0.019904805 + objectReference: {fileID: 0} + - target: {fileID: 407702, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.z + value: -0.7650837 + objectReference: {fileID: 0} + - target: {fileID: 407702, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.w + value: 0.5351683 + objectReference: {fileID: 0} + - target: {fileID: 407702, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.x + value: -0.01406145 + objectReference: {fileID: 0} + - target: {fileID: 407702, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.y + value: 0.16261646 + objectReference: {fileID: 0} + - target: {fileID: 407702, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.z + value: 0.012725617 + objectReference: {fileID: 0} + - target: {fileID: 425120, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.x + value: -0.35755518 + objectReference: {fileID: 0} + - target: {fileID: 425120, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.y + value: -0.019904805 + objectReference: {fileID: 0} + - target: {fileID: 425120, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.z + value: -0.7650837 + objectReference: {fileID: 0} + - target: {fileID: 425120, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.w + value: 0.5351683 + objectReference: {fileID: 0} + - target: {fileID: 425120, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.x + value: -0.028058626 + objectReference: {fileID: 0} + - target: {fileID: 425120, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.y + value: 0.1516181 + objectReference: {fileID: 0} + - target: {fileID: 425120, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.z + value: -0.007066776 + objectReference: {fileID: 0} + - target: {fileID: 436198, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.x + value: -0.35755518 + objectReference: {fileID: 0} + - target: {fileID: 436198, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.y + value: -0.019904805 + objectReference: {fileID: 0} + - target: {fileID: 436198, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.z + value: -0.7650837 + objectReference: {fileID: 0} + - target: {fileID: 436198, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.w + value: 0.5351683 + objectReference: {fileID: 0} + - target: {fileID: 436198, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.x + value: -0.04851018 + objectReference: {fileID: 0} + - target: {fileID: 436198, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.y + value: 0.13554814 + objectReference: {fileID: 0} + - target: {fileID: 436198, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.z + value: -0.035985827 + objectReference: {fileID: 0} + - target: {fileID: 429658, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.x + value: 0.068455175 + objectReference: {fileID: 0} + - target: {fileID: 429658, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.y + value: -0.06767921 + objectReference: {fileID: 0} + - target: {fileID: 429658, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9898138 + objectReference: {fileID: 0} + - target: {fileID: 429658, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.w + value: -0.10489072 + objectReference: {fileID: 0} + - target: {fileID: 429658, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.x + value: -0.106627315 + objectReference: {fileID: 0} + - target: {fileID: 429658, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.y + value: 0.12722489 + objectReference: {fileID: 0} + - target: {fileID: 429658, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.z + value: 0.091546714 + objectReference: {fileID: 0} + - target: {fileID: 441364, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.x + value: 0.068455175 + objectReference: {fileID: 0} + - target: {fileID: 441364, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.y + value: -0.06767921 + objectReference: {fileID: 0} + - target: {fileID: 441364, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9898138 + objectReference: {fileID: 0} + - target: {fileID: 441364, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.w + value: -0.10489072 + objectReference: {fileID: 0} + - target: {fileID: 441364, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.x + value: -0.104022 + objectReference: {fileID: 0} + - target: {fileID: 441364, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.y + value: 0.12403929 + objectReference: {fileID: 0} + - target: {fileID: 441364, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.z + value: 0.07046972 + objectReference: {fileID: 0} + - target: {fileID: 447880, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.x + value: 0.068455175 + objectReference: {fileID: 0} + - target: {fileID: 447880, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.y + value: -0.06767921 + objectReference: {fileID: 0} + - target: {fileID: 447880, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.z + value: -0.9898138 + objectReference: {fileID: 0} + - target: {fileID: 447880, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.w + value: -0.10489072 + objectReference: {fileID: 0} + - target: {fileID: 447880, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.x + value: -0.099956654 + objectReference: {fileID: 0} + - target: {fileID: 447880, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.y + value: 0.11906841 + objectReference: {fileID: 0} + - target: {fileID: 447880, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.z + value: 0.037580773 + objectReference: {fileID: 0} + - target: {fileID: 166188, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_IsActive + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 5483358, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5416028, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5485240, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5478578, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5490284, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5463978, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5451820, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5457042, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5475042, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5406576, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5456926, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5435790, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5442896, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5407498, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5401370, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5490042, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5473404, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_Interpolate + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 403030, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.y + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 403030, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.z + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 445228, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.y + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 445228, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.z + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 434850, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.y + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 434850, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.z + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 467038, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.y + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 467038, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.z + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 452704, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.y + value: -0.074111804 + objectReference: {fileID: 0} + - target: {fileID: 452704, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalPosition.x + value: -0.045183998 + objectReference: {fileID: 0} + - target: {fileID: 452704, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.y + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 452704, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.z + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 433670, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.y + value: -0.074111804 + objectReference: {fileID: 0} + - target: {fileID: 433670, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.y + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 433670, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.z + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 484030, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.y + value: -0.074111804 + objectReference: {fileID: 0} + - target: {fileID: 484030, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.y + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 484030, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.z + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 429658, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.y + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 429658, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.z + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 441364, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.y + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 441364, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.z + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 447880, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.y + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 447880, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.z + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 483186, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.y + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 483186, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.z + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 478232, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.y + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 478232, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.z + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 494458, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.y + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 494458, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.z + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 407702, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.y + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 407702, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.z + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 425120, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.y + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 425120, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.z + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 436198, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.y + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 436198, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.z + value: 1.0000001 + objectReference: {fileID: 0} + - target: {fileID: 415952, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalEulerAnglesHint.x + value: -89.980194 + objectReference: {fileID: 0} + - target: {fileID: 415952, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalEulerAnglesHint.y + value: -540 + objectReference: {fileID: 0} + - target: {fileID: 494458, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 484030, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.w + value: 0.0062661883 + objectReference: {fileID: 0} + - target: {fileID: 484030, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 483186, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 478232, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 467038, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 452704, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.w + value: 0.0062661883 + objectReference: {fileID: 0} + - target: {fileID: 452704, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 447880, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 445228, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 441364, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 436198, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 434850, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 433670, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalRotation.w + value: 0.0062661883 + objectReference: {fileID: 0} + - target: {fileID: 433670, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 429658, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 425120, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 407702, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 403030, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + propertyPath: m_LocalScale.x + value: 1 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 100100000, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + m_IsPrefabParent: 0 +--- !u!4 &1434188112 stripped +Transform: + m_PrefabParentObject: {fileID: 415952, guid: c8515ebee271c0649b9db1321f3026a4, type: 2} + m_PrefabInternal: {fileID: 1434188111} +--- !u!114 &1434188113 stripped +MonoBehaviour: + m_PrefabParentObject: {fileID: 11406422, guid: c8515ebee271c0649b9db1321f3026a4, + type: 2} + m_PrefabInternal: {fileID: 1434188111} + m_Script: {fileID: 11500000, guid: 9ea79be653ce14db8969d7225d95ec6c, type: 3} +--- !u!1 &1966885502 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 4 + m_Component: + - 4: {fileID: 1966885504} + - 108: {fileID: 1966885503} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!108 &1966885503 +Light: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1966885502} + m_Enabled: 1 + serializedVersion: 6 + m_Type: 1 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_Lightmapping: 4 + m_BounceIntensity: 1 + m_ShadowRadius: 0 + m_ShadowAngle: 0 + m_AreaSize: {x: 1, y: 1} +--- !u!4 &1966885504 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1966885502} + m_LocalRotation: {x: 0.40821794, y: -0.23456973, z: 0.109381676, w: 0.87542605} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 diff --git a/Assets/LeapMotionModules/Android/Cardboard/Scenes/Leap_Hands_Demo_HMD.unity.meta b/Assets/LeapMotionModules/Android/Cardboard/Scenes/Leap_Hands_Demo_HMD.unity.meta new file mode 100644 index 0000000000..d32a467f8a --- /dev/null +++ b/Assets/LeapMotionModules/Android/Cardboard/Scenes/Leap_Hands_Demo_HMD.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9f2970612d1b94b1eb751f1ee863593c +timeCreated: 1465259581 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: