在旋转矩阵中切换设备轴,用于OpenGL ES2模型旋转

时间:2013-10-10 11:51:12

标签: android opengl-es matrix rotation sensormanager

我正在尝试旋转位于我的OpenGL-World (X,Y,Z)=(0,0,0)的模型(地形)。 +X为东,-Z为北,+Y为高度。 View正在查看-Y,因为设备的Euler角度为(0°,0°,0°),而设备位于指向北方的桌子上。

问题

我需要切换设备的轴以将测量的角度device -y更改为device z

目前围绕device x-axis的轮播工作(导致围绕World X-axis轮换)。

但围绕device y进行轮换导致围绕World Y而不是World -Z旋转,并围绕device z旋转,以围绕World Z而不是World 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 - >没有帮助
  • 更改我的旋转矩阵的cols / rows SensorManager.getRotationMatrix - >没有帮助

1 个答案:

答案 0 :(得分: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);
  }

}

<强> MyRenderer:

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