сделать 3D матрицу конуса прожектора - PullRequest
0 голосов
/ 29 марта 2010

Как создать матрицу преобразования (4x4), которая преобразует цилиндр (высотой 1 и диаметром 1) в конус, который представляет мой прожектор (положение, направление и угол отсечки)?

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

- edit2 -
Следующий (псевдо) код дает мне ожидаемый результат:

PushMatrix();
LoadIdentity();
Perspective(lightCutoffAngle * 2, 1, 0.001, 10000); // fov, aspect, near, far
LookAt(lightPos.x,lightPos.y,lightPos.z, lightDir.x,lightDir.y,lightDir.z, 0,0,1);
Matrix44 mat = GetModelViewMatrix();
mat.Invert();
PopMatrix();
MultMatrix(mat);
DrawCone(1,1); // diameter, height

Е.И.В.

Ответы [ 2 ]

1 голос
/ 29 марта 2010

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

Я думаю, что вы можете построить матрицу подобным образом, создав матрицу «взглянуть» (gluLookAt или D3DXMatrxiLookAtLH) и умножив ее на матрицу перспективы (gluPerspective или D3DXMatrixPerspectiveFovLH), но я серьезно сомневаюсь, что вы сможете визуализировать этот цилиндр с помощью OpenGL или D3D. Это связано с тем, что для работы проекции 3D-рендеринг использует 4-й векторный компонент - W, который рассчитывается умножением векторов на матрицу проекции. Компонент W обычно скрыт и доступен только через шейдеры. Перемешивание с этим компонентом обычно портит любую геометрию, и вы не можете превратить цилиндр в конус, не используя компонент w. То есть если вы преобразуете цилиндр в конус, вам придется использовать W, это приведет к нарушению проекции.

Предлагаю построить цилиндр нормально - из вершин. Это не сложно как в D3D, так и в OpenGL.

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

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

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

О углу среза света.

Учитывая точку P, положение света L и направление света LDir, а также угол отсечки, вы можете легко проверить, находится ли P в пределах светового конуса. Для этого вам понадобится косинус либо полного, либо половины угла отсечки (зависит от того, рассчитывается ли угол отсечки относительно направления света или определяет ширину конуса). Сделайте вектор PDir = P - L, нормализуйте PDir и вычислите скалярное произведение между нормализованным PDir и нормализованным LDir, это даст косинус угла между направлением света в точке P. Если косинус (между PDir и Ldir) больше косинуса светового конуса, тогда точка находится внутри светового конуса.

0 голосов
/ 29 марта 2010

Я верю, что вы хотите матрицу что-то вроде

x/y 0   0  0
 0  y   0  0
 0  0  z/y 0
 0  0   0  1

или, возможно,

x(1-y) 0   0    0
  0    1   0    0
  0    0 z(1-y) 0
  0    0   0    1

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

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

UPDATE

Как указано в комментариях, это хотят работать. Я думаю, что наполовину прыгнул пистолет. Если вы замените x ans z на 1, умножьте матрицу на ваш вектор. вы получите что-то вроде

x = x/y  or x(1-y)
y =  y
z = z/y  or z(1-y)

UPDATE

Чтобы учесть угол света, мы масштабируем радиус нашего конуса, но оставим его единицу длины. если у нас есть угол света L (который находится от его центральной точки, а не от края до края), мы можем сказать, что радиус нашего конуса должен быть tan ^ -1 (L)

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

x = tan^-1(L) * [ x/y  or x(1-y) ]
y =  y
z = tan^-1(L) * [ z/y  or z(1-y) ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...