使用滚动OpenGL ES在场景周围旋转相机

问题描述

我正在尝试通过触摸(滚动)在场景中旋转相机:

public class SurfaceView extends GLSurfaceView 
        implements GestureDetector.OnGestureListener {
    SceneRenderer renderer;        

    @Override
    public boolean onScroll(MotionEvent e1,MotionEvent e2,float distanceX,float distanceY) {
        renderer.setMotion(distanceX,distanceY); // pass movement to render
        return true;
    }    
}

相机在渲染中的移动如下:

public class SceneRenderer implements GLSurfaceView.Renderer {
    private float[] viewMatrix = new float[16];
    
    @Override
    public void onSurfaceCreated(GL10 gl,EGLConfig config) {
        Matrix.setLookAtM(viewMatrix,0f,3f,1.0f,0.0f);
    }

    ...
    // movement of camera
    public synchronized void setMotion(float xDistance,float yDistance) {
        Matrix.rotateM(viewMatrix,-xDistance * 0.1f,1,0);
        Matrix.rotateM(viewMatrix,-yDistance * 0.1f,0);
    }
}

起初效果很好。但是,然后相机开始旋转不正常。如何使用滚动使相机相对于场景(对象)的中心正确移动?也许有人解决了类似的问题?

谢谢您的任何回答/评论!

解决方法:

  private float kx = 0f;
  private float ky = 0f;
  private float radius = 3.0f;
  private float x,y,z = 0f;

  ...
  public synchronized void setMotion(float xDistance,float yDistance) {
      kx = kx + xDistance * 0.001f;
      x = (float) (radius * Math.sin(kx));
      z = (float) (radius * Math.cos(kx));

      ky = ky + yDistance * 0.001f;
      y = (float) (radius * Math.sin(ky));

      Matrix.setLookAtM(viewMatrix,x,-y,z,0.0f);
  }

但是,通过这种方法,摄像机沿Y轴旋转时会离开场景。

解决方法

在矩阵代数中,顺序很重要。由于增量旋转交错矩阵和中断顺序,因此无法按预期工作。因此,您需要在每次setMotion()调用时基于累积增量x / y重建视图矩阵,以便始终按以下正确顺序应用旋转。

target_link_libraries

附录:仅通过setLookAtM构成视图矩阵

只有使用setLookAtM肯定可以实现相同的目标。要使视点保持恒定距离,请在spherical coordinates中移动视点。并且也要调整向上方向。

public class SceneRenderer implements GLSurfaceView.Renderer {
    private float[] viewMatrix = new float[16];
    private float cumulativeX = 0.0f;
    private float cumulativeY = 0.0f;

    @Override
    public void onSurfaceCreated(GL10 gl,EGLConfig config) {
        Matrix.setLookAtM(viewMatrix,0f,3f,1.0f,0.0f);
        cumulativeX = 0.0f;
        cumulativeY = 0.0f;
    }

    ...
    // movement of camera
    public synchronized void setMotion(float xDistance,float yDistance) {

        cumulativeX += xDistance;
        cumulativeY += yDistance;

        Matrix.setLookAtM(viewMatrix,0.0f);

        //Matrix.rotateM(viewMatrix,-cumulativeX * 0.1f,1,0);
        //Matrix.rotateM(viewMatrix,-cumulativeY * 0.1f,0);

        Matrix.rotateM(viewMatrix,0);
        Matrix.rotateM(viewMatrix,0);
    }
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...