Einführung in die Java3D TM -Klassenbibliothek

Ähnliche Dokumente
Java 3D. Linien, Flächen und Objekte Axel Bartsch, Okt. 2002

Java 3D Einstiegs-Tutorial Teil 1

Einführung - Was ist Java3D?

Einführung - Was ist Java3D?

Der Szenegraph. Im Folgenden eine kurze Beschreibung der wichtigsten Knoten des Szenegraphen:

Einführung in Java3D

Einige weitere Fähigkeiten und Anwendungsbeispiele

Schlussendlich geben wir die Listen aus. Es kommt zu folgender Ausgabe:

9. Digitale Verarbeitung 3-dimensionaler Darstellungen

Objektorientierte Programmierung. Kapitel 22: Aufzählungstypen (Enumeration Types)

Computergrafik Universität Osnabrück, Henning Wenke,

Neben der Verwendung von Klassen ist Vererbung ein wichtiges Merkmal objektorientierter

Objekte. Theorieteil. Inhaltsverzeichnis. Begriffe. Programmieren mit Java Modul 5. 1 Modulübersicht 3

Von der UML nach C++

Einstieg in die Informatik mit Java

Java 3D Einstiegs-Tutorial Teil 3

Prof. Dr. Wolfgang Schramm. Vorlesung. Techniken der Programmentwicklung. Exkurs: Anonyme Klassen

Objektorientierte Programmierung Studiengang Medieninformatik

Programmieren II. Innere Klassen. Heusch 10, Ratz 5.2.1, Institut für Angewandte Informatik

Kapitel 9. Programmierkurs. Attribute von Klassen, Methoden und Variablen. 9.1 Attribute von Klassen, Methoden und Variablen

Vererbung, Polymorphie

Implementieren von Klassen

Vererbung. Gerd Bohlender. Institut für Angewandte und Numerische Mathematik. Vorlesung: Einstieg in die Informatik mit Java 14.1.

Einstieg in die Informatik mit Java

Einstieg in die Informatik mit Java

3D-Grafik und -Animation: Java3D

Programmieren in Java -Eingangstest-

1 Abstrakte Klassen, finale Klassen und Interfaces

Vererbung. Gerd Bohlender. Institut für Angewandte und Numerische Mathematik. Vorlesung: Einstieg in die Informatik mit Java 23.5.

Humboldt-Universität zu Berlin Wintersemester 2010/11 Institut für Informatik Grundlagen der Programmierung. 6. Übungsblatt

Institut für Programmierung und Reaktive Systeme. Java 6. Markus Reschke

Universität Augsburg, Institut für Informatik Sommersemester 2001 Prof. Dr. Martin Ester 08. Oktober Klausur II

ADT: Verkettete Listen

12 Abstrakte Klassen, finale Klassen und Interfaces

Exkurs: ANONYME KLASSEN. Techniken der Programmentwicklung Prof. Dr. Wolfgang Schramm

Shader. Computer Graphics: Shader

Grafik-Programmierung

Einstieg in die Informatik mit Java

Einstieg in die Informatik mit Java

B6. 3D-Computergrafik mit Java

Programmierung Nachklausurtutorium

Silke Trißl Wissensmanagement in der Bioinformatik. Objektorientierte Programmierung (OOP) Vorstellung wie in der realen Welt: Farbe Hubraum Tank...

Methoden und Klassen. Silke Trißl Wissensmanagement in der Bioinformatik

Programmieren in Java

Objektorientierung (OO)

Johannes Unterstein - TINF16 - Java - Sommersemester 2017 JAVA. Weiterführende Spracheigenschaften

Klausur Software-Entwicklung März 01

7.1 Polygon Offset. Anwendung - Darstellung von Polygonen als Teil von Oberflächen - Beispiel: Gradlinien auf der Erde - Schwierigkeit:

Handbuch für die Erweiterbarkeit

Einführung in die Programmierung

Übung Datenstrukturen. Objektorientierung in C++

Algorithmen und Datenstrukturen 06

EAD II Übung 5. Graphische Benutzungsoberfläche mit BlueJ

Zellaufbau Java 3D Verteilungsalgorithmus

Institut für Informatik und Angewandte Kognitionswissenschaften

B6. 3D-Computergrafik mit Java

Silke Trißl, Prof. Ulf Leser Wissensmanagement in der Bioinformatik. Jede Applikation braucht eine Klasse mit einer main-methode

1 Klassen und Objekte

Einführung in die Programmierung für NF MI. Übung 07

Java 3D Einstiegs-Tutorial Teil 2 Steuerung des Erscheinungsbildes (Appearance):

Kapitel 13. Abstrakte Methoden und Interfaces. Fachgebiet Knowledge Engineering Prof. Dr. Johannes Fürnkranz

Durch die Teil-von-Beziehung soll ausgedrückt werden, dass ein Objekt A als (physikalischer) Teil eines Objekts B angesehen wird. Insbesondere kann ei

Polymorphie und UML Klassendiagramme

Probeklausur: Programmierung WS04/05

ÜBUNGEN ZUR OBJEKTORIENTIERTEN MODELLIERUNG

Probeklausur Java Einführung in die Informatik. Wintersemester 2016/2017

Vorbereitende Aufgaben

Umsetzung einer Klassenkarte in einer Programmiersprache

Vorbereitende Aufgaben

Aufgabenblatt 2. Kompetenzstufe 2. Allgemeine Informationen zum Aufgabenblatt:

3. Klassen Statische Komponenten einer Klasse. Klassenvariablen

Übungsblatt 10: Klausurvorbereitung

Algorithmen und Datenstrukturen 07

1. Referenzdatentypen: Felder und Strings. Referenz- vs. einfache Datentypen. Rückblick: Einfache Datentypen (1) 4711 r

1. Referenzdatentypen: Felder und Strings

Programmierpraktikum 3D Computer Grafik

Universität Augsburg, Institut für Informatik Sommersemester 2001 Prof. Dr. Martin Ester 16. Juli Klausur

Fragen zur OOP in Java

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 16/17. Kapitel 13. Listen. Listen 1

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 15/16. Kapitel 12. Listen. Listen 1

1 Einleitung Generizität Syntax... 2

Rechtsbelehrung. Java und OOP Das Buch Christian Silberbauer 144

Kapitel 8. Programmierkurs. Methoden. 8.1 Methoden

Javakurs FSS Lehrstuhl Stuckenschmidt. Tag 3 - Objektorientierung

Objektorientierte Programmierung

Kapitel 10. Verweise und Referenzen. Fachgebiet Knowledge Engineering Prof. Dr. Johannes Fürnkranz

C++ Notnagel. Ziel, Inhalt. Programmieren in C++

Durch die Möglichkeit, Ein- und Ausgaben auf der Konsole durchzuführen, kann man auch systematisch das Verhalten von Klassen analysieren.

Einführung in die Programmierung 1

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 11/12 1. Kapitel 11. Listen. Listen

Definition eigener Knotentypen: Prototypen

Info B VL 11: Innere Klassen/Collections

Repetitorium Informatik (Java)

C++ - Objektorientierte Programmierung Konstruktoren und Destruktoren

Erstellung geometrischer Figuren und Verwendung von Texturen in Java 3D

OOP und Angewandte Mathematik. Eine Einführung in die Anwendung objektorientierter Konzepte in der angewandten Mathematik

Transkript:

Einführung in die Java3D TM -Klassenbibliothek Sebastian Bergmann (mailto:sebastian.bergmann@web.de) Kay Küsgen (mailto:kuesgen@informatik.uni-bonn.de) Kay Michael Masslow (mailto:kuesgen@informatik.uni-bonn.de) Stand: 26. März 2000

Vorwort Diese Einführung in die Java3D TM -Klassenbibliothek entstand im Rahmen des Programmierpraktikums Grafik und Sprache in Java im Sommersemester 2000 an der Universität Bonn. Diese Dokumentation wurde mit dem pdfl A TEX-Paket erzeugt und enthält dokumentinterne Verweise sowie WWW-Links. Wir empfehlen den Einsatz eines Anzeigeprogramms, das diesen Merkmalen Rechnung trägt. 1

Inhaltsverzeichnis 1 Einleitung 4 2 Grundkonzepte der Java3D TM - Klassenbibliothek 5 2.1 Übersicht......................................... 5 2.2 Funktionsweise von Java3D TM............................. 6 2.2.1 Kochrezept.................................... 8 2.2.2 Nützliche Hilfsklassen:.............................. 8 2.3 Erstes Beispiel...................................... 8 2.4 Modifikation von Szenen................................. 11 2.5 Anzeige und Koordinatensystem von Java3D TM.................... 11 3 Darstellung von Objekten und Erzeugen von Geometrie 13 3.1 Einleitung (Ausblick auf die Welt nach ColorCube).................. 13 3.2 Geometric Utility Classes (Welt aus Kugeln, Kegeln Quadern und Zylindern)... 14 3.2.1 Box........................................ 14 3.2.2 Cone........................................ 14 3.2.3 Sphere....................................... 14 3.2.4 Cylinder...................................... 15 3.3 Appearance........................................ 16 3.3.1 PointAttributes.................................. 16 3.3.2 LineAttributes.................................. 17 3.3.3 PolygonAttributes................................ 17 3.3.4 ColoringAttributes................................ 18 3.3.5 TransparencyAttributes............................. 18 3.4 Geometry......................................... 20 3.4.1 Überblick..................................... 20 3.4.2 Shape3D..................................... 20 3.4.3 Die Klassen PointArray, LineArray, TriangleArray und QuadArray... 22 3.4.4 GeometryArray.................................. 23 3.4.5 Unterklassen von GeometryStripArray.................... 25 3.4.6 Unterklassen von IndexedGeometryArray................... 26 4 Geometrische Transformationen und Java3D TM 29 4.1 Einleitung......................................... 29 4.2 Transformationen und Koordinatensysteme...................... 29 4.2.1 Translation.................................... 30 4.2.2 Skalierung..................................... 30 4.2.3 Rotationen.................................... 31 4.2.4 Transformationen konkatenieren und Anwendung durch Java3D TM..... 32 4.2.5 Beispiel...................................... 33 4.3 Blickkoordinatensystem und perspektivische Projektion......................................... 38 2

INHALTSVERZEICHNIS 3 A Ungereimtheiten 40 A.1 Java3D TM und das Swing-Paket............................. 40 A.2 Namensüberschneidungen................................ 41 A.3 VRML-Loader...................................... 41 A.4 Manipulation von Szenebäumen............................. 41 A.5 Farbverlaufsinterpolation bei Flächendarstellung................... 42 B Begriffserklärungen 43 C Literatur und Verweise 44

Kapitel 1 Einleitung Die Java3D TM -Klassenbibliothek stellt innerhalb der Java-Produktfamilie den Ansatz dar, eine Schnittstelle für die Darstellung und Manipulation dreidimensionaler Szenerien bereitzustellen. Die Bibliothek implementiert selbst Objekte und Methoden zur Repräsentation einer Szenerie und nutzt für deren Darstellung ausschließlich vorimplementierte und an das jeweilige Betriebssystem angepaßte Funktionsbibliotheken. Derzeit sind angepaßte Fassungen der Java3D TM - Klassenbibliothek für OpenGL von SiliconGraphics (www.sgi.com) auf Windows NT und diversen UNIX-Plattformen erhältlich sowie eine Version für Direct3D auf Windows 9x und Windows 2000. Hierdurch erbt die Java3D TM -Klassenbibliothek einen Großteil der Vorteile, die die herstellerspezifischen Implementationen an Optimierungen mitbringen, beispielsweise wird das Zeichnen (und z.t. sogar die Transformation) von Objekten heutzutage schon durchweg durch die Videohardware beschleunigt. In dieser Einführung erläutern wir im Kapitel 2 die grundlegenden Schritte zur Erstellung eigener kleinerer Anwendungen, die die Java3D TM -Klassenbibliothek nutzen. In Kapitel 3 zeigen wir, wie Verhalten und Aussehen einer dreidimensionalen Umgebung zu beeinflussen sind und Kapitel 4 befaßt sich mit der Manipulation der Objekte im Raum. Um maximalen Nutzen aus dieser Einführung zu ziehen, sollte der Leser allerdings mit folgenden Themen vertraut sein. Programmierung in Java, insbesondere Verständnis Java-spezifischer Konstrukte wie Klassen, Interfaces, lokale Klassen, Exceptions und deren Behandlung. Verständnis der Entwicklung (einfacher) Anwendungen mit grafischer Benutzeroberfläche, insbesondere der Klassen java.awt.frame und java.applet.applet. Ebenso sollte die Funktionsweise des Ereignisbehandlungsmodells in Java 1.1.x und höher keine Neuheit sein. Ein grundlegendes Verständinis über Prinzipien der grafischen Darstellung dreiminsionaler Objekte, wie die Darstellung der grundlegenden Operationen Skalierung, Rotation und Translation als 4 4-Matrizen, deren Konkatenation und Anwendung der so erhaltenen linearen Abbildung auf einen Vektor sind ebenfalls von Vorteil; eine kurze Einführung geben wir jedoch in Kapitel 4. 4

Kapitel 2 Grundkonzepte der Java3D TM - Klassenbibliothek 2.1 Übersicht Die Java3D TM -Klassenbibliothek besteht aus 16 einzelnen Paketen, die die Repräsentation dreidimensionaler Geometrie implementieren, sowie Aufrufe der vom Betriebssystem bereitgestellten Routinen für deren Darstellung kapseln. Darunter enthält die Bibliothek ein Paket, das Vektorgeometrie implementiert. Die übrigen Pakete enthalten Klassen zur Einbringung von Klängen und vielerlei Hilfsklassen, von denen einige die Entwicklung von Anwendungen sehr vereinfachen und als schnell zu verwendende Grundkomponenten in einer Anwendung dienen können. Dies sind z.b.: Die Klasse SimpleUniverse aus dem Paket com.sun.j3d.utils.universe, die den gesamten Zweig der Transformation von Objekten aus dem Objektraum in den Blickraum und deren perspektivische Darstellung übernimmt. Die Klassen des Paketes com.sun.j3d.utils.geometry, die vordefinierte Grundobjekte wie Würfel, Quader, Kugeln oder Prismen bereitstellen (mehr in Kapitel 3). Die Paketfamilie com.sun.j3d.utils.behaviors.*, die u.a. ein einfaches Modell zur Reaktion der Anwendung auf Benutzereingaben aus der Maus und der Tastatur implementiert. Ferner gibt es Funktionsgeneratoren (interpolators), deren generierte Werte auf Parameter von Objekten abgebildet werden können. Auch findet sich ein Paket, das Funktionen für die Rücktransformation aus der zweidimensionalen Darstellung in den Objektraum bereitstellt. Das Paket com.sun.j3d.loaders, das eine Grundklasse für das Laden von 3D-Grafikformaten enthält. Die mit der Java3D TM -Klassenbibliothek ausgelierferte Subklasse von Loader ermöglicht das Laden von Objekten im Lightwave-Format. Weitere Subklassen können von anderen Stellen heruntergeladen werden, die auf java.sun.com gelinkt sind oder in Anhang C gefunden werden können. Die Qualität und Vollständigkeit dieser Implementationen weichen jedoch stark voneinander ab. Die übrigen Pakete enthalten Hilfsklassen für verschiedene Situationen wie vereinfachtes Laden von Texturen, Einbringung von Sound oder ein angepaßtes Appletgerüst. 5

KAPITEL 2. GRUNDKONZEPTE DER JAVA3D TM - KLASSENBIBLIOTHEK 6 2.2 Funktionsweise von Java3D TM Java3D TM faßt jegliche dreidimensionale Szenerie (Objekte, Transformationen, Parametermodulation (!)) als Wurzelbaum auf, exakter als gerichteten antizyklischen Graphen (DAG). (Die Gewährleistung der Antizyklik ist von besonderer Bedeutung). Dabei finden sich Geometrie und Matrizen gleichberechtigt als Knoten im Baum und Java3D TM kümmert sich selbstständig um die Konkatenation und Anwendung der Abbildungen innerhalb der Szene, sowie die verdeckungs- und perspektivisch korrekte Darstellung. Um die Szene zu ändern benötigt der Anwender beispielweise lediglich eine Referenz auf das Matrizenobjekt, das die gewünschte Transformation repräsentiert. Manipuliert er dieses, veranlaßt Java3D TM selbstständig eine Aktualisierung der Darstellung. Eine Szenerie in Java3D TM wird als virtuelles Universum aufgefaßt, in dem alle notwendigen Parameter wie Objekte, Transfomationen, Betrachterstandort 1 als Zweige eines Baumes eines Szeneriebaumes gespeichert sind.objekte in diesen Zweigen sind Subklassen von javax.media.j3d. Leaf oder javax.media.j3d.group, die wiederum von javax.media.j3d.node abgeleitet sind. An Instanzen der Subklassen von Group können ihrerseits wiederum Kinder mit der Methode addchild(node n) angehangen werden, jedoch endet ein Zweig an einer Instanz der Klasse Leaf. Eine komplette Szene in Java3D TM könnte z.b. dieses Aussehen haben: Abbildung 2.1: Grundgerüst einer Java3D TM -Szene 1 Es besteht durchaus die Möglichkeit, innerhalb des Blickzweiges des Szeneriebaumes mehrere Anzeigekomponenten (viewports, hier ViewPlatform-Knoten) anzulegen und Java3D TM anzuweisen, diese auch gleichzeitig zu aktualisieren und darzustellen.

KAPITEL 2. GRUNDKONZEPTE DER JAVA3D TM - KLASSENBIBLIOTHEK 7 Die Symbole haben die folgenden Bedeutungen: Ein Objekt der Klasse javax.media.j3d.virualuniverse ist die Wurzel einer jeden Java3D TM - Szenerie. Es enthält lediglich eine Referenz auf ein Locale- Objekt. Es wird empfohlen, innerhalb einer Java3D TM -Anwendung nur ein einziges VirtualUniverse-Objekt zu verwenden. Ein javax.media.j3d.locale-objekt ist ein Knoten direkt unterhalb der Wurzel, der den Baum in 3D-Objektzweige und Blickzweig spaltet (obwohl hier nur jeweils ein Zweig dargestellt ist). Ein Locale-Object referenziert zum einen das VirtualUniverse-Objekt und ermöglicht mit der Funktion addcontentbranch(), das Anhängen von Teilbäumen an diesen Knoten. Instanzen von Group repräsentieren Teilbäume innerhalb der Szenerie. Besonders hervorzuheben sind die Klassen BranchGroup und TransformGroup. BranchGroup dient zur Referenzierung eines oder mehrer beliebig gearteter Teilbäume (BranchGroups oder TransformGroups) oder mehrerer Leaf- Objekte. TransformGroups leisten dasselbe, beherbergen jedoch eine oder mehrere Matrizen, die auf die Geometrien, die die TransformGroup als Kinder hat, angewandt werden. Transformationsobjekte (Matrizen oder Konkatenationen von Matrizen, Kapitel 4) werden als Objekte des Typs Transform3D mit settransform3d(transform3d t) gesetzt. Klassen des Typs Shape3D sind von Leaf abgeleitet und repräsentieren eine Hülle für ein darstellbares 3D-Objekt. Das Objekt referenziert ein Geometryund ein Appearance-Objekt. Ein weiteres besonderes Leaf-Objekt ist die Klasse ViewPlatform, die Parameter für die Position,Orientierung und Skalierung des Betrachers enthält. Diese Klasse ist innerhalb des Blickzweiges angesiedelt. Die Klassen Geometry und Appearance sind beide Subklassen von NodeComponent, einer Klasse, deren Objekte von Shape3D-Objekten referenziert werden. Geometry ist ein Grundtyp für Objekte, die Koordinaten (meist Vertices und Linien) der Hülle von 3D-Objekten enthalten. Appearance referenziert einige Unterklassen, die das Aussehen der Objekte bestimmen, wie beispielsweise die Darstellung als Punkt, Linien, gefüllten (texturierten) Flächen, Farbe u.s.w. (siehe Kapitel 3). Besonderer Erwähnung bedürfen noch einige weitere Klassen, die den Blickzweig der Szene betreffen: Das View-Objekt steuert alle Parameter, die nötig sind, um die Szenerie in einen zweidimensoinalen Blick zu transformieren und referenziert die weiteren notwendigen Objekte dazu, wie das ViewPlatform-Objekt, den Canvas3D u.s.w.. Das Canvas3D-Objekt, eine Subklasse von java.awt.canvas stellt zu diesem Zeitpunkt die einzige Möglichkeit dar, Java3D TM -Szenen auf dem Bildschirm darzustellen. Die Klasse PhysicalBody versucht, physiologische Eigenschaften des Betrachters nachzumodellieren, wie z.b. die Positionen der Augen oder der Ohren. PhysicalBody und PhysicalEnvironment werden jeweils durch das View-Objekt referenziert. Das Screen3D-Objekt speichert die physikalischen Eigenschaften des Bildschrims. (Diese Klassen wollen wir nicht näher betrachten, da uns die in Abschnitt 2.2.2 zu besprechenden Hilfsklassen die Arbeit erleichtern.)

KAPITEL 2. GRUNDKONZEPTE DER JAVA3D TM - KLASSENBIBLIOTHEK 8 2.2.1 Kochrezept Im SUN-Tutorial findet sich ein allgemeines Rezept für den grundsätzlichen Aufbau von Java3D TM - Programmen, das wir hier zitieren wollen: 1. Ein Canvas3D-Objekt erzeugen 2. Ein VirtualUniverse-Objekt erzeugen 3. Ein Locale-Objekt erzeugen und mit dem VirtualUniverse-Objekt verknüpfen, am einfachsten durch Angabe als Argument im Konstruktor von Locale 4. Einen Blickzweig erzeugen (a) Ein View-Objekt erzeugen (b) Ein ViewPlatform-Objekt erzeugen (c) Ein PhysicalBody-Objekt erzeugen (d) Ein PhysicalEnvironment-Objekt erzeugen (e) Die ViewPlatform-, PhysicalBody-, PhysicalEnvironment- und Canvas3D-Objekte dem View-Objekt zuweisen mit der jeweils passenden set*-funktion des View -Objektes 5. Einen Objektzweig erzeugen 6. Die Zweige kompilieren mit BranchGroup.compile() 7. Die Zweige an das Locale-Objekt anhängen. Die Untergruppe des Blickzweiges (4) läßt sich eleganter (und minder fehlerträchtig) mit einer geeigneten Hilfklasse erzeugen, nämlich SimpleUniverse aus Abschnitt 2.2.2. 2.2.2 Nützliche Hilfsklassen: Der Anfang der Arbeit mit Java3D TM wird durch eine wahre Parameterflut und wohlzudurchdenkende Initialisierungen der Komponenten erschwert, sodaß wir dringend raten, die in den com.sun.utils.-paketen zur Verfügung gestellten Hlfsklassen für die ersten Gehversuche zu verwenden. com.sun.j3d.utils.universe.simpleuniverse Der gesamte Blickzweig (die rechte Seite von Abbildung 2.1) wird durch eine Instanz von SimpleUniverse mit sinnvollen Voreinstellung erzeugt. Der einzige Parameter, der zur Darstellung benötigt wird, ist ein Canvas3D-Objekt. SimpleUniverse kann Referenzen auf seine Objekte liefern, sodaß diese Klasse oft ausreicht, um den gesamten Blickzweig einer Anwendung zu liefern. com.sun.j3d.utils.geometry.colorcube Das einfachste darstellbare Objekt vom Typ Shape3D ist dieser Würfel mit farbigen Flächen und einer Seitenlänge von 1. Er ist ideal, um schnell in eine Szene integriert zu werden, wenn geprüft werden soll, ob die darstellenden Komponenten richtig initialisiert wurden (Weitere Typen dieses Paketes werden in Kapitel 3 besprochen). 2.3 Erstes Beispiel Das folgende Beispiel zeigt schrittweise die Erzeugung einer Anwendung, die einen einfachen, leicht um die y-achse gedrehten Würfel darstellt. Wir machen ausgiebig Gebrauch von den zuvor in Abschnitt 2.2.2 vorgestellten Hilfsklassen: Zuerst die nötigen import-anweisungen:

KAPITEL 2. GRUNDKONZEPTE DER JAVA3D TM - KLASSENBIBLIOTHEK 9 import java.awt.*; import javax.media.j3d.*; import com.sun.j3d.utils.universe.simpleuniverse; import com.sun.j3d.utils.geometry.colorcube; Die Klasse Beispiel00 ist ein erweitertes Fenster mit der Canvas3D-Komponente zum Anzeigen unserer Szene public class Beispiel00 extends Frame { Der Konstruktor von Beispiel00 nimmt eine Zeichenkette als Fenstertitel entgegen: public Beispiel00 (String title) { Die Zeichenkette reichen wir an die Vaterklasse weiter: super(title); Die Klasse java.awt.graphicsconfiguration beherbergt Information über die Anzeigeumgebung unserer Anwendung, beispielsweise Farbtiefe und Transparenzwerte der Pixel. Wir verwenden die statische Hilfsfunktion getpreferredconfiguration() der Klasse SimpleUniverse die eine zu unserer Anzeige kompatible Instanz von GraphicsConfiguration erzeugt (Dies erspart u.a. die Wahl eines geeigenten Farbmodells u.s.w.)... GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();... und übergeben diese Instanz als Argument an den Konstruktor von Canvas3D, der als Anzeigefläche für die kleine Szene dient. Canvas3D canvas3d = new Canvas3D (config); Wir fügen unser Canvas3D-Objekt dem Clientbereich des Fensters zu. Die Initialisierung der Fensterkomponenten ist damit abgeschlossen. add(canvas3d); Wir erzeugen nun ein Universum, das unsere Szene beherbergt. Die Klasse SimpleUniverse erzeugt den gesamten Blickzweig (ViewPlatform, View, PhysicalBody und PhysicalEnvironment) mit sinnvollen Voreinstellungen. Wir verknüpfen unser Universum mit dem Canvas3D-Objekt als Anzeigefläche, indem wir es dem Konstruktor übergeben. SimpleUniverse universe = new SimpleUniverse(canvas3d); Die folgende Aufrufkette sorgt dafür, daß der virtuelle Betrachter einen Schritt zurückgeht, um aus einiger Entfernung einen besseren Überblick zu haben: Die Funktion getviewingplatform( ) liefert eine Instanz des ViewingPlatform-Objekts, das für die Darstellung zuständig ist. Die Funktion setnominalviewingtransform() der ViewingPlatform-Klasse stellt den Betrachter 2,41 Meter auf die positive z-achse mit Blick in die negative z-richtung (zur Orientierung und Koordinatensystem von Java3D TM im folgenden Abschnitt). universe.getviewingplatform().setnominalviewingtransform(); Nun erzeugen wir unseren Würfel, den die Hilfsklasse com.sun.utils.geometry.colorcube vordefiniert. Wir vermindern seine Kantenlänge auf 40cm, da er sonst ein wenig zu groß erscheint: ColorCube colorcube = new ColorCube(0.4); Die Transform3D-Klasse beherbergt 4 4-Transformationsmatrizen, die Java3D TM auf Geometrien in Kindknoten anwendet. Der Standardkonstruktor erzeugt ein Transform3D-Objekt mit einer 4 4-Identitätsmatrix als Transformation.

KAPITEL 2. GRUNDKONZEPTE DER JAVA3D TM - KLASSENBIBLIOTHEK 10 Transform3D transform3d = new Transform3D(); Transform3D-Objekte besitzen eine Reihe von Hilfsfunktionen, die die Komponenten der ihrer Transformationsmatrizen so initialisieren, daß sie die gewünschte Standardoperation auf 3D- Objekten durchführen. Wir erzeugen eine Drehung von 30 um die Y-Achse: transform3d.roty (Math.toRadians(30)); Wir haben nun die Anzeigeumgebung mit Blickzweig, ein Objekt und eine Transformation bereitgestellt. Es gilt nun, den eigentlichen Szenenbaum aufzubauen: TransformGroup-Objekte referenzieren zum einen andere Knoten und führen zum anderen die Transformation, die ihr gespeichertes Transform3D-Objekt innehat, auf ihren Kindknoten aus. Unser TransformGroup-Objekt transformgroup erhält unser Transform3d-Objekt transform3d als Transformation... TransformGroup transformgroup = new TransformGroup(transform3d);... und den Würfel als Geometrie-Objekt transformgroup.addchild(colorcube); Um unseren Zweig an das Locale-Objekt anhängen zu können, erzeugen wir einen leeren BranchGroup-Knoten, denn Locale erlaubt nur BranchGroup-Objekte als Kinder... BranchGroup branchgroup = new BranchGroup();... und hängen den Zweig mit dem Würfel und der Transformation an. branchgroup.addchild(transformgroup); Nun wird der Gesamtzweig an das Universum gehängt. universe.addbranchgraph(branchgroup); } Damit ist die Anwendung vollständig für die Anzeige gerüstet. Wir machen aus der Klasse eine Anwendung, die ausgeführt werden kann: public static void main(string args[]) { Beispiel00 beispiel = new Beispiel00("Beispiel00 - gedrehter Wuerfel"); beispiel.setsize(600,400); } } Hier das Ergebnis unter Windows NT mit 16-bit-Farbtiefe (Je nach Hardwarekonfiguration kann das Aussehen des Würfels stark variieren.): Abbildung 2.2: Beispiel00.java Man kann sich schnell davon überzeugen, daß der Szenenbaum dieser Abbildung extakt dem aus Abbildung 2.1 entspricht.

KAPITEL 2. GRUNDKONZEPTE DER JAVA3D TM - KLASSENBIBLIOTHEK 11 2.4 Modifikation von Szenen Die hier vorgestellte Szene wird während des Programmablaufs nicht modifiziert. Der Aufbau geschieht ausschließlich durch Verwendung der add()-methode des Group-Objektes und das Ergebnis ist ein Szenebaum. Java3D TM nimmt bei der Erzeugung von Szenebäumen, insbesondere bei Verwendung der compile()-methode nicht näher beschriebene Optimierungen (Geometriekompression u.s.w.) in der internen Darstellung der Objekte vor, was die Konsequenz hat, daß der Zugriff auf alle Komponenten eines Szenebaums mehr oder weniger stark eingeschränkt ist: Beim Anhängen von Teilbäumen an Group-Objekte und dem Referenzieren von Geometrie- und Apprearance-Objekten durch Leaf-Objekte wird das Schreiben und Lesen von Objekten dessen, was die Objekte referenzieren, verboten. Der Zugriff muß explizit durch Verwendung der setcapability-methode der SceneGraphObject-Klasse, der Vaterklasse beinahe aller Java3D TM - Klassen, erlaubt werden, andernfalls generiert Java3D TM zur Laufzeit eine Ausnahme. Alle Subklassen der SceneGraphObject-Klasse besitzen Konstanten, die als Argument dieser Methode dienen und die man in der Referenz nachschlägt. Mehrere Capabilities werden verodert. Will man zur Laufzeit des Programms, z.b. in Abhängigkeit von Benutzereingaben das Aussehen des colorcube-objektes auslesen oder ändern, muß bei seiner Erzeugung der Aufruf colorcube.setcapability (Shape3D.ALLOW_APPEARANCE_READ Shape3D.ALLOW_APPEARANCE_WRITE); erfolgen. Will man einen Teilzweig (Group und deren Subklassen) eines Szeneriebaumes entfernen, sind sogar zwei Vorkehrungen notwendig: Sind parent und child Instanzen von BranchGroup und wird child an parent angehängt und beabsichtigt, child später wieder zu entfernen, ist folgendes zu tun: Nach der Erzeugung von parent: parent.setcapability(group.allow_children_write); Nach der Erzeugung von child: child.setcapability(branchgroup.allow_detach); Nach dem Aufruf parent.add(child); kann child mit child.detach() von parent abgetrennt und gelöscht werden. Wenn ein Kindknoten nachträglich an eine BranchGroup angehangen werden soll, muß parent.setcapability(group.allow_children_extend); aufgerufen werden. Für TransformGroups gilt ähnliches. Die Konstanten TransformGroup.ALLOW_ TRANSFORM_READ und TransformGroup.ALLOW_TRANSFORM_WRITE steuern den Lese- und Schreibzugriff. 2.5 Anzeige und Koordinatensystem von Java3D TM Die untere Abbildung zeigt die Orientierung der Raumachsen in Java3D TM. Die Ausrichtung eines solchen Koordinatensystems wird als rechtshändig bezeichnet und kann nicht geändert werden. Die halbdurchsichtige Ebene, die die negative z-achse schneidet, soll die Projektionsebene des Körpers darstellen. Der Testwürfel aus dem ersten Beispielprogramm hat sein Zentrum im Ursprung und der Stanpunkt des Betrachters liegt auf der positiven z-achse.

KAPITEL 2. GRUNDKONZEPTE DER JAVA3D TM - KLASSENBIBLIOTHEK 12 Abbildung 2.3: Koordinatensystem von Java3D TM

Kapitel 3 Darstellung von Objekten und Erzeugen von Geometrie 3.1 Einleitung (Ausblick auf die Welt nach ColorCube) Nachdem die grundlegenden Konzepte von Java3D TM in Kapitel 2 behandelt wurden, geht es in diesem Kapitel darum, wie man eigene Objekte erstellt. Die in Abschnitt 2.2.2 genutzte Klasse ColorCube ist eigentlich nur dazu gedacht dem Programmierer die Möglichkeit zu geben schnell etwas zu testen und einen SceneGraph ohne viel Aufwand zu erstellen. Mit ihr können keine weiteren graphischen Objekte erstellt werden. Hierfür gibt es andere Möglichkeiten. Bei komplexen 3D-Modellen ist es am einfachsten, wenn man sie extern mit einem der dafür geschriebenen Programme kreiert. Dieses Programm kann z.b. ein CAD- oder Raytracing-Programm sein. Über sogenannte Content-Loader ist es dann möglich, das Modell auch in Java3D TM zu nutzen. Auf diese Möglichkeit wird im weiteren aber nicht mehr eingegangen, stattdessen beschäftigt sich dieses Kapitel mit den internen Möglichkeiten von Java3D TM. Um grafische Objekte zu erstellen muß man zunächst wissen, wie diese in Java3D TM aufgebaut sind. Grundsätzlich genügt es ein Shape3D Objekt zu kreieren. Optional hat dieses Objekt dann noch Referenzen auf eine Geometry-Komponente und eine Appearance-Komponente. Grob gesehen beinhaltet die Geometry-Komponente Informationen über die Form. Die Appearance-Komponente enthält dagegen Informationen über das Aussehen des zu rendernden Gegenstands. Das können z.b. Tranzparenz- oder Farbwerte sein. Später wird darauf noch detailliert eingegangen (siehe Abschnitt 3.3). Zunächst genügt es den groben Aufbau zu kennen, da mit den Geometric Utility Classes einfachere Möglichkeiten existieren unser VirtualUniverse mit grafischen Objekten zu bevölkern. 13

KAPITEL 3. DARSTELLUNG VON OBJEKTEN UND ERZEUGEN VON GEOMETRIE 14 3.2 Geometric Utility Classes (Welt aus Kugeln, Kegeln Quadern und Zylindern) Mit diesen Klassen werden dem Java3D TM -Programmierer Hilfen zur Verfügung gestellt mit denen grundlegende 3D-Objekte erstellt werden können. Es gibt jeweils eine Klasse für Kugeln, Kegel, Quader und Zylinder. Diese Klassen sind in im Paket com.sun.java3d TM.utils.geometry definiert. com.sun.java3d\texttrademark.utils.geometry.box ist dabei für die Quader zuständig, com.sun.utils.geometry.cone für Kegel und com.sun.utils.geometry.cylinder und com. sun.utils.geometry.sphere für Zylinder und Kugeln. Diese Klassen bieten im Vergleich zur ColorCube-Klasse dadurch mehr Flexibilität, das zwar die Geometry-Komponente festgelegt ist, Appearance aber verändert werden kann. Man kann auch mehrere Instanzen einer Klasse erstellen, die alle auf eine andere Appearance-Komponente verweisen und deswegen auch anders aussehen. Im Folgenden werden Box, Cone, Sphere und Cylinder einzeln vorgestellt. Sowohl für diese Klassen, als auch für noch folgende muß jedoch gelten, daß nicht alle Methoden, Konstruktoren und Parameter aufgeführt werden können. Alle für diese Einführung wesentlichen Aspekte werden besprochen, weitere Informationen entnehme man der Referenz von Java3D TM. 3.2.1 Box Diese Klasse dient dem Erstellen von Quadern. Der Standardwert für Länge, Breite und Höhe ist dabei jeweils 2 Meter. Der Mittelpunkt liegt im Ursprung des durch das Locale-Objekt definierten Koordinatensystems. Konstruktoren: Box() Erstellt einen Quader mit Standardwerten Box(float xdim, float ydim, float zdim, Appearance appearance) Erstellt einen Quader dessen Maße mit den Variablen xdim, ydim und zdim festgelegt werden und dessen Appearance in appearance definiert wird. 3.2.2 Cone Mit der Cone-Klasse können Kegel erstellt werden. Der Standardwert für die Höhe beträgt 2 Meter, der Wert für den Radius 1 Meter. Der Mittelpunkt liegt wiederum im Ursprung, wobei der Mittelpunkt definiert ist als der Mittelpunkt des den Kegel umschließenden Quaders. Die Achse verläuft dabei an der y-achse des Koordinatensystems entlang. Konstruktoren: Cone() Erstellt einen Kegel mit Standardwerten Cone(float radius, float height) Erstellt einen Kegel dessen Radius in xdim und dessen Höhe in heigth festgelegt wird 3.2.3 Sphere Mit dieser Klasse werden Kugeln erzeugt. Standardmäßig beträgt der Radius einen Meter. Der Mittelpunkt liegt im Ursprung. Konstruktoren: Sphere() Erstellt eine Kugel mit Standardwerten Sphere(float radius) Erstellt eine Kugel deren Radius in radius festgelegt ist. Sphere(float radius, Appearance appearance) Erstellt eine Kugel mit Radius radius und Appearance appearance.

KAPITEL 3. DARSTELLUNG VON OBJEKTEN UND ERZEUGEN VON GEOMETRIE 15 3.2.4 Cylinder Diese Klasse dient dem Erstellen von Zylindern. Standardwert für den Radius ist 1.0, für die Höhe 2.0 Meter. Mittelpunkt ist der Ursprung und die Achse verläuft entlang der y-achse. Konstruktoren: Cylinder() Erstellt einen Zylinder mit Standardwerten Cylinder(float radius, float height) Erstellt einen Zylinder mit Radius radius und Höhe height. Cylinder(float radius, float height, Appearance appearance) Erstellt einen Zylinder mit Radius radius, Höhe heigth und Appearance appearance. Mit diesen Befehlen kann man schon ein erstes, einfaches Programm schreiben, das eines oder mehrere der Geometric Primitives darstellt. Geometric Primitive ist der Oberbegriff für die Klassen Cone, Box, Sphere und Cylinder. Das folgende Programmstück zeigt, wie man einen kompletten Scene-Graphen erstellt, der, wenn man ihn rendert, eine Kugel zeigt. 1. public BranchGroup createscenegraph() { 2. BranchGroup objroot = new BranchGroup(); 3 Appearance app= new Appearance(); 4 Box box = new Box(0.4f,0.4f,0.4f,app); 5. objroot.addchild(box); 6. return objroot;} In Zeile 3 wird ein neues Appearance-Objekt erstellt, mit dem Box in Zeile 4 aufgerufen wird. Da mit new Appearance ein Standard Appearance-Objekt erstellt wird, sieht der Quader auch nicht gerade spektakulär aus. Auf dem Bildschirm erscheint ein weißes Viereck. Man sieht dem Quader nicht einmal seine Dreidimensionalität an. Abbildung 3.1: Box-Primitive Die Möglichkeiten von Appearance-Objekten, mit denen sich das Aussehen des Quaders leicht ändern läßt, werden im nächsten Abschnitt besprochen.

KAPITEL 3. DARSTELLUNG VON OBJEKTEN UND ERZEUGEN VON GEOMETRIE 16 3.3 Appearance Zuerst konkretisieren wir die recht ungenaue Beschreibung, daß Appearance das Aussehen eines graphischen Objektes beschreibt. Ein Appearance-Objekt enthält nicht selbst diese Daten sondern verweist auf verschiedene Unterklassen der abstrakten Klasse NodeComponent, die dann die gewünschten Informationen enthalten. Diese Unterklassen werden daher auch Appearance Attribut Objekte genannt. Einige davon sind: - PointAttributes - LineAttributes - PolygonAttributes - Coloring Attributes - TransparencyAttributes - RenderingAttributes - Material - TextureAttributes - Texture - TexCoordGeneration Die ersten sechs werden in diesem Abschnitt behandelt. Material bezieht sich auf die Beleuchtung eines Objektes und die letzten drei werden beim TextureMapping genutzt. Diese beiden Themen sind jeweils so komplex, daß sie ein eigenes Kapitel erfordern. Der Standardkonstruktor der Appearance-Klasse ist: Appearance() Hiermit wird ein Appearance-Objekt erschaffen für das gilt, daß alle Verweise auf Appearance-Attribute mit null initialisiert werden. Die Standardwerte werden also genutzt. Genauer heißt das, daß die Farbe weiß ist, das Objekt keinerlei Textur und Tranzparenz besitzt und normal gezeichnet wird. Mit den folgenden Methoden ist es dann möglich das jeweils benötigte NodeComponent-Objekt als Appearance Attribut hinzuzufügen: Appearance Methoden-(ohne Texturemapping und Beleuchtung) void setpointattributes(pointattributes pointattributes) void setlineattributes(lineattributes lineattributes) void setpolygonattributes(polygonattributes polygonattributes) void setcoloringattributes(coloringattributes coloringattributes) void settransparencyattributes(transparencyattributes transparencyattributes) void setrenderingattributes(renderingattributes renderingattributes) Die einzelnen Attribut Klassen und ihre Funktion definieren sich wie folgt: 3.3.1 PointAttributes Diese Klasse bestimmt, wie Punkte dargestellt werden. Die Ausgangseinstellung sieht vor, daß ein Punkt genau die Größe eines Pixels hat und die Darstellung kein Antialiasing verwendet. Mit Antialiasing werden bei Punktgrößen mit mehr als einem Pixel die Kanten geglättet indem die immer viereckigen Punkte an den Außenrändern einen Farbverlauf zur Umgebungsfarbe zeigen. Konstruktoren: PointAttributes() Erstellt das Objekt mit den oben vorgestellten Standardwerten. PointAttributes(float pointsize, boolean state) Die float-variable gibt die Größe in Pixeln an, die boolsche ob Antialiasing verwendet wird

KAPITEL 3. DARSTELLUNG VON OBJEKTEN UND ERZEUGEN VON GEOMETRIE 17 Methoden: void setpointsize(float pointsize) Gibt für Punkte die Größe in Pixeln an void setpointantialiasingenable(boolean state) Aktiviert oder deaktiviert Antialiasing 3.3.2 LineAttributes Diese Klasse ist im Aufbau der vorherigen sehr ähnlich, es kann die Breite der Linie verändert werden, Antialiasing aktiviert werden und die Zeichenart der Linie bestimmt werden. Standard ist, daß die Linie durchgehend, ohne Antialiasing und mit Breite 1 gezeichnet wird. Konstruktoren: LineAttributes() Erstellt ein Objekt, so daß Linien mit den vorgestellten Standardwerten gerendert werden. LineAttributes(float PointSize, int linepattern, boolean state) PointSize gibt die Breite der Linie in Pixeln an, state gibt die Verwendung von Antialiasing vor und linepattern die Art der Linie. Eine Linie kann entweder durchgehend gezeichnet werden, gestrichelt, gepunktet oder gestrichelt und gepunktet. Die möglichen Konstanten für linepattern sind dementsprechend: PATTERN SOLID, PATTERN DASH, PATTERN DOT und PATTERN DASH DOT. Methoden: void setlinewidth(float linewidth) void setlinepattern(int linepattern) void setlineanitaliasingenable(boolean state) Mit diesen Methoden werden die beim Konstruktor besprochenen Parameter einzeln gesetzt 3.3.3 PolygonAttributes Mit PolygonAttributes kann der Programmierer das Aussehen von Polygonen beeinflussen. So kann zum einen die Darstellung von Polygonen gewählt werden. Ein Polygon kann als Menge seiner Eckpunkte gezeichnet werden, was zwar am schnellsten geht aber auch am schlechtesten aussieht, als Drahtgittermodell, wobei hier noch die Verbindungslinien zwischen den Punkten zusätzlich gezeichnet werden, oder aber farbig gefüllt. Um Rechenleistung zu sparen ist es zudem möglich dafür zu sorgen daß die Hälfte der Polygone eines Objektes nicht gezeichnet wird. Dieses Weglassen (engl.: Culling) wird entweder als Backface- Culling oder Frontface-Culling bezeichnet, abhängig davon, ob die Front eines Objektes, oder aber der hintere Teil weggelassen wird. Standard ist dabei, daß ein Polygon gefüllt gezeichnet wird, kein Culling vorgenommen wird und auch kein besonderer Tiefenwert gesetzt wird. Konstruktoren: PolygonAttributes() Erstellt ein Objekt mit Standardwerten. PoygonAttributes( int polygonmode, int cullface, float polygonoffset) PolygonMode ist dabei entweder POLYGON POINT (nur Eckpunkte), POLYGON LINE (Drahtgitter) oder POLYGON FILL (gefüllt). CullFace ist eine der folgenden Konstanten: CULL FRONT (Frontface-Culling), CULL BACK (Backface-Culling) oder CULL NONE (kein Culling). Mit polygonoffset kann gezielt der Tiefenwert eines Polygons gesetzt werden. PolygonAttributes( int polymode, int cullface, float polyoffset, boolean backfacenormalflip) Dieser Konstruktor entspricht weitgehend dem vorherigen, zusätzlich kann aber die Bestimmung ob Polygone (oder genauer die Normalenvektoren der Polygone)in die Tiefe des Bildschirms zeigen oder nach vorne so variiert werden, daß das jeweils umgekehrte Ergebnis ausgegeben wird.

KAPITEL 3. DARSTELLUNG VON OBJEKTEN UND ERZEUGEN VON GEOMETRIE 18 Methoden: void setcullface(int cullface) void setpolygonmode(int polygonmode) void setpolygonoffset(polygonoffset) void setbackfacenormalflip(boolean backfacenormalflip) Mit diesen Methoden können die bei den Konstruktoren besprochenen Parameter einzeln gesetzt werden. 3.3.4 ColoringAttributes Mit dieser Klasse kann die Farbe eines Objektes festgelegt werden und ein Shading-Algorithmus bestimmt werden. Shading wird das Verfahren genannt, das bei beleuchteten Objekten den Farbverlauf auf der Oberfläche des Objektes berechnet. Je feiner und realistischer diese Berechnung ist, desto schöner wirkt natürlich auch das Objekt, desto mehr Rechenzeit wird aber auch benötigt. Java3D TM kennt zwei Shading-Algorithmen: Flat- und Gouraud Shading, wobei letzteres schöner und langsamer ist. Standardmäßig ist weiß die Objektfarbe und es wird Gouraud-Shading genutzt. Konstruktoren: ColoringAttributes() Erstellt ein Objekt mit Standardwerten. ColoringAttributes(Color3f color,int shademodel) ColoringAttributes(float red, float green, float blue,int shademodel) Bei beiden Konstruktoren kann shademodel dabei SHADE GOURAUD, SHADE FLAT, FASTEST oder NICEST sein. FASTEST ist meistens aber identisch mit SHADE FLAT und NICEST mit SHADE GOURAUD. Mit Color3f bzw. den einzelnen Farbwerten von rot, grün und blau wird die Farbe des Objekts definiert. Methoden: void setcolor(color3f color) void setcolor(float red, float green, float blue) void setcolor(float red, float green, float blue) void set ShadeModel(int shademodel) Mit diesen Methoden können die bei den Konstruktoren besprochenen Parameter einzeln gesetzt werden. Zu beachten ist noch, daß die mit setcolor gesetzte oder beim Konstruktor übergebene Farbe nicht immer Auswirkungen auf die Färbung des Objektes hat. Das liegt daran, daß Farben auch an jedem Punkt eines Geometry-Objektes festgesetzt werden können. Ist das der Fall, so wird die durch die Komponente ColoringAttributes definierte Farbe ignoriert. Wird das Objekt beleuchtet, so wird die Komponenten Farbe ebenfalls nicht genutzt. 3.3.5 TransparencyAttributes Mit dieser Klasse wird das Transparenzverhalten gesteuert. Es kann dabei der Grad der Durchsichtigkeit und das Verfahren, mit dem die Transparenz berechnet wird, bestimmt werden. Konstruktoren: TransparencyAttributes() Erstellt ein Objekt, das keine Transparenz vorgibt und dessen Modus zur Transparez-berechnung der schnellstmögliche ist.

KAPITEL 3. DARSTELLUNG VON OBJEKTEN UND ERZEUGEN VON GEOMETRIE 19 TransparencyAttributes(int tmode, float tval) tval gibt die Durchsichtigkeit eines Objektes vor. 0.0 bedeutet dabei das es undurchsichtig erscheint und 1.0 das es völlig transparent ist. tmode ist eine der folgenden Konstanten: BLENDED, SCREEN DOOR, FASTEST, NICEST oder NONE. Hiermit wird die Art der Transparenzberechnung vorgegeben. NONE heißt, daß keinerlei Transparenz bestimmt wird, FASTEST nutzt die schnellstmögliche und NICEST die schönste Berechnung. BLENDED und SCREEN DOOR sind die beiden möglichen Algorithmen. Methoden: void settransparency(float tval) void set TransparencyMode(int tmode) Mit diesen Methoden können die bei den Konstruktoren besprochenen Parameter einzeln gesetzt werden. Nachdem die einzelnen Appearance-Attribute nun hinreichend besprochen wurden soll ein Programmausschnitt, der einen kompletten SceneGraph definiert, die praktische Nutzung demonstrieren: 1 private Appearance app() //gibt eine Appearance Objekt zurück 2 { 3 ColoringAttributes ca = new ColoringAttributes(); 4 ca.setcolor (1.0f,0f,0); //die Farbe wird auf rot gesetzt 5 TransparencyAttributes ta = new TransparencyAttributes(); 6. ta.settransparency(0.6f); //Tranzparenzstärke wird gesetzt 7. ta.settransparencymode(transparencyattributes.nicest); 8. Appearance appear= new Appearance(); //erstellt neues Appearance Objekt 9. appear.setcoloringattributes(ca); //Hinzufügen von ca als AppearanceAttribut 10. appear.settransparencyattributes(ta); //Hinzufügen von ta zu appear 11. return appear; 12. } 13. 14. public BranchGroup createscenegraph() //gibt den SceneGraph zurück 15. { 16. BranchGroup scene = new BranchGroup(); 17. Sphere sph = new Sphere(0.5f); 18. sph.setappearance(app()); //sph erhält die in app() gesetzte Appearance 19. scene.addchild(sph); 20. return scene; 21. } Dieser SceneGraph enthält eine transparente, rote Kugel. Die komplette Appearance-Komponente wird dabei in app() definiert. Um das Programmstück zu kürzen hätte man z.b.: die Zeilen 5 bis 7 ersetzen können durch: TransparencyAttributes ta = newtransparencyattributes (TransparencyAttributes.NICEST, 0.6f); Durch diesen Konstruktor werden die Parameter direkt gesetzt, so daß die Methoden in Zeile 6 und 7 überflüssig werden. Zu beachten ist noch der Gebrauch von NICEST. Da NICEST keine globale Variable ist sondern nur in und für TransparencyAttributes definiert ist muß sie folglich auch mit TransparencyAttributes.NICEST aufgerufen werden. Das Abbildung 3.2 zeigt den gerenderten SceneGraph. Hinzugefügt wurde lediglich noch ein Hintergrundbild um den Transparenzeffekt insbesondere auch in Graustufen deutlich hervorzuheben. Mit den anderen Appearance-Attributen wird genauso verfahren, weswegen dieses Codestück bei-

KAPITEL 3. DARSTELLUNG VON OBJEKTEN UND ERZEUGEN VON GEOMETRIE 20 Abbildung 3.2: Transparenz mit Hintergrund spielhaft für den allgemeinen Umgang damit stehen kann. Zu bemerken ist noch, daß mehrere Objekte, auch unterschiedlicher Klassen, auf eine Appearance- Komponente zugreifen können. Unterschiedliche Appearance-Objekte können wiederum dasselbe Appearance-Attribut nutzen. Also können z.b. die Appearance-Objekte a1 und a2 unterschiedliche ColoringAttributes aber ein TransparencyAttributes setzen. Was auch sinnvoll ist, da damit die Zeit, die zur Berechnung einer Szene nötig ist, verringert wird. 3.4 Geometry 3.4.1 Überblick Die bisher behandelten Geometric Primitive Klassen gestatten es zwar das Aussehen (Appearance) der damit gestalteten graphischen Objekte zum Teil weitgehend zu beeinflussen, die zu Grunde liegende Form (Geometry) bleibt jedoch immer gleich und ist nur hinsichtlich der Größe und der Relation einzelner Werte zueinander beeinflußbar. So kann in einem Kegel der Radius und die Höhe geändert werden und damit indirekt bestimmt werden, ob der Kegel spitz, flachgedrückt, groß oder klein erscheint. Letztendlich kann aber immer nur ein Kegel erzeugt werden. Zwar ist es auch möglich aus mehreren dieser einfachen Objekte ein komplexeres, größeres zu erstellen, indem man z.b. mehrere zu einer Gruppe zusammenfaßt, die eigentliche Einschränkung dieser Klassen kann damit jedoch nur unzulänglich ausgeglichen werden. Dieser Abschnitt zeigt nun Möglichkeiten auf eigene Formen zu erstellen. Bei der Einleitung zu diesem Kapitel wurde bereits angedeutet wie graphische Objekte in Java3D TM aufgebaut sind. Ein übergeordnetes Shape3D besitzt normalerweise genau ein zugeordnetes Appearance- und Geometry- Objekt. Diese bestimmen dann Aussehen bzw. Form des Objektes und können entweder beim Konstruktoraufruf des Shape3D-Objektes als Parameter übergeben werden oder später gesetzt werden. 3.4.2 Shape3D Konstruktoren: Shape3D() Erzeugt und initialisiert ein Shape3D-Objekt ohne Appearance- und Geometry-Komponenten Shape3D(Geometry geometry) Erzeugt und initialisiert ein Shape3D-Objekt mit der Geometry- Komponente geometry und ohne Appearance-Komponente. In diesem Fall werden die Standardwerte für Appearance genommen (siehe Abschnitt 3.3).

KAPITEL 3. DARSTELLUNG VON OBJEKTEN UND ERZEUGEN VON GEOMETRIE 21 Shape3D(Geometry geometry, Appearance appearance) Erzeugt und initialisiert ein Shape3D Objekt mit den übergebenen Geometry- und Appearance -Komponenten. Methoden: void setgeometry() void setappearance() void getgeometry() void getappearance() Diese Methoden setzen (set*) die Geometry und Appearance Komponenten, bzw. geben die bereits gesetzten zurück (get*). Die set-methoden können allerdings wie üblich nur genutzt werden, solange das Shape3D-Objekt noch nicht kompiliert und damit nicht live ist. Da Geometry eine abstrakte Oberklasse ist, ist das Geometry-Objekt, das in der oberen Referenz genutzt wird eine Instanz einer der Unterklassen von Geometry. Die meisten dieser Unterklassen basieren dabei auf einfachen Punkten. Wie bei professionellen Raytraycing-Programmen definiert sich die Form eines Objektes also durch eine Menge von Punkten und die damitverbundenen Informationen. Grob lassen sich die Unterklassen in drei Gruppen einteilen: nicht indizierte, Punkt basierende Geometrie (d.h., daß jedesmal wenn ein graphisches Objekt gerendert wird seine Punkte nur einmal verwendet werden können) indizierte, Punkt basierte Geometrie (die Punkte können mehrmals genutzt werden) andere graphische Objekte (Raster, Text3D und CompresssedGeometry) In diesem Abschnitt werden die ersten beiden Gruppen behandelt. Abbildung 3.3 zeigt die Hierarchie der Geometry-Klassen und Unterklassen. Auf Abbildung 3.3 erkennbar ist unter anderem, daß alle hier besprochenen Klassen Unterklassen von GeometryArray sind. Wie der Name bereits andeutet heißt das, daß alle Arrays nutzen, um die Daten zu jedem Punkt zu speichern. Es gibt jeweils Klassen um Punkte, Linien und Polygone, genauer Dreiecke und Vierecke, zu definieren. Die Gruppe der indizierten, Punkt basierten Geometrien sind dabei die Unterklassen von IndexedGeometryArray. Für alle gilt jedoch die oben bereits erwähnte Array-Struktur. Konkret bedeutet das, daß wenn ein n-eck mit Hilfe einer GeometryArray-Klasse definiert wird zunächst ein Array mit n Feldern erstellt wird. Für jeden Punkt des n-ecks gibt es ein Feld, das die Koordinaten des Punktes enthält. Zusätzlich können noch weitere Arrays mit ebenfalls n Feldern hinzugenommen werden um weitere Informationen zu den Punkten zu speichern. Das können z.b. Farbwerte oder Normalenvektoren sein. Auf die Problematik, daß Farbwerte sowohl in der Geometry-Komponente, als auch in der Appearance-Komponente gespeichert werden können, wurde bereits im Abschnitt 3.3.4 unter ColoringAttributes eingegangen, weshalb diese Thematik hier nicht weiter behandelt wird. Alle Arrays die Punktinformationen enthalten werden auch Data-Arrays genannt. Wird ein GeometryArray-Objekt erstellt, so müssen dem Konstruktor zwei Parameter übergeben werden: Die Anzahl der Punkte und die Daten die zu jedem Punkt gespeichert werden. Diese Daten bestehen aus den Koordinaten des Punktes und weiteren optionalen Daten. Das Datenformat wird so übergeben, daß Flags bitweise mit einem or verknüpft werden. Flags werden Bits genannt, die einen speziellen Sachverhalt anzeigen. In diesem Fall, ob eine Information zum Datenformat gehört oder nicht. Die einzelnen Flag-Konstanten sind: COORDINATES: muß gesetzt sein, da zu jedem Punkt Koordinaten gegeben sein müssen NORMALS: gibt an, ob Normalenvektoren gespeichert werden COLOR 3: gibt an, ob Farben ohne Transparenzwerte gespeichert werden

KAPITEL 3. DARSTELLUNG VON OBJEKTEN UND ERZEUGEN VON GEOMETRIE 22 Abbildung 3.3: Hierarchie der Geometry-Klassen COLOR 4: gibt an, ob Farben mit Transparenzwerten gespeichert werden TEXTURECOORDINATE 2: gibt an, ob 2D Texturkoordinaten gespeichert werden TEXTURECOORDINATE 3: gibt an, ob 3D Texturkoordinaten gespeichert werden Je mehr Flags gesetzt werden, desto größer ist das Datenformat, da für jedes gesetzte Flag ein zusätzliches Array mit Größe der Punktanzahl erstellt wird. Genutzt werden diese Flags bei den Konstruktoren der einzelnen Unterklassen, da GeometryArray eine abstrakt Oberklasse ist. Diese Konstruktoren nicht indizierter Geometrie sind, soweit später nicht anders definiert, im Gebrauch identisch. Es wird die Anzahl der Punkte übergeben und das Datenformat. Der Konstruktor der GeometryArray Klasse ist: GeometryArray(int vertexcount, int vertexformat) Vor allem auch den Gebrauch der bitweisen OR-Verknüpfung zeigt der nächste LineArray- Konstruktor: LineArray line = new LineArray(2, LineArray.COORDINATES LineArray.COLOR_3); Das Array hat also zwei Felder, und für jeden der zwei Punkte werden neben den notwendigen Koordinaten auch noch Farbwerte gespeichert. 3.4.3 Die Klassen PointArray, LineArray, TriangleArray und QuadArray LineArray übernimmt zusammen mit PointArray, TriangleArray und QuadArray den Konstruktor der Oberklasse. Die Konstruktoren sind demnach: PointArray(int vertexcount, int vertexformat)

KAPITEL 3. DARSTELLUNG VON OBJEKTEN UND ERZEUGEN VON GEOMETRIE 23 LineArray(int vertexcount, int vertexformat) TriangleArray(int vertexcount, int vertexformat) QuadArray(int vertexcount, int vertexformat) Erstellt wird jeweils ein leeres Objekt mit der angegebenen Anzahl von Punkten und dem angegebenen Datenformat. Die Bilder, die entstehen, wenn man mit identischen Punkten (vertices) die Arrays der einzelnen Unterklassen füllt und die entstehende Geometrie dann in einem Shape3D-Objekt nutzt, welches dann gerendert wird, sind aber sehr unterschiedlich. PointArray übernimmt die einzelnen Punkte, während LineArray je zwei Punkte zu einer Linie zusammenfaßt, TriangleArray je drei Punkte zu einem Dreieck überführt und QuadArray aus je vier Punkten ein Viereck macht. Abbildung 3.4 verdeutlicht das: Abbildung 3.4: Point-, Line- und TriangleArray Da alle Klassen zur Gruppe der nicht-indizierenden Geometrien gehören wird kein Punkt mehrmals verwendet und alle Linien bzw. Dreiecke werden unabhängig von einander gezeichnet. Die Methoden, die nötig sind, um die nach Aufruf des Konstruktors leeren Arrays z.b. mit Punktkoordinaten von P0-P5 zu füllen, übernehmen diese Unterklassen von GeometryArray. Im Referenzblock vorkommende * sind als Wildcards zu verstehen. Für * können alle sinnvollen Zeichen und Zeichenfolgen gesetzt werden. Wird eine Methode mit Color* aufgerufen, heißt das also, daß diese Methode sowohl mit Color3f als auch mit Color4b verwendet werden kann. 3.4.4 GeometryArray Methoden: void setcoordinate(int index, float[] coordinate) void setcoordinate(int index, double[] coordinate) void setcoordinate(int index, Point* coordinate) Setzt die Koordinaten für den durch index bestimmten Punkt void setcoordinates(int index, float[] coordinates) void setcoordinates(int index, double[] coordinates) void setcoordinates(int index, Point*[] coordinates) Setzt die Koordinaten für alle Punkte ab index void setcolor(int index, float[] color) void setcolor(int index, byte[] color)

KAPITEL 3. DARSTELLUNG VON OBJEKTEN UND ERZEUGEN VON GEOMETRIE 24 void setcolor(int index, Color* color) Setzt die Farbe für den durch index bestimmten Punkt. void setcolors(int index, float[] colors) void setcolors(int index, byte[] colors) void setcolors(int index, Color*[] colors) Setzt die Farbe für alle Punkte ab index void setnormal(int index, float[] normal) void setnormal(int index, Vector* normal) Setzt den Normalenvektor für den durch index bestimmten Punkt void setnormals(int index, Vector*[] normals) void setnormals(int index, float[] normals) Setzt dennormalenvektor für alle Punkte ab index. void settexturecoordinate(int index, float[] texcoord) void settexturecoordinate(int index, Point* coordinate) Setzt die Texturkoordinate für den durch index bestimmten Punkt void settexturecoordinates(int index, float[] texcoords) void settexturecoordinates(int index, Point*[] texcoords) Setzt die Texturkoordinate für alle Punkte ab index Mit diesen Methoden und den vorherigen Konstruktoren kann man nun eigene Geometrien erzeugen. Das nächste Codestück sollte ein Dreieck mit einem Farbverlauf von rot nach blau erstellen. Auf das sollte wird noch näher eingegangen (siehe auch Anhang A). 1. public BranchGroup createscenegraph() 2. { 3. BranchGroup scene = new BranchGroup(); 4. 5. Color3f red = new Color3f(1.0f, 0.0f, 0.0f); 6. Color3f blue = new Color3f(0.0f, 0.0f, 1.0f); 7. Color3f green = new Color3f(0.0f, 1.0f, 0.0f); 8. 9. TriangleArray tri= new TriangleArray (3,TriangleArray.COORDINATES 10. TriangleArray.COLOR_3); 11. tri.setcoordinate(0, new Point3f(-0.7f, -0.2f, 0.0f)); 12. tri.setcoordinate(1, new Point3f( 0.7f, -0.2f, 0.0f)); 13. tri.setcoordinate(2, new Point3f( 0.0f, 0.5f, 0.0f)); 14. tri.setcolor(0,blue); 15. tri.setcolor(1,red); 16. tri.setcolor(2,blue); 17. scene.addchild(new Shape3D(tri)); 18. 19. scene.compile(); 20. return scene; 21. } In Zeile 9 wird ein neues, leeres TriangleArray mit 3 Punkten erstellt. Das Datenformat, welches für jeden Punkt gespeichert werden soll besteht aus den Koordinaten und der Farbe. Diese Werte werden dann in den Zeilen 11-16 gesetzt. Da der erste Punkt als Farbwert blau hat, der zweite rot und der dritte blau, müßte der besagte Farbverlauf entstehen. In Zeile 17 wird dann ein neues