A JavaScript nyelv nem a típusosságáról híres. A változókhoz nem is tudunk típust rendelni, az értékadás szerinti típust rendeli hozzá az értelmező. Számértékek esetén például csak lebegőpontos számot (más magasszintű nyelvekben ez a float típus) kezel, még akkor is, ha egész értéket adunk egy változónak. A tömbökben mindenféle típusú érték (szám, szöveg, stb.) vegyesen előfordulhat. A tömbök méretét futás közben szabadon módosíthatjuk.
Ezzel szemben a grafikus hardver erősen típusolt megközelítést használ: megkülönböztet 8, 16 és 32 bites, előjeles és előjel nélküli egészeket, valamint lebegőpontos típusokat, ezekből a típusokból keletkező 2, 3 és 4 elemű vektorokat.
Fontos, hogy a JavaScript nyelv oldaláról a grafikus hardvernek megfelelő, típusolt értékek kerüljenek át, elem darabszám információval. Ehhez a JavaScript megfelelő típusolt tömb konstrukcióit kell használnunk, majd a THREE.js megfelelő konstruktor függvényével puffer attribútum tömbbé kell alakítani, ami átadható a grafikus hardvernek.
Megjegyezzük, hogy JavaScript tömböt is átadhatunk inicializáláskor közvetlenül a típusolt tömbnek, vagy akár a puffer attribútum tömbnek is, vagyis a típusolt tömb létrehozási lépés elkerülhető. Ez a megközelítés másolatot készít az adatokról, így nagy adatmennyiség esetén nagyon pazarló a memóriával. Emiatt célszerű lehet eleve típusolt tömböt létrehoznunk, és abban beállítani a szükséges értékeket.
Az első példában JavaScript tömböt definiálunk, abból hozzuk létre a típusolt Float32 tömböt, amit puffer attribútum tömbbé alakítunk.
let vertices = [];
let vertexPositionAttributeSize = 3; // 3D: vx, vy, vz
vertices.push(
1, 0, 0, // V0
4, 6, 5, // V1
7, 3, 3, // V2
10, 7, -3 // V3
);
let positionFloatArray = new Float32Array( vertices );
let positionBuffer = new THREE.Float32BufferAttribute( positionFloatArray, vertexPositionAttributeSize );
Ebben a példában a positionFloatArray közvetlen létrehozása tulajdonképpen felesleges, mert egyrészt a változót másra nem használjuk, csak átadjuk a puffer konstruktornak, másrészt a vertices tömb közvetlenül is átadható lenne a puffer attribútum tömb konstruktorának, ami ekkor létrehozza a lebegőpontos tömböt, de így jobban látható lezajló folyamat. Egy gyakoribb hívási szintaktika:
let positionBuffer = new THREE.Float32BufferAttribute( vertices, vertexPositionAttributeSize );
A puffer attribútum tömb létrehozásakor azt is meg kell adnunk, hogy a tömbben hány darab elem tartozik egy csúcsponthoz. Jelen esetben ez 3, mert 3 dimenziós koordinátákat adunk át, amit a vertexPositionAttributeSize változónk tartalmaz.
A memóriával jobban bánó megközelítés, ha a csúcspont koordinátákat eleve típusolt tömbként hozzuk létre, a JavaScript tömb kihagyásával. Itt nincs push() függvény, előre meg kell mondanunk a tömb méretét és tömb indexeléssel tudjuk az értékeket beállítani, illetve lehetőség van a definíciókor a teljes tömb tartalmát megadni. Jó megközelítés, ha a tömbben tárolt csúcspont információ számát, valamint az egy csúcsponthoz tartozó elemek számát külön változókban feljegyezzük, és a kódban azt használjuk. Amennyiben változatunk a méreten, elegendő a változó értékeket egy helyen módosítani, nem kell a kódba égetett konstans értékeket keresgetnünk, ami sok hibaforrást jelenthet.
let vertexCount = 5;
let vertexPositionAttributeSize = 3;
let vertices = new Float32Array(
[
-5.0, 5.0, 0.0, // V0
-2.5, 0.0, 0.0, // V1
0.0, 5.0, 0.0, // V2
2.5, 0.0, 0.0, // V3
5.0, 5.0, 0.0 // V4
]
);
positionBuffer = new THREE.BufferAttribute( vertices, vertexPositionAttributeSize );
A fenti kódrészletben a típusolt tömböt helyben inicializáljuk is. További példaprogramokban látunk majd arra példát, amikor darabszám információt adunk csak át, és később, for ciklusban adjuk meg az értékeket.
A kódból az is látható, hogy amennyiben típusolt tömbből hozzuk létre a puffert, akkor nincs szükség típus információra, mert a típusolt tömb azt tartalmazza. Elegendő a THREE.BufferAttribute() hívása.
A típusolt tömbök használati lehetőségei ennél jóval bővebbek. Részletesebben például az alábbi oldalon olvashatunk erről (angol nyelven):