private void UpdateCompanionAttachment(HOTK_OverlayBase ov) { var overlay = Target as HOTK_CompanionOverlay; if (overlay == null) { return; } switch (overlay.Overlay.AnchorDevice) { case HOTK_Overlay.AttachmentDevice.World: case HOTK_Overlay.AttachmentDevice.Screen: _matchingController = false; gameObject.transform.parent = overlay.gameObject.transform; gameObject.transform.localPosition = Vector3.zero; gameObject.transform.localRotation = Quaternion.identity; break; case HOTK_Overlay.AttachmentDevice.LeftController: case HOTK_Overlay.AttachmentDevice.RightController: _matchingController = true; gameObject.transform.parent = overlay.Overlay.RotationTracker.transform; gameObject.transform.localPosition = Vector3.zero; gameObject.transform.localRotation = Quaternion.identity; break; default: throw new ArgumentOutOfRangeException(); } }
private void StopAiming() { if (lastAimed == null) { return; } if (lastAimed.HittingTracker != null && lastAimed.OnControllerUnhitsOverlay != null) { lastAimed.OnControllerUnhitsOverlay(lastAimed, lastAimed.HittingTracker); } lastAimed.HittingTracker = null; lastAimed = null; }
private void StopTouching() { if (lastTouched == null) { return; } if (lastTouched.TouchingTracker != null && lastTouched.OnControllerStopsTouchingOverlay != null) { lastTouched.OnControllerStopsTouchingOverlay(lastTouched, lastTouched.TouchingTracker); } lastTouched.TouchingTracker = null; lastTouched = null; }
private void UpdateAim() { HOTK_OverlayBase hitBase = null; HOTK_TrackedDevice hitTracker = null; SteamVR_Overlay.IntersectionResults?hitResults = null; // Check if we are touching an overlay foreach (var overlay in _interactableOverlays.Where(overlay => overlay.OnControllerTouchesOverlay != null)) { TestControllerTouchesOverlay(overlay, ref _leftTracker, HOTK_TrackedDevice.EType.LeftController, ref hitBase, ref hitTracker, ref hitResults); TestControllerTouchesOverlay(overlay, ref _rightTracker, HOTK_TrackedDevice.EType.RightController, ref hitBase, ref hitTracker, ref hitResults); } if (hitBase == null && lastTouched != null) { StopTouching(); } if (hitBase != null && lastTouched != hitBase) { StopTouching(); } if (hitBase != null && hitResults != null) { StopAiming(); hitBase.OnControllerTouchesOverlay(hitBase, hitTracker, hitResults.Value); hitBase.TouchingTracker = hitTracker; lastTouched = hitBase; return; } // Check if we are aiming at an overlay foreach (var overlay in _interactableOverlays.Where(overlay => overlay.OnControllerHitsOverlay != null)) { TestControllerAimsAtOverlay(overlay, ref _leftTracker, HOTK_TrackedDevice.EType.LeftController, ref hitBase, ref hitTracker, ref hitResults); TestControllerAimsAtOverlay(overlay, ref _rightTracker, HOTK_TrackedDevice.EType.RightController, ref hitBase, ref hitTracker, ref hitResults); } if (hitBase == null && lastAimed != null) { StopAiming(); } if (hitBase != null && lastAimed != hitBase) { StopAiming(); } if (hitBase != null && hitResults != null) { hitBase.OnControllerHitsOverlay(hitBase, hitTracker, hitResults.Value); hitBase.HittingTracker = hitTracker; lastAimed = hitBase; } }
private void UnAimAtCompanion(HOTK_OverlayBase o, HOTK_TrackedDevice tracker) { if (!_aiming) { return; } _aimedSelectable = null; _aiming = false; _aimingX = -1f; _aimingY = -1f; StartCoroutine(FadeOutCursor()); }
public void SetOverlayCanAim(HOTK_OverlayBase overlay, bool isInteractable = true) { if (isInteractable) { if (!_interactableOverlays.Contains(overlay)) { _interactableOverlays.Add(overlay); } } else { if (_interactableOverlays.Contains(overlay)) { _interactableOverlays.Remove(overlay); } } }
public void SetCompanionCanGaze(HOTK_OverlayBase overlayBase, bool isInteractable = true) { if (isInteractable) { if (!_gazeableCompanionOverlays.Contains(overlayBase)) { _gazeableCompanionOverlays.Add(overlayBase); } } else { if (_gazeableCompanionOverlays.Contains(overlayBase)) { _gazeableCompanionOverlays.Remove(overlayBase); } } }
private void TestControllerTouchesOverlay(HOTK_OverlayBase overlay, ref HOTK_TrackedDevice tracker, HOTK_TrackedDevice.EType role, ref HOTK_OverlayBase target, ref HOTK_TrackedDevice hitTracker, ref SteamVR_Overlay.IntersectionResults?results) { FindTracker(ref tracker, role); if (tracker == null || !tracker.IsValid) { return; } if (overlay.TouchingTracker != null && overlay.TouchingTracker != tracker) { return; } var result = new SteamVR_Overlay.IntersectionResults(); var hit = !(Vector3.Angle(tracker.transform.forward, overlay.RotationTracker.transform.forward) > 90f) && ComputeIntersection(overlay, tracker.gameObject.transform.position - (tracker.gameObject.transform.forward * 0.1f), tracker.gameObject.transform.forward, ref result); if (!hit || result.distance >= 0.15f || (results != null && !(result.distance < results.Value.distance))) { return; } target = overlay; hitTracker = tracker; results = result; }
/// <summary> /// Compute a given Ray and determine if it hit an Overlay /// </summary> /// <param name="source"></param> /// <param name="direction"></param> /// <param name="results"></param> /// <returns></returns> private bool ComputeIntersection(HOTK_OverlayBase hotkOverlay, Vector3 source, Vector3 direction, ref SteamVR_Overlay.IntersectionResults results) { var overlay = OpenVR.Overlay; if (overlay == null) { return(false); } var input = new VROverlayIntersectionParams_t { eOrigin = SteamVR_Render.instance.trackingSpace, vSource = { v0 = source.x, v1 = source.y, v2 = -source.z }, vDirection = { v0 = direction.x, v1 = direction.y, v2 = -direction.z } }; var output = new VROverlayIntersectionResults_t(); if (!overlay.ComputeOverlayIntersection(hotkOverlay.Handle, ref input, ref output)) { return(false); } results.point = new Vector3(output.vPoint.v0, output.vPoint.v1, -output.vPoint.v2); results.normal = new Vector3(output.vNormal.v0, output.vNormal.v1, -output.vNormal.v2); results.UVs = new Vector2(output.vUVs.v0, output.vUVs.v1); results.distance = output.fDistance; return(true); }
private void AttachToOverlay(HOTK_OverlayBase o) { var overlay = o as HOTK_Overlay; if (overlay == null) { return; } // Update Overlay Anchor position GetOverlayPosition(); // Update cached values _anchorDevice = overlay.AnchorDevice; _anchorPoint = overlay.AnchorPoint; _anchorOffset = overlay.AnchorOffset; _alpha = overlay.GetCurrentAlpha(); _scale = overlay.GetCurrentScale(); gameObject.transform.parent = o.gameObject.transform; gameObject.transform.localPosition = Vector3.zero; OverlayReference.transform.parent = Overlay.OverlayReference.transform; OverlayReference.transform.localPosition = Vector3.zero; // Attach Overlay switch (_anchorDevice) { case HOTK_Overlay.AttachmentDevice.Screen: _anchor = OpenVR.k_unTrackedDeviceIndexInvalid; gameObject.transform.localRotation = OverlayMode == CompanionMode.Backside ? Quaternion.AngleAxis(180f, Vector3.up) : Quaternion.identity; OverlayReference.transform.localRotation = Quaternion.identity; break; case HOTK_Overlay.AttachmentDevice.World: _anchor = OpenVR.k_unTrackedDeviceIndexInvalid; gameObject.transform.localRotation = OverlayMode == CompanionMode.Backside ? Quaternion.AngleAxis(180f, Vector3.up) : Quaternion.identity; OverlayReference.transform.localRotation = Quaternion.identity; break; case HOTK_Overlay.AttachmentDevice.LeftController: _anchor = HOTK_TrackedDeviceManager.Instance.LeftIndex; gameObject.transform.localRotation = Quaternion.identity; OverlayReference.transform.localRotation = OverlayMode == CompanionMode.Backside ? Quaternion.AngleAxis(180f, Vector3.up) : Quaternion.identity; OverlayRotationChanges(true); // Force rotational update break; case HOTK_Overlay.AttachmentDevice.RightController: _anchor = HOTK_TrackedDeviceManager.Instance.RightIndex; gameObject.transform.localRotation = Quaternion.identity; OverlayReference.transform.localRotation = OverlayMode == CompanionMode.Backside ? Quaternion.AngleAxis(180f, Vector3.up) : Quaternion.identity; OverlayRotationChanges(true); // Force rotational update break; default: throw new ArgumentOutOfRangeException("device", _anchorDevice, null); } if (OnOverlayAttachmentChanges != null) { OnOverlayAttachmentChanges(this); } updateCompanion = true; }
private void UpdateGaze() { FindTracker(ref _hmdTracker, HOTK_TrackedDevice.EType.HMD); HOTK_Overlay hitOverlay = null; HOTK_OverlayBase hitOverlayBase = null; SteamVR_Overlay.IntersectionResults?hitResult = null; // Test Overlays foreach (var overlay in _gazeableOverlays) { if (overlay.AnimateOnGaze == HOTK_Overlay.AnimationType.None) { continue; } if (overlay.GazeLocked || _hmdTracker == null || !_hmdTracker.IsValid) { continue; } if (!(Vector3.Angle(_hmdTracker.transform.forward, overlay.RotationTracker.transform.forward) <= 90f)) { continue; } var result = new SteamVR_Overlay.IntersectionResults(); var hit = ComputeIntersection(overlay, _hmdTracker.gameObject.transform.position, _hmdTracker.gameObject.transform.forward, ref result); if (!hit || (hitResult != null && !(result.distance < hitResult.Value.distance))) { continue; } hitOverlay = overlay; hitResult = result; } // Test Companions foreach (var overlay in _gazeableCompanionOverlays) { if (_hmdTracker == null || !_hmdTracker.IsValid) { continue; } if (!(Vector3.Angle(_hmdTracker.transform.forward, overlay.RotationTracker.transform.forward) <= 90f)) { continue; } var result = new SteamVR_Overlay.IntersectionResults(); var hit = ComputeIntersection(overlay, _hmdTracker.gameObject.transform.position, _hmdTracker.gameObject.transform.forward, ref result); if (!hit || (hitResult != null && !(result.distance < hitResult.Value.distance))) { continue; } hitOverlay = null; hitOverlayBase = overlay; hitResult = result; } if (hitOverlay != null) { foreach (var overlay in _gazeableOverlays) { overlay.UpdateGaze((overlay.GazeLocked && overlay.GazeLockedOn) || (!overlay.GazeLocked && overlay == hitOverlay)); } foreach (var companion in _gazeableCompanionOverlays) { companion.UpdateGaze(false); } } else if (hitOverlayBase != null) { foreach (var overlay in _gazeableOverlays) { overlay.UpdateGaze(overlay.GazeLocked && overlay.GazeLockedOn); } foreach (var companion in _gazeableCompanionOverlays.Where(o => o != hitOverlayBase)) { companion.UpdateGaze(false); } hitOverlayBase.UpdateGaze(true); } else { foreach (var overlay in _gazeableOverlays) { overlay.UpdateGaze(overlay.GazeLocked && overlay.GazeLockedOn); } foreach (var companion in _gazeableCompanionOverlays) { companion.UpdateGaze(false); } } }
public void GazeDetectorGazed(HOTK_OverlayBase o, bool wasHit) { var changed = false; if (_dodging && (_dodgingOffsetX != DodgeGazeOffset.x || _dodgingOffsetY != DodgeGazeOffset.y)) { _dodgingOffsetX = DodgeGazeOffset.x; _dodgingOffsetY = DodgeGazeOffset.y; AnchorDodge(); if (_dodgingFull) { OverlayReference.transform.localPosition = _dodgingTarget; changed = true; } } if (wasHit) { if (!_dodging) { _dodging = true; _dodgingBase = OverlayReference.transform.localPosition; AnchorDodge(); _dodgingVal = 0f; } else if (_dodgingVal < 1f) { _dodgingVal += DodgeGazeSpeed; if (_dodgingVal > 1f) { _dodgingVal = 1f; } OverlayReference.transform.localPosition = Vector3.Lerp(_dodgingBase, _dodgingTarget, _dodgingVal); changed = true; } else { _dodgingFull = true; } } else { _dodgingFull = false; if (_dodging) { if (_dodgingVal > 0f) { _dodgingVal -= DodgeGazeSpeed; if (_dodgingVal < 0f) { _dodgingVal = 0f; } OverlayReference.transform.localPosition = Vector3.Lerp(_dodgingBase, _dodgingTarget, _dodgingVal); changed = true; } else { _dodging = false; OverlayReference.transform.localPosition = _dodgingBase; } } } if (changed) { DoUpdate(); } }
private void AttachToOverlay(HOTK_OverlayBase o) { var overlay = o as HOTK_Overlay; if (overlay == null) { return; } // Update Overlay Anchor position GetOverlayPosition(); // Update cached values _anchorDevice = overlay.AnchorDevice; _anchorPoint = overlay.AnchorPoint; _anchorOffset = overlay.AnchorOffset; _alpha = overlay.GetCurrentAlpha(); _scale = overlay.GetCurrentScale(); OverlayReference.transform.parent = Overlay.OverlayReference.transform; OverlayReference.transform.localPosition = Vector3.zero; // Attach Overlay switch (_anchorDevice) { case HOTK_Overlay.AttachmentDevice.Screen: _anchor = OpenVR.k_unTrackedDeviceIndexInvalid; gameObject.transform.localRotation = OverlayMode == CompanionMode.Backside ? Quaternion.AngleAxis(180f, Vector3.up) : Quaternion.Euler(_companionEuler.x, _companionEuler.y, _companionEuler.z); OverlayReference.transform.localRotation = Quaternion.identity; break; case HOTK_Overlay.AttachmentDevice.World: _anchor = OpenVR.k_unTrackedDeviceIndexInvalid; gameObject.transform.parent = OverlayMode == CompanionMode.DodgeOnGaze ? o.gameObject.transform.parent : o.gameObject.transform; gameObject.transform.localPosition = OverlayMode == CompanionMode.DodgeOnGaze ? o.gameObject.transform.localPosition : Vector3.zero; gameObject.transform.localRotation = OverlayMode == CompanionMode.Backside ? Quaternion.AngleAxis(180f, Vector3.up) : OverlayMode == CompanionMode.DodgeOnGaze ? o.gameObject.transform.localRotation : Quaternion.Euler(_companionEuler.x, _companionEuler.y, _companionEuler.z); OverlayReference.transform.localRotation = Quaternion.identity; break; case HOTK_Overlay.AttachmentDevice.LeftController: _anchor = HOTK_TrackedDeviceManager.Instance.LeftIndex; gameObject.transform.localRotation = Quaternion.identity; OverlayReference.transform.localRotation = OverlayMode == CompanionMode.Backside ? Quaternion.AngleAxis(180f, Vector3.up) : Quaternion.Euler(_companionEuler.x, _companionEuler.y, _companionEuler.z); OverlayRotationChanges(); // Force rotational update break; case HOTK_Overlay.AttachmentDevice.RightController: _anchor = HOTK_TrackedDeviceManager.Instance.RightIndex; gameObject.transform.localRotation = Quaternion.identity; OverlayReference.transform.localRotation = OverlayMode == CompanionMode.Backside ? Quaternion.AngleAxis(180f, Vector3.up) : Quaternion.Euler(_companionEuler.x, _companionEuler.y, _companionEuler.z); OverlayRotationChanges(); // Force rotational update break; default: throw new ArgumentOutOfRangeException("device", _anchorDevice, null); } if (OverlayMode == CompanionMode.VRInterface) { switch (_attachMode) { case InterfaceAttachMode.Free: gameObject.transform.parent = o.gameObject.transform; gameObject.transform.localPosition = _companionOffset; Pivot.hideFlags = HideFlags.HideInHierarchy; Pivot.SetActive(false); break; case InterfaceAttachMode.PivotTop: case InterfaceAttachMode.PivotRight: case InterfaceAttachMode.PivotBottom: case InterfaceAttachMode.PivotLeft: SetupPivot(overlay); SetPivotOffset(overlay); AttachToPivot(overlay); break; default: throw new ArgumentOutOfRangeException(); } } if (OnOverlayAttachmentChanges != null) { OnOverlayAttachmentChanges(this); } updateCompanion = true; }
private void AimAtCompanion(HOTK_OverlayBase o, HOTK_TrackedDevice tracker, SteamVR_Overlay.IntersectionResults result) { if (VRInterfaceCanvas == null || VRInterfaceCursor == null) { return; } var lx = (VRInterfaceCanvas.pixelRect.width * result.UVs.x); var ly = (VRInterfaceCanvas.pixelRect.height * result.UVs.y); var x = -(VRInterfaceCanvas.pixelRect.width / 2f) + lx; var y = (VRInterfaceCanvas.pixelRect.height / 2f) - ly; if (AimLimitOn) { if (y > AimLimitYLow && x > AimLimitXLow && x < AimLimitXHigh) { DoAimAction(x, y, tracker); } else { StartCoroutine(FadeOutCursor()); _aiming = false; } } else { DoAimAction(x, y, tracker); } if (_aimingX == x && _aimingY == y) { return; } _aimingX = x; _aimingY = y; if (!_aiming || _draggingSlider != null) { return; } var data = new PointerEventData(EventSystem.current) { position = new Vector2(x, y) }; _aimedSelectable = null; foreach (var r in Raycastables.Where(r => r.Selectable.interactable)) { var re = r.Handle != null ? (RectTransform)r.Handle.transform : (RectTransform)r.Selectable.transform; if (re == null) { continue; } if (x < (re.position.x + re.rect.xMin) || x > (re.position.x + re.rect.xMax) || y < (re.position.y + re.rect.yMin) || y > (re.position.y + re.rect.yMax)) { continue; } if (!_aimedSelectables.Contains(r.Selectable)) { _aimedSelectables.Add(r.Selectable); r.Selectable.OnPointerEnter(data); if (DesktopPortalController.Instance.HapticsEnabledToggle.isOn) { tracker.TriggerHapticPulse(DesktopPortalController.HitOverlayHapticStrength); } } _aimedSelectable = r.Selectable; break; } foreach (var b in _aimedSelectables.Where(b => _aimedSelectable == null || b != _aimedSelectable).Where(b => b.interactable)) { b.OnPointerExit(data); } _aimedSelectables.Clear(); if (_aimedSelectable != null) { _aimedSelectables.Add(_aimedSelectable); } }