iosobjective-cxcodescenekitsceneview

After enable user interaction on a SCNView, how to make it only rotate horizontally?


I’m new to SceneKit,and what I’m trying do is to load a dae file to a SCNScene, set this SCNScene to a SCNView, enable the user interaction, and then I can rotate the 3D model through gestures. So far it goes well, when I swipe or zoom in/zoom out, the 3D model works as the way it should be. However, what I really need is that when a gesture(swipe right or left)takes place, the 3D model rotates only horizontally, and no zoom in/zoom out, what can I do to make it happen? Here is my code:

// retrieve the SCNView
SCNView *myView = (SCNView *)self.view;

// load dae file and set the scene to the view
myView.scene = [SCNScene sceneNamed:@"model.dae"];

myView.userInteractionEnabled = YES;
myView.allowsCameraControl = YES;
myView.autoenablesDefaultLighting = YES;
myView.backgroundColor = [UIColor lightGrayColor];

Thanks for any help!


Solution

  • I'm not sure you can do it with allowsCameraControl - it seems to be a very basic provision for interaction with the model.

    If you add a pan gesture to the scene you can then manipulate any node in the model however you please:

    - (void)viewDidLoad {
        // Add the scene etc....
    
        UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
        [_sceneView addGestureRecognizer:panRecognizer];
    }
    
    - (void)panGesture:(UIPanGestureRecognizer *)sender {
        CGPoint translation = [sender translationInView:sender.view];
    
        if (sender.state == UIGestureRecognizerStateChanged) {
            [self doPanWithPoint:translation];
        }
    }
    
    - (void)doPanWithPoint:(CGPoint)translation {
        CGFloat x = (CGFloat)(translation.y) * (CGFloat)(M_PI)/180.0;
        CGFloat y = (CGFloat)(translation.x) * (CGFloat)(M_PI)/180.0;
    
        // Manuipulate the required (root?) node as you see fit
        _geometryNode.transform = SCNMatrix4MakeRotation(x, 0, 1, 0);
        _geometryNode.transform = SCNMatrix4Mult(_geometryNode.transform, SCNMatrix4MakeRotation(y, 1, 0, 0));
    }
    

    You can obviously omit the second rotation step (or set y=0) to only rotate horizontally.