Переместите камеру для установки 3D сцене

Я ищу алгоритм для установки ограничительной рамке в области просмотра (в моем случае сцена DirectX). Я знаю об алгоритмах для центрирования сферы ограничения в ортогональной камере, но нуждался бы в том же для ограничительной рамки и перспективной камеры. Я не могу только изменить FOV, потому что это приложение имеет FOV как пользователя доступная для редактирования переменная, таким образом, это должно переместить камеру.

У меня есть большинство данных:

  • У меня есть векторное для камеры
  • У меня есть центральная точка ограничительной рамки
  • У меня есть взгляд - в векторе (направление, и расстояние) от камеры указывают на центр поля
  • Я спроектировал точки на плоском перпендикуляре к камере и получил коэффициенты, описывающие, сколько макс. провода X и Y / минимальные провода X и Y в или вне плоскости просмотра.

Проблемы я имею:

  • Центр ограничительной рамки находится не обязательно в центре области просмотра (то есть, это - ограничительный прямоугольник после проекции).
  • Начиная с поля зрения "скос" проекция (см. http://en.wikipedia.org/wiki/File:Perspective-foreshortening.svg) я не могу просто использовать коэффициенты в качестве масштабного коэффициента для перемещения камеры, потому что это промахнется/недостаточно поднимется по положению требуемой камеры

Как я нахожу положение камеры так, чтобы оно заполнило область просмотра как пиксель, прекрасный как возможную (исключение, являющееся, если соотношение сторон далеко от 1,0, оно только должно заполнить одну из экранной оси)?

Я попробовал некоторые другие вещи:

  • Используя сферу ограничения и Касательную, чтобы найти, что масштабный коэффициент перемещает камеру. Это не работает хорошо, потому что, это не принимает во внимание перспективную проекцию, и во-вторых сферы являются плохими ограничивающими объемами для моего использования, потому что у меня есть много плоских и длинных конфигураций.
  • Итерация вызовов к функции для получения меньшей и меньшей ошибки в положении камеры. Это работало несколько, но я могу иногда сталкиваться со странными пограничными случаями, где положение камеры промахивается слишком много и ошибочные увеличения фактора. Кроме того, при выполнении этого я не повторно центрировал основанное на модели на положении ограничительного прямоугольника. Я не мог найти твердый, устойчивый способ сделать это надежно.

Справка!

23
задан LachlanG 20 August 2010 в 02:57
поделиться

3 ответа

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

Если вы хотите рассмотреть ограничивающие сферы, одним из решений может быть

  • сначала изменить ориентацию, чтобы смотреть на центр ограничивающей сферы
  • затем переместиться достаточно назад (отрицательное направление взгляда), чтобы ограничивающая сфера поместилась во фрустум

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

У меня нет опыта работы с DirectX, но перемещение и изменение направления взгляда камеры для центрирования определенной точки должно быть простым. Самое сложное - сделать математический расчет, чтобы решить, на какое расстояние нужно переместиться, чтобы увидеть объект.

Математика

Если вы знаете граничный размер s объекта в мировых координатах (нас не интересуют пиксели или координаты камеры, поскольку они зависят от расстояния), исходя из ориентации камеры, вы можете вычислить необходимое расстояние d камеры до граничной формы, если вам известны углы x и y поля зрения a перспективной проекции.

     frustum      ------            
            ------    *****          -  
       -----          *   *          |
   -===     ) FOV a   *bounding box  | BB size s
camera -----          *   *          |
            ------    *****          -
                  ------

  |-------------------|
        distance d

Итак, математика: tan(a/2) = (s/2) / d => d = (s/2) / tan(a/2). Это даст вам расстояние, на котором камера должна быть расположена от ближайшей граничной поверхности.

34
ответ дан 29 November 2019 в 01:35
поделиться

Поскольку у вас есть ограничивающая рамка, у вас должна быть основа, описывающая ее ориентацию. Кажется, что вы хотите расположить камеру на линии, совпадающей с базисным вектором, описывающим наименьший размер коробки, а затем поверните камеру так, чтобы наибольшее измерение было горизонтальным (при условии, что у вас есть OBB, а не AABB). Это предполагает, что соотношение сторон больше 1.0; в противном случае вы захотите использовать вертикальный размер.

Что бы я сделал:

  1. Найдите наименьший размер коробки.
  2. Найдите соответствующий базисный вектор.
  3. Масштабируйте базисный вектор на расстояние от центра прямоугольника, в котором должна находиться камера. Это расстояние равно boxWidth / (2 * tan (horizontalFov / 2)) . Обратите внимание, что boxWidth - это ширина наибольшего измерения бокса.
  4. Поместите камеру в boxCenter + scaledBasis , глядя на boxCenter .
  5. При необходимости поверните камеру, чтобы выровнять вертикальный вектор камеры с соответствующим базисным вектором коробки.

Редактировать:

Итак, я думаю, вы имеете в виду, что камера находится в произвольной позиции и куда-то смотрит, а AABB находится в другой позиции.Не перемещая камеру к стороне коробки, вы хотите:

  • Посмотрите в центр рамки
  • Переместите камеру по вектору взгляда так, чтобы коробка занимала максимальное пространство на экране

В этом случае у вас будет немного больше работы; вот что я предлагаю:

  1. Поверните камеру, чтобы посмотреть на центр ограничивающей рамки.
  2. Спроецируйте все точки рамки в пространство экрана и найдите ограничивающую рамку минимума / максимума в пространстве экрана (она у вас уже есть).
  3. Теперь Отмените проецирование двух противоположных углов ограничивающей рамки экранного пространства в мировое пространство. Для значения Z используйте ближайшие точки мирового пространства вашего AABB к камере.
  4. Это должно дать вам самолет мирового пространства, обращенный к камере, расположенный в точке на AABB, которая находится ближе всего к камере.
  5. Теперь используйте наш существующий метод боковой ориентации, чтобы переместить камеру в нужное место, рассматривая эту плоскость как сторону вашего бокса.
6
ответ дан 29 November 2019 в 01:35
поделиться

Сейчас у меня ее нет под рукой, но книга, которая вам нужна - http://www.amazon.com/Jim-Blinns-Corner-Graphics-Pipeline/dp/1558603875/ref=ntt_at_ep_dpi_1

У него есть целая глава об этом

1
ответ дан 29 November 2019 в 01:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: