| |
VRML / X3D und 3D-Präsentationen
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.
4 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/
|
| |
|
|