1

私は拡張現実アプリのようなものを作っています。このアプリでは、iOSデバイスがどのように動いても重力との整合性を保ちたいOpenGLシーンがあります。iPhoneを横に傾けるとその番号が台無しになるのを発見するまで、CMDeviceMotion.attitude.pitchでうまく設定できたと思いました。そこで、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サンプルコードは、実空間にいくつかのポイントを設定し、ユーザーの位置とそれらのポイントの相対的な方向を計算して画面上に描画し、その位置を指す地平線に浮かんでいるように見せます。

4

3 に答える 3

3

デバイス画面の向きに応じて、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);
}
于 2013-03-17T03:44:14.577 に答える
2

これは、attitude.rotationMatrixの使用方法を明確にするためのコードです。

// initial model view matrix
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -5.f);

// convert CMRotationMatrix to GLKMatrix4
CMRotationMatrix r = motion.attitude.rotationMatrix;
GLKMatrix4 = GLKMatrix4Make(r.m11, r.m21, r.m31, 0.0f,
                            r.m12, r.m22, r.m32, 0.0f,
                            r.m13, r.m23, r.m33, 0.0f,
                             0.0f,  0.0f,  0.0f, 1.0f);

// apply motion rotation matrix
modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, _motionRotationMatrix);

// apply matrix to effect
self.effect.transform.modelviewMatrix = modelViewMatrix;
于 2014-04-09T15:33:41.647 に答える
0

私はこの答えからいくつかのヒントを取り、解決策を考え出しました:

https://stackoverflow.com/questions/5328848/simulating-an-image-floating-effect-using-coremotion-devicemotion-on-the-iphone/5442962#5442962

if (d != nil) {

    GLKMatrix4 rotMatrix = GLKMatrix4MakeRotation(0, 0, 1, 0);
    float pitch = d.attitude.pitch;

    if (d.gravity.z > 0)
        pitch = -pitch;

    rotMatrix = GLKMatrix4Rotate(rotMatrix, pitch, -1, 0, 0);
    rotMatrix = GLKMatrix4Rotate(rotMatrix, d.attitude.roll, 0, -1, 0);
    rotMatrix = GLKMatrix4Rotate(rotMatrix, d.attitude.yaw, 0, 0, -1);
    rotMatrix = GLKMatrix4Multiply(rotMatrix, GLKMatrix4MakeRotation(M_PI/2, 1, 0, 0));
}

しかし、電話がほぼ垂直になっているときのこの干し草。だから私はまだ探しています。

于 2011-12-03T03:03:16.643 に答える