Показать сообщение отдельно
Старый 25.06.2011, 15:10   #6
YellowAfterlife
ПроЭктировщик
 
Аватар для YellowAfterlife
 
Регистрация: 19.02.2011
Сообщений: 134
Написано 81 полезных сообщений
(для 219 пользователей)
Ответ: Проекция 3D

Преобразование 3d координат точки в 2d координаты на экране.
Пример на п̶с̶е̶в̶д̶о̶к̶о̶д̶е GameMaker:

Функция задания проэкции (вызывать при смене позиции камеры):
/* argument[] - массив переданных в функцию параметров
P.S.: практически все переменные из этой функции должны быть глобальными */
/*
0..2 координаты источника камеры (откуда смотрит)
3..5 координаты цели камеры (куда смотрит)
6..8 вектор "нормали" камеры (можно просто поставить 0,0,1)
*/
/*
    p3d_set_projection(
    0   xFrom
    1   yFrom
    2   zFrom
    3   xTo
    4   yTo
    5   zTo
    6   xUp
    7   yUp
    8   zUp
    9   arc = 60
    A   view = 0
    )
*/
_sx = argument[0]
_sy = argument[1]
_sz = argument[2]
_sw = view_wview[argument[10]] /* ширина экрана */
_sh = view_hview[argument[10]] /* высота экрана */
_sa = _sw / _sh
// delta:
_dx = argument[3] - _sx
_dy = argument[4] - _sy
_dz = argument[5] - _sz
// delta vector length:
_dl = sqrt(_dx * _dx + _dy * _dy + _dz * _dz)
// divide by length to get 1-long vector:
_dx /= _dl
_dy /= _dl
_dz /= _dl
// xyzUp:
_nx = argument[6]
_ny = argument[7]
_nz = argument[8]
//
_nn = _dx * _nx + _dy * _ny + _dz * _nz
// subtract from xyzUp:
_nx -= _dx * _nn
_ny -= _dy * _nn
_nz -= _dz * _nn
// xyzUp length:
_nl = sqrt(_nx * _nx + _ny * _ny + _nz * _nz)
_am = tan(argument[9] * pi / 360)
//
_nx *= _am / _nl
_ny *= _am / _nl
_nz *= _am / _nl
//
_vx = (_dz * _ny - _dy * _nz) * _sa
_vy = (_dx * _nz - _dz * _nx) * _sa
_vz = (_dy * _nx - _dx * _ny) * _sa

Преобразование координат:
/* px, py - глобальные переменные. можно заменить на возврат структуры Point {x, y }*/
/*
    p3d_vertex(offset, x, y, z)
*/
var tx, ty, tz, tl, tt, ti;
ti = argument[0]
tx = argument[1] - _sx
ty = argument[2] - _sy
tz = argument[3] - _sz
tl = tx * _dx + ty * _dy + tz * _dz
//
tx /= tl
ty /= tl
tz /= tl
//
tt = (tx * _vx + ty * _vy + tz * _vz) / sqr(_sa * tan(pi / 8))
px[ti] = (tt + 1) * _sw / 2
tt = (tx * _nx + ty * _ny + tz * _nz) / sqr(tan(pi / 8))
py[ti] = (1 - tt) * _sh / 2

Для рисования, используем вторую функцию для занесения преобразованных координат точки в массив, и потом рисуем это как-либо:
p3d_vertex(0, 0, 0, 0)
p3d_vertex(1, 256, 0, 0)
p3d_vertex(3, 0, 256, 0)
p3d_vertex(2, 256, 256, 0)
for (i = 0; i < 4; i += 1)
draw_line(px[i], py[i], px[(i + 1) mod 4], py[(i + 1) mod 4])


Отредактировано: кажется, я зря писал это сообщение и добавлял комментарии в код.
(по крайней мере я пытался помочь)
__________________

Мой сайт-блог. Игры, обновления, примеры для Haxe, JavaScript(+HTML5), GameMaker, Love2d...
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
RegIon (25.06.2011)