3D Flash Tutorial

Selbst in Flash 8 kann man leider nur "affine Transformationen" durchführen. Das bedeutet, parallele Linien sind auch nach der Transformation noch parallel. Damit sind zwar Rotieren, Neigen und Skalieren möglich, aber Verzerren mit "Perspektive" lässt sich damit nicht bewerkstelligen. Daran ändert leider auch die neue Matrix Klasse in Flash 8 nichts.
Mittlerweile hat Thomas Pfeiffer aka "kiroukou", die 3D Klasse "Sandy" geschrieben, die 3D Verzerrung emuliert, indem sie die Bitmap in mehrere Dreiecke zerteilt und dann mit affinen Transformationen auskommt.

Flash Texture Mapping

In manchen Fällen ist es damit allerdings noch nicht getan. Nehmen wir einmal an, man bekommt als Vorlage einen mit einem 3D Renderer erzeugten Movie Clip und soll darin Objekte durch dynamisch geladene Bilder austauschen. Wenn die Objekte Rechteckig sind, und die Dimensionen denen der nachzuladenden Bilder entsprechen, ist auch noch alles in Ordnung. Andernfalls hat man ein Problem. Am einfachsten beschreibt es die folgende Illustration:

Perspektivische Verzerrung

Problem

Das Problem stellt sich nun folgendermaßen: Im gerenderten Film sieht man lediglich die Umrisse des Objekts (hier das Dreieck), muss das Bild aber anhand der vier Eckpunkte positionieren. Wir müssen also irgendwie die Eckpunkte der Textur auf die (unsichtbaren) Eckpunkte des Objekts mappen.
Hierfür wählen wir uns vier markante Punkte, die wir in der GUI gut erkennen können, und setzen an ihre Position Markierungen (wie in der Demo von kiroukou). Die Markierungen werden mit AS ausgelesen, auf die vier imaginären Eckpunkte gemappt und schließlich die Textur perspektivisch verzerrt eingeblendet.

Projektionsebene

Ich will Euch nicht mit mathematischen Details langweilen, aber ein kleiner Exkurs in die Lineare Algebra kann nicht schaden:
Seien f1, f2, f3, f4 die vier markanten Punkte als 3D Vektoren, die wir im Video markiert haben. x und y lesen wir aus den Markierungen aus. Den z-Wert setzen wir fest auf 1, und erweitern somit die euklidische Ebene.
Mit diesen vier Vektoren bilden wir ein Gleichungssystem aus drei Gleichungen:

f1 a + f2 b + f3 c = f4
bzw:
f1.x * a + f2.x * b + f3.x * c = f4.x

f1.y * a + f2.y * b + f3.y * c = f4.y
f1.z * a + f2.z * b + f3.z * c = f4.z
a, b und c sind skalare Variablen, die wir als nächstes herausfinden müssen, indem wir das lineare Gleichungssystem mit dem Gauß-Jordan Verfahren lösen.
Schließlich erhalten wir folgende erste Transformationsmatrix:
[ f1.x * a | f2.x * b | f3.x * c ]

[ f1.y * a | f2.x * b | f3.x * c ]
[ f1.z * a | f2.x * b | f3.x * c ]
Diese Matrix M sendet die Koordinaten des sogenannten "Standard Frame" (SF) - (1,0,0), (0,1,0), (0,0,1), (1,1,1) - auf die vier Punkte f1, f2 ,f3, f4.

Genau dasselbe müssen wir als nächstes für die vier ausgesuchten Stellen g1, g2, g3, g4 innerhalb der Textur machen. Diese zweite Matrix N sendet die Koordinaten des SF auf die vier Punkte g1, g2, g3, g4.
Wir wollen aber nicht zweimal vom "Standard Frame" woanders hin transformieren, sondern von der Textur zum SF und dann zum Dummy, also G->S->F.
Mit der Matrix N haben wir S->G und müssen das nur noch invertieren (N') um G->S zu erhalten.
Schließlich multiplizieren wir M und N' und erhalten T.
Die Transformationsmatrix T können wir jetzt mit beliebigen Referenzpunkten der Textur multiplizieren - wir nehmen natürlich die vier Eckpunkte - und erhalten ihre Repräsentation im Movie. Wir müssen die Koordinaten lediglich noch durch Ihre z-Werte dividieren, damit z wieder zu 1 wird und sind fertig.

Beispiel

Ich habe für EscapeFutura einen 3D Flash Shop für Schuhe und Shirts geschrieben.
Nach den Animationen zum Preloaden kann man im Ufo zwischen "shoes" und "shirts" wählen. Bei den Shirts kommt ein Laufband bei dem ich die in diesem Flash Tutorial beschriebene Technik anwenden musste um die Shirts prespektivisch zu verzerren.

Flash Matrix Klasse

Die Flash 8 Matrix Klasse (flash.geom.Matrix) ist leider für unsere Zwecke unbrauchbar. Sie stellt zwar eine 3x3 Matrix dar, man kann allerdings nur die Zellen 2x3 davon setzen, die letzte Zeile ist kostant [ 0 | 0 | 1 ].

Es gibt aber im Netz einen Array.protoype zur Matrix Inversion, Multiplikation und Gauß-Jordan Elimination (letzteres ganz am Ende des Threads). Wenn Ihr einen Fehler bekommt, dass die "flash.geom.Matrix" Klasse nicht geladen werden konnte, dann schaut mal in der Flash FAQ nach.

Wenn Euch diese Seite weitergeholfen hat, dann verlinkt sie bitte. Ihr habt ein Problem? Fragen, Anregungen und Kritik bitte an feedback@lilalinux.net
Ihr könnt mich auch per ICQ erreichen: 1028730, sowie mit Jabber/GoogleTalk/XMPP: lilalinux@jabber.net-lab.net