轨道控制会使场景在一段时间后消失

时间:2018-11-29 23:36:14

标签: java opengl graphics camera scene

我正在使用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);
    }
}

我首先想到这是因为,当摄像机方向向量和世界向上向量相同时,摄像机右向量(两者之间的叉积)将为零,但这仅意味着控件丢失了一个机芯尺寸;这不会导致整个场景消失。

1 个答案:

答案 0 :(得分:0)

我最初提出的想法是,随着每次旋转(在远平面之外的某个点),照相机与聚焦点之间要保持一定距离。解决该问题的方法是使用极坐标系实现轨道控制。因此,在您的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));
}