【问题标题】:Switching device axes in rotation matrix for OpenGL ES2 model rotation在 OpenGL ES2 模型旋转的旋转矩阵中切换设备轴
【发布时间】:2013-10-10 11:51:11
【问题描述】:

我正在尝试旋转位于我的 OpenGL 世界的 (X,Y,Z)=(0,0,0) 的模型(地形)。 +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 更改我的旋转矩阵的列/行 -> 没有帮助

【问题讨论】:

    标签: android opengl-es matrix rotation sensormanager


    【解决方案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);
      ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多