Подтвердить что ты не робот

Как проверить, находится ли объект перед камерой?

У меня есть несколько деревьев, которые сильно отстают от игры, поэтому я хотел бы проверить, находятся ли деревья перед камерой или нет. A swaggy picture

Я получил некоторую помощь от Математического форума, а также посмотрел Эта ссылка на помогите мне преобразовать шаг/рыскание в нужный вектор направления.

Но по какой-то причине, всякий раз, когда я перемещаю камеру влево, деревья становятся видимыми, и всякий раз, когда я перемещаю ее вправо, они становятся невидимыми (поэтому, если камера указывает на +1 на оси Z, кажется, для рендеринга деревьев, но -1 на оси Z и, похоже, их не отображать). GIF of trees being dumb (См. http://i.gyazo.com/cdd05dc3f5dbdc07577c6e41fab3a549 для менее прыгающего .mp4)

Я использую следующий код, чтобы проверить, находится ли объект перед камерой или нет:

Ship you = shipsID.get(UID);
int dis = 300;
Vector3f X = new Vector3f(camera.x(), camera.y(), camera.z());
float x = (float) (Math.cos(Math.toRadians(camera.yaw()))*Math.cos(Math.toRadians(camera.pitch())));
float y = (float) (Math.sin(Math.toRadians(camera.yaw()))*Math.cos(Math.toRadians(camera.pitch())));
float z = (float) Math.sin(Math.toRadians(camera.pitch()));
Vector3f V = new Vector3f(x, y, z);

for (Tree tree : trees){
    Vector3f Y = new Vector3f(tree.location.x, tree.location.y, tree.location.z);
    Vector3f YMinusX = Y.negate(X);//new Vector3f(Y.x - X.x, Y.y - X.y, Y.z - X.z);
    float dot = Vector3f.dot(YMinusX, V);
    if (dot > 0){
        tree.render();
    }
}

Кто-нибудь может сказать мне, что я сделал здесь неправильно? Я не могу разобраться, если это математика.. Или код.. Или что?

Код перевода камеры:

 public void applyTranslations() {
    glPushAttrib(GL_TRANSFORM_BIT);
    glMatrixMode(GL_MODELVIEW);
    glRotatef(pitch, 1, 0, 0);
    glRotatef(yaw, 0, 1, 0);
    lastYaw = yaw;
    glRotatef(roll, 0, 0, 1);
    glTranslatef(-x, -y, -z);
    glPopAttrib();
}

UPDATE:

Кажется, что камера смотрит. Например, если я смотрю на -Z, ничего не происходит, но если я смотрю на + Z, они все визуализуют. if (dot > 0) code кажется как-то + Z, а не + TheCameraRotation.

4b9b3361

Ответ 1

Вращения вашей камеры вращаются вокруг Y, подразумевая, что Y - ваш вектор вверх. Однако float z = (float) Math.sin(Math.toRadians(camera.pitch())); дает Z для вашего вектора вверх. Существует несогласованность. Я бы начал с обмена y и Z здесь, а затем распечатал все из каждого кадра, чтобы вы могли видеть, что происходит при повороте камеры. Также выведите только одно дерево и напечатайте dot. Например. вы можете быстро заметить приближение числа 1.0 только тогда, когда вы посмотрите на 90 градусов слева от дерева, что сужает проблему. Как отмечает @DWilches, замена cos/sin изменит фазу вращения, что приведет к такому эффекту.

Вы можете подумать о том, чтобы ограничить точечный продукт в поле зрения камеры. Есть еще проблемы в том, что деревья - это не только точки. Лучше всего было бы проверить ограничивающие прямоугольники дерева против усечения камеры, как предлагает @glampert.

Тем не менее геометрия дерева не выглядит такой сложной. Оптимизация мудрая, я бы начал пытаться сделать их быстрее. Вы используете VBOs? Возможно, посмотрите методы, чтобы уменьшить призывы к призыву, такие как instancing. Возможно, даже используйте несколько моделей для LOD или рекламных щитов. Идя еще дальше, рекламные щиты с несколькими деревьями на них. Методы отбраковки окклюзии можно использовать для игнорирования деревьев за горами.

[EDIT]
Поскольку ваши деревья расположены примерно на плоскости, вы можете ограничить проблему рысканием камеры:

float angleToTree = Math.atan2(tree.location.z - camera.z(), tree.location.x - camera.x());
float angleDiff = angleToTree - camera.yaw();
if (angleDiff > Math.PI)
    angleDiff -= 2.0f * Math.PI;
if (angleDiff < -Math.PI)
    angleDiff += 2.0f * Math.PI;
if (abs(angleDiff) < cameraFOV + 0.1f) //bias as trees are not points
    tree.render();

Ответ 2

Не могли бы вы написать его вот так.

    Ship you = shipsID.get(UID);
    int dis = 300;
    Vector3f X = new Vector3f(camera.x(), camera.y(), camera.z());
    float x = (float) (Math.cos(Math.toRadians(camera.yaw()))*Math.cos(Math.toRadians(camera.pitch())));
    float y = (float) (Math.sin(Math.toRadians(camera.yaw()))*Math.cos(Math.toRadians(camera.pitch())));
    float z = (float) Math.sin(Math.toRadians(camera.pitch()));
    Vector3f V = new Vector3f(x, y, z);

    for (Tree tree : trees){
        Vector3f Y = new Vector3f(tree.location.x, tree.location.y, tree.location.z);
        Vector3f YMinusX = Y.negate(X);//new Vector3f(Y.x - X.x, Y.y - X.y, Y.z - X.z);
        float dot = Vector3f.dot(YMinusX, V);
        if (dot > 0){
            tree.render();
        }
    }

Как вы можете видеть, для каждого дерева выполняется гораздо меньше вычислений.

Ответ 3

Для чего я вижу здесь, правильные формулы:

x = Math.sin(pitch) * Math.cos(yaw);
y = Math.sin(pitch) * Math.sin(yaw);
z = Math.cos(pitch);

Не могли бы вы их попробовать?