Java 3D Einstiegs-Tutorial Teil 1



Ähnliche Dokumente
Java 3D Einstiegs-Tutorial Teil 3

Einführung in Java3D

Java: Vererbung. Teil 3: super()

Einige weitere Fähigkeiten und Anwendungsbeispiele

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Programmieren in Java

Aktuelle Binaries: Version 1.5.2; download: + Visual Toolkit (VTK -> KITWARE)

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

5. Abstrakte Klassen. Beispiel (3) Abstrakte Klasse. Beispiel (2) Angenommen, wir wollen die folgende Klassenhierarchie implementieren:

Assoziation und Aggregation

Objektorientierte Programmierung für Anfänger am Beispiel PHP

5. Abstrakte Klassen

B6. 3D-Computergrafik mit Java

Innere Klassen in Java

Software Engineering. Zur Architektur der Applikation Data Repository. Franz-Josef Elmer, Universität Basel, HS 2015

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 22

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

Suchbäume. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Objektorientierte Programmierung

Einführung in die Programmierung

Fachdidaktik der Informatik Jörg Depner, Kathrin Gaißer

Klausur zur Einführung in die objektorientierte Programmierung mit Java

Objektorientierte Programmierung. Kapitel 12: Interfaces

Es sollte die MS-DOS Eingabeaufforderung starten. Geben Sie nun den Befehl javac ein.

Kleines Handbuch zur Fotogalerie der Pixel AG

3D-Grafik und -Animation: Java3D

Java Einführung Umsetzung von Beziehungen zwischen Klassen. Kapitel 7

Prinzipien Objektorientierter Programmierung

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

4. Jeder Knoten hat höchstens zwei Kinder, ein linkes und ein rechtes.

Pakete dienen dazu, die Software eines Projektes in größere inhaltlich zusammengehörige Bereiche mit eigenem Namen einzuteilen (siehe Java API).

Graphische Benutzungsoberflächen

Übung: Verwendung von Java-Threads

Software Engineering Klassendiagramme Assoziationen

Objektorientierte Programmierung OOP

Einführung - Was ist Java3D?

Grundlagen von Python

GUI Programmierung in Java

Die Beschreibung bezieht sich auf die Version Dreamweaver 4.0. In der Version MX ist die Sitedefinition leicht geändert worden.

Programmierkurs Java

Hilfe zur Urlaubsplanung und Zeiterfassung

Sichtbarkeit & statische Methoden. Einsatz von Sichtbarkeit Einsatz statischer Methoden programmatische Realisierung 2 Beispielaufgaben

teischl.com Software Design & Services e.u. office@teischl.com

Prof. Dr. Uwe Schmidt. 21. August Aufgaben zur Klausur Objektorientierte Programmierung im SS 2007 (IA 252)

Einführung in die Java- Programmierung

Ordner Berechtigung vergeben Zugriffsrechte unter Windows einrichten

Kapiteltests zum Leitprogramm Binäre Suchbäume

Applet Firewall und Freigabe der Objekte

Prüfungszeuch im Fach Objektorientierte Programmierung WS 2000

Dieses Tutorial gibt eine Übersicht der Form Klassen von Struts, welche Besonderheiten und Unterschiede diese aufweisen.

Software Engineering Interaktionsdiagramme

Abschnitt 12: Strukturierung von Java-Programmen: Packages

Vorkurs C++ Programmierung

Java Kurs für Anfänger Einheit 5 Methoden

Drei-Schichten-Architektur. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 16: 3-Schichten-Architektur 1 Fachkonzept - GUI

Java Einführung Packages

Leichte-Sprache-Bilder

Java Kurs für Anfänger Einheit 4 Klassen und Objekte

Professionelle Seminare im Bereich MS-Office

Formale Spezialisierungstechniken. am Beispiel des binären Baums. Hybride Programmiersprachen Daniel Krompass Berlin, 2009

Kurzeinführung Excel2App. Version 1.0.0

Xcode/Cocoa/Objective-C Crashkurs Programmieren unter Mac OS X

Java Projekt: Tic Tac Toe + GUI

Java Einführung Collections

4. AUSSAGENLOGIK: SYNTAX. Der Unterschied zwischen Objektsprache und Metasprache lässt sich folgendermaßen charakterisieren:

5.2 Neue Projekte erstellen

Bilder zum Upload verkleinern

3 Objektorientierte Konzepte in Java

Programmieren I. Strategie zum Entwurf von Klassen. Beispiele. Design von Klassen. Dr. Klaus Höppner. Beispiel: Bibliothek

ODBC-Treiber Programmübersicht

Drei-Schichten-Architektur. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 17: 3-Schichten-Architektur 2

Suche schlecht beschriftete Bilder mit Eigenen Abfragen

Kapitel 6. Vererbung

Schnittstelle DIGI-Zeiterfassung

Einführung in die Programmierung für Wirtschaftsinformatik

SEP 114. Design by Contract

Wasserzeichen mit Paint-Shop-Pro 9 (geht auch mit den anderen Versionen. Allerdings könnten die Bezeichnungen und Ansichten etwas anders sein)

Binärdarstellung von Fliesskommazahlen

Einstieg in die Informatik mit Java

Kap. 35 Swing: Grundlagen Kap Swing: Hauptfenster

WebService in Java SE und EE

Grafikausgabe mit dem Abstract- Windowing-Toolkit. Eine Einführung

Anleitung über den Umgang mit Schildern

SafeRun-Modus: Die Sichere Umgebung für die Ausführung von Programmen

.htaccess HOWTO. zum Schutz von Dateien und Verzeichnissen mittels Passwortabfrage

Zählen von Objekten einer bestimmten Klasse

2. Einrichtung der ODBC-Schnittstelle aus orgamax (für 32-bit-Anwendungen)

Das erste Programm soll einen Text zum Bildschirm schicken. Es kann mit jedem beliebigen Texteditor erstellt werden.

Java Reflection. Meta-Programmierung mit der java.lang.reflection API. Prof. Dr. Nikolaus Wulff

Algorithmik II. a) Fügen Sie in einen anfangs leeren binären Baum die Schlüsselfolge 20, 28, 35, 31, 9, 4, 13, 17, 37, 25 ein.

2. ERSTELLEN VON APPS MIT DEM ADT PLUGIN VON ECLIPSE

Adobe Flash CS4»3D-Tool«

1. Man schreibe die folgenden Aussagen jeweils in einen normalen Satz um. Zum Beispiel kann man die Aussage:

Wir gehen aus von euklidischen Anschauungsraum bzw. von der euklidischen Zeichenebene. Parallele Geraden schneiden einander nicht.

Revit Modelle in der Cloud: Autodesk 360 Mobile

Transkript:

Java 3D Einstiegs-Tutorial Teil 1 Computergrafik - Übungen W. Kurth, E. Roth WS 2001/02 Java 3D: Application Programming Interface (API) für Java Erweiterung von Java um Klassenbibliotheken, die als Interface für ein 3D-Grafik- und Soundsystem dienen gehört zu den Java Media APIs (neben Java Shared Data Toolkit, Java Advanced Imaging, Java 2D, Java Media Framework etc.) Download: http://java.sun.com/products/java-media/3d/download.html Java3D 1.2 API Specification (mit Einführung, Beschreibung der Klassen, Beschreibung der beim Download mitgelieferten Beispiele): http://java.sun.com/products/javamedia/3d/fordevelopers/j3d_1_2_api/j3dguide/index.html systematische Klassendokumentation: http://java.sun.com/products/javamedia/3d/fordevelopers/j3d_1_2_api/j3dapi/index.html Tutorial: siehe http://java.sun.com/products/java-media/3d/collateral/ Ein Java 3D - Programm besteht (teilweise) aus Objekten der Java 3D - Klassen, die ein virtuelles Universum beschreiben, welches dann gerendert wird: Kern-Klassen (Java 3D core classes) in javax.media.j3d Hilfs-Klassen (utility classes) in com.sun.j3d.utils außerdem werden benutzt: java.awt (Abstract Windowing Toolkit) für die Ausgabe der gerenderten Ergebnisse javax.vecmath für Vektor- und Matrizenrechnung

typische Import-Statements für eine Java 3D - Anwendung: import java.applet.applet; import java.awt.borderlayout; import java.awt.frame; import java.awt.event.*; import com.sun.j3d.utils.applet.mainframe; import com.sun.j3d.utils.universe.*; import javax.media.j3d.*; import javax.vecmath.*; Java 3D benutzt das Szenengraph-Konzept aber erweitert gegenüber VRML 2 Arten von Beziehungen zwischen Java 3D-Klassen- Instanzen: Eltern-Kind-Beziehung (nicht verwechseln mit Vererbung!) entspricht children-relation in VRML Referenzierung: entspricht der Verwendung von Knoten in Feldern anderer Knoten in VRML, z.b. Felder material, proxy Szenengraph = gerichteter azyklischer Graph (DAG), bei Weglassen der Referenzierungskanten sogar ein Baum Wurzel des Szenengraphen: Locale-Objekt (spezifiziert Referenzpunkt im virtuellen Universum) jeder Blattknoten des Szenengraphen hat eindeutigen Pfad von der Wurzel (ohne Referenzierungskanten), dieser spezifiziert vollständig die Zustandsinformation des Blattknotens: Position, Orientierung, Größe. eine Reihe von Methoden wird bereitgestellt, um Szenengraphen zu manipulieren.

Konventionen für Szenengraph-Skizzen in den folgenden Beispielen: Beispiel eines Szenengraphen in Java 3D:

Die meisten Knoten eines Szenengraphen (außer der Wurzel: VirtualUniverse, und Locale) sind Instanzen (von Subklassen) der SceneGraphObject-Klasse. Ausschnitt aus der Klassenhierarchie von Java 3D: SceneGraphObject Node Group... Leaf... man beachte die Ähnlichkeiten, aber auch Erweiterungen gegenüber VRML! spezielle Group-Knoten (Subklassen von Group): BranchGroup (entsprechend Group-Knoten in VRML) TransformGroup (entspr. Transform-Knoten in VRML) Die BranchGroup-Klasse besitzt eine compile-methode, die vor dem Rendering des Szenengraphen angewendet werden kann. Aufruf dieser Methode überführt den gesamten darunterliegenden Teilbaum des Szenengraphen in eine interne Repräsentation für Java 3D, die ggf. optimiert ist.

Beispiel für effizientere Repräsentation in der internen Darstellung: Zusammenfassung von adjazenten Transform- Group- (TG-) Knoten Grundschema zur Erstellung von Java 3D - Programmen: 1. Erzeugen eines Canvas3D-Objekts (die Canvas3D-Klasse ist abgeleitet von der Canvas-Klasse des Abstract Windowing Toolkit (AWT)) 2. Erzeugen eines VirtualUniverse-Objekts 3. Erzeugen eines Locale-Objekts, dies wird verknüpft mit dem VirtualUniverse-Objekt 4. Erzeugen eines view branch-graphen ("rechter Flügel" des Szenengraphen): a. Erzeugen eines View-Objekts b. Erzeugen eines ViewPlatform-Objekts c. Erzeugen eines PhysicalBody-Objekts d. Erzeugen eines PhysicalEnvironment-Objekts e. Verknüpfung von ViewPlatform, PhysicalBody, PhysicalEnvironment und Canvas3D-Objekt mit dem View-Objekt 5. Erzeugen eines oder mehrerer content branch-graphen ("linker Flügel" des Szenengraphen) 6. Kompilieren dieser beiden branch-graphen 7. Einfügen beider Teilgraphen in das Locale-Objekt

Da wir den view branch-graphen nur in standardisierter, einfacher Form benutzen, können wir eine Utility für vereinfachte Generierung von Szenengraphen benutzen, die SimpleUniverse-Klasse (in com.sun.j3d.utils. universe). Durch Erzeugen eines SimpleUniverse-Objekts wird ein "minimales virtuelles Universum" bereitgestellt, das den Inhalt des gestrichelt berandeten Bereichs in Standardform bereitstellt: Damit vereinfacht sich das obige allgemeine Schema für die Programmerstellung zu: 1. Erzeugung eines Canvas3D-Objekts 2. Erzeugung eines SimpleUniverse-Objekts, das auf das vorher erzeugte Canvas3D-Objekt Bezug nimmt 2a. Anpassen des SimpleUniverse-Objekts 3. Konstruktion des content branch 4. Compilieren des content branch 5. Einfügen des content branch in das Locale-Objekt des SimpleUniverse-Objekts.

Erstes Beispielprogramm: Darstellung eines Würfels mit farbigen Seitenflächen, der um 2 Achsen gedreht wurde, damit 3 seiner Seitenflächen sichtbar sind (es wird ein ColorCube-Objekt verwendet, das schon als Utility bereitsteht) import java.applet.applet; import java.awt.borderlayout; import java.awt.frame; import java.awt.event.*; import com.sun.j3d.utils.applet.mainframe; import com.sun.j3d.utils.universe.*; import com.sun.j3d.utils.geometry.colorcube; import javax.media.j3d.*; import javax.vecmath.*; public class FarbWuerfel1 extends Applet public FarbWuerfel1() setlayout(new BorderLayout()); Canvas3D canvas3d = new Canvas3D(null); add("center", canvas3d); BranchGroup szene = macheszenengraph(); szene.compile(); // Verwendung der Utility-Klasse // SimpleUniverse: SimpleUniverse universum = new SimpleUniverse(canvas3D); universum.getviewingplatform( ).setnominalviewingtransform(); universum.addbranchgraph(szene); } // end Konstruktor public BranchGroup macheszenengraph() BranchGroup objwurzel = new BranchGroup(); // Transformation, // Komposition von 2 Rotationen: Transform3D drehung = new Transform3D(); Transform3D drehung2 = new Transform3D();

drehung.rotx(math.pi / 4.0d); drehung2.roty(math.pi / 5.0d); drehung.mul(drehung2); TransformGroup objdreh = new TransformGroup(drehung); objdreh.addchild(new ColorCube(0.4)); objwurzel.addchild(objdreh); return objwurzel; } // end macheszenengraph-methode public static void main(string[] args) Frame frame = new MainFrame(new FarbWuerfel1(), 256, 256); } } // end class FarbWuerfel1 man beachte: als einziges zusätzliches import neben den oben schon angegebenen wird hier com.sun.j3d.utils.geometry. ColorCube gebraucht die Funktion main wird gebraucht, um das Programm als Anwendung laufen zu lassen (die Klasse Applet stellt die Fensterverwaltung bereit) im Konstruktor von FarbWuerfel1 wird das oben angegebene vereinfachte Schema der Szenenerstellung abgearbeitet dieser Teil kann für die meisten weiteren Beispiele übernommen werden die Konstruktion des content branch ist in die Methode macheszenengraph ausgelagert es gibt Transform3D-Objekte, die keine Knoten sind, sondern nur zu deren Spezifikation (nämlich von TransformGroup-Knoten) benötigt werden diese entsprechen geometrischen (affinen) Transformationen und verfügen über eine Methode mul zur Komposition (hier für die Nacheinanderanwendung der beiden Rotationen) addchild ist die Methode von Group-Knoten, um Kindknoten anzufügen

am Schluss wird die Wurzel des zusammenhängenden content branch an den Konstruktor zurückgegeben und wird dort mit addbranchgraph eingebaut. Das Ergebnis sollte etwa so aussehen (Fensterlayout möglicherweise betriebssystemabhängig): dem Beispiel zugrundeliegender Szenengraph:

Capabilities Im Vergleich zu VRML ist Java 3D besser abgesichert: Visuelle Objekte können zur Laufzeit nur verändert werden (z.b. in Animationen), wenn vorher entsprechende "Capabilities" gesetzt wurden. Jedes SceneGraphObject hat eine Liste von capability bits. Direkter Zugriff auf diese Tabelle (wird seltener gebraucht): Methoden von SceneGraphObject: void clearcapability(int bit) löscht das spezifizierte capability bit boolean getcapability(int bit) stellt das spezifizierte bit zur Verfügung void setcapability(int bit) setzt das spezifizierte bit intuitiverer Zugriff: <Instanz-Name>.setCapability (<Klassenname>.<capability-Name>) dabei ist <capability-name> einer der für die jeweilige Klasse vordefinierten capability-namen (in Großbuchstaben). Capabilities von Group: ALLOW_CHILDREN_EXTEND erlaubt das Anfügen neuer Kindknoten ALLOW_CHILDREN_READ ALLOW_CHILDREN_WRITE erlaubt die Änderung der Referenzen auf die Kindknoten (Überschreiben) Capabilities von TransformGroup: zusätzlich ALLOW_TRANSFORM_READ ALLOW_TRANSFORM_WRITE

Beispiel: TransformGroup drehobjekt = new TransformGroup(); drehobjekt.setcapability (TransformGroup.ALLOW_TRANSFORM_WRITE); generiert neue TransformGroup-Instanz und gibt die Möglichkeit, in Animationen ihre Parameter zu überschreiben. Shape3D-Objekte entsprechen den Shape-Knoten in VRML. Ihre Capabilities: ALLOW_GEOMETRY_READ ALLOW_GEOMETRY_WRITE ALLOW_APPEARANCE_READ ALLOW_APPEARANCE_WRITE ALLOW_COLLISION_BOUNDS_READ ALLOW_COLLISION_BOUNDS_WRITE Definition sichtbarer Objekte mit Shape3D Wie in VRML werden Geometrie und Erscheinungsbild durch Geometry- und Appearance-Knoten, auf die referenziert wird, näher spezifiziert.

Mögliche Aufrufe des Shape3D-Konstruktors: Shape3D() Shape3D(Geometry geometrieknoten) Shape3D(Geometry geometrieknoten, Appearance appknoten) Methoden zum Hinzufügen von entsprechenden Knoten, wenn der Shape3D-Knoten schon vorhanden ist: void setgeometry(geometry geometrieknoten) void setappearance(appearance appknoten) sowie entsprechende get-methoden (analog). Geometry und Appearance sind Subklassen von NodeComponent: Ausschnitt aus der Klassenhierarchie von Java 3D

Eigene, spezielle visuelle Objekte lassen sich als Subklasse von Shape3D selbst definieren und in Java 3D-Programmen benutzen, etwa nach folgendem Schema: public class SichtbaresObj extends Shape3D private Geometry sio_geom; private Appearance sio_app; public SichtbaresObj() sio_geom = erzeugegeometrie(); sio_app = erzeugeapp(); this.setgeometry(sio_geom); this.setappearance(sio_app); } private Geometry erzeugegeometrie() /* Code, um Default-Geometrie zu erzeugen */ } private Appearance erzeugeapp() /* Code, um Default-Erscheinungsbild zu erzeugen */ } } // Ende von SichtbaresObj-Klasse Die so def. SichtbaresObj-Klasse kann genauso einfach benutzt werden wie ColorCube im ersten Programmierbeispiel (s.o.). Wenn z.b. objwurzel eine Instanz von Group ist, erzeugt der folgende Code ein SichtbaresObj und fügt es als Kindknoten im Szenengraph an objwurzel an: objwurzel.addchild(new SichtbaresObj() );

Bei Verwendung "vordefinierter" Möglichkeiten gibt es drei Varianten der Geometrie-Spezifikation in Java 3D: Verwendung von Geometrie-Primitiven Verwendung von boundary-representation-objekten (analog zu IndexedLineSet etc. in VRML) Verwendung eines geometry loader zum Laden von Objekten aus anderer Software / anderen Spezifikationssprachen Verfügbare Loader: Verwendung geometrischer Primitive: Wie in VRML gibt es Box, Cone, Cylinder und Sphere. Die Parameter unterscheiden sich etwas. Box, Cone und Cylinder setzen sich (intern) aus mehr als einem Shape3D-Objekt zusammen. Package: com.sun.j3d.utils.geometry

Einordnung in die Klassenhierarchie: Box: Default-Seitenlänge 2, Positionierung mit dem Mittelpunkt im Zentrum des Koordinatensystems. Konstruktor-Aufrufe: Box() Box(float xdim, float ydim, float zdim, Appearance app) Cone: Default-Radius 1, Höhe 2, Zentrum im Mittelpunkt der bounding box, Zentralachse = y-achse. Konstruktor-Aufrufe: Cone() Cone(float radius, float hoehe) Cylinder: Defaults wie für Cone. Konstruktor-Aufrufe: Cylinder() Cylinder(float radius, float height, Appearance app)

Sphere: Default-Radius 1, Mittelpunkt im Zentrum des Koordinatensystems. Konstruktor-Aufrufe: Sphere() Sphere(float radius) Sphere(float radius, Appearance app) Verknüpfung mit einem Appearance-Knoten bei schon instanziiertem Objekt (für Box, Cone, Cylinder und Sphere): Methode void setappearance(appearance app) Zugriff auf die Einzelkomponenten (Seitenflächen) dieser "Primitiv-Objekte": Methode Shape3D getshape(int id) id ist ein Index, der festlegt, welche Einzelkomponente ausgewählt wird. Verknüpfung von Appearance mit nur einer Einzelkomponente: void setappearance(int id, Appearance app)

Beispiel-Programm: Erzeugung einer Jojo-Figur aus 2 Kegeln Zugehöriger Szenengraph: Die Strukturen innerhalb der inneren Rechtecke (Cone object) werden im Programm nicht explizit konstruiert. Die Struktur innerhalb des äußeren Rechtecks wird im Beispielprogramm durch "kegeljojo" referenziert (man könnte hierfür eine neue Klasse definieren, das ist im Beispielprogramm nicht geschehen):

import java.applet.applet; import java.awt.borderlayout; import java.awt.frame; import java.awt.event.*; import com.sun.j3d.utils.applet.mainframe; import com.sun.j3d.utils.universe.*; import com.sun.j3d.utils.geometry.cone; import javax.media.j3d.*; import javax.vecmath.*; public class Jojo1 extends Applet public Jojo1() setlayout(new BorderLayout()); Canvas3D canvas3d = new Canvas3D(null); add("center", canvas3d); BranchGroup szene = macheszenengraph(); szene.compile(); SimpleUniverse univ = new SimpleUniverse(canvas3D); univ.getviewingplatform( ).setnominalviewingtransform(); univ.addbranchgraph(szene); } // end Konstruktor public BranchGroup macheszenengraph() BranchGroup objwurzel = new BranchGroup(); BranchGroup jojo = kegeljojo(); objwurzel.addchild(jojo); return objwurzel; } // end macheszenengraph-methode public BranchGroup kegeljojo() BranchGroup jojobg = new BranchGroup(); Transform3D dreh = new Transform3D(); Transform3D verschieb = new Transform3D(); Appearance jojoapp = new Appearance(); dreh.rotz(math.pi/2.0d); TransformGroup jojod1 = new TransformGroup(dreh);

verschieb.set(new Vector3f(0.1f, 0f, 0f)); TransformGroup jojov1 = new TransformGroup(verschieb); Cone kegel1 = new Cone(0.6f, 0.2f); kegel1.setappearance(jojoapp); jojobg.addchild(jojov1); jojov1.addchild(jojod1); jojod1.addchild(kegel1); dreh.rotz(-math.pi/2.0d); TransformGroup jojod2 = new TransformGroup(dreh); verschieb.set(new Vector3f(-0.1f, 0f, 0f)); TransformGroup jojov2 = new TransformGroup(verschieb); Cone kegel2 = new Cone(0.6f, 0.2f); kegel2.setappearance(jojoapp); jojobg.addchild(jojov2); jojov2.addchild(jojod2); jojod2.addchild(kegel2); jojobg.compile(); return jojobg; } // end kegeljojo public static void main(string[] args) Frame frame = new MainFrame(new Jojo1(), 500, 400); // x=500, y=400: Fenster-Ausmasse (Pixel) } } // end class Jojo1

Ergebnis: