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

这是360度video播放器项目。

我将一个cameranode( SCNNode )添加到根节点,将cameranode放在SCNSphere的中心(0,0,0),它现在可以播放video。

现在我必须使用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"); } 

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

这是问题所在?

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

CMGyroDataCMDeviceMotion 。 如果使用CMDeviceMotion ,我应该使用哪个特定值? deviceMotion.attitudedeviceMotion.attitude.quaterniondeviceMotion.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;

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

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

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

 if motionManager.deviceMotionAvailable { motionManager.deviceMotionUpdateInterval = 0.017 motionManager.startDeviceMotionUpdatesToQueue(NSOperationQueue(), withHandler: deviceDidMove) } 

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

 func deviceDidMove(motion: CMDeviceMotion?, error: NSError?) { if let motion = motion { yourCameraNode.orientation = motion.gaze(atOrientation: UIApplication.sharedApplication().statusBarOrientation) } } 

现在,您的相机应该在空间中遵循您的设备方向。