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

StackOverflow https://stackoverflow.com/questions/203787

Вопрос

У меня есть объект, обращенный в определенном направлении с (например) полем зрения 45 градусов и ограниченным диапазоном обзора.Я выполнил все начальные проверки (узел квадрата и расстояние), но теперь мне нужно проверить, находится ли конкретный объект в пределах этого конуса обзора (в данном случае, чтобы решить следовать за этим объектом только в том случае, если мы можем его видеть).

Помимо отбрасывания луча для каждого градуса из Direction - (FieldOfView / 2) Для Direction + (FieldOfView / 2) (Я делаю это в данный момент, и это ужасно), каков наилучший способ выполнить эту проверку видимости?

Это было полезно?

Решение

Вычислите угол между направлением вашего взгляда (понимаемым как вектор) и вектором, который начинается у вас и заканчивается у объекта.Если он попадает в раздел fieldOfView /2, вы можете просмотреть объект.

Этот угол равен:

arccos(scalarProduct(viewDirection, (object - you)) / (norm(viewDirection)*norm(object - you))).

Другие советы

Я работал в индустрии видеоигр и могу сказать, что выполнение тригонометрических функций, таких как arccos, в каждом кадре далеко не идеально.Вместо этого вы предварительно вычисляете косинус угла для конуса:

float cos_angle = cos(PI/4); // 45 degrees, for example

Затем в каждом кадре вы можете быстро проверить, попадает ли точка внутрь этого конуса, сравнив это с точечным произведением конуса и .

vector test_point_vector = normalize(test_point_loc - cone_origin);
float dot_product = dot(normalized_cone_vector, text_point_vector);
bool inside_code = dot_product > cos_angle;

Здесь нет тригонометрических функций, только некоторое умножение, деление и сложение.Большинство игровых движков имеют оптимизированную функцию normalize() для векторов.

Это работает из-за этого уравнения:

A · B = |A| * |B| * cos(Θ)

Если вы нормализуете векторы (A -> An), уравнение упрощается:

An · Bn = cos(Θ)

Получите угол между вектором направления наблюдателя и вектором от наблюдателя к цели.Если этот угол меньше (fieldOfView/2), то цель находится в поле зрения наблюдателя.

Если ваши векторы являются 2d или 3d, это будет работать таким же образом.(В 3D, если у вас вид усеченного конуса вместо конуса, вам нужно будет разделить углы на две составляющие.) Вам просто нужно найти угол между двумя векторами.

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

Если вы работаете в 3D и можете определить диапазон просмотра как усеченную точку, то вы можете использовать что-то похожее на это Отбраковка Фрустрации техника.

Хорошие ответы уже есть, но я просто хотел дать вам ссылку на блог Wolfire, недавно они запустили серию статей по алгебре, в которых в качестве одного из примеров используется уравнение "поля зрения". Иди и прочти это, он хорошо написан и прост.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top