public CameraNavigation() { this.axes = UseAxes.MouseXAndY; this.defaultMouseNavigation = NavigationMode.Orbit; this.drag1FingerNavigation = NavigationMode.Orbit; this.drag2FingerNavigation = NavigationMode.Pan; this.drag3FingerNavigation = NavigationMode.Look; this.drag4FingerNavigation = NavigationMode.None; this.rotate2FingerNavigation = NavigationMode.Look; this.pinch2FingerNavigation = NavigationMode.Dolly; this.doubleTap1Finger = DoubleTabMethod.Focus; this.doubleTap2Finger = DoubleTabMethod.None; this.doubleTap3Finger = DoubleTabMethod.Frame; this.frameKey = KeyCode.F; this.frameOnStartup = true; this.upperRotateLimit = 80; this.lowerRotateLimit = 280; this.orbitSpeed = 1f; this.lookSpeed = 1f; this.panSpeed = 1f; this.dollySpeed = 0.1f; this.touchPauseTimeout = 0.6f; this.longPressRadius = 40; this.touchNavigation = TouchNavigation.None; this.touchInputDelay = 2; this.navigationLookup = new NavigationAction[][] { new NavigationAction[] { this.orbit, this.pan, this.look, this.dolly }, new NavigationAction[] { this.pan, this.orbit, this.look, this.dolly }, new NavigationAction[] { this.look, this.pan, this.orbit, this.dolly }, new NavigationAction[] { this.dolly, this.pan, this.look, this.orbit } }; this.touchNavigationLookup = new NavigationAction[] { this.nullNav, this.orbit, this.pan, this.look, this.dolly }; this.doubleTapMethodLookup = new NavigationAction[] { this.nullTap, this.focus, this.frameCamera }; this.touchSpot = new Vector2(-50, -50); this.sceneBoundingBoxDirty = true; }
// Performs the recognition and nagivation for 2 fingured inputs. private void check2FingerNavigation() { Vector2 delta0 = default(Vector2); Vector2 delta1 = default(Vector2); Touch touch0 = Input.GetTouch(0); Touch touch1 = Input.GetTouch(1); float diffTime = (touch0.deltaTime + touch1.deltaTime) * 0.5f; // If the user has not moved their fingers in 0.6 seconds we assume that we should // attempt to recognise the gesture. This allows the user to keep their fingers // on the screen and start a new gesture. if (diffTime > this.touchPauseTimeout) { this.clearTouchInput(); } if (this.touchInputCount < this.touchInputDelay) { this.touchInputCount++; return; } else { if (this.touchInputCount == this.touchInputDelay) { this.touchInputCount++; delta0 = touch0.position - this.initialInputs[0]; delta1 = touch1.position - this.initialInputs[1]; } else { delta0 = touch0.deltaPosition; delta1 = touch1.deltaPosition; } } if ((this.touchNavigation == TouchNavigation.None) || (this.touchNavigation == TouchNavigation.Drag2Fingers)) { float angleDifference = Vector2.Angle(delta0, delta1); // If the angle between the difference vectors is less than 60 then it is likely the two fingers // are moving in the same direction which indicates a drag. if (((Mathf.Abs(angleDifference) < 60) || (this.touchNavigation == TouchNavigation.Drag2Fingers)) || ((this.pinch2FingerNavigation == NavigationMode.None) && (this.rotate2FingerNavigation == NavigationMode.None))) { // Dragging. // While averaging should be just 0.5, often this results in movement that's much faster // that what a normal drag with the mouse would be. Vector2 averageMove = (touch0.deltaPosition + touch1.deltaPosition) * 0.5f; //var averageMove:Vector2 = delta0 * 0.5; this.touchNavigation = TouchNavigation.Drag2Fingers; NavigationAction touchAction = this.touchNavigationLookup[((int)this.drag2FingerNavigation)]; touchAction(averageMove.x, averageMove.y); return; } } // Makes use of the average vectors. These are used to actually calculate // the gesture being executed. Vector2 oldVectorAverage = (touch0.position - delta0) - (touch1.position - delta1); // These always use the most recent deltaPosition Vector2 newVector = touch0.position - touch1.position; float newMagnitude = newVector.magnitude; Vector2 oldVector = (touch0.position - touch0.deltaPosition) - (touch1.position - touch1.deltaPosition); float diffAverage = newMagnitude - oldVectorAverage.magnitude; Vector3 curlAverage = Vector3.Cross(oldVectorAverage.normalized, newVector.normalized); // Find the ratio between the curl of the vectors and the difference in // maginutde. When this is over 1000 this usually indicates that the difference // is greater which indicates a pinch, otherwise it indicates that the curl is // greater and that the user is rotating. float ratioAverage = Mathf.Abs(diffAverage / curlAverage.z); if ((this.touchNavigation == TouchNavigation.None) || (this.touchNavigation == TouchNavigation.Rotating)) { if (((ratioAverage < 1000) || (this.touchNavigation == TouchNavigation.Rotating)) || (this.pinch2FingerNavigation == NavigationMode.None)) { Vector3 curl = Vector3.Cross(oldVector.normalized, newVector.normalized); this.touchNavigation = TouchNavigation.Rotating; NavigationAction touchAction = this.touchNavigationLookup[((int)this.rotate2FingerNavigation)]; touchAction(curl.z * 400, 0); } } if ((this.touchNavigation == TouchNavigation.None) || (this.touchNavigation == TouchNavigation.Pinching)) { if ((((ratioAverage >= 1000) && (Mathf.Abs(diffAverage) > 20)) || (this.touchNavigation == TouchNavigation.Pinching)) || (this.rotate2FingerNavigation == NavigationMode.None)) { float diff = newMagnitude - oldVector.magnitude; this.touchNavigation = TouchNavigation.Pinching; float diffLog = 0; if (Mathf.Abs(diff) > 1) { diffLog = Mathf.Log(Mathf.Abs(diff)) / 1.25f; } float d = 0.1f + diffLog; NavigationAction touchAction = this.touchNavigationLookup[((int)this.pinch2FingerNavigation)]; touchAction(diff > 0 ? d : -d, 0); } } }
// Resets the variables required to reset the touch input recognition. private void clearTouchInput() { this.touchNavigation = TouchNavigation.None; this.touchInputCount = 0; }