相关疑难解决方法(0)

SceneKit - 映射物理360度旋转

我很难将设备运动(传感器融合)映射到SceneKit节点旋转.问题的前提如下,

我有球体,并且相机定位在球体内部,使得球体的几何中心和相机节点的中心重合.我想要实现的是当我围绕一个点物理旋转时,运动也需要准确地映射到相机上.

实施细节如下:

我有一个节点,一个球体作为几何,并且是一个子节点.我正在使用传感器融合来获得姿态四元数,然后将它们转换为欧拉角.代码是:

- (SCNVector3)eulerAnglesFromCMQuaternion:(CMQuaternion) {
    GLKQuaternion gq1 =  GLKQuaternionMakeWithAngleAndAxis(GLKMathDegreesToRadians(90), 1, 0, 0);
    GLKQuaternion gq2 =  GLKQuaternionMake(q.x, q.y, q.z, q.w);
    GLKQuaternion qp  =  GLKQuaternionMultiply(gq1, gq2);
    CMQuaternion rq =   {.x = qp.x, .y = qp.y, .z = qp.z, .w = qp.w};
    CGFloat roll = atan2(-rq.x*rq.z - rq.w*rq.y, .5 - rq.y*rq.y - rq.z*rq.z);
    CGFloat pitch = asin(-2*(rq.y*rq.z + rq.w*rq.x));
    CGFloat yaw = atan2(rq.x*rq.y - rq.w*rq.z, .5 - rq.x*rq.x - rq.z*rq.z);
    return SCNVector3Make(roll, pitch, yaw);
}
Run Code Online (Sandbox Code Playgroud)

转换方程式来自 3D Math Primer for Graphics …

objective-c quaternions euler-angles core-motion scenekit

18
推荐指数
2
解决办法
5922
查看次数

如何避免在Core Motion控制的SceneKit相机中滚动?

我正在CMDeviceMotion使用本答案中描述的CMDeviceMotion扩展将SceneKit相机设置为当前姿态:

func deviceDidMove(motion: CMDeviceMotion?, error: NSError?) {
    if let motion = motion {
        let orientation = motion.gaze(atOrientation: UIApplication.sharedApplication().statusBarOrientation)
        cameraNode.orientation = orientation
    }
}
Run Code Online (Sandbox Code Playgroud)

这很漂亮,但是,我想阻止旋转(滚动)并且只允许相机转动(偏转)和俯仰.

我试图将四元数转换回欧拉角,并将roll保持为0:

cameraNode.eulerAngles = SCNVector3(
            x: orientation.pitch(),
            y: orientation.yaw(),
            z: 0)
Run Code Online (Sandbox Code Playgroud)

然而,这仅适用于偏航运动的一半.另一半,相机倒置.我怀疑这是涉及欧拉角的万向节锁定问题.

四元数对我来说有点像黑魔法,但是有没有办法直接在四元数上去除滚动分量,这样我就可以避免欧拉角?

camera quaternions ios core-motion scenekit

6
推荐指数
0
解决办法
669
查看次数