Skip navigation

Geometriai transzformációk alaposabb vizsgálata

Kiegészítő anyag!

Részletesen nem tárgyaljuk, a Three.js működésének jobb megértését célozza.

Általános objektum attribútumok működése

Az általános objektum attribútumok vizsgálatához visszakanyarodunk a térbeli modellezés példaprogramhoz (02_01_ThreeJsCubeTransformCommon). Figyeljük meg a következőket.

Kiindulópont

  • Az objektum saját koordináta-rendszere és a világ koordináta-rendszer egybeesik, az objektum csúcspontjai a definíciókori helyükön jelennek meg.

Skálázás

  • A csúcspontok X, Y és Z koordinátái szorzódnak a skálaparaméterekkel. A tengelyirányok nem változnak, továbbra is egybeesnek.

Forgatás

  • Először a Z-tengely körül. Ez egybeesik a világ Z-tengelyével. A forgatás hatására - amennyiben az nem nulla - az X és Y lokális tengelyek elmozdulnak, nem esnek ezután egybe a világ tengelyekkel!
  • Utána a világ Y-tengelye körül. Ha Z forgás nulla, akkor esik egybe a lokálissal, egyébként nem!
  • Végül a világ X-tengelye körül. Ha Z és Y forgás nulla, csak akkor esik egybe a lokálissal.

Eltolás

  • A világ tengelyei mentén.

Megjegyzés

A forgatás a fenti módon a három tengely körüli elforgatással megadva az úgynevezett Euler szögek használatát jelenti. Az Euler szögekkel való forgatás speciális esetben forgatási dimenzióvesztéshez, gimbal lock-hoz vezethet, illetve a kamera orientációk közötti interpoláció furcsa mozgási pályákat eredményezhet. Emiatt a grafikus szoftverekben a forgatást úgynevezett egység kvaternióval írják le. A Three.js újabb verzióiban már ez az alapértelmezés. Természetesen van oda-vissza alakítási lehetőség a kétféle reprezentáció között.

Angol nyelvű magyarázó videók a témában: Euler (gimbal lock) Explained és Euler vs Quaternion - What's the difference?

Three.js háttérműködés

A geometria csúcspont koordinátái nem változnak a geometriai transzformációk hatására! A világ koordináta-rendszerben a végleges helyükre egy geometriai transzformáció segítségével kerülnek! A geometriai transzformáció lineáris, vagyis egy 4x4-es homogén reprezentációs mátrixszal megadható. A transzformációt a GPU hajtja végre a csúcspont koordinátákra.

A beállított objektum attribútumok határozzák meg a 4x4-es transzformációs mátrixokat, amelyek összeszorzásra kerülnek egy közös kompozíciós mátrixot kialakítva (object.matrix attribútum).

A transzformációs mátrixok szorzásának sorrendje rögzített: skálázás, forgatás, végül eltolás.

Az object.matrix számításához:

  1. az attribútum változtatások befejeztével meg kell hívni az object.updateMatrix() függvényét,
  2. vagy igazra kell állítani a matrixAutoUpdate kapcsolót. Ez utóbbi esetben a rendereléskor automatikusan történik a frissítés, a renderer feladata az object.updateMatrix() meghívása. Ez egyébként az alapértelmezett működés, amit eddig is használtunk.

A rendszer minden objektumhoz nyilvántartja, hogy a világ koordináta-rendszerben hogyan helyezkedik el. Ez elérhető az object.matrixWorld attribútummal.

Amennyiben saját magunk számítjuk ki a transzformációs mátrixot, akkor mindenképpen állítsuk hamisra a matrixAutoUpdate kapcsolót, egyébként rendereléskor a Three.js felülírja!

Transzformáció tényleges végrehajtása a csúcspontokra

A Three.js lehetőséget biztosít arra, hogy a geometriai transzformációt végrehajtsuk, a csúcspontok tényleges új értéket kapjanak. Ekkor figyelnünk kell az alábbiakra.

  • Először biztosítsuk, hogy az objektum transzformációs mátrixa érvényes. Ha nem közvetlenül adjuk meg, hanem általános objektum attribútumokkal, akkor hívjuk meg az updateMatrix() függvényt!
  • Transzformáljuk a csúcspontokat az új helyükre az applyMatrix4() függvénnyel!
  • Jelezzük a rendszernek, hogy a geometria csúcspont koordinátái változtak, frissítés szükséges.
  • Az objektumhoz tartozó mátrixot állítsuk vissza az egységmátrixra! Ha az általános objektum attribútumokat használjuk, akkor a forgatási és eltolási paraméterek 0, a skálázó paraméterek 1 értéket kapjanak, és újra frissítsük a mátrixot. Közvetlen mátrix megadásánál a mesh.matrix.identity() függvény használható.
  • Figyeljünk arra, hogy ha a forgatást Euler szögekkel adjuk meg, akkor meg kell hívni az objektum setRotationFromEuler() függvényét az egység kvaternió reprezentáció frissítéséhez!
mesh.updateMatrix();
mesh.geometry.applyMatrix4( mesh.matrix );

mesh.geometry.verticesNeedUpdate = true;

mesh.position.set( 0, 0, 0 );
mesh.rotation.set( 0, 0, 0 );
mesh.setRotationFromEuler();

mesh.scale.set( 1, 1, 1 );
mesh.updateMatrix();