2011-12-03 72 views
0

我正在製作類似增強現實應用程序的東西,其中我有一個OpenGL場景,無論iOS設備如何移動,我都想保持與重力保持一致。我認爲我已經用CMDeviceMotion.attitude.pitch設置好了,直到我發現iPhone傾向於與這個數字混淆。所以我從pARk *例子中拿了一些代碼,現在我正試圖隔離圍繞垂直訪問的旋轉。我正在繪製的場景不關心用戶面對的是哪個標題,這些數字將始終與觀看者相距一定距離。我認爲,當我計算出垂直軸旋轉分量時,我可以將其旋轉並將其從旋轉矩陣中乘以,以便在用戶更改標題時保持OpenGL數字不變。從CoreMotion的態度旋轉中分離並移除水平旋轉Matrix0

這裏是我的代碼:

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]); 

    } 

我然後使用rotMatrix像往常一樣在OpenGL。

想法,建議?提前致謝。 * pARk示例代碼在實際空間中設置幾個點,計算出用戶的位置和這些點的相對方向,並在屏幕上繪製它們,以便看起來漂浮在指向它們位置的地平​​線上。

回答

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)); 
} 

然而,這失控的時候,手機是接近垂直。所以我還在尋找。

+0

我想你應該使用attitude.rotationMatrix而不是處理roll/pitch/yaw。使用rotationMatrix,您不會遇到「接近垂直」位置的問題。 –

+1

attitude.rotationMatrix是我原來問題的第三行。如果您可以建議如何以不同方式使用它,請在完整答案中完成,我會嘗試。 – Craig

3

我只是圍繞Z軸旋轉方向取決於設備的屏幕方向。這是不是最漂亮的,但它似乎做的正是我需要的,而不去歐拉和背部(因此,避免了gymbal鎖問題)

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); 
} 
+0

@克雷格,你試過這個答案嗎?這似乎與您在不使用旋轉矩陣的情況下嘗試手動完成的操作類似。我會認爲這會更好。 –

2

下面是一些代碼來闡明如何使用的態度。 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;