x


gesture rotation clamp

hi everybody, I've found this script by Alexander Orozco somewhere on the web, and it works perfectly with pinch and swipe gesture to rotate and zoom in/out the camera, but I can't figure it out how I can clamp the y and z axis value. I've tried with Mathf.Clamp but I can't find the right value to clamp..

using UnityEngine; using System.Collections;

public class Gestures : MonoBehaviour {

 // adjust accordingly in the inspector
 public float zoomNearLimit = 5;
 public float zoomFarLimit = 12;
 public float zoomScreenToWorldRatio = 3.0f;
 public float orbitScreenToWorldRatio = 1.0f;
 public float twistScreenToWorldRatio = 5.0f;
 public float rotateMinLimit = 0;
 public float rotateMaxLimit = 80;
 
 
 // don't change these
 Vector3 orbitSpeed = Vector3.zero;
 float twistSpeed = 0;
 float distWeight;
 float zoomDistance;
 float zoomSpeed = 0;
 float lastf0f1Dist;
 
 
 void Update () {
     
     
     // one finger gestures
     if (iPhoneInput.touchCount == 1) {
         
         // finger data
         iPhoneTouch f0 = iPhoneInput.GetTouch(0);
         
         // finger delta
         Vector3 f0Delta = new Vector3(f0.deltaPosition.x, -f0.deltaPosition.y, 0);
         
         // if finger moving
         if (f0.phase == iPhoneTouchPhase.Moved) {
             
             // compute orbit speed
             orbitSpeed += (f0Delta + f0Delta * distWeight) * orbitScreenToWorldRatio * Time.deltaTime;
         }
     }
     
     // two fingers gestures
     else if (iPhoneInput.touchCount == 2) {
         
         // fingers data
         iPhoneTouch f0 = iPhoneInput.GetTouch(0);
         iPhoneTouch f1 = iPhoneInput.GetTouch(1);
         
         // fingers positions
         Vector3 f0Pos = new Vector3(f0.position.x, f0.position.y, 0);
         Vector3 f1Pos = new Vector3(f1.position.x, f1.position.y, 0);
         
         // fingers movements
         Vector3 f0Delta = new Vector3(f0.deltaPosition.x, f0.deltaPosition.y, 0);
         Vector3 f1Delta = new Vector3(f1.deltaPosition.x, f1.deltaPosition.y, 0);
         

         // fingers distance
         float f0f1Dist = Vector3.Distance(f0.position, f1.position);
         
         // if both fingers moving
         if (f0.phase == iPhoneTouchPhase.Moved && f1.phase == iPhoneTouchPhase.Moved) {
             
             // fingers moving direction
             Vector3 f0Dir = f0Delta.normalized;
             Vector3 f1Dir = f1Delta.normalized;
             
             // dot product of directions
             float dot = Vector3.Dot(f0Dir, f1Dir);
             
             // if fingers moving in opposite directions
             if (dot < -0.7f) {
                 
                 float pinchDelta = f0f1Dist - lastf0f1Dist;
                 
                 // if fingers move more than a threshold
                 if (Mathf.Abs(pinchDelta) > 2) {
                     
                     // if pinch out, zoom in 
                     if (f0f1Dist > lastf0f1Dist && zoomDistance > zoomNearLimit) {
                         zoomSpeed += (pinchDelta + pinchDelta * distWeight) * Time.deltaTime * zoomScreenToWorldRatio;
                     }
                     
                     // if pinch in, zoom out
                     else if (f0f1Dist < lastf0f1Dist && zoomDistance < zoomFarLimit) {
                         zoomSpeed += (pinchDelta + pinchDelta * distWeight) * Time.deltaTime * zoomScreenToWorldRatio;
                     }
                 }
                 
                 // detect twist
                 /*if (f0Delta.magnitude > 2 && f1Delta.magnitude > 2) {
                     
                     // homemade algorithm works, but needs code review
                     Vector3 fingersDir = (f1Pos - f0Pos).normalized;
                     Vector3 twistNormal = Vector3.Cross(fingersDir, Vector3.forward);
                     Vector3 twistAxis = Vector3.Cross(fingersDir, twistNormal);
                     float averageDelta = (f0Delta.magnitude + f1Delta.magnitude) / 2;
                     if (Vector3.Dot(f0Dir, twistNormal) > 0.7f) {
                         twistSpeed =  twistAxis.z * averageDelta * Time.deltaTime * twistScreenToWorldRatio;
                     }
                     else if (Vector3.Dot(f0Dir, twistNormal) < -0.7f) {
                         twistSpeed = -twistAxis.z * averageDelta * Time.deltaTime * twistScreenToWorldRatio;
                     }
                 }*/
             }
         }
         
         // record last distance, for delta distances
         lastf0f1Dist = f0f1Dist;
         
         // decelerate zoom speed
         zoomSpeed = zoomSpeed * (1 - Time.deltaTime * 10);
     }
     
     // no touching, or too many touches (we don't care about)
     else {
         
         // bounce to zoom limits
         if (zoomDistance < zoomNearLimit) {
             zoomSpeed += (zoomDistance - zoomNearLimit) * zoomScreenToWorldRatio;
         }
         else if (zoomDistance > zoomFarLimit) {
             zoomSpeed += (zoomDistance - zoomFarLimit) * zoomScreenToWorldRatio;
         }

         // or decelerate
         else {
             zoomSpeed = zoomSpeed * (1 - Time.deltaTime * 10);
         }
     }
     
     // decelerate orbit speed
     orbitSpeed = orbitSpeed * (1 - Time.deltaTime * 5);

     // decelerate twist speed
     twistSpeed = twistSpeed * (1 - Time.deltaTime * 5);

     // apply zoom
     transform.position += transform.forward * zoomSpeed * Time.deltaTime;
     zoomDistance = transform.position.magnitude;
     
     // apply orbit and twist
     transform.position = Vector3.zero;
     transform.localRotation *= Quaternion.Euler(orbitSpeed.y, orbitSpeed.x, twistSpeed);
     transform.position = -transform.forward * zoomDistance;
     

     // compensate for distance (ej. orbit slower when zoomed in; faster when out)
     distWeight = (zoomDistance - zoomNearLimit) / (zoomFarLimit - zoomNearLimit);
     distWeight = Mathf.Clamp01(distWeight);
 }
 

}

thanks for your help!

more ▼

asked Jan 13, 2012 at 06:11 PM

c.zeta gravatar image

c.zeta
36 12 11 13

(comments are locked)
10|3000 characters needed characters left

2 answers: sort voted first

You could try to limit Transform.localEulerAngles after "apply orbit and twist".

more ▼

answered Jan 13, 2012 at 06:42 PM

efge gravatar image

efge
5.3k 20 26 57

how can I do this exactly?

I've tried with this code but it doesn't work and I can't undestand why..

orbitSpeed.y = Mathf.Clamp(orbitSpeed.y, rotateMinLimit, rotateMaxLimit);

Jan 14, 2012 at 01:21 PM c.zeta
(comments are locked)
10|3000 characters needed characters left

I know this is an old thread-- but I was looking for a similar solution. After some messing around and googling stuff I got this to work with the script above...

 // define these
 public float maxYRotationDegrees;
 public float minYRotationDegrees;
 public float maxXRotationDegrees;
 public float minXRotationDegrees;
 public float maxZRotationDegrees;
 public float minZRotationDegrees;
 private Quaternion tempQuaternion;
 private Quaternion clampedQuaternion;
 
 // then down at the apply orbit and twist, replace with:
 tempQuaternion = transform.localRotation;
 // apply the quaternion adjustments to our tempQuaternion
 tempQuaternion *= Quaternion.Euler (orbitSpeed.y, orbitSpeed.x, twistSpeed);
 // clamp the quaternion and convert to eulerangles
 clampedQuaternion.eulerAngles = new Vector3 ((ClampAngle(tempQuaternion.eulerAngles.x,minXRotationDegrees, maxXRotationDegrees)), (ClampAngle(tempQuaternion.eulerAngles.y, minYRotationDegrees, maxYRotationDegrees)),(ClampAngle(tempQuaternion.eulerAngles.z, minZRotationDegrees, maxZRotationDegrees)));
 // note: here you can substitute in hard number angles if you wish.  I set the z to 0f to ignore twist, for instance
 transform.localEulerAngles = new Vector3 (clampedQuaternion.eulerAngles.x, clampedQuaternion.eulerAngles.y, clampedQuaternion.eulerAngles.z);
 
 // finally, a clamp euler angle function
 float ClampAngle (float a, float min, float max) 
 {
 while (max < min) max += 360.0f;
 while (a > max) a -= 360.0f;
 while (a < min) a += 360.0f;
 if (a > max)
     {
     if (a - (max + min) * 0.5f < 180.0f)
        return max;
     else
        return min;
     }
 else
     return a;
 }

Hope this is helpful to someone!,

more ▼

answered Apr 05, 2012 at 12:38 PM

funasylum gravatar image

funasylum
36 3 2 4

what is this code?

Sep 09 at 08:36 PM abtrakt
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x3774
x169
x140
x17

asked: Jan 13, 2012 at 06:11 PM

Seen: 2577 times

Last Updated: Sep 09 at 08:36 PM