Advertisement
Guest User

Untitled

a guest
May 20th, 2019
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.45 KB | None | 0 0
  1.  
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6.  
  7. #if UNITY_2017_2_OR_NEWER
  8. using InputTracking = UnityEngine.XR.InputTracking;
  9. using Node = UnityEngine.XR.XRNode;
  10. #else
  11. using InputTracking = UnityEngine.VR.InputTracking;
  12. using Node = UnityEngine.VR.VRNode;
  13. #endif
  14.  
  15. /// <summary>
  16. /// A head-tracked stereoscopic virtual reality camera rig.
  17. /// </summary>
  18. [ExecuteInEditMode]
  19. public class OVRCameraRig : MonoBehaviour
  20. {
  21. /// <summary>
  22. /// The left eye camera.
  23. /// </summary>
  24. public Camera leftEyeCamera { get { return (usePerEyeCameras) ? _leftEyeCamera : _centerEyeCamera; } }
  25. /// <summary>
  26. /// The right eye camera.
  27. /// </summary>
  28. public Camera rightEyeCamera { get { return (usePerEyeCameras) ? _rightEyeCamera : _centerEyeCamera; } }
  29. /// <summary>
  30. /// Provides a root transform for all anchors in tracking space.
  31. /// </summary>
  32. public Transform trackingSpace { get; private set; }
  33. /// <summary>
  34. /// Always coincides with the pose of the left eye.
  35. /// </summary>
  36. public Transform leftEyeAnchor { get; private set; }
  37. /// <summary>
  38. /// Always coincides with average of the left and right eye poses.
  39. /// </summary>
  40. public Transform centerEyeAnchor { get; private set; }
  41. /// <summary>
  42. /// Always coincides with the pose of the right eye.
  43. /// </summary>
  44. public Transform rightEyeAnchor { get; private set; }
  45. /// <summary>
  46. /// Always coincides with the pose of the left hand.
  47. /// </summary>
  48. public Transform leftHandAnchor { get; private set; }
  49. /// <summary>
  50. /// Always coincides with the pose of the right hand.
  51. /// </summary>
  52. public Transform rightHandAnchor { get; private set; }
  53. /// <summary>
  54. /// Anchors controller pose to fix offset issues for the left hand.
  55. /// </summary>
  56. public Transform leftControllerAnchor { get; private set; }
  57. /// <summary>
  58. /// Anchors controller pose to fix offset issues for the right hand.
  59. /// </summary>
  60. public Transform rightControllerAnchor { get; private set; }
  61. /// <summary>
  62. /// Always coincides with the pose of the sensor.
  63. /// </summary>
  64. public Transform trackerAnchor { get; private set; }
  65. /// <summary>
  66. /// Occurs when the eye pose anchors have been set.
  67. /// </summary>
  68. public event System.Action<OVRCameraRig> UpdatedAnchors;
  69. /// <summary>
  70. /// If true, separate cameras will be used for the left and right eyes.
  71. /// </summary>
  72. public bool usePerEyeCameras = false;
  73. /// <summary>
  74. /// If true, all tracked anchors are updated in FixedUpdate instead of Update to favor physics fidelity.
  75. /// \note: If the fixed update rate doesn't match the rendering framerate (OVRManager.display.appFramerate), the anchors will visibly judder.
  76. /// </summary>
  77. public bool useFixedUpdateForTracking = false;
  78.  
  79. protected bool _skipUpdate = false;
  80. protected readonly string trackingSpaceName = "TrackingSpace";
  81. protected readonly string trackerAnchorName = "TrackerAnchor";
  82. protected readonly string leftEyeAnchorName = "LeftEyeAnchor";
  83. protected readonly string centerEyeAnchorName = "CenterEyeAnchor";
  84. protected readonly string rightEyeAnchorName = "RightEyeAnchor";
  85. protected readonly string leftHandAnchorName = "LeftHandAnchor";
  86. protected readonly string rightHandAnchorName = "RightHandAnchor";
  87. protected readonly string leftControllerAnchorName = "LeftControllerAnchor";
  88. protected readonly string rightControllerAnchorName = "RightControllerAnchor";
  89. protected Camera _centerEyeCamera;
  90. protected Camera _leftEyeCamera;
  91. protected Camera _rightEyeCamera;
  92.  
  93. #region Unity Messages
  94. protected virtual void Awake()
  95. {
  96. _skipUpdate = true;
  97. EnsureGameObjectIntegrity();
  98. }
  99.  
  100. protected virtual void Start()
  101. {
  102. UpdateAnchors();
  103. }
  104.  
  105. protected virtual void FixedUpdate()
  106. {
  107. if (useFixedUpdateForTracking)
  108. UpdateAnchors();
  109. }
  110.  
  111. protected virtual void Update()
  112. {
  113. _skipUpdate = false;
  114.  
  115. if (!useFixedUpdateForTracking)
  116. UpdateAnchors();
  117. }
  118. #endregion
  119.  
  120. protected virtual void UpdateAnchors()
  121. {
  122. EnsureGameObjectIntegrity();
  123.  
  124. if (!Application.isPlaying)
  125. return;
  126.  
  127. if (_skipUpdate)
  128. {
  129. centerEyeAnchor.FromOVRPose(OVRPose.identity, true);
  130. leftEyeAnchor.FromOVRPose(OVRPose.identity, true);
  131. rightEyeAnchor.FromOVRPose(OVRPose.identity, true);
  132.  
  133. return;
  134. }
  135.  
  136. bool monoscopic = OVRManager.instance.monoscopic;
  137. bool hmdPresent = OVRNodeStateProperties.IsHmdPresent();
  138.  
  139. OVRPose tracker = OVRManager.tracker.GetPose();
  140.  
  141. trackerAnchor.localRotation = tracker.orientation;
  142.  
  143. Quaternion emulatedRotation = Quaternion.Euler(-OVRManager.instance.headPoseRelativeOffsetRotation.x, -OVRManager.instance.headPoseRelativeOffsetRotation.y, OVRManager.instance.headPoseRelativeOffsetRotation.z);
  144.  
  145. //Note: in the below code, when using UnityEngine's API, we only update anchor transforms if we have a new, fresh value this frame.
  146. //If we don't, it could mean that tracking is lost, etc. so the pose should not change in the virtual world.
  147. //This can be thought of as similar to calling InputTracking GetLocalPosition and Rotation, but only for doing so when the pose is valid.
  148. //If false is returned for any of these calls, then a new pose is not valid and thus should not be updated.
  149.  
  150. if (hmdPresent)
  151. {
  152. Vector3 centerEyePosition = Vector3.zero;
  153. Quaternion centerEyeRotation = Quaternion.identity;
  154.  
  155. if (OVRNodeStateProperties.GetNodeStatePropertyVector3(Node.CenterEye, NodeStatePropertyType.Position, OVRPlugin.Node.EyeCenter, OVRPlugin.Step.Render, out centerEyePosition))
  156. centerEyeAnchor.localPosition = centerEyePosition;
  157. if (OVRNodeStateProperties.GetNodeStatePropertyQuaternion(Node.CenterEye, NodeStatePropertyType.Orientation, OVRPlugin.Node.EyeCenter, OVRPlugin.Step.Render, out centerEyeRotation))
  158. centerEyeAnchor.localRotation = centerEyeRotation;
  159. }
  160. else
  161. {
  162. centerEyeAnchor.localRotation = emulatedRotation;
  163. centerEyeAnchor.localPosition = OVRManager.instance.headPoseRelativeOffsetTranslation;
  164. }
  165.  
  166. if (!hmdPresent || monoscopic)
  167. {
  168. leftEyeAnchor.localPosition = centerEyeAnchor.localPosition;
  169. rightEyeAnchor.localPosition = centerEyeAnchor.localPosition;
  170. leftEyeAnchor.localRotation = centerEyeAnchor.localRotation;
  171. rightEyeAnchor.localRotation = centerEyeAnchor.localRotation;
  172. }
  173. else
  174. {
  175. Vector3 leftEyePosition = Vector3.zero;
  176. Vector3 rightEyePosition = Vector3.zero;
  177. Quaternion leftEyeRotation = Quaternion.identity;
  178. Quaternion rightEyeRotation = Quaternion.identity;
  179.  
  180. if (OVRNodeStateProperties.GetNodeStatePropertyVector3(Node.LeftEye, NodeStatePropertyType.Position, OVRPlugin.Node.EyeLeft, OVRPlugin.Step.Render, out leftEyePosition))
  181. leftEyeAnchor.localPosition = leftEyePosition;
  182. if (OVRNodeStateProperties.GetNodeStatePropertyVector3(Node.RightEye, NodeStatePropertyType.Position, OVRPlugin.Node.EyeRight, OVRPlugin.Step.Render, out rightEyePosition))
  183. rightEyeAnchor.localPosition = rightEyePosition;
  184. if (OVRNodeStateProperties.GetNodeStatePropertyQuaternion(Node.LeftEye, NodeStatePropertyType.Orientation, OVRPlugin.Node.EyeLeft, OVRPlugin.Step.Render, out leftEyeRotation))
  185. leftEyeAnchor.localRotation = leftEyeRotation;
  186. if (OVRNodeStateProperties.GetNodeStatePropertyQuaternion(Node.RightEye, NodeStatePropertyType.Orientation, OVRPlugin.Node.EyeRight, OVRPlugin.Step.Render, out rightEyeRotation))
  187. rightEyeAnchor.localRotation = rightEyeRotation;
  188. }
  189.  
  190. //Need this for controller offset because if we're on OpenVR, we want to set the local poses as specified by Unity, but if we're not, OVRInput local position is the right anchor
  191. if (OVRManager.loadedXRDevice == OVRManager.XRDevice.OpenVR)
  192. {
  193. Vector3 leftPos = Vector3.zero;
  194. Vector3 rightPos = Vector3.zero;
  195. Quaternion leftQuat = Quaternion.identity;
  196. Quaternion rightQuat = Quaternion.identity;
  197.  
  198. if (OVRNodeStateProperties.GetNodeStatePropertyVector3(Node.LeftHand, NodeStatePropertyType.Position, OVRPlugin.Node.HandLeft, OVRPlugin.Step.Render, out leftPos))
  199. leftHandAnchor.localPosition = leftPos;
  200. if (OVRNodeStateProperties.GetNodeStatePropertyVector3(Node.RightHand, NodeStatePropertyType.Position, OVRPlugin.Node.HandRight, OVRPlugin.Step.Render, out rightPos))
  201. rightHandAnchor.localPosition = rightPos;
  202. if (OVRNodeStateProperties.GetNodeStatePropertyQuaternion(Node.LeftHand, NodeStatePropertyType.Orientation, OVRPlugin.Node.HandLeft, OVRPlugin.Step.Render, out leftQuat))
  203. leftHandAnchor.localRotation = leftQuat;
  204. if (OVRNodeStateProperties.GetNodeStatePropertyQuaternion(Node.RightHand, NodeStatePropertyType.Orientation, OVRPlugin.Node.HandRight, OVRPlugin.Step.Render, out rightQuat))
  205. rightHandAnchor.localRotation = rightQuat;
  206.  
  207. }
  208. else
  209. {
  210. leftHandAnchor.localPosition = OVRInput.GetLocalControllerPosition(OVRInput.Controller.LTouch);
  211. rightHandAnchor.localPosition = OVRInput.GetLocalControllerPosition(OVRInput.Controller.RTouch);
  212. leftHandAnchor.localRotation = OVRInput.GetLocalControllerRotation(OVRInput.Controller.LTouch);
  213. rightHandAnchor.localRotation = OVRInput.GetLocalControllerRotation(OVRInput.Controller.RTouch);
  214. }
  215.  
  216. trackerAnchor.localPosition = tracker.position;
  217.  
  218. OVRPose leftOffsetPose = OVRPose.identity;
  219. OVRPose rightOffsetPose = OVRPose.identity;
  220. if (OVRManager.loadedXRDevice == OVRManager.XRDevice.OpenVR)
  221. {
  222. leftOffsetPose = OVRManager.GetOpenVRControllerOffset(Node.LeftHand);
  223. rightOffsetPose = OVRManager.GetOpenVRControllerOffset(Node.RightHand);
  224.  
  225. //Sets poses of left and right nodes, local to the tracking space.
  226. OVRManager.SetOpenVRLocalPose(trackingSpace.InverseTransformPoint(leftControllerAnchor.position),
  227. trackingSpace.InverseTransformPoint(rightControllerAnchor.position),
  228. Quaternion.Inverse(trackingSpace.rotation) * leftControllerAnchor.rotation,
  229. Quaternion.Inverse(trackingSpace.rotation) * rightControllerAnchor.rotation);
  230. }
  231. rightControllerAnchor.localPosition = rightOffsetPose.position;
  232. rightControllerAnchor.localRotation = rightOffsetPose.orientation;
  233. leftControllerAnchor.localPosition = leftOffsetPose.position;
  234. leftControllerAnchor.localRotation = leftOffsetPose.orientation;
  235.  
  236. RaiseUpdatedAnchorsEvent();
  237. }
  238.  
  239. protected virtual void RaiseUpdatedAnchorsEvent()
  240. {
  241. if (UpdatedAnchors != null)
  242. {
  243. UpdatedAnchors(this);
  244. }
  245. }
  246.  
  247. public virtual void EnsureGameObjectIntegrity()
  248. {
  249. bool monoscopic = OVRManager.instance != null ? OVRManager.instance.monoscopic : false;
  250.  
  251. if (trackingSpace == null)
  252. trackingSpace = ConfigureAnchor(null, trackingSpaceName);
  253.  
  254. if (leftEyeAnchor == null)
  255. leftEyeAnchor = ConfigureAnchor(trackingSpace, leftEyeAnchorName);
  256.  
  257. if (centerEyeAnchor == null)
  258. centerEyeAnchor = ConfigureAnchor(trackingSpace, centerEyeAnchorName);
  259.  
  260. if (rightEyeAnchor == null)
  261. rightEyeAnchor = ConfigureAnchor(trackingSpace, rightEyeAnchorName);
  262.  
  263. if (leftHandAnchor == null)
  264. leftHandAnchor = ConfigureAnchor(trackingSpace, leftHandAnchorName);
  265.  
  266. if (rightHandAnchor == null)
  267. rightHandAnchor = ConfigureAnchor(trackingSpace, rightHandAnchorName);
  268.  
  269. if (trackerAnchor == null)
  270. trackerAnchor = ConfigureAnchor(trackingSpace, trackerAnchorName);
  271.  
  272. if (leftControllerAnchor == null)
  273. leftControllerAnchor = ConfigureAnchor(leftHandAnchor, leftControllerAnchorName);
  274.  
  275. if (rightControllerAnchor == null)
  276. rightControllerAnchor = ConfigureAnchor(rightHandAnchor, rightControllerAnchorName);
  277.  
  278. if (_centerEyeCamera == null || _leftEyeCamera == null || _rightEyeCamera == null)
  279. {
  280. _centerEyeCamera = centerEyeAnchor.GetComponent<Camera>();
  281. _leftEyeCamera = leftEyeAnchor.GetComponent<Camera>();
  282. _rightEyeCamera = rightEyeAnchor.GetComponent<Camera>();
  283.  
  284. if (_centerEyeCamera == null)
  285. {
  286. _centerEyeCamera = centerEyeAnchor.gameObject.AddComponent<Camera>();
  287. _centerEyeCamera.tag = "MainCamera";
  288. }
  289.  
  290. if (_leftEyeCamera == null)
  291. {
  292. _leftEyeCamera = leftEyeAnchor.gameObject.AddComponent<Camera>();
  293. _leftEyeCamera.tag = "MainCamera";
  294. }
  295.  
  296. if (_rightEyeCamera == null)
  297. {
  298. _rightEyeCamera = rightEyeAnchor.gameObject.AddComponent<Camera>();
  299. _rightEyeCamera.tag = "MainCamera";
  300. }
  301.  
  302. _centerEyeCamera.stereoTargetEye = StereoTargetEyeMask.Both;
  303. _leftEyeCamera.stereoTargetEye = StereoTargetEyeMask.Left;
  304. _rightEyeCamera.stereoTargetEye = StereoTargetEyeMask.Right;
  305. }
  306.  
  307. if (monoscopic && !OVRPlugin.EyeTextureArrayEnabled)
  308. {
  309. // Output to left eye only when in monoscopic mode
  310. if (_centerEyeCamera.stereoTargetEye != StereoTargetEyeMask.Left)
  311. {
  312. _centerEyeCamera.stereoTargetEye = StereoTargetEyeMask.Left;
  313. }
  314. }
  315. else
  316. {
  317. if (_centerEyeCamera.stereoTargetEye != StereoTargetEyeMask.Both)
  318. {
  319. _centerEyeCamera.stereoTargetEye = StereoTargetEyeMask.Both;
  320. }
  321. }
  322.  
  323. // disable the right eye camera when in monoscopic mode
  324. if (_centerEyeCamera.enabled == usePerEyeCameras ||
  325. _leftEyeCamera.enabled == !usePerEyeCameras ||
  326. _rightEyeCamera.enabled == !(usePerEyeCameras && (!monoscopic || OVRPlugin.EyeTextureArrayEnabled)))
  327. {
  328. _skipUpdate = true;
  329. }
  330.  
  331. _centerEyeCamera.enabled = !usePerEyeCameras;
  332. _leftEyeCamera.enabled = usePerEyeCameras;
  333. _rightEyeCamera.enabled = (usePerEyeCameras && (!monoscopic || OVRPlugin.EyeTextureArrayEnabled));
  334. }
  335.  
  336. protected virtual Transform ConfigureAnchor(Transform root, string name)
  337. {
  338. Transform anchor = (root != null) ? root.Find(name) : null;
  339.  
  340. if (anchor == null)
  341. {
  342. anchor = transform.Find(name);
  343. }
  344.  
  345. if (anchor == null)
  346. {
  347. anchor = new GameObject(name).transform;
  348. }
  349.  
  350. anchor.name = name;
  351. anchor.parent = (root != null) ? root : transform;
  352. anchor.localScale = Vector3.one;
  353. anchor.localPosition = Vector3.zero;
  354. anchor.localRotation = Quaternion.identity;
  355.  
  356. return anchor;
  357. }
  358.  
  359. public virtual Matrix4x4 ComputeTrackReferenceMatrix()
  360. {
  361. if (centerEyeAnchor == null)
  362. {
  363. Debug.LogError("centerEyeAnchor is required");
  364. return Matrix4x4.identity;
  365. }
  366.  
  367. // The ideal approach would be using UnityEngine.VR.VRNode.TrackingReference, then we would not have to depend on the OVRCameraRig. Unfortunately, it is not available in Unity 5.4.3
  368.  
  369. OVRPose headPose;
  370.  
  371. headPose.position = InputTracking.GetLocalPosition(Node.Head);
  372. headPose.orientation = InputTracking.GetLocalRotation(Node.Head);
  373.  
  374. OVRPose invHeadPose = headPose.Inverse();
  375. Matrix4x4 invHeadMatrix = Matrix4x4.TRS(invHeadPose.position, invHeadPose.orientation, Vector3.one);
  376.  
  377. Matrix4x4 ret = centerEyeAnchor.localToWorldMatrix * invHeadMatrix;
  378.  
  379. return ret;
  380. }
  381. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement