1

(X,Y,Z)=(0,0,0)OpenGL-World にあるモデル (地形) を回転させようとしています。+Xは東、-Z北、+Y高度です。-Yデバイスのオイラー角は(0°,0°,0°)、デバイスが北を向いたテーブルの上に置かれている間であるため、ビューが見ています。

問題:

device -y測定角度をに変更するには、デバイスの軸を切り替える必要がありdevice zます。

現在、device x-axis作品を中心に回転しています(結果は を中心に回転していますWorld X-axis)。

しかし、回転は の代わりに回転にdevice yつながり、回転はWorld Yの代わりに回転World -Zにつながります。device zWorld ZWorld Y

今では、これを解決する方法のアイデアが不足しています。ヒントを教えてくれる人はいますか?

    (OpenGL)                         (Device)

   ^ +Y-axis                       ^ +z-axis                                  
   *                               *                                 
   *                               *                                 
   *                               *    ^ +y-axis (North)               
   *                               *   *                               
   *                               *  *                                
   *                               * *                                 
   ************> + X-axis          ************> +x-axis                      
  *                                                                   
 *                                                                    
v +Z-axis (Minus North)    

私がこれまでに試したこと:

  • オイラー角の使用SensorManager.getOrientationと角度の切り替えはうまく機能しますが、ピッチ 90 度近くでジンバル ロックに入ります。だから私は別の解決策(SensorManager回転行列または四元数)を探しています。
  • SensorManager.remapCoordinateSystemほとんどすべての可能な星座で -> 役に立たない
  • 回転行列の列/行をSensorManager.getRotationMatrix-> から変更しても役に立たない
4

1 に答える 1

1

さて、四元数を使用した非常に簡単な解決策を見つけました。軸は最後に切り替えられています。

以下も参照してください。

現在、90 度を超えるピッチ角を有効にする方法をまだ考えています (ポートレート モード)。何か案は?

アクティビティ:

private SensorManager sensorManager;
private Sensor rotationSensor;

public void onCreate(Bundle savedInstanceState) {
  ...
  rotationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
  ...
}

// Register/unregister SensorManager Listener at onResume()/onPause() !

public void onSensorChanged(SensorEvent event) {

  if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
    // Set rotation vector
    MyRenderer.setOrientationVector(event.values);
  }

}

マイレンダラー:

float[] orientationVector = new float[3];

public void setOrientationVector (float[] vector) {

  // Rotation vector to quaternion
  float[] quat = new float[4];
  SensorManager.getQuaternionFromVector(quat, vector);
  // Switch quaternion from [w,x,y,z] to [x,y,z,w]
  float[] switchedQuat = new float[] {quat[1], quat[2], quat[3], quat[0]};

  // Quaternion to rotation matrix
  float[] rotationMatrix = new float[16];
  SensorManager.getRotationMatrixFromVector(rotationMatrix, switchedQuat);

  // Rotation matrix to orientation vector
  SensorManager.getOrientation(rotationMatrix, orientationVector);

}

public void onDrawFrame(GL10 unused) {
  ...
  // Rotate model matrix (note the axes beeing switched!)
  Matrix.rotateM(modelMatrix, 0,
    (float) (orientationVector[1] * 180/Math.PI), 1, 0, 0);

  Matrix.rotateM(modelMatrix, 0,
    (float) (orientationVector[0] * 180/Math.PI), 0, 1, 0);

  Matrix.rotateM(modelMatrix, 0,
    (float) (orientationVector[2] * 180/Math.PI), 0, 0, 1);
  ...
}
于 2013-10-10T15:58:57.690 に答える