随着iOS设备的移动,cameranode旋转

ron*_*nan 13 ios cmmotionmanager scenekit scnnode

这是360度视频播放器项目.

我添加了一个cameranode(SCNNode)到一个根节点,cameranode被放在了中心(0,0,0)SCNSphere,它现在可以播放视频了.

现在我必须使用devicemotion.设备移动时我需要旋转相机.不只是旋转一定的角度.(不只是设备移动,当我拿着设备时,我的移动方式就像设备移动一样.因为我发现如果我使用deviceMotion.attitude.roll,cameranode仅在设备自行移动时移动,而不是当我绕着设备移动时)

当设备位于(x1,y1,z1)位置时,cameranode将随设备移动而旋转,当设备再次位于(x1,y1,z1)位置时,视图应与我们离开的最后一个相同.

这就是我所做的:

if (self.motionManager.gyroAvailable) {
        self.motionManager.gyroUpdateInterval = 1.0/60.0;
        [self.motionManager startGyroUpdatesToQueue:self.queue withHandler:^(CMGyroData *gyroData, NSError *error){
            if (error) {
                [self.motionManager stopGyroUpdates];
                NSLog(@"Gyroscope encountered error:%@",error);
            }else {
                CGFloat tempX = 0;
                CGFloat tempY = 0;
                CGFloat tempZ = 0;
                if ((fabs(gyroData.rotationRate.y)/60) > 0.002) {
                    tempY = gyroData.rotationRate.y/60;
                }
                tempX = gyroData.rotationRate.x/60;
                tempZ = gyroData.rotationRate.z/60;
                [self.cameraNode runAction:[SCNAction rotateByX:-tempY y:tempX z:tempZ duration:0]];
            }
        }];
    }else {
        NSLog(@"This device has no gyroscope");
    }
Run Code Online (Sandbox Code Playgroud)

数学可能是错误的,我不知道为什么我会划分60,但它似乎是我使用时所需的最接近的值 [self.cameraNode runAction:[SCNAction rotateByX:-tempY y:tempX z:tempZ duration:0]];

这是问题所在?

  1. 我应该使用哪些数据?

CMGyroDataCMDeviceMotion.如果使用CMDeviceMotion,我应该使用哪个具体值?deviceMotion.attitude,deviceMotion.attitude.quaternion,deviceMotion.gravity

  1. 旋转cameranode的正确方法是什么?有很多方法,我不确定.

+ (SCNAction *)rotateByX:(CGFloat)xAngle y:(CGFloat)yAngle z:(CGFloat)zAngle duration:(NSTimeInterval)duration;

+ (SCNAction *)rotateToX:(CGFloat)xAngle y:(CGFloat)yAngle z:(CGFloat)zAngle duration:(NSTimeInterval)duration;

Tra*_*vis 27

设备运动是最好的,因为它连接多个传感器并以有意义的方式将数据融合在一起.最好避免使用欧拉角,因为它们遭受所谓的万向节锁定.而是使用四元数并使用它们设置相机方向.

为CMDeviceMotion创建了一个Swift类扩展,它可以让你确定设备正在查看的内容(对于屏幕的任何方向).

从那里,旋转相机很简单.首先,设置您的设备动作(在视图中确实显示,或其他一些适当的位置):

if motionManager.deviceMotionAvailable {

    motionManager.deviceMotionUpdateInterval = 0.017
    motionManager.startDeviceMotionUpdatesToQueue(NSOperationQueue(), withHandler: deviceDidMove)
}
Run Code Online (Sandbox Code Playgroud)

然后使用前面提到的CMDeviceMotion扩展,在deviceDidMove实现中处理这些更新:

func deviceDidMove(motion: CMDeviceMotion?, error: NSError?) {

    if let motion = motion {

        yourCameraNode.orientation = motion.gaze(atOrientation: UIApplication.sharedApplication().statusBarOrientation)
    }
}
Run Code Online (Sandbox Code Playgroud)

现在你的相机应该跟随你的设备在太空中的方向.