V tom prvním 3d-engine je chyba. Když se přiletí s letadlem blízko ke kameře,
tak se prohodí předek a zadek.
|
Není to chyba v engine, jen je špatně nastavená konstanta perspektivního
zkreslení. Zkus si ji změnit (přidej si obsluhu třeba tlačítky */) a uvidíš.
|
Říkal jsi že první tři řádky v matici jsou různé vektory a pozice matice.
Dá se toho nějak využít ? A dá se matice posouvat taky podle os souřadnicového
systému a ne podle vlastních jak to dělá funkce translatematrix() ?
|
Ano, dobrá otázka - zapomněl jsem to tam dát. Matice jsou vlastně čtyři vektory.
Tři udávají směr souřadných os (x, y, z), jsou na sebe tudíž vždycky kolmé a jejich
velikost je 1 a ten čtvrtý je už vzpomenutá pozice :
Dobře.. u je vektor, směřující doprava, v směřuje nahoru a vektoru w dopředu (pokud matice patří kameře, kamera se dívá právě tímto směrem) jak jsem na to přišel ? Můžete si to odvodit z jednotkové matice :
Potom u = (1, 0, 0), v = (0, 1, 0), w = (0, 0, 1) a pozice = (0, 0, 0) - je to jednoduché. Dá se to použít třeba ke konstrukci kamery když známe jen její pozici a místo, kam se dívá :
Tahle funkce vytvoří matici kamery, která je na pozici pos a dívá se směrem k target. Posouvat matici po osách systému jde, prostě se k vektoru pozice v kameře přičte vektor posunutí. Je to logické a nebolí to :-) |
Ahoj ! Prokousávám se seriálem o 3D-Enginech, právě se učím matice v matice - to je
legrační. Kde se to vlastně dá naučit ? Mám takovej problém - když počítám inverzní
matici tak mi ta tvoje funkce dá vždycky jinej výsledek ! Je to špatně ?
|
No, špatně to určitě není, jinak by to nefungovalo. Musíš si pamatovat že v posledním
řádku matice je vždy {0, 0, 0, 1} a na to je taky funkce optimalizovaná. Zkus si to
spočítat třeba v excelu a mělo by to vyjít - je tam přímo funkce pro inverzi matice.
Když se to počítá ručně, musíš si pamatovat že většina věcí v učebnicích se dělá pro
matice 3.řádu a pro matice 4.řádu ty pravidla většinou už neplatí a musí se vypouštět
řádky a sloupce a vznikají menší matice se kterými se operace provádí znovu dokud
nevyjde matice dost malá atd.. Naučit se to dá - pokud umíš anglicky, zadej v googlu
matrix a budeš se tím moct prokousávat roky :-) nebo zkus www.math.com, tam taky něco
bude. No a pokud anglicky neumíš, puč si nějaký středoškolský skripta nebo učebnice na
matiku, je to skoro ve všech průmyslovkách, občas i v ekonomkách a občas i úplně jinde.
Jo, a taky - matice je nejen inverzní, ale i transponovaná ! (má prohozené řádky a sloupce)
|
Zrovna se prokousávám těma maticema, co tam máš napsané v enginech. Zajímala by mě
jedna věc: používá se tam pole typu float. Chápu ze to musí byt přesně. Proč velikost 4*4 ?
Píšeš tam ze jsou to čtyři vektory a jeden ukazuje doprava druhý nahoru a třetí dopředu.
To znamená x,y,z. Proč je každá souřadnice napsaná třemi čísly. Možná ze jsi nepochopil
co po tobě vlastně chcu tak se to zkusím napsat nějak lip. Proč je směr doprava definován
třemi neznámými (čísly), nahoru taky třemi, dopředu taky třemi ?
|
Správně. sou tam tři vektory, takže stačí matice 3 × 3. ale pokud chceš s objektem ještě
posouvat, potřebuješ ještě tři souřadnice. ale s maticí 3 × 4 nemůžeš pracovat - matice musí
být čtvercová - takže se rozšiřuje na 4 × 4 ...
doufám ze to tak stačí, kdyžtak esce napiš... |
Asi jsem fakt napsal blbe otázku a tak ještě jednou. Otázka byla proč je jeden směr definován
třemi neznámými. Já jsem si proste myslel ze když chcu mít bod v prostoru tak k vyjádření
jeho polohy mi stačí tři čísla. A ta matice je 4*4 takže jeden sloupec je určen k posouvání
(poslední sloupec) a jeden řádek - ten poslední dolní je na doplnění k nutnosti počítáni aby
byla ne 3*4 ale 4*4. A teď k jádru věci zbývá nám tedy (bez posunovacího sloupce a doplňujícího
řádku) matice velikosti 3*3 což dohromady dává devět prvků. A zjevně jak jsem pochopil se
nakonec používá asi jenom diagonála (3 prvky). Poslední větu neber jako součást otázky,
ale můžeš k tomu taky něco napsat.
|
Aha .. byl jsem nějak mimo .. ne, nepoužívá se jen diagonála, ale všechny prvky v matici.
Diagonála se naplní jedničkami, aby vektory odpovídaly původnímu směru souřadnicových os
x, y, z ... Při transformaci se jich použije všech devět. ty 3 × 3 jsou tri vektory - nahoru,
doprava a dopředu - což tedy odpovídá osám x, y, z. jde samozřejmě definovat i pomoci dvou,
jenže s tím se nedá počítat (pomalu) ...
|
Tak a jsme konečně u jádra věci. Tři vektory nahoru doprava a dopředu. Teda spíš doprava
nahoru a dopředu. V celé matici je nakonec ale uložená pozice jenom jednoho bodu ne ? Proč
je nutné aby byl směr (jedna souřadnice) definovaná vektorem a ne jenom jedním číslem.
Vektory jsou totiž v tomto případě čísla 3 nebo se mýlím?
|
to jo.. jeden bod, jenže ten bod je relativní ke svému vlastnímu souřadnicovému systému.
jednou maticí se transformuje celý objekt, takže ty body se otáčí kolem nuly v objectspace.
Jednodušeji to opravdu nejde. Můžeš jen použít polární souřadnice, což by vyšlo na minimum
čísel, ale složitější počítání.
Mimochodem - Vektor definuje směr, číslo je jen tzv. skalár - délka.
|
Tak fajn tím už se nebudu zabývat. Zkoušel jsem k tomu tvém enginu dávat svoje scény ze 3d
studia MAX a zjistil jsem že jeden objekt se vůbec nehýbe a ten druhý se hýbe po vlastních
osách, ale rotace je trochu divná protože objekt nerotoval po svých osách ale po těch které
byly ve studiu. To znamená že když jsem tam mel třeba krychli tak se netočila kolem svého
středu, ale kolem nějakého bodu mimo ni. Dá se to nějak vyřešit?
|
Když objekty nahraješ, musíš jim inicializovat matice, až potom s nimi pracovat .. jestli
to bude ten efekt co chceš.. jinak tam je problém, že 3d-studio má asi trochu chybu v maticích,
protože posuny občas nezahrne do matice, ale dá je přímo do vertexů ... je to trochu problém.
Já používám 3D Max R3 a R5, u R3 nebyl problém, spíš mi vadilo u třeba letadla z více částí
Že každá část (křídla, motory …) rotuje po vlastních souřadnicích :-)
|
Potřeboval bych objasnit jeden řádek ve funkci násobení matic. Je to ten poslední a asi bude
něco předávat dál, ale nechápu ho - nevím co je to za příkaz a jak funguje. Je to tento řádek :
memcpy(r, temp, sizeof(Matrix)); Jinak radši tady dám celou funkci, aby to bylo jasnější a přehlednější.
|
ten příkaz zkopíruje obsah matice temp do matice r. nejde napsat r = temp, protože r je
ukazatel do paměti. r[0] = temp taky nebude fungovat, protože je to dvourozměrné pole (-> pole
pointerů) takže se musí kopírovat paměť. Funkci dáš pointer kam, pointer odkud a velikost
v bytech a už to jede :-)
|