2017-02-04 10 views
2

私はVuforiaでレンダリングされたSCNSceneのカメラ位置を計算します。しかし、オブジェクトはマーカーに固定されているのではなく、動くときに飛び回っています。シーン内の立方体は正書法でしか表示されませんが、デバイスをどのように左右に動かしても見えません。Vuforia GLマトリックスからカメラ位置を計算するには?

カメラの位置はすべてのフレームで計算されます。カメラを見つめているとき

// Get model view matrix 
Vuforia::Matrix44F modelViewMatrix = Vuforia::Tool::convertPose2GLMatrix(result->getPose()); 

// Convert to extrinsic matrix 
SCNMatrix4 extrinsic = [self SCNMatrix4FromVuforiaMatrix44: modelViewMatrix]; 
SCNMatrix4 inverted = SCNMatrix4Invert(extrinsic); 

// Set new position of SCNCamera 
cameraNode.transform = inverted; 

カメラ射影行列が計算されます。私はここで間違って

// Get device camera calibration  
const Vuforia::CameraCalibration& cameraCalibration = Vuforia::CameraDevice::getInstance().getCameraCalibration(); 
projectionGLMatrix = Vuforia::Tool::getProjectionGL(cameraCalibration, 2.0f, 5000.0f); 

// Convert matrix 
GLKMatrix4 glkMatrix; 

for(int i=0; i<16; i++) { 
    glkMatrix.m[i] = projectionGLMatrix.data[i]; 
} 

// Convert matrix 
SCNMatrix4 projectionTransform = SCNMatrix4FromGLKMatrix4(glkMatrix); 
cameraNode.camera.projectionTransform = projectionTransform; 

何をしているのですか?

更新1

射影行列は、現在のカメラの起動時に、次のように計算される:

const Vuforia::CameraCalibration& cameraCalibration = Vuforia::CameraDevice::getInstance().getCameraCalibration(); 
Vuforia::Matrix44F vuforiaMatrix = Vuforia::Tool::getProjectionGL(cameraCalibration, 2.0f, 5000.0f); 
matrix_float4x4 simdMatrix = simdMatrixWithVuforiaMatrix44F(vuforiaMatrix); 
cameraNode.camera.projectionTransform = SCNMatrix4FromMat4(simdMatrix); 

カメラ位置がフレーム毎に更新され:移動させることにより

Vuforia::Matrix44F modelViewMatrix = Vuforia::Tool::convertPose2GLMatrix(result->getPose()); 
matrix_float4x4 simdMatrix = simdMatrixWithVuforiaMatrix44F(modelViewMatrix); 
cameraNode.transform = SCNMatrix4FromMat4(simdMatrix); 

NSLog(@"camera position: x%lf, y%lf, z%lf, rotation: x%lf, y%lf, z%lf", _cameraNode.position.x, _cameraNode.position.y, _cameraNode.position.z, _cameraNode.rotation.x, _cameraNode.rotation.y, _cameraNode.rotation.z); 

カメラの位置(左グラフ)と回転(右グラフ)の記録を観察すると、軸は次のようになります: enter image description here

回転軸は位置軸とは異なります。また、残りの軸(以下のグラフではタイトルなし)を中心とした回転は、0.999付近に浮かぶcameraNode.rotation.x値に影響しません。

ここで何が間違っていますか?

答えて

2

あなたは古典的な体験をしています。解決するために多くの試行錯誤が必要な「私はマトリックスに何か問題がありました」という動作です。私はまたあなたがVuforiaのウェブサイト上のものを読んでいると思う。これはほとんど役に立たない。 :)

行列を並べ替えるのはおそらく間違っているところです。 SCNMatrixは、OpenGLと直接互換性があると考えられています。私は実際にすべてをsimd::matrix4x4に入れて、SCNMatrix4FromMat4に組み込まれたものをSCNMatrixに変換して使用します。

SceneKitは空間変換を、座標表すために行列を使用して順番に3次元空間における物体の位置を合わせ、回転又は 配向、およびスケールを表すことができる 。 SceneKitの行列構造は行優先順序になっているので、 マトリックスパラメータを受け入れるシェーダプログラムまたはOpenGL APIに渡すのに、 が適しています。だから、

、まとめるために...私はあなたが削除する必要があります信じる:SCNMatrixGLMatrixのコピーについては

SCNMatrix4 inverted = SCNMatrix4Invert(extrinsic); 

を、それをしようとせず、正しいはずです。メソッドを使用して生成された投影行列の結果を比較してください。それらは同一でなければなりません。

投射行列

私はこのような投影行列を取得しています:

const Vuforia::Matrix44F projectionMatrix = Vuforia::Tool::getProjectionGL(cameraCalibration, nearPlane, farPlane); 
simdMatrixWithVuforiaMatrix44F(projectionMatrix); 

私はsimd::matrix4x4(私はC++で多くの時間を費やす - 陸)に行列を変換するだけですAppleはSceneKitがサポートしている構造体を定義しました。

バックビューコントローラで
#include <simd/simd.h> 

matrix_float4x4 simdMatrixWithVuforiaMatrix44F(const Vuforia::Matrix44F &matrix) 
{ 
    vector_float4 col0 = { matrix.data[0], matrix.data[1], matrix.data[2], matrix.data[3] }; 
    vector_float4 col1 = { matrix.data[4], matrix.data[5], matrix.data[6], matrix.data[7] }; 
    vector_float4 col2 = { matrix.data[8], matrix.data[9], matrix.data[10], matrix.data[11] }; 
    vector_float4 col3 = { matrix.data[12], matrix.data[13], matrix.data[14], matrix.data[15] }; 

    return matrix_from_columns(col0, col1, col2, col3); 
} 

let extrinsic = SCNMatrix4FromMat4(projectionMatrix) 
_cameraNode?.camera?.projectionTransform = extrinsic 

Framemarkerは、私が実際に識別子の両方が含まれており、ポーズをFramemarkerをオブジェクトと呼ばれてきたが、そのポーズがちょうど同じsimd::matrix4x4としてある

を提起します投影行列

for framemarker in framemarkers { 
     switch framemarker.identifier { 
     case 337: 
      let pose = SCNMatrix4FromMat4(framemarker.pose) 
      _firstNode?.transform = pose 
      break 
     case 357: 
      let pose = SCNMatrix4FromMat4(framemarker.pose) 
      _secondNode?.transform = pose 
      break 
     default: 
      break 
     } 
} 
+0

ありがとうございます。カメラのx、y、zの位置は、あなたの方法と同じです。しかし、私は同じ問題を抱えている、私はデバイスを移動するときにオブジェクトがパーカーにとどまっていない。デバイスを右(+ x)​​に動かすと、レンダリングされたオブジェクトは画面上の左に移動しません。ここでは、それをより良く説明するビデオがあります:https://dl.dropboxusercontent.com/u/71604584/vuforia_1.m4v – Manuel

+0

私は 'renderFrameVuforia'でカメラの投影行列を更新するだけで、他のノードは変換しないシーンのそれが理由だろうか? Btw。私はSCNRendererを使用しています。 – Manuel

+1

投影行列は開始時に一度更新されます。その後、リフレッシュ/コールバックごとにオブジェクトを表すノードのポーズを更新する必要があります。 –

関連する問題