1,此中有真意,欲辨已忘言。

Google Cardboard中一个脚本

// 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;
using System.Collections.Generic;/// @ingroup Scripts
/// This class is the main Cardboard SDK object.
///
/// The Cardboard object communicates with the head-mounted display in order to:
/// -  Query the device for viewing parameters
/// -  Retrieve the latest head tracking data
/// -  Provide 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("Cardboard/Cardboard")]
public class Cardboard : MonoBehaviour {// Cardboard SDK Versionpublic const string CARDBOARD_SDK_VERSION = "0.7";/// The singleton instance of the Cardboard class.public static Cardboard SDK {get {
#if UNITY_EDITORif (sdk == null && !Application.isPlaying) {sdk = UnityEngine.Object.FindObjectOfType<Cardboard>();}
#endifif (sdk == null) {Debug.LogError("No Cardboard instance found.  Ensure one exists in the scene, or call "+ "Cardboard.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 Cardboard.SDK to a later point in time.\n"+ "If exiting the scene, this indicates that the Cardboard object has already "+ "been destroyed.");}return sdk;}}private static Cardboard sdk = null;/// Generate a Cardboard instance.  Takes no action if one already exists.public static void Create() {if (sdk == null && UnityEngine.Object.FindObjectOfType<Cardboard>() == null) {Debug.Log("Creating Cardboard object");var go = new GameObject("Cardboard", typeof(Cardboard));go.transform.localPosition = Vector3.zero;// sdk will be set by Cardboard.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<StereoController>();}return currentController;}}private static Camera currentMainCamera;private static StereoController currentController;/// @condpublic 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 correctionNative,  /// Use the native C++ pluginUnity,   /// 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 Cardboard 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 offOnlyInVR,  /// On in VR Mode, otherwise offOn         /// 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;/// @condpublic 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 CardboardProfile.ScreenSizes ScreenSize {get {return screenSize;}set {if (value != screenSize) {screenSize = value;if (device != null) {device.UpdateScreenData();}}}}[SerializeField]private CardboardProfile.ScreenSizes screenSize = CardboardProfile.ScreenSizes.Nexus5;/// The device type to emulate when testing in the Unity Editor.public CardboardProfile.DeviceTypes DeviceType {get {return deviceType;}set {if (value != deviceType) {deviceType = value;if (device != null) {device.UpdateScreenData();}}}}[SerializeField]private CardboardProfile.DeviceTypes deviceType = CardboardProfile.DeviceTypes.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 CardboardProfile Profile {get {return device.Profile;}}/// Distinguish the stereo eyes.public enum Eye {Left,   /// The left eyeRight,  /// The right eyeCenter  /// The "center" eye (unused)}/// When retrieving the #Projection and #Viewport properties, specifies/// whether you want the values as seen through the Cardboard lenses (`Distorted`) or/// as if no lenses were present (`Undistorted`).public enum Distortion {Distorted,   /// Viewing through the lensesUndistorted  /// 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 CardboardEye 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;/// @endcondprivate void InitDevice() {if (device != null) {device.Destroy();}device = BaseVRDevice.GetDevice();device.Init();List<string> diagnostics = new List<string>();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 (sdk == null) {sdk = this;}if (sdk != this) {Debug.LogError("There must be only one Cardboard object in a scene.");UnityEngine.Object.DestroyImmediate(this);return;}
#if UNITY_IOSApplication.targetFrameRate = 60;
#endif// Prevent the screen from dimming / sleepingScreen.sleepTimeout = SleepTimeout.NeverSleep;InitDevice();StereoScreen = null;AddCardboardCamera();}void Start() {UILayerEnabled = true;}void AddCardboardCamera() {var preRender = UnityEngine.Object.FindObjectOfType<CardboardPreRender>();if (preRender == null) {var go = new GameObject("PreRender", typeof(CardboardPreRender));go.SendMessage("Reset");go.transform.parent = transform;}var postRender = UnityEngine.Object.FindObjectOfType<CardboardPostRender>();if (postRender == null) {var go = new GameObject("PostRender", typeof(CardboardPostRender));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 Cardboard trigger was pulled. True for exactly one complete frame/// after each pull.public bool Triggered { get; private set; }/// Whether the Cardboard 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 Cardboard device 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();}
#endifdevice.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 (sdk == this) {sdk = null;}}
}

// 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;/// @ingroup Scripts
/// Controls a pair of CardboardEye 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
/// CardboardEye). You control this  decision for all cameras at once by setting
/// the value of Cardboard#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 CardboardEye scripts attached, and a CardboardHead script
/// somewhere in the hierarchy of parents and children for head tracking.  The rig
/// is created if necessary, the CardboardHead 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 CardboardEye 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 -> Cardboard -> Update Stereo Cameras_ in the Editor’s
/// main menu, and in the context menu for the `Camera` component.
[RequireComponent(typeof(Camera))]
[AddComponentMenu("Cardboard/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 Cardboard 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 Cardboard 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 Cardboard.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 CardboardEye[] eyes;private CardboardHead 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 CardboardEye[] Eyes {get {
#if UNITY_EDITORCardboardEye[] eyes = null;  // Local variable rather than member, so as not to cache.
#endifif (eyes == null) {eyes = GetComponentsInChildren<CardboardEye>(true).Where(eye => eye.Controller == this).ToArray();}return eyes;}}/// Returns the nearest CardboardHead that affects our eyes./// @note Cached for speed.  Call InvalidateEyes to clear the cache.public CardboardHead Head {get {
#if UNITY_EDITORCardboardHead head = null;  // Local variable rather than member, so as not to cache.
#endifif (head == null) {head = Eyes.Select(eye => eye.Head).FirstOrDefault();}return head;}}/// Clear the cached array of CardboardEye children, as well as the CardboardHead that controls/// their gaze./// @note Be sure to call this if you programmatically change the set of CardboardEye children/// managed by this StereoController.public void InvalidateEyes() {
#if !UNITY_EDITOReyes = 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() {CardboardEye[] eyes = Eyes;for (int i = 0, n = eyes.Length; i < n; i++) {eyes[i].UpdateStereoValues();}}public Camera cam { get; private set; }void Awake() {Cardboard.Create();cam = GetComponent<Camera>();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<CardboardEye>(true).Where(eye => eye.Controller == this);if (eyes.Any()) {return;}CreateEye(Cardboard.Eye.Left);CreateEye(Cardboard.Eye.Right);if (Head == null) {var head = gameObject.AddComponent<CardboardHead>();// 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(Cardboard.Eye eye) {string nm = name + (eye == Cardboard.Eye.Left ? " Left" : " Right");GameObject go = new GameObject(nm);go.transform.SetParent(transform, false);go.AddComponent<Camera>().enabled = false;var cardboardEye = go.AddComponent<CardboardEye>();cardboardEye.eye = eye;cardboardEye.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(Cardboard.Eye eye, float proj11, float zScale) {if (centerOfInterest == null || !centerOfInterest.gameObject.activeInHierarchy) {return Cardboard.SDK.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 FOVfloat 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 = Cardboard.SDK.ComfortableViewingRange.x;float maxComfort = Cardboard.SDK.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 * Cardboard.SDK.EyePose(eye).Position + eyeOffset * Vector3.forward;}void OnEnable() {StartCoroutine("EndOfFrame");}void OnDisable() {StopCoroutine("EndOfFrame");}void OnPreCull() {if (Cardboard.SDK.VRModeEnabled) {// Activate the eyes under our control.CardboardEye[] 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 {Cardboard.SDK.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();}}
}

程序应该怎样写比较规范相关推荐

  1. 程序员必知--代码规范

    首先用我之前的博客中的代码举例子 (C语言编程100例): 第一段代码: #include <stdio.h> int main(){int i, j, n = 0, a[17] = { ...

  2. 技术总监谈好的程序员如何写代码[转]

    技术总监谈好的程序员如何写代码[转] 要判断一个程序员是不是好的程序员,主要看他写的代码,因为程序员最重要的事是写代码.          即便不去理解代码的意图,只要看一眼,好的程序员写的代码与差的 ...

  3. [转]为什么程序员总是写糟糕的代码?这3个原因

    原文请看:为什么程序员总是写糟糕的代码?这3个原因 我最近一直在想我们作为一个行业为什么总是产出糟糕代码的原因. 1.明显原因-- 我一下子想到的最明显的原因是,有好的程序员,也有不那么好的程序员,有 ...

  4. 程序详细设计之代码编写规范_我在不编写任何代码的情况下建立了一个设计策划网站

    程序详细设计之代码编写规范 It's been just over a month since MakeStuffUp.Info - my first solo project as an indep ...

  5. JAVA-重写equalse规范、技巧

    JAVA-重写equalse规范.技巧 1.自反性 任何非空引用x,x.equalse(x) 应该返回true 2.对称性 任何引用x和y,当x.equals(y)返回true,y.equals(x) ...

  6. 程序员如何写简历?来自硅谷的八条建议

    转载自  程序员如何写简历?来自硅谷的八条建议 前言 半个月前我发起了程序员内推项目之后,收到一些邮件,对方单纯希望我帮忙优化一下简历.我提了一些修改意见之后,有一位同学专门给我送了一张亚马逊的礼品卡 ...

  7. 有一个小白程序员,写了一个只能对5个数字进行排序的函数,现在有25个不重复的数字,

    题目:有一个小白程序员,写了一个只能对5个数字进行排序的函数,现在有25个不重复的数字,请问小白同学最少调用几次该函数,可以找出其中最大的三个数? A.5 B.6 C.7 D.8 答案:C 解析:第一 ...

  8. java面试题25 在程序代码中写的注释太多,会使编译后的程序尺寸变大。

    java面试题25 在程序代码中写的注释太多,会使编译后的程序尺寸变大. A:正确 B:错误 蒙蔽树上蒙蔽果,蒙蔽树下你和我 拿到这道题,我觉得说的贼有道理,注释太多,尺寸变大.无疑与就和驾考 一样, ...

  9. google python代码规范_Python代码这样写才规范优雅! (二)

    前文传送门:Python代码这样写才规范优雅! (一)参考:https://www.python.org/dev/peps/pep-0008/Python PEP8编码规范的内容如下: 1. Intr ...

  10. 卖掉 3000 平房子,50 岁程序员回国写代码,三个月内融资 2000 万美元

    2019年7月12日,10多万行C代码的中国物联网大数据平台 TDengine 在 GitHub开源,立即冲上 GitHub 榜首,整整五天霸榜 GitHub.目前该项目在 GitHub 上 Star ...

最新文章

  1. 零基础Java学习之super关键字
  2. ora-12514: tns: 监听程序当前无法识别连接描述符中请求的服务 问题解决
  3. 离线轻量级大数据平台Spark之MLib机器学习库SVM实例
  4. R开发(part3)--概率基础和R语言
  5. 使用jXLS将Excel文件解析为JavaBeans
  6. python爬虫数据分析系统_2小时精通python爬虫技术 带你打造Bug系统数据抽取及统计分析...
  7. [转]很经典的http协议详解
  8. 手撕代码合集[短期更新]
  9. Ubuntu 网速显示,ssh配置
  10. android框架揭秘!Android开发者跳槽指南一线互联网公司面经总结
  11. Google NIK插件的介绍及使用
  12. 阿里云域名以及子域名解析教程
  13. 软件测试之测试用例设计(一)
  14. 数据管理平台(DMP)简介
  15. 若不是因为生活所迫,谁愿把自己搞得满身才华
  16. 虚幻4渲染编程(材质编辑器篇)【第三卷:正式准备开始材质开发】
  17. 剑三重制版怎么同步插件_剑网三重制版茗伊插件怎么导入 | 手游网游页游攻略大全...
  18. html中背景不平铺怎么写,css怎么让背景图片不平铺?
  19. 搭建VLC流媒体服务
  20. 软件体系结构基本概念汇总

热门文章

  1. java多肽跟重载_Java多态vs重写vs重载
  2. python深度神经网络_深度神经网络 (第七部分)。 神经网络的融合: 堆叠
  3. macos怎么装mysql80_Mac下MySQL安装配置教程
  4. MySQL 创建数据表的命令行
  5. QTQuick控件基础(1)
  6. 关于Activity跳转动画大汇总
  7. 分享给设计师们9款免费和有用的英文字体
  8. HTML5 新属性的讲解
  9. MySQL数据库学习2 - 数据库的操作
  10. JVM本地方法栈及native方法