【问题标题】:Android OpenGL rotation matrix deformationAndroid OpenGL 旋转矩阵变形
【发布时间】:2013-02-18 08:55:17
【问题描述】:

在我的渲染器中,我有:

private float[] MATRIX_VIEW = new float[16];
private float[] MATRIX_PROJECTION = new float[16];
private float[] MATRIX_VP = new float[16];

在“onSurfaceChanged”中:

...
//Set projection
Matrix.orthoM(
  MATRIX_PROJECTION,0,
  -hDim,hDim,
  -vDim,vDim,
  1,100
);
//Set View
Matrix.setLookAtM(
  MATRIX_VIEW,0,
  cameraPosition[0],
  cameraPosition[1],
  cameraPosition[2],
  cameraFacing[0],
  cameraFacing[1],
  cameraFacing[2],
  cameraHook[0],
  cameraHook[1],
  cameraHOOK[2]
);
//SetView*Projection
Matrix.multiplyMM(
  MATRIX_VP,0,
  MATRIX_PROJECTION,0,
  MATRIX_VIEW,0
);
...

我有许多相同形状的克隆, 所以我写了“ShapeSet_Set”类:

...    
private float[] MATRIX_ORIGIN = new float[16];
private float[] MATRIX_VPO = new float[16];

private float[] MATRIX_SCALE = new float[16];
...

/*
origin matrix is group of all shapes center position
scale matrix represents zoom
*/

和“ShapeSet_Element”:

...    
private float[] MATRIX_POSITION = new float[16];
private float[] MATRIX_ROTATION = new float[16];

private float[] MATRIX_ALL = new float[16];
...

/*
position matrix is position of shape relative to origin position
rotation matrix is shape rotation arond its center
all matrix is matrix which will be passed to shader
*/

在渲染器的“DrawFrame”上,ShapeSet_Set 的“onDrawFrame”被调用。 它计算 View*Projection*Origin 矩阵:

...
Matrix.multiplyMM(
  MATRIX_VPO,0,
  RENDERER.getVPMatrix(),0,
  MATRIX_ORIGIN,0
);
...

并调用每个 ShapeSet_Element 的“onDrawFrame”,其中包含:

...
//Get View*Projection*Origin matrix
System.arraycopy(
  SET.getVPOMatrix(),0,
  MATRIX_ALL,0,
  16
);
//Apply zoom
Matrix.multiplyMM(
  MATRIX_ALL,0,
  MATRIX_ALL,0,
  SET.getScaleMatrix(),0
);
//Apply element's position
Matrix.multiplyMM(
  MATRIX_ALL,0,
  MATRIX_ALL,0,
  MATRIX_POSITION,0
);
//Apply element's rotation
Matrix.multiplyMM(
  MATRIX_ALL,0,
  MATRIX_ALL,0,
  MATRIX_ROTATION,0
);
...

一切正常,直到我应用旋转。 这是设置元素旋转的方法:

public void setRotation(float xDeg,float yDeg,float zDeg)
{
  //Set new rotation values to open up actual values
  rotation_X = xDeg;
  rotation_Y = yDeg;
  rotation_Z = zDeg;
  //Set new rotation matrix
  Matrix.setIdentityM(MATRIX_ROTATION,0);
  //Rotate around x axis
  Matrix.rotateM(
    MATRIX_ROTATION,0,
    rotation_X,0,
    1,0,0
  );
  //Rotate around y axis
  Matrix.rotateM(
    MATRIX_ROTATION,0,
    -rotation_Y,0,
    0,1,0
  );
  //Rotate around z axis
  Matrix.rotateM(
    MATRIX_ROTATION,0,
    rotation_Z,0,
    0,0,-1
  );
}

当元素围绕 x 或 y 轴旋转时,它可以正常工作,但是... 当围绕 z 轴旋转时,元素的高度(原始 y 维度)在几何上减小 旋转 90 度时最大为 0,旋转 180 度时放大到原始值。

有谁知道,这是什么原因造成的?

如果这是通过错误的矩阵乘法或错误的旋转矩阵设置完成的,我无法解决。

【问题讨论】:

  • 在处理涉及多轴的旋转时最好使用四元数。还可以防止云台锁定。
  • 你能说得具体点吗,我现在对这个方法一无所知。
  • 我试过四元数。围绕 x 和 y 轴的旋转工作正常,但 z 轴变形仍然存在。
  • 围绕 z 轴的旋转会变形,即使我只围绕它旋转形状。有谁知道,什么可能导致绕z轴旋转变形?

标签: android opengl-es matrix rotation


【解决方案1】:

可以避免像这样http://tutorialrandom.blogspot.com/2012/08/how-to-rotate-in-3d-using-opengl-proper.html这样没有四元数的云台锁定

听起来你的模型视图矩阵中的某些东西出了问题,尝试像上面链接中那样进行旋转,它可能会解决你的问题

【讨论】:

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