Ütközésvizsgálat 3d-s virtuális
környezetben,
AABB -vel
A mai háromdimenziós játékok mindegyikének alapvető eleme az,
hogy a benne lévő karakterek mozgása hasonló törvényeket kövessen, mint a
valóságban, például nem megy át a falakon, nem esik át a padlón, felmegy a
lépcsőn, vagy lecsúszik egy meredek
leejtőn.
Ez - saját tapasztalatom szerint - elég kemény dió tud lenni annak aki még nem
csinált azelőtt ilyet. A neten elég sokféle megközelítést lehet találni
(angolul), milliószám vannak a topikok, melyek általában ugyanazokat a
kérdéseket teszik fel, elég kevés sikerrel. Érdekes dolog, hogy manapság ezrével
érkeznek az olyan játékok a piacra, amelyek nemcsak egyszerű elmozdulásokat, de
komplett fizikai szimulációkat is képesek megvalósítani (lásd Havok), de a
módszerek nyilvános dokumentálása elég hiányos (szerintem) - aki nem így
gondolja, azt irigylem.
Lehetséges források lehetnek a nyílt forráskódú programok, mint pl a quake
sorozat, ami letölthető, de eléggé specifikus és nehezen érthető,
agyonoptimalizált - kommententezések nélkül. Tény, hogy abból a szempontból
hasznosak, hogy bevált dolgokról van szó, össze lehet legózni belőlük ezt-azt. A
másik nagy kútfő, amiből merigélhetünk esetleg, a robotikában ismert 'motion-planning'
fogalomkörhöz köthető, azaz robotok mozgásának tervezése, például egy
autógyárban - mondani se kell, magyarul itt se sokat lehet olvasni, de ez van.
A másik dolog, hogy egy kis gammát is megírni, ha mindent egy embernek kell
kitalálni, szintén rengeteg idő, még akkor is, ha sok minden készen van. A
legviccesebb az egészben az, hogy ha senki nem tesz fel doksikat, akkor
mindenkinek mindent legelőről kell kezdeni, és így a világ nem fejlődik sehova,
így is egyre hosszabb idő egy jó játékot megírni, pl hl2 volt vagy 6 év. Mondjuk
azt nagyon megértem, hogy a profik nem foglalkoznak azzal, hogy anyagokat
gyártsanak a netre, meg példaprogikat írosgassanak, amikor határidő van, meg
minden, úgyhogy ez az egész az amatőrökre hárul, mint amilyen szerénységem -
amíg nem lesz valami.
Na ennyi elég elöljáróban, ezen írás arra fókuszál milyen
problémákkal kell szembenéznie annak, aki ütközésvizsgálatra adja a fejét (ja,
beveri a fejét -kiszámoljuk merre pattanjon ;). A
test ami az ütközésekben részt vesz, egy ún. 'AABB' - axis-aligned-bounding-box
- egy olyan téglatest, aminek minden éle egy koordinátatengellyel párhuzamos.
Azaz itt nem lesz szó arról, hogy mi lenne, ha ez a test még forogna is egy
pont körül - az jóval bonyolultabb.
A lényeg, hogy amíg valaki a síkokkal, vektorokkal, ezek elemi műveleteivel
nincs köszönőviszonyban, addig nem sok mindent fog érteni ebben a témában - nem
sok mindent kell amúgy hozzá tudni, a net tele van oktatóanyagokkal -
magyar is sok van szerencsére, egyetemek honlapjain is minden algoritmus leírása
fellelhető, ami csak ide kellhet. Ezzel csak azt mondom, hogy nem mennék bele
abba, hogy hogyan számoljuk két vektor bezárt szögét, meg ilyenek.
Elméletileg csak annyi a feladat, hogy A-ból B-be el tud-e mozdulni, ha nem
akkor minek ütközik neki, és ott mi történik, hova jut el. Gyakorlatilag jóval
több minden történhet, de nézzük előröl:
Bemenő adatok:
Tehát adott egy téglatest - áltatában egy négyzet alapú hasáb - melynek van 3
oldalhossza (x,y,z), és egy pozíciója, ami egy 3d-s vektor. Így hat adattal le
lehet írni egy kiinduló állapotot, ehhez kell még, hogy hova szeretne
elmozdulni, ez még egy vektor.
Meddig tud elmozdulni:
Amíg nem ér hozzá valamihez, ez nyilvánvaló. Aki ismeri a Sutherland-Hodge
poligon-vágó algoritmust, annak most egy fokkal jobb, mivel ennek
megállapításához az szükséges. Ezzel a módszerrel gyorsan lehet egy tetszőleges,
síkkal elvágni egy konvex poligont, és ezt több síkra alkalmazva
egyértelműen megmondható, egy síkokkal
határolt konvex térrészben van-e a poligonból valami, s ekkor
nekiment.
Igen ám, de ha csak az aabb 6 síkjával nézzük meg -mondjuk- a végpontban,
akkor -főleg nagy elmozdulások esetén- kihagyhatunk egy-két (sok) poligont, ami
azt jelentené, hogy pl. átmegy egy falon. Ez a jelenség az alagúthatás:
Ennek egyik megoldása a komplexebb szimulációkban használt
'tapogatós-módszer', ami azt jelenti, hogy pici lépésenként az aabb-t tolva
mindig megnézi, ütközik-e, és ha igen akkor ott meg kell állni, esetleg
visszafele is lépkedni. Ez elég időrabló
tud lenni, rengeteg ellenőrzéssel járna. Itt jön be a 'sepert test'
fogalma. Ez annyi csupán, hogy a mozgatni kívánt testet meg kell nyújtani a
mozgással párhuzamosan, és ebbe térbe ami poligon csak beleesik, annak biztos
nekimegy:
Például ezen a képen a pirossal jelölt poligon zöld része esik
bele a képzett térrészbe.
Tehát annak a vizsgálata, hogy nekimegy-e valaminek, elég
egyszerű. Annak a megállapítása, hogy hol van az a pont, ameddig elmehet, hogy
ne olvadjon egybe a doboz mondjuk a fallal, de ez a lehetséges leghosszabb
mozgás legyen, már neccesebb. Ekkor nem az egész
testet kell egyszerre nézni, hanem csak az aabb megfelelő oldallapjait kell
megnyújtani, mintegy a lap négy éléből és az elmozdulásból kell képezni egy
testet.
Ez egy 6 síkból álló térrészt alakít ki (4 oldallap, plusz eleje-vége), remélem nem
baj ha eztán csak mint "cső" néven illetném - ha lehetek bátor.
Innen szerintem már kezd kirajzolódni a koncepció. Minden olyan
aabb lapot meg kell nézni, aminek normája a mozgási irány fele figyel - már ha az aabb lapjainak a normáljai kifele néznek - nekem pont befele, de mindegy, akkor
fordítva. Ekkor a pirossal jelölt polit két konvex cső is vágja, mindegyikbe az
a része kerül, aminek nekimegy az a lap, amiből a cső készült. Így megvannak azokat a pontok, amiknek konkrétan a
doboz egy oldallapja nekimegy. Már csak azt kellene megtalálni a pontok közül,
hogy melyiknek ütközik először neki. Ez egyszerű kivonásokkal meghatározható,
először minden lapnak meg kell keresni a legközelebbi pontját:
Csak ki kell vonni a lap megfelelő x,y,vagy z koordinátáját a pontok
koordinátáiból, és a legkisebb győz, annak megy neki elsőként. Ekkor megvan
laponként, a minimum. A fenti képen példaként egy függőleges lap x irányú
maximális lehetséges elmozdulásait mutatja, a kettő közül nyilván az alsó a
rövidebb - ez lesz letárolva. Most meg kell keresi, minden lap közül azt, amelyik a
legkisebb elmozdulást adja. Ezt nyilván nem lehet sima minimum
összehasonlításokkal végezni, mert minden lapnál a megengedett maximális
elmozdulás függ attól, milyen szöget zár be a mozgási vektor az adott lap
síkjának normájával. példa:
Legjobban ez az efféle 'lapos' elmozdulásoknál látható. A két lapból képzet térrészben
egy-egy pirossal jelölt poligon-darab van, és a lapokhoz húzott vékony kék
zöld szakaszok a minimum távolságok oldalanként. Jól látszik, hogy pl ha a felső poli
darab nem lenne, jóval tovább mehetne a doboz, mielőtt nekimenne az alsónak.
Pedig az alsó laptól való távolság sokkal kisebb volt, mint a függőlegesnél
(zöld hossza). A
megoldás, hogy nem a kapott abszolút távokat kell nézni, inkább a vetületek
szerint kell eldönteni melyik a legrövidebb. Konkrétan:
n - legyen az aabb lapjának normája (kifele mutat, hossza 1)
i - mozgási vektor , amennyit elmozdul
minh - a minimum távolság (vékony zöld szakasz hossza) - aabb síktól a táv
Ekkor:
max_vetulet = dotproduct(n,i); // megadja az n-re vetített maximumot - skaláris
szorzat
tav = minh / max_vetulet; // tav
0-1 ennyit mehet az i vektoron
Így minden oldalnak - csőnek - kijön egy 'tav', amelyekből a legkisebb lesz az, amelyikkel
tovább is kell foglalkozni.
Ekkor már megvan az, hogy meddig mehet a doboz:
vec_mehet = i * tav; // vagyis az új pozíciója
startpos+vec_mehet.
Ha csak az lenne a lényeg, hogy meddig mehet a test, amíg neki nem megy
valaminek, akkor készen is lenne. Az az érdekes, hogy eddig szoktak tartani az
online 'tutorial'-ok - egyesek szerint "turtorialok" -, azonban a feketeleves csak
innen kezdődik. Ha csak ennyit csinálnók meg, akkor az player nekiütközne a
falnak és megállna, nem mozdulna tovább semerre, amíg a mozgási iránya pozitív
szöget nem zárna be a fal síkjával. Ez nem annyira 'handy', mert itt a kívánt
reakció általában, hogy a mozgás nem áll meg, hanem sebessége és iránya
megváltozik.
Ezzel be is lépünk a "collision-response", azaz az ütközésre adott válasz sötét
világába.
A legnépszerűbb az szokott lenni, hogy a test elcsúszik a fal mellett, le is
lassul általában - attól függően, milyen meredek szögben érkezik.
Úgyhogy mostantól az a feladat, hogy találjon egy új (értelmes) irányt,
amerre a test tovalibbenhet.
Ennek lényege, hogy keresni kell egy síkot, melyen a doboz elcsúszik. Előbbi
példánál maradva egy falnak ütközve használhatjuk a fal síkját. Erre le kell
vetíteni a mozgási irányt, az új irány párhuzamos lesz a síkkal:
Itt az eredeti (kék) mozgás helyett a kezdő és végpontjait levetítve a talált
síkra lesz két új vektor, amiknek megfelelő különbsége megadja az új irányt,
ahhoz, hogy a fal mentén elcsússzon. Ez körülbelül az, amit a neten sok helyütt
meg lehet találni, és boldoguljon mindenki, ahogy tud.
Most akkor rajzolok párat, amikor ez nem igazán jó:
Első esetben a doboz elmozdul a zöld pontig majd a barna vektort generálja a
síkkal. Viszont nem fog tudni arra továbbhaladni, mert akkor beleakadna a
poligonba.A második esetben egy lépcső aljának függőleges falával ütközik, s
mivel a mozgási irány merőleges a síkjára, az új irányvektor (0,0,0) lesz, azaz
eben az esetben is megakad. Tehát vannak speciális esetek, amiket külön kellene
kezelni.
Csúszó-síkok generálása
1. ütközés poligon belső pontjával.
A legegyszerűbb a már felvázolt aminek-nekimegy-annak-a-síkja-kell. Ez csak
akkor működik, ha nem egy poli élével vagy sarokpntjával ütközött a test.
2. Ütközés poligon élével.
Emiatt külön ellenőrizni kell, amikor a poligonok vágása történik a
'csövekkel',hogy a kapott pontok hol helyezkednek el az eredeti poligonban.
Ha ez a pont közel van egy élhez akkor az ütközés-éllel eset létrejött. Ekkor
érdemes eltárolni ezt a poligon élt (a 2 vektorát), mert nyilvánvaló, hogy a majdan képzett síkban ez
az él benne lesz - vagyis az élen fog elcsúszni. Példaként tegyük fel, hogy az avatar (player) egy sátortetős (nem panel- ha tudja még valaki, mi az) ház
tetején áll, esetleg a gerinc is ferde, akkor ezen az élen milyen sík állítható
elő, amin továbbcsúszhat. De ez az él más esetben lehetne mondjuk oldalt is, például egy
szögletes korlát éle. Én úgy oldottam ezt meg, hogy
a. eltároltam az élt, amin a pont van (ennek iránya kell tul.)
b. megnéztem a pont mely csőbeli vágósíkhoz van a legközelebb,
kihagyva az elülső és hátoldalt. Ekkor a síkhoz tartozó 2 aabb-s vektorból és az
élből vektoriális szorzattal (magyarul crossproduct :) állítható elő a sík
normája. Lásd segédkép:
A vastag piros szakasz most nem poligon-síkot, hanem élt jelöl, még stilizálva
a földrengés sújtotta tetőt kontúrját is berajzoltam, hogy jobb legyen. A zöld
petty nyilván a talált ütközési pont, matekkönyvesen szólva: "vegyük észre",
hogy ez a legközelebbi pont mind a vízszintes, mind pedig a függőleges
oldalnak). Tehát megvan a pont, kiderül róla, hogy egy poligon élén van (itt két
poligon élén is lesz egy pont ugyanott (4 egy helyen!)- és ez általában igaz, mert egy élen 2 poligon szokott találkozni, kivéve kezdő pályatervezők esetében :). Vegyük a
fölső csövet. Mivel ez a pont az ő alsó síkjához van a legközelebb, ezért
az ahhoz megfelelő aabb oldal 2 vekorát (a barnácska nyíl a téglalapban), és az
élt alkotó 2 vektorral kiszámolható a sík normája, ugye, ami itt afféle
sötéttürkizzel tüntettem fel.
Vigyázat: ha ez az él rajtavan valamely vágósíkon, akkor nincs él ütköztetés,
sima belső pontként kezelendő !
3. Ütközés sarokpontokkal.
Azaz az aabb poligonok sarkainak megy neki -ez ugye se nem belső
pontja, sem nem éle (2 élen van rajta). Itt se nehéz a dolog, mert ekkor nem lehet mást tenni, mint
csúszó síknak használni az aabb azon oldalát, amelyikkel nekiment.
Mindegyik csőben (amiben van legközelebbi pont - lehet akár háromban cső is
egyszerre) meg kell keresni a síkokat, és ezeket állandóan egymáshoz hasonlítva
meg kell keresni a legjobbat. Példaként mutatok egy esetet, amitől majd
propellerré gyűrtem már a TFT-t:
Ez egy elég általános eset, amikor előre mozgunk bonyolultabb geometriájú
talajon, és a gravitáció is hozzáadódik. Mindkét csőben van legközelebbi
ponthalmaz, mondjuk mindkettőnek kijön, belső pont és a zölddel jelölt síkokat
dobja ki, mint lehetséges csúszási sík. Régebbi dolog: anno úgy gondoltam, ha több
sík jön ki, vetítsük le mindre külön-külön a mozgást, ez itt teljesen lenullázná
a mozgást.
Egyértelmű, hogy ki kell választani, mely sík lenne jó csúsztatni. Ránézésre
nyilvánvaló, hogy a vízszintes kellene, de hogy is lehetne eldönteni. Eddigi
legjobb ötletem az volt eddig, hogy kigyűjtöttem az összes olyan pontot a talált
síknak, ami rajta van (síktól való táv nulla -kb(!) ). Vagyis ezek
reprezentálják a síkot. Ha jön egy újabb sík, akkor meg kell nézni, hogy annak
az összes pontja (ami rajta van), hol van az előzőhöz képest. Ha az újnak minden
pontja az első mögött (vagy rajta) van, akkor az új sík eldobható, mintegy
'messzebb van' - legalábbis a pontjai - mint a másik. Ellenkező esetben
vica-versa is meg lehet nézni, és ki lehet ejteni a másikat. Ha mindkettő
megfelel, akkor igazából nem jöttem még rá, mi is van.
Lépcsők, lépcsők.
Igen, vannak lépcsők is a világon. A virtuálisban is. Az eddigi anyag
szerint, ha az aabb-be zárt főhős megérkezik egy lépcsőhöz, mi is történne?
Detektálná a lépcső legalsó fokának függőleges oldalát, mint csúszó-síkot, és
ezzel elcsúszatná balra vagy jobbra. Ez nem nyerő. Fel kellene lépnie.
Ez tehát egy külön speciális eset. Mi is egy lépcsőfok egy virtuális világban?
Egy meredek sík, de az azt alkotó poligon pontjainak maximum 'magassága' a
játékos talpától egy megadott határon belül van - mondjuk, ha a "poligon csak
térdig ér", akkor fel lehet rá lépni. Ekkor már csak azt kell megnézni,
hogy tényleg fel lehet-e lépni annyit, amekkora a lépcső magassága, vagy esetleg
van ott valami - mondjuk alacsony a plafon.
Az eljárás menete:
1. Lépcső detektálása. Csak meredek csúszó síkoknál. Ha 60 foknál
nagyobb a szög és nem negatív leejtő :
if (plane.B<0.5 && plane.B>=0)
Valamint ha a csúszó-sík az aabb x, z normájú oldalai
által képzett csövek valamelyikében keletkezett, a fel- és lefele
néző
oldalakban nem. Vagyis nem alatta van.
2. Ha kijött, hogy meg kellene próbálni fellépni, akkor meg kellene tudni
mennyivel, mert elég rosszul néz ki, ha pici
göcsörtökre is nagyokat ugrálna.
Szimplán meg kell nézni, hogy a csövekben
keletkezett legközelebbi pontok mennyivel vannak magasabban,
mint az aabb talpa,
és ezek maximuma az, amennyivel fel kell lépni.
Vigyázat: csak az x, z normájú csöveket kell nézni itt is, az
y irányúak értelmetlen (pl negatív) értékeket adnak.
Nem y irányú csöveknél is lehet negatív érték meredek
mozgási irány esetén, ekkor nem kell lépni szintén.
Nyílván kell egy maximális érték, amekkorát fel tud
lépni, ha ez a magasság kisebb, akkor jön a harmadik pont.
3.Fellépés lehetséges-e. Most jön az már említett ellenőrzés, hogy az
rendben van, hogy lépcső van előtte, de nem ütközik-e
bele valamibe, ha fel akar lépni. Ez csak annyit jelent, hogy el kell tolni az aabb-t oda ahova fel szeretne lépni
(csak y irányban érdemes mozgatni...?), és
ott bele kell vágni az összes poligont, van-e benne valami. Ha
nincs akkor
felléphet, és a mozgás folytatódhat, fontos, hogy a talált lépcső
síkra nem érdemes leképezni új irányt,
mehet a régivel. Vagy jobb
megoldás lehet egy vízszintes síkra képezni az irányt, és úgy mehet tovább,
most
már vízszintesen indulva a lépcső tetején.
Egyéb
Van még egy 'érdekes' jelenség a response háza táján, ami általam
önkényesen 'negatív dőlésszögű fal problémája' nevet kapta, elismerem, nem
elég velős, de leírja a környezetet, amiben fellép (quake II-ben volt sok ilyen
folyosó). Nevezetesen, hogy a fal a padlóval laposszöget zár be. Probléma azzal
van, hogy ez a két sík felváltva ütközik a doboznak és külön-külön sose fogják
jó irányba mozgatni.
Lásd képetske:
Legyen ez egy képzeletbeli (QII-es) folyosó, bedőlő falakkal, és a strogg irtása
közben fellép az, hogy a hős nekimegy srég a falnak. Ekkor simán megtörténik az,
hogy egyik sík a másiknak adogatja a dobozt, de egyik sem fogja kitéríteni a
folyosó hosszanti tengelye felé. Többfélével próbálkoztam, hogy elkerüljem ezt,
elsőként egyszerűen az olyan síkokat, amiknek normájának y komponense negatív,
átalakítottam függőlegessé (y=0, majd újra normálás). Ez is működhet, csak ez már a tweek-elés (buherálás) veszélyes mezejére visz, aminek mindig az a vége, hogy más bug-ok élednek
fel a fűben...
Egyszóval, nem lesz stabil. Eljárás:
a. Mindez egy elmozdulási körben történik (1 külső hívás alatt)
b. minden új csúszó-sík létrejöttekor, ha nem volt jelentős az elmozdulás
a síkot eltárolja ügyesen.
c. ha vége és még sok mozgás maradt (maradék mozgási vektor hosszú),
akkor, ha van több ilyen letárolt sík, egyszerűen
vektoriálisan kell szorozni a síkok normáját, így kijön a megfelelő irány - vagy a
negatívja, ekkor meg kell fordítani.
Ez csak akkor működik, ha 2 sík van legalább.
d. ezzel az új iránnyal újrakezdeni az egészet mozgatási hajcihőt -
mintha megint meghívtuk volna.
A kapott új irány tulajdonképpen a quake-es példát véve párhuzamos lesz a
folyosó tengelyével.
Pár szó a végére, csak levezetésképpen.
Lebegőpontos precizitás:
Ez a legfontosabb dolog, amit mindig szem előtt kell tartani. A mondás, hogy az
ördög a részletekben lakik, mintha ide lenne kitalálva. Nem is gondolná először az
ember, mennyi gonoszság rejlik az ötödik tizedes jegy után... Általánosságban el
lehet mondani, hogy soha ne használjunk ütközésvizsgálatban == <, >
relációkat csak úgy önmagukban. Az program elején meg kell határozni egy
konstanst, ami az 'elhanyagolható különbséget' jelenti a számolásokkor.
Példaként legyen itt egy makró, ami az a==b helyett van:
#define FLOAT_EQ(a,b,diff) ( ((b)-(diff))<(a) && (a)<((b)+(diff)) )
vagyis, ha a,és b különbségének abszolút értéke kisebb, mint diff
(a már említett elhanyagolható érték), akkor a és b egyenlők. Ugyanígy kell
eljárni a többi reláció esetén is.
Mindjárt a legelején el lehet ezzel követni egy jó kis hibát:
Ha a kezdet-kezdetén megadott mozgási irány, valamely komponense, legyen mondjuk
az y, nagyon kicsi, de nem nulla (mondjuk a demo esetében pl 0.0000005f), akkor az aabb
fölső y lapjából is generál egy vágócsövet, azonban mivel a
lebegőpontos ábrázolás (float) 5-6 tizedes jegyig vehető pontosnak, ezért egy
ilyen csővel való vagdosásnál mindenképpen hibák jönnek elő - mikor rájöttem egy
csokor hiba szűnt meg egyszerre.
Koordinátarendszer mérete:
Erre a neten mindenhol azt mondják, hogy mindegy, de ez nem egészen így van.
Én például a demo-ban, 1m = 1.f -re vettem, az elhanyagolható értéket pedig
(1/1024.f)-nek. Így 1
milliméter kb 1/1000.f. Ütközésvizsgálatnál ez még nem jelent nagy problémát,
mert belül van a float tűréshatárán, de a grafikai megjelenítésnél már bajok
lesznek.
Nem tartozik szervesen ehhez a témához, meg kell említsem, hogy 1.f-nél
közelebbi dolgok kirajzolása sok grafikai hibához vezethet, csak pár példa:
1. Point-sprite-ok méretváltozása: ezek méretét a d3d a távolságtól teszi
függővé, nyilván minél messzebb van,
annál kisebbek - legtöbb esetben. Viszont, ha a
távolság 1 alá csökken, akkor a mérete elkezd csökkenni, ez elég furcsa.
2. Z-buffer felbontás csökkenés: A távolsággal a z buffer felbontása egyre
csökken, azaz a nagyon távoli dolgok
z-tesztjénél egyre több hiba fordul elő. Ha 1-nél közelebb is
ki kell rajzolni dolgokat, meg jóval messzebb is,
akkor a frusztrum-ot mondjuk 0.1-1000.f-ig kell beállítani,
ekkor a fenti esetben 10cm-től 1000 méterig osztja
be a z-buffert. Ekkor a buffer felbontásának 99%-a az első 1
méterre megy el!
Csak, hogy egy kicsit továbbmenjek, ennek a legkisebb-értéknek szinkronban kell lennie a
pályát betömörítő algoritmusban használt legkisebb értékkel. Például, ha a motor bsp-fát használ, akkor a bsp-ben lévő vágósíkoknál is ezzel az értékkel kell
számolni (ez a sík 'vastagsága'), ott sem járható út a sima <>=.
Jól elmagyarázza
Charles Bloom, innen elég
jól meg lehet érteni, minek is ez, főleg a második és harmadik részben.
A legérdekesebb benne talán az, hogy ez az elhanyagolható érték szorozva
egymillióval a pálya maximális mérete. Példaként hozza, ha ez 1 milliméter,
akkor 1 kilométeres lesz a pályát befoglaló kocka élhossza. (nekem az 1cm jobban
tetszene 10km kockával - ekkor azonban nem lehet 1cm-nél kevesebbet mozogni, és
rövid mozgásoknál a bekavarhat, például az fentebb említett irányvektorának
kerekítésekor).
Meg kell még említenem Paul Nettle nevét, aki szintén írt cikket
ütközésvizsgálatról, csak ő aabb helyett gömböt, meg ellipszist használt. Ez sem
rossz alternatíva, gyorsabb algoritmus is, mint ezé, mert nem kell poligonokat
vagdosni, a kód is kevesebb (kb 600 sorban megoldotta). Letölthető a teljes
forráskódja, lehet belőle tanulni. Mondjuk én 2 játékban vettem észre, hogy
használják (serious sam, painkiller),az összes quake, HL inkább az aabb-,
esetleg henger-ütköztetés vonalon mozog, ez is hasonló az aabb-hez, csak itt
hengereket használnak 'doboz'-ok helyett.
Összekalapáltam egy kis demót, letölthető a forrással
együtt - a lényeg a collide.ccp-ben van.
Ahhoz, hogy fusson Direct3D 9 kompatibilis videokártya szükséges.
Ha bárkinek ötlete, kérdése van, vagy hibát talált, írhat a
pjotrfu@freemail.hu -ra.
Füleki Péter, 2007 február.