{progz}

3ds Max-ből telefonra: low-poly modell és M3G export (JSR 184)

Az elmúlt két évben sok 3ds Max képet és animációt készítettem, renderelt látványterveket és reklámfilmeket. Most kipróbáltam, mi marad ebből, ha a cél nem egy 1024×768-as render, hanem egy 176×208 pixeles telefonkijelző, valós időben. A Mobile 3D Graphics API (JSR 184, röviden M3G) egyre több telefonon elérhető, például a Nokia S60-asokon és a Sony Ericsson K-sorozaton. Ezzel Javából lehet 3D jelenetet megjeleníteni.

A modellezés: másképp kell gondolkodni

Rendereléskor nem kell spórolni a poligonnal, a turbosmooth is mehet. Telefonon minden háromszög számít:

  • Költségvetés. Egy játékos karakter 300–600 háromszögből álljon, egy pálya néhány ezerből. A Maxben a Polygon Count segédprogram mutatja a számot.
  • A forma a textúrából jön. A részleteket (ablakokat, csavarokat, ráncokat) fesd a textúrára, ne modellezd.
  • Nincs smooth group luxus. Minden élesen törő él duplázza a csúcspontokat az exportban. Csak ott legyen éles él, ahol látszik.
  • Kis textúra. 64×64 vagy 128×128 pixel, kettő hatvány oldallal. Az M3G nem fogad el más méretet.

Az export

A Maxhez készült M3G exportáló pluginek a jelenetet (geometriát, anyagokat, textúrákat, kamerát, kulcskockás animációt) egyetlen .m3g fájlba írják. Exportálás előtt érdemes:

  1. a transzformációkat alaphelyzetbe állítani (Reset XForm), mert a skálázott objektumok furcsán viselkednek,
  2. a modellt a világ origójához igazítani,
  3. a fontos objektumoknak (kamera, főszereplő) egyedi azonosítót (user ID) adni.

Betöltés és megjelenítés

import javax.microedition.m3g.*;

World vilag;
Mesh hajo;

void betolt() throws java.io.IOException {
    Object3D[] objektumok = Loader.load("/jelenet.m3g");
    for (int i = 0; i < objektumok.length; i++) {
        if (objektumok[i] instanceof World) {
            vilag = (World) objektumok[i];
        }
    }
    hajo = (Mesh) vilag.find(10);   // a Maxben megadott user ID
}

void rajzol(Graphics g, int ido) {
    Graphics3D g3d = Graphics3D.getInstance();
    try {
        g3d.bindTarget(g);
        vilag.animate(ido);          // kulcskockás animáció léptetése
        g3d.render(vilag);
    } finally {
        g3d.releaseTarget();
    }
}

A rajzol egy GameCanvas játékciklusából hívható. A try/finally fontos. Ha a renderelés közben kivétel történik, és a releaseTarget elmarad, a következő bindTarget már nem fog működni.

Számok egy valódi készülékről

A 420 háromszöges hajómodell egy 128×128-as textúrával, egyszerű háttérrel egy Nokia 6630-on nagyjából 15 képkocka/másodperccel futott. Egy második, ugyanilyen modellel már csak 10-zel. A lassulást elsősorban nem a háromszögek száma okozta, hanem a kitöltött képernyőterület, vagyis a pixelek textúrázása. A tanulság: a kamerát ne tedd túl közel, és a háttér legyen egyszerű, egyszínű vagy egy Background kép.