private void HandleRetainedInput(bool preserveEndedTouches) { bool isNewPoint = true; if (CurrentTouchIndex >= 0) { var eventSystem = MultiselectEventSystem.current; TouchPt currentTouch = Touches[CurrentTouchIndex]; isNewPoint = currentTouch.UpdatePointFromMouse(eventSystem.MaxDoubleClickDistancePixels, eventSystem.MaxDoubleClickTime); if (preserveEndedTouches && (currentTouch.phase == TouchPhase.Ended || currentTouch.phase == TouchPhase.Canceled)) { // in retained mode, keep the completed point around as though it is still pressed currentTouch.phase = TouchPhase.Stationary; currentTouch.deltaPosition = Vector2.zero; } Touches[CurrentTouchIndex] = currentTouch; } if (isNewPoint) { // Add new point if (Input.GetMouseButton((int)PointerEventData.InputButton.Left)) { Touches.Add(TouchPt.GetMouseAsTouchPt(_nextTouchId++)); CurrentTouchIndex = Touches.Count - 1; } else { CurrentTouchIndex = -1; } } }
private void AddTouchToListIfActive(TouchPt touch) { if (touch.phase != TouchPhase.Canceled && touch.phase != TouchPhase.Ended) { _touchList.Add(touch); } _pointList.Add(touch); }
private void ComputeDisplayEdges(SpanningTree.Node current, SpanningTree tree) { if (current == null) { return; } TouchPt touch = tree.GetTouchPoint(current); Vector2 pos; RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)transform, touch.position, Camera.main, out pos); _lines.Add(pos); foreach (var neighbor in current.Neighbors) { ComputeDisplayEdges(neighbor, tree); _lines.Add(pos); } }
private void HandleSingleTouchInput() { bool isCurrent = CurrentTouchIndex >= 0; for (int i = Touches.Count - 1; i >= 0; i--) { TouchPt touch = Touches[i]; if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled) { // touch ended last update, remove it from the list now Touches.RemoveAt(i); } else if (!isCurrent) { // Set as canceled so it will be removed next time touch.phase = TouchPhase.Canceled; Touches[i] = touch; } isCurrent = false; } CurrentTouchIndex = Touches.Count - 1; HandleRetainedInput(false); }
// New implementation of PointerInputModule.GetTouchPointerEventData() // which takes a TouchPt instead of Touch protected MultiTouchPointerEventData GetTouchPointerEventData(TouchPt touch, TouchCluster cluster, out bool pressed, out bool released) { MultiTouchPointerEventData pointerData; var created = GetMultiTouchPointerData(cluster.ClusterId, out pointerData, true); pointerData.Reset(); pressed = created || (touch.phase == TouchPhase.Began); released = (touch.phase == TouchPhase.Canceled) || (touch.phase == TouchPhase.Ended); if (created) { // position information needs to be set first when // EventData has just been created pointerData.position = touch.position; pointerData.centroidPosition = cluster.Centroid; pointerData.touchCluster.CopyFrom(cluster); } if (pressed) { pointerData.delta = Vector2.zero; pointerData.centroidPressPosition = cluster.Centroid; pointerData.centroidDelta = Vector2.zero; } else { pointerData.delta = touch.position - pointerData.position; pointerData.centroidDelta = cluster.Centroid - pointerData.centroidPosition; } if (!created) { // position information needs to be set here after deltas // are computed when not first created. (time optimization since cluster copy can take time) pointerData.position = touch.position; pointerData.centroidPosition = cluster.Centroid; pointerData.touchCluster.CopyFrom(cluster); } pointerData.button = PointerEventData.InputButton.Left; eventSystem.RaycastAll(pointerData, m_RaycastResultCache); RaycastResult raycast; while (true) { raycast = FindFirstRaycast(m_RaycastResultCache); var raycastProxy = raycast.gameObject != null?raycast.gameObject.GetComponent <RaycasterProxy>() : null; if (raycastProxy == null || !raycastProxy.IsProxyActive) { break; // found a result that is not an active proxy } // The proxy is the primary item. Therefore, discard the results to this point and raycast within the // proxied camera m_RaycastResultCache.Clear(); //raycastProxy.RcTransform.SetAsLastSibling(); raycastProxy.ProxyRaycaster.Raycast(pointerData, m_RaycastResultCache); } pointerData.pointerCurrentRaycast = raycast; m_RaycastResultCache.Clear(); return(pointerData); }
private bool ProcessTouch(TouchPt touch, TouchCluster cluster) { bool released; bool pressed; var pointer = GetTouchPointerEventData(touch, cluster, out pressed, out released); if (pointer.rawPointerPress != null && _usedTargets.Contains(pointer.rawPointerPress)) { return(false); // Don't send to same object another touch has been sent to } int oldContext = SetSelectedObjectContext(cluster.ClusterId, false); bool processed = false; bool allowNormalEvents = true; if (ProcessMultiTouchPress(pointer, pressed, released) || AlwaysProcessGestures) { // Only do multitouch gesture processing if there is a target found for them foreach (IMultiTouchGestureModule module in _multitouchModules) { MultiTouchProcessResult result = module.Process(pointer, this); processed |= result != MultiTouchProcessResult.NotProcessed; if (result == MultiTouchProcessResult.Exclusive) { allowNormalEvents = false; break; } if (result == MultiTouchProcessResult.NonExclusiveBlockNormalEvents) { allowNormalEvents = false; } } } if (pointer.singleTouchProcessingEnabled) { if (allowNormalEvents) { ProcessTouchPress(pointer, pressed, released); // May have sent the following events on Pressed: // for these comments, "go" is pointer.pointerCurrentRaycast.gameObject // IPointerEnter/Exit (all up and down the hierarchy, all "entered" objects held in pointer.hovered // pointer.pointerEnter = go // IPointerDownHandler (to first handler) // pointer.pointerPress = handler game object OR IPointerClickHandler game object // pointer.rawPointerPress = go // IInitializePotentialDragHandler if IDragHandler is found // pointer.pointerDrag = Drag Handler if (!released) { ProcessMove(pointer); ProcessDrag(pointer); processed = true; } } else if (!pressed) { CancelSingleTouchProcessing(pointer); } } if (processed) { _usedTargets.Add(pointer.rawPointerPress); } if (released) { RemovePointerData(pointer); if (_multiselectEventSystem != null) { _multiselectEventSystem.RemoveSelectedObjectContext(touch.fingerId); } } SetSelectedObjectContext(oldContext, !processed); return(processed); }
private void ProcessInput() { if (RendererPrefab != null) { if (_touchList.Count > 0) { if (_currentTrees.Count == 0) { SpanningTree newTree = SpanningTree.Get(); newTree.SetTouchList(_touchList); if (newTree.SeparateClusters(_currentTrees)) { newTree.Dispose(); } } else { foreach (var tree in _currentTrees) { // UpdateTouchPoints returns zero if the tree has been emptied of all touch points // SeparateClusters adds either tree, or the results of the split trees into _tempTrees // and returns true if the tree was split if (tree.UpdateTouchPoints(_touchList) == 0 || tree.SeparateClusters(_tempTrees)) { tree.Dispose(); } } // Swap tree lists, making the result of the update the _currentTrees var temp = _currentTrees; _currentTrees = _tempTrees; _tempTrees = temp; // clear the _tempTrees list // Any trees that are not current have already been disposed _tempTrees.Clear(); // Any touches left in _touchList are ones that are new foreach (var touch in _touchList) { if (touch.phase == TouchPhase.Canceled || touch.phase == TouchPhase.Ended) { continue; // don't add old touches } // add any new touches into the closest tree // but only if the distance is less than the maximum edge length float bestDistance = MultiselectEventSystem.current.MaxTouchClusterDistancePixels; SpanningTree tree = null; foreach (var spanningTree in _currentTrees) { float treeDistance = spanningTree.ComputeMinimumDistanceToPoint(touch.position); if (treeDistance < bestDistance) { bestDistance = treeDistance; tree = spanningTree; } } if (tree != null) { tree.AddTouch(touch); tree.ProcessTree(); } else { // Too far from any tree, create a new one tree = SpanningTree.Get(); tree.AddTouch(touch); _currentTrees.Add(tree); } } } EnsureRenderers(_currentTrees.Count); for (int i = 0; i < _currentTrees.Count; i++) { DisplayTreeInRenderer(_renderers[i], _currentTrees[i]); _renderers[i].gameObject.SetActive(true); } } else { ReleaseTrees(_currentTrees); } for (int i = _currentTrees.Count; i < _renderers.Count; i++) { _renderers[i].gameObject.SetActive(false); } } EnsurePointMarkers(_pointList.Count); RectTransform rcTransform = (RectTransform)transform; Vector2 offset = rcTransform.localPosition.XY(); for (int i = 0; i < _pointList.Count; i++) { TouchPt touch = _pointList[i]; Vector2 pos; if (TouchCanvas.renderMode == RenderMode.ScreenSpaceOverlay) { pos = touch.position - offset; } else { RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)transform, touch.position, TouchCanvas.worldCamera, out pos); } _pointMarkers[i].transform.localPosition = pos.AsVector3(); _pointMarkers[i].color = touch.phase == TouchPhase.Ended ? TouchEnded : touch.phase == TouchPhase.Canceled ? TouchCancelled : TouchActive; } }