protected override void Start() { base.Start(); if (_deviceOffsetMode == DeviceOffsetMode.Transform && _deviceOrigin == null) { Debug.LogError("Cannot use the Transform device offset mode without " + "specifying a Transform to use as the device origin.", this); _deviceOffsetMode = DeviceOffsetMode.Default; } if (Application.isPlaying && _mainCamera == null && _temporalWarpingMode != TemporalWarpingMode.Off) { Debug.LogError("Cannot perform temporal warping with no pre-cull camera."); } //Get the local tracked pose from the XR Headset so we can calculate the _trackingBaseDeltaPose from it var trackedPose = new Pose(XRSupportUtil.GetXRNodeCenterEyeLocalPosition(), XRSupportUtil.GetXRNodeCenterEyeLocalRotation()); //Find the pose delta from the "local" tracked pose to the actual camera pose, we will use this later on to maintain offsets if (!_trackingBaseDeltaPose.HasValue) { _trackingBaseDeltaPose = _mainCamera.transform.ToLocalPose().mul(trackedPose.inverse()); } }
private void OnDrawGizmos() { Gizmos.color = Color.Lerp(Color.magenta, Color.white, 0.3f).WithAlpha(0.5f); var totalHeight = roomScaleHeightOffset; var segmentsPerMeter = 32; var numSegments = totalHeight * segmentsPerMeter; var segmentLength = totalHeight / numSegments; var rigPos = this.transform.position; var down = this.transform.rotation * Vector3.down; if (Application.isPlaying && XRSupportUtil.IsRoomScale()) { var roomScaleGizmoOffset = Vector3.up * totalHeight; rigPos += roomScaleGizmoOffset; } for (int i = 0; i < numSegments; i += 2) { var segStart = rigPos + down * segmentLength * i; var segEnd = rigPos + down * segmentLength * (i + 1); Gizmos.DrawLine(segStart, segEnd); } var groundPos = rigPos + down * totalHeight; drawCircle(groundPos, down, 0.01f); Gizmos.color = Gizmos.color.WithAlpha(0.3f); drawCircle(groundPos, down, 0.10f); Gizmos.color = Gizmos.color.WithAlpha(0.2f); drawCircle(groundPos, down, 0.20f); }
protected void Update() { if (_shouldSetLocalPosition) { transform.localPosition = transform.forward * _deviceInfo.forwardOffset; _shouldSetLocalPosition = false; } if (Input.GetKeyDown(_recenter) && XRSupportUtil.IsXREnabled() && XRSupportUtil.IsXRDevicePresent()) { XRSupportUtil.Recenter(); } // Manual Time Alignment if (_allowManualTimeAlignment) { if (_unlockHold == KeyCode.None || Input.GetKey(_unlockHold)) { if (Input.GetKeyDown(_moreRewind)) { _customWarpAdjustment += 1; } if (Input.GetKeyDown(_lessRewind)) { _customWarpAdjustment -= 1; } } } }
public void UpdateOrderGivenComponent(Component component) { if (Application.isPlaying) { return; } //Allow the user to specify themselves if VR is disabled. if (!XRSupportUtil.IsXREnabled()) { return; } Camera camera = component.GetComponent <Camera>(); if (camera == null) { camera = component.gameObject.AddComponent <Camera>(); } SerializedObject obj = new SerializedObject(camera); SerializedProperty targetEyeProp = obj.FindProperty(TARGET_EYE_PROPERTY_NAME); OrderType newOrder = (OrderType)targetEyeProp.intValue; if (_orderType != newOrder) { _orderType = newOrder; EditorUtility.SetDirty(component); } }
void OnPreCull() { #if UNITY_EDITOR if (!Application.isPlaying) { return; } #endif // Get most recent tracked pose. Pose trackedPose = new Pose(XRSupportUtil.GetXRNodeCenterEyeLocalPosition(), XRSupportUtil.GetXRNodeCenterEyeLocalRotation()); // BEGIN EDIT YUJIN if (_useLocalTracking) { trackedPose = new Pose(transform.localPosition, transform.localRotation); } // END EDIT YUJIN // If we don't know of any pose offset yet, account for it by finding the pose // delta from the "local" tracked pose to the actual camera pose. if (!_trackingBaseDeltaPose.HasValue) { _trackingBaseDeltaPose = _cachedCamera.transform.ToLocalPose() * trackedPose.inverse; } // This way, we always track a scene-space tracked pose. Pose effTransformPose = _trackingBaseDeltaPose.Value * trackedPose; transformHistory.UpdateDelay(effTransformPose, _leapController.Now()); OnPreCullHandTransforms(_cachedCamera); }
void LateUpdate() { var projectionMatrix = _mainCamera == null ? Matrix4x4.identity : _mainCamera.projectionMatrix; switch (SystemInfo.graphicsDeviceType) { #if !UNITY_2017_2_OR_NEWER case UnityEngine.Rendering.GraphicsDeviceType.Direct3D9: #endif case UnityEngine.Rendering.GraphicsDeviceType.Direct3D11: case UnityEngine.Rendering.GraphicsDeviceType.Direct3D12: for (int i = 0; i < 4; i++) { projectionMatrix[1, i] = -projectionMatrix[1, i]; } // Scale and bias from OpenGL -> D3D depth range for (int i = 0; i < 4; i++) { projectionMatrix[2, i] = projectionMatrix[2, i] * 0.5f + projectionMatrix[3, i] * 0.5f; } break; } // Update Image Warping Vector3 pastPosition; Quaternion pastRotation; transformHistory.SampleTransform(imageTimeStamp - (long)(warpingAdjustment * 1000f), out pastPosition, out pastRotation); // Use _tweenImageWarping var currCenterRotation = XRSupportUtil.GetXRNodeCenterEyeLocalRotation(); var imageReferenceRotation = _temporalWarpingMode != TemporalWarpingMode.Off ? pastRotation : currCenterRotation; Quaternion imageQuatWarp = Quaternion.Inverse(currCenterRotation) * imageReferenceRotation; imageQuatWarp = Quaternion.Euler(imageQuatWarp.eulerAngles.x, imageQuatWarp.eulerAngles.y, -imageQuatWarp.eulerAngles.z); Matrix4x4 imageMatWarp = projectionMatrix #if UNITY_2019_2_OR_NEWER // The camera projection matrices seem to have vertically inverted... * Matrix4x4.TRS(Vector3.zero, imageQuatWarp, new Vector3(1f, -1f, 1f)) #else * Matrix4x4.TRS(Vector3.zero, imageQuatWarp, Vector3.one) #endif * projectionMatrix.inverse; Shader.SetGlobalMatrix("_LeapGlobalWarpedOffset", imageMatWarp); }
protected void LateUpdate() { if (_forceCustomUpdate) { ManuallyUpdateTemporalWarping(); } else if (XRSupportUtil.IsXREnabled()) { updateTemporalWarping(XRSupportUtil.GetXRNodeCenterEyeLocalPosition(), XRSupportUtil.GetXRNodeCenterEyeLocalRotation()); } }
void LateUpdate() { var projectionMatrix = _cachedCamera.projectionMatrix; switch (SystemInfo.graphicsDeviceType) { #if !UNITY_2017_2_OR_NEWER case UnityEngine.Rendering.GraphicsDeviceType.Direct3D9: #endif case UnityEngine.Rendering.GraphicsDeviceType.Direct3D11: case UnityEngine.Rendering.GraphicsDeviceType.Direct3D12: for (int i = 0; i < 4; i++) { projectionMatrix[1, i] = -projectionMatrix[1, i]; } // Scale and bias from OpenGL -> D3D depth range for (int i = 0; i < 4; i++) { projectionMatrix[2, i] = projectionMatrix[2, i] * 0.5f + projectionMatrix[3, i] * 0.5f; } break; } // Update Image Warping Vector3 pastPosition; Quaternion pastRotation; transformHistory.SampleTransform(imageTimeStamp - (long)(warpingAdjustment * 1000f), out pastPosition, out pastRotation); // Use _tweenImageWarping var currCenterRotation = XRSupportUtil.GetXRNodeCenterEyeLocalRotation(); // BEGIN EDIT YUJIN if (_useLocalTracking) { currCenterRotation = transform.localRotation; } // END EDIT YUJIN var imageReferenceRotation = _temporalWarpingMode != TemporalWarpingMode.Off ? pastRotation : currCenterRotation; Quaternion imageQuatWarp = Quaternion.Inverse(currCenterRotation) * imageReferenceRotation; imageQuatWarp = Quaternion.Euler(imageQuatWarp.eulerAngles.x, imageQuatWarp.eulerAngles.y, -imageQuatWarp.eulerAngles.z); Matrix4x4 imageMatWarp = projectionMatrix * Matrix4x4.TRS(Vector3.zero, imageQuatWarp, Vector3.one) * projectionMatrix.inverse; Shader.SetGlobalMatrix("_LeapGlobalWarpedOffset", imageMatWarp); }
private void Start() { _lastKnownHeightOffset = _roomScaleHeightOffset; if (XRSupportUtil.IsRoomScale()) { this.transform.position -= this.transform.up * _roomScaleHeightOffset; } if (recenterOnStart) { XRSupportUtil.Recenter(); } }
protected virtual void onPreCull(Camera preCullingCamera) { if (preCullingCamera != preCullCamera) { return; } #if UNITY_EDITOR if (!Application.isPlaying) { return; } #endif Pose trackedPose; if (_deviceOffsetMode == DeviceOffsetMode.Default || _deviceOffsetMode == DeviceOffsetMode.ManualHeadOffset) { // Get most recent tracked pose from the XR subsystem. trackedPose = new Pose(XRSupportUtil.GetXRNodeCenterEyeLocalPosition(), XRSupportUtil.GetXRNodeCenterEyeLocalRotation()); // If we don't know of any pose offset yet, account for it by finding // the pose delta from the "local" tracked pose to the actual camera // pose. if (!_trackingBaseDeltaPose.HasValue) { _trackingBaseDeltaPose = _cachedCamera.transform.ToLocalPose() * trackedPose.inverse; } // This way, we always track a scene-space tracked pose. trackedPose = _trackingBaseDeltaPose.Value * trackedPose; } else if (_deviceOffsetMode == DeviceOffsetMode.Transform) { trackedPose = deviceOrigin.ToPose(); } else { Debug.LogError("Unsupported DeviceOffsetMode: " + _deviceOffsetMode); return; } transformHistory.UpdateDelay(trackedPose, _leapController.Now()); OnPreCullHandTransforms(_cachedCamera); }
protected virtual void onPreCull(Camera preCullingCamera) { if (preCullingCamera != _mainCamera) { return; } #if UNITY_EDITOR if (!Application.isPlaying) { return; } #endif if (_mainCamera == null || _leapController == null) { if (_temporalWarpingMode == TemporalWarpingMode.Auto || _temporalWarpingMode == TemporalWarpingMode.Manual) { Debug.LogError("The camera or controller need to be set for temporal warping to work"); } return; } Pose trackedPose; if (_deviceOffsetMode == DeviceOffsetMode.Default || _deviceOffsetMode == DeviceOffsetMode.ManualHeadOffset) { //Get the local tracked pose from the XR Headset trackedPose = new Pose(XRSupportUtil.GetXRNodeCenterEyeLocalPosition(), XRSupportUtil.GetXRNodeCenterEyeLocalRotation()); //Use the _trackingBaseDeltaPose calculated on start to convert the local spaced trackedPose into a world space position trackedPose = _trackingBaseDeltaPose.Value.mul(trackedPose); } else if (_deviceOffsetMode == DeviceOffsetMode.Transform) { trackedPose = deviceOrigin.ToPose(); } else { Debug.LogError($"Unsupported DeviceOffsetMode: {_deviceOffsetMode}"); return; } transformHistory.UpdateDelay(trackedPose, _leapController.Now()); OnPreCullHandTransforms(_mainCamera); }
private void onValidCameraParams(LeapVRCameraControl.CameraParams cameraParams) { _projectionMatrix = cameraParams.ProjectionMatrix; if (XRSupportUtil.IsXREnabled()) { if (provider != null) { updateHistory(XRSupportUtil.GetXRNodeCenterEyeLocalPosition(), XRSupportUtil.GetXRNodeCenterEyeLocalRotation()); } if (_syncMode == SyncMode.LOW_LATENCY) { updateTemporalWarping(XRSupportUtil.GetXRNodeCenterEyeLocalPosition(), XRSupportUtil.GetXRNodeCenterEyeLocalRotation()); } } }
private void Update() { if (Application.isPlaying) { var deviceIsPresent = XRSupportUtil.IsXRDevicePresent(); if (deviceIsPresent) { if (enableRuntimeAdjustment) { if (Input.GetKeyDown(stepUpKey)) { roomScaleHeightOffset += stepSize; } if (Input.GetKeyDown(stepDownKey)) { roomScaleHeightOffset -= stepSize; } } if (recenterOnUserPresence && !XRSupportUtil.IsRoomScale()) { var userPresence = XRSupportUtil.IsUserPresent(); if (_lastUserPresence != userPresence) { if (userPresence) { XRSupportUtil.Recenter(); } _lastUserPresence = userPresence; } } if (recenterOnKey && Input.GetKeyDown(recenterKey)) { XRSupportUtil.Recenter(); } } } }
private bool checkShouldEnableHeadMounted() { if (XRSupportUtil.IsXREnabled()) { var parentCamera = GetComponentInParent <Camera>(); if (parentCamera != null && parentCamera.stereoTargetEye != StereoTargetEyeMask.None) { if (!_isHeadMounted) { if (Application.isPlaying) { Debug.LogError("VR is enabled and the LeapServiceProvider is the child of a " + "camera targeting one or both stereo eyes; You should " + "check the isHeadMounted option on the LeapServiceProvider " + "if the Leap is mounted or attached to your VR headset!", this); } return(true); } } } return(false); }
public static Quaternion GetXRNodeHeadLocalRotation() { #if SVR if (SvrManager.Instance != null) { if (XRSupportUtil.IsXREnabled()) { return(SvrManager.Instance.head.transform.localRotation); } else { Debug.LogWarning("Cannot read XRNodeHeadLocalRotation as XR is not enabled"); return(Quaternion.identity); } } #endif #if UNITY_2019_2_OR_NEWER InputTracking.GetNodeStates(nodeStates); Quaternion rotation; foreach (XRNodeState state in nodeStates) { if (state.nodeType == XRNode.Head && state.TryGetRotation(out rotation)) { return(rotation); } } return(Quaternion.identity); #elif UNITY_2017_2_OR_NEWER return(InputTracking.GetLocalRotation(XRNode.Head)); #else return(InputTracking.GetLocalRotation(VRNode.Head)); #endif }
public static Vector3 GetXRNodeHeadLocalPosition() { #if SVR if (SvrManager.Instance != null) { if (XRSupportUtil.IsXREnabled()) { return(SvrManager.Instance.head.localPosition); } else { Debug.LogWarning("Cannot read XRNodeHeadLocalPosition as XR is not enabled"); return(Vector3.zero); } } #endif #if UNITY_2019_2_OR_NEWER InputTracking.GetNodeStates(nodeStates); Vector3 position; foreach (XRNodeState state in nodeStates) { if (state.nodeType == XRNode.Head && state.TryGetPosition(out position)) { return(position); } } return(Vector3.zero); #elif UNITY_2017_2_OR_NEWER return(InputTracking.GetLocalPosition(XRNode.Head)); #else return(InputTracking.GetLocalPosition(VRNode.Head)); #endif }