Damit Sie mit Cut und Paste arbeiten können, empfiehlt es sich, die Webseite http://www.csv.ica.uni-stuttgart.de/vrml/programming/vrml_programming_windows.html zu öffnen.

VRML programmieren

Inhalt:

Blick in den Standard

Betrachtet man einen VRML Knoten (hier der häufig benutzte "Transform" Knoten, der z.B. für Verschiebung, Drehung usw. zuständig ist) im offizellen VRML97 Standard ISO/IEC 14772 (in der Liste der VRML Knoten unter http://www.web3d.org/x3d/specifications/vrml/ISO_IEC_14772-All/part1/nodesRef.html#Transform )


kann man 5 Spalten unterscheiden:
Darunter befindet sich eine genaue Beschreibung der Bedeutung der einzelnen Fieldnamen.

Eventinformation

Vergleicht man die Notation im Standard mit dem Bild, dass sich in Dune



oder dem Szenengraph in Cosmoworlds (siehe Editors -> Outline Edior)

bietet, erkennt man die graphische Darstellung dieser Eventinformation.

Die nach links weisenden Kästchen in Dune (wie z.B. ("set_translation") deuten darauf hin, dass an den entsprechenden Fieldname eine Nachricht geschickt werden kann, die nach rechts weisenden Kästchen deuten darauf hin, dass vom entsprechenden Fieldname eine Nachricht abgeschickt werden kann. Dabei dienen die Vor/Nachsilben "set_" bzw. "_changed" nur zur Verdeutlichung, sie können in einem Routestatement (als Text im VRML File) auch weggelassen werden.

Genauso deuten die nach links oder rechts deutenden Pfeilchen im Cosmoworlds-Szenengraph auf eingehende oder ausgehende Nachrichten hin.

Es lassen sich dabei 4 verschiedene Typen unterscheiden:

Datentypen

Datentypen sind ein wichtiges Programmierprinzip. Sie verhindern, dass Daten ausgetauscht werden können, die nicht zueinander passen.

Es macht zum Beispiel in der Regel wenig Sinn, wenn eine Zeitinformation (ein Wert) einer Verschiebung (drei Werte) zugewiesen werden soll. Über dieses einfache Beispiel hinaus gibt es noch feinere Unterscheidungen.
Betrachtet man die Liste aller möglichen Datentypen in VRML, wie in http://www.web3d.org/x3d/specifications/vrml/ISO_IEC_14772-All/part1/fieldsRef.html#Introduction


so kann man zuerst "SF" und "MF" Typen unterscheiden. Dabei bedeutet "MF" ("M" von "multiple") eine Liste ("Array") des entsprechenden "SF" Typs. Diese Liste wird von [ und ] eingeschlossen (ausser der Array enthält nur einen Wert).

Einige wichtige Datentypen sind zum Beispiel:

Modularisierung

Modularisierung ist wahrscheinlich das wichtigste Programmierkonzept überhaupt. Man versteht darunter die Kunst, ein Problem in isolierte Teilprobleme zu unterteilen und dabei Übersichtlichkeit, Wartbarkeit und Wiederverwendbarkeit zu fördern.

Modularisierung bedeutet nicht nur, Programme in verschiede Dateien aufzuteilen, sonder auch, übersichtliche Einheiten innerhalb einer Datei zu bilden. VRML verfügt deshalb über mehrere Möglichkeiten zur Modularisierung:

Leider hat keiner der bisher verwendeten Programme eine brauchbare Unterstützung zum Erstellen von PROTO's, noch ist man also gezwungen, dafür zum Texteditor zu greifen. 8-(

Die Benutzung eines fertigen PROTO/EXTERNPROTO kann einem allerdings viel Arbeit abnehmen, deshalb hier ein Beispiel.

Cover/Covise bietet für die Unterstützung immersiver Umgebungen einen 3D RaumSensor an, der laut Standard nicht existiert (Obwohl man legale Erweiterungen zum VRML Standard über PROTOs implementieren kann (der VRML Browser erkennt "seinen" Knoten, alle anderen VRML Browser benutzen das PROTO)).
Der Cover/Covise funktioniert wie der PlaneSensor, leider existiert noch kein genau entsprechendes PROTO, aber es existiert ein ähnliches SpaceSensor-PROTO als Emulation mit 2D-VRML-Browsern.

Für die Benutzung eines EXTERNPROTO benötigt man einen Header und entsprechende Benutzung. Für den emulierten SpaceSensor laden Sie sich das File http://www.csv.ica.uni-stuttgart.de/vrml/programming/externproto_header_und_aufruf.wrl

#VRML V2.0 utf8

#Header 

EXTERNPROTO SpaceSensor [
   eventOut     SFVec3f translation_changed
   eventIn      MFNode addChildren
   eventIn      MFNode removeChildren
   exposedField MFNode children
   field        SFVec3f bboxCenter
   field        SFVec3f bboxSize
   ]
   [ 
     "urn:www.csv.ica.uni-stuttgart.de:library:SpaceSensor",
     "SpaceSensor.wrl",
     "http://www.csv.ica.uni-stuttgart.de/vrml/spacesensor/SpaceSensor.wrl" 
   ]

#Benutzung

SpaceSensor {}

Achten Sie darauf, dass die erste Zeile mit "#VRML V2.0 utf8" beginnt, sonst sind seltsame Fehlermeldungen wie "File is empty" vorprogrammiert.
Betrachten Sie den Header des PROTO und vergleichen sie ihn mit der Spezifikation im VRML Standard für den "Group"-Knoten. Er ist identisch, nur dass zusätzlich noch das Feld "translation_changed" vorkommt, entsprechend dem "PlaneSensor"-Knoten.

Es gehört zur Wartbarkeit von Programmen, ähnliche Dinge entsprechend zu benennen und etwas Zeit in das Suchen nach sinnvollen Bezeichnungen zu investieren.

Dieses PROTO läuft auch nicht anders, wenn statt der Bezeichnung "translation_changed" zum Beispiel "Kartoffelpuffer", "Tuba" oder "Klapperstorch" gewält worden wäre. Berüchtigt sind auch Namen wie "a17", "h25" usw. ("da musste man nicht so viel tippen"). Einem Benutzer der VRML Welt bleiben diese Namen in der Regel verborgen. Trotzdem würde man bei solchen Namen sagen, dass es sich um ein "schlecht geschriebenes" Stück Software handelt.

Übrigens werden die www-Adressen unterhalb des PROTO-Headers nacheinander durchlaufen. Hier kommt zuallererst eine Adresse, anhand derer ein VRML Browser eigene Erweiterungen erkennen kann. Liegt das nicht vor, versucht er, das VRML File von der Platte zu laden, ansonsten wird das File aus dem Internet geladen.

Das Feld "children" des SpaceSensors bedeutet, dass an diesem Punkt die VRML-Nodes eingefügt werden müssen, der Szenengraph sieht dann so aus:

(beim SpaceSensor von Cover/Covise, der wie ein PlaneSensor funktioniert, sieht der Szenengraph übrigens so:

aus, leider kann man das nicht so einfach über ein PROTO emulieren)

Die Felder "addChildren" und "removeChildren" bedeuten analog zum "Group"-Knoten, dass zur Laufzeit VRML-Nodes eingefügt oder entfernt werden können (wird hier nicht benutzt).

Die 2D Emulation des 3D SpaceSensors erfordert die Parameter einer sogenannten "Bounding Box".
Damit ist die Grösse und Position des Würfels gemeint, der ein VRML Objekt gerade noch einschliesst. Cosmoworlds kann Bounding Box Daten liefern. Starten Sie dazu Cosmoworlds und benutzen Sie File -> Import für irgendeinen einzelnen VRML Körper, dem Sie den SpaceSensor zuordnen wollen.
In der Windowsversion von cosmoworlds muss die Bounding Box "zu Fuss" mit Hilfe der Gitter ungefähr abgelesen werden. Bei diesem Problem ist es nicht wichtig, wenn das Gitter etwas grösser als das Object ist. Benutzen Sie placement -> Grid Properties ... , um die jeweiligen Längen abzulesen.
Hier kann man zum Beispiel eine Boundingbox von x=6/y=2.5/z=4 ablesen.

Da hier die Struktur des Szenengraphen entscheidend ist, ist Dune (obwohl seine Unterstützung für EXTERNPROTO nur sehr düftig ist) die bessere Wahl. Da (älteren Versionen) von Dune (noch) das (vollständige) File -> Import von Cosmoworlds fehlt, muss man ggf. das File mit EXTERNPROTO Header und Benutzung und das File mit dem VRML Körper vorher zusammenfügen. Das könnte man in einem Texteditor machen, am einfachsten geht es per Cut and Paste über die Kommandozeile.
Unter Unix artigen Betriebssystemen benutzt man zum Beispiel

cat externproto_header_und_benutzung.wrl vrmlkoerper.wrl > protobenutzung.wrl

Unter MSDOS artigen Betriebssystemen benutzt man
copy externproto_header_und_benutzung.wrl+vrmlkoerper.wrl  protobenutzung.wrl

Laden Sie dann das entstandene File (hier "protobenutzung.wrl") in das white_dune Programm (Version 0.18 oder höher). Unter Umständen sehen Sie die Meldungen:
BUG: Currently, EXTERNPROTO definitions are not read
BUG: Default field values are incorrect
using [] as default  field value
BUG: Currently, EXTERNPROTO definitions are not read
BUG: Default field values are incorrect
using 0.0,0.0,0.0 as default SFVec3f field value
BUG: Currently, EXTERNPROTO definitions are not read
BUG: Default field values are incorrect
using 0.0,0.0,0.0 as default SFVec3f field value


Das bedeutet, dass white_dune das EXTERNPROTO File nicht analysiert hat und deswegen nicht weiss, welche Defaultwerte im EXTERNPROTO File stehen. Sie müssen also alle (Field/exposedField) Felder der EXTERNPROTO Benutzung ausfüllen.

Zuerst füllen Sie das "children" Feld. Dazu verschieben Sie einfach im Scenengraphen den VRML Körper in den SpaceSensor.

Dass der VRML Körper jetzt nicht mehr zu sehen ist, ist immerhalb normaler Parameter und liegt daran, dass white_dune EXTERNPROTO Benutzungen (noch) nicht anzeigt.

Danach übertragen Sie die vorher abgelesenen Bounding Box Werte (10 stellige Genauigkeit ist sicher nicht notwendig), die in Cosmoworlds zu sehen sind.

Benutzen Sie jetzt File -> Preview um zu sehen, wie der Körper im Raum bewegt werden kann. Zuerst muss der Körper angeklickt werden,

Dann kann der Körper durch Ziehen an den entsprechenden Flächen in allen Raumrichtungen bewegt werden.



Einen Körper zu verschieben ist aber nicht der eigentliche Sinn eines SpaceSensors. Die Information über das Verschieben soll zugäglich gemacht werden. Also benutzen Sie den RouteView von dune (ggf. View -> Route View) um translation_changed des SpaceSensors in die Transform->scale (Vergrössern/Verkleinern) eines anderen Objektes zu leiten.

Beim Aufprobieren mit Preview können Sie sowohl ein erwartetes

als auch ein unerwartetes Ergebnis

sehen. Der tiefere Grund liegt darin, dass er erlaubte Wertebereich bei scale von Transform zwischen 0 und Unendlich liegt. Liegt eine der Grössen < 0, kann zum Beispiel bei Cosmoplayer durch Drücken der "\" Taste eine entsprechende Fehlermeldung angezeigt werden.

* Transform with illegal scale factor (-4.853672, -1.353548, 3.326290) encountered.

Man kann zwar die Meinung vertreten, dass eine negative Vergrösserung als Spiegelung verstanden werden sollte (Cover/Covise macht es so als Erweiterung), allerdings ist dies im aktuellen offiziellen VRML97 Standard nicht vorgesehen.

Um zu Vermeiden, dass der Fehler auftritt, kann man Scriptprogrammierung benutzen.

Ein Einstieg in "javascript"

Das in einen VRML Browser eingebaute "javascript" wird auch als "VRML-Script" bezeichnet, da die HTML spezifischen Befehle von "javascript" im VRML-Browser nicht funktionen (sollten) und gegen VRML spezifischen Befehle ausgetauscht wurden. Offiziell heisst diese Computersprache "ECMA-Script", nach dem gleichnamigen Normierungsgremium der Europäischen Gemeinschaft.

Die wichtigsten Konstruktionen in "javascript" sind: