123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using UnityEngine;
- using UnityEngine.EventSystems;
- namespace SC.XR.Unity.Module_InputSystem.InputDeviceHand {
- public class TouchPointer : PointerBase, INearPointer
- {
- public HandDetector handDetector {
- get {
- return detectorBase as HandDetector;
- }
- }
- public float TouchRadius { get => 0.2f; }
- public bool IsNearObject { get => newClosestTouchable!=null; }
- public override PointerType PointerType => PointerType.Touch;
- private Collider[] queryBuffer=new Collider[60];
- public Action<bool> TargetDetectModelChange;
- SCPointEventData scPointEventData {
- get {
- return handDetector.inputDevicePartBase.inputDataBase.SCPointEventData;
- }
- }
- private Vector3 mPreviousTouchPosition;
- public Vector3 PreviousTouchPosition {
- get {
- if(mPreviousTouchPosition == Vector3.zero) {
- mPreviousTouchPosition = TouchPosition;
- }
- return mPreviousTouchPosition;
- }
- private set {
- mPreviousTouchPosition = value;
- }
- }
- public Vector3 TouchPosition {
- get {
- //return gT26DofDetector.inputDeviceGT26DofPart.inputDeviceGT26DofPartUI.modelGT26Dof.TouchCursor.transform.position;
- return handDetector.inputDeviceHandPart.inputDeviceHandPartUI.modelHand.ActiveHandModel.GetJointTransform(FINGER.forefinger, JOINT.One).transform.position;
- }
- }
- public float DistToTouchable {
- get;
- private set;
- }
- float closestDistance;
- Vector3 closestNormal;
- BaseNearInteractionTouchable newClosestTouchable;
- Vector3 start, end;
- public override void OnSCStart() {
- //base.OnSCStart();
- cursorBase?.ModuleStart();
- }
- public override void OnSCDisable() {
- base.OnSCDisable();
- if(currentPokeDownObject) {
- PokeUp(ref currentPokeDownObject, ref currentTouchableObject);
- }
- IsFocusLocked = false;
- PreviousTouchPosition = Vector3.zero;
- }
- protected override void UpdateTransform() {
- start = TouchPosition + TouchRadius * closestNormal;
- end = TouchPosition - TouchRadius * closestNormal;
- transform.rotation = Quaternion.LookRotation(end - start);
- transform.position = start;
- }
-
- private GameObject currentPokeDownObject = null;
- private BaseNearInteractionTouchable currentTouchableObject = null;
- protected override void DoTargetDetect() {
- SCInputModule.Instance.ProcessCS(scPointEventData, transform, LayerMask, (end - start).magnitude);
- IsFocusLocked = currentPokeDownObject != null;
- //Debug.Log(scPointEventData.pointerCurrentRaycast.gameObject);
- if(scPointEventData.pointerCurrentRaycast.gameObject) {
- DistToTouchable = Vector3.Distance(transform.position, scPointEventData.pointerCurrentRaycast.worldPosition) - TouchRadius;
- bool newIsDown = (DistToTouchable < 0.0f);
- bool newIsUp = (DistToTouchable > newClosestTouchable.DebounceThreshold);
- if(newIsDown && currentPokeDownObject == null) {
- if(IsObjectPartOfTouchable(scPointEventData.pointerCurrentRaycast.gameObject, newClosestTouchable)) {
- currentPokeDownObject = scPointEventData.pointerCurrentRaycast.gameObject;
- currentTouchableObject = newClosestTouchable;
- PokeDown(currentPokeDownObject, currentTouchableObject);
- }
- } else if(currentPokeDownObject) {
- if(newIsUp) {
- PokeUp(ref currentPokeDownObject, ref currentTouchableObject);
- } else {
- PokeUpdated(currentPokeDownObject, currentTouchableObject);
- }
- }
- } else {
- if(currentPokeDownObject) {
- PokeUp(ref currentPokeDownObject, ref currentTouchableObject);
- }
- }
- PreviousTouchPosition = TouchPosition;
- }
- private void PokeDown(GameObject _target, BaseNearInteractionTouchable touchableObj) {
- if(touchableObj.EventsToReceive == TouchableEventType.Pointer) {
- handDetector.inputDevicePartBase.inputDataBase.inputKeys.InputDataAddKey(InputKeyCode.Enter, InputKeyState.DOWN);
- } else if(touchableObj.EventsToReceive == TouchableEventType.Touch) {
- HandDispatcher.OnPokeDown(touchableObj.gameObject, this, scPointEventData);
- }
- }
- private void PokeUp(ref GameObject _target, ref BaseNearInteractionTouchable touchableObj) {
- if(touchableObj.EventsToReceive == TouchableEventType.Pointer) {
- handDetector.inputDevicePartBase.inputDataBase.inputKeys.InputDataAddKey(InputKeyCode.Enter, InputKeyState.UP);
- } else if(touchableObj.EventsToReceive == TouchableEventType.Touch) {
- HandDispatcher.OnPokeUp(touchableObj.gameObject, this, scPointEventData);
- }
- touchableObj = null;
- _target = null;
- }
- private void PokeUpdated(GameObject _target, BaseNearInteractionTouchable touchableObj) {
- if(touchableObj.EventsToReceive == TouchableEventType.Pointer) {
- } else if(touchableObj.EventsToReceive == TouchableEventType.Touch) {
- HandDispatcher.OnPokeUpdated(touchableObj.gameObject, this, scPointEventData);
- }
- }
- private static bool IsObjectPartOfTouchable(GameObject targetObject, BaseNearInteractionTouchable touchable) {
- return targetObject != null && touchable != null &&
- (targetObject == touchable.gameObject ||
- // Descendant game objects are touchable as well. In particular, this is needed to be able to send
- // touch events to Unity UI control elements.
- (targetObject.transform != null && touchable.gameObject.transform != null &&
- targetObject.transform.IsChildOf(touchable.gameObject.transform)));
- }
- public bool FindClosestTouchableForLayerMask() {
- newClosestTouchable = null;
- closestDistance = float.PositiveInfinity;
- closestNormal = Vector3.zero;
- int numColliders = Physics.OverlapSphereNonAlloc(TouchPosition, TouchRadius, queryBuffer, LayerMask);
- if(numColliders == queryBuffer.Length) {
- Debug.LogWarning($"Maximum number of {numColliders} colliders found in PokePointer overlap query. Consider increasing the query buffer size in the input system settings.");
- }
- for(int i = 0; i < numColliders; i++) {
- var collider = queryBuffer[i];
- var touchable = collider.GetComponent<BaseNearInteractionTouchable>();
- if(touchable) {
- float distance = touchable.DistanceToTouchable(TouchPosition, out Vector3 normal);
- if(distance < closestDistance) {
- newClosestTouchable = touchable;
- closestDistance = distance;
- closestNormal = normal;
- }
- }
- }
-
- // Unity UI does not provide an equivalent broad-phase test to Physics.OverlapSphere,
- // so we have to use a static instances list to test all NearInteractionTouchableUnityUI
- for(int i = 0; i < NearInteractionTouchableUnityUI.Instances.Count; i++) {
- NearInteractionTouchableUnityUI touchable = NearInteractionTouchableUnityUI.Instances[i];
- float distance = touchable.DistanceToTouchable(TouchPosition, out Vector3 normal);
- if(distance <= TouchRadius && distance < closestDistance) {
- newClosestTouchable = touchable;
- closestDistance = distance;
- closestNormal = normal;
- }
- }
- //if(newClosestTouchable != null) {
- // Debug.Log("newClosestTouchable:" + newClosestTouchable.name);
- //}
- return newClosestTouchable != null;
- }
- public bool TryGetNearGraspPoint(out Vector3 position) {
- position = Vector3.zero;
- return false;
- }
- public bool TryGetNearGraspAxis(out Vector3 axis) {
- axis = transform.forward;
- return true;
- }
- public bool TryGetDistanceToNearestSurface(out float distance) {
- distance = closestDistance;
- return true;
- }
- public bool TryGetNormalToNearestSurface(out Vector3 normal) {
- normal = closestNormal;
- return true;
- }
- void OnDrawGizmos() {
- if(Application.isPlaying) {
- Gizmos.color = Color.black*0.2f;
- Gizmos.DrawSphere(transform.position, 0.01f);
- Gizmos.color = Color.black * 0.1f;
- Gizmos.DrawSphere(TouchPosition, TouchRadius);
- Gizmos.color = Color.blue * 0.3f;
- Gizmos.DrawSphere(start, 0.02f);
- Gizmos.color = Color.blue * 0.2f;
- Gizmos.DrawSphere(end, 0.01f);
- }
- }
- }
- }
|