Проверка пересечения / столкновения ограничивающего прямоугольника с усечением вида - PullRequest
2 голосов
/ 18 марта 2011

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

Ответы [ 2 ]

3 голосов
/ 21 марта 2011

Я выяснил, что построение модели пространства мира и проверка на наличие столкновений с bbox с ней было неправильным способом.

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

Вот код:

vertexMatrix = matrix([vertex.x,vertex.y,vertex.z,1]) 
productMatrix = (vertexMatrix * camMatrix)
pVectSS = vector(prodMatrix[0][0],prodMatrix[0][1],prodMatrix[0][2])

pointX = ((pVectSS.x/(-pVectSS.z))/tan(radians(hFOV/2)))/2.0+.5
pointY = ((pVectSS.y/(-pVectSS.z))/tan(radians(vFOV/2)))/2.0+.5

ключ:

 camMatrix = camera inverse world-space matrix
 pVectSS = position vector screen-space
 hFOV = horizontal field of view
 vFOV = vertical field of view
2 голосов
/ 21 марта 2011

Это будет работать.Тем не менее, обычно лучше выделить плоскости усеченного конуса и рассчитать расстояния до них.Вы сказали, что «скорость не имеет большого значения», но в конце концов вы можете обнаружить, что это так.В конце концов, мы делаем выборку усеченного контура, чтобы ускорить процесс.

Умножение вершины на матрицу требует эквивалента четырехточечных произведений, поэтому вам необходим эквивалент 32-точечных произведений, чтобы проверить все 8 углов.Для вычисления расстояния от точки до плоскости требуется скалярное произведение и сложение, что несколько более эффективно в худшем случае и намного более эффективно в среднем (поскольку вы часто можете выбросить объект после отсечения после одной или двух плоскостей,и не более трех).Существует ряд оптимизаций для плоскостей отсечения, использующих временную когерентность, которые я не буду вдаваться в более глубокие детали.

Кроме того, вы можете заранее выполнить грубую выборку, рассчитав расстояние от центральной точки до плоскости ипроверьте, больше ли это, чем радиус ограничительной рамки.Это отбраковывает объекты, которые явно "в" или "из" очень дешево.Или, в качестве альтернативы, вы можете сравнить точечное произведение вектора вашего вида с косинусом значения вашего поля зрения плюс некоторую «подстановку» (или, альтернативно, просто посмотрите, является ли она положительной) в качестве первой очень грубой проверки.Как вы помните, скалярное произведение двух векторов говорит вам, сколько они указывают в одном направлении.То, что имеет отрицательный точечный продукт с вектором вашего взгляда, безусловно, можно безопасно отбросить, потому что оно позади вас.

...