Управление орбитой заставляет сцену исчезнуть через некоторое время - PullRequest
0 голосов
/ 30 ноября 2018

Я использую 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 голосов
/ 30 ноября 2018

Идея, которую я изначально придумал, заключалась в удалении камеры от ее точки фокусировки при каждом повороте (в некоторой точке за дальней плоскостью).Решение этой проблемы заключается в реализации средств управления орбитой с использованием полярной системы координат.Таким образом, в вашем 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));
}
...