예제 #1
0
        public MultiTouchProcessResult Process(MultiTouchPointerEventData eventData, Win10TouchInputModule module)
        {
            GestureData = GetGestureData(eventData);

            int touchCount = eventData.touchCluster.Count;

            if (touchCount < MinimumFingers || touchCount > MaximumFingers)
            {
                Reset(eventData);
                return(MultiTouchProcessResult.NotProcessed);         // Wrong touch count, don't check
            }

            if (touchCount != GestureData.PriorCluster.Count)
            {
                Reset(eventData);
            }

            bool anyEvent = false;

            if (HasPriorData)
            {
                NormalizedPriorCluster.CopyFrom(GestureData.PriorCluster);
                NormalizedPriorCluster.NormalizeForCentroidDelta(eventData.touchCluster);
                EvaluateRelativeMotion(eventData);
                anyEvent = CheckPan(eventData) || CheckRotate(eventData) || CheckPinch(eventData);
            }

            if (!HasPriorData || anyEvent)
            {
                GestureData.PriorCluster.CopyFrom(eventData.touchCluster);
            }
            return(anyEvent ? ResultIfEventSent : ResultIfTouchCountMatches);
        }
예제 #2
0
        private bool ProcessMultiTouchPress(MultiTouchPointerEventData pointerEvent, bool pressed, bool released)
        {
            var currentOverGo = pointerEvent.pointerCurrentRaycast.gameObject;

            // PointerDown notification
            if (pressed)
            {
                pointerEvent.singleTouchProcessingEnabled = true;
                pointerEvent.eligibleForClick             = true;
                pointerEvent.delta               = Vector2.zero;
                pointerEvent.dragging            = false;
                pointerEvent.useDragThreshold    = true;
                pointerEvent.pressPosition       = pointerEvent.position;
                pointerEvent.pointerPressRaycast = pointerEvent.pointerCurrentRaycast;

                // search for the control that will receive the multitouch events
                pointerEvent.multitouchTarget = ExecuteEvents.GetEventHandler <IMultiTouchEventSystemHandler>(currentOverGo);

                pointerEvent.rawPointerPress = currentOverGo;
            }

            // PointerUp notification
            if (released)
            {
                ExecuteEvents.Execute(pointerEvent.multitouchTarget, pointerEvent, EndGestureHandlerDelegate);
                pointerEvent.multitouchTarget = null;
            }
            return(pointerEvent.multitouchTarget != null);
        }
예제 #3
0
        protected bool GetMultiTouchPointerData(int id, out MultiTouchPointerEventData data, bool create)
        {
            PointerEventData temp;

            if (m_PointerData.TryGetValue(id, out temp))
            {
                data = temp as MultiTouchPointerEventData;
                if (data != null)
                {
                    return(false); // good value, pre-existing
                }
            }

            if (!create)
            {
                data = null;
                return(false);
            }

            data = new MultiTouchPointerEventData(eventSystem)
            {
                pointerId = id,
            };
            m_PointerData[id] = data;
            return(true);
        }
예제 #4
0
        public void CancelSingleTouchProcessing(MultiTouchPointerEventData pointer)
        {
            if (!pointer.singleTouchProcessingEnabled)
            {
                return;
            }

            pointer.singleTouchProcessingEnabled = false;

            // Exit any hovered states
            HandlePointerExitAndEnter(pointer, null);

            pointer.eligibleForClick = false;   // Not elegible for click

            if (pointer.pointerPress)
            {
                // ReSharper disable once RedundantTypeArgumentsOfMethod
                ExecuteEvents.Execute <IPointerUpHandler>(pointer.pointerPress, pointer, ExecuteEvents.pointerUpHandler);
                pointer.pointerPress    = null;
                pointer.rawPointerPress = null;
            }
            if (pointer.pointerDrag != null && pointer.dragging)
            {
                // ReSharper disable once RedundantTypeArgumentsOfMethod
                ExecuteEvents.Execute <IEndDragHandler>(pointer.pointerDrag, pointer, ExecuteEvents.endDragHandler);
                pointer.pointerDrag = null;
                pointer.dragging    = false;
            }
        }
예제 #5
0
 public void Reset(MultiTouchPointerEventData eventData)
 {
     if (IsGestureStarted)
     {
         SendEvent <IGestureEndHandler>(gameObject, eventData, GestureEndEvent, false);
     }
     GestureData.PriorCluster.Clear();
     IsGestureStarted = false;
 }
예제 #6
0
 private bool SendEvent <TU>(GameObject target, MultiTouchPointerEventData eventData, ExecuteEvents.EventFunction <TU> handlerDelegate, bool sendBeginGestureIfNeeded)
     where TU : IEventSystemHandler
 {
     eventData.EventSender = this;
     if (!IsGestureStarted && sendBeginGestureIfNeeded)
     {
         ExecuteEvents.ExecuteHierarchy(target, eventData, (ExecuteEvents.EventFunction <IGestureStartHandler>)GestureStartEvent);
         IsGestureStarted = true;
     }
     return(ExecuteEvents.ExecuteHierarchy(target, eventData, handlerDelegate) != null);
 }
예제 #7
0
        protected SimpleGestureData GetGestureData(MultiTouchPointerEventData eventData)
        {
            var simpleGestureData = (SimpleGestureData)eventData.GetGestureData(this);

            if (simpleGestureData == null)
            {
                simpleGestureData = SimpleGestureData.Get();
                eventData.SetGestureData(this, simpleGestureData);
            }
            return(simpleGestureData);
        }
예제 #8
0
        private void ClearPointerPressOrDrag(MultiTouchPointerEventData eventData)
        {
            if (!eventData.singleTouchProcessingEnabled)
            {
                return;
            }

            Win10TouchInputModule module;

            if (Win10TouchInputModule.TryGetCurrentWin10TouchInputModule(out module))
            {
                module.CancelSingleTouchProcessing(eventData);
            }
        }
예제 #9
0
 private bool CheckPan(MultiTouchPointerEventData eventData)
 {
     // In a pan, all of the touch points are moving in the same direction as the centroid,
     // and none are moving significantly counter to it.
     if (DetectPan && NumAntiCentroid == 0 && NumMatchCentroid >= eventData.touchCluster.Count)
     {
         if (ShouldStartDrag(eventData.centroidPressPosition, eventData.centroidPosition,
                             EventSystem.current.pixelDragThreshold, eventData.useDragThreshold))
         {
             ClearPointerPressOrDrag(eventData);
             return(SendEvent <IPanHandler>(eventData.multitouchTarget, eventData, PanEvent, true));
         }
     }
     return(false);
 }
예제 #10
0
        /// <summary>
        /// Check for rotate. This would be all normalized touches moving the same clock direction
        /// </summary>
        /// <returns></returns>
        private bool CheckRotate(MultiTouchPointerEventData eventData)
        {
            if (!DetectRotate)
            {
                return(false);
            }

            int countNeeded = eventData.touchCluster.Count - NumNearCenter;

            if (countNeeded > 1 && (NumOffAxisCCW >= countNeeded || NumOffAxisCW >= countNeeded))
            {
                ClearPointerPressOrDrag(eventData);
                return(SendEvent <IRotateHandler>(eventData.multitouchTarget, eventData, RotateEvent, true));
            }
            return(false);
        }
예제 #11
0
        /// <summary>
        /// Check for a pinch. This would be all normalized touches moving more-or-less toward
        /// or away from the centroid.
        /// </summary>
        /// <returns>true if event fired</returns>
        private bool CheckPinch(MultiTouchPointerEventData eventData)
        {
            if (!DetectPinch)
            {
                return(false);
            }

            int countNeeded = eventData.touchCluster.Count - NumNearCenter;

            if (countNeeded > 1 && (NumInward >= countNeeded || NumOutward >= countNeeded))
            {
                ClearPointerPressOrDrag(eventData);
                return(SendEvent <IPinchHandler>(eventData.multitouchTarget, eventData, PinchEvent, true));
            }
            return(false);
        }
예제 #12
0
 private void LogMultiTouchEvent <T>(string eventName, MultiTouchPointerEventData eventData, T delta)
 {
     LogPointerEvent(eventName, eventData);
     _eventDesc.AppendFormat("Centroid[pos {0}, delta {1}, pressed pos {2}] event delta {3}\n",
                             eventData.centroidPosition, eventData.centroidDelta, eventData.centroidPressPosition, delta);
 }
예제 #13
0
 public void OnPinch(SimpleGestures sender, MultiTouchPointerEventData eventData, Vector2 pinchDelta)
 {
     LogMultiTouchEvent("OnPinch", eventData, pinchDelta);
 }
예제 #14
0
 public void OnPan(SimpleGestures sender, MultiTouchPointerEventData eventData, Vector2 delta)
 {
     LogMultiTouchEvent("OnPan", eventData, delta);
 }
예제 #15
0
 public void OnRotate(SimpleGestures sender, MultiTouchPointerEventData eventData, float delta)
 {
     LogMultiTouchEvent("OnRotate", eventData, delta);
 }
예제 #16
0
        protected void EvaluateRelativeMotion(MultiTouchPointerEventData eventData)
        {
            NumInward        = 0;
            NumOutward       = 0;
            NumOffAxisCW     = 0;
            NumOffAxisCCW    = 0;
            NumMatchCentroid = 0;
            NumAntiCentroid  = 0;

            NumNearCenter = 0;
            DeltaPinch    = Vector2.zero;
            DeltaRotate   = 0;

            float clusterRadius = eventData.touchCluster.Radius;

            Vector2 centroidDelta = eventData.centroidPosition - GestureData.PriorCluster.Centroid;

            foreach (var entry in eventData.touchCluster.Touches)
            {
                TouchPt currentTouch = entry.Value;
                TouchPt normalizedPriorTouch;
                if (NormalizedPriorCluster.Touches.TryGetValue(entry.Key, out normalizedPriorTouch))
                {
                    float   dot;
                    Vector2 rawMove = currentTouch.position - GestureData.PriorCluster.Touches[currentTouch.fingerId].position;
                    if (rawMove.sqrMagnitude > 0.5f)
                    {
                        dot = Vector2.Dot(centroidDelta.normalized, rawMove.normalized);
                        if (Mathf.Abs(dot) >= (1.0f - DragTollerance))
                        {
                            NumMatchCentroid++;
                        }
                        else
                        {
                            NumAntiCentroid++;
                        }
                    }
                    Vector2 fromCentroid = eventData.touchCluster.GetRelativeTouchVector(entry.Key);
                    if (!Mathf.Approximately(clusterRadius, 0f))
                    {
                        if (fromCentroid.magnitude / clusterRadius < CloseToCenterRatio)
                        {
                            NumNearCenter++;
                        }
                    }

                    Vector2 delta          = currentTouch.position - normalizedPriorTouch.position;
                    float   deltaMagnitude = delta.magnitude;
                    dot = Vector2.Dot(fromCentroid.normalized, delta.normalized);
                    float absDot = Mathf.Abs(dot);

                    if (1.0f - absDot < PinchTollerance)
                    {
                        if (dot > 0)
                        {
                            NumOutward++;
                            DeltaPinch += delta.Abs();
                        }
                        else
                        {
                            NumInward++;
                            DeltaPinch -= delta.Abs();
                        }
                    }
                    else if (absDot < RotateTollerance)
                    {
                        float dotPerp = Vector2.Dot(fromCentroid.Perp(), delta);
                        if (dotPerp < 0)
                        {
                            NumOffAxisCW++;
                            DeltaRotate += deltaMagnitude / fromCentroid.magnitude;
                        }
                        else
                        {
                            NumOffAxisCCW++;
                            DeltaRotate -= deltaMagnitude / fromCentroid.magnitude;
                        }
                    }
                }
            }
            if (NumOffAxisCCW > 0 || NumOffAxisCW > 0)
            {
                DeltaRotate = Mathf.Atan2(DeltaRotate, 1f) * Mathf.Rad2Deg;
                if (DeltaRotate > 180f)
                {
                    DeltaRotate -= 360f;
                }
            }
        }