Remélem kijut a poszt, mielőtt elkezdődik az idei Experience. Ugyanis demo készül nagy erőkkel.
Mint arról már korábban írtam, Betasector a csapatunk legújabb tagja és rögtön aktivizálta magát. Blenderben rittyentett két jelenetet, ami már önmagában is tök jól nézett ki. A feladat elég egyszerűen indult: ezt kell valós időben elkészíteni.
Most, hogy Pythonban is viszonylag otthon vagyok és korábban is használtam a programot tartalmak előállítására, azt gondoltam, nem lesz nehéz a feladat. Ez a túlzott optimizmus. Még ennyi év után is. Ráadásul úgy gondoltam, jó volt ez a Unity, de ideje tovább lépni.
A modellek még gond nélkül bemásztak a demóba. A problémák a kamera animációnál kezdődtek. Eddig fel sem tűnt, hogy a Blender másik koordináta rendszert használ, mint az OpenGL. Persze azért nem tűnt fel, mert az OBJ exporter lehetőségként megadja az "Y up" és "-Z forward" opciókat, ezért az exportált modell az OpenGL környezetben pontosan úgy jelenik meg, mint a szerkesztő programban. A kameránál mindez nem működik.
A pozíció esetén még nincs is gond, két koordinátát kell felcserélni, de a forgatás esetén valami miatt remeg a kép, mintha két forgatási szög között váltakozna. A megoldásra egy Babylon.js fórumban bukkantam. Az itt leírt módszer nem működött, de kellő alapot adott, hogy próbálgatással megtaláljam azt a kombinációt, ami pont ugyan azt az eredményt adja, mint amit a Blender mutatott. Mikor láttam a megoldást, akkor már értettem, miért ezt kell csinálni, de addig nem esett le a tantusz.
Ennyi bevezető után jöjjön a módszer:import bpy
f = open("/tmp/pos.txt", "w")
camera = bpy.data.objects['Camera.003']
for i in range(bpy.context.scene.frame_end):
bpy.context.scene.frame_set(i)
for j in range(4):
f.write(str(camera.location[j]))
f.write(" ")
for j in range(4):
f.write(str(camera.rotation[j]))
f.write(" ")
f.write("\n")
f.close()
A fenti kóddal Blenderből ki tudjuk menteni a kamera pozícióját és forgás szögeit. Természetesen ez még nem megfelelő nekünk. Tegyük fel, minden egyes sor elemeit a pos nevű tömb tárolja. Ebben az esetben a következő kóddal fordíthatjuk őket OpenGL "kompatibilissé":
translate(tr, -pos[0], -pos[2], pos[1]);
rotate(rot, -pos[3] + 1.570796326794897, -pos[5], pos[4]);
matrixMultiply4x4(tr, rot, camera);
Viszont rengeteg időt vesztegettem el a kiderítésével. A másik érdekes kihívás a demó elején három kamera között váltogat a kép, de átmenettel. Ez igazából nem bonyolult, csak én még nem programoztam ilyet. Annyi történt, hogy a jelenetet három kameraállásból textúrába rendereltem, majd a második lépésben, mikor jött a post-processing, a két textúrát mixeltem. Mivel itt a shader mindig két textúrát várt, ezért készült egy nagyon ronda boiler-plate kód, hogy amikor csak egy képet kell mutatni, akkor is van mix, csak 100%-ban a második textúra látszik. Nem szép, de ekkor a sok éjszakázás és gyereksírás között már nagyon nem tudott érdekelni, hogy a kód elegáns legyen.
Az utolsó nap Shamen is meglepett egy stílusos befelyezéssel. Addig a zene egyszerűen csak abbamaradt. Nem volt valami szép, de annyira örültem, hogy nem jártunk úgy, mint Function-ön, hogy nem szóltam miatta. Most pedig még a zene is tökéletes lett!
Szombaton vendégek is jöttek, de csak a gyerkőc érdkelte őket, ezért én észrevétlenül kódolni kezdtem, hogy be tudjam fejezni a demót. Chaten Betasector is bejelentkezett, és az utolsó egy órában adta az instrukciókat, hogyan nézzen ki a demó. Sajnos a második jelenetet így sem tudtam rendesen befejezni. Az alagútas jelenet nagyon lapos lett, ezért Betasector tett bele mintákat és kiadtuk.
Negyedikek lettünk a hét indulóból. Nem lettünk utolsók! A második jelenet hiányosságait majd egy végső változatban utólag kiadjuk.