/*--------------------------------------------------------------------------------------------*/ protected virtual void UpdateCursorsWithFinger(Hand pLeapHand, Finger pLeapFinger) { CursorType cursorType = GetFingerCursorType(pLeapHand.IsLeft, pLeapFinger.Type); if (!CursorDataProvider.HasCursorData(cursorType)) { return; } Transform leapTx = LeapControl.transform; Vector tipPos = (UseStabilizedPositions ? pLeapFinger.StabilizedTipPosition: pLeapFinger.TipPosition); Bone distalBone = pLeapFinger.Bone(Bone.BoneType.TYPE_DISTAL); Vector3 tipWorldPos = leapTx.TransformPoint(tipPos.ToUnityScaled()); Vector3 boneWorldPos = leapTx.TransformPoint(distalBone.Center.ToUnityScaled()); Vector3 extendedWorldPos = tipWorldPos; if (ExtendFingertipDistance != 0) { extendedWorldPos += (tipWorldPos - boneWorldPos).normalized * ExtendFingertipDistance; } ICursorDataForInput data = CursorDataProvider.GetCursorDataForInput(cursorType); data.SetWorldPosition(extendedWorldPos); data.SetWorldRotation(leapTx.rotation * distalBone.Basis.Rotation() * RotationFix); data.SetSize(pLeapFinger.Width * UnityVectorExtension.INPUT_SCALE); data.SetUsedByInput(true); }
/*--------------------------------------------------------------------------------------------*/ public void Update() { gameObject.GetComponentsInChildren(true, vCursorsForInput); Cursors.Clear(); SelectableCursors.Clear(); ExcludedCursors.Clear(); vCursorMap.Clear(); for (int i = 0; i < vCursorsForInput.Count; i++) { ICursorDataForInput cursor = vCursorsForInput[i]; if (vCursorMap.ContainsKey(cursor.Type)) { ExcludedCursors.Add(cursor); continue; } Cursors.Add(cursor); vCursorMap.Add(cursor.Type, cursor); if (cursor.CanCauseSelections) { SelectableCursors.Add(cursor); } } }
/*--------------------------------------------------------------------------------------------*/ private void UpdateDataForSize(ICursorDataForInput pData, HoverInputVive.ControlState pState) { float prog = GetInputSourceProgress(CursorSizeInput, pState, 0.5f); pData.SetSize(Mathf.Lerp(MinSize, MaxSize, prog)); }
/*--------------------------------------------------------------------------------------------*/ private void UpdateCursorWithDevice(Transform pDeviceTx, SteamVR_Controller.Device pDevice, Info pInfo, CursorType pCursorType) { if (!CursorDataProvider.HasCursorData(pCursorType)) { return; } ICursorDataForInput data = CursorDataProvider.GetCursorDataForInput(pCursorType); data.SetUsedByInput(pDevice.valid); if (!pDevice.valid) { return; } Vector2 touchAxis = pDevice.GetAxis(EVRButtonId.k_EButton_SteamVR_Touchpad); Vector2 triggerAxis = pDevice.GetAxis(EVRButtonId.k_EButton_SteamVR_Trigger); bool isTouch = pDevice.GetTouch(EVRButtonId.k_EButton_SteamVR_Touchpad); float sizeProg = (isTouch ? touchAxis.x * 2 + 1 : 0.5f); Vector3 worldOffset = pDeviceTx.TransformVector(pInfo.LocalPosition); data.SetWorldPosition(pDeviceTx.position + worldOffset); data.SetWorldRotation(pDeviceTx.rotation * Quaternion.Euler(pInfo.LocalRotation)); data.SetSize(Mathf.Lerp(pInfo.MinSize, pInfo.MaxSize, sizeProg)); data.SetTriggerStrength(triggerAxis.x); }
/*--------------------------------------------------------------------------------------------*/ private void UpdateDataForTrigger(ICursorDataForInput pData, HoverInputVive.ControlState pState) { float prog = GetInputSourceProgress(TriggerStrengthInput, pState, 0); pData.SetTriggerStrength(prog); }
//////////////////////////////////////////////////////////////////////////////////////////////// /*--------------------------------------------------------------------------------------------*/ public void UpdateData(HoverCursorDataProvider pCursorDataProv, HoverInputOculusTouch.ControlState pState, OvrAvatar pAvatar) { ICursorDataForInput data = GetData(pCursorDataProv); if (data == null) { return; } data.SetUsedByInput(pState.IsValid); if (!pState.IsValid) { return; } if (!TryUpdateDataWithAvatarElement(data, pAvatar)) { UpdateDataWithLocalOffsets(data, pState); } UpdateDataForTrigger(data, pState); UpdateDataForSize(data, pState); }
//////////////////////////////////////////////////////////////////////////////////////////////// /*--------------------------------------------------------------------------------------------*/ private bool TryUpdateDataWithAvatarElement(ICursorDataForInput pData, OvrAvatar pAvatar) { if (!ShouldFollowAvatarElement) { AvatarElementTransform = null; return(false); } if (AvatarElementTransform == null) { AvatarElementTransform = HoverInputOculusTouch.FindAvatarTransform( pAvatar.transform, AvatarElementName); } if (AvatarElementTransform == null) { return(false); } Quaternion sidedLocalRotFix = (Type < CursorType.RightPalm ? LocalLeftRotFix : LocalRightRotFix); pData.SetWorldRotation(AvatarElementTransform.rotation * sidedLocalRotFix); pData.SetWorldPosition(AvatarElementTransform.position + pData.WorldRotation * LocalPosFix); return(true); }
/*--------------------------------------------------------------------------------------------*/ protected virtual void UpdateCursorsWithFinger(Hand pLeapHand, Finger pLeapFinger) { CursorType cursorType = GetFingerCursorType(pLeapHand.IsLeft, pLeapFinger.Type); if (!CursorDataProvider.HasCursorData(cursorType)) { return; } Bone distalBone = pLeapFinger.Bone(Bone.BoneType.TYPE_DISTAL); Vector3 tipWorldPos = pLeapFinger.TipPosition.ToVector3(); Vector3 boneWorldPos = distalBone.Center.ToVector3(); Vector3 extendedWorldPos = tipWorldPos; if (ExtendFingertipDistance != 0) { extendedWorldPos += (tipWorldPos - boneWorldPos).normalized * ExtendFingertipDistance; } ICursorDataForInput data = CursorDataProvider.GetCursorDataForInput(cursorType); data.SetWorldPosition(extendedWorldPos); data.SetWorldRotation(distalBone.Basis.CalculateRotation() * RotationFix); data.SetSize(pLeapFinger.Width); data.SetUsedByInput(true); }
//////////////////////////////////////////////////////////////////////////////////////////////// /*--------------------------------------------------------------------------------------------*/ private void UpdateDataWithLocalOffsets(ICursorDataForInput pData, HoverInputVive.ControlState pState) { Vector3 worldOffset = pState.Tx.TransformVector(LocalPosition); pData.SetWorldPosition(pState.Tx.position + worldOffset); pData.SetWorldRotation(pState.Tx.rotation * Quaternion.Euler(LocalRotation)); }
/*--------------------------------------------------------------------------------------------*/ private void UpdateDataWithLocalOffsets(ICursorDataForInput pData, HoverInputOculusTouch.ControlState pState) { pData.SetWorldPosition( OriginTransform.TransformPoint(pState.LocalPos) + pState.LocalRot * LocalPosition); pData.SetWorldRotation( OriginTransform.rotation * pState.LocalRot * Quaternion.Euler(LocalRotation)); }
/*--------------------------------------------------------------------------------------------*/ private void UpdateDataWithLocalOffsets(ICursorDataForInput pData, HoverInputOculusTouch.ControlState pState) { Matrix4x4 txMat = OriginTransform.localToWorldMatrix; Matrix4x4 txRotMat = txMat * Matrix4x4.TRS(Vector3.zero, pState.LocalRot, Vector3.one); pData.SetWorldPosition(txMat.MultiplyPoint3x4(pState.LocalPos) + txRotMat.MultiplyVector(LocalPosition)); pData.SetWorldRotation(txRotMat.GetRotation() * Quaternion.Euler(LocalRotation)); }
/*--------------------------------------------------------------------------------------------*/ private void UpdateCursorWithCamera() { if (!CursorDataProvider.HasCursorData(CursorType.Look)) { return; } ICursorDataForInput data = CursorDataProvider.GetCursorDataForInput(CursorType.Look); data.SetWorldPosition(LookCursorTransform.position); data.SetWorldRotation(LookCursorTransform.rotation); data.SetUsedByInput(true); }
//////////////////////////////////////////////////////////////////////////////////////////////// /*--------------------------------------------------------------------------------------------*/ public void UpdateData(HoverCursorDataProvider pCursorDataProv, HoverInputVRTK.ControlState pState) { ICursorDataForInput data = GetData(pCursorDataProv); if (data == null) { return; } data.SetUsedByInput(true); UpdateDataWithLocalOffsets(data, pState); UpdateDataForTrigger(data, pState); UpdateDataForSize(data, pState); }
/*--------------------------------------------------------------------------------------------*/ public void SwitchHands() { HoverCursorFollower follow = GetComponent <HoverCursorFollower>(); HoverCursorDataProvider curProv = follow.CursorDataProvider; ICursorDataForInput stdFol = curProv.GetCursorDataForInput(StandardFollowCursor); ICursorDataForInput swiFol = curProv.GetCursorDataForInput(SwitchedFollowCursor); ICursorDataForInput stdInt = curProv.GetCursorDataForInput(StandardInteractionCursor); ICursorDataForInput swiInt = curProv.GetCursorDataForInput(SwitchedInteractionCursor); HovercastMirrorSwitcher mirror = GetComponent <HovercastMirrorSwitcher>(); bool isMirror = !mirror.UseMirrorLayout; if (isMirror) { mirror.UseMirrorLayout = true; follow.CursorType = SwitchedFollowCursor; swiFol.SetCapability(CursorCapabilityType.TransformOnly); swiInt.SetCapability(CursorCapabilityType.Full); stdFol.SetCapability(CursorCapabilityType.None); stdInt.SetCapability(CursorCapabilityType.None); swiFol.gameObject.SetActive(true); swiInt.gameObject.SetActive(true); stdFol.gameObject.SetActive(false); stdInt.gameObject.SetActive(false); } else { mirror.UseMirrorLayout = false; follow.CursorType = StandardFollowCursor; swiFol.SetCapability(CursorCapabilityType.None); swiInt.SetCapability(CursorCapabilityType.None); stdFol.SetCapability(CursorCapabilityType.TransformOnly); stdInt.SetCapability(CursorCapabilityType.Full); swiFol.gameObject.SetActive(false); swiInt.gameObject.SetActive(false); stdFol.gameObject.SetActive(true); stdInt.gameObject.SetActive(true); } }
/*--------------------------------------------------------------------------------------------*/ protected virtual void UpdateCursorsWithPalm(Hand pLeapHand) { CursorType cursorType = (pLeapHand.IsLeft ? CursorType.LeftPalm : CursorType.RightPalm); if (!CursorDataProvider.HasCursorData(cursorType)) { return; } Vector palmPos = (UseStabilizedPositions ? pLeapHand.StabilizedPalmPosition : pLeapHand.PalmPosition); ICursorDataForInput data = CursorDataProvider.GetCursorDataForInput(cursorType); data.SetWorldPosition(palmPos.ToVector3()); data.SetWorldRotation(pLeapHand.Basis.CalculateRotation() * RotationFix); data.SetSize(pLeapHand.PalmWidth); data.SetTriggerStrength(pLeapHand.GrabStrength); data.SetUsedByInput(true); }
/*--------------------------------------------------------------------------------------------*/ protected virtual void UpdateCursorsWithPalm(Hand pLeapHand) { CursorType cursorType = (pLeapHand.IsLeft ? CursorType.LeftPalm : CursorType.RightPalm); if (!CursorDataProvider.HasCursorData(cursorType)) { return; } Transform leapTx = LeapControl.transform; Vector palmPos = (UseStabilizedPositions ? pLeapHand.StabilizedPalmPosition : pLeapHand.PalmPosition); ICursorDataForInput data = CursorDataProvider.GetCursorDataForInput(cursorType); data.SetWorldPosition(leapTx.TransformPoint(palmPos.ToUnityScaled())); data.SetWorldRotation(leapTx.rotation * pLeapHand.Basis.Rotation() * RotationFix); data.SetSize(pLeapHand.PalmWidth * UnityVectorExtension.INPUT_SCALE); data.SetTriggerStrength(pLeapHand.GrabStrength); data.SetUsedByInput(true); }
/*--------------------------------------------------------------------------------------------*/ protected override void PerformAdjustments() { HoverCursorDataProvider cursProv = FindObjectOfType <HoverCursorDataProvider>(); ICursorDataForInput palL = cursProv.GetCursorDataForInput(CursorType.LeftPalm); ICursorDataForInput indR = cursProv.GetCursorDataForInput(CursorType.RightIndex); ICursorDataForInput look = cursProv.GetCursorDataForInput(CursorType.Look); HovercastInterface cast = FindObjectOfType <HovercastInterface>(); HoverCursorFollower castFollow = cast.GetComponent <HoverCursorFollower>(); HoverCursorRendererUpdater[] cursorRendUps = Resources.FindObjectsOfTypeAll <HoverCursorRendererUpdater>(); foreach (HoverCursorRendererUpdater rendUp in cursorRendUps) { CursorType ct = rendUp.GetComponent <HoverCursorFollower>().CursorType; rendUp.gameObject.SetActive(ct != CursorType.LeftPalm && ct != CursorType.RightPalm); } foreach (ICursorData cursorData in cursProv.Cursors) { ICursorDataForInput cursorDataInp = cursProv.GetCursorDataForInput(cursorData.Type); cursorDataInp.SetCapability(CursorCapabilityType.None); } palL.SetCapability(CursorCapabilityType.TransformOnly); indR.SetCapability(CursorCapabilityType.Full); look.SetCapability(CursorCapabilityType.TransformOnly); cast.transform.GetChild(0).localPosition = new Vector3(0, 0, 0.02f); //moves "TransformAdjuster" castFollow.CursorType = palL.Type; //for non-playing editor... palL.SetWorldRotation(Quaternion.Euler(0, 160, 80)); //face the camera (for editor) castFollow.Update(); //moves interface to the correct cursor transform cast.GetComponent <TreeUpdater>().Update(); //forces entire interface to update }
//////////////////////////////////////////////////////////////////////////////////////////////// /*--------------------------------------------------------------------------------------------*/ public void UpdateData(HoverCursorDataProvider pCursorDataProv) { if (!pCursorDataProv.HasCursorData(Type)) { return; } ICursorDataForInput data = pCursorDataProv.GetCursorDataForInput(Type); if (data == null) { return; } if (FollowTransform == null) { data.SetUsedByInput(false); return; } data.SetUsedByInput(FollowTransform.gameObject.activeInHierarchy); data.SetWorldPosition(FollowTransform.position); data.SetWorldRotation(FollowTransform.rotation); }
//////////////////////////////////////////////////////////////////////////////////////////////// /*--------------------------------------------------------------------------------------------*/ public void PerformBuild() { TreeUpdater treeUp = gameObject.AddComponent <TreeUpdater>(); HoverCursorFollower follow = gameObject.AddComponent <HoverCursorFollower>(); HovercastInterface inter = gameObject.AddComponent <HovercastInterface>(); //// var adjustGo = new GameObject("TransformAdjuster"); adjustGo.transform.SetParent(transform, false); adjustGo.transform.localPosition = new Vector3(0, 0, 0.02f); adjustGo.transform.localRotation = Quaternion.Euler(0, 180, 80); var openItemGo = new GameObject("OpenItem"); openItemGo.transform.SetParent(adjustGo.transform, false); openItemGo.transform.localPosition = new Vector3(0, -0.05f, 0); var titleItemGo = new GameObject("TitleItem"); titleItemGo.transform.SetParent(adjustGo.transform, false); var backItemGo = new GameObject("BackItem"); backItemGo.transform.SetParent(adjustGo.transform, false); var rowContGo = new GameObject("Rows"); rowContGo.transform.SetParent(adjustGo.transform, false); rowContGo.AddComponent <TreeUpdater>(); var row0Go = new GameObject("Root"); row0Go.transform.SetParent(rowContGo.transform, false); //// BuildOpenItem(openItemGo); BuildTitleItem(titleItemGo); BuildBackItem(backItemGo); BuildRow(row0Go, "Hovercast"); if (IncludeExampleRows) { BuildExampleRows(rowContGo, row0Go); } adjustGo.AddComponent <TreeUpdater>(); //after building items //// follow.CursorType = (AttachToLeftHand ? CursorType.LeftPalm : CursorType.RightPalm); follow.ObjectsToActivate = new[] { openItemGo, titleItemGo, backItemGo, rowContGo }; inter.RowContainer = rowContGo.transform; inter.ActiveRow = row0Go.GetComponent <HoverLayoutArcRow>(); inter.OpenItem = openItemGo.GetComponent <HoverItemDataSelector>(); inter.TitleItem = titleItemGo.GetComponent <HoverItemDataText>(); inter.BackItem = backItemGo.GetComponent <HoverItemDataSelector>(); HovercastOpenTransitioner openTrans = gameObject.AddComponent <HovercastOpenTransitioner>(); HovercastRowTransitioner rowTrans = gameObject.AddComponent <HovercastRowTransitioner>(); rowTrans.RowEntryTransition = HovercastRowSwitchingInfo.RowEntryType.FromInside; #if UNITY_EDITOR UnityEditor.Events.UnityEventTools.AddPersistentListener( inter.OnOpenToggledEvent, openTrans.OnOpenToggled); UnityEditor.Events.UnityEventTools.AddPersistentListener( inter.OnRowSwitchedEvent, rowTrans.OnRowSwitched); #else inter.OnOpenToggledEvent.AddListener(openTrans.OnOpenToggled); inter.OnRowSwitchedEvent.AddListener(rowTrans.OnRowSwitched); #endif gameObject.AddComponent <HovercastHighlightPreventer>(); HovercastBackCursorTrigger backTrig = gameObject.AddComponent <HovercastBackCursorTrigger>(); backTrig.BackTriggerCursorType = follow.CursorType; HovercastActiveDirection actDir = gameObject.AddComponent <HovercastActiveDirection>(); actDir.ChildForActivation = adjustGo; HovercastMirrorSwitcher mirror = gameObject.AddComponent <HovercastMirrorSwitcher>(); mirror.UseMirrorLayout = !AttachToLeftHand; gameObject.AddComponent <HovercastAlphaUpdater>(); if (AutoRotateHandToFaceCamera) { HoverCursorDataProvider curDataProv = FindObjectOfType <HoverCursorDataProvider>(); ICursorDataForInput curData = curDataProv.GetCursorDataForInput(follow.CursorType); float addRotZ = 80 * (AttachToLeftHand ? 1 : -1); actDir.TreeUpdate(); //forces search for the "facing" transform curData.transform.LookAt(actDir.ActiveWhenFacingTransform, Vector3.up); curData.transform.localRotation *= Quaternion.Euler(0, 0, addRotZ); } follow.Update(); //moves interface to the correct cursor transform treeUp.Update(); //forces entire interface to update }