Virtuelle Realität
Funktionale Modellierung in X3D
Dr. Thies Pfeiffer
Termin: Freitags, 10:15 Uhr
Raum: S2-121
Überblick
Inhalte dieser Veranstaltung
- Umsetzung von funktionalen Elementen in der Simulation
- Funktionale Modellierung in X3D
- Einführung in die wesentlichen Techniken der funktionalen Modellierung
- Felder
- Routen
- Scripting in X3D
- Skriptknoten in JavaScript und Java
- Externe Anbindung
Funktionale Modellierung - Stand der Vorlesung
Bisher
- Modellierung von Geometrie, Vorlesungstermine 02 und 03
- Punkte, Linien, Flächen
- Einfache Objekte
- Komposition von komplexeren Objekten über Transformationen
- Einfacher Szenengraph
- Modellierung von Geräuschen, Vorlesungstermin 04
- Positionierung von 3D Sound über das Sound-Tag
- Die bisherigen Modellierungen sind statisch und nicht interaktiv
- Bis auf die vom Browser bereitgestellte Navigation
Funktionale Modellierung
Funktionale Modellierung
Warum benötigen wir eine funktionale Modellierung?
- Unsere reale Welt verändert sich ständig und wir können Einfluß auf sie haben. Wenn eine virtuelle Welt natürlich vorkommen soll, dann sollte sie sich ebenfalls verändern und vom Benutzer verändert werden können.
- Viele Sachverhalte, die mit Mitteln der Virtuellen Realität dargestellt werden sollen, sind in sich dynamisch.
- Oft geht es z.B. um die Simulation von Prozessen mit Benutzer-Interaktion, z.B. bei Trainings oder Erprobungen. Dort muss sich die Situation dynamisch an die Entscheidungen des Benutzers anpassen.
- Häufig werden sehr komplexe Daten dargestellt und daher ist während der Exploration der Daten eine Auswahl und Manipulation durch den Benutzer erforderlich, z.B. zur Auswahl von Kriterien als Filter für die Darstellung.
- Inhalte, die bestimmten Mustern folgen, können über funktionale Modellierung einfacher/kompakter ausgedrückt werden (Design-Time Vorteil).
Funktionale Modellierung
Rahmenbedinungen
- Die Darstellung der Virtuellen Welt erfolgt in diskreten Zeitschritten. Diese können für die unterschiedlichen Modalitäten verschieden sein
- Framerate der visuellen Darstellung (Ziel: > 25 Hz)
- Samplerate der auditiven Darstellung (Ziel: > 44 kHz)
- Updaterate der taktilen Darstellung (Ziel: > 1 kHz)
- Die funktionale Modellierung muss diesen Umstand berücksichtigen und sollte für eine entsprechende konsistente Aktualisierung der Weltbeschreibung sorgen.
- Entkopplung von Simulationszeit und Framerate: nur so kann die Simulation auch unter ungünstigen Bedingungen noch valide Ergebnisse zeigen, wenn auch dann vielleicht nicht mehr in interaktiven Frameraten.
Funktionale Modellierung in X3D
Der Szenengraph von X3D
X3D Szenengraph
- X3D ist eine objektorientierte Szenenbeschreibungssprache (ähnlich wie Java3D, VRML, OpenInventor)
- Graphische Darstellung umfasst vier Basisknoten
- Wurzelknoten/root: Die Basis des Szenengraphen. Es kann nur einen geben!
- Gruppenknoten: Fassen eine beliebige Anzahl an Knoten zusammen, die sog. Kinder/Children
- Kindknoten: Sind keine Gruppenknoten, können aber eine Komposition einzelner Objektknoten umfassen (Bsp: Shape)
- Objektknoten: Sind keine Kindknoten oder Gruppenknoten und haben selbst auch keine untergeordneten Knoten mehr (Bsp. ImageTexture)
Basis-Knotentypen für die Darstellung von X3D Szenengraphen
Der Szenengraph von X3D
X3D Szenengraph: Beispiel
Einfaches Beispiel für einen Szenengraphen in X3D
Der Szenengraph von X3D
X3D Szenengraph: Felder
- Knoten in X3D besitzen Felder
- Einige haben wir schon genutzt, aber noch nicht kennen gelernt
- children
- geometry
- Die Hierarchie des X3D-XML Dokumentes wird also auf Felder der X3D Knoten abgebildet.
- Andere haben wir schon genutzt
- Transform:translation
- Transform:rotation
- Transform:scale
Beispiel für einen Szenengraphen in X3D mit Darstellung der versteckten Felder
Der Datengraph: Felder
Der Datengraph
- Orthogonal zum Szenengraph lässt sich in X3D ein Datengraph definieren.
- Im Datengraph werden einzelne Felder miteinander verbunden (Ausgangsfeld $\to$ Zielfeld).
- Eine Änderung des Feldinhalts im Ausgangsfeld wird dann in das Zielfeld übertragen (aber nicht automatisch auch umgekehrt).
- Um die Verbindungen syntaktisch abzusichern, werden für jedes Feld Zugriffsrechte und Typ festgelegt.
Beispiel für einen Datengraph in X3D: die rotation-Felder der beiden Transformationsknoten werden verbunden, so dass die lokale (!) Rotation der Box stets auch auf die Sphere übertragen wird. Dies gilt jedoch nicht umgekehrt!
Der Datengraph: Felder
Zugriffsrechte
- inputOnly: nur schreibender Zugriff
- outputOnly: nur lesender Zugriff
- inputOutput: schreibender und lesender Zugriff
- initializeOnly: schreibender Zugriff nur bei Initialisierung des Knotens
Typen
- Unterscheidung in Single-Fields (SF) und Multi-Fields (MF), letztere mit einfacher Array-Syntax
- Folgende Typen sind definiert:
- SFBool/MFBool, SFFloat/MFFloat, SFDouble/MFDouble, SFColor/MFColor, SFColorRGBA/MFColorRGBA, SFInt32/MFInt32, SFString/MFString, SFTime/MFTime
- SFRotation/MFRotation, SFVec2f/MFVec2f, SFVec3f/MFVec3f
- SFImage/MFImage, SFNode/MFNode
Der Datengraph: Routen
Felder verknüpfen: Routen
- Die Verknüpfung der Felder geschieht durch Routen
- Syntax:
<ROUTE
fromNode="" fromField=""
toNode="" toField=""/>
- Beispiel:
<Transform DEF="T1" rotation="1 0 0 0.75"/>
<Transform DEF="T2"/>
<ROUTE
fromNode="T1" fromField="rotation"
toNode="T2" toField="rotation"/>
- Routen sind keine Knoten des Szenengraphen (als Kennzeichnung komplett groß geschrieben), ihre Spezifikation wird direkt umgesetzt.
- Daher wichtig: Die Route muss nach den Bezugsknoten definiert werden, da sonst die Referenzen unbekannt sind!
Der Datengraph: Animationen
Animationen mit dem Datengraph: TimeSensor
- Neben Knoten zur Geometrie-Beschreibung gibt es in X3D auch Knoten, die Funktionen für den Datengraph bereitstellen.
- Wichtigste Knoten für die Animation sind
TimeSensor und Interpolatoren (nächste Seite)
- Syntax:
<TimeSensor
fraction_changed (SFTime, outputOnly): Wert zwischen 0 und 1.0, 0 beim Start, 1.0 bei Erreichen von cycleInterval nach dem Start
cycleInterval (SFTime, inputOutput): Dauer der Animation
loop (SFBool, inputOutput): Wenn gesetzt, unendliche Wiederholung, startet dann auch den TimeSensor
startTime (SFTime, inputOutput): wenn kleiner aktueller Zeit, startet der TimeSensor
/>
Der Datengraph: Animationen
Animationen mit dem Datengraph: Interpolatoren
- Wichtige Interpolatoren:
PositionInterpolator, OrientationInterpolator, ScalarInterpolator, ColorInterpolator ...
- Syntax:
<PositionInterpolator
set_fraction (SFFloat, inputOnly): Wert zwischen 0 und 1.0, als Index in die Schlüsseltabelle (Bsp. 0.7)
key (MFFloat, inputOutput): Schlüsseltabelle mit den Schlüsseln, muss gleiche Anzahl an Einträgen wie keyValue haben (Bsp. 0 0.5 1.0)
keyValue (MFVec3f, inputOutput): Schlüsselwerte, hier Vec3f (Bsp. 0 0 0, 1 0 0, 0 0 0)
value_changed (SFVec3f, outputOnly): aktueller Wert, ergibt sich als Wert in
keyValue an der Position in key ab der noch
set_fraction > key gilt (Bsp. 1 0 0)
/>
Der Datengraph: Interaktionen
Animationen mit dem Datengraph: Interaktionen
- "Sensoren" zur Interaktion mit dem Benutzer:
TouchSensor, PlaneSensor, CylinderSensor, SphereSensor, KeySensor, StringSensor
- Syntax:
<TouchSensor
isOver (SFBool, outputOnly): Wert true wenn Maus über Geometrie
isActive (SFBool, outputOnly): Wert true wenn Maus über Geometrie und Mausbutton geklickt
touchTime (SFTime, outputOnly): Zeitpunkt des letzten Klicks
/>
- Routed man
isActive in das loop Feld eines TimeSensors oder touchTime in startTime eines TimeSensors, so wird dieser gestartet und läuft mehrfach oder einfach durch.
Download als X3D-Datei
Dieses Beispiel in X3DOM ist derzeit (14. November 2011) nicht funktionsfähig, da die aktuelle Version von X3DOM keinen TouchSensor unterstüzt und der TimeSensor nicht das Standardverhalten zeigt. Eigentlich dürfte sich der Block nicht bewegen. Das Beispiel sollte jedoch im InstantPlayer laufen, dazu müssten die Tags jedoch alle mit einem Großbuchstaben anfangen und ROUTE ganz groß geschrieben werden.
Scripting
Der Script Knoten
- Neben den Möglichkeiten des Datengraphen bietet X3D noch einen Script Knoten der entweder durch JavaScript oder durch Java implementiert werden kann.
- Syntax:
<Script
url (MFString, inputOutput): Array mit URLs zum Script-Code (falls nicht JavaScript inline als CDATA verwendet wird)
directOutput (SFBool, initializeOnly): Sollte auf true gesetzt werden, falls das Skript anders als durch Routen den Szenengraphen modifiziert.
mustEvaluate (SFBool, initializeOnly): Sollte auf true gesetzt werden, falls das Skript auf jeden Fall direkt ausgeführt werden soll und keine Werte für ein Batch-processing gecached werden dürfen.
/>
Scripting: JavaScript
Scripting mit JavaScript
- Typischer Aufbau
function initialize() {}: wird beim Initialisieren des Scripts aufgerufen
function prepareEvents() {}: wird vor der Verarbeitung eingehender Events aufgerufen
function eventsProcessed() {}: wird nach der Verarbeitung eingehender Events aufgerufen
function shutdown() {}: wird beim Beenden des Scripts aufgerufen
- Für jedes Skript können eigene Felder definiert werden
- z.B.
<field name="NAME" type="SFInt32/..." accessType="inputOnly/..."/>
- Für jedes outputOnly-Feld wird eine entsprechend benannte Variable zur Ausgabe bereitgestellt
- Für jedes inputOnly-Feld kann eine
function NAME( value, timestamp ) {} definiert werden
- Für jedes inputOutput-Feld wird eine les- und schreibbare Variable NAME bereitgestellt
- Für jedes initializeOnly-Feld wird eine lesbare Variable NAME bereitgestellt
Scripting: JavaScript
Beispiel für Scripting mit JavaScript
<Script DEF="myAdd" mustEvaluate="true" directOutput="false">
<field name="inA" type="SFInt32" accessType="inputOnly"/>
<field name="inB" type="SFInt32" accessType="inputOnly"/>
<field name="outResult" type="SFInt32" accessType="outputOnly"/>
<![CDATA[
ecmascript:
var a, b;
function initialize() {
a = 0; b = 0;
}
function inA( value, timestamp ) { a = value; }
function inB( value, timestamp ) { b = value; }
function eventsProcessed() {
outResult = a + b;
}
]]></Script>
Download als X3D-Datei
Scripting: JavaScript
Weiterführende Informationen zum Scripting mit JavaScript
Scripting: Java
Java als Scriptsprache
- Java kann als Scriptsprache verwendet werden
- Nicht inline, nur über Verweis auf Klassendatei (.class) über url-Feld
- Deklaration der Felder wie bei JavaScript-Skriptknoten
- Zugriff auf die Felder durch explizite API: SAI (Beispiel folgt)
- Entsprechend wird ein Java-Interface benötigt, bei InstantReality
instantreality.jar (meist im Bin-Verzeichnis der Installation)
- Interface angelehnt an den Vorgänger für VRML
- Packages
vrml, vrml.field, vrml.node
Scripting: Java
Das Java Interface
- Aufbau ähnlich dem JavaScript Interface
public void initialize() {}: wird beim Initialisieren des Scripts aufgerufen
public void prepareEvents() {}: wird vor der Verarbeitung eingehender Events aufgerufen
public void eventsProcessed() {}: wird nach der Verarbeitung eingehender Events aufgerufen
public void shutdown() {}: wird beim Beenden des Scripts aufgerufen
- Zusätzlich noch
public void processEvent(Event e) {}: wird jedesmal aufgerufen, wenn ein Feldwert geändert wird
Scripting: Java
Beispiel für Scripting mit Java, analog zum JavaScript Beispiel
public class MyAddNode extends vrml.node.Script {
int a, b;
SFInt32 output;
public void initialize() {
a = 0; b = 0;
output = (SFInt32) getEventOut("outResult");
}
public void processEvent(vrml.Event event)
{
if( event.getName().equals("inA") ) {
a = ((ConstSFInt32) event.getValue()).getValue();
}
if( event.getName().equals("inB") ) {
b = ((ConstSFInt32) event.getValue()).getValue();
}
}
public void eventsProcessed() {
output.setValue( a + b );
}
}
Scripting: Java
Was gilt es zu beachten? Typische Probleme mit Java als Scriptsprache
- Jeder Java-Skriptknoten läuft in eigener Sandbox mit eigenem Classloader (zumindest in InstantReality)
- Problematisch bei der Verwendung von JNI
- Achtung bei der Verwendung von Singletons und anderen statischen Variablen! Zwischen den Knoten kann damit keine Kommunikation abgewickelt werden.
- Da Java-Skriptknoten in der Sandbox laufen, müssen Ausnahmen, wie für den Zugriff auf das Dateisystem oder das Öffnen von Ports, explizit in der
java_policy freigegeben werden.
- Die Aufrufe der Knoten-Interfacefunktionen (
initialize, shutdown, processEvent, ...) erfolgen im Thread des jeweiligen X3D Browsers
- Direkte Zugriffe auf Knoten/Felder und das Browser-Objekt sind nur in diesem Thread erlaubt!
- Zugriffe aus anderen Java-Threads (die möglich sind) können im besten Fall das System stark ausbremsen, im schlimmsten Fall jedoch zu Speicherfehlern und Ausnahmen führen.
- Dies gilt insbesondere für
System.out/err Aufrufe, die in die Console im Browser umgeleitet werden.
Scripting: Java
Weiterführende Informationen zum Scripting mit Java
Scripting: Remote
Andocken externer Prozesse
- Über das VRML External Authoring Interface (EAI) können auch externe Prozesse angedockt werden
- In der X3D Spezifikation gibt es auch das X3D Scene Access Interface (SAI), welches aber von InstantReality noch nicht unterstüzt wird
- InstantReality bietet Implementierungen des EAI für Java und .net (C#, Visual Basic, etc.)
- API ähnlich der des Skriptknotens, aber nun wird kein *neuer* Knoten implementiert!
- Erster wesentlicher Schritt ist die Herstellung der Verbindung zum X3D Browser
java.net.InetAddress address = java.net.InetAddress.getByName("mypc");
vrml.eai.Browser browser = vrml.eai.BrowserFactory.getBrowser(address, 4848);
vrml.eai.Node scriptNode = browser.getNode("myAdd");
vrml.eai.field.EventOutSFInt32 result =
(vrml.eai.field.EventOutSFInt32)scriptNode.getEventOut("outResult");
Scripting: Möglichkeiten
Weitere Möglichkeiten des Scriptings über Java/JavaScript
- Bislang nur Zugriff auf den Szenengraph gesehen
- Es können aber auch neue Routen über
Browser.addRoute() angelegt werden
- Erstellen von neuen Teilgraphen über
Browser.createVrmlFromString()
- Aber nur in alternativer VRML-Syntax möglich
- Kann aber über Kommandozeilen-Tool
aopt oder online mittels Konverter aus X3D Dateien gewonnen werden
Scripting: Weitere Möglichkeiten
Alternativen
- Distributed Interactive Simulation (DIS)
- IEEE Standard für physikalische verteilte Simulationen
- wird z.B. in militärischen Simulationen verwendet
- von InstantReality derzeit keine volle Unterstützung
- Remote JavaScript/AJAX
- Unter Verwendung von XMLHttpRequest in einem JavaScript-Skriptknoten können JavaScript Fragmente im AJAX-Stil von einem externen Server geladen werden.
- Szenengraph ganz/teilweise überschreiben
- Bei einer Benutzerinterkation könnte der Szenengraph auch teilweise/vollständig ersetzt werden
- Dabei wird der neue Graph dann den alten ersetzen
- Die Veränderungen können dann extern mit beliebiger Sprache erstellt werden
- Alternative für komplexe Modelländerungen bzw. die Anbindung externer Software
Zusammenfassung
Zusammenfassung
Inhalte dieser Veranstaltung
- Umsetzung von funktionalen Elementen in der Simulation
- Funktionale Modellierung in X3D
- Einführung in die wesentlichen Techniken der funktionalen Modellierung
- Felder
- Routen
- Scripting in X3D
- Skriptknoten in JavaScript und Java
- Externe Anbindung
Ausblick
Termin 06 - Interaktion
- Basisinteraktionen
- Navigation
- Selektion
- Manipulation
- Evaluation von Interaktionstechniken
- Anbindung von Geräten
- InstantIO: Integration von Geräten in den Szenengraphen mit X3D