V předchozích článcích jsme se seznámili se dvěma odlišnými přístupy k vytváření těles, které se lišily v efektivitě využití paměti. Tentokrát k nim přidáme další, opět trochu jiný přístup, jímž bude využití indexované geometrie.

Označení indexovaná geometrie pojmenovává takový způsob uložení vrcholů těles, v němž máme dva typy polí – pole dat a pole indexů. V poli dat jsou uloženy souřadnice vrcholů a indexy z druhého pole do tohoto pole odkazují. Díky tomu můžeme mít souřadnice každého uloženého vrcholu v poli dat pouze jednou a odkazovat na ně z pole indexů, kolikrát jen bude potřeba. To samé platí rovněž o barvách, normálových vektorech a souřadnicích textur.

Třídy, umožňující pracovat s indexovanou geometrií, mají všechny společnou bázovou třídu IndexedGeometryArray, například IndexedTriangleArray, IndexedQuadArray nebo IndexedTriangleStripArray. První dvě jsou indexovanými analogiemi ke třídám TriangleArray a QuadArray (s tou jsme se zatím nesetkali), třetí pak odpovídá třídě TriangleStripArray. Z toho je vidět, že indexované můžeme mít jak jednotlivé trojúhelníky nebo čtyřúhelníky, tak i jejich trsy a pásy.

Konstruktor, definovaný ve třídě IndexedGeometryArray, přebírá tři parametry a vypadá takto: IndexedGeometryArray(int vertexCount, int vertexFormat, int vertexCount). První parametr určuje počet vrcholů v poli dat, druhý parametr určuje, co bude v daném objektu uloženo za informace, a konečně třetí parametr říká, jakou velikost bude mít pole indexů. Tento konstruktor ale nevyužijeme při vytváření trsů nebo pásů pomocí indexované geometrie, protože u těch potřebujeme navíc vědět, kolik vrcholů bude uloženo v jednotlivých trsech nebo pásech. V konstruktoru IndexedGeometryStripArray(int vertexCount, int vertexFormat, int indexCount, int stripIndexCounts[]) jsou zmiňované informace uloženy v poli stripIndexCounts.

K nastavování polí dat se používají metody definované ve třídě GeometryArray, jako jsou setCoordinates nebo setNormals. Pro nastavování indexů už ale s metodami definovanými ve třídě GeometryArray pochopitelně nevystačíme, protože budeme potřebovat rovněž metody pro nastavování polí indexů, jako například setCoordinateIndices(int index, int coordinateIndices[]) nebo setColorIndices(int index, int colorIndices[]).

Jako příklad využití indexované geometrie si ukážeme vytvoření krychle pomocí třídy IndexedQuadArray. Screenshot tentokrát nečekejte, jedná se pouze o další variaci na téma osvětlené krychle.

package interval.j3d;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.geometry.*;
public class OurColorCube extends Shape3D{
  public OurColorCube(float size) {
   //pole dat
   float coordinates[] = {
    1,1,1, -1,1,1, -1,-1,1, 1,-1,1,
    1,1,-1, -1,1,-1, -1,-1,-1, 1,-1,-1};
   for (int i = 0; i < 24; i++)
    coordinates[i] *= size/2f;
   //pole indexů do pole dat
   int indices[] ={0,1,2,3,//přední stěna
        7,6,5,4,//zadní stěna
        2,1,5,6,//levá stěna
        0,3,7,4,//pravá stěna
        3,2,6,7,//dolní stěna
        0,4,5,1};//horní stěna
   //vytvoříme objekt IndexedQuadArray
   IndexedQuadArray geometry = new IndexedQuadArray(8, GeometryArray.COORDINATES | GeometryArray.NORMALS, 24);
   //nastavíme pole dat pomocí metody definované ve třídě GeometryArray
   geometry.setCoordinates(0, coordinates);
   //nastavíme pole indexů
   geometry.setCoordinateIndices(0, indices);
   float normals[] = {1,0,0, -1,0,0, 0,1,0, 0,-1,0, 0,0,1, 0,0,-1};
   int normalIndices[] = {4,4,4,4,
           5,5,5,5,
           1,1,1,1,
           0,0,0,0,
           3,3,3,3,
           2,2,2,2};
   geometry.setNormals(0, normals);
   geometry.setNormalIndices(0, normalIndices);
   this.setGeometry(geometry);
  }
}

Je sice pravda, že indexovaná geometrie dokáže ušetřit prostor v paměti, ale za tyto úspory musíme platit výkonem. Pokud se tedy budete rozhodovat, jaký přístup k vytváření objektů zvolit, mějte to na zřeteli.

Žádný příspěvek v diskuzi

Odpovědět