IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

3. diel - XNA tvorba v 3D - súradnice a matice 3D sveta

Vítam vás štvrtýkrát u skromného seriálu tak na 3D v XNA. Dnes sa pozrieme na 3D priestor ako taký. Je to nutné zlo, ktorým si musíme prejsť, aby bolo možné pokračovať ďalej k lepším veciam. Tiež sa pozrieme znova a viac podrobne na všetky tri matice. Ale hlavne na maticu World, ktorú sme zatiaľ ešte nijako nepoužívali a pritom nám všetkým mohla ušetriť veľa práce a počítanie. Stále sa čudujem, že nikto znalý sa už dávno neozval.

Možno ste si všimli, že pri všetkých príkladov, čo som tu uvádzal, sme pracovali iba s dvoma súradnicovými osami. Boli to X a Y. Z osu sme ponechávali vždy na nule. XNA využíva pravotočivý systém súradníc. Os X teda vedie vodorovne doprava, os Y hore a os Z smerom z obrazovky k nám.

osi - Základy 3D grafiky a tvorba enginu

Samozrejme záleží na pohľadu kamery (na maticu View a Projection) a jej nastavení. V našich príkladoch, ktoré sme mali v predchádzajúcich dieloch, bola kamera dobre narafičena :-) A toto rozloženie os platilo. Pozrime sa teda na definíciu matice View, ktorú sme doteraz používali:

Matrix.CreateLookAt(new Vector3(0, 0, 30), new Vector3(0,0,0), Vector3.Up);

Znovu zopakujem, že matica View slúži k definícii pohľadu odkiaľ (prvý parameter), kam (druhý parameter) sa pozeráme. Tretí parameter udáva, kde a akým smerom má kamera v jej pohľade smer nahor. Ako vidno tak máme kameru nastavenú o 30 jednotiek akoby k nám a pozerá sa priamo do stredu súradnicového systému. V tomto chytro zvolenom nastavení nám osi X a Y kopírujú výšku a šírku monitora. Ak by bola kamera nastavená inak, tak by to tak samozrejme nebolo. Pozrime sa tiež podrobnejšie na druhú maticu. V prvom diele som k nej moc faktov schválne neprezradil. Teraz už ale musím s pravdou von, takže vyzeralo to takto:

effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver2, GraphicsDevice.DisplayMode.AspectRatio, 1, 1000);

Opäť by bolo asi dobré povedať, že matica Projection slúži k definíciu toho, ako bude 3D priestor prevedený do 2D na našej obrazovke.

3D kamera - Základy 3D grafiky a tvorba enginu

Používa sa tu obyčajná perspektíva. Prvý parameter nám určuje ako veľmi širokú výseč kamerou sledujeme a to v radiánoch (na obrázku modrá kostrbatá čiara). Tu používame 90 °, ja ale zvyčajne používam 45 °, ale je to opäť závislé od účelu. Ďalšia parameter je pomer strán okna nášho programu. Jednička je vzdialenosť takzvané near plane. Je to akási pomyselná plocha, od ktorej sa začnú objekty vykresľovať (na obrázku označená ako near). Všetko čo bude pred ňou nebude vidieť. Tu dôsledne odporúčam vždy na toto miesto dávať jedničku, ušetríte si tým veľa starostí s neskoršími chybami v efektoch. Posledné číslo je takzvaná far plane (na obrázku označená prekvapivo ako far). Všetko čo bude za touto virtuálny plochou opäť nebude vykreslené. Toto číslo voľte podľa potreby, ale nie zas zbytočne veľa veľké.

Aby bol výpočet vlastností používaných matíc kompletné, musíme si povedať aj niečo k matici World, ktorú sme zatiaľ nepoužili. Je to celkom škoda, ale aj akýsi môj zámer. Matice World, ako už by ste mali vedieť, určuje s umiestnenia objektu vo svete. Jeho pozíciu, natočenie, ale tiež treba meradlo. Až do tejto chvíle sme všetky súradnice počítali ručne a umiestňovali objekty na dané miesta. Čo keď by sme ale chceli nie jeden objekt, ale napríklad desať vedľa seba? Iste môžeme využiť nejakého rafinovaného cyklu, ktorý by za nás súradnice vypočítal. Čo keby sme ale potrebovali objekt aj o nejaký uhol natočiť. Zvládli by ste to? ja nie :-) Lepšie je urobiť si len akýsi prototyp nášho objektu sa stredom na súradniciach (0,0,0) as ním len potom posúvať pomocou matice World. Umiestniť ho na dané súradnice, natočiť ho a ešte zmeniť mierku. Práve preto tu táto matica je, aby nám pomohla riešiť tieto problémy veľmi ľahko a elegantne. Matica sa skladajú nie sčítaním, ale násobením, takže jediné úskalia, ktoré sa tu skrýva, je správne poradie pri násobenie matíc. Ako je známe A * B nie je u matíc rovnaké ako B * A. Výsledok je zakaždým iný. Našťastie to nie je u týchto matíc tak horúce, ale je dobré naučiť sa určité poradie, aby ste predišli možným chybám.

World = S * R * T
  • písmenko S označuje Scale teda zmenu mierky
  • písmenko R označuje Rotation teda natočenie
  • písmenko T označuje Translate a nie je to preložiť, ale posunúť

Dá sa to ľahko zapamätať ako srt a to ak sa nemýlim je jedna z prípon súboru na titulky. To je jedno pre mňa zatiaľ vždy fungujúcich poradí. Zaujímavé však je, že tu je uvedené presne opačné poradie, než som doteraz používal. Všetky matice sa v XNA, ako ste si možno už všimli, vytvárajú skrze statickej metódy triedy Matrix. Metódy zakaždým začínajú na Create* kde za hviezdičku dosadíte čo presne potrebujete. Ďalším výhodným poznatkom je, že zakaždým ak vyžaduje nejaký parameter uhol, tak je v XNA vždy v radiánoch.

Maticu pre meradlo vytvoríme veľmi ľahko:

Matrix.CreateScale(meritko)

Kde meradle je Vector3. Origniální veľkosti dosiahneme sa samými jednotkami (výhodné je taky použiť Vector3.One). Veľkosťou väčších väčšími číslami a veľkostí s číslami medzi nulou a jednotkou. Ak by bola niekedy použitá 0, tak sa nám nezobrazí vôbec nič a ak číslo záporné, teleso by sa nám prevrátilo.

Maticu pre posun vytvoríme tiež veľmi ľahko:

Matrix.CreateTranslation(posun)

Kde opäť posun je Vector3 a vyjadruje o koľko sa má sa s objektom vo svete hnúť.

Posledný je matica pre rotáciu, ktorá je pomerne zradná. Možno ju vytvoriť niekoľkými spôsobmi, podľa niekoľkých rôznych matematických predstáv. Pre určité operácie sa viac hodí niečo a pre iných zas to druhé. Vždy som používal len túto najjednoduchšiu metódu, pretože mi prišla najviac pochopiteľná. Je to rotácie okolo jednotlivých osí objektu. Ak by niekto mal väčšie skúsenosti a vedel viac tak sa prosím vyjadrite dole v komentároch.

osi otáčania - Základy 3D grafiky a tvorba enginu

Opäť pripomínam, že uhly musí byť v radiánoch. Na prevod do nich má XNA vstavanú metódu ToRadians triedy MathHelper, ktoré sa o prevod postará sama.

Asi je dobré napísať si na toto nejakú pomocnú metódu, ktorá sa nám o to postará a v budúcnosti sa nebudeme musieť zaoberať nejakými pravidlami. Vložíme si teda nový súbor s triedou Utility, urobíme jej verejnú identifikátorom public a dovnútra dáme sadu statických, navzájom preťažených metód:

public static Matrix CreateWorld(Vector3 posun){
  return Matrix.CreateTranslation(posun);
}

public static Matrix CreateWorld(Vector3 posun, Matrix rotace){
  return rotace*Matrix.CreateTranslation(posun);
}

public static Matrix CreateWorld(Vector3 posun, Matrix rotace, Vector3 meritko){
  return Matrix.CreateScale(meritko) * rotace * Matrix.CreateTranslation(posun);
}

public static Matrix CreateRotation(Vector3 rotace){
  return Matrix.CreateFromYawPitchRoll(rotace.Y, rotace.X, rotace.Z);
}

Pridal som tiež jednu metódu pre vytvorenie matice pre rotáciu. Bude sa nám neskôr hodiť. A to je myslím všetko, čo som chcel povedať k tejto téme. Dúfam, že ste pochopili k čomu je to všetko dobré a že sa bez tohto naďalej nezaobídeme. Nabudúce sa skúsime vrhnúť na nejaký ten vysnívaný model. Opäť čakám na komentáre pod článkom.


 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 636x (99.53 kB)

 

Predchádzajúci článok
XNA tvorba v 3D - textúry
Všetky články v sekcii
Základy 3D grafiky a tvorba enginu
Preskočiť článok
(neodporúčame)
XNA tvorba v 3D - Modely
Článok pre vás napísal vodacek
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Vodáček dělá že umí C#, naplno se již pět let angažuje v projektu ŽvB. Nyní studuje na FEI Upa informatiku, ikdyž si připadá spíš na ekonomice. Není mu také cizí PHP a SQL. Naopak cizí mu je Java a Python.
Aktivity