Inhalt:
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
)

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



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
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:
Die Benutzung eine 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&uerfels gemeint, der ein
VRML Objekt gerade noch einschliesst. Cosmoworlds kann Bounding Box Daten
liefern. Starten Sie dazu Cosmoworlds und benutzen
Sie File -> Import as Inline... für irgendeinen einzelnen
VRML Körper, dem Sie den SpaceSensor zuordnen wollen.
Drücken Sie auf das "Open Outline Editor" Icon

Klicken Sie sich durch den Szenengraph, bis Sie die Parameter für
die Bounding Box sehen.

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 Dune (noch) das File -> Import von
Cosmoworlds fehlt, muss man 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 über die Kommandozeile.
Unter Unix artigen Betriebssystemen benutzt man zum Beispiel
cat externproto_header_und_benutzung.wrl vrmlkoerper.wrl > protobenutzung.wrl
copy externproto_header_und_benutzung.wrl+vrmlkoerper.wrl protobenutzung.wrl
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
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 Bounding Box Werte (10 stellige Genauigkeit
ist sicher nicht notwendig), die in Cosmoworlds zu sehen sind.
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.
Um zu Vermeiden, dass der Fehler auftritt, kann man Scriptprogrammierung benutzen.
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:
linke_seite = rechte_seite ;
translation_changed[0]=value*Math.sin(value);
if (rechte_seite1 vergleichsoperator rechte_seite2)
{
irgendwelche_befehle1;
irgendwelche_befehle2;
usw.
}
else
{
irgendwelche_befehle3;
irgendwelche_befehle4;
usw.
}
if (value < 0.5)
{
switch_wert=0;
}
else
{
switch_wert=1;
}
for ( anfangsbefehl ; vergleich ; inkrementbefehl )
{
irgendwelche_befehle5;
irgendwelche_befehle6;
usw.
}
for (i=0;i<3;i=i+1)
{
vec3f1[i]=vec3f2[i];
}
Das entspricht den einzelnen Zuweisungenvec3f1[0]=vec3f2[0]; vec3f1[1]=vec3f2[1]; vec3f1[2]=vec3f2[2];
Um einen Scriptknoten mit Javascript zu erstellen ist sehr viel mehr
nötig, als die bisher kennengelernten Befehle.
Glücklicherweise ist Cosmoworlds in der Lage, einem den Hauptteil
dieser Arbeit abzunehmen.
Dabei generiert Cosmoworlds eine Vorlage mit dem Scriptknoten und startet
dann einen Texteditor, damit man die Vorlage weiter bearbeiten kann.
Dabei überlässt Cosmoworlds dem Benutzer die Wahl des Editors
über die Systemvariable $WINEDITOR bzw. $EDITOR.
Im schlimmsten Fall könnte Cosmoworlds den Editor vi benutzen,
falls die Systemvariable $EDITOR z.B. vom Systemadministrator entsprechend
gesetzt wurde.
Der Editor vi hat zwar den grossen Vorteil, dass er auf wirklich
auf so gut wie jedem Computersystem (auch über die Unix/PC oder
Homecomputerwelt hinaus) läuft, allerdings ist seine Bedienung ohne
weitere Einweisung so gut wie unmöglich.
Setzen Sie ihren graphischen Lieblingseditor (hier nedit, auch
z.B. jot, xedit oder xemacs sind hier möglich) mit dem Befehl
setenv WINEDITOR nedit
bzw.
export WINEDITOR=nedit
und überprüfen Sie ihre Wahl mit dem Befehl
echo $WINEDITOR
Klicken Sie auf das Script Icon ("Open Script Editor").
Es erscheint
function meine_translation_in(value, time)
{
for (i=0;i<3;i++)
{
if (value[i]>0)
{
meine_scale_out[i]=value[i];
}
else
{
meine_scale_out[i]=0.1;
}
}
}
cat protobenutzung.wrl script.wrl > protobenutzung2.wrl
Beim Programmieren ist es ziemlich "normal", dass die ersten Versionen eines neuen Programmteils Fehler enthalten.
Leider werden sind Fehlermeldungen in Cosmoplayer ausgesprochen
unauffällig.
Leuchtet im Navigationsbalken von Cosmoplayer eine Reihe roter Lämpchen
auf


#VRML V2.0 utf8nicht am absoluten Anfang des File gefunden wurde.



Während Fehler und "print" Ausgaben bei in "javascript" geschriebenen Scriptknoten bei Cosmoplayer in der VRML Console erscheinen, werden Fehler und "println" Ausgaben bei in java geschriebenen Scriptknoten in die java Console geschrieben. Bei netscape 4.7X ist sie über Communicator -> Tools -> Java Console erreichbar.