Wie funktioniert VRML ?

VRML ist eine deklarative Sprache. Im Vergleich zu einem traditionellen 3D-Programm in einer prozeduralen Sprache (z.B. ein OpenGL Programm in C) heisst das, dass man sich nicht über Dinge wie "jetzt mache ich ein Fenster auf dem Schirm auf", "jetzt will ich wissen, ob und wo ein Mausklick passiert ist" oder "jetzt verschiebe ich diesen Körper um 5 Einheiten" kümmern muss.

Stattdessen beschreibt man lediglich die Eigenschaften der gewünschten 3D Welt, um den Rest kümmert sich dann der VRML-Browser. Solche Eigenschaften sind zum Beispiel: "an dieser Stelle soll ein 3D-Körper mit der Geometrie einer Kugel erscheinen" oder "wenn auf die Kugel geklickt wurde, soll die Kugel langsam um 5 Einheiten verschoben werden".

Grundlage einer solchen Beschreibung bei 3D-Programmierung ist der Scenengraph. Er wird auch häufig als Dokumentationsform für traditionelle 3D-Programme in prozeduralen Sprachen benutzt.

Im Scenengraph werden ausgehend vom graphischen Ursprung ("Nullpunkt") alle graphischen Knoten (z.B. geometrischer Körper, Bewegung usw.) in Baumform angeordnet.

Zusätzlich zu den Knoten werden in den Scenengraph auch "Routes" eingetragen. Routes übertragen Ereignisse ("Events" z.B die Zeit, eine Verschiebung oder Rotation) von Knoten zu Knoten.

Knoten, die Events abhängig von einem äusseren Einfluss (z.B. Mausklick, Ablauf einer Uhr, ein Punkt im Raum wird für die Kamera sichtbar usw.) aussenden, nennt man "Sensoren".

Eine weitere wichtige Klasse von Knoten sind Interpolationsknoten. Sie empfangen Events und verarbeiten sie zu neuen Events. Dabei wird ausgehend vom Eingangsevent ein Mittelwert aus dem vorgegebenen Eingangsbereich des Interpolatorknotens gebildet. Dieser Mittelwert wird auf den vorgegebenen Ausgangsbereich der Interpolatorknotens übertragen und damit ein Ausgangsevent erzeugt.

Ein einfaches Beispiel eines Scenengraph:

<img align="top" src="howto.jpg">

Klicken Sie hier um die volle Fenstergröße ihres Browsers zu nutzen.

Im Scenengraph steht unterhalb des graphischenUrsprungs ein "Anchor" Knoten, so dass ein Mausklick auf folgende Körper im Scenengraph das Laden der entsprechenden HTML-Seite (oder auch VRML-Seite) im World Wide Web bewirkt. Danach folgt ein "Transform" Knoten, der für die Bewegung/Verzerrung der folgenden Knoten im Scenengraph zuständig ist. Der Transformknoten wirkt auf zwei weitere Knoten: einen "Shape" Knoten, der als geometrischen Körper einen Schriftzug enthält und einen "Inline" Knoten, der ein weiteres VRML File einhält, das von Steve Baker mit dem 3D-Modeller AC3D erstellt wurde.

Animiert wird diese VRML-Welt über einen "Timesensor" Knoten, der dauernd einen Time-Event (einWert zwischen 0 und 1) in eine Route leitet, die zu einem "OrientationInterpolator" Knoten führt. Daraus erzeugt der Orientationinterpolator einen Rotationsevent (eine Drehung, die aus dem Achsevektor (0 1 0) und einem Winkel zwischen 0 und 2*Pi besteht). Über eine Route wird der Rotationsevent in den Transformknoten geleitet, der den Shapeknoten und den Inlineknoten enthält.

Insgesamt ergibt sich also eine VRML-Welt mit einem sich drehenden Schriftzug und einem sich drehenden 3D-Modell.

VRML 2.0 Plugin needed

Klicken Sie hier um die volle Fenstergröße ihres Browsers zu nutzen.

Betrachtet man den Quellcode dieses Programms, so erkennt man, dass der Inhalt eines VRML-Programms nichts anderes ist, als eine Abbildung des entsprechenden Scenengraphs.

#VRML V2.0 utf8
# Der Kommentar der ersten Zeile ist zwingend vorgeschrieben

# Einfaches Hello World Programm das einen String und ein 3D-VRML Modell
# darstellt animiert und einen Link ins World Wide Web darauf legt

Background 
   {
   skyColor 0 0 1
   }

Anchor 
   {
   children 
      [
      DEF SCHRIFT  Transform
         {
         children
            [
            Inline { url "tux.wrl" }
            Shape 
               {
               geometry Text 
                  {
                  string ["Hello World"]
                  }
               }
            ]
         }
      ]
   description "Hello World"
   url "http://www.csv.ica.uni-stuttgart.de/vrml/vrml_csv.html"
   }
   
DEF ROTOTATOR OrientationInterpolator 
   {
   key [0, 0.5, 1]
   keyValue 
      [
      0 1 0 0, 
      0 1 0 3.14, 
      0 1 0 6.28 
      ]
   }

DEF TIMER TimeSensor 
   {
   cycleInterval 10
   loop TRUE
   }

ROUTE TIMER.fraction_changed TO ROTOTATOR.set_fraction
ROUTE ROTOTATOR.value_changed TO SCHRIFT.set_rotation

An Stelle eines eigentlich unnötigen "Nullpunkt"-Knotens tritt ein "Background"-Knoten, der die Hintergrundfarbe dieser VRML-Welt einstellt.

Wozu braucht man Java oder Javascript ?

VRML unterstützt die Programmiersprachen Javascript ("jscript", "vrmlscript", eigentlich "ECMA Script" ISO/IEC 16262) und Java im Anhang der VRML Spezifikation ISO/IEC 14772.
Sie werden sich fragen, wie diese prozeduralen Sprachen in das Konzept der deklarativen Sprache passen. Programmcode in diesen prozeduralen Sprachen werden in eigene "Script"-Knoten geschrieben, um damit Events gezielt zu verarbeiten. Dabei kann so ein Scriptknoten mehrere Events aussenden oder empfangen.

Im einfachen VRML Programm von oben lässt sich zum Beispiel der OrientationInterpolator

DEF ROTOTATOR OrientationInterpolator 
   {
   key [0, 0.5, 1]
   keyValue 
      [
      0 1 0 0, 
      0 1 0 3.14, 
      0 1 0 6.28 
      ]
   }

durch einen gleichwertigen Scriptknoten

DEF ROTOTATOR Script
   {
   eventIn      SFFloat     set_fraction
   eventOut     SFRotation  value_changed
   url       "vrmlscript:
   function set_fraction(value)
      {
      value_changed[0]=0;
      value_changed[1]=1;
      value_changed[2]=0;
      value_changed[3]=value*2.0*Math.PI;
      }
    "
    }

austauschen, der vrmlscript ("ECMA-script","Javascript") benutzt.

Das Beispiel mit Javascript finden Sie hier

Mit den vrmlscript-Funktionen "createVrmlFromString", "createVrmlFromURL" und "addRoute" lassen sich neue VRML-Knoten in einen bestehenden Scenengraph einbauen und animieren.

Ansonsten sind die Möglichkeiten von vrmlscript ziemlich beschränkt, da (laut Standard) nur VRML-spezifische Funktionen zur Verfügung stehen.
Um diese Beschränkungen zu umgehen, benötigt man Scriptknoten, die die Sprache Java unterstützen. Damit stehen alle Möglichkeiten des Java API zur Verfügung.

Der gleichwertigen Scriptknoten in unserem Beispiel ergibt sich dann zu

DEF ROTOTATOR Script
   {
   eventIn      SFFloat     set_fraction
   eventOut     SFRotation  value_changed
   url       "hello_java.class"
   }

hello_java.class ist dabei eine Javabytecode Klasse. Sie muss aus dem Javaprogramm

import vrml.field.*;
import vrml.node.*;
import vrml.*;

public class hello_java extends vrml.node.Script
   {
   float[] rotation=new float[4];

   public void processEvent(Event e)
      {
      if (e.getName().equals("set_fraction")) 
         {
//System.out.println("silly debug message");
         rotation[0]=0.0f;
         rotation[1]=1.0f;
         rotation[2]=0.0f;
         rotation[3]=((ConstSFFloat)e.getValue()).getValue()
                     *2.0f*(float)Math.PI;
         SFRotation value_changed=(SFRotation)getEventOut("value_changed");
         value_changed.setValue(rotation);
         }
      }
   }

kompiliert werden. Beachten Sie dabei, dass der Java CLASSPATH die Klassen vrml.* usw. enthalten muss. Diese Klassen werden üblicherweise mit Ihrem VRML-Browser mitgeliefert.

Das Beispiel mit Java finden Sie hier

Ausserdem