Переключение осей устройства в матрице вращения для вращения модели OpenGL ES2

Я пытаюсь повернуть модель (территорию), расположенную в (X,Y,Z)=(0,0,0) моего OpenGL-мира. +X — восток, -Z — север, +Y — высота. Вид смотрит на -Y, потому что углы Эйлера устройства равны (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 почти во всех возможных созвездиях -> не помогает
  • Изменение столбцов/строк моей матрицы вращения с SensorManager.getRotationMatrix -> не помогает

person Peter K.    schedule 10.10.2013    source источник


Ответы (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);
  ...
}
person Peter K.    schedule 10.10.2013