首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >6 6DoF中实现滚动的几个问题

6 6DoF中实现滚动的几个问题
EN

Stack Overflow用户
提问于 2015-07-25 16:01:26
回答 1查看 138关注 0票数 0

我使用的相机有偏航,音高和滚动。当偏航== 0摄像机向下看-z轴时(偏航== 90为正x),当俯仰== 270摄像机正向上看时(俯仰== 0是直视的),当滚动== 180时相机是倒转的。

相机的偏航、俯仰和滚动值从不小于零或大于360 (当任何值接近0或360时,当它通过该值时,就会自动移到“另一边”)。

我已经实现了3 3DoF,它运行得很好;但是,当我实现6 3DoF时,所有东西似乎都正常工作,直到滚动到90或270左右,然后向上和右向量都会出现奇怪的事情(前向似乎总是工作,因为滚动围绕着那个轴旋转?)

我呈现的场景只是一堆块(在我的风格的块中),我总是能够向前/向后移动,并且使用前向向量来瞄准一个块,所以我知道前向向量已经完成了。

这是我的initGL:

代码语言:javascript
复制
public void initGL() {
    GL11.glEnable(GL11.GL_TEXTURE_2D);
    GL11.glShadeModel(GL11.GL_SMOOTH);
    GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    GL11.glClearDepth(1.0);
    GL11.glEnable(GL11.GL_DEPTH_TEST);
    GL11.glDepthFunc(GL11.GL_LEQUAL);

    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glLoadIdentity();

    GLU.gluPerspective(fov, ((float) Display.getWidth()) / ((float) Display.getHeight() != 0 ? Display.getHeight() : 1), 0.1f, 100.0f);//fov is 45.0f

    GL11.glMatrixMode(GL11.GL_MODELVIEW);
    GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
}

这里是我旋转并转换到相机视图的地方:

代码语言:javascript
复制
public final void lookThrough() {
    GL11.glRotatef(this.roll, 0.0f, 0.0f, 1.0f);
    GL11.glRotatef(this.pitch, 1.0f, 0.0f, 0.0f);
    GL11.glRotatef(this.yaw, 0.0f, 1.0f, 0.0f);
    GL11.glTranslatef(-this.position.x, -this.position.y, -this.position.z);
}

下面是我的六自由度计算:

代码语言:javascript
复制
public static final double  zeroRad         = Math.toRadians(0);
public static final double  ninetyRad       = Math.toRadians(90);
public static final double  oneEightyRad    = Math.toRadians(180);
public static final double  twoSeventyRad   = Math.toRadians(270);

public static final strictfp void updateLookVectorsIn6DoF(Vector3f yawPitchAndRoll, Vector3f forward, Vector3f up, Vector3f right) {
    final double yaw = Math.toRadians(yawPitchAndRoll.getX());
    final double pitch = Math.toRadians(yawPitchAndRoll.getY());
    final double roll = Math.toRadians(yawPitchAndRoll.getZ());

    final float sinYaw = ((float) Math.sin(yaw));
    final float cosYaw = ((float) Math.cos(yaw));

    final float sinYaw90 = ((float) Math.sin(yaw + ninetyRad));
    //final float sinYaw180 = ((float) Math.sin(yaw + oneEightyRad));
    final float cosYaw270 = ((float) Math.cos(yaw - ninetyRad));

    final float sinRoll = ((float) Math.sin(roll));
    final float cosRoll = ((float) Math.cos(roll));
    //final float sinRoll180 = ((float) Math.sin(roll + oneEightyRad));

    final float cosPitch90 = ((float) Math.cos(pitch + ninetyRad));
    //final float cosPitch270 = ((float) Math.cos(pitch + twoSeventyRad));
    final float sinPitch90 = ((float) Math.sin(pitch + ninetyRad));
    final float sinPitch270 = ((float) Math.sin(pitch - ninetyRad));

    //Forward:(No roll because roll goes around the Z axis and forward movement is in that axis.)
    float x = sinYaw * ((float) Math.cos(pitch));
    float y = -((float) Math.sin(pitch));
    float z = cosYaw * ((float) Math.cos(pitch - oneEightyRad));
    forward.set(x, y, z);

    //cos(90) = 0, cos(180) = -1, cos(270) = 0, cos(0) = 1
    //sin(90) = 1, sin(180) = 0, sin(270) = -1, sin(0) = 0

    //Up: Strange things occur when roll is near 90 or 270 and yaw is near 0 or 180
    x = -(sinYaw * cosPitch90) * cosRoll - (sinRoll * sinYaw90);
    y = -sinPitch270 * cosRoll;
    z = (cosYaw * cosPitch90) * cosRoll + (sinRoll * cosYaw270);
    up.set(x, y, z);
    //Right: Strange things occur when roll is near 90 or 270 and pitch is near 90 or 270
    x = (cosRoll * sinYaw90) - (sinRoll * (sinYaw * cosPitch90));
    y = 0 - (sinRoll * sinPitch90);//This axis works fine
    z = (cosRoll * cosYaw270) + (sinRoll * (sinYaw * cosPitch90));
    right.set(x, y, z);
}

我在这里确实找到了一个非常类似的问题,但它使用矩阵和四元数,我不想这样做,除非我绝对必须这样做(而且我非常小心地尝试以正确的顺序乘以滚动俯仰和偏航):LWJGL - Problems implementing 'roll' in a 6DOF Camera using quaternions and a translation matrix

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-26 02:41:05

所以,我终于明白了“因为”和“罪恶”的含义(但别让我教它),我才能做到这一点!

下面是新的和改进的代码:

代码语言:javascript
复制
public static final double  zeroRad         = Math.toRadians(0);
public static final double  ninetyRad       = Math.toRadians(90);
public static final double  oneEightyRad    = Math.toRadians(180);
public static final double  twoSeventyRad   = Math.toRadians(270);

public static final strictfp void updateLookVectorsIn6DoF(Vector3f yawPitchAndRoll, Vector3f forward, Vector3f up, Vector3f right) {
    final double yaw = Math.toRadians(yawPitchAndRoll.getX());
    final double pitch = Math.toRadians(yawPitchAndRoll.getY());
    final double roll = Math.toRadians(yawPitchAndRoll.getZ());

    final float sinYaw = ((float) Math.sin(yaw));
    final float cosYaw = ((float) Math.cos(yaw));

    final float sinYaw90 = ((float) Math.sin(yaw + ninetyRad));
    final float sinYaw270 = ((float) Math.sin(yaw - ninetyRad));//+ twoSeventyRad));
    final float cosYaw90 = ((float) Math.cos(yaw + ninetyRad));
    final float cosYaw180 = ((float) Math.cos(yaw + oneEightyRad));
    final float cosYaw270 = ((float) Math.cos(yaw - ninetyRad));//+ twoSeventyRad));

    final float sinRoll = ((float) Math.sin(roll));
    final float cosRoll = ((float) Math.cos(roll));
    final float cosRoll180 = ((float) Math.cos(roll + oneEightyRad));

    final float cosPitch90 = ((float) Math.cos(pitch + ninetyRad));
    final float sinPitch90 = ((float) Math.sin(pitch + ninetyRad));
    final float sinPitch270 = ((float) Math.sin(pitch - ninetyRad));

    //Forward:(No roll because roll goes around the Z axis and forward movement is in that axis.)
    float x = sinYaw * ((float) Math.cos(pitch));
    float y = -((float) Math.sin(pitch));
    float z = cosYaw * ((float) Math.cos(pitch - oneEightyRad));
    forward.set(x, y, z);

    //Multiply in this order: roll, pitch, yaw
    //cos(90) = 0, cos(180) = -1, cos(270) = 0, cos(0) = 1
    //sin(90) = 1, sin(180) = 0, sin(270) = -1, sin(0) = 0

    //hmm... gimbal lock, eh? No!

    //Up://
    x = (cosRoll180 * cosPitch90 * sinYaw) - (sinRoll * cosYaw180);
    y = -sinPitch270 * cosRoll;
    z = (cosRoll * cosPitch90 * cosYaw) + (sinRoll * sinYaw);
    up.set(x, y, z);
    //Right:
    x = (cosRoll * sinYaw90) - (sinRoll * cosPitch90 * cosYaw90);
    y = 0 - (sinRoll * sinPitch90);//This axis works fine
    z = (cosRoll * cosYaw270) + (sinRoll * cosPitch90 * sinYaw270);
    right.set(x, y, z);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31628390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档