Animationen in Java 3D Seminararbeit in der Lehrveranstaltung Java 3D FH-Fulda WS 2002/2003 Prof. Dr. Heinzel Verfasst von Gerd Mühlinghaus [email protected] Java 3D – Animation Gerd Mühlinghaus Inhaltsverzeichnis 1. Grundlagen zur Animation mit Java 3D ................................................................................ 3 2. Animationsarten ..................................................................................................................... 3 3. Erstellen einer zeitbasierten Animation in Java 3D ............................................................... 4 3.1 Erstellen des Zielobjekts mit seinen Eigenschaften ......................................................... 4 3.2 Erstellen des Alpha Objektes ........................................................................................... 5 3.3 Erstellen eines Interpolator Objektes mit Verweis auf Alpha und Ziel Objekt ............... 7 3.3.1 ColorInterpolator ....................................................................................................... 7 3.3.2 PositionInterpolator ................................................................................................... 8 3.3.3 RotationInterpolator .................................................................................................. 8 3.3.4 ScaleInterpolator ....................................................................................................... 9 3.3.5 SwitchValueInterpolator ......................................................................................... 10 3.3.6 TransparencyInterpolator ........................................................................................ 10 3.4 Spezifizieren des Wirkungsbereichs des Interpolator Objektes ..................................... 11 3.5 Einfügen des Interpolator Objekts in den Szenegraphen ............................................... 12 4. Die Billboard Klasse ............................................................................................................ 13 4.1 Anwendung eines Billboard Objektes ............................................................................ 13 4.2 Anwendungsbeispiel der Billboard Behavior ................................................................ 14 5. Die Level of Detail Animation ............................................................................................. 15 5.1 Anwendung eines DistanceLOD Objekts ...................................................................... 16 5.2 Anwendungsbeispiel eines DistanceLOD Objektes ....................................................... 16 6. Die Morph Klasse................................................................................................................. 17 6.1 Anwendung eines Morph Objekts .................................................................................. 17 6.2 Anwendungsbeispiel eines Morph Objektes .................................................................. 18 7. Bemerkung ........................................................................................................................... 20 Literaturverzeichnis .................................................................................................................. 21 Anhang Quellcode zum Interpolatoren Beispielprogramm InterpolatorApp.java Anhang Quellcode zum RotationInterpolator Beispielprogramm ClockApp.java Anhang Quellcode zum Billboard Beispielprogramm BillboardApp.java Anhang Quellcode zum DistanceLOD Beispielprogramm DistanceLODApp.java Anhang Quellcode zum Morph Beispielprogramm MorphApp.java Seite 2 Java 3D – Animation Gerd Mühlinghaus 1. Grundlagen zur Animation mit Java 3D Für Animationen in Java 3D wird, wie auch bei Interaktionen, die Behavior Klasse verwendet. Dabei besteht die Möglichkeit auf eine Reihe vorgefertigter Behaviors (Verhalten, hier Animationsverhalten) zurückzugreifen, oder eigene zu entwerfen. Die Verwendung dieser Behaviors bietet den Vorteil, dass diese mit einem visuellen Objekt assoziiert und dadurch ihre Attribute (Farbe, Orientierung, Position, etc.) automatisch angepasst werden. Dem Programmierer wird dabei die Entwicklung wesentlich vereinfacht, da er sich nicht mehr um diese Dinge kümmern muss. Im Gegensatz zu Interaktionen, bei denen ein Benutzer durch seine Eingaben Veränderungen an einem visuellen Objekt im virtuellen Raum vornimmt, spricht man von Animation, wenn Änderungen der virtuellen Welt auch ohne Benutzerinteraktion stattfinden. Ein gutes Beispiel für Animation ist eine Zeigeruhr (Analoguhr) bei der sich die Zeiger ohne direkte Benutzeraktion weiterbewegen. Die Präsentation der von Java 3D angebotenen, vorgefertigten Behaviors, sowie die Vorstellung der Morph Klasse sind Inhalt dieser Präsentation. Als Grundlage hierfür diente das Animations-Tutorial von Sun in der Version 1.5. Auf weitere Literatur wurde weitestgehend verzichtet, da die mir bekannte Literatur ebenfalls nur auf diesem Tutorial aufbaut und nichts wirklich Neues bietet. Im Anhang finden Sie zudem eine von mir angefertigte Übersetzung des 5. Kapitels – Animation – dieses Tutorials. 2. Animationsarten Es gibt verschiedene Möglichkeiten eine Animation in Java 3D zu erzeugen. Zeitbasierte Animation Die erste hier vorgestellte Möglichkeit, ist die Verwendung der Behavior Gruppe der Interpolatoren. Ein Interpolator manipuliert zusammen mit einem Alpha Objekt einige Parameter eines visuellen Objekts um eine zeitbasierte Animation zu erzeugen. Dabei bestimmt das Alpha Objekt die Zeitpunkte an denen die Veränderungen stattfinden und der Interpolator welches Objekt wie verändert werden soll. Blickwinkelbezogene Animation Im Gegensatz zur Zeitgesteuerten steuern die Klassen „Billboard“ und „Level of Detail“ (LOD) eine Animation über den Blickwinkel des Betrachters. Auch diese beiden Klassen sind von der Behavior Klasse abgeleitet. Seite 3 Java 3D – Animation Gerd Mühlinghaus In der folgenden Abbildung1 ist, zum besseren Verständnis, noch einmal die Klassenhierarchie der Animationsklassen dargestellt. Interpolation von Geometrie Um mehr als nur die Veränderung von einzelnen Positionen, Größen etc. visueller Objekte zu ermöglichen, gibt es als weitere Alternative die Morph Klasse. Mit dieser können komplette geometrische Objekte animiert werden. Anders als die zeitbasierte und blickwinkelbezogene Animation ist die Morph Klasse nicht von der Behavior Klasse abgeleitet. 3. Erstellen einer zeitbasierten Animation in Java 3D Das Java 3D Turorial von Sun bietet die folgende Anleitung zum Erstellen einer zeitgesteuerten Animation in Java 3D: Erstellen eines Zielobjektes mit seinen Eigenschaften. Erstellen eines Alpha Objektes. Erstellen eines Interpolator Objektes mit Verweis auf Alpha und Ziel Objekt. Spezifizieren des Wirkungsbereichs des Interpolator Objektes. Einfügen des Interpolator Objekts in den Szenegraphen. 3.1 Erstellen des Zielobjekts mit seinen Eigenschaften Als erstes muss das zu veränderte Zielobjekt erstellt und seine Eigenschaften definiert werden. Die hier festgelegten Eigenschaften können anschließend mit den ausgewählten Interpolatoren verändert werden. Dem in der Einleitung angesprochenen Beispiel der Zeigeruhr folgend, verwenden wir an dieser Stelle die im Sun Tutorial beschriebene Uhr. 1 Abbildung 5-1 des Java 3D Turorials Kapitel 5 Animation Seite 4 Java 3D – Animation Gerd Mühlinghaus // Erstellen des Zielobjektes (hier ein TransformGroup Objekt) TransformGroup objSpin = new TransformGroup(); // mit seinen Eigenschaften. ALLOW_TRANSFORM_WRITE bedeutet, dass die // Parameter des Zielobjekts verändert werden können. objSpin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); 3.2 Erstellen des Alpha Objektes Wie bereits in der Einleitung erwähnt, dient das Alpha Objekt im Wesentlichen dazu einem Interpolator Objekt zu sagen wann dieses seinen Einsatz hat. Es ist sozusagen der Taktgeber oder besser der Zeitgeber eines Interpolators. Das Alpha Objekt produziert den so genannten Alpha Wert, aus dem Intervall [0.0, 1.0]. Da dieser von der Zeit abhängig ist, gibt es zu jedem Zeitpunkt einen anderen Alpha Wert. So ergibt sich während der Zeit die so genannte Alpha Wellenform des Alpha Objekts. Die Alpha Wellenform besteht aus vier Phasen: ansteigendes, gleich bleibendes, absteigendes und bei null befindliches Alpha. Zur besseren Veranschaulichung werden die vier Phasen in der folgenden Abbildung2 graphisch dargestellt. Die Dauer dieser Phasen kann durch einen Integer Wert über vier Parameter des Alpha Objekts eingestellt werden und wird in Millisekunden angegeben. Wichtig ist hierbei der Parameter increasingAlphaDuration der die Dauer eines Zyklus festlegt. 2 Abbildung von S. 26 des 6. Kapitels einer Ausarbeitung über Java 3D von Michael Haller. Seite 5 Java 3D – Animation Gerd Mühlinghaus Da ein Alpha Objekt als Starzeit immer die Systemstartzeit erhält, haben alle Alpha Objekte, auch wenn sie zu unterschiedlichen Zeitpunkten erstellt wurden, die gleiche Startzeit. Dadurch beginnen alle Interpolatoren synchron. Allerdings können die Wellenformen der Alpha Objekte zu unterschiedlichen Zeitpunkten beginnen. Möglich wird dies durch den Einsatz von TriggerTime (Aktivierungszeit) und/oder PhaseDelayDuration (Phasenverzögerungszeit). Dabei bestimmt die Aktivierungszeit einen Zeitpunkt nach der Startzeit, an dem die Operation des Alpha Objektes beginnen soll. Für eine bestimmte Zeit nach der Aktivierungszeit, die durch die Phasenverzögerungszeit festgelegt wird, beginnt der Zyklus der Wellenform. Der loopCount (Schleifenzähler) legt fest, wie oft die Wellenform durchlaufen wird, bestimmt also die Anzahl der Zyklen. Ist der Wert des Schleifenzählers positiv gibt er die Anzahl der Zyklen an. Ein loopCount von -1 hingegen steht für kontinuierliches wiederholen. Eine Alpha Wellenform muss nicht zwingend alle vier Phasen verwenden, sondern kann aus ein bis vier Phasen gebildet werden. In der folgenden Abbildung3 werden sechs der 15 möglichen Kombinationen dargestellt. Das Alpha Objekt hat zwei Modi, die bestimmen welche Untergruppen (subsets) von Phasen verwendet werden. Der INCREASING_ENABLE Modus zeigt an, dass ein steigendes Alpha und ein gleich bleibendes Alpha benutzt werden. Der DECREASING_ENABLE Modus zeigt an, dass ein absteigendes Alpha und ein Alpha bei null benutzt werden. Zurück zu unserem Beispiel mit der Zeigeruhr. Nach dem Festlegen des Zielobjektes erzeugen wir nun ein Alpha Objekt. Dieses soll sich mit der Periode von einer Minute wiederholen. Allgemein: Alpha(int loopCount, long increasingAlphaDuration) Angewendet in unserem Uhrenbeispiel: // Erstellen eines Alpha Objekts // das sich kontinuierlich, mit einer Periode von 1 Minute, dreht. Alpha alpha = new Alpha (-1, 60000); 3 Abbildung 5-3 des Java 3D Turorials Kapitel 5 Animation. Seite 6 Java 3D – Animation Gerd Mühlinghaus 3.3 Erstellen eines Interpolator Objektes mit Verweis auf Alpha und Ziel Objekt Gleich werden wir einen Interpolator erstellen. Doch zunächst noch einmal zum besseren Verständnis: Interpolatoren legen fest welches Objekt auf welche Art animiert werden soll. Dabei sind Interpolatoren eine Anzahl von vordefinierten Kernklassen aus dem Java 3D Package, die von der Behavior Klasse abgeleitet sind (natürlich können auch eigene Interpolatoren erstellt werden). Sie sind von einem Alpha Objekt abhängig, welches ihnen, wie weiter oben erklärt, den Zeitpunkt bekannt gibt an dem sie die vorher festgelegten Manipulationen ausführen sollen. In den Szenengraphen werden sie als Kind ihres (zu verändernden) Zielobjekts eingefügt. An dieser Stelle ist zu beachten, dass die unterschiedlichen Interpolatoren verschiedene Zielobjekte haben (dazu später mehr). Mit der so genannten processStimulus Funktion passen sie ihre Zielobjekte dem Wert ihres Alpha Objektes an und das für jedes keyFrames des Alpha Zyklus. Es gibt verschiedene Möglichkeiten ein Objekt zu animieren, für jede dieser Möglichkeiten gibt es einen eigenen Interpolator. Folgende Interpolator Klassen (mit Angabe ihres Verwendungszweckes) werden von Java 3D unter anderem zur Verfügung gestellt: Interpolator ColorInterpolator PositionInterpolator RotationInterpolator ScaleInterpolator SwitchValueInterpolator TransparencyInterpolator ändert Farbe Position Rotation Größe Aussehen Transparenz Ich werde jetzt alle aufgelisteten Interpolatoren kurz vorstellen und beispielhaft beschreiben wie ihre Einstellungen geändert werden können. Bei Interesse empfehle ich als Weiterführung und Vertiefung die Literatur des Java Tutorials. 3.3.1 ColorInterpolator Ein ColorInterpolator Objekt hat ein Material Objekt als Ziel, welches der NodeComponent zugeordnet ist. Dieser Interpolator ändert die Farbeinstellungen seines Zielmaterials. Er hat die Möglichkeit mehr als ein visuelles Objekt zu haben, das dasselbe Material Objekt verwendet. So kann ein ColorInterpolator mit einem Materialziel mehr als ein visuelles Objekt beeinflussen. Beschränkt ist er allerdings durch die Tatsache, dass visuelle Objekte mit einem Material NodeComponent, nur beleuchtet sichtbar sind. Seite 7 Java 3D – Animation Gerd Mühlinghaus Es gibt folgende Möglichkeiten einen ColorInterpolator zu erstellen: 1. // Erstellen eines einfachen ColorInterpolators mit zugehörigem Alpha und Ziel. ColorInterpolator(Alpha alpha, Material target) 2. // Erstellen eines ColorInterpolators mit zugehörigem Alpha, Ziel, Start- und Endfarbe ColorInterpolator(Alpha alpha, Material target, Color3f startColor, Color3f endColor) Die wichtigsten Methoden eines ColorInterpolators sind: setEndColor, setStartColor, setTarget, getEndColor, getStartColor, getTarget und in ihrer Anwendung gleichen diese ihren o. g. Erstellungsmöglichkeiten. 3.3.2 PositionInterpolator Das Ziel eines PositionInterpolators ist ein TransformGroup Objekt. Der PositionInterpolator verändert die Position eines, oder mehrerer, visueller Objekte entlang einer Achse. Die Einstellungen der Endpunkte dieser Interpolation werden aus zwei Fließkommawerten und einer Achsentranslation berechnet. Die Standard-Achse der Translation ist die x-Achse. Es gibt folgende Möglichkeiten einen PositionInterpolator zu erstellen: 1. // Erstellen eines einfachen PositionInterpolators mit zugehörigem Alpha und Ziel. PositionInterpolator(Alpha alpha, TransformGroup target) 2. // Erstellen eines PositionInterpolators mit zugehörigem Alpha, Ziel, Translations Achse, Start- und Endposition. PositionInterpolator(Alpha alpha, TransformGroup target, Transform3D axisOfTranslation, float startPosition, float endPosition) Die wichtigsten Methoden eines PositionInterpolator sind: setAxisOfTranslation, setEndPosition, setStartPosition, setTarget // Jede dieser set Methoden hat eine passende parameterlose get Methode. und in ihrer Anwendung gleichen diese ihren o. g. Erstellungsmöglichkeiten. 3.3.3 RotationInterpolator Das Ziel eines RotationInterpolators ist, wie bereits beim PositionInterpolator, ein TransformGroup Objekt. Der RotationInterpolator verändert die Drehungsrichtung eines, oder mehrerer, visueller Objekte entlang einer Achse. Die Einstellungen der Endpunkte dieser Interpolation werden aus zwei Fließkommawinkelwerten und einer Drehungsachse berechnet. Die Standard-Achse der Drehung (rotation) ist die y-Achse. Seite 8 Java 3D – Animation Gerd Mühlinghaus Es gibt folgende Möglichkeiten einen RotationInterpolator zu erstellen: 1. // Erstellen eines einfachen RotationInterpolators mit zugehörigem Alpha und Ziel. RotationInterpolator (Alpha alpha, TransformGroup target) 2. // Erstellen eines RotationInterpolators mit zugehörigem Alpha, Ziel, Drehungsachse, // mini- und maximaler Winkel. RotationInterpolator (Alpha alpha, TransformGroup target, Transform3D axisOfRotation, float minimumAngle, float maximumAngle) Die wichtigsten Methoden eines RotationInterpolators sind: setAxisOfRotation, setMaximumAngle, setMinimumAngle, setTarget // Jede dieser set Methoden hat eine passende parameterlose get Methode. und in ihrer Anwendung gleichen diese ihren o. g. Erstellungsmöglichkeiten. 3.3.4 ScaleInterpolator Das Ziel eines ScaleInterpolators ist wiederum ein TransformGroup Objekt. Der ScaleInterpolator verändert die Größe eines, oder mehrerer, visueller Objekte entlang einer Achse. Die Einstellungen der Endpunkte dieser Interpolation werden aus zwei Fließkommawerten berechnet. Es gibt folgende Möglichkeiten einen ScaleInterpolator zu erstellen: 1. // Erstellen eines einfachen ScaleInterpolators mit zugehörigem Alpha und Ziel. ScaleInterpolator (Alpha alpha, TransformGroup target) 2. // Erstellen eines ScaleInterpolators mit zugehörigem Alpha, Ziel, Skalierungsachse, // mini- und maximaler Skalierungswert. ScaleInterpolator (Alpha alpha, TransformGroup target, Transform3D axisOfScale, float minimumScale, float maximumScale) Die wichtigsten Methoden eines ScaleInterpolators sind: setAxisOfScale, setMaximumScale, setMinimumScale, setTarget // Jede dieser set Methoden hat eine passende parameterlose get Methode. und in ihrer Anwendung gleichen diese ihren o. g. Erstellungsmöglichkeiten. Seite 9 Java 3D – Animation Gerd Mühlinghaus 3.3.5 SwitchValueInterpolator Der SwitchValueInterpolator interpoliert Werte nicht so wie andere Interpolatoren es tun. Er wählt eines der Kinder eines Switch Objektes für das Rendering aus. Die Schwellenwerte um zu einem anderen Kind umzuschalten sind dadurch bestimmt, dass der Bereich von 0 bis 1 genau auf die Anzahl der Kinder eines Switch Objektes aufgeteilt worden ist. Es gibt folgende Möglichkeiten einen SwitchValueInterpolator zu erstellen: 1. // Erstellen eines einfachen SwitchValueInterpolators mit zugehörigem Alpha und // Ziel. SwitchValueInterpolator (Alpha alpha, Switch target) 2. // Erstellen eines SwitchValueInterpolators mit zugehörigem Alpha, Ziel, // Schwellenwert des ersten und letzten Kindes. SwitchValueInterpolator (Alpha alpha, Switch target, int firstChildIndex, int lastChildIndex) Die wichtigsten Methoden eines SwitchValueInterpolators sind: setFirstChildIndex, setLastChildIndex, setTarget // Jede dieser set Methoden hat eine passende parameterlose get Methode. und in ihrer Anwendung gleichen diese ihren o. g. Erstellungsmöglichkeiten. 3.3.6 TransparencyInterpolator Ein TransparencyInterpolator Objekt hat ein TransparencyAttributes NodeComponent als Ziel. Dieser Interpolator ändert den Transparenzwert seines Zielobjekts. Er kann mehr als ein visuelles Objekt beeinflussen. Ziehen Sie die Java 3D API Spezifikationen für weiterführende Informationen über die TransparencyAttributes Klasse zu Rate. Es gibt folgende Möglichkeiten einen TransparencyInterpolator zu erstellen: 1. // Erstellen eines einfachen TransparencyInterpolators mit zugehörigem Alpha und // Ziel. SwitchValueInterpolator (Alpha alpha, TransparencyAttributes target) 2. // Erstellen eines TransparencyInterpolators mit zugehörigem Alpha, Ziel, // mini- und maximale Transparenz. SwitchValueInterpolator (Alpha alpha, TransparencyAttributes target, float minimumTransparency, float maximumTransparency) Die wichtigsten Methoden eines TransparencyInterpolators sind: setMinimumTransparency, setMaximumTransparency, setTarget // Jede dieser set Methoden hat eine passende parameterlose get Methode. und in ihrer Anwendung gleichen diese ihren o. g. Erstellungsmöglichkeiten. Seite 10 Java 3D – Animation Gerd Mühlinghaus Ein gutes Beispiel zur Demonstration der eben vorgestellten Interpolatoren ist das Programm InterpolatorApp.java des Sun Tutorials. In diesem Programm wird jedes Interpolator Objekt von einem Alpha Objekt gesteuert. Die folgende Abbildung4 zeigt zwei Szenen die mit InterpolatorApp gerendert wurden. Die Änderungen von position, rotation, scale, color, transparency und switchValue Objekt (von oben nach unten) wurden von den Objekten PositionInterpolator, RotationInterpolator, ScaleInterpolator, ColorInterpolator, TransparencyInterpolator, und SwitchValueInterpolator durchgeführt. Den kompletten Quellcode für InterpolatorApp finden Sie im Anhang. Da sich die Zeiger der Uhr im Clock.java Programm von Sun bereits drehen, werden wir an dieser Stelle einen RotationInterpolator verwenden um die Uhr sich auch noch um die eigene (y-)Achse drehen zu lassen. Jetzt können wir endlich unseren RotationInterpolator erstellen: // Erstellen eines Interpolator Objektes mit Verweis auf Alpha und Ziel Objekt; // mit der Standardeinstellung: volle Drehung um die y-Achse. RotationInterpolator rotInt = new RotationInterpolator(alpha, objSpin); 3.4 Spezifizieren des Wirkungsbereichs des Interpolator Objektes Da Interpolatoren aus Performancegründen nur im Sichtbereich aktiv sind, müssen wir noch dessen Wirkungsbereich festlegen. Dies geschieht mit Hilfe eines Bound Objekts. 4 // Festlegen des Wirkungsbereichs. rotInt.setSchedulingBounds(new BoundingSphere()); Abbildung 5-9 des Java 3D Turorials Kapitel 5 Animation. Seite 11 Java 3D – Animation Gerd Mühlinghaus 3.5 Einfügen des Interpolator Objekts in den Szenegraphen Zu guter letzt fügen wir das Interpolator Objekt noch, mit der bei den Behaviors bekannten addChild() Methode, in den Szenegraphen ein. // Einfügen des Interpolator Objekts in den Szenegraphen. objRoot.addChild(objSpin); objSpin.addChild(new Clock()); objRoot.addChild(rotInt); Der Quellcode der von uns beispielhaft verwendeten createSceneGraph Funktion der ClockApp.java sieht (komplett) folgendermaßen aus: 1. public BranchGroup createSceneGraph() { 2. // Erstellen der Wurzel des branch graph. 3. BranchGroup objRoot = new BranchGroup(); 4. 5. // Erstellen des Zielobjektes (hier ein TransformGroup Objekt). 6. TransformGroup objSpin = new TransformGroup(); 7. // mit seinen Eigenschaften. ALLOW_TRANSFORM_WRITE bedeutet, dass 8. // die Parameter des Zielobjekts verändert werden können. 9. objSpin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); 10. 11. // Erstellen eines Alpha Objekts 12. // das sich kontinuierlich, mit einer Periode von 1 Minute, dreht. 13. Alpha alpha = new Alpha (-1, 60000); 14. 15. // Erstellen eines Interpolator Objektes mit Verweis auf Alpha und 16. // Ziel Objekt; mit der Standardeinstellung: volle Drehung um die 17. // y-Achse. 18. RotationInterpolator rotInt = new RotationInterpolator(alpha, 19. objSpin); 20. // Festlegen des Wirkungsbereichs. 21. rotInt.setSchedulingBounds(new BoundingSphere()); 22. 23. // Einfügen des Interpolator Objekts in den Szenegraphen. 24. objRoot.addChild(objSpin); 25. objSpin.addChild(new Clock()); 26. objRoot.addChild(rotInt); 27. 28. objRoot.compile(); 29. 30. return objRoot; 31. } // Ende der CreateSceneGraph Methode der ClockApp Das ClockApp Programm zeigt die einfache Anwendung einer zeitbasierten Animation mit einem RotationInterpolator. Seite 12 Java 3D – Animation Gerd Mühlinghaus In der folgenden Abbildung5 ist eine um 4:30 Uhr vom ClockApp Beispielprogramm gerenderte Szene zu sehen, bei der die Uhr begonnen hat sich um die y-Achse zu drehen. 4. Die Billboard Klasse Wie bereits in der Einleitung erwähnt, ermöglicht die Billboard Klasse eine blickwinkelbezogene Animation. Sie ist dafür verantwortlich, ein zweidimensionales Bild automatisch so zu drehen, dass es immer dem Betrachter zugewandt ist. Dadurch ist es möglich, 3D-Objekte durch einfache 2D Objekte (Bitmaps) zu ersetzen und auf diese Weise Rechenzeit zu sparen. Die klassische Beispielanwendung einer Billboard Behavior ist es Bäume als 2D Texturen (Oberflächen) darzustellen. Diese wirken auf den Betrachter dreidimensional, da Bäume prinzipiell gleich aussehen, wenn sie von vorne, hinten oder von irgendeinem Winkel aus betrachtet werden. Die Billboard Behavior kann auch verwendet werden, wenn Objekte aus großer Entfernung betrachtet werden. 4.1 Anwendung eines Billboard Objektes Ein Billboard Objekt zu verwenden funktioniert genauso wie der Gebrauch eines Interpolators abgesehen davon, dass es kein Alpha Objekt gibt das die Animation steuert. Die Animation des Billboard Objekts wird durch seine relative Position zum Betrachter in der virtuellen Welt gesteuert. 5 Abbildung 5-5 des Java 3D Turorials Kapitel 5 Animation. Seite 13 Java 3D – Animation Gerd Mühlinghaus Erstellen einer Ziel TransformGroup mit ALLOW_TRANSFORM_WRITE Eigenschaft. Erstellen eines Billboard Objektes mit Verweis auf die Ziel TransformGroup. Spezifizieren des Wirkungsbereichs des Billboard Objektes. Einfügen des Billboard Objekts in den Szenegraphen. 4.2 Anwendungsbeispiel der Billboard Behavior Das BillboardApp Beispielprogramm, aus dem Java 3D Tutorial von Sun, erzeugt eine virtuelle Welt mit Billboard Behavior Bäumen. In diesem Beispiel gibt es für jeden Baum zwei TransformGroup Objekte. Eine TransformGroup, die TGT, bringt (translates) den Baum ganz einfach in die Position der Anwendung. Die zweite TransformGroup, die TGR, sorgt für die Drehung (rotation) der Bäume. Dabei ist TGR das Ziel der Billboard. 1. public BranchGroup createSceneGraph(SimpleUniverse su) { 2. BranchGroup objRoot = new BranchGroup(); 3. 4. Vector3f translate = new Vector3f(); 5. Transform3D T3D = new Transform3D(); 6. 7. // Erstellen einer Ziel TransformGroup. 8. TransformGroup TGT = new TransformGroup(); 9. TransformGroup TGR = new TransformGroup(); 10. Billboard billboard = null; 11. BoundingSphere bSphere = new BoundingSphere(); 12. 13. translate.set(new Point3f(1.0f, 1.0f, 0.0f)); 14. T3D.setTranslation(translate); 15. TGT.set(T3D); 16. 17. // Einstellen der ALLOW_TRANSFORM_WRITE Eigenschaft. 18. TGR.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); 19. 20. // Erstellen eines Billboard Objektes mit Verweis auf die Ziel 21. // TransformGroup. 22. billboard = new Billboard(TGR); 23. 24. //Spezifizieren des Wirkungsbereichs des Billboard Objektes. 25. billboard.setSchedulingBounds(bSphere); 26. 27. // Einfügen des Billboard Objekts in den Szenegraphen. 28. objRoot.addChild(TGT); 29. objRoot.addChild(billboard); 30. TGT.addChild(TGR); 31. TGR.addChild(createTree()); 32. 33. return objRoot; 34. } // Ende der CreateSceneGraph Methode der BillboardApp. In der folgenden Abbildung6 ist ein Bild zu sehen, welches mit dem BillboardApp Programm gerendert wurde. Das eben gezeigte Codefragment zeigt den Code zum Plazieren eines 6 Abbildung 5-16 des Java 3D Turorials Kapitel 5 Animation. Seite 14 Java 3D – Animation Gerd Mühlinghaus animierten Baumes in der virtuellen Welt. Das BillboardApp Programm platziert mehrere Bäume auf einer virtuellen Landschaft, darum sind in dieser Abbildung vier Bäume zu sehen. 5. Die Level of Detail Animation Neben der Billboard ist die Level of Detail Animation die zweite blickwinkelbezogene. Level of Detail ist eine Technik die es erlaubt, die Details eines visuellen Objekts, auf die Entfernung des Betrachters hin zu ändern. Je weiter sich die Entfernung zu einem visuellen Objekt vergrößert, je weniger Details erscheinen beim Rendering. Die Menge an Details eines visuellen Objekts zu verringern, wenn es weit vom Betrachter entfernt ist, reduziert die Menge von Rendering Berechnungen. Wird dies gut gemacht, kann eine signifikante Menge an Rechenoperationen gespart werden, ohne visuellen Verlust des Inhalts. Jedes LOD Objekt hat ein oder mehrere Switch Objekte als Ziel. Ein Switch Objekt gehört zu einer speziellen Gruppe, die eines oder mehrere ihrer Kinder zum Rendern auswählen kann (für mehr Informationen, siehe auch Switch im Sun Tutorial). Mit einem DistanceLOD Objekt, wird die Auswahl des Kindes eines Ziel Switch Objekts, durch die Entfernung des DistanceLOD Objekts zum Blickwinkel kontrolliert, basierend auf eine Gruppe von Schwellenentfernungen. Die Schwellenentfernungen werden in einem Array festgelegt. Beim erreichen eines Schwellenwertes, wird das entsprechende Kind des Ziel Switch Objekts ausgewählt. Seite 15 Java 3D – Animation Gerd Mühlinghaus 5.1 Anwendung eines DistanceLOD Objekts Ein DistanceLOD Objekt zu verwenden funktioniert genauso wie der Gebrauch eines Billboard Objektes, da es ebenfalls kein Alpha Objekt gibt und die Animation des DistanceLOD Objekts durch seine relative Position zum Betrachter in der virtuellen Welt gesteuert wird. Im Sun Turorial findet sich daher die folgende Anleitung: Erstellen einer Ziel Switch Objekts mit ALLOW_TRANSFORM_WRITE Eigenschaft. Erstellen eines Schwellenwert Arrays für das DistanceLOD Objekt. Erstellen eines DistanceLOD Objektes unter Verwendung des Schwellenwert Arrays. Erstellen des Ziel Switch Objekts für das DistanceLOD Objekt. Spezifizieren des Wirkungsbereichs des Billboard Objektes. Einfügen des DistanceLOD Objekts in den Szenegraphen, inklusive dem Einfügen von Kindern zum Ziel Switch Objekt. 5.2 Anwendungsbeispiel eines DistanceLOD Objektes Das Java 3D Tutorial beinhaltet ein einfaches und anschauliches Beispielprogramm für die Anwendung eines DistanceLOD Objektes. Dieses wird im Folgenden kurz beschrieben: 1. public BranchGroup createSceneGraph() { 2. BranchGroup objRoot = new BranchGroup(); 3. BoundingSphere bounds = new BoundingSphere(); 4. 5. // Erstellen eines Ziel Switch Objektes mit ALLOW_TRANSFORM_WRITE 6. // Eigenschaft. 7. Switch targetSwitch = new Switch(); 8. targetSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE); 9. 10. // Einfügen von Kindern zum Ziel Switch Objekt. 11. targetSwitch.addChild(new Sphere(.40f, 0, 25)); 12. targetSwitch.addChild(new Sphere(.40f, 0, 15)); 13. targetSwitch.addChild(new Sphere(.40f, 0, 10)); 14. targetSwitch.addChild(new Sphere(.40f, 0, 4)); 15. 16. // Erstellen eines Schwellenwert Arrays für das DistanceLOD Objekt. 17. float[] distances = { 5.0f, 10.0f, 20.0f}; 18. 19. // Erstellen eines DistanceLOD Objektes unter Verwendung des 20. // Schwellenwert Arrays. 21. DistanceLOD dLOD = new DistanceLOD(distances, new Point3f()); 22. 23. // Erstellen des Ziel Switch Objekts für das DistanceLOD Objekt. 24. dLOD.addSwitch(targetSwitch); 25. 26. // Spezifizieren des Wirkungsbereichs des Billboard Objektes. Seite 16 Java 3D – Animation 27. 28. 29. 30. 31. 32. 33. 34. 35. } Gerd Mühlinghaus dLOD.setSchedulingBounds(bounds); // Einfügen der Objekte in den Szenegraphen. objRoot.addChild(objMove); objMove.addChild(dLOD); objMove.addChild(targetSwitch); return objRoot; // Ende der CreateSceneGraph Methode der DistanceLODApp. 6. Die Morph Klasse In den bisherigen Ausführungen konnten immer nur einzelne Attribute eines visuellen Objekts verändert werden und nie ein ganzes Objekt. Zur Animation kompletter GeometryArray Objekte gibt es die spezielle Morph Klasse. Ein Morph Objekt erzeugt die Geometrie eines visuellen Objekts durch die Interpolation einer Gruppe von geometrischen Objekten. In dieser Sache ist die Morph Klasse wie eine Interpolator Klasse. Die Morph Klasse ist jedoch kein Interpolator; sie ist nicht von der Behavior sondern der Node Klasse abgeleitet. Morph Objekte können dazu eingesetzt werden Pyramiden in Würfel, Katzen in Hunde oder jede Geometrie in jede andere Geometrie umzuwandeln. Die einzige Beschränkung ist, dass die geometrischen Objekte die für die Interpolation genutzt werden von der gleichen Klasse, einer Unterklasse des GeometryArray, sein müssen und die gleiche Anzahl an Punkten haben. Morph Objekte können auch dazu benutzt werden, ein visuelles Objekt zu animieren (z.B. eine Person laufen zu lassen, oder eine Hand greifen zu lassen). 6.1 Anwendung eines Morph Objekts Glücklicherweise ist die Anwendung eines Morph Objektes nicht sehr komplex. Eine Morph Klasse enthält ein Array von GeometryArray Objekten. Jedes individuelle GeometryArray Objekt definiert eine komplette geometrische Beschreibung für das visuelle Objekt inklusive dessen Farbe, Normalen und Texture Koordinaten. Unter den GeometryArray Objekten kann man sich die KeyFrames in einer Animation vorstellen. Neben dem GeometryArray hat das Morph Objekt ein Array mit gewichteten Werten. Diese beiden Arrays werden für die Erstellung eines neuen GeometryArray verwendet. Werden die eingesetzten Gewichte verändert, dann ändert sich auch die Geometrie des Objektes. Im Sun Turorial findet sich daher die folgende Anleitung für die Anwendung eines Morph Objekts: Erstellen eines Arrays mit GeometryArray Objekten. Erstellen eines Morph Objektes mit ALLOW_WEIGHTS_WRITE Eigenschaft. Einfügen des Morph Objekts in den Szenegraphen. Man sieht also, es ist nicht schwer ein Morph Objekt zu verwenden; allerdings bieten die genannten Schritte weder Animation noch Interaktion. Beide werden erst durch ein Behavior Seite 17 Java 3D – Animation Gerd Mühlinghaus Objekt ermöglicht. Konsequenterweise bedeutet ein Morph Objekt zu verwenden für gewöhnlich eine Behavior Klasse zu schreiben. Ein Morph Objekt kann sich auf ein Erscheinungspaket (appearance bundle) beziehen. Das Erscheinungspaket wird mit einem GeometryArray Objekt durch das Morph Objekt erzeugt. Es sollte jedoch beachten werden, dass ein Morph Objekt immer ein GeometryArray Objekt mit per-vertex-colors erzeugt. 6.2 Anwendungsbeispiel eines Morph Objektes Die folgende Morph Anwendung verwendet ein angepasstes Behavior Objekt um Animationen zu ermöglichen. Der erste Schritt dieser Entwicklung ist es, die angepasste Behavior zu schreiben. In dieser ändert die processStimulus Funktion die Gewichte (weights) des Morph Objekts und richtet sich dabei zeitlich nach den Werten eines Alpha Objekts. Außer diesem Codebeispiel wird auf das Erstellen einer eigenen Behavior nicht weiter eingegangen, da es sich hierbei um ein anderes Kapitel der Java 3D API handelt und nichts mit der Animation im eigentlichen Sinn zu tun hat. 1. public class MorphBehavior extends Behavior{ 2. 3. private Morph targetMorph; 4. private Alpha Alpha; 5. 6. // Da in diesem Beispiel 4 Schlüsselbilder verwendet werden, muss das 7. // GeometryArray auch 4 Einträge enthalten. 8. private double[] weights = {0, 0, 0, 0}; 9. private WakeupCondition trigger = new WakeupOnElapsedFrames(0); 10. 11. // Erstellen der MorphBehavior 12. MorphBehavior(Morph targetMorph, Alpha Alpha){ 13. this.targetMorph = targetMorph; 14. this.alpha = Alpha; 15. } 16. 17. public void initialize(){ 18. // Festlegen der initial wakeup condition 19. this.wakeupOn(trigger); 20. } 21. 22. public void processStimulus(Enumeration criteria){ 23. // Initialisieren des Gewichte Arrays. 24. weights[0] = 0; weights[1] = 0; weights[2] = 0; weights[3] = 0; 25. 26. // Ändern der Gewichte in Abhängigkeit von Alpha. 27. float alphaValue = 4f * alpha.value(); 28. int alphaIndex = (int) alphaValue; 29. weights[alphaIndex] = (double) alphaValue - (double)alphaIndex; 30. if(alphaIndex < 3) 31. weights[alphaIndex + 1] = 1.0 - weights[alphaIndex]; 32. else 33. weights[0] = 1.0 - weights[alphaIndex]; 34. 35. targetMorph.setWeights(weights); 36. 37. this.wakeupOn(trigger); //Setzen der nächsten wakeup condition. Seite 18 Java 3D – Animation Gerd Mühlinghaus 38. } 39. } // Ende der MorphBehavior Klasse. Das Ergebnis der MorphBehavior wird in der nächsten Abbildung7 dargestellt. Das nächste Codefragment zeigt einen Auszug der createSceneGraph Funktion der MorphApp Funktion kommentiert mit den Schritten der weiter oben genannten Anleitung der Verwendung eines Morph Objektes. In dieser Funktion werden ein MorphBehavior Objekt, Alpha Objekt, und ein Morph Objekt erzeugt und in den Szene Graph eingefügt. Die Schlüsselbild GeometryArray Objekte werden durch Verwendung einiger anderer Funktionen erzeugt (die hier nicht gezeigt werden). Den kompletten Code finden Sie im Anhang. 1. public BranchGroup createSceneGraph() { 2. // Erstellen der Wurzel des branch graph 3. BranchGroup objRoot = new BranchGroup(); 4. 5. Transform3D t3d = new Transform3D(); 6. t3d.set(new Vector3f(0f, -0.5f, 0f)); 7. TransformGroup translate = new TransformGroup(t3d); 8. 9. // Erstellen eines Arrays mit GeometryArray Objekten. 10. GeometryArray[] geomArray = new GeometryArray[4]; 11. geomArray[0] = createGeomArray0(); 12. geomArray[1] = createGeomArray1(); 13. geomArray[2] = createGeomArray2(); 14. geomArray[3] = createGeomArray3(); 15. 16. // Erstellen eines Morph Objektes mit ALLOW_WEIGHTS_WRITE 16. // Eigenschaft. 17. Morph morphObj = new Morph(geomArray); 18. morphObj.setCapability(Morph.ALLOW_WEIGHTS_WRITE); 19. 20. // Erstellen eines Alpha Objekts. 21. Alpha Alpha = new Alpha(-1, 2000); // continuous 2 sec. period 22. alpha.setIncreasingAlphaRampDuration(100); 23. 24. // Erstellen der Morph Behavior 25. MorphBehavior morphBehav = new MorphBehavior(morphObj, Alpha); 26. morphBehav.setSchedulingBounds(new BoundingSphere()); 27. 28. // Einfügen des Morph Objekts in den Szenegraphen. 29. objRoot.addChild(translate); 30. translate.addChild(morphObj); 7 Abbildung 5-21 des Java 3D Turorials Kapitel 5 Animation. Seite 19 Java 3D – Animation Gerd Mühlinghaus 31. objRoot.addChild(morphBehav); 32. 33. return objRoot; 34. } // Ende der CreateSceneGraph Methode der MorphApp. 7. Bemerkung Bei dieser Präsentation der Animationsaspekte aus der Java 3D API wurde versucht, alle wesentlichen Bestandteile zu integrieren. Als Grundlage diente das bereits erwähnte Java 3D Tutorial von Sun in der Version 1.5, diese ist die offizielle Version der Sun Website (siehe Literatur) und beschreibt die Eigenschaften der Java 3D API v. 1.1.2. Die in der aktuellen API v. 1.2 hinzugekommenen Bestandteile OrientatedShape3D und Partikelanimation konnten daher leider nicht berücksichtigt werden. In diesem Zusammenhang verweise ich auf das neue Tutorial v. 1.6. Seite 20 Java 3D – Animation Gerd Mühlinghaus Literaturverzeichnis [Bouvier 1999] - Bouvier, D. J.: Getting Started with the Java 3D™ API - Chapter 5, Sun Tutorial version 1.5 (Java 3D API v 1.1.2), http://developer.java.sun.com/developer/onlineTraining/java3d/ j3d_tutorial_ch5.pdf, November 2002 [Haller 2001] – Haller, M.: Java 3D Teil 6, http://webster.fhs-hagenberg.ac.at/staff/haller/mmp5_20012002/07java3d_1.pdf, November 2002 Seite 21