ios - 从 CoreMotion 的姿态旋转矩阵中分离并移除水平旋转

标签 ios opengl-es augmented-reality core-motion glkit

我正在制作类似增强现实应用程序的东西,其中我有一个 OpenGL 场景,无论 iOS 设备如何移动,我都希望它与重力保持一致。我以为我已经通过 CMDeviceMotion.attitude.pitch 设置好了,直到我发现将 iPhone 侧向倾斜会弄乱这个数字。所以我从 pARk* 示例中提取了一些代码,现在我正试图隔离垂直访问周围的旋转。我正在绘制的场景不关心用户面对的是哪个标题,图形将始终绘制在距观察者一定距离的位置。我认为,当我计算出垂直轴旋转分量时,我可以将其反转并将其与旋转矩阵相乘,这样当用户改变航向时保持 OpenGL 数字静止。

这是我的代码:

CMDeviceMotion *d = motionManager.deviceMotion;
if (d != nil) {

    CMRotationMatrix r = d.attitude.rotationMatrix;
    transformFromCMRotationMatrix(cameraTransform, &r);


    mat4f_t projectionCameraTransform;
    multiplyMatrixAndMatrix(projectionCameraTransform, projectionTransform, cameraTransform);

    GLKMatrix4 rotMatrix = GLKMatrix4Make(projectionCameraTransform[0], 
                                          projectionCameraTransform[1], 
                                          projectionCameraTransform[2], 
                                          projectionCameraTransform[3], 
                                          projectionCameraTransform[4], 
                                          projectionCameraTransform[5], 
                                          projectionCameraTransform[6], 
                                          projectionCameraTransform[7], 
                                          projectionCameraTransform[8], 
                                          projectionCameraTransform[9], 
                                          projectionCameraTransform[10], 
                                          projectionCameraTransform[11], 
                                          projectionCameraTransform[12], 
                                          projectionCameraTransform[13], 
                                          projectionCameraTransform[14], 
                                          projectionCameraTransform[15]);

    }

然后我像往常一样在 OpenGL 中使用 rotMatrix。

想法、建议?提前致谢。

*pARk 示例代码在真实空间中设置了几个点,计算出用户的位置和这些点的相对方向,并将它们绘制在屏幕上,使它们看起来漂浮在地平线上指向它们的位置。

最佳答案

我只是根据设备屏幕方向围绕 Z 轴旋转方向。这不是最漂亮的,但它似乎完全符合我的需要,没有去欧拉和返回(因此,避免了体操锁定问题)

GLKMatrix4 deviceMotionAttitudeMatrix;
if (_cmMotionmanager.deviceMotionActive) {
    CMDeviceMotion *deviceMotion = _cmMotionmanager.deviceMotion;

    // Correct for the rotation matrix not including the screen orientation:
    // TODO: Let the device notify me when the orientation changes instead of querying on each update.
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
    float deviceOrientationRadians = 0.0f;
    if (orientation == UIDeviceOrientationLandscapeLeft) {
        deviceOrientationRadians = M_PI_2;
    }
    if (orientation == UIDeviceOrientationLandscapeRight) {
        deviceOrientationRadians = -M_PI_2;
    }
    if (orientation == UIDeviceOrientationPortraitUpsideDown) {
        deviceOrientationRadians = M_PI;
    }
    GLKMatrix4 baseRotation = GLKMatrix4MakeRotation(deviceOrientationRadians, 0.0f, 0.0f, 1.0f);

    CMRotationMatrix a = deviceMotion.attitude.rotationMatrix;
    deviceMotionAttitudeMatrix
        = GLKMatrix4Make(a.m11, a.m21, a.m31, 0.0f,
                         a.m12, a.m22, a.m32, 0.0f,
                         a.m13, a.m23, a.m33, 0.0f,
                         0.0f, 0.0f, 0.0f, 1.0f);
    deviceMotionAttitudeMatrix = GLKMatrix4Multiply(baseRotation, deviceMotionAttitudeMatrix);
}
else
{
    // Look straight forward (we're probably in the simulator, or a device without a gyro)
    deviceMotionAttitudeMatrix = GLKMatrix4MakeRotation(-M_PI_2, 1.0f, 0.0f, 0.0f);
}

关于ios - 从 CoreMotion 的姿态旋转矩阵中分离并移除水平旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8364664/

相关文章:

computer-vision - ARCore或ARKit如何产生实时视频的实时增强?

ios - 共享扩展以打开包含的应用程序

ios - 在 MKMapView 上同步 COCOS2D 层

swift - 立体 ARSCNview 使 VR 和 AR 混合

ios - 使用 ARKit 显示 DAE 文件并跟踪场景中的 anchor

javascript - Threejs着色器实现

ios - 如何将光标移动到 Swift 中 UITextField 的开头?

ios - Alamofire http 请求到本地网络服务器

ios - 制作带有图像背景缩放到 iphone 大小的 UI 按钮

opengl - 如何仅在特定矩形区域内更改纹理中的纹素?