Title:

VRML / X3D und 3D-Präsentationen

Description:  Mit VRML kann man eigene virtuelle Welten im Internet bauen. Man kann seine eigenen virtuellen Räume, Gebäude, Städte, Berge oder Planeten bauen.
Author:Manuel Schiewe, Bozana Bokan
deutsch
  
ISBN: 3423050012   ISBN: 3423050012   ISBN: 3423050012   ISBN: 3423050012 
 
  Wir empfehlen:       
 

VRML / X3D und 3D-Präsentationen

von Bozana Bokan & Manuel Schiewe
1 Einleitung
2 VRML
    2.1 Die VRML-Datei
    2.2 Ereignisse (Events) und Routen (Routes)
    2.3 Shapes
    2.4 Animation
    2.5 Sensoren
    2.6 Weitere Effekte
3 X3D
    3.1 X3D Working Group
    3.2 Andere Web3D Working Groups
4 VRML in 3D-Präsentationen
   4.1 Eine erste statische Version
   4.2 Animation
   4.3 "Hand-Eingriff" in die WRL-Datei
   4.4 Auslösen von Effekten durch Mausklicks
   4.5 Fußboden & Hintergrund
      4.5.1 Mehrschichtiger Fußboden
      4.5.2 Hintergrund
   4.6 Geräusche
   4.7 Mehrere Effekte mit EINEM Sensor auslösen
   4.8 Viewpoints
   4.9 Vorlagen für die Erstellung eine VRML-Welt (Vorlagen als Download: vorlagen1_1.zip)
5 Referenzen & Links (Viewer, Editoren)
 

1 Einleitung

VRML ist die Abkürzung für Virtual Reality Modeling Language. Mit VRML kann man eigene virtuelle Welten im Internet bauen. Man kann seine eigenen virtuellen Räume, Gebäude, Städte, Berge oder Planeten bauen. Mann kann diese virtuellen Welten mit virtuellen Möbeln, Autos, Menschen usw. füllen. VRML ermöglicht auch den Bau von dynamischen Welten, wie z.B.:

  • die Animation der Objekte in der virtuellen Welt, so daß sie sich bewegen können
  • den Ton und den Film in der virtuellen Welt
  • VRML erlaubt dem Benutzer, mit der Welt zu interagieren
  • auf die Welt mit Skripten und kleinen Programmen einzuwirken und sie zu kontrollieren
Versionen
VRML wurde von Open Inventor ASCII File Format durch Gavin Bell von Silicon Graphics, Inc. abgeleitet. Gavin Bell (damals bei Silicon Graphics, Inc.), Anthony Parisi (damals bei Intervista Software) und Mark Pesce (damals bei Labyrinth Group) trugen zu dem Zustandekommen der VRML V1.0 Spezifikation bei (http://www.vrml.org/VRML1.0/vrml10c.html#History). Ungefähr ein Jahr danach folgte VRML 2.0 Spezifikation. Im Dezember 1997 wurde die Version VRML 97 veröffentlicht, die die Version VRML 2.0 zum internationalen Standard (ISO/IEC 14772) machte (http://www.web3d.org/fs_specifications.htm). Im September 2000 wurde die VRML 200x-Spezifikation verfaßt. Die X3D-Working Group (http://www.web3d.org/x3d.html) des Web3D (http://www.web3d.org) Konsortiums arbeitet gerade an dem Projekt X3D - die neue, erweiterbare, aus Komponenten bestehende VRML-Evolution.
 

2 VRML

2.1 Die VRML-Datei
Die VRML-Datei ist die textuelle Beschreibung der VRML-Welt. Die Datei enthält Text, den man mit irgendeinem Texteditor schreiben kann. Es gibt auch VRML-Editoren, die das Eintippen des Textes und den Bau der VRML-Welt vereinfachen.
Die Namen der VRML-Dateien enden mit ".wrl" (Abkürzung für "World"). Die VRML-Datei kann folgende Komponenten enthalten:

  • VRML-Header
  • Prototypen (prototypes)
  • Shapes, Interpolatoren (interpolators), Sensoren (sensors) und Skripte (scripts)
  • Routers
  • Kommentare
  • Knoten
  • Felder und Feldwerte
  • Definierte Knotennamen
  • Benutzte Knotennamen
Nur der VRML-Header ist erforderlich in jeder VRML-Datei.
VRML-Header
Der VRML-Header sieht so aus:
Syntax : #VRML V2.0 utf8
Dieser Header sagt dem VRML-Browser, daß es sich um eine VRML-Datei der VRML-Version 2.0 handelt und daß UTF-8-Buchstaben benutzt werden.
Kommentare
Die VRML-Kommentare ermöglichen das Zufügen von zusätzlichen Informationen in die VRML-Datei, die die Darstellung der VRML-Welt im Browser nicht beeinflussen. Kommentare beginnen mit dem Zeichen "#" und enden mit dem Zeilenende.
Knoten (Nodes)
Die VRML-Datei enthält Knoten, die die Objekte und ihre Eigenschaften in der Welt beschreiben. Knoten beschreiben Shapes, Colors, Lights, Viewpoints, Sensors, Interpolators usw. Knoten sind also VRML-"Baublöcke" und enthalten im allgemeinen folgendes:
  • Knotentyp
  • Geschweifte Klammern
  • Einige Felder und ihre Werte, welche innerhalb der geschweiften Klammern die Knotenattribute definieren
Geschweifte Klammern gruppieren alle Feldinformationen innerhalb eines Knotens.
Felder und Feldwerte
Felder beschreiben die statische Objekteigenschaften. D.h. man kann sie dynamisch nicht ändern. Sie beschreiben die Objekteigenschaften wie z.B. Höhe und Radius (z.B. eines Zylinders). Felder sind innerhalb eines Knoten optional, da sie Defaultwerte haben, die von dem Browser benutzt werden, falls man selber keine Werte spezifiziert hat. Jeder Feldwert hat einen Feldtyp, der die Werte beschreibt, die in diesem Feld erlaubt sind. Die Feldtypen kann man grob in single-value und multiple-value Typen unterteilen. Single-value Typen sind Einzelwerte, wie Einzelfarbe oder Einzelnummer und haben Namen, die mit SF (Single Field) beginnen. Z.B. SFColor Feldtyp stellt eine Einzelfarbe dar. Multiple-value Typen können mehrere Werte darstellen, wie eine Farbliste oder eine Liste von Nummern und sie haben Namen, die mit MF (Multiple Field) beginnen. Z.B. MFColor Feldtyp stellt eine Farbliste dar. Wenn man die multiple-value Feldtypen spezifiziert, schreibt man die Liste von Werten innerhalb der eckigen Klammern und man trennt sie optional mit Kommas.
Definieren von Knotennamen
Man kann die Namen für die Knoten definieren. Die Namen können irgendeine Sequenz von Buchstaben, Nummern und Unterstrichen sein, sind case-sensitive und dürfen nicht mit einer Ziffer anfangen. Wenn der Knoten einmal einen Namen hat, kann man ihn wieder in derselben VRML-Datei benutzen. Den Knoten mit dem definierten Namen nennt man original node und jede weitere Benutzung dieses Knotens nennt man instance. Dabei kann man nur bei der original node die Feldwerte definieren. Die instances benutzen dann dieselben Feldwerte. Man kann also einen Stuhl definieren und mit instances noch weitere Stühle um den Tisch stellen, ohne Knoten und Felder von neuem zu definieren. Um einen Original-Knoten zu definieren, stellt man dem Knoten das Wort DEF und den Knotennamen voran:
Syntax : DEF node-name node-type { ...}
Eine VRML-Datei kann beliebig viele solche Knoten haben. Zwei Knoten können nicht den gleichen Namen tragen.
Benutzung von Knotennamen
Wenn man einmal einen Namen für einen Knoten definiert hat, kann man diesen immer wieder in derselben Datei benutzen, indem man dem Knotennamen das Wort USE voranstellt:
Syntax : USE node-name

2.2 Ereignisse (Events) und Routen (Routes)
Wie schon oben erwähnt, enthält die VRML-Datei die Bauinstruktionen für die virtuelle Welt. Um diese Welt dynamisch zu gestalten, enthalten diese Bauinstruktionen auch die ROUTE-Instruktionen. Diese Instruktionen beschreiben, wie man die Knoten miteinander routen kann. Die VRML Route umfaßt folgendes:

  • Ein Knotenpaar, das miteinander geroutet wird
  • Die Route oder den Pfad zwischen zwei Knoten
Wenn die Route einmal zwischen zwei Knoten aufgebaut ist, kann ein Knoten eine Nachricht zu dem anderen Knoten über dieser Route senden. Diese Nachricht (Ereignis) heißt event.
Knoten-Inputs und -Outputs
Die meisten Knoten können miteinander geroutet werden. Jeder Knoten hat Eingangs- und Ausgangs-"Stecker". Der Eingangsstecker heißt eventIn. Er empfängt events, wenn er an die Route gebunden ist und wenn das Ereignis zu ihm gesendet ist. Der Ausgangsstecker heißt eventOut. Er kann events aussenden, wenn er an die Route gebunden ist.
EventIns und eventOuts haben einen Typ. Wenn der eventOut z.B. von dem Typ SFColor ist, dann sendet er colors aus. Entsprechend, wenn eventIn von dem Typ SFColors ist, kann er colors empfangen.
Beim Spezifizieren von Routen muß man aufpassen, daß eventIns und eventOuts miteinander im Typ übereinstimmen.
Verdrahtung (wiring) von Routen (routes)
Eine Route wird von eventOut eines Knotens zu eventIn eines anderen Knotens definiert. Die Route ist nicht aktiv, solange kein event von dem ersten zu dem zweiten Knoten geschickt wird. Wenn der erste Knoten einen event zu dem zweiten Knoten entlang der Route schickt, wird die Route aktiviert. Wenn der event den zweiten Knoten erreicht,  reagiert der zweite Knoten auf irgendeine Art und Weise. Der Reaktionstyp hängt ab von:
  • dem Knotentyp des Knoten, der das event empfängt
  • dem Knoteneingangsstecker, mit dem die Route verdrahtet ist
  • den Werten, die das event enthält
  • den aktuellen Aktivitäten des Knotens


2.3 Shapes
Ein VRML-Shape hat eine Form oder Geometrie (geometry) und ein Erscheinungsbild (appearance). Diese zwei Attribute, geometry und appearance, sind innerhalb von Shape Node spezifiziert.
Die Geometrie definiert die 3D-Struktur. VRML unterstützt ein paar Arten von primitiven Geometrien, die in VRML vordefiniert sind: Box (box), Zylinder (cylinder), Kegel (cone), Kugel (sphere) und text, so wie ein paar erweiterte, wie extruded shapes und elevation grids.
Die appearance basiert auf dem Material (material), bzw. der Farbe, die das Objekt hat und auf der Oberflächentextur. Das Feld material der Appearance Node kann auf Material Node gesetzt werden. Mit diesem Knoten kann man diffuses und aussendendes Licht, Transparenz, Ambientintensität usw. definieren. Der Wert des Texturfeldes innerhalb von Appearance Node kann auf ImageTexture-, PixelTexture- oder MovieTexture Node gesetzt werden.
Shapes können gruppiert werden, um größere und komplexere Objekte zu bilden. Die einzelnen Shapes werden mit Hilfe von Group-, Switch-, Transform-, Billboard- und Bounding Box Node gruppiert. Den Knoten, der durch die Gruppierung entsteht, nennt man "parent" und die Shapes, die diesen Knoten bilden, nennt man "children". Die Gruppe kann beliebig viele children haben. Sie können sogar andere Gruppen als children haben.
Die Group Node stellt den Basisknoten dar. Die Transform Node erweitert die Möglichkeiten von Group Node, indem er ein neues Koordinatensystem für diese Gruppe definiert. Man kann die Shapes und Gruppen in der virtuellen Welt mit Hilfe der Transform Node beliebig positionieren: translieren, rotieren und skalieren.

Beispiel 1: HelloWorld.wrl
Zur Betrachtung der VRML-Welt benötigt man einen Viewer (siehe die Links.)
 
#VRML V2.0 utf8
Group {
  children [
    Shape {
      geometry DEF S Sphere { }
      appearance Appearance {
        texture ImageTexture {
          url [ "earth-topo.gif" ]
        }
      }
    }
    Transform {
      translation -1.0 -2.0 -5.0
      children [
        Shape {
          geometry Text {
            string [ "Hello" "world!" ]
          }
          appearance Appearance {
            material Material {
              diffuseColor 0.1 0.5 1
            }
          }
        }
      ]
    }
  ]
}

Bild 1: HelloWorld.wrl Beispiel im WWW Browser 
mit CosmoPlayer Plug-in

2.4 Animation
Um Bewegung in die virtuelle Welt einzufügen, kann man Position, Orientierung und Skalierung von Koordinatensystemen animieren. Wenn sich ein Koordinatensystem bewegt, werden auch alle Shapes und Gruppen innerhalb dieses Koordinatensystems bewegt. Um zu starten, zu stoppen oder um auf eine andere Weise die Animation zu kontrollieren, benutzt man die TimeSensor Node. Dieser Sensor hat die Rolle einer Uhr. Wenn eine bestimmte Zeit abgelaufen ist, sendet TimeSensor ein event. Wenn man diese events von dem eventOut des TimeSensor Knotens zu den anderen Knoten routet, kann man erreichen, daß sich die anderen Knoten so ändern, wie die Uhr des TimeSensor Knotens tickt. Um ein Koordinatensystem zu translieren, rotieren oder skalieren, kann man die events des TimeSensor-Knotens mit dem PositionInterpolator oder OrientationInterpolator Knoten routen. Diese Knoten generieren neue Positionswerte (bzw. Skalierungsfaktoren) und Rotationswerte. Mit dem Routen des EventOuts dieser Interpolatoren, durch den sie neugenerierte Positionswerte, Skalierungsfaktoren bzw. Rotationswerte aussenden, zum entsprechenden EventIn der Transform Node kann man die Koordinatensysteme translieren, rotieren oder skalieren.
Absolute Zeit, fractional time und Zyklusintervall
Man kann die absolute Zeit (in Sekunden gemessene Zeit seit 24:00 Uhr, GMT, 01.01.1970) für die Felder startTime, stopTime und time des TimeSensor Knotens benutzen. Es ist aber meistens angenehmer, die Animation so zu gestalten, daß sie unabhängig von der absoluten Zeit ist. Eine solche Animation ist dann mit Hilfe von fractional time beschrieben. Man kann sich dabei denken, daß die Animation um 0.0 fractional time gestartet und um 1.0 beendet wird. Die Animationsdauer d.h. die absolute Zeit zwischen 0.0 und 1.0 fractional time kann man in dem Feld cycleInterval der TimeSensor Node definieren. Der CycleInterval Feldwert ist ein Zeitintervall, das in Sekunden gemessen wird und größer als 0.0 sein muß (Defaultwert ist 1.0). So kann z.B. eine Animation 5 Sekunden oder 30 Minuten dauern.
StartTime, stopTime, cycleInterval und loop Feldwerte können zusammen benutzt werden, um folgende Effekte zu erzielen:
 
loop Feldwert startTime, stopTime und cycleInterval Feldwertrelationen Effekt
TRUE stopTime <= startTime Läuft immer
TRUE startTime < stopTime Läuft bis zu stopTime
FALSE stopTime <= startTime Läuft einen Zyklus lang und hört dann auf (startTime + cycleInterval)
FALSE startTime < (startTime + cycleInterval) <= stopTime Läuft einen Zyklus lang und hört dann auf (startTime + cycleInterval)
FALSE startTime < stopTime < (startTime + cycleInterval) Läuft kürzer als ein Zyklus, hört dann bei stopTime auf

Keyframe Animation
Keyframe Animation ist eine Animationsbeschreibung, in der die Position, der Skalierungsfaktor oder die Orientierung nur für ein paar Zeitpunkte definiert werden muß, anstatt für die unzähligen fractional times zwischen 0.0 und 1.0. Diese Positionswerte, Skalierungsfaktoren oder Rotationswerte sind key values. Z.B. um ein Auto von einem zum anderen Punkt zu bewegen, muß die keyframe animation nur zwei fractional times definieren (0.0 und 1.0) und nur zwei key values (Start- und Endposition). Eine  Interpolator Node, in diesem Fall eine PositionInterpolator Node, errechnet automatisch alle anderen Positionen zwischen Start- und Endposition für die Zeit zwischen 0.0 und 1.0. So wird die Autoposition bei der fractional time 0.5 genau in der Mitte zwischen Start- und Endposition sein. Sowohl der PositionInterpolator als auch der OrientationInterpolator benutzen lineare Interpolation (Man kann sich das so vorstellen, als ob man zwei Punkte im Raum linear miteinander verbinden würde.). Die fractional times sind im key Feld des Interpolatorknotens spezifiziert und die values im keyValue Feld.
Das fraction_changed - eventOut des TimeSensor-Knotens wird mit dem set_fraction -  eventIn des Interpolatorknotens geroutet. Jedes Mal wenn die TimeSensor Node neue fractional time aussendet, berechnet der Interpolator die neue Positionswerte, Skalierungsfaktoren bzw. Rotationswerte und sendet sie durch sein value_changed - eventOut aus. Dieser ist dann wiederum mit der Transform Node geroutet, um das Koordinatensystem zu translieren, rotieren oder skalieren.
Sehen wir uns ein Beispiel an, indem sich eine Box immer von einem Punkt (-3, 0, 0) zum anderem Punkt (3, 0, 0) und wieder zurück zu dem ersten Punkt bewegt. Diesen Weg macht sie in 5 Sekunden, was im Feld cycleInterval = 5 definiert ist. Der Wert TRUE des loop-Feldes sagt, daß die Animation ständig wiederholt wird.

Beispiel 2: Animation.wrl

#VRML V2.0 utf8
Group {
    children [
    # Moving box
        DEF Cube Transform {
          children Shape {
                appearance Appearance {
                    material Material { }
                }
                geometry Box { size 1.0 1.0 1.0 }
            }
        },
    # Animation clock
        DEF Clock TimeSensor {
            cycleInterval 5.0
            loop TRUE
        },
    # Animation path
        DEF CubePath PositionInterpolator {
            key [
                0.0, 0.5, 1.0
            ]
            keyValue [
                -3.0 0.0 -5.0,  3.0 0.0 -5.0, -3.0 0.0 -5.0
            ]
        }
    ]
}
ROUTE Clock.fraction_changed TO CubePath.set_fraction
ROUTE CubePath.value_changed TO Cube.set_translation

2.5 Sensoren
Um die Welt interaktiv zu machen, kann man einen Sensor mit einer Shape verbinden. Das macht man, indem man den Sensor mit einer Shape gruppiert (s.o. - 2.3 Shapes). Dieser Sensor nimmt dann die Benutzeraktionen mit der Maus wahr und sendet events durch seine EventOuts aus, die dann an die anderen Knoten geroutet werden können. TouchSensor, PlaneSensor, SphereSensor und CylinderSensor nehmen wahr, wenn der Benutzer mit der Maus auf die Shape (mit der ein Sensor verbunden ist) klickt, die Maus über die Shape (mit der ein Sensor verbunden ist) bewegt oder die Maus mit dem gedrückten linken Knopf über die Shape (mit der ein Sensor verbunden ist) zieht. Wenn eine Route zwischen TouchSensor- und TimeSensor Node existiert und der Benutzer mit der Maus auf die Shape (mit der TouchSensor verbunden ist) klickt, sendet die TouchSensor Node den boolschen Wert "TRUE" durch seinen isActive - eventOut und die aktuelle Zeit durch seinen touchTime - eventOut zu der TimeSensor Node. Wenn eine Route zwischen PlaneSensor- und Transform Node existiert und der Benutzer über eine Shape (mit der PlaneSensor verbunden ist) mit der Maus zieht, berechnet die PlaneSensor Node den Translationsabstand (bei der Mausbewegung) und sendet ihn durch seinen translation_changed - eventOut zu Transform Node. Die SphereSensor Node berechnet die Rotationsachsen und -winkel und sendet sie durch seinen rotation_changed - eventOut zu Transform Node, falls sie geroutet sind. Für den Benutzer sieht es so aus, als ob die Shape ein Ball wäre und als ob man diesen Ball beliebig rotieren würde (um alle drei Achsen). Der CylinderSensor funktioniert genau so wie der SphereSensor, nur daß hier die Shape nur um eine Achse rotiert wird (zylindrische Rotation - um die Achse, die durch die Mitte beider Basen eines Zylinders geht). Hier ist eine Beispielwelt für Plane-, Sphere- und CylinderSensor : Sensoren.wrl

Hier ist ein Beispiel für TouchSensor:
Es werden drei Routen definiert: zwischen der TouchSensor- und der TimeSensor Node, zwischen der TimeSensor- und OrientationInterpolator Node und zwischen der OrientationInterpolator- und Transform Node.
Wenn der Benutzer mit der Maus auf die Box klickt, sendet die TouchSensor Node die aktuelle Zeit über seinen touchTime - eventOut zum set_startTime -  eventIn der TimeSensor Node. Die fractional times sind im key Feld von OrientationInterpolator Node spezifiziert und die values im keyValue Feld. Jedes Mal wenn die TimeSensor Node eine neue fractional time aussendet, berechnet der Interpolator eine neue Rotation und sendet sie durch seinen value_changed - eventOut zu der Transform Node, um das Koordinatensystem zu rotieren.

Beispiel 3: TouchSensor.wrl

#VRML V2.0 utf8
Group {
    children [
    # Rotating Cube
        DEF Cube Transform {
            translation 0.0 1.0 -5.0
            children Shape {
                appearance Appearance {
                    material Material { }
                }
                geometry Box { }
            }
        },
    # Sensor
        DEF Touch TouchSensor { },
    # Animation clock
        DEF Clock TimeSensor { cycleInterval 4.0 },
    # Animation path
        DEF CubePath OrientationInterpolator {
            key [ 0.0, 0.50, 1.0 ]
            keyValue [
                0.0  1.0  -5.0  0.0,
                0.0  1.0  -5.0  3.14,
                0.0  1.0  -5.0  6.28
           ]
        }
    ]
}
ROUTE Touch.touchTime             TO Clock.set_startTime
ROUTE Clock.fraction_changed    TO CubePath.set_fraction
ROUTE CubePath.value_changed TO Cube.set_rotation
 

Die VisibilitySensor Node überprüft, ob ein Teil der VRML-Welt (innerhalb einer definierten, unsichtbaren Box) von der Position und Orientierung des Benutzers sichtbar ist. Der Ort und die Größe dieser Boxregion sind mit den Feldern center und size spezifiziert. Sobald sich die Boxregion in der Blickpyramide des Benutzers befindet, sendet der Sensor TRUE durch seinen isActive - eventOut und die aktuelle Zeit durch seinen enterTime - eventOut. Wenn die spezifizierte Boxregion der VRML-Welt die Sichtpyramide des Benutzers verläßt, wird FALSE durch einen isActive - eventOut und die absolute Zeit durch einen exitTime - eventOut ausgesendet.
Die ProximitySensor Node "spürt", wenn der Benutzer eine bestimmte, quaderförmige Region betritt, verläßt oder sich in ihr bewegt. Beim Betreten und Verlassen der Boxregion, funktioniert dieser Sensor genau so wie die VisibilitySensor Node. Jedes Mal, wenn sich der Benutzer innerhalb der Boxregion bewegt, werden seine Position und Orientiertung durch position_changed und orientation_changed - eventOuts ausgesendet.
Die Collision Node wirkt auf die Knoten (Objekte) innerhalb des children-Feldes eines Groupierungsknotens. Wenn der Wert des collide Feldes TRUE ist, wird die Kollision des Benutzers mit dieser Objektgruppe erkannt und der Benutzer kann sich nicht durch diese Objektgruppe bewegen. Um schnellere collision detection zu erzielen, kann man optional eine "Proxy"-Shape im proxy Feld der Collision Node definieren. Statt komplizierte Shapes innerhalb des children -Feldes für die "collisiondetection" -Berechnungen zu benutzen, ist es viel einfacher eine "Proxy"-Shape zu benutzen.

2.6 Weitere Effekte
Detailkontrolle
Je mehr Details die VRML-Welt enthält, desto länger braucht der Browser, sie anzuzeigen. Um beides zu ermöglichen, eine realitätsnahe Welt und eine schnelle Benutzerinteraktion mit ihr, kann man die Details in der Welt kontrollieren. In Abhängigkeit davon, wie nah der Benutzer zu einer Shape ist, kann man mit der LOD Node zwischen verschiedenen Detailversionen derselben Shape wechseln. Je näher er zu einem Objekt ist, desto mehr Objektdetails sieht er.
Viewpoint
Die Viewpoint Node spezifiziert eine vordefinierte Betrachterposition für die VRML-Welt. Der Position-Feldwert spezifiziert die Betrachterposition. Der Orientation-Feldwert rotiert den Viewpoint, um in die gewünschte Richtung zu sehen. Der FieldOfView -Feldwert spezifiziert die Winkelausbreitung der Betrachtersichtpyramide (eine Art "Zoomfaktor"). Der Wert des description Feldes ist eine kleine Beschreibung dieses Viewpoints. VRML-Browser benutzen diese Beschreibung und können ein Viewpointmenü kreieren, aus dem dann der Benutzer einen Viewpoint selektieren kann. So kann sich der Benutzer von einem zu dem anderen Viewpoint innerhalb der VRML-Welt bewegen.
Hintergrund , Nebel, Sound und Anchors
VRML bietet eine Background Node an, mit dessen Hilfe man Himmel- und Bodenfarben definieren kann und Bilder über, unter und um die Welt herum plazieren kann.
Man kann in seine virtuelle Welt auch den Effekt des Nebels einfügen. Der Nebel kann durch die Fog Node kontrolliert werden. Das Color Feld spezifiziert die Farbe des Nebels und das visibilityRange-Feld die Nebeldichte.
Um den Realitätsgrad zu erhöhen, kann man in die virtuelle Welt auch Töne (Geräusche) einbauen. Das kann man mit Hilfe von AudioClip-, MovieTexture- und Sound Node erzielen. Man kann Hintergrundmusik einbauen oder einen Geräusch nach einem Ereignis ertönen lassen oder den Ton von links hören lassen usw.
VRML ermöglicht auch die Benutzung von Verweisen (Links). Die Verweise können z.B. eine Tür mit einem anderen Bestimmungsort (einer zweiten VRML-Welt) verbinden. Eine Anchor Node bindet einen Verweis an ein Objekt. Wenn man auf das Objekt klickt, folgt der Browser dem Verweis, lädt die Daten der zweiten Welt und stellt sie dar.
Skripten
Für komplexere Animationen bietet VRML die Script Node. Die Script Node hat Felder, eventIns und eventOuts. Man kann selber Aktionen einfügen, indem man ein Skriptprogramm schreibt. Die Felder, eventIns und eventOuts stellen die Schnittstellen zu dem Skriptprogramm dar. Diese Programme können in jeder Programmiersprache, die der Browser versteht, geschrieben werden. Meistens sind sie aber in Java oder JavaScript geschrieben.
Eine Script Node wird aktiviert, wenn ein bestimmter event sie erreicht. Sie kann dann Aktionen ausführen wie das Versenden von events, Berechnungen durchführen, usw. Die Script Node verweist auf eine URL, an der sich ein Programm oder ein Skript befindet.
JavaScript-Programm kann sowohl innerhalb, als auch ausserhalb der VRML Datei sein. Innerhalb von VRML-Datei sieht es z.B. folgendermaßen aus:
...
  DEF Filter1 Script {
   url "javascript:
    function set_boolean( bool, eventTime ) {
     if ( bool == true ) { true_changed  = true; }
     else                   { false_changed = true; }
    }"
   eventIn  SFBool set_boolean
   eventOut SFBool true_changed
   eventOut SFBool false_changed
  }
...
URL-Feld der Script Node enthält "javascript"-Wort, das auf die JavaScript deutet. Danach folgt eine JavaScript-Funktionimplementierung. Außerdem sind hier ein eventIn und zwei eventOuts definiert.
Falls man ein externes JavaScript-Programm benutzt, enthält das URL-Feld der Script Node die URL der JavaScript-Datei:
...
  DEF Filter1 Script {
   url "ScriptNode.js"
   eventIn  SFBool set_boolean
   eventOut SFBool true_changed
   eventOut SFBool false_changed
  }
...
Um Java mit der Script Node zu benutzen, braucht man Java VRML-Klassen und Methoden, die den Zugriff auf die Welt ermöglichen. Diese Java Klassen bzw. vrml package (vrml, vrml.node, vrml.field) bekommt man z.B. im Paket dis-java-vrml.zip (http://sdk.web3D.org/source/vrtp/dis-java-vrml/download.html). Die Script Node von vorhin sieht dann folgendermaßen aus:
...
  DEF Filter1 Script {
   url "ScriptNode1.class"
   eventIn    SFBool set_boolean1
   eventOut SFBool true_changed
   eventOut SFBool false_changed
  }
.....
URL-Feld enthält die URL von Java Bytecode.
Hier ist eine und dieselbe Beispielwelt, einmal mit JavaScript und einmal mit Java Programmiersprache :
!!! Achtung:
Blaxxun Contact Viewer (siehe die Links) unterstüzt keine Java mit der Script Node!!! Bitte benutzen Sie deshalb Cosmoplayer!!!

JavaScript: ScriptNode_mitJS.wrl
Java: ScriptNode_mitJava.wrl
Dazugehörende Java-Dateien: ScriptNode1.java, ScriptNode2.java, ScriptNode3.java.
Erzeugen von neuen Knotentypen
VRML bietet mehr als 50 verschiedenen Knotentypen für das Erzeugen von Shapes, Farbenauswahl, Animationsspezifikation usw. Neue Knotentypen kann man mit Hilfe von PROTO (Abkürzung für Prototype) definieren. Man kann die neuen Namen von Knotentypen, Feldern, eventIns, eventOuts und dem Knoten-Body festlegen.
 

3 X3D

Web3D ist ein Konsortium, daß sich mit VRML und anderen Web 3D Technologien beschäftigt. Innerhalb dieses Konsortiums gibt es verschiedenen Working Groups, wie z.B. X3D, GeoVRML, Distrubuted Interactive Simulation (DIS), External Authoring Interface (EAI),  Humanoid Animation (H-ANIM) usw.

3.1 X3D Working Group
Die Ziele des X3D Working Group sind das Design, die Entwicklung, die Auswertung und die Standardisierung der X3D Spezifikation. X3D steht für Extensible 3D und deutet auf die VRML Beschreibung durch XML Syntax hin.

Die VRML200x/X3D Spezifikation enthält folgende Teile:
 

Teil Beschreibung
Teil1 - Core functional specification X3D Kern Spezifikation
Teil2 - Extensions functional specification Erweiterungsspezifikation wegen der Unterstützung anderer Profilen
Teil3 - Scene authoring interface Spezifikation von EAI, von Java und ECMAScript language bindings und von Zugriffsmechanismen über Document Object Modell (DOM)
Teil4 - UTF-8 encoding UTF-8 Kodierung (VRML 97 Kodierungsstiel)
Teil5 - XML encoding (X3D) XML Kodierung (X3D Kodierungsstiel)
Teil6 - Binary encoding Binäre Kodierung (könnte zukünftige Arbeit von BIFS - Binary Format for Scenes - sein).

Teil1 : X3D Kern Spezifikation unterscheidet sich von der VRML 97 Spezifikation folgendermaßen:

  • Einige Eigenschaften wurden entfernt:
    • nicht alle VRML Knoten sind im X3D Kern
  • Es gibt Eigenschaften, die in X3D anders geschrieben werden als in VRML 97. Im Viewer werden sie aber gleich dargestellt. Die Konvertierung dieser Eigenschaften von VRML 97 in X3D ist problemlos und ohne Daten- und Funktionalitätsverlust.
  • Ein paar andere Eigenschaften sind dazugefügt, die in VRML 97 nicht vorhanden sind. Das macht X3D leistungsfähiger. Beim Konvertieren nach VRML 97 können diese Eigenschaften vernachlässigt werden. Z.B.:
    • KeySensor Knoten ist hinzugefügt, der merkt, wenn der Benutzer eine Taste auf der Tastatur drückt.
Teil2 : Hier werden die Eigenschaften spezifiziert, die die X3D Kernspezifikation erweitern, um sowohl volle VRML 97 Funktionalität zu gewährleisten, als auch andere Profile zu unterstützen, wie z.B. GeoVRML oder NURBS (Non Uniform Rational B-Splines) d.h. außer weiteren VRML Knoten, die zusammen mit denen in dem X3D Kern alle VRML Knoten darstellen, werden hier auch die GeoVRML und NURBS Knoten spezifiziert.

Teil3 : Dieser Teil definiert eine Schnittstelle, über die zugegriffen werden kann, um die Objekte in der VRML Welt zu manipulieren. Auf diese Schnittstelle kann man auf zwei Weisen zugreifen: von einer externen Anwendung (external access) und von Script Node innerhalb der VRML Welt (internal access). Der Zugriff auf den VRML Browser ist gleich sowohl für eine Datenbank mit einer Objektschnittstelle als auch für ein Java Applet innerhalb des Web Browsers und die verfügbaren Dienste ändern sich nicht. Die Dienste und ihre Parameter werden hier spezifiziert. Ein Minimum von Eigenschaften wird spezifiziert, die die Browser und andere Anwendungen, die EAI language bindings benutzen, unterstützen müssen. Außerdem wird hier EAI mit Hilfe von Object Management Group's  Interface Definition Language (IDL) definiert, Java und ECMAScript language bindings und die Zugriffsweise auf die hier definierten Dienste über Document Object Model (DOM)  beschrieben.

Teil4 : Hier ist die UTF-8 (ISO 10646-1:1993) Kodierung von VRML spezifiziert. UTF steht für UCS Transformation Format und UCS steht für Universal Character Set. Hier ist die Syntax der VRML -Datentypen, -Felder und -Knoten mit Hilfe des UTF-8 Zeichensatzs spezifiziert. UTF-8 ermöglicht VRML die Unterstützung von englischen Zeichen (A bis Z), als auch Zeichen wie diese in koreanischer, japanische und arabischer Sprache. ASCII Zeichen, die durch meisten Komputer benutzt werden, sind nur ein Teil der UTF-8 Zeichen. Deshalb ist jedes Zeichen, das man an seiner Tastatur tippt, auch ein UTF-8 Zeichen.

Teil5 : Hier ist die XML Kodierung von VRML spezifiziert (VRML mit XML Syntax). Eine DTD (Document Type Definition)für VRML ist hier definiert.

Teil6: Dieser Teil wurde noch nicht spezifiziert. Hier soll die binäre Kodierung von VRML definiert werden, d.h. es soll die Syntax der VRML-Datentypen, -Felder und Knoten in binärem Format spezifiziert werden.

Hier ist das Beispiel 1 in X3D: HelloWorld.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "http://www.web3D.org/TaskGroups/x3d/translation/x3d-compromise.dtd"
                                       "file://localhost/C:/www.web3D.org/TaskGroups/x3d/translation/x3d-compromise.dtd">
<X3D>
  <Header>
    <meta
      name='filename'
      content='HelloWorld.xml'/>
    <meta
      name='description'
      content='Simple X3D example'/>
  </Header>
  <Scene>
    <Group>
      <children>
        <Shape>
          <geometry>
            <Sphere
              DEF='S'/>
          </geometry>
          <appearance>
            <Appearance>
              <texture>
                <ImageTexture
                  url='"earth-topo.gif"'/>
              </texture>
            </Appearance>
          </appearance>
        </Shape>
        <Transform
          translation='-1.0 -2.0 0.0'>
          <children>
            <Shape>
              <geometry>
                <Text
                  string='"Hello" "world!"'/>
              </geometry>
              <appearance>
                <Appearance>
                  <material>
                    <Material
                      diffuseColor='0.1 0.5 1.0'/>
                 </material>
                </Appearance>
              </appearance>
            </Shape>
          </children>
        </Transform>
      </children>
    </Group>
  </Scene>
</X3D>

VRML Knoten sind XML Tags, VRML Felder sind XML Attributen, und Kinderknoten sind der Inhalt von Tags. Unter http://www.web3d.org/TaskGroups/x3d/translation/x3d-compromise.dtd gibt es auch eine DTD (Document Type Definition) für die VRML Darstellung in XML.

X3D Ziele sind:

1. Komponentenmodell:
Das Komponentenmodell bedeutet das Kapseln von entscheidenden VRML Funktionalitäten in einem kleinen Kern, den alle Implementierungen des Standards unterstützen sollen. Der Kern kann dann von den Profilen erweitert werden, um komplexere und anwendungsspezifischere Möglichkeiten zu bieten. Die Komponenten fügen neue Knoten hinzu während die PROTOs schon vorhandene Knoten auf interessante Weise kombinieren. Deshalb ermöglicht das Komponentenmodell eine größere VRML Erweiterung als das PROTOs alleine tun. So braucht man auch keine Komponentenerweiterungen für die Knoten, die mit PROTOs implementiert werden können.

2. Erweiterbarkeit:
Die Erweiterbarkeit bedeutet, daß die Komponenten benutzt werden, um die Kernfunktionalität innerhalb von spezifischen Bereichen zu erweitern. So kann man eine VRML 97 Erweiterung, oder z.B. NURBS, GeoVRML, H-Anim o.ä. Erweiterungen hinzufügen. Durch die Benutzung mehrerer Erweiterungen werden die Profile implementiert. Die Profile sind funktionale Komponenten, die unabhängig von anderen Komponenten sind.

3. Rückwärtskompatibel mit VRML 97:
Es gibt ein Profil, das die vollständige VRML 97 Rückwertskompatibilität bietet.

4. XML Integration:
Eine Erweiterung sorgt für die Möglichkeit, VRML mit Extensible Markup Language (XML) auszudrücken.

Bild 2.   X3D Komponenten: Der X3D Kern enthält nur einige VRML Knoten. Andere Komponenten erben die Kernfunktionalität und fügen neue, komplexere oder anwendungsspezifischere dazu. Die VRML 97 Profile Komponente bietet die vollständige VRML 97 Rückwärtskompatibilität. X3D (Level 2) Erweiterung ist eine Erweiterung der X3D Kernfunktionalität, die die VRML Funktionalität mit XML Syntax bietet. "Geo VRML Erweiterung" ist auch eine mögliche Erweiterung von X3D Kerneigenschaften.

3.2 Andere Web3D  Working Groups

GeoVRML (http://www.ai.sri.com/geovrml/)
Das Ziel dieser Working Group ist die Entwicklung von Tools und Anwendungen für die Darstellung von geographischen Daten mit VRML. Der Wunsch ist, die Geodaten wie Mappen und 3D Bodenmodelle über standard Web VRML Browsern anschauen zu können. Die Gruppe hat GeoVRML 1.0 Recommended Practice Document (http://www.geovrml.org/1.0/doc/index.html) ausgegeben, der die VRML Erweiterung zur Unterstützung von geographischen Anwendungen beschreibt. Es gibt auch Open Source Java Beispielsimplementation dieser Knoten (http://www.geovrml.org/1.0/download/welcome.shtml).

DIS (http://www.web3d.org/WorkingGroups/vrtp/dis-java-vrml/)
Interessenbereich dieser Gruppe ist die Verknüpfung von Distributed Interactive Simulation (DIS) Protokol, Java und VRML mit dem Ziel, large-scale virtuelle Umgebungen zu erhalten. Java Programmierung in Kombination mit VRML bietet eine größere Leistung. Mit dem DIS Protokoll kann man Lageinformationen, wie z.B. Position, Orientierung, Geschwindigkeit, Beschleunigung usw., zwischen Einheiten innerhalb einer gemeinsamen Netzwerkumgebung übermitteln.

EAI (http://www.web3d.org/WorkingGroups/vrml-eai/)
Das Ziel dieser Gruppe ist der Entwurf von einer Standardschnittstelle zwischen einer VRML Welt und externer Umgebung.

H-Anim (http://h-anim.org/)
Das Ziel ist der Entwurf von Standard VRML Präsentationen für Humanoide.
 
 

VRML in 3D-Präsentationen

In diesem Teil unseres Referates beschäftigen wir uns damit, wie man auf Basis der Virtual Reality Modeling Language Präsentationen in 3D gestalten kann.
 

4.1 Eine erste statische Version

Eine erste, sehr simple Version einer solchen Präsentation erzeugt man recht schnell, ohne auch nur eine Zeile VRML-Code beherrschen zu müssen. Dabei kann man folgendermaßen vorgehen:
Man erstellt (wie für "normale" Vorträge) Folien mit Stichpunkten und erschafft mit einem simplen Freeware-3D-Editor eine Welt, in der mehrere Würfel auf dem Boden stehen, die als Textur je eine der Folien erhalten. Dies kann etwa folgendermaßen aussehen:

Als Textur-Bildformat empfiehlt sich JPG oder PNG. Von GIF möchte ich an dieser Stelle abraten, da bei diesem Bildformat meist (je nach Bild-Editor) eine bestimmte Farbe als "durchsichtig" interpretiert wird, was die gesamte Folie unleserlich machen kann.
Die Bildtextur kann mit PowerPoint oder beliebigen Editoren/Zeichenprogrammen erstellt werden, die diese Formate unterstützen.

Als einfachen 3D-Editor möchte ich den VRML-Editor von RenderSoft hier kurz vorstellen. Er ist kostenlos erhältlich, bietet zwar lediglich die Grundfunktionen von VRML an, ist dafür aber sehr leicht zu bedienen.
Editoren, die fast die gesamte Funktionalität von VRML zugänglich machen, sind im Normalfall sehr teuer (teilweise bis 1500 DM), und eine (eventuelle) kostenlose Testnutzung ist auf ca. 4 Wochen begrenzt. Diese Programme sind relativ komplex, so dass die Einarbeitung in die Benutzung des Editors etwas zeitintensiv ist. Welche Art von Editor man nun wählt, hängt davon ab, wie kompliziert die zu erstellende Welt sein soll, oder ob ein simpler Editor auch ausreichen würde.
Ein Beispiel für einen solchen komplexeren 3D-Editor ist Spazz3D , ein sehr mächtiges Programm, das aber dafür verhältnismäßig kompliziert zu bedienen ist (und trotzdem leider nur FAST alle für dieses Thema interessanten VRML-Möglichkeiten abdeckt):

Bleiben wir in unserem Beispiel nun also beim einfacher zu verwendenden RenderSoft-Editor. Mit einem Klick auf das Quader-Icon erscheint ein Würfel im 3D-Fenster. Per Drag&Drop zieht man diesen an die gewünschte Stelle im Raum. Mit einem Klick auf das Texture-Icon ("PICT") öffnet sich ein Dialog, in dem man eine vorher erstellte Textur auswählt. Wenn man diese Prozedur einige Male wiederholt, erhält man in etwa dieses Bild:

Unter "File/Export" kann man die Datei nun im VRML2.0-Format speichern. Man erhält eine solche Datei:  RS-3cubes.wrl . Mit einem VRML-Viewer (siehe die Links) kann man die Szene betrachten und sich in ihr bewegen.

4.2 Animation

Natürlich wäre es ganz schön, wenn die Welt nicht statisch wäre, sondern wenn die Bewegung von Objekten etwas "Leben" hineinbringen würde. Auch dies ist recht einfach zu bewerkstelligen:
Dazu klickt man auf "Animation/Show Animation Panel"). Das Fenster mit den Animationseinstellungen erscheint.
Die Zeit, die während der Animation verstreicht, wird in einzelne Zeitpunkte unterteilt, sogenannte 'Frames'. In unserem Beispiel soll nun der Vorgang 30 Frames dauern, und in dieser Zeit soll sich ein Würfel drehen.
Links oben im Feld namens 'Frame Number' steht anfangs die Zahl 0. Dies bedeutet, dass der jetzige Zustand der Welt dem Frame 0 zugeordnet ist.

Nun wollen wir den Zustand für Frame 30 definieren. Dazu gibt man im Feld 'Frame Number' die Zahl 30 ein. Dann klickt man auf
das 'Rotate Object'_Icon (der rund gebogene Pfeil) und dreht den Würfel per Drag&Drop in die richtige Position.
Wenn man links unten auf 'Play' drückt, sieht man, wie die Frame-Number  von 0 bis 30 läuft und der Würfel sich langsam von der ersten Position in die zweite dreht. Wenn man möchte, dass sich die Bewegung endlos wiederholt, stellt man links in der Mitte die Animations-Eigenschaften auf 'loop'. Damit sich die Folientextur einmal bewegt und man sie danach lesen kann, lässt man die Einstellung auf 'No Repetition'. Fertig ist die Animation!
Dabei ist eine ähnliche Datei wie RS-animation.wrl entstanden. Wenn man diese nun im Browser startet, sieht man, dass die Bewegung des Würfels direkt startet, wenn die Welt fertig geladen ist.
Vorsicht beim Viewer 'Blaxxun Contact' ! Bei mir stellte er Animationen teilweise nicht mehr da, sobald der sich bewegende Körper eine Textur besaß, die größer als ca. 50 kB ist.
Als nächsten Schritt möchten wir erreichen, dass die Drehung erst beginnt, wenn der Betrachter dem Würfel nahe genug gekommen ist. Dazu erläutere ich zunächst mit Hilfe des folgenden Schaubildes, wie dies in VRML ermöglicht werden kann:

Zuerst erstellt man einen ProximitySensor genau am Ort der Box, die gedreht werden soll. Mit ihm kann man "spüren", wann der Avatar in einen bestimmten Bereich eingedrungen ist (hier symbolisiert durch den grünen, halbdurchsichtigen Quader). Betritt der Betrachter nun diesen Bereich, so sendet der Proximity-Sensor (über sein event-out 'enterTime') die aktuelle Zeit an einen TimeSensor, der dann startet (event-in 'startTime'). Dieser sendet nun (über sein event-out 'fraction_changed') die sogenannten fractional times zwischen 0 und 1 an einen OrientationInterpolator.
Dieser wurde mit den Rotationswerten für die fractional times 0 und 1 initialisiert; so kann er für jeden "dazwischenliegenden" Zeitpunkt (der ihn als event-in 'set_fraction' erreicht) den passenden, linear errechneten Rotationswert errechnen. Diesen sendet er (als event-out 'value_changed') an den Würfel, der gedreht wird. Dieser nimmt den Rotationswert an, der als event-in 'set_rotation' zu ihm gelangt. So entsteht eine gleichmäßige Drehung.

4.3 "Hand-Eingriff" in die WRL-Datei

Schauen wir nun also in die Datei  RS-animation.wrl hinein und sehen nach, wie der 3D-Editor die beim Laden der VRML-Welt beginnende Animation einbaute. Dafür empfehle ich den TEXT-VRML-Editor VRML-Pad . Er hilft mit farblicher Hervorhebung der Syntax und einem Szenen-Baum bei der Orientierung, außerdem überprüft er Syntax und Semantik während der Eingabe und vervollständigt auf Wunsch eingegebene Wortanfänge.
Im unteren Teil der Datei 'RS-animation.wrl' entdecken wir folgendes:

Der zweite dieser drei DEF-Abschnitte erzeugt einen ProximitySensor namens '_startClock', der praktisch unendliche Größe (Attribut 'size') hat. Dies bedeutet, dass beim Laden der Welt der Avatar sofort automatisch den Bereich des ProximitySensors 'betritt' und ihn auslöst. Damit startet der Sensor den TimeSensor namens '_globalClock'. Dies ist der 'Taktgeber', der den OrientationInterpolator mit den  fractional times zwischen 0 und 1 versorgt. Dieser sendet dann die entsprechenden Orientationswerte an den drehenden Würfel, hier '_motion_node8' genannt.

Nun fällt natürlich auf, dass dies gar nicht soweit entfernt ist von dem, was wir als Ziel haben: die Animation durch das Annähern des Avatars auszulösen.
Dazu sind lediglich folgende 2 Dinge zu tun:

  • Dem ProximitySensor eine angemessene Größe zuweisen (z.B. 2 x 2 x 2  'Meter')
  • Den ProximitySensor an den richtigen Platz verschieben
Wie man weiter oben in der Datei sieht, befindet sich der Würfel an der Stelle 0.3 0.0 3.62 im Raum (x,y,z-Koordinaten; y ist die Höhe) :

    DEF _motionNode8 Transform {
         scale  0.300 0.300 0.300
         translation  0.300 0.000 3.620
    [...]

Wir müssen also nur die Zeile:

    DEF _startClock ProximitySensor { size 10000000000 10000000000 10000000000 }

ersetzen durch den Block:

    DEF _startClock ProximitySensor {
         size 2 2 2
         center 0.3 0 3.62
    }

Fertig ist die Datei  RS-animation_2.wrl , unser Ziel ist erreicht.
Auf die gleiche Weise erstellt man auch recht schnell andere nette Effekte:

  • Würfel bewegen sich (Translation) : siehe dazu im RenderSoft-Editor das 'Move Object'-Icon
    • Bei diesem Effekt wird ein PositionInterpolator statt des OrientationInterpolators erzeugt, der die jeweiligen Positionen im Raum errechnet.
  • Würfel ändern ihre Form (wachsen, schrumpfen etc.) : siehe das 'Scale'-Icon
  • Die (Folien-)Textur auf einem Würfel dreht sich, wächst oder schrumpft: siehe das 'Texture Transform' (TT) - Icon

4.4 Auslösen von Effekten durch Mausklicks

Um noch intensiver mit der Welt zu interagieren, kann man mit Hilfe von TouchSensoren Aktionen durch Mausklicks in Gang setzen. Betrachten wir folgenden Effekt als Beispiel für eine solche Anwendung:
Der Betrachter steht vor einem Würfel, der mit einer Textur versehen ist. Sobald er diesen Würfel anklickt, scheint die Textur sich langsam in eine andere zu verwandeln (z.B. in die nächste Vortragsfolie): RS-changing-texture-2.wrl .
Ein Objekt in VMRL kann nicht mit zwei verschiedenen Texturen belegt werden. Deshalb greifen wir zu einem kleinen Trick: Wir erstellen einen Würfel mit der ersten (Folien-)Textur. Innerhalb von ihm erschaffen wir einen zweiten, minimal kleineren Würfel mit der zweiten Textur. Dann verwenden wir das Animations-Panel analog zu dem Beispiel davor, mit dem Unterschied dass wir jetzt die Transparenz bei Frame 0 auf 0 (das Objekt ist voll sichtbar) setzen und bei Frame 30 auf 1 (das Objekt ist unsichtbar). Dies erledigt man mit dem 'transparency'-Schieberegler im Material-Fenster (Icon: 'Colors). Es entsteht die Datei  RS-changing-texture-1.wrl , in der die gewünschte Animation stattfindet, allerdings wieder sofort beim Laden der virtuellen Welt. Schauen wir also in die Datei hinein:

Der Start der Aktion wird wie beim vorherigen Beispiel durch den "unendlich" großen ProximitySensor 'startClock' ausgeführt. Diese zwei Zeilen müssen  mit dem Lattenkreuz (#) auskommentiert werden:

    DEF _startClock ProximitySensor { size 10000000000 10000000000 10000000000 }
    ROUTE _startClock.enterTime TO _globalClock.startTime

Jetzt müssen wir einen TouchSensor erzeugen und dann dafür sorgen, dass das Anklicken des Sensors die Aktion auslöst. Der TouchSensor soll  zum größeren der zwei Würfel gehören, deswegen fügen wir die rot markierte Zeile in der Definition dieses Würfels ein:

      # der etwas größere Würfel
      Transform {
       children [
        Transform {
         scale  0.300 0.300 0.300
         children [
          Shape {
           appearance Appearance {
             material DEF _chromaNode43  Material {
               ambientIntensity 0.200
               diffuseColor  0.800 0.800 0.800
               shininess  0.000
             }
             texture DEF _texture42 ImageTexture {
               url  "animation.jpg"
             }
           }
           geometry Box {
               size  2.000 2.000 2.000
           }
          }, DEF ausloeser TouchSensor {}
         ]
        }
       ]
      }

'ausloeser' ist der Name, den wir dem Sensor geben.
Nun müssen wir noch an der Stelle, an der wir die zwei Zeilen des ProximitySensors auskommentieren, eine Zeile einfügen:

    # DEF _startClock ProximitySensor { size 10000000000 10000000000 10000000000 }
    # ROUTE _startClock.enterTime TO _globalClock.startTime
      ROUTE ausloeser.touchTime   TO _globalClock.startTime

Diese Zeile bewirkt, dass die Animation beginnt, sobald der TouchSensor angeklickt wurde ('touchTime').
Fertig ist die Datei  RS-changing-texture-2.wrl und unser Ziel erreicht.

4.5 Fußboden & Hintergrund

Um einen Fußboden in die Szene zu integrieren, kopiert man einfach die folgenden Zeilen in seine WRL-Datei:

    # Fußboden
    Shape {
        appearance Appearance {
            textureTransform DEF _ttNode441 TextureTransform { scale  222 222 }
            texture ImageTexture { url "floorBraun.gif" }
        }
        geometry IndexedFaceSet {
            coord Coordinate { point [ -50. -0.3  50.,  50. -0.3 50.,
                                        50. -0.3 -50., -50. -0.3 -50. ] }
            coordIndex [ 0, 1, 2, 3, -1 ]
        }
    }

  (Wenn die Szene noch leer ist, nicht den VRML-Header vergessen: #VRML V2.0 utf8)

Der obige Code-Abschnitt erstellt eine riesige, quadratische Fläche (IndexedFaceSet), auf der der Avatar sich fortbewegen kann. Lediglich den Namen der Textur (rot markiert) muß man korrigieren. Mit dem Attribut 'scale' in Zeile 4 stellt man ein, wie oft das Bild nebeneinander auf die Bodenfläche abgebildet wird.

Um unseren Betrachter auf die richtige Höhe/Größe zu bringen, müssen wir noch die folgenden Zeilen in die Datei kopieren :

      # Höhe des Betrachters: 1,60 m Augenhöhe, Gravitation: aus ("FLY")
      NavigationInfo {
            avatarSize [ 0.1, 1.6, 0.1 ]
            type ["FLY", "ANY"]
      }

Der 'Typ' "FLY" bedeutet, dass der Betrachter nicht an die Gravitation gebunden ist, mit "ANY" erlauben wir dem Viewer, dass in ihm auch andere Fortbewegungsmodi eingestellt werden dürfen.
Es entsteht folgendes Grundgerüst einer VRML-Welt:  grundgeruest.wrl .

4.5.1 Mehrschichtiger Fußboden

Einen hübschen Effekt kann man auch mit mehrschichtigen Fußböden erzielen, wenn die oberen Schichten teilweise durchsichtig sind (multiple_floors.wrl), so dass man die darunterliegenden Schichten sieht (insbesondere wenn man sich bewegt). Dazu muß man die oberen Schichten als GIF-Dateien erstellen und eine der vorkommenden Farben als 'transparent' definieren. Nicht alle Bildverarbeitungsprogramme ermöglichen einem dieses, bei anderen ist es recht gut versteckt (z.B.bei Photoshop 5.0 unter "File/Export/Gif89a-Export" als GIF abspeichern, diese Datei laden und dann wieder "File/Export/Gif89a-Export" aufrufen. Nun kann man durch einen Klick in das Bild die transparente Farbe wählen).

4.5.2 Hintergrund

Nun fehlt noch ein Hintergrund für die Szene. Dazu kann man 4 Wände um die "erschaffene" Welt "stellen" lassen, die sich aber immer in unendlicher Ferne zu befinden scheinen. Verantwortlich sind die folgenden Zeilen:

    # Hintergrund
    Background {
         frontUrl "sky.jpg"
         backUrl  "sky.jpg"
         leftUrl  "sky.jpg"
         rightUrl "sky.jpg"
    }

Es entsteht eine Datei wie diese (hintergrund.wrl):

Wenn man keinen Background-Node verwenden möchte, kann man den Hintergrund auch selbst erschaffen, indem man 5 riesige Flächen (ähnlich dem Fußboden) erstellt: Vier für die Seiten und eine als "Dach" der Szene: (hintergrund_perHand.wrl) .

4.6 Geräusche

Auch Geräusche, die auf beliebige Art ausgelöst werden, sind ohne großen Aufwand realisierbar. Dazu erstellt man erst einmal einen unsichtbaren "Lautsprecher", aus dem der Sound tönen wird:

        Sound {
            source DEF speaker AudioClip {
                url "explode.wav"
            },
            location 8 0 -6
        }

Im Attribut 'url' gibt man den Namen der Datei an, die abgespielt werden soll,  'location' ist der Ort im Raum, an dem das Geräusch ertönen soll.

Als zweites müssen wir noch den Auslöser erschaffen, z.B. einen TouchSensor oder einen ProximitySensor. Dies geschieht auf die gleiche Weise wie in den obigen Beispielen. Als letztes verknüpfen wir noch den Auslöser mit unserem "Lautsprecher":
Wenn man einen TouchSensor namens 'touchSensor' als Auslöser wählt:

    ROUTE touchSensor.touchTime TO speaker.startTime

Oder: wenn man einen ProximitySensor namens 'proxSensor' als Auslöser wählt:

    ROUTE proxSensor.enterTime TO speaker.startTime

4.7 Mehrere Effekte mit EINEM Sensor auslösen

Man kann mit einem Sensor mehrere Aktionen gleichzeitig auslösen. Betrachten wir hier zum Beispiel einen ProximitySensor, der eine Bewegung und gleichzeitig ein Geräusch auslösen soll. Dies kann man erreichen, indem die 'enterTime' des ProximitySensors sowohl an den Soundknoten als auch an den TimeSensor gesendet wird, der die für die Animation nötigen fractional times erzeugt (siehe Beispiel oben).

ROUTE proxSensor.enterTime TO speaker.startTime
ROUTE proxSensor.enterTime TO timeSensorForAnimation.startTime

4.8 Viewpoints

Sehr elegant sieht es aus, wenn man nicht nur selbst in der virtuellen Welt herumläuft, sondern 'rasante' Kamerafahrten einbaut. Dazu muss man nicht die Fahrten selbst definieren, sondern man bestimmt nur die 'Aussichtspunkte' (Viewpoints); die Fahrten zwischen ihnen beherrscht der Viewer ohne weiteres Zutun des VRML-Designers. Ein Viewpoint hat die Form:

    Viewpoint {
       position  9 0 -5
       orientation 0 1 0  3.14
       fieldOfView  0.5
       description "Kamera Wuerfel 1"
    }

'position' ist der Ort im Raum, 'orientation' definiert eine Drehung: die ersten 3 Zahlen (x,y,z) bestimmen eine Achse, und die vierte Zahl gibt den Winkel im RAD-Maß an, um den gedreht werden soll. In diesem Beispiel wird also um die y-Achse gedreht, und zwar recht genau eine halbe Umdrehung (3.14 = PI).
'fieldOfView' ist eine Art Zoomfaktor, und damit man im Viewer den Viewpoint auch auswählen kann, muss man ihm einen Namen/eine Beschreibung geben ('description').
Die meisten VRML-3D-Editoren ermöglichen das Erstellen von Viewpoints, mit etwas Überlegung kann man diese auch per Hand setzen.

Hinweis: Beim Setzen der Viewpoints sollte man die Gegebenheiten der CAVE berücksichtigen und mit einfließen lassen:

  • Augenhöhe ( = Viewpoint-Höhe): ca. 1,30 m ( 1 Meter entspricht 1 Längeneinheit in VRML ).
  • Entfernung  Auge->Leinwand ( = Entfernung Viewpoint->Betrachtetes Objekt) : 2,70m
  • Außerdem empfiehlt es sich, Würfel der Kantenlänge 2 Meter zu nehmen, da dies der Höhe der Leinwand entspricht (Diese Maße entsprechen der CAVE der First GMD, in der wir unser Referat hielten.)

4.9 Vorlagen für die Erstellung einer VRML-Welt

Wir stellen den anderen Teilnehmern des Kurses mehrere Dateien zur Verfügung, um ihnen ein möglichst schnelles Erstellen einer 3D-Umgebung zu ermöglichen (vorlagen1_1.zip). Diese Dateien enthalten einzelne Teile (Objekte) einer solchen Welt (z.B. einen Würfel, der sich bei Annäherung dreht, inklusive passendem Viewpoint etc.). Diese Komponenten können beliebig kombiniert und zusammengefügt werden. Lediglich der Name von Texturen und ähnliches muß natürlich verändert werden, und an einer markierten Stelle in einer solchen Template-Datei muss angegeben werden, wo auf der virtuellen Welt dieses Objekt (inklusive all seiner Komponenten) erscheinen soll. Diese Stelle hat die Form:

    # Hier angeben, wo im Raum dieses Objekt stehen soll(x,y,z-Koordinaten).
    # (Die mittlere Komponente (y) entspricht der Höhe, sollte also meist unverändert bleiben.)
    translation 0 0 0

Um hierbei nicht den Überblick zu verlieren, sollte man eine Skizze seiner geplanten VRML-Welt (Sicht von oben) anlegen. Hierbei ist X die waagerechte Achse (nach rechts gerichtet) und Z die senkrechte Achse (nach unten gerichtet).

WICHTIG: In mehreren Dateien werden Knoten-Namen definiert, z.B. :

    DEF ausloeser TouchSensor {}

auf die dann weiter unten zugegriffen wird:

   ROUTE ausloeser.touchTime TO _globalClock.startTime

Wenn man eine solche Datei mehrmals verwenden will (z.B. um mehrere gleichartige Würfel zu haben, die mit verschiedenen Folien-Texturen belegt sind), muß man z.B. die definierten Namen umbenennen ( z.B. 'ausloeser' in 'ausloeser_2' ändern), da ein Name jeweils nur ein Mal definiert werden darf!
Ein wesentlich eleganterer Weg ist die Verwendung des 'Inline'-Knotens. Dieser bewirkt so etwas wie 'Import'- oder 'include'_Befehle: eine andere Datei wird eingelesen. Wenn man seine Hauptdatei so aufbaut, dass dort die einzelnen Objekte  per 'Inline' importiert werden, behält man einen guten Überblick und umgeht diese Probleme mit doppelten Namen.

    Inline { url "objekt_1.wrl" }
    Inline { url "objekt_2.wrl" }
    Inline { url "objekt_3.wrl" }
              [...]

Wir haben die Lage der Viewpoints und die Größe der Würfel in den Vorlagen so genau wie möglich auf eine CAVE abgestimmt, deren Leinwandhöhe 2,00 m beträgt und die auf eine Augenhöhe von 1,30 m ausgerichtet ist. Deshalb erscheint es auf dem heimische PC so, als ob die Viewpoints zu weit oben stehen würden.
Weiterhin empfielt es sich, links und rechts einen "Rand" zu lassen, da die Sicht in der CAVE etwas schmaler ausfällt.
Hinweis: Man sollte  also prinzipiell bereits vor dem Tag des Referates seine VRML-Welt in der CAVE testen. Szenen, die zu Hause wunderbar liefen, können in der CAVE ganz anders aussehen: insbesondere Viewpoints und der Background-Node können für unangenehme Überraschungen sorgen!
 
 

5 Referenzen & Links

VRML-Viewer (Plugins für Web-Browser):

VRML-Editoren:

Weitere Quellen:

VRML
1. "VRML 2.0 SourceBook" - Andrea L. Ames, David R. Nadeau und John L. Moreland
2. Spezifikation VRML v1.0: http://www.vrml.org/VRML1.0/vrml10c.html#History
3. Empfehlenswert: Das Siggraph96-Tutorial: http://www.sdsc.edu/siggraph96vrml
4. Spezifikation VRML97: http://www.web3d.org/fs_specifications.htm
5. vrml package: http://sdk.web3D.org/source/vrtp/dis-java-vrml/download.html

X3D
1. Web 3d Konsorium: http://www.web3d.org/
2. X3D Working Group: http://www.web3d.org/x3d.html
3. DTD für VRML: http://www.web3d.org/TaskGroups/x3d/translation/x3d-compromise.dtd
4. Geo Working Group: http://www.ai.sri.com/geovrml/
5. GeoVRML 1.0 Recommended Practice Document: http://www.geovrml.org/1.0/doc/index.html
6. Java Beispielimplementation von Geo-VRML-Knoten: http://www.geovrml.org/1.0/download/welcome.shtml
7. DIS-Java_VRML Working Group: http://www.web3d.org/WorkingGroups/vrtp/dis-java-vrml/
8. VRML-EAI Working Group: http://www.web3d.org/WorkingGroups/vrml-eai/
9. H-Anim Working Group: http://h-anim.org/
 
 

  
Bürgerliches Gesetzbuch BGB: mit Allgemeinem Gleichbehandlungsgesetz, BeurkundungsG, BGB-Informationspflichten-Verordnung, Einführungsgesetz, ... Rechtsstand: 1. August 2012
Siehe auch:
Handelsgesetzbuch HGB: ohne Seehandelsrecht, mit …
Strafgesetzbuch StGB: mit Einführungsgesetz, …
Grundgesetz GG: Menschenrechtskonvention, …
Arbeitsgesetze
Basistexte Öffentliches Recht: Rechtsstand: 1. …
Aktiengesetz · GmbH-Gesetz: mit …
 
   
 
     

This web site is a part of the project StudyPaper.com.
We are grateful to Manuel Schiewe, Bozana Bokan for contributing this article.

Back to the topic site:
StudyPaper.com/Startseite/Computer/Internet

External Links to this site are permitted without prior consent.
   
  deutsch  |  Set bookmark  |  Send a friend a link  |  Copyright ©  |  Impressum