THREE DEE
---------


* A cikk tbb mint fl ve rdott s
* akkor nem hasznltam kezetet, most
* meg nem grcsltem bele ket. Bocs!
* (-egy kis LAMETOX a lamerek ellen.)


A "demoiparban" tombol a 3D laz, nincs
olyan  "nagycsapat" akinek ne lenne 3D
introja/demoja.   Sokaknak almuk, hogy
ok   is   csinaljanak   3D  rutint  de
elkepzeleseik    szerint    ez    igen
bonyolult feladat, pedig nem az!  Most
a    kezdoknek   szeretnek   egy   kis
segitseget  nyujtani.  Elmeleti sikon,
nem lesz programlista, mert azt minden
lamer  begepelne  es azt hinne, hogy o
az   asz.    Erzesem   szerint  aki  a
kovetkezoket  elolvassa  es egy kicsit
is  tud  codolni az siman megirhatja a
sajat 3D rutinjat.




Amit forgatunk
--------------

A    legegyszerubb   mod   az   object
letarolasara a kovetkezo:  egy tombben
(matrix)    letaroljuk    az    object
potjainak  koordinatait  szep  sorban,
x,y,z    koordinataja   minden   egyes
pontnak.    Egy   masik   tombben  meg
letaroljuk   a   vonalakat,   ez   egy
felsorolas hogy mely sorszamu pontokat
kotjuk  majd  ossze vonalakkal.  Pelda
egy negyzet letarolasara:

pontok (x,y,z koordinatak sorban):
        0,0,0, 10,0,0, 10,10,0, 0,10,0
vonalak (pontok sorszamai a pont
tablazatbol):
        0,1, 1,2, 2,3, 3,0

Tiszta a kep, nem?

Az   termeszetes,  hogy  a  rutinunkat
gepikodban fogjuk irni, tehat a tombok
tarolasara  egy  "lehetseges" mod van,
egy  memoriacimtol  kezdve szep sorban
letaroljuk az adatokat, az elerest azt
hiszem   mar   nem   kell  kifejtenem,
esetleg  csak  a  lamereknek,  ok  meg
nem fontosak.

Vannak   meg   elvetemult  tagok  akik
minden   vonalnak   kulon  taroljak  a
kezdopont   es  vegpont  koordinatait,
ebbol   az  adodik,  hogy  a  tablazat
sokkal  hosszab  lesz  es  tobb pontot
kell  forgatnunk  a  terben (ez eszi a
legtobb  idot!)  teljesen feleslegesen
mert  ugyanaz a pont tobbszor szerepel
a  tablazatban.   Az  o modszerukkel a
fenti  peldahoz  8  pont  koordinatait
taroljak  es  forgatjak  mig  mi  csak
4-et.

A haromdimenzios alakok tervezese eleg
nehezkesnek latszik ha papiron akarjuk
megtervezni   (ami   ketdimenzios)  az
objectjeinket.  Ennek kikerulesere van
egy  nagyszeru  3Deditor a piacon.  Ez
egy nagyon egyszeru "cad"-szeru proggy
amivel pofonegyszeruen szerkeszthetunk
objecteket.   A legfobb elonye, hogy a
"mi"  modszerunkel tarolja az adatokat
egy   kis  "kulonbseggel",  ami  abban
jelentkezik,  hogy a tombok elejen egy
longwordon  a  pontok  szamat  ill.  a
vonalak szamat tarolja ami nekunk csak
jo     a     kesobbi    cikluszervezes
szempontjabol.   Amikor  kimentjuk  az
objectunket  es  adunk  neki  egy xxxx
nevet,  akkor az editor ket filet ment
ki    a    lemezre,   xxxx.points   es
xxxx.lines   neven   ami  a  ket  tomb
megfeleloje.   Akinek  nincs meg ez az
editor  annak  szivesen  elkuldjuk  az
altala kuldott lemezen!




A forgatas
----------

A  legelemibb mozgatasa az objectnek a
forgatas.    Ez   a  muvelet  fogja  a
legtobb idot enni a 3D rutinunkban.  A
kovetkezo  keplettel  az  origo  korul
tudjuk   forgatni   az   objectet.   A
keplet:

1. X=(sin(alfa)*Y)+(cos(alfa)*X)

   Y=(cos(alfa)*Y)-(sin(alfa)*X)

2. X=(cos(beta)*X)-(sin(beta)*Z)

   Z=(cos(beta)*Z)+(sin(beta)*X)

3. Y=(sin(gamma)*Z)+(cos(gamma)*Y)

   Z=(cos(gamma)*Z)-(sin(gamma)*Y)

A  forgatasi szogek az alfa (Z tengely
korul),  beta  (Y  tengely korul) es a
gamma  (X  tengely  korul).   A  fenti
muveletekenel  az azonos koordinatknal
muveletparonkent  a  mar  valtoztatott
ertekeket hasznaljuk, egy muveletparon
belul  viszont  az  eredeti  ertekeket
hasznaljuk!      Peldaul    az    elso
muveltparnal a masodik kepletnel ismet
elofordul az X koordinata, ekkor ne az
elso  lepesben megvaltozott X ertekkel
szamoljunk,   hanem   az   eredetivel,
viszont  a  kovetkezo  muveletparoknal
mar     a    valtoztatott    ertekeket
hasznaljuk!   Ha ezzel a muveletsorral
akarjuk    az    alakunkat    forgatni
kivetelesen  nem az origo korul, akkor
folyamodjunk   egy  kis  csalashoz  es
mozditsuk  el az objectunket a terben.
A mar emlitett 3Deditorral ezt konnyen
megoldhatjuk,  es  meg  egy  elonye az
editornak,     hogy     a    tervezett
objectunket   az  egyik  funkciojaval,
sulypontosan  kozepre rendezi a terben
(az origohoz).

Most kovetkezik egy lenyeges problema,
hogyan  szamoljunk  sinust es cosinust
gepikodban,  elojelesen es legfokeppen
gyorsan?   A  megoldas nagyon egyszeru
es ezen a szinten a leggyorsabb!




Sinus es Cosinus
----------------

Hasznaljunk tablazatot!  Legegyszerubb
mod   erre   a  jo  regi  kis  tucskot
(Basicet)   hasznalni.   Irj  egy  kis
programot ami be-POKE-olja a memoriaba
a  sinusertekeket.   A tablazatnak egy
egesz ciklust kell tartalmaznia, 0-tol
2*pi-ig, vagy ha jobban tetszik 0-tol
360-ig.   Az  elojel problema meg van
oldva  mert  a 68000-es tud elojelesen
osznani  (DIVS) es szorozni (MULS).  A
sinustablazatunk  1  alatti  ertekeket
fog igy tartalmazni, a processor ezzel
nehezen boldogul, ezert szorozzuk be a
tablazatunkat   egy  nagyobb  szammal,
majd   ha   egy   erteknek  a  sinusat
kiszamoltuk   az   egeszet  osszuk  el
ugyanazzal   a   szammal.   Ha  byteon
taroljuk  az  ertekeket  (bar  ez nagy
hulyeseg!)  akkor  a  legnagyobb  szam
amivel beszorozhatjuk a tablazatot, az
a  127  (hogy az elojelek meg elojelek
maradjanak!),  wordnel ez a legnagyobb
szam   a   32767.    Byteot   hulyeseg
hasznalni,  longwordot meg felesleges,
igy  maradjunk  a  16  bitnel!   Minel
hosszabb     a    tablazatunk    annal
finomabban  tudunk forgatni vele, ha a
wordnel    maradunk   ne   hasznaljunk
$200-nal  rovidebb  tablazatot mert az
mar nagyon gyors forgas lesz!  Ha kesz
a  tablazatunk,  lepjunk ki a basicbol
es  egy  monitorproggyval mentsuk ki a
tablazatunkat.

Mondjuk  D0-ban  van egy ertekunk amit
szeretnenk  megszorozni  sin(180)-al
illetve  sin(pi)-vel.   A  tablazatunk
modjuk  $200  hoszu,  es  ugye 360-ig
ill.  2pi-ig tart, $200/(360/180)=$100
tehat  a sin(180) megfelelo erteket a
tablazat   $100-ik   elemen  talaljuk.
Ezzel  az  ertekkel  szorozzuk  meg  a
D0-at,  majd osszuk el azzal a szammal
amivel a tablazatot beszoroztuk es mar
meg is kaptuk az eredmenyt.  A cosinus
tablazat    meg    ertelemszeruen    a
sinustablazat  masodik  negyedenel fog
kezdodni, esetunkben $80-nal.

A konkret megvalositas:

Ahol   az   A0-ban  van  a  sinustabla
kezdete, D7-ben a kivant szog!

sinus:  muls    (A0,D7.w),D0
        divs    #32768,D0
        ....

cosinus:muls    $80(A0,D7.w),D0
        divs    #32768,D0
        ....

A   divs   egy  eleg  lassu  utasitas,
helyettesiteni tudjuk, estetunkben:

        asl.l   #1,d0
                ;szorzas kettovel
        swap    d0
                ;megfel a 65536-al
                ;valo osztasnak

Ez  a ket utasitas lenyegesen gyorsabb
mint a divs!




A lekepezes
-----------

XX = (X * (P - M)) / (P - Z)

YY = (Y * (P - M)) / (P - Z)

Az      x,y,z     ertelemszeruen     a
haromdimenzios  koordinatak,  az XX es
az   YY   a   lekepezett  ketdimenzios
koordinatak.  M a nagyitas aranya, P a
perspekitiva   faktor   (ezzel  tudjuk
allitani    hogy   a   hatso   oldalak
mennyivel   kissebbek   mint  az  elol
lathatoak).   Ha  egy  kockat  akarunk
lekepezni aminek a koordinatai -50tol,
+50ig  terjednek, eloszor probaljuk az
M=1000,  P=500 ertekeket, majd allitsa
be  ezeket  az  ertekeket  mindenki  a
sajat izlesenek megfeleloen.

A   fenti  keplet  egy  "al  lekepezo"
keplet mivel nem egy pontbol kepezi le
a  "latottakat"  es  mindig az origoba
"nez",   mindezek   ellenere   korrekt
perspektivikus kepet ad es legfokeppen
gyors!




A folyamat
----------

Most  egy  3D  rutin teljes folyamatat
irom le.

A  forgatassal  kezdjuk.   A  forgatas
szogenek     tarolasahoz    hasznaljuk
pointereket      amik      majd     az
indexregiszterek   lesznek  a  sin/cos
szamolasnal.   Ezt  ugy  kepzeljuk  el
hogy van a memoriaban egy wordunk amin
az   aktualis  elforgatasi  szog  lesz
talahato,   ennek   erteke   0-tol   a
sinustabla   hosszaig   fog  valtozni.
Peldaul    az    objectunket    minden
keplefutasnal   a   Z   tengely  korul
akarjuk  elforditani  2  fokkal, ekkor
nem  a  letarolt  object  koordinatait
fogjuk     mindig    ket-ket    fokkal
elforditani,    mert    a    szamolasi
pontatlansagok   miatt   az  objectunk
hamar  eltorzulna.   Ehelyett  eloszor
elforditjuk  mondjuk  2  fokkal  es az
elforgatott  koordinatakat  egy  masik
tombbe      taroljuk     a     kesobbi
lekepezeshez,      majd      kovetkezo
lefutasnal  mar  4  fokkal  forditjuk,
majd  6-al, 8-al, stb.  Amikor elerjuk
a   360x   fokot  (a  tablazat  veget)
kezdjuk   a  tablazat  elejen.   Ehhez
hasznaljuk a pointereket amiket minden
lefutasnal    noveluk/csokkentunk    a
kivant   ertekkel   amig   elerjuk   a
tablazat  veget/elejet  majd kezdjuk a
tablazat elejerol/hatuljarol.

Ezutan  a lekepezo keplet segitsegevel
az  elforgatott  koordinatak tombjebol
lekepezzuk     minden    egyes    pont
koordinatait  egy ujjab tombbe ami mar
a   ketdimenzios  koordinatakat  fogja
tartalmazni.

Vegul   az   objectunk  vonaltombjebol
parosaval   kiolvassuk   az  ertekeket
amelyek     erteke     a     vonnallal
osszekotendo      pontok     sorszamat
tartalmazza    a    lekepezett    (2D)
tombunkben.     Ekkor   kiolvassuk   a
lekepezett  koordinatak  tombbjebol  a
pontok   sorszamanak   megfelelo   X,Y
koordinatakat  es  ezeket  osszekotjuk
vonallal.   Ezt  addig folytatjuk amig
el nem fogynak a vonalak.

Es  az  uj keplefutasnal kezdhetjuk az
egeszet elolrol!

Hat  ennyi az egesz, igazan nem nehez!
Nemde???



                        ADT
w