123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- using System;
- using Rokid.UXR.Utility;
- using UnityEngine;
- using UnityEngine.EventSystems;
- namespace Rokid.UXR.Interaction
- {
- public class CursorVisual : AutoInjectBehaviour
- {
- [SerializeField]
- private HandType hand;
- [SerializeField]
- private RayInteractor rayInteractor;
- [Tooltip("光标Size")]
- [SerializeField]
- private float cursorAngularSize = 100;
- [Autowrited("Cursor_Focus")]
- private Transform focusCursor;
- [Autowrited("Cursor_Press")]
- private Transform pressCursor;
- private bool dragging;
- private IBezierCurveDrag[] allCanDragObjs;
- private IBezierCurveDrag currentDragObj;
- private float scaleRelease = 1.5f;
- private float scalePress = 1.0f;
- private float startSmoothPinchDistance = 0.06f;
- private void Start()
- {
- InteractorStateChange.OnHandDragStatusChanged += OnHandDragStatusChanged;
- RKPointerLisener.OnPointerDragBegin += OnPointerDragBegin;
- RKPointerLisener.OnPointerDragEnd += OnPointerDragEnd;
- }
- private void OnHandDragStatusChanged(HandType hand, bool dragging)
- {
- if (hand == this.hand)
- {
- if (dragging)
- {
- this.dragging = true;
- if (rayInteractor.Interactable != null)
- {
- allCanDragObjs = rayInteractor.Interactable.GetComponentsInChildren<IBezierCurveDrag>();
- currentDragObj = GetCurrentDragObj();
- }
- }
- else
- {
- this.dragging = false;
- currentDragObj = null;
- allCanDragObjs = null;
- }
- }
- }
- private void OnDestroy()
- {
- InteractorStateChange.OnHandDragStatusChanged -= OnHandDragStatusChanged;
- RKPointerLisener.OnPointerDragBegin -= OnPointerDragBegin;
- RKPointerLisener.OnPointerDragEnd -= OnPointerDragEnd;
- }
- private void OnEnable()
- {
- rayInteractor.WhenPostprocessed += UpdateVisual;
- rayInteractor.WhenStateChanged += UpdateVisualState;
- RKPointerLisener.OnGraphicPointerEnter += OnPointerEnter;
- RKPointerLisener.OnGraphicPointerExit += OnPointerExit;
- RKPointerLisener.OnGraphicPointerHover += OnPointerHover;
- }
- private void OnDisable()
- {
- rayInteractor.WhenPostprocessed -= UpdateVisual;
- rayInteractor.WhenStateChanged -= UpdateVisualState;
- RKPointerLisener.OnGraphicPointerEnter -= OnPointerEnter;
- RKPointerLisener.OnGraphicPointerExit -= OnPointerExit;
- RKPointerLisener.OnGraphicPointerHover -= OnPointerHover;
- isInHover = false;
- }
- private void OnPointerDragEnd(PointerEventData eventData)
- {
- if (hand == HandType.None)
- {
- RKLog.Info("====CursorVisual====: OnPointerDragEnd");
- dragging = false;
- currentDragObj = null;
- allCanDragObjs = null;
- }
- }
- private void OnPointerDragBegin(PointerEventData eventData)
- {
- if (hand == HandType.None)
- {
- dragging = true;
- if (rayInteractor.Interactable != null)
- {
- allCanDragObjs = rayInteractor.Interactable.GetComponentsInChildren<IBezierCurveDrag>();
- currentDragObj = GetCurrentDragObj();
- }
- }
- }
- private bool HandDragging(GestureType GesType)
- {
- if (dragging && hand != HandType.None)
- {
- if (GesEventInput.Instance.GetGestureType(hand) == GesType)
- {
- return true;
- }
- }
- return false;
- }
- private IBezierCurveDrag GetCurrentDragObj()
- {
- if (allCanDragObjs == null || allCanDragObjs.Length == 0)
- {
- return null;
- }
- foreach (var dragObj in allCanDragObjs)
- {
- if (dragObj.IsInBezierCurveDragging())
- {
- return dragObj;
- }
- }
- return null;
- }
- private bool IsBezierDragging()
- {
- if (currentDragObj == null)
- {
- currentDragObj = GetCurrentDragObj();
- }
- if (dragging && currentDragObj != null)
- {
- return true;
- }
- return false;
- }
- private Vector3 ComputeScaleWithAngularScale(Vector3 targetPoint)
- {
- if (MainCameraCache.mainCamera != null)
- {
- float cursorDistance = Vector3.Distance(MainCameraCache.mainCamera.transform.position, targetPoint);
- float desiredScale = Utils.ScaleFromAngularSizeAndDistance(cursorAngularSize, cursorDistance);
- return Vector3.one * desiredScale;
- }
- return Vector3.zero;
- }
- private void UpdateVisual()
- {
- if (rayInteractor.CollisionInfo == null || rayInteractor.State == InteractorState.Disabled || IsBezierDragging())
- {
- focusCursor.gameObject.SetActive(false);
- pressCursor.gameObject.SetActive(false);
- return;
- }
- if (isInHover && hoverNormal != Vector3.zero && hoverPosition != Vector3.zero)
- {
- this.transform.position = hoverPosition;
- this.transform.rotation = Quaternion.LookRotation(hoverNormal, Vector3.up);
- this.transform.localScale = ComputeScaleWithAngularScale(hoverPosition);
- }
- else
- {
- Vector3 collisionNormal = IsBezierDragging() ? currentDragObj.GetBezierCurveEndNormal() : rayInteractor.CollisionInfo.Value.Normal;
- Vector3 collisionPosition = IsBezierDragging() ? currentDragObj.GetBezierCurveEndPoint() : rayInteractor.End;
- this.transform.position = collisionPosition + collisionNormal * 0.001f;
- this.transform.rotation = Quaternion.LookRotation(collisionNormal, Vector3.up);
- this.transform.localScale = ComputeScaleWithAngularScale(collisionPosition);
- }
- bool press = rayInteractor.State == InteractorState.Select || IsBezierDragging();
- focusCursor.gameObject.SetActive(!press);
- pressCursor.gameObject.SetActive(press);
- if (hand != HandType.None)
- {
- if (!press)
- {
- Vector3 index_tip = GesEventInput.Instance.GetSkeletonPose(SkeletonIndexFlag.INDEX_FINGER_TIP, hand).position;
- Vector3 thumb_tip = GesEventInput.Instance.GetSkeletonPose(SkeletonIndexFlag.THUMB_TIP, hand).position;
- float sqrDistance = Vector3.SqrMagnitude(index_tip - thumb_tip);
- if (sqrDistance > startSmoothPinchDistance * startSmoothPinchDistance)
- {
- this.transform.localScale *= scaleRelease;
- }
- else
- {
- float pow = Mathf.Max(scalePress, scaleRelease * (sqrDistance / (startSmoothPinchDistance * startSmoothPinchDistance)));
- this.transform.localScale *= pow;
- }
- }
- else
- {
- this.transform.localScale *= scalePress;
- }
- }
- }
- public void UpdateCursorVisual(Transform forcusCursor, Transform pressCursor)
- {
- Destroy(this.focusCursor);
- Destroy(this.pressCursor);
- this.focusCursor = forcusCursor;
- this.pressCursor = pressCursor;
- this.focusCursor.SetParent(this.transform);
- this.pressCursor.SetParent(this.transform);
- this.focusCursor.localPosition = Vector3.zero;
- this.pressCursor.localPosition = Vector3.zero;
- }
- private void UpdateVisualState(InteractorStateChangeArgs args) => UpdateVisual();
- #region ForCursorHoverPose
- private bool isInHover;
- private Vector3 hoverPosition;
- private Vector3 hoverNormal;
- private void OnPointerEnter(PointerEventData eventData)
- {
- if (RayInteractor.GetHandTypeByIdentifier(eventData.pointerId) == hand && eventData.pointerCurrentRaycast.gameObject != null)
- {
- isInHover = true;
- hoverPosition = Vector3.zero;
- hoverNormal = Vector3.zero;
- }
- }
- private void OnPointerExit(PointerEventData eventData)
- {
- if (RayInteractor.GetHandTypeByIdentifier(eventData.pointerId) == hand)
- {
- isInHover = false;
- hoverPosition = Vector3.zero;
- hoverNormal = Vector3.zero;
- }
- }
- private void OnPointerHover(PointerEventData eventData)
- {
- if (isInHover && RayInteractor.GetHandTypeByIdentifier(eventData.pointerId) == hand)
- {
- hoverPosition = eventData.pointerCurrentRaycast.worldPosition;
- hoverNormal = eventData.pointerCurrentRaycast.worldNormal;
- }
- }
- #endregion
- }
- }
|