Nachdem wir einen großen Teil der in VRML zur Verfügung stehenden Knoten und Methoden vorgestellt haben, möchten wir zum Abschluß des statischen Tutorialteils zeigen, wie sich das Inventar an Knoten und damit die Mächtigkeit der Beschreibungssprache noch erweitern läßt. Anstatt beim Worldbuilding ausschließlich auf die vordefinierten Knoten von VRML97 zurückzugreifen, können Sie den Sprachumfang nach Ihren eigenen Vorstellungen mit entsprechenden Knoten ergänzen.
Bei der Ausstattung einer virtuellen Stadt mit verschiedenen Kirchengebäuden läßt sich beispielsweise ein der typischen Grundform entsprechender Prototyp definieren, der sich mit Variationen in den Ausmaßen, Farben oder Texturen der einzelnen Komponenten schnell und effektiv vielfach einsetzen läßt. Ebenso sind die meisten Haustypen auf wenige Grundformen zurückzuführen, so daß mit einer kleinen Anzahl von Prototypen abwechslungsreiche Städte aufgebaut werden können. In Zeiten normierter Stadtplanungen lassen sich sogar ganze Stadtszenen als Prototypen in Länderinformationssystemen einsetzen. Natürlich können neben den statischen auch dynamische Prototypen erzeugt werden. Ein in Farbe und Dimension veränderbarer animierter Autoprototyp würde sich beispielsweise als Grundlage für eine realistische Verkehrssimulation eignen. Letztendlich lassen sich auch Funktionserweiterungen mittels Scripting als Prototypen integrieren.
Die Gestaltung eines Prototypen vollzieht sich in zwei grundlegenden Schritten, die an das Prinzip der Klassendefinition mit privaten und öffentlichen Funktionen in der objektorientierten Programmierung erinnern. Im ersten Schritt wird der Prototyp in der von den Standardknoten bekannten Weise vollständig spezifiziert. Wie anhand der Abbildung 5.2 ersichtlich ist, setzt sich jede Spezifikation aus dem Namen des Knotens, den Feldtypen, den Datentypen, den Feldbezeichnern und im Falle der Fields und ExposedFields zusätzlich aus Default-Werten zusammen. Entsprechend ist bei der Gestaltung eines Prototypen im Knoten PROTO eine neue Kombination von Feldern anzugeben, wobei man vom Vorgang der Deklaration spricht. Über die öffentlichen Felder (und Events) lassen sich dann die Eigenschaften des durch den Knoten erzeugten Objekts manipulieren.
Im Gegensatz dazu ist der als Definition n bezeichnete Teil der Prototypengestaltung privat, d.h. die entsprechenden Daten sind im Knoten gekapselt. In diesem der Deklaration folgenden Schritt wird das eigentliche Objekt mit seinen Eigenschaften definiert. Hier werden die zu erzeugende Geometrie und gegebenenfalls interaktive Verhaltensformen beschrieben, wobei Standard-, bereits gestaltete oder weitere untergeordnete prototypische Knoten eingesetzt werden können. Die Eigenschaften des definierten Prototyps sind somit weitestgehend festgelegt und können nur innerhalb des durch den Worldbuilder vorgegebenen Rahmens über die Felder manipuliert werden. Zur Verdeutlichung auf den Standardknoten Box übertragen, würde dies beispielsweise bedeuten, daß das Ausmaß des Quaders bzw. Würfels zwar beliebig über das Feld size verändert werden kann, wobei die sich aus einer Höhe, Tiefe und Breite zusammensetzende Grundform jedoch unverändert bleibt.
Mit der Gestaltung eines Prototypen wird nicht automatisch eine Instanz desselben erzeugt, sondern lediglich ein neuer Knotentyp für den Einsatz in einer VRML-Datei bereitgestellt. Erst wenn dieser an entsprechender Stelle im Quellcode Verwendung findet, entsteht ein Objekt korrespondierenden Typs. An welcher Stelle ein Prototyp im Quellcode eingesetzt werden darf, hängt von dem ersten im Definitionsteil aufgeführten Knoten ab, der den Knotentyp des gesamten Prototyps bestimmt. Steht an dieser entscheidenden Stelle beispielsweise ein Geometrieknoten Box, kann der entsprechende Prototyp ausschließlich überall dort eingesetzt werden, wo Geometrieknoten erlaubt sind, wie beispielsweise im Feld geometry des Knotens Shape. Das folgende Listing zeigt, wie - redundanterweise - eine deutschsprachige Version des Knotens Box als Prototyp Quader deklariert, definiert und schließlich instanziiert wird.
Listing 8.9
#VRML V2.0 utf8
# Datei PRO_BOX.WRL: Einfacher Quader-Prototyp
PROTO Quader [ # Prototyp
field SFVec3f Groesse 4 2 1 ] { # Deklaration
Box { size IS Groesse } # Definition
}
Group { children [
Shape {
appearance Appearance { material Material {
diffuseColor 1 0 0 }}
geometry Quader { Groesse 5 3 2 } # Instanz
}
]}
Nachdem der Prototyp mit der Bezeichnung Quader versehen wurde, wird im Deklarationsteil ein Feld Groesse vom Feldtyp field erzeugt, das Werte vom Datentyp SFVec3f aufnehmen kann. Zusätzlich wird dem Feld Groesse ein Default-Wert 4 2 1 zugewiesen. Im Definitionsteil des Prototypen wird lediglich auf einen Standardknoten Box zurückgegriffen. Um dessen Ausmaß über das Feld size manipulieren zu können, wird der Wert des Feldes Groesse an Feld size mit Hilfe der Anweisung IS übergeben. Im Scene Graph wird der Prototyp Quader schließlich - dem Typ des ersten Knotens im Definitionsteil entsprechend - über das Feld geometry im Knoten Shape eingebunden und damit instanziiert. Der Default-Wert wird hierbei von einem Wert 5 3 2 überschrieben, so daß ein Quader mit den entsprechenden Maßen resultiert.
In der Regel erweist
sich der Einsatz von Prototypen erst dann als sinnvoll, wenn komplexe
Objekte in leicht abgewandelten Variationen mehrfach Verwendung finden.
Während der Quader aus Datei ,,pro_box.wrl" demnach eher als
übersichtliches Demonstrationsobjekt zu betrachten ist, wollen wir
im folgenden den Prototypen einer Parkbank entwerfen, der sich aus vier
Beinen und zwei Sitzflächen zusammensetzt. Die Variationen des
Prototypen bestehen darin, daß sowohl die Farbe der Beine als auch
die der Sitzflächen über Felder manipuliert werden
können. Abbildung 8.8
Drei Instanzen des Parkbank-Prototyps
Wie aus Abbildung 8.8 ersichtlich ist, sollen die Instanzen des Parkbank-Prototyps die bekannte Kirchhofszene ergänzen. Jede der drei Bänke weist für ihre Sitzflächen und Beine eine andere Farbkombination auf, so daß unterschiedliche Varianten derselben Grundform Verwendung finden. Zur Erzeugung der gezeigten Szene wird die frühere Datei ,,billbord.wrl" mit folgendem Code ergänzt.
Listing 8.10
#VRML V2.0 utf8
# Datei PROTOTYP.WRL: Drei Instanzen des Parkbank-Prototyps
...
PROTO Bank [ # Prototyp Bank - Anfang
exposedField SFColor SitzFarbe 1 0 0 # Deklaration
exposedField SFColor BeinFarbe 0 1 0 ]
{
Group { children [ # Definition
Transform { # Sitz
translation 0 0.03 0
children
DEF Sitz Shape {
appearance Appearance { material Material {
diffuseColor IS SitzFarbe }}
geometry Box { size 0.6 0.05 0.2 }
}
}
Transform { # Lehne
translation 0 0.2 -0.1
rotation 1 0 0 1.4
scale 1 1 0.8
children USE Sitz
}
Transform { # Bein kurz
translation -0.3 -0.05 0.1
children
DEF Bein Shape {
appearance Appearance { material Material {
diffuseColor IS BeinFarbe }}
geometry Cylinder { height 0.2 radius 0.025 }
}
}
Transform {
translation 0.3 -0.05 0.1
children USE Bein
}
Transform { # Bein lang
translation -0.3 0.05 -0.1
scale 1 2 1
children USE Bein
}
Transform {
translation 0.3 0.05 -0.1
scale 1 2 1
children USE Bein
}
]} # Group
} # Prototyp Bank - Ende
DEF Szene Group {
children [
NavigationInfo { headlight FALSE }
# DirectionalLight {direction .5 -1 -.5 }
# SpotLight {
# direction 1 .2 0
# location -11 0 0
# }
DEF Bank1 Transform { # Instanz_1
translation -4 -0.85 2.5
rotation 0 1 0 2.7
children Bank {}
}
DEF Bank2 Transform { # Instanz_2
translation -1 -0.85 1.3
children Bank { SitzFarbe .5 .5 0 BeinFarbe 1 1 1 }
}
DEF Bank3 Transform { # Instanz_3
translation 2.5 -0.85 2.5
rotation 0 1 0 4
children Bank { SitzFarbe 0.7 0.7 0 BeinFarbe 0.7 0 0 }
}
...
Sowohl der Prototyp als auch die Instanzen lassen sich an beliebiger Stelle im Quellcode der Datei ,,prototyp.wrl" einfügen. Wie schon bei dem weiter oben beschriebenen Quader, wird auch hier der Parkbank-Prototyp Bank zuerst deklariert und dann definiert. Über die Felder SitzFarbe und BeinFarbe werden bei der späteren Instanziierung den Sitzflächen und Beinen Farbwerte vom Datentyp SFColor zugewiesen. Der Definitionsteil gestaltet sich nunmehr ein wenig komplexer, da insgesamt sechs Komponenten zu einem Objekt kombiniert werden. Um den Prototypen-Code dabei möglichst effizient zu halten, dienen lediglich zwei grafische Primitive als Grundlage, die unter Verwendung der Anweisung USE und entsprechender Transformationen die Grundform der Parkbank ausmachen. Die Zuweisung der Farbwerte zu den einzelnen Komponenten erfolgt erneut über die Anweisung IS.
Im Verlaufe des Listings werden drei Instanzen des Prototypen Bank erzeugt, die sich - genau wie jedes andere Objekt in VRML97 auch - in der 3D-Szene beliebig integrieren und verwenden lassen. Das Objekt Bank1 greift hierbei auf die in der Deklaration des Prototypen vorgegebenen Default-Farbwerte zurück, während die beiden anderen Instanzen neue Farben zugewiesen bekommen.
Mit zunehmender Länge der Prototypen-Definition steigt erneut die Unübersichtlichkeit im Quellcode der VRML-Datei. Eine mögliche Lösung wäre die Auslagerung der Beschreibungen in eine separate Datei, welche via Inline in die Szene eingebunden werden könnte. Für die Integration externer Prototypen-Definitionen sieht die VRML-Spezifikation jedoch einen speziellen Knoten EXTERNPROTO vor.
Dieser enthält in der Regel einen vollständigen Deklarationsteil, wobei den Feldern jedoch keine Default-Werte zugeordnet werden können. Der Definitionsteil beschränkt sich lediglich auf die Angabe eines oder mehrerer URLs. Die aufzurufende VRML-Datei enthält dann die vollständige Deklaration und Definition des Prototypen innerhalb eines Knotens PROTO, wobei die Namen des Prototypen und der Felder im Knoten EXTERNPROTO nicht mit denen im Knoten PROTO übereinstimmen müssen, da automatisch auf den ersten Prototypen der externen Datei zugegriffen wird. Läge die vollständige Prototypen-Beschreibung Bank aus Datei ,,prototyp.wrl" demnach in Form einer separaten Datei unter der WWW-Adresse www.vrml97.edu/protos/pro_bank.wrl vor, ließe sich die gleiche Szene mit folgendem Code erzielen.
Listing 8.11
#VRML V2.0 utf8
# Datei EXPROTO.WRL: Drei Instanzen eines externen Prototyps
...
EXTERNPROTO Parkbank [ # Externer Prototyp
exposedField SFColor SitzFarbe 1 0 0 ]
http://www.vrml2.edu/prot os/pro_bank.wrl
...
DEF Bank1 Transform { # Instanz_1
translation -4 -0.85 2.5
rotation 0 1 0 2.7
children Parkbank {}
}
...
Sofern der eingesetzte VRML-Viewer direkte Verweise auf einzelne Prototypen innerhalb einer Datei unterstützt, können ganze Bibliotheken von 3D-Objekten angelegt werden. Über einen Pfad www.vrml2.edu/protos/moebel.wrl#tisch ließe sich somit beispielsweise aus einer inhaltlich strukturierten Datei ,,moebel.wrl" gezielt der Möbel-Prototyp tisch herausgreifen. Die entsprechende Bibliotheksdatei muß dabei lediglich ein einziges Mal über das WWW transportiert werden. Dies kann sich jedoch auch nachteilig auswirken, wenn nur wenige Prototypen in einer 3D-Szene verwendet, die Mehrzahl der transportierten Objekte also nicht eingesetzt werden.
Durch die geschickte Gestaltung einzelner Prototypen und die überlegte Kombination zu Objektbibliotheken läßt sich der Sprachumfang von VRML97 möglicherweise so sehr erweitern, daß sich die Szenengestaltung für den routinierten Worldbuilder zunehmend als Kombination und Variation vordefinierter Objektsammlungen gestaltet. Hierbei gilt es, die Variationsmöglichkeiten der Prototypen weitestgehend flexibel zu halten, um bei möglichst geringem Modellieraufwand einen hohen Grad an Abwechslung realisieren zu können. Nutzen Sie Ihre Erfahrungen und Modelle, die Sie im Laufe Ihrer Worldbuilder-Karriere sammeln werden, um diese gewinnbringend bei neuen Projekten immer wieder einsetzen zu können.