>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Doomoidní techniky
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Začneme Wolfem ... kdo z vás ho nikdy neviděl ? Ze nikdo ? No tak to
půjde snadno. Jak si osobně vzpomínám, Wolf byl takovej svět
složenej z kvádrů a neměl ani strop ani podlahu (myslim). Když ale
nejste obyčejní pařani, který koukaj kde by koho sundali,
sestřelili, zavraždili (vrrrr ... kdo dá se mnou Dooma ?), všimnete
si, že se systémem mapování textur uvedeným výše na tuhle gamesu
prostě nemáte (rychlostně)... Kde je rozdíl ? No v tom, že ta
předešlá pracuje s polygonem definovaným dvěma vektory, kdežto
taková nevinná zeď ve Wolfovi je spíš lichoběžník :
A takle vypadaj zdi ve Wlkovi
Už je to vidět ?
Takže musíme "vymyslet" jinou metodu. Výhoda zdi je ta, že má dvě
strany paralelní.
A to prostě nejde toho nezneužít. Ale jak ?
Dost napoví další obrázek :
Nějakej Karel nebo co
Celý fígl je v tom, že si vydělíme X-velikost textury velikostí
max_x (= a), uděláme smyčku, v níž půjdeme od bodu s nejmenším X do
bodu s největším X. No a potom nenásleduje nic jiného, než pro každé
X najít body y1 a y2 , odečíst je od sebe (větší od menšího) a
vydělit to Y-velikostí textury (=b). Následuje další smyčka, a to od
y1 do y2. Každé y mezi těmito dvěmi vynásobíme číslem b, a každé x
číslem a. Získáme tak odpovídající souřadnice tohoto pixelu v
textuře.
Kód by moh vypadat takhle :
...
zjisti minimální x (=minx) ;
zjisti maximální x (=maxx) ;
deltaX = maxx - minx ;
def_koef_X = X_velikost_textury / deltaX ;
for I = 0 to deltaX do
{
pro J spočítej Y1 a Y2 // viz poznámka
deltaY = (Y2 - Y1 ) ;
def_koef_Y =Y_velikost_textury / deltaY ;
for J = 0 to deltaY do
{
oriY = J * def_koef_Y ;
oriX = I * def_koef_X ;
putpixel ( I+minx , J+miny , textura[oriY,oriX] );
// předpokládám, že textura je dvourozměrné pole
}
}
Poznámka :
Možná není úplně jasné, jak vypočítat ty proklaté body y1 a y2 ...
Vysvětlení je jednoduché : Každá přímka má svojí obecnou rovnici
(tzn. něco ve tvaru ax + by + c = 0, kde čísla a,b jsou souřadnice
normálového vektoru na tuto přímku. Parametr c lze vypočítat tak, že
do rovnice dosadíme nějaký bod ležící na přímce (já nevim, třeba
jeden z vrcholů polygonu)). Jakmile máme rovnici kompletní,
zůstávejí jen dvě neznámé - x a y . Ale nám tam zbyde jen jedna,
neboť X známe. Můžu jí zkusit napsat : mějme přímku, která vede z
bodu [x1,y1] do bodu [x2,y2]. Potřebujeme pro jakýkoliv X-bod
vypočítat Y souřadnici :
obecná rovince:
ax + bx + c = 0
směrový vektor přímky:
(x2-x1, y2-y1)
normálový vektor:
(y2-y1, x1-x2)
a tedy:
(y2-y1)*x + (x1-x2)*y + C = 0
dosadíme třeba bod 1 (můžeme klidně i bod 2):
C = - (y2-y1)* x1 - (x1-x2) * y1
no a dostaneme:
(y2-y1)*x + (x1-x2)*y - (y2-y1)*x1 - (x1-x2)*y1 = 0
redukce:
(y2-y1)*(x-x1) + (x1-x2)*(y-y1) = 0
a vypočtem Ypsilon :
(y2-y1)*(x-x1)
Y = --------------------- + Y1
(x1-x2)
Myslím, že by to nemělo dělat problémy.
No a pokud si dobře vzpomínám (jako že jo), tak v Doomu už byly i
podlahy a stropy. Co že je na nich tak těžkého ? Vůbec nic. Je to
jenom obdoba zdi s tím, že je o 90 stupňů otočená. Takže se akorát
"jede" po Y souřadnicích a počítaj se iXový. That's all.
Ještě poznámka :
výše uvedený algoritmus není optimalizován ; dalo by se tak udělat
vyhozením pár věcí před cyklus a nahradit násobení permanentním
přičítáním. Když to "řácky" vyšperkujete, dostanete slušně rychlý
algoritmus ... a Doom III. může být váš ...
výheň