Search code examples
objective-cxcode3drotational-matrices

Rotate a 3D Object using Touch inputs in iOS


I am working on an ios application where I need to rotate a 3d matrix (3D object) just by swiping a finger over it. the method i use for the rotation is

setRotationMatrix(float angle, float x, float y, float z, float *matrix);

However I am not sure how to use the touch's x and y location values in order to rotate the 3D matrix correctly. Here is the code that I am using

-(IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {

    if(recognizer.state == UIGestureRecognizerStateBegan)
    {
        panStartPoint = [recognizer locationInView:self];
        previousPoint.x = 0;
        previousPoint.y = 0;
        currentPoint.x = panStartPoint.x;
        currentPoint.y = panStartPoint.y;
    }
    else if(recognizer.state == UIGestureRecognizerStateEnded)
    {
        panEndPoint = [recognizer locationInView:self];
    }
    else if (recognizer.state == UIGestureRecognizerStateChanged)
    {
        previousPoint.x = currentPoint.x;
        previousPoint.y = currentPoint.y;
        CGPoint instanteneousPoint = [recognizer locationInView:self];
        currentPoint.x = instanteneousPoint.x;
        currentPoint.y = instanteneousPoint.y;

        int xdifference = currentPoint.x - previousPoint.x;
        int ydifference = currentPoint.y - previousPoint.y;



        if((xdifference <= rotationThreshold *-1) || xdifference >= rotationThreshold)  //rotationThreshold = 3;
        {
            if(xdifference <= rotationThreshold *-1)
            {
                rotationY = -1.0;
            }
            else
            {
                rotationY = 1.0;
            }

            if( (ydifference >= rotationThreshold *-1) && ydifference <= rotationThreshold )
            {
                rotationX = 0.0;
            }
        }

        if((ydifference <= rotationThreshold *-1) || ydifference >= rotationThreshold)
        {
          if((ydifference <= rotationThreshold *-1))
          {
            rotationX = -1.0;
          }
          else
          {
              rotationX = 1.0;
          }
            if( (xdifference >= rotationThreshold *-1) && xdifference <= rotationThreshold )
            {
                rotationY = 0.0;
            }

        }
        if(rotationX != 0.0 || rotationY != 0.0)
        {
            rotationDegree += 5.0f;
            if(rotationDegree >= 360.0f)
            {
                rotationDegree = 0.0f;
            }
            ShaderUtils::rotatePoseMatrix(rotationDegree, rotationX, rotationY, rotationZ, &modelViewMatrix.data[0]); //rotationZ = 0;
        }}}

This is providing me with some rotation of the 3D object but its not as natural as it should be. Any help will be much appreciated. Thanks.


Solution

  • well..i never used used UIPanGestureRecognizer so i dont know how and why doesnt it work but i used UITouch to move a 3d object (i find it to be easyer)

    ok..so here is what i did (i dont have the code anymore so i cant give it to you ...sorry):

    you get the first touch with touchesBegan (UITouchPhaseBegan)

    then, if touchesMoved you rotate the object over x axis if touch moved on y and rotate it on y axis if touch moved on x ..and any combination of the 2 (you have to set sensitivity yourself)

    also you have the option to move the object in view like this: you tap twice and then move the finger (like a laptop's track pad)

    to move it on the z axis just use UIPinchGestureRecognizer

    its obvious you can't move a 3d object in all 3 dimensions with a 2d surface

    for more look in UITouch class reference

    i may not have explained very well...but you get the basic idea