Как я могу проверить, может ли один игровой объект видеть другой? - PullRequest
9 голосов
/ 15 октября 2008

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

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

Ответы [ 5 ]

10 голосов
/ 31 октября 2008

Я работал в индустрии видеоигр и могу сказать, что выполнение триггерных функций, таких как 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(Θ)
9 голосов
/ 15 октября 2008

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

Этот угол:

arccos(scalarProduct(viewDirection, (object - you)) / (norm(viewDirection)*norm(object - you))).
3 голосов
/ 15 октября 2008

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

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

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

2 голосов
/ 15 октября 2008

Если вы делаете 3D и можете определить диапазон просмотра как усеченный, тогда вы можете использовать что-то похожее на эту Frustrum Culling технику.

1 голос
/ 04 июля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...