【问题标题】:Orbit controls make scene disappear after a while轨道控制使场景在一段时间后消失
【发布时间】:2018-11-29 23:36:13
【问题描述】:

我正在使用 JOGL 构建点云查看器,并且我已经实现了自己的轨道控制。它在一段时间内工作得很好,但在某些时候(我认为在左右拖动鼠标非常快速之后)场景完全消失了。这是我的代码:

public void mouseDragged(MouseEvent e) {
    if (oldX < 0.0005 && oldY < 0.0005) {
        // when the mouse drag starts initially           

        oldX = e.getX();
        oldY = e.getY();
    } else {
        float differenceX = e.getX() - oldX;
        float differenceY = e.getY() - oldY;

        oldX = e.getX();
        oldY = e.getY();

        float speedX = differenceX / 2;
        float speedY = differenceY / 2;

        Vector3f velocityX = new Vector3f();
        Vector3f velocityY = new Vector3f();

        Vector3f oldTarget = camera.getTarget();
        Vector3f cameraRight = new Vector3f();

        // getting right vector of the camera in the world space

        camera.getDirection().cross(camera.getWorldUp(), cameraRight);

        /* moving the camera first along its right vector
         * then setting its target to what it was originally
         * looking at */

        cameraRight.mul(-speedX, velocityX);
        camera.translate(velocityX);
        camera.setTarget(oldTarget);

        /* moving the camera second along its up vector
         * then setting its target to what it was originally
         * looking at */

        camera.getUp().mul(-speedY, velocityY);
        camera.translate(velocityY);
        camera.setTarget(oldTarget);
    }
}

我一开始以为是因为当相机方向向量和世界向上向量相同时,相机右向量(两者之间的叉积)为零,但这仅意味着控件失去了一个运动尺寸;这不应导致整个场景消失。

【问题讨论】:

  • 每次更新时,您都会将相机远离目标。也许,你的场景只是被推到了 zfar 平面之外?
  • 经过进一步测试,我意识到这就是问题所在。这对于正交相机并不明显,因为它具有无限的视野,但使用透视相机我可以看到它立即缩小。一旦我找到一个解决方案(也许使用极坐标?),我会提供另一种解决方案。
  • 是的,极坐标是一个不错的选择。只需更新极坐标并从中重建相机位置。

标签: java opengl graphics camera scene


【解决方案1】:

我最初提出的想法是在每次旋转时(在远平面之外的某个点)将相机与其焦点保持距离。解决这个问题的方法是使用极坐标系来实现轨道控制。因此,在您的 mouseDragged() 方法中:

if (oldX < 0.0005 && oldY < 0.0005) {
    oldX = e.getX();
    oldY = e.getY();
} else {
    float differenceX = e.getX() - oldX;
    float differenceY = e.getY() - oldY;

    oldX = e.getX();
    oldY = e.getY();

    // getting the current position of the camera in the spherical coordinate system

    Vector3f sphericalCoords = MathUtils.toSphericalCoords(camera.getPosition());

    float speedY = (float)Math.toRadians(differenceY / 4.0f);
    float speedX = (float)Math.toRadians(differenceX / 4.0f);

    // adding speedY to the theta angle and speedX to the phi angle

    sphericalCoords.add(new Vector3f(0, speedY, speedX));

    // making sure the angles are not outside the [0, 2 * PI] interval

    polarCoords.y = MathUtils.wrapTo2Pi(sphericalCoords.y);
    polarCoords.z = MathUtils.wrapTo2Pi(sphericalCoords.z);

    // updating the position of the camera

    camera.setPosition(MathUtils.toCartesianCoords(sphericalCoords));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-08
    • 2012-04-10
    • 1970-01-01
    相关资源
    最近更新 更多