ARwin

Aus toolbox_interaktion
Wechseln zu: Navigation, Suche

Arwin logo.png

 

ARwin in Aktion
Die vorliegende Dokumentation beschäftigt sich mit dem im Wintersemester 2006/2007 realisierten Anwendung ARwin (Augmented Reality Window). Die Idee hierzu basierte darauf, ein Fenster zur virtuellen Welt schaffen zu wollen. Das Fenster stellt dabei ein Notebook dar, das mit einer Kamera bestückt ist. Eine auf dem Notebook laufende Bildverarbeitungsanwendung erkennt die Lage vordefinierter Marker, die sich im Bild der Kamera befinden. Hierdurch ist es möglich, eine virtuelle Welt korrekt ausgerichtet darzustellen bzw. die reale Perspektive nachzubilden. Diese virtuelle Welt ist eine exakte Nachbildung der realen Welt und entstand durch detailgetreue Nachmodellierung des Präsentationsraumes.
 

Einleitung

Das Projektteam setzte sich aus sechs Mitglieder zusammen, wovon drei sich mit der dreidimensionalen Nachmodellierung des Präsentationsraumes befassten und zwei sich mit der generellen Funktionalität des Systems bzw. mit der Bildverarbeitung. Ein weiteres Teammitglied war für die Leitung des Projektes (und das verflucht mühsame Zusammenfügen dieser Dokumentation) zuständig.

Nach Ende einer Brainstorming-Phase aus der sich die letztendliche Anwendungsidee herauskristallisierte, standen zwei Varianten bezüglich der Umsetzung des Systems zur Diskussion.
Variante eins sah vor, das reale Videobild mit virtuellen Objekten zu erweitern – die klassische Art einer Augmented-Reality-Anwendung. Dabei sollten die Lichtsituation des realen Raumes ermittelt werden, um sie dann auf das virtuelle Objekt übertragen zu können, um eine bessere Illusion zu erzielen. Eine mögliche Anwendung wäre etwa eine Möbelvisualisierung oder ein elektronischer Stadtführer, der zusätzliche Informationen zu einem Gebäude liefern könnte oder ein 3D-Modell von zukünftigen Gebäuden einblenden könnte.
Die zweite Variante bestand darin, dass das reale Videobild lediglich zur Analyse der Benutzer-Position herangezogen werden würde, es also nicht auf Notebook ausgegeben werden würde. Der umgebende Raum müsste dazu virtuell nachgebaut werden. Eine mögliche Anwendung wäre eine virtuelle Darstellung realer Objekte, die im Idealfall nicht auf dem ersten Blick als solche erkannt werden. Erst wenn sich die virtuellen Objekte im Vergleich zu den realen verändern, fällt es dem Benutzer auf. Beispielsweise könnte sich ein Apfel, der auf einem Tisch liegt, in der virtuellen Welt im Zeitraffer altern. Eine andere Möglichkeit, wäre die Steuerung der Sichtbarkeit der Außenhülle des Objektes. Der Hintergrundgedanke dabei wäre die Möglichkeit, hinter die Hülle zu sehen, um zu erkennen, wie etwas funktioniert.

Die Projektgruppe entschied sich nach längeren Überlegungen der Überschneidung und dem parallelen Arbeit an beiden Varianten dafür, Variante 2 zu entwickeln.

Systemschema gemäß Anforderungsdefinition

Nachbildung des Raums

Anforderungen

Bevor mit den Modellierungsarbeiten an der Fensterfront bzw. der Raumnachbildung begonnen werden kann, ist festzustellen, welche Eigenschaften die virtuelle Umgebung später aufweisen soll. Da bei der Anwendung sowohl Raum, als auch 3D-Modell zugegen sein müssen, ist es notwendig, die Anforderungen an Vorlage und Nachbildung klar zu beschreiben und zu definieren.

Anforderungen an den Raum
Wichtig ist es, sowohl im Rahmen der Entwicklungsphase, als auch für die Projektpräsentation, uneingeschränkten Zugang zum Raum zu haben. Die Anforderung in Bezug auf die Verfügbarkeit mag trivial erscheinen, doch ist bei der Raumfindung zu beachten, dass die Raumsuche innerhalb der FH Nürnberg erfolgt. Somit gilt es, sich mit den organisatorischen Verfahrensweisen und Anlaufstellen vertraut zu machen. So ist es in Einzelfällen nicht immer möglich, im Vorfeld verbindliche Absprachen zu machen.
Neben der Forderung nach Verfügbarkeit muss der Raum bestimmte Kriterien in Bezug auf Abmessung, Größe, Lichtsituation und Detailgrad erfüllen. So ist ein rechteckiger bzw. quadratischer Grundriss von Vorteil, da diese Formen die Modellierungsarbeiten erleichtern. Auch die Interaktion mit dem System und die Einschränkungen für die Platzierung des Objektträgers in Form des Tisches tragen maßgeblich zur Entscheidungsfindung bei. Ein abschüssiger Raum mit fest montierten Stuhlreihen, wie es für Vorlesungssäle einer Hochschule nicht untypisch ist, ist denkbar ungeeignet.
Weiterhin müssen die Lichtverhältnisse des Raumes konstant sein und mittels einer 3D Engine mit virtuellen Lichtquellen im Echtzeit-Betrieb nachgebildet werden können.
Auch soll der Detailgrad des Referenz-Raumes in einem verträglichen Rahmen bleiben. Fest montierte Stuhlreihen, Präsentationsequipment, wie ein an der Decke angebrachter Beamer mit zugehöriger Leinwand, oder die Computeranlagen innerhalb der Informatik-Räume würden innerhalb des Zeitrahmens nicht fertiggestellt werden können.
Einerseits wären zu umfangreiche Modelling-Arbeiten notwendig, um jedes Detail realistisch nachzubilden, andererseits würde ein komplexer Hintergrund unter Umständen zu viel Aufmerksamkeit auf Seiten des Nutzers auf sich ziehen und somit von der eigentlichen Anwendung ablenken.

Anforderungen an die 3D-Nachbildung
Um eine für den Nutzer nachvollziehbare Grundlage für die Interaktion mit "Arwin" zu schaffen, ist es notwendig, ein möglichst realistisches Umfeld für die Anwendung zu erstellen. Im Rahmen der Fähigkeiten, die eine 3D-Echtzeit-Engine bietet, gilt es also, dem Aussehen des Raumes bestmöglich nahe zu kommen. So müssen alle Längenmaße des virtuellen Modells mit dem realen Vorbild übereinstimmen. Weiterhin ist es wichtig, dass alle sichtbaren Flächen der einzelnen 3D- Körper das gleiche Verhalten in Bezug auf Transparenz, Schattenverlauf, Spiegelung und Oberflächenanmutung aufweisen.
Neben dem realistischen Aussehen muss das Raummodell echtzeitfähig sein. So gilt es, schon bei der Modellierungsphase darauf zu achten, möglichst wenige Polygone zur Erstellung der Raumobjekte zu verwenden, da mit jedem zusätzlichen Vertex das System zunehmend beansprucht wird. Auch Größe und Farbtiefe der verwendeten Texturen wirkt sich auf die Lauffähigkeit der Anwendung aus. Weiterhin spielen Oberflächeneffekte wie Transparenzen und Spiegelungen eine große Rolle, was die Inanspruchnahme von Systemressourcen betrifft.
Da man bei der Entwicklung der 3D Umgebung auf Tools wie Cinema4D, 3ds Max und Virtools angewiesen ist, muss darauf geachtet werden, welche Anforderungen diese Instrumente an das System stellen. Je nach Plattforum weist vor allem Virtools ein anderes Verhalten auf.
Um sicherzustellen, dass die Anwendung auf einer Vielzahl von unterschiedlichen Rechnern lauffähig ist, dürfen nur diejenigen Arbeitsmittel eingesetzt werden, die von den meisten Komponentenherstellern unterstützt werden. So laufen beispielsweise Virtools-eigene ATI Shader nur im begrenzten Umfang auf einem Computer mit Nvidia-Grafikkarte.

Raumfindung

der Präsentationsraum A525
Ideale Vorraussetzungen für die 3D-Modellierung und im Hinblick auf Präsentationstauglichkeit boten die Räumlichkeiten im Erdgeschoss des G-Baus. Da man sie abdunkeln kann, lässt sich also eine Lichtsituation einstellen, die jederzeit wiederherstellbar ist. Sie sind nicht schwer nachzubauen, und die Texturenvielfalt hält sich auch in Grenzen, da die Wände weiß sind. Sie wären auch deswegen ideal gewesen, da sie die meiste Zeit während des Semesters nicht belegt sind und man jederzeit Abmessungen, Texturfotos oder auch die Anwendung unter realen Bedingungen hätte testen können.

Da die Verwaltung und somit auch die Vermietung der Räumlichkeiten im Gestaltungsbau nicht über die Zentrale Raumvergabe der FH erfolgt, wäre es zwar möglich gewesen, einen der Räume zu reservieren, doch haben Professoren und Studenten aus dem FB Gestaltung stets Vorrang und somit die Möglichkeit, auch kurzfristig auf die Präsentationsräume zuzugreifen. Nicht nur angesichts der gegen Semesterende stattfindenden Diplomausstellung des FB Gestaltung, wäre eine Reservierung also sehr unsicher gewesen und es musste ein anderer Raum gesucht werden.
Auch die Suche im BWL-Bau brachte keinen Erfolg. Schließlich wurde direkt in der Raumverwaltung bei Frau Schilbach (Referat 3.2, Kesslerplatz 12) nachgefragt, die freundlich weiterhalf, aber für den Prüfungszeitraum nur den A525 als verlässlich buchbar anbieten konnte. Dieser Raum besteht zwar aus einer Vielzahl verschiedener Texturen und sehr aufwendigen Formen, aber aufgrund fehlender Alternativen blieb nichts anderes übrig, als diesen Raum zu buchen.

Modelling-Vorarbeiten

Vermessen des Raums

Akribisch wurde der Präsentationsraum mit Hilfe von Maßbändern ausgemessen. Es wurden Fotos des Raumes aufgenommen und Skizzen angefertigt, die mit den Messergebnis versehen wurden. Um Fehlerquellen aufzuspüren wurden anhand der Skizzen technische Zeichnungen mit dem CAD-Programm DesignCAD Pro 2000 erstellt.

Skizze der Decke
Die Decke als CAD-Zeichnung. Die schraffierten Vierecke haben eine Strukturierung, die weißen Vierecke sind real nur grün, die Vierecke mit der Raute darauf sind integrierte Lautsprecher, die Vierecke mit der Kreuzschraffur sind die Deckenlampen (bestehend aus Metallstreben; dahinter sind Neonleuchten befestigt), die kleinen Vierecke über den Längs- und Querstreben sind kleine Spots, die Längs- und Querstreben bestehen aus gebürsteten Metall.

Texturen erstellen

Bei den Texturarbeiten sind generell folgende Dinge zu beachten.

Linsen-Verzerrungen
Verzerrungen im Bild, die beim Fotografieren durch die Krümmung der Linsen und andere Einflussfaktoren entstehen, müssen korrigiert werden.

Schattenverläufe
Schatten-, Reflektions- und Lichteffekte werden erst zur Laufzeit der 3D-Szene eingebunden bzw. simuliert. Aus diesem Grund müssen alle Schattenverläufe mittels Photoshop aus den Fotografien entfernt werden, sodass alle Bilder über eine gleichmäßige Ausleuchtung verfügen.

Bild-Abmessungen
Das Verhältnis der Bildgröße zu der zugehörigen Objektfläche muss übereinstimmen. Beispiel: Ist eine Polygonfläche 120 mm breit und 40 mm hoch, so sollten auch die Seitenlängen des Bildes im Verhältnis 3:1 stehen.

Farben und Farbverläufe
Texturen, die nur aus Farbverläufen oder einer Farbe bestehen sollten ebenfalls in Photoshop erstellt und als Bild abgespeichert werden. Dies ist sinnvoll, da Virtools Textureffekte (FallOff, Color) anders interpretiert als 3ds Max.

Sichern der Texturen
Die Texturen werden als JPG gespeichert. Bei den Dateinamen ist hier ebenfalls darauf zu achten, dass kurze Zeichenketten ohne Sonderzeichen verwendet werden.

Auflösung
In Bezug auf die Auflösung der Grafiken gibt es keine allgemeingültige Vorgehensweise. So sollte die Bildgröße so gewählt werden, dass ein möglichst gutes optisches Ergebnis bei der 3D-Anwendung erzielt wird, ohne dabei zu viel Systemressourcen in Anspruch nehmen zu müssen. Für einfarbige Oberflächen genügt eine geringe Auflösung, während bei detailreichen Flächen größere Bilder sinnvoll sind. Da die Sichtbarkeit der Oberflächendetails proportional zum Betrachtungsabstand variiert, ist zu überlegen, ob das sogenannte Mip-Mapping angewendet werden soll. Dabei werden für verschiedene Distanzen zum Objekt unterschiedlich auflösende Bilder hinterlegt und abhängig von Betrachtungsabstand ausgetauscht.

Verzeichnisstruktur
Die Textur-Bilder werden in Verzeichnisse gelegt, an denen nachfolgend weder Pfad noch Namen geändert werden. Diese Verzeichnisse sollten auf jedem Rechner, auf dem gearbeitet wird, identisch sein, sodass 3ds Max und Virtools unabhängig von der Plattform am gleichen Ort auf die Texturen zugreifen können. 3ds Max speichert nämlich nur die Pfade zu den Bildern ab, nicht aber die Bilder selbst. Für Testzwecke ist es im Rahmen der Entwcklung sinnvoll, auf jeder Plattform die gleiche Arbeitsumgebung einzurichten.

Im Projekt verwendete Pfade:

  • C:\projekt_tb_ws06\raum3d\texturen\decke_boden\
  • C:\projekt_tb_ws06\raum3d\texturen\waende\
  • C:\projekt_tb_ws06\raum3dl\texturen\fenster\

Virtools hingegen sichert Kopien der Bilder innerhalb des save-Files, sobald die 3D-Szene abgespeichert wird.

Da die Schattenverläufe in der 3D-Engine erzeugt werden sollten mussten diese in den abfotografierten Texturen entfernt werden. Es bestand die Vorüberlegung mit Hilfe von Folien und Licht, oder sogar mittels Lichtwannen die Verläufe zu reduzieren oder ganz zu beseitigen. Aufgrund von Schwierigkeiten bei der Raumreservierung wurde diese Konzept allerdings verworfen, zumal mittels Photoshop doch einiges manipulierbar ist. Deswegen wurden die Texturen vergleichsweise unspektakulär fotografiert.
Da tagsüber fotografiert wurde und der Himmel bewölkt aber hell war, kamen annähernd weiche Verläufe zustande, die gut bearbeitet werden konnten.

Während das Abfotografieren für Decke, Wandelemente und Boden problemlos anwendbar ist, ergeben sich bei der Fensterfront Probleme. Ein Abfotografieren ist aufgrund der spiegelnden Oberflächen von Fensterglas und Stahlrahmen und der vielen Kleinobjekte wie der Scharniere und Fenstergriffe in vielen Fällen nicht möglich. Von einzelnen Fensterfront-Elementen existieren Aufnahmen, doch müssen diese nachbearbeitet werden. So ist beispielsweise die Textur der Heizkörperabdeckung neu anzufertigen.
Zwar ist die Aufnahme der Verschalung technisch einwandfrei, doch in Virtools verschmieren die Oberflächen mit zunehmendem Betrachtungsabstand. Zum Einen liegt das am MipMap-Level, zum Anderen an dem verhältnismäßig niedrigen Kontrast des Bildes. Die Kontrastprobleme sind darauf zurückzuführen, dass sich die Tiefenebenen von Aussparungen und Schalungsblech nicht deutlich genug voneinander abgrenzen.
Aus diesem Grund sind – mit Ausnahme der Rolläden – alle Texturen der Fensterseite per Hand mit Photoshop zu erstellen gewesen. Unter Zuhilfenahme der bei den Messarbeiten aufgenommenen Fotos wurden alle notwendigen Texturen angefertigt.

Vergleich zwischen Fotografie und Photoshop-Anfertigung
Arwin 3d texturfoto1.jpg Arwin 3d texturcustom1.jpg
Arwin 3d texturfoto2.jpg Arwin 3d texturcustom2.jpg
Photoshop Arbeiten
manuell entzerrtes Foto
Die Bilddateien durften nicht zu groß sein und wurden auf eine Auflösung von 72 dpi reduziert. Die Seitenverhältnisse mussten zu den jeweiligen Objekten passen und die Farbtiefe 16 Bit pro Kanal umgeschaltet.

Außerdem wurden kleine Verzerrungen beseitigt. Dazu wurden Hilfslinien gesetzt, das ganze Bild markiert und über den Menupunkt [Bearbeiten] → [Transformieren] → [Verzerren] transformiert. Mit dem Auswahlpfeil werden nun die Eckpunkte angefasst und in die gewünschte Position gebracht bis schließlich alle im Bild verlaufenden Linien gerade gerückt wurden.
Zum Schluss wurden noch kleine Farbanpassungen mit Hilfe von Farbbalanceebenen oder Gradationsebenen gemacht. Schließlich wurden die Bilder als JPG-Dateien abgespeichert.

Verläufe entfernen

Um die Verläufe zu entfernen wurde das Pipetten-Werkzeug benutzt. Hiermit wurden vier feste Punkte gesetzt (Alt + Shift + linke Maustaste). Das Informationsfenster zeigt an, welche Farbwerte der aktuelle Punkt hat und wie er sich aus den einzelnen Farbkanälen zusammensetzt, d.h., aus wie viel Prozent Rot, wie viel Prozent Grün und wie viel Prozent Blau er besteht. Bei einer Änderung der Farbwerte bleiben die Werte der gesetzten Punkte auf der linken Seite des Informationsfensters stehen, während neue Werte, die die Punkte nach der Farbänderung annehmen würden, zum Vergleich rechts stehen.
Nun werden Gradationsebenen im Ebenen-Manager angelegt. In diesen Gradationsebenen gibt es eine Kurve, mit der Helligkeit und Kontraste geregelt werden können. So können alle 3 Farbkanäle geregelt oder die einzelnen Kanäle separat verändert werden.

Entfernen des Schattenverlaufs in Photoshop
Um die Punkte 2, 3 und 4 an die Farbwerte des ersten Punktes anzupassen, wurde bei jedem Punkt die Gradationskurve entsprechend abgeändert. Dabei legen sich allerdings die veränderten Werte über das gesamte Bild und färben somit auch den ersten Referenzpunkt ein. Um dies rückgängig zu machen wird die angepasste Gradationsebene ausmaskiert. Dies gelingt, indem man die aktivierte Ebene schwarz ausfüllt. Hierdurch verschwindet erst einmal die Farbänderung wieder von der Oberfläche. Um nun den Bereich des Bildes einzufärben, den man verändert haben möchte, wählt man das Pinselwerkzeug, legt die Farbe weiß als Pinselfarbe fest und malt über den Bereich in dem die ausmaskierte Gradationsebene sichtbar sein soll. Um leichte Übergänge zu vermeiden, sollte man nicht mit der vollen Deckkraft des Pinsels arbeiten, sondern lieber mehrmals über die gleiche Stelle malen.

Mit dem Anwenden dieser Vorgehensweise mit allen Pipettenpunkte/Gradationsebenen verschwinden die Verläufe – je nachdem wie genau vorgegangen wird.
Da man nicht mehr als 4 feste Pipettenpunkte anlegen kann, muss man diese nach erfolgreicher Arbeit verschieben. Hierzu wird das Pipettenwerkzeug aktiviert während die Shift-Taste gedrückt gehalten wird. Auf diese Weise arbeitet man sich Stück für Stück nach oben und nach unten bis der Schattenverlauf so gut wie möglich reduziert ist.
Sind diese Arbeitsschritte erledigt, wird das komplette Bild mit Hilfe eine Farbbalanceebene an die Farbgebung des Raumes angepasst. Hierzu half das HDR-Panoramabild des Präsentationsraumes. Zum Abschluss wurden alle Ebenen auf den Hintergrund reduziert und das Bild als JPG abgespeichern.


Kachelbare Texturen
Erstellung einer kachelbaren Textur des Teppichs
Bei 3D-Programmen gibt es die Funktion "kachelbare Texturen". Das Anwenden dieser Funktionalität war vor allem beim Teppich sehr sinnvoll, da es die Echtzeitfunktionalität des Systems enorm in die Knie gezwungen hätte, wenn ein Bild vom kompletten Teppich hätte verwendet werden müssen. Selbst wenn das Bild von der Auflösung noch so klein und die JPG-Komprimierung noch so hoch gewesen wäre, hätte die Größe des Bildes einen ziemlich großen Teil der Rechenleistung in Anspruch genommen. Dazu kommt auch noch, dass größtenteils nur der Teppich in unserer Anwendung zur Geltung kommt und immer sichtbar ist. Also sollte vor allem dieser nicht unter mangelnder Auflösung leiden.

In 3D-Modellierungsprogrammen besteht die Möglichkeit, Texturen zu kacheln und diese damit nahtlos aneinander zu fügen. Hierzu darf in den Texturen kein Verlauf existieren. Der Übergang muss fließend sein und es dürfen keine Unregelmäßigkeiten der Muster in den Texturen zu sehen sein, da diese dann durch die Unzahl aneinander gereihter Vierecke sofort ins Auge springen würden.
Also wurde der Teppich senkrecht von oben aus kurzer Distanz fotografiert. In Photoshop wurden Hilfslinien um einen der im Teppich auftretenden Musterblöcke mit 4 kleinen rosa Quadraten gesetzt. Danach wurde mit dem Auswahlwerkzeug ein ca. 2 cm größerer Bereich ausgewählt und dieser nach rechts versetzt, sodass die rosa Quadrate übereinander lagen. Diese Prozedur wurde noch für nach oben und oben links wiederholt. Damit ergab sich ein 9x9 Felder großer Bereich. Die Ränder wurden dann mit dem Stempel oder dem Radierer so retuschiert, dass kein Übergang mehr sichtbar war. Die vier Ebenen wurden anschließend auf den Hintergrund reduziert. Die Hintergrundebene wurde sodann mehrmals dupliziert und versetzt bis ein einigermaßen großes Rechteck entstand bzw. die kachelbare Textur von der Größe her ausreichend war.
Abschließend wurde die Textur noch an das HDR-Panormamabild angepasst und als JPG abgespeichert.

3D-Modelling

Vor Beginn der 3D-Modellierung wurde überlegt, mit welchen Programmen im Verlauf des Projekts gearbeitet werden sollte. Dabei wurde entschieden, Cinema4D für die Modellierungsarbeiten einzusetzen, da Erfahrungen mit diesem Programm bereits vorhanden waren und zudem die 3D-Modellierung in anderen Programmen als zu schwierig empfunden wurde. 3D Studio Max wurde deswegen ausgewählt, da dieses Programm mit verschiedenen 3D-Engines gut zusammenarbeiten kann und es sehr gut die verschiedenen Texturen aufnimmt. Die 3D-Engine stand zu Beginn des Projekt noch nicht fest, erst im Lauf des Projekts entschied man sich für Virtools als 3D-Engine.

Cinema4D

Über Cinema4D
Arwin 3d cinema4d.jpg

Cinema4D ist ein 3D-Modellierungs- und Animationstool. Es ermöglicht mit seiner übersichtlichen Oberfläche und den erwartungskonformen Verhaltensweisen einen leichten Einstieg in das Programm. Für jeden Arbeitsschritt verfügt Cinema4D über einen eigenen Programm-Modus. Über vordefinierte Standardlayouts kann man zwischen der Modelling-, der Programmier- und der Animationsebene wechseln.
Die Menüführung erfolgt entweder über die Kopfleiste des Programms oder kontextbezogen und über einen Druck auf die rechte Maustaste. Somit stehen dem Anwender nur die Funktionen zur Verfügung, die in dem jeweiligen Moment möglich sind und benötigt werden. Weiterhin ermöglicht das Programm die Anpassung der Oberfläche durch den Benutzer. Jeder Anwender kann die Positionen und die Anordnung der Fenster speichern und bei der nächsten Sitzung wieder aufrufen. Dabei können mehrere Nutzerprofile gesichert werden.
Die im Programmkopf angebrachte Menüleiste bietet unter anderem Möglichkeiten zur Objekt-Modellierung, zum Rendering und zur Animation. Der Wechsel zwischen den verschiedenen Objektebenen erfolgt über die linke Menüleiste. Je nach Auswahl lassen sich Objekte auf globaler, Punkt-, Kanten- oder Polygonebene bearbeiten. Auf der rechten Seite befindet sich ein Objektbrowser, der alle Modelle der Szene beinhaltet. Über diesen Browser können Objekte mit Tags (Eigenschaften), Materialien und programmierten Verhaltensweisen versehen werden.
Auch die Schachtelung und Zusammenfassung in Nullobjekten erfolgt über dieses Menü. Unterhalb des Objektbrowsers befindet sich ein Kontextmenü, über das Änderungen am ausgewählten Material, der Animation, der Lichtquellen oder der 3D Körper vorgenommen werden können. Der untere Bereich ist je nach Betriebsmodi unterschiedlich und beinhaltet Elemente der Materialgestaltung, der Programmierung oder der Animation. Das Zahlen- Eingabefeld ermöglicht die präzise Angabe von Objektpositionen und somit ein sauberes Arbeiten.

Modellierung der Fensterfront

Für jedes Element wurde über [Objekte] → [Polygon-Objekt] ein Polygonobjekt erzeugt.
Mit dem "Polygon erzeugen"-Werkzeug wurde in der Vorderansicht per Hand ein Polygon mit vier Eckpunkten aufgezogen und über das Zahlen-Eingabefeld von Cinema4D anhand der CAD-Zeichnungen auf Maß gebracht. Durch diesen Arbeitsschritt entstand ein zweidimensionales Rechteck, an dem nun je nach Objekt weitere Arbeiten durchgeführt wurden.
An den Fenstern waren Aussparungen für das Fensterglas zu erzeugen. Hierzu wurde das gesamte Polygon ausgewählt und über das Kontextmenü wurde das "Innen extrudieren"-Werkzeug selektiert. "Innen extrudieren" fügt dem Polygon weitere Objektpunkte hinzu. Dabei wird automatisch die Fläche in kleinere Polygone unterteilt, wobei der Offset, also der Abstand der neuen Punkte von den Polygonkanten, einzustellen ist.

"Innen Extrudieren"

Anschließend wurde die neu entstandene Polygonfläche entfernt, sodass man einen zweidimensionalen Rahmen erhält. Extrudiert man nun das Objekt, so entsteht ein dreidimensionaler Körper.

"Extrudieren"

Mit Hilfe des "Messer"-Werkzeuges wurden Polygonflächen geteilt und Detailarbeiten durchgeführt. Über das "Bevel"-Werkzeug lassen sich ohne großen Aufwand Fasen und Abschrägungen an Objektkanten erstellen.

Analog zum Fensterrahmen wurde mit jedem Element verfahren, bis ein komplettes Fenster- Modul, bestehend aus Rahmen, Zwischenrahmen, Fensterscheiben, Fensterbrett, Heizkörperabdeckungen, Heizkörper, Träger, Scharnieren, Steckdosen, Fenstergriffen & Hebeln vorlag.
Das Fenster-Modul wurde daraufhin viermal dupliziert und an die entsprechenden Positionen verschoben. Da sich die ersten drei Module nur unwesentlich voneinander unterscheiden, mussten an ihnen kaum Anpassungen vorgenommen werden. Der vierte Fensterabschnitt wies jedoch eine Glastür auf, die zum Außenbalkon führt. Auf Basis des vierten Moduls wurde der Heizkörper entsprechend der technischen Zeichnung verkürzt, das Fenster horizontal gespiegelt und der horizontal unterteilte Rahmen nach unten hin erweitert.
Nachfolgend wurden ein Polygon für die Rollläden und die Schiene oberhalb der Fenstersegmente modelliert und an die richtige Position gesetzt. Metallleisten bilden den Übergang zu den Raumwänden und den Abschluss der Arbeiten an der Fensterfront.

Fenstermodul
Modellierung der Decke
Die Decke, wie sie letztendlich in die Anwendung eingebunden wurde
Für die Modellierung der Decke wurde vor allem mit dem Würfel-Grundobjekt gearbeitet. Hierbei wird ein Würfel mit den Maßen 200 x 200 x 200 cm auf den Nullpunkt des Arbeitsraumes gesetzt. Bei den Objekteigenschaften wurden sodann für die x-, y- und z-Größe die Werte 110, 10, 110 eingegeben. Anschließend wurde das Würfelobjekt in ein Polygonobjekt konvertiert.

Nun musste darauf geachtet werden, dass die Normalen der Deckenplatten richtig ausgerichtet sind. Jedes Polygon besitzt ein eigenes Koordinatensystem. x-, y- und z-Achse treffen sich im Zentrum des Polygons. Die Normalen können entweder nach außen (rot) oder nach innen (blau) gerichtet sein. Dadurch ist festgelegt, dass die später aufgesetzten Texturen außen auf oder innerhalb des Polygons platziert werden. Da die Texturen außen angebracht werden sollen, musste die Normalenrichtung über [Funktion] → [Normalen umdrehen] umgekehrt werden. Danach wurde die Rückseite der Deckenplatte gelöscht, was die Polygonanzahl um zwei Polygone verringerte. Nun wurde das Deckenplattenobjekt 51 mal dupliziert und jedes Objekt an die richtige Position innerhalb der Decke gesetzt. Die Längs- und Querbalken wurden auf gleiche Weise angefertigt.
Bei den Lautsprechern wurden die ganzen kleinen Kapseln nicht nachmodelliert, da es ausreicht, diese mittels Texturierung zu visualisieren. Außerdem ersparte man sich durch diese Verfahrensweise eine große Anzahl Polygone.
Die Deckenplatten, die Neonröhren enthalten, wurden nachgebildet, indem eines der oben erstellten Deckenplattenobjekte dupliziert und umgedreht wurde, sodass man eine Einsicht in das Objekt erhielt. Schließlich wurde die Deckenplatte noch mit einem Gitter aus 11 x 11 Metallleisten (á 10 x 2 x 10 cm) ausgefüllt. Um die Anzahl Polygone gering zu halten wurde auf eine detailreichere Modellierung verzichtet. Aus demselben Grund bestanden die kleinen Lichtstrahler lediglich aus jeweils einem Quader, der zudem an der nicht sichtbaren Seite von einem unnötigen Polygonen befreit wurde.
Zum Schluss wurden alle Teile in einem Null-Objekt zusammengefasst.

Modellierung der Wandseiten

Begonnen wurde mit dem einfachen Grundobjekt Würfel. Um das Objekt weiter im Punkt- oder im Polygon-Modus bearbeiten zu können, musste es zunächst konvertiert werden indem das Objekt markiert und in der senkrechten Befehlspalette der Befehl "Grundobjekt konvertieren" aufgerufen wurde. Anschließend wurde in den Polygon-Modus gewechselt, wo zunächst die überflüssigen Seiten des Würfels entfernt wurden. Übrig blieb eine einfache, quadratische Ebene, die zu einer der zahlreichen Holztafeln der Holzwand werden sollte. Ein weiterer Wechsel in den Punkt-Modus ermöglichte das Verändern der einzelnen Eckpunkte bzw. deren Koordinaten. Durch den Befehl "Optimize" kann man alle überflüssigen Punkte, die durch das Löschen der anderen Würfelflächen entstanden sind, entfernen.
Nach den Vorgaben aus den CAD-Plänen wurden nun die Koordinaten angepasst, sodass dieses erste Holzwandteil genau die reale Größe besaß. Nun konnte die Position des Objekts eingegeben werden, womit man auch gleich die Position im Raum bestimmen konnte. Zuvor sollte aber der Nullpunkt des Objekt, der zunächst in der Mitte des Objekts lag auf eine Ecke des Objekts legen, da man auf diese Weise das Objekt leichter verschieben kann. Bei der Bestimmung der Position ist es enorm wichtig darauf zu achten, auch nur die Eckpunkte der Fläche ausgewählt zu haben, die man verschieben möchte. Sollte man versehentlich einen Punkt markiert haben der nicht mit verschoben werden soll, führt das dazu, dass nach dem Verschieben die Punkte zwar nur minimal von den vorgegeben Koordinaten abweichen, die Wand jedoch nicht mehr exakt zusammen passt. Korrekturen sind in diesem Fall sehr aufwendig, da sich oft durch das Verschieben des einen Punktes auch die Koordinaten von anderen Punkten ändern. Die Kontrolle aller Punkte auf exakte Koordinaten kann wahrlich als Sissifußarbeit bezeichnet werden.

Extrudieren der Wandfuge
Nun fehlen noch die Fugen zwischen den einzelnen Wandtafeln und die Leisten oberhalb und unterhalt der Tafel. Unter Berücksichtigung der Größe dieser einzelnen Teile ergab sich dann eine neue Tafelgröße. Mittels des Befehls "Messer" wurden an der Tafel weitere Kanten angebracht, die mit dem Befehl "Extrudieren" (mit einem der Fugentiefe entsprechenden Offset-Wert von 2 cm), herausgearbeitet wurden.

Was folgte, war größtenteils Copy&Paste. Jedoch verlangte es schon viel Genauigkeit, die einzelnen Wandteile exakt aneinander anschließen zu lassen. Die Hervorhebung in der Mitte der Türseiten wurde durch einen einfachen Würfel umgesetzt, dessen Rück-, Ober- und Unterseite entfernt und der wiederum mit Hilfe der Befehle "Messer" und "Extrudieren" bearbeitet wurde.
Bei genauem Betrachten der Wand fiel auf, dass bei jeder Holztafel noch ein Polygonloch vorhanden war. Dies ließ sich jedoch ohne großen Aufwand schließen. Dazu wurde der Befehl "Polygon erzeugen" eingesetzt. Hierbei mussten nur die vier Punkte dieses Polygonloches angeklickt und anschließend der Befehl "Polygonloch schließen" angewendet werden.

Etwas aufwendiger dagegen gestaltete sich die Modellierung der Tür. Auch hier wurde von einer flachen Ebene ausgegangen. Mit dem Befehl "Messer" wurden die zu vertiefenden Polygonflächen hergestellt, welche sodann wiederum mit "Extrudieren" vertieft wurden. Wobei das vorhergehende Anpassen jedes einzelnen Punktes an die richtigen Koordinaten den umfangreichere Teil bildete.
Das Problem bei der Modellierung der Tür war die Aussparung an der Stelle, in der später die Türklinkenarmatur sitzen sollte. Diese Aussparung war mitten in der Polygonfläche und dadurch entstanden weitere Polygone, deren Form und Ausrichtung nicht ganz nachzuvollziehen waren, das lag vermutlich auch an der bereits vorgestellten Funktion "Optimize", bei deren Anwendung diese Polygone entstanden sind. Auch hier mussten die Koordinaten wieder mühsam per Hand angeglichen werden.

Die voreingestellte Funktion "Optimize" sorgte für Probleme bei der Türmodellierung.
die fertige Türgriffarmatur
Der nächste Schritt war die schwarze Vertiefung zu modellieren, in der später die Türklinke angebracht sein sollte. Ausgehend von einer quadratischen Fläche, wurde hierfür zunächst die Funktion "Innen extrudieren" mit dem Wert 0,5 mm angewendet. Die Funktion "Innen extrudieren" erstellt eigenständig neue Kanten und Polygone innerhalb der Polygonfläche. Die erneute Anwendung der Funktion "Extrudieren" erzeugte die 5-cm-Vertiefung dieses Klinkenrahmens.

Bei der Modellierung des Türgriffs wurde in der Draufsicht von Cinema4D mittels "Polygon erzeugen" eine Fläche mit der Form des Türgriffs erzeugt. Mittels "Extrudieren" wurde die Höhe der Klinke erzeugt und anschließend wurde mit dem Befehl "Polygonloch schließen" die Oberseite der Klinke geschlossen.

Mit etwas Geduld und Millimeterarbeit wurden schließlich alle Teile der Wand (also die Holztafeln, die Hervorhebung in der Mitte, die Türe, der Klinkenrahmen und die Türklinke) zusammengesetzt und in einem Nullobjekt zusammengefasst.

Ähnlich wurde bei der Modellierung des Tisches vorgegangen. Ausgehend vom Grundobjekt Würfel wurden hierbei jedoch nicht alle überflüssigen Ebenen gelöscht, sondern mit Hilfe der bereits erwähnten "Messer"-Funktion die Beine des Tisches herausgearbeitet.

Arwin 3d tisch.jpg

 

Export der modellierten Raumteile

Bevor mit den Material-Arbeiten in 3ds Max begonnen werden kann, muss die Modellierung mit Cinema4D am 3D-Objekt zu 100% abgeschlossen sein. Folgende Punkte sind dabei zu beachten.

Vereinfachung der Körper durch die Wegnahme von Polygonen/Punkten
Dies gilt vor allem für Körper, die über eine hohe Anzahl von Polygonen verfügen und somit rechenintensive Arbeit vom System verlangen. Wenn es möglich ist, Objekte – wie beispielsweise eine Kugel – durch eine geringere Anzahl von Polygonen/Punkten darzustellen, ohne dass dadurch die spätere Anwendung negativ beeinflusst wird, so sollte man dies tun.

Entfernung ungenutzter und redundanter Punkte/Polygone
Ist die grundlegende Form eines 3D-Elements fertiggestellt, so muss man nun überschüssige Polygoneckpunkte und freiliegende Punkte im Raum entfernen. Dies geschieht entweder per Hand oder mittels der "Optimieren"-Funktion von Cinema4D.

Ausrichtung der Normalen aller Polygone
Polygone verfügen über eine Vorder- und eine Rückseite. Wählt man ein Polygon in Cinema4D an, so wird die Rückseite rot und die Vorderseite bläulich dargestellt. Virtools zeigt lediglich die Vorderseite der einzelnen Elemente an. Daher sollte darauf geachtet werden, dass die in der späteren Anwendung sichtbaren Seiten blau sind.
Hierzu ordnet man die Normalen der Polygonflächen mit dem "Normalen ausrichten"-Werkzeug so an, dass die in Cinema4D blau dargestellte Vorderseite zur Raummitte zeigt. Dies ist wichtig, da aufgrund der Beanspruchung von Systemressourcen nur die Vorderseiten der Polygonflächen gerendert werden. Führt man diesen Arbeitsschritt nicht durch, so werden einzelne Ebenen gar nicht oder nur fehlerhaft dargestellt.

Koordinatenkorrektur
Durch den Einsatz einiger Werkzeuge bei der Modellierung kann es vorkommen, dass Objektpunkte unbeabsichtigt verschoben werden. Daher sollte man während der gesamten Modellierungsarbeiten darauf achten, dass sich die Polygoneckpunkte stets auf den beabsichtigten Koordinaten befinden. Spätestens kurz vor dem Export müssen die Positionen der Vertices korrekt sein, sodass das Auftauchen sichtbarer Spalten im 3D-Raum ausgeschlossen werden kann.

Nun gilt es, die einzelnen Bestandteile des Objektes zusammenzufügen.

Objektmanager
Im Objektmanager von Cinema4D werden die Objekte in sinnvoller Reihenfolge geschachtelt und anschließend in einem Null-Objekt verpackt. Über das Null-Objekt wird nachfolgend die Position des gesamten Körpers bestimmt.

3D-Raum
Innerhalb des Objektes – auf der Punkt-/Polygon-/Kanten-Ebene – muss der Körper nahe am Nullpunkt liegen. Oftmals ist es ratsam, den Nullpunkt des internen Objektes auf einem der Körper- Eckpunkte zu platzieren. Auf der äußeren Objektebene werden die Elemente so positioniert, dass sie mit den anderen Raummodulen – die erst in der 3D-Engine eingebunden werden – zusammenpassen. Dadurch wird sichergestellt, dass der komplette Raum spaltenfrei ist und weitere Verschiebungs- Arbeiten in 3ds Max oder Virtools nicht vorgenommen werden müssen.

Beispiel: Die gesamte Fensterfront wird in einem Null-Objekt zusammengefasst. Das Null-Objekt wird daraufhin so positioniert, dass die x- und z-Koordinaten auf 0 stehen und die y-Koordinate der Oberkante auf 31,2 (skalierte Raumhöhe: Bild "Ausrichtung und Export" – 1) liegt. Andere Elemente wie die Wand oder der Boden werden so ausgerichtet, dass ihre Unterkanten mit der Grundebene im 3D- Raum übereinstimmen (Bild "Ausrichtung und Export" – 2).

Ausrichtung und Export

Skalierung
Da Cinema4D mit anderen Positions- und Größenwerten arbeitet als Virtools und 3ds Max, ist es wichtig, die Größe des Gesamtobjektes anzupassen. Hierfür wählt man das Objekt als solches aus und führt die Änderungen auf der Hauptebene durch – nicht aber auf der Polygon-/Punkt- Ebene. Dies hat den Vorteil, dass durch die Größenänderung des gesamten Objektes die innere Skalierung nicht verändert wird und man intern weiterhin mit den ursprünglichen Abmessungen arbeiten kann. Beispiel: außen – 10 cm, innen – 100 cm. 1/10 der Ausgangsgröße hat sich für den Export bewährt.

Entfernung aller Cinema4D-Tags
Cinema4D- Tags werden von anderen Programmen entweder gar nicht oder nur fehlerhaft erkannt. Deshalb müssen der Phong-Shader, die Texturfixierung und sämtliche Textur- Tags gelöscht werden.

Zuweisung kurzer Objektnamen ohne Sonderzeichen
Sind soweit alle Vorarbeiten abgeschlossen, so gilt es nun die Objekte so zu benennen, dass sie ohne Probleme von anderen Programmen erkannt werden können. So versieht man die Komponenten mit individuellen Namen, um spätere Überschneidungen der Bezeichnungen in Virtools und 3ds Max zu vermeiden.

Objekt-Export

Um möglichst wenige programminterne Informationen an 3ds Max zu übertragen erweist sich das VRML-1-Format als sinnvoll. Zwar verfügt Cinema4D über eine 3DS-Export-Funktion, baut dabei aber überschüssige Tags in das Export-File ein, welche von 3ds Max und Virtools fehlerhaft interpretiert werden.
VRML steht für "Virtual Reality Modeling Language" und ist eine Beschreibungsspache für 3D-Szenen. Die meisten 3D-Modellierungswerkzeuge ermöglichen den Im- und Export von VRML-Dateien, wodurch sich, wie bei unseren 3D-Arbeiten, dieses Dateiformat als ein Austauschformat von 3D-Modellen etabliert hat.
VRML-Dateien erkennt man an der Dateierweiterung ".wrl" (world), sie sind im Klartext (ASCII bzw. UTF-8) geschrieben und könnten somit an sich auch in einem einfachen Texteditor erstellt werden.

3D Studio Max

Über 3D Studio Max
Arwin 3d 3dsmax.jpg

Genau wie Cinema4D ist auch 3ds Max ein Tool zur Modellierung und Animation von 3D-Szenen. Dabei orientiert es sich stärker als Cinema4D an technischen Fachbegriffen und Darstellungsformen, die eher auf die Denk- und Arbeitsweisen von Programmierern abzielen. Im Allgemeinen bietet 3ds Max mehr Möglichkeiten als Cinema4D, doch verlangt es dafür vom Benutzer, dass dieser ein hohes Grundverständnis für das Programm mitbringt. So sind wichtige Programmteile und Werkzeuge zum Teil in verschachtelten Menüs versteckt, was die selbstständige Einarbeitung in 3ds Max sehr erschwert. Weiterhin bietet das Programm keine Symbole, welche die Funktionen der Werkzeuge veranschaulichen würden und durch die nicht immer aufschlussreichen Werkzeugbezeichnungen ist die Bedeutung einiger Tools auf den ersten Blick nicht immer erkennbar. Der Aufbau des Interfaces gleicht in vielen Punkten Cinema4D. Auch hier gibt es ein Kontextmenü, welches über die rechte Maustaste aufzurufen ist. Auffällig ist die rechte Menüleiste, die je nach Programmreiter unterschiedliche Möglichkeiten für Objekt-Modifizierungen, Anzeigeeinstellungen und Animationen bietet. Im Ausgleich zur unübersichtlichen Menüführung bietet 3ds Max einige Fähigkeiten, die dieses Programm unverzichtbar machen. Standards in Bezug auf Dateiformate und Objekteigenschaften wie Skalierung werden sehr gut umgesetzt. Auch der Datenaustausch mit anderen Programmen funktioniert im Gegensatz zu Cinema4D stets fehlerfrei.

Texturierung

Sobald die Modellierung und die Arbeiten an den Texturen abgeschlossen sind, kommt 3ds Max zum Einsatz. Sowohl bei 3ds Max, als auch bei Virtools gilt es, jeden Arbeitsschritt so sauber wie möglich durchführen, da diese Programme – wie im Vorfeld bereits beschrieben – zum Teil sehr empfindlich auf falsche Benutzereingaben reagieren. So weist 3ds Max den importierten Objekten automatisch Dummy-Materialien zu, obwohl diese laut Cinema4D gar keine Materialeigenschaften haben dürften. Diesen Umstand kann man jedoch ignorieren, da es möglich ist, überschüssige Materials in Virtools zu entfernen.
Der Import der modellierten Dateien erfolgt über [File] → [Import]. Dabei wird VRML (WRL, WRZ) als Import- Format ausgewählt, da die Standardeinstellung von 3ds Max 3DS ist. Beim Import werden alle von 3ds Max vordefinierten Eigenschaften der Datei übernommen.

Material-Maps bestimmen das Erscheinungsbild der Materialien und somit auch der Texturen. So geben sie an, in welcher Form eine Textur/ein Material auf einem Körper abgebildet wird. Dabei ist es beispielsweise möglich, Bilder auf einer Oberfläche mehrmals zu kacheln oder die Textur dynamisch nach der Kameraperspektive oder dem Objektwinkel zur Normalen der 3D-Szene auszurichten. In den vorliegenden Fällen wurde zumeist das planare Mapping gewählt. Durch das planare Mapping wird das Bild ganzflächig auf dam Objekt aufgebracht und unverzerrt auf diesem dargestellt. Die Abmessung der Polygonfläche entsprechen dabei exakt der Abmessung des Bildes.
Um einem Körper eine Map zuzuweisen, wählt man ein Polygonobjekt aus und wandelt es über das Kontextmenü der rechten Maustaste in ein "editable Mesh" um. Dadurch erhält man Zugriff auf die einzelnen Polygonflächen. Auf der rechten Seite der Programmoberfläche klappt dadurch der Register-Reiter "Modify" auf.

Konvertierung eines Polygonobjekts zu einem "Editable Mesh"
Modify-Menu
Dieses Menü verfügt über folgende Merkmale:
  • Anzeige des aktiven Elements (hk_abdeckung_01) mit der Zugehörigen Einfärbung in der 3D- Umgebung. Die Einfärbung hat nichts mit einer Oberflächentextur zu tun und dient lediglich der farblichen Unterscheidung der einzelnen 3D-Elemente.
  • Modifier List:
    Diese Liste beinhaltet sämtliche Modifizierungstools.
  • Editable Mesh:
    Dies ist der eigentliche 3D- Grundkörper, der sich aus verschiedenen Elementen wie Vertices, Ecken, Faces (Polygone mit 3 Eckpunkten), Polygonen (ein viereckiges Polygon wird als solches auch in der 3D-Ansicht angezeigt, intern jedoch als zwei zusammengehörige Polgyone mit jeweils drei Eckpunkten behandelt.) und dem Element (dies ist wiederum das gesamte 3D-Objekt, jedoch auf einer tieferen Ebene) zusammensetzt.
  • Liste mit Eigenschaften und Modifikatoren:
  • Selection:
    Je nach Auswahl (Vertex, Edge, Polygon, usw.) erscheinen hier kontextbezogene Modifikationsmöglichkeiten.
  • Soft Selection, Edit Geometry, usw.:
    Hierbei handelt es sich um Möglichkeiten, Objektkanten zu brechen und Elemente zu transformieren.
  • Surface Properties:
    An dieser Stelle werden die Normalen (Polygonseiten) ausgerichtet und umgedreht. Zudem kann man einzelnen Polygonen oder Polygongruppen IDs zuweisen.

Um einem Körper/einer Oberfläche die Material-Map zuweisen zu können, muss man die Polygon-Selektion aktivieren und die gewünschte Oberfläche in der 3D-Ansicht selektieren. Nachfolgend weist man der Auswahl eine ID über die Surface Properties zu. Dabei ist darauf zu achten, dass alte Selektionen nicht unbeabsichtigt überschrieben werden. Im Beispiel werden für den Heizkörper zwei IDs erstellt. Die Erste dient der Aufbringung der Lüftungsschlitze, die Zweite der Grundfarbe für Rückseite und Kanten.

Arwin 3d id1.jpg Arwin 3d id2.jpg
ID1 ID2

Im nächsten Schritt wählt man aus der "Modifier List" das Element "UVW Mapping" aus. Daraufhin erscheint dieses über dem "Editable Mesh".

Das UVW Mapping wird wie folgt eingestellt:

Mapping: Planar für Ebenen, Box für Quader, usw.
Channel: Map-Channel: 1
Alignment: Je nach Ausrichtung der Ebene. (im Beispiel des Heizkörpers: Z- Achse)
Material Editor
Will man die gesamte Polygonfläche als Texturoberfläche nutzen, so betätigt man den Button "Fit".

Nachdem alle Objekte mit Maps versehen wurden, gilt es nun, die Materialien anzufertigen.
Obwohl die materialeigenen Texturen beim Objekt-Export verloren gehen, ist es sinnvoll, die Körper schon in 3ds Max mit Texturen zu versehen. Zum Einen dient die Zuweisung dazu, mögliche Material-Map Fehler schon in 3ds Max zu entdecken und zu beheben. Zum anderen gehen durch den Export nur die Texturen verloren, die Materialien bleiben jedoch mit ihren grundlegenden Eigenschaften erhalten. In Virtools muss man somit lediglich die Materialien mit Bildern versehen.

Über das Rendermenü wird der Material Editor geöffnen. Dieser erschient in einem Popup.
Ein Material – dargestellt durch eine Kugeln, einen Würfel oder eine ebenflächige Abbildung – wird ausgewählt. Die Darstellungsformen lassen sich über ein Menü beliebig wählen. Über den Button "Standard" neben dem Dropdown-Menü mit der Materialbezeichnung gelangt man in den Material/Map Browser. Hier lassen sich die verschiedenen Materialtypen auswählen. Für ein Objekt, welches über mehrere unterschiedliche Texturen verfügen soll, wird das sogenannte "Multi/Sub-Object" ausgewählt. Diesem Material-Typ lassen sich mehrere Maps – sprich Texturen – zuweisen. Über "Set Number" wird ausgewählt, über wie viele Texturen das "Multi/Sub-Object" verfügen soll. Unter "Sub-Material" kann man nun jeder Textur verschiedene Eigenschaften zuweisen. Innerhalb der Sub-Material Eigenschaften befindet sich ein Menü, in dem verschiedene Maps aufgelistet sind. Die "Diffuse Color"-Map dient als Träger für Grafiken und wird mit einem Haken und einem Bild versehen. Dieser Schritt wird für jedes Sub-Material wiederholt, bis alle Material-IDs eine Textur in sich tragen.
Über das blau- weiße Würfelsymbol aktiviert man die Sichtbarkeit des Materials. Abschließend wird das Material gespeichert und über "Assign Material to Selection" dem Objekt zugewiesen. Die Material-IDs des "Multi/Sub-Object"- Materials entsprechen dabei den Selection-IDs des dreidimensionalen Körpers. "Multi/Sub-Object"- Materials lassen sich zudem auch auf mehrere Objekte verteilen.
Für jeden Körper und jedes Material wird diese Prozedur wiederholt und abschließend kontrolliert man das gesamte 3D-Objekt auf Vollständigkeit bezüglich der Maps.

Sind Fensterfront, Decke, Boden und Wände mit Material-Maps und Materials versehen, so werden sie auf einem Rechner gesammelt und in die Virtools 3D-Entwicklungsumgebung eingebunden. Da Virtools einwandfrei mit 3DS-Daten von 3ds Max umgehen kann, werden alle Raumelemente in diesem Format exportiert. Der Texturverlust wird dabei in Kauf genommen.

Virtools

Über Virtools
Arwin 3d virtools.jpg

Virtools ist sowohl eine echtzeitfähige 3D-Engine, als auch eine 3D-Entwicklungsumgebung.
Virtools verfügt über keine Möglichkeit, 3D-Körper zu modellieren. Objekte müssen mit anderen Programmen erstellt und über die Importfunktion in die Szene eingebunden werden. Sodann ist es möglich, die Elemente mit Programmblöcken zu versehen, um eine Animation und/oder Interaktion zu realisieren.
Eine 3D-Vorschau erlaubt es dem Nutzer, schon während der Entwicklungsphase, Einblick auf die spätere 3D Anwendung zu erhalten. Links davon befindet sich ein Menü, über das Änderungen an Szenenobjekten vorgenommen werden können. Die rechte Seite der Programmoberfläche beinhaltet die sogenannten "Building Blocks". Dies sind vordefinierte Programmbausteine, die durch deren Platzierung und Verknüpfung in der Schematic-Anzeige die Programmabläufe der Engine realisieren. Der untere Bereich dient den Einstellungsmöglichkeiten an 3D-Objekten, Meshes, Lichtquellen, Materialien, Texturen und fasst zudem einen Level- Manager auf, über den alle Szenenobjekte abrufbar sind. Auch die oben angesprochene Schematic-Ebene ist hier zu finden.
Virtools unterscheidet sich entsprechend dem Verwendungszweck grundlegend von den Modellierungstools Cinema4D und 3ds Max. So ist die Engine auf die Hardware des Systems ausgerichtet und beinhaltet Einstellungsoptionen, die gezielt auf die Fähigkeiten der Grafikkarte des Rechners zugreifen.
Auffällig an Virtools ist das nicht immer berechenbare Verhalten des Programms. So wird beispielsweise bei jedem Programmneustart entgegen aller Justierungen die diffuse Lichtfarbe einiger Materialien auf Cyan gesetzt. Auch verschwinden oftmals Objekte, sobald man versucht, sie im 3D-Raum zu verschieben.

Zusammenfügen der Raumelemente

Der Import der Raum-Module erfolgt über [Resources] → [Import File As] → [Place]

Place-Objekt
Beim Objekt-Import muss man darauf achten, dass die Elemente in Form eines Place-Objektes sauber in die 3D Szene/Umgebung einpflegt werden. Durch die Zusammenfassung der einzelnen Elemente eines Raumteils (so besteht das Fenster aus verschiedenen Komponenten, wie der Glasscheibe oder dem Fensterrahmen) in einem Place-Objekt kann man jederzeit problemlos auf das gesamte Objekt zugreifen. Importiert man es jedoch über "Import File", so zerfällt die Gruppe.

Komplettiert wird der Raum, indem alle Raumbausteine auf gleiche Art und Weise importiert werden. Da die Passgenauigkeit über die Bezugnahme auf den Nullpunkt bereits in der Modelling-Phase sichergestellt wurde, sind weitere Positionierungsarbeiten nicht notwendig.

Raum ohne Texturen
Das Grundgerüst des Raumes ist nun komplett, doch besitzt es derzeit noch keine Texturen.

Wie bereits erwähnt, setzen sich Materialien aus Texturen und Oberflächeneffekten zusammen. Da durch die Übertragung mit Hilfe des 3DS-Formates die Texturinformationen verworfen wurden, gilt es nun, diese erneut hinzuzufügen.
Per Drag&Drop werden die JPG-Grafiken in die Programmoberfläche der 3D-Entwicklungsumgebung gezogen. Dadurch erstellt Virtools automatisch Kopien der Bilder und fasst diese beim Speichern der Szene mit allen anderen Informationen in einer cmo-Kompositionsdatei zusammen.

Materialauswahl über Meshes
Über das Kontextmenü der rechten Maustaste werden nun die Mesh-Ebenen der Objekte selektiert. Meshes bilden das räumliche Grundgerüst und spannen somit dreidimensionale Körper auf.

Handelt es sich – wie bei der Heizkörperverschalung – um einen Körper mit mehreren Materialien, so erscheinen diese aufgelistet im Setup-Menü des Meshes unter dem Punkt "Materials Used". Die Anzahl der Materialien/Texturen richtet dabei nach den Selection-IDs, die dem 3D-Objekt zuvor in 3ds Max zugewiesen wurden. Objektinstanzen gleichen Typs, wie beispielsweise die Glasscheiben oder Heizkörperabdeckungen, erhalten durch die Zuweisung auf eines der Objekte ebenfalls die gleichen Texturen.

Effekt-Einstellung
Innerhalb des Material-Setup-Menüs lassen sich die bereits durch Drag&Drop eingebunden Texturen den entsprechenden Materialien zuordnen. Innerhalb der Materialeinstellungen kann man zudem Justierungen an Lichtverhalten, Transparenzen und Materialeffekten vornehmen. So lassen sich durch die Kombination von mehreren Texturen innerhalb eines Materials Reflektionen durch die Überlagerung von zwei oder mehreren Bildern simulieren.
Arwin 3d fensterohneeffekt.jpg Arwin 3d fenstermiteffekt.jpg
Fensterglas ohne und mit Reflektion

Als Referenzbild für die Spiegelung in den Fensterscheiben wird das Umgebungsbild der HDR-Aufnahme verwendet. Zu Testzwecken wird dieses durch die Kombination von zwei Texturen (Fensterglas-Farbe und 360°-Raumaufnahme) in die Szene eingebunden. Für die finale Anwendung wird die Kombination der zwei Texturen zu einem späteren Zeitpunkt durch die Verwendung einer CubeMap (siehe Abschnitt "Environment Mapping" weiter unten) ersetzt.
Um Systemresourcen einzusparen, wird die Farbtiefe der Bilder von 32bit auf 16bit herabgesetzt.

Da das Verfahren des "image based lighting" aufgrund von Komplikationen nicht umgesetzt werden konnte (siehe Abschnitt "Image Based Lighting & HDR Images" weiter unter), mussten die Lichtquellen per Hand gesetzt werden. Somit galt es, eine möglichst genaue Annäherung an die reale Lichtsituation des Raumes zu erzielen. Dabei muss man darauf achten, dass das Setzen von Lichtquellen in Virtools mit Einschränkungen verbunden ist. So lässt das Programm je nach Rechnerleistung meist nur acht – in Sonderfällen auch mehr – aktive Lichtquellen zu. Dies macht das Lichtverhalten von Virtools unvorhersehbar, da man aufgrund der mangelhaften Dokumentation kaum abschätzen kann, wie viele aktive Lichtquellen auf dem jeweiligen Rechner gleichzeitig angezeigt werden können. Daher gilt es, sich auf ein Minimum an Lichtobjekten zu beschränken und zu versuchen, mit weniger als acht Lichtern eine angemessene Ausleuchtung des Raumes zu erreichen. Weiterhin unterscheidet sich das virtuelle Lichtverhalten von dem Verhalten von realen Licht. Positioniert man die Lichter an den Orten, an denen auch die echten Lichtquellen sind, so ist nicht gewährleistet, dass Schattenwurf, Glanz usw. mit der Realität übereinstimmen.
Auch das Render-Device bestimmt das Erscheinungsbild des Lichtes. So unterscheiden sich Schattenwurf, Lichtweite und Lichtfarbe von OpenGL und DirectX deutlich voneinander.
Unter Verwendung des HDR-Bildes als Vorlage werden nun Position, Art und Verhalten der Lichtquellen festgelegt.

Virtools verfügt über drei verschiedene Lichtquellen-Arten

  • Spot: gerichteter Lichtkegel mit einer bestimmten Reichweite
  • Point: ungerichtetes Punktlicht mit einer bestimmten Reichweite
  • Directional: gerichtetes Licht ohne Reichweitenbeschränkung

Sowohl Spot Light, als auch Point Light verfügen über Einstellmöglichkeiten für Reichweite und Abnahme. Die Abnahme der Lichtstärke lässt sich in drei Arten unterteilen.

  • Constant: konstante Lichtstärke
  • Linear: lineare Abnahme der Lichtstärke
  • Quadratc: quadratische Abnahme der Lichtstärke

Dem Spot Light lässt sich ein Referenz- Objekt zuordnen. Weiterhin verfügt es über Eigenschaften bezüglich der Lichtkegel.

  • Hot Spot: Winkel des inneren Lichtkegels
  • Fall Off: Winkel des äußeren Lichtkegels
  • Fall Off Shape: Abnahme der Lichtintensität entlang des Lichtkegels

Das gerichtete Licht (Directional) bietet kaum Einstellmöglichkeiten. Es beleuchtet nur die Objekte, die in einem bestimmten Winkel zur Lichtobjekt-Achse liegen.
Allen Lichtquellen- Typen gemein ist die einstellbare Lichtfarbe. Der Raum wurde mit insgesamt sechs Lichtquellen beleuchtet.

Spot Light Setup Menu

Vier Spot Lights erzeugen mit ihren inneren und äußeren Lichtkegeln den Schattenwurf an Boden, Wänden und Fenstern. Sie simulieren die Lichteinstrahlung durch die Deckenleuchten im realen Raum. Dabei gilt es, Leuchtstärke, Lichtkegelgröße, Beleuchtungsweite und Lichtfarbe auf Grundlage der Panorama-Aufnahme so einzustellen, dass ein möglichst realistischer Schattenwurf entsteht.
Das Lichtverhalten von Virtools basiert entweder auf dem OpenGL-Rendermodell oder auf der mittlerweile veralteten DirectX5-Version. Beide Render Devices bieten nur einen begrenzten Funktionsumfang für die Lichtsetzung. Daher ist es nicht möglich, die Beleuchtungssituation exakt dem Vorbild entsprechend nachzustellen.

Ein diffuses Punktlicht mit maximaler Reichweite dient der gleichmäßigen Ausleuchtung des Raumes. Ohne dieses Punktlicht wäre die Decke nicht zu sehen, da die Lichtkegel der Spot Lights auf den Boden gerichtet sind. Im ünrigen ermöglicht das Punktlicht über sein Setup-Menü, das Lichtverhalten des gesamten Raumes zu steuern. Eine Anpassung jedes Lichtobjektes in Bezug auf Farbe und Helligkeit ist somit nicht notwendig.

Im 45°-Winkel in Bezug auf die Grundebene des Raumes werden alle Partien der Kante zwischen Decke und Fensterfront durch ein gerichtete Licht gleichmäßig ausgeleuchtet. Das Directional Light dient der Hervorhebung des oberen Bereiches der Fensterfront. Durch den Schattenwurf der Laufschienen für Vorhange wären die Oberflächen der Metallplatten oberhalb der Fensterrahmen ohne das gerichtete Licht nicht sichtbar.

Ausleuchtung des virtuellen Raums in Virtools

Bildverarbeitung

Es musste ein System entwickelt werden, das die Räumliche Lage der Kamera anhand des Videobildes erkennen kann. Genauer gesagt musste die räumliche Lage, also die drei Werte für die X-, Y- und Z-Achse erkannt werden, die meist zusammengefasst als Vektor übertragen werden. Zusätzlich musste die Orientierung der Kamera erfasst werden, d.h. die drei Winkelwerte für Rollen, Neigen und Gieren, die meist in Form von Quaternionen übertragen werden. Quaternionen sind komplexe Zahlen, die v.a. für Winkelangaben in der Computergrafik verwendet werden. Das System Artoolkit – kurz für Augmented Reality – erschien sehr gut für unsere Anforderungen geeignet.

ARToolkit

ARToolkit steht für „Augmented Reality Toolkit“ und stellt eine freie Programmbibliothek für die Programmierung von Augmented-Reality-Anwendungen dar (siehe ARToolkit-Website). Wie jede andere Programmbibliothek besteht auch ARToolkit aus einer Sammlung von Programmfunktionen für zusammengehörige Aufgaben. Sie ist C-basiert und stellt vor allem Computer-Vision-Algorithmen zur Verfügung, die ein Videobild analysieren, vorher definierte Marker im Bild erkennen und diese mit einem bekannten Modell vergleichen. Anhand der perspektivischen Verzerrung der Marker im 2D-Bild der Kamera, kann deren räumliche Lage errechnet werden.

Installation

Zusätzlich zu der, auf der ARToolkit-Website beschriebenen Installationsanweisungen sind uns bei der Einrichtung von ARToolkit folgende Punkte aufgefallen.

  • Die DSVideoLib, die unter Windows die Kommunikation mit dem Kameratreiber übernimmt, erzeugt in den späteren Versionen eine DSVLib.dll. Diese muss unbedingt in DSVL.dll umbenannt werden, damit auf sie richtig zugegriffen werden kann.
  • Die Installation des GLUT Runtime war nicht ganz so einfach, da die Ordner, in welche die GLUT-Dateien kopiert werden müssen, etwas schwierig zu finden waren.
  • Die drei Dateien libARvideo.dll, libARvideod.dll und libARvideod.ilk sollten in das Systemverzeichnis kopiert werden, damit diese den eigenen Anwendungen zur Verfügung stehen. Sie müssten sonst im gleichen Verzeichnis wie die Anwendung liegen.
  • Es hat sich gezeigt, dass bei den meisten Rechnern für ein Build von ARToolkit DLLs auf dem System fehlen. das waren beispielsweise MSVCP71D.DLL und MSVCR71D.DLL. Diese können aber leicht aus dem Internet heruntergeladen werden.

Die Marker

Um von der Kamera besser erkannt zu werden und beste Resultate in den Tracking-Algorithmen zu erzielen, sollten die optischen Marker neben einem obligatorischen, schwarzen Rand und der quadratischen Form bestimmte Vorrassetzungen erfüllen. Zunächst sollten sie einen hohen Kontrast aufweisen, damit eine Binarisierung erleichtert wird. Des weiteren sollten sie möglichst niederfrequent sein, d.h. wenige Änderungen zwischen schwarz und weiß in einem bestimmten Längenabschnitt besitzen. Schließlich sollten sie asymmetrisch aufgebaut sein, um nur ein einziges Ergebnis für die Berechnung der Kameralage zuzulassen. Farbige Marker sind zwar möglich, jedoch muss dabei auf eine gute Binarisierbarkeit geachtet werden.
Um ein vergleichbares Modell zu erzeugen, werden die Marker mit Hilfe des kleinen, mitgelieferten Tools „mk_patt“ fotografiert. Es zeigt beim Fotografieren des Markers an, ob dieser gerade erkannt wird. Dafür muss der Marker den oben erwähnten Rand aufweisen. Mit diesem digitalen Bild eines Markers wird die Anwendung „gefüttert“.

Transformationsmatrix

Mit der Funktion "arGetTransMat()" kann, nachdem der Marker mit "arDetectMarker()" erkannt wird, eine Transformationsmatrix erstellt werden, die sich aus einem Rotations- und einem Translations-Teil zusammensetzt. Invertiert man nun mit "arUtilMatInv()" diese Matrix für den Marker, erhält man die Matrix der Kamera relativ zum Marker. Aus dieser Matrix konnten wir die für uns wichtigen Informationen, Position und Orientierung der Kamera extrahieren.

if( arDetectMarker(dataPtr, thresh, &marker_info, &marker_num) < 0 ) {
  cleanup();
  exit(0);
}
 
/*Transformationsmatrix holen*/
if( arGetTransMat(marker_info, tar_c, tar_w, target_trans) < 0 ) return;
 
/*Transformationsmatrix invertieren*/
if( arUtilMatInv(target_trans, cam_trans) < 0 ) return;
 
/*Rotationsteil der Transformationsmatrix für Rotationsmatrix kopieren*/
for (i=0 ; i < 3; i++){
  for (j=0; j < 3; j++){
    rot[i][j] = target_trans[i][j];
  }
}
 
/*von Quaternionen in Bogenmaß umwandeln*/
arGetAngle(rot, &angle[0], &angle[1], &angle[2]);


Kamerakalibrierung

Um bestmögliche Tracking-Ergebnisse zu erhalten, erscheint es völlig sinnvoll und notwendig, die verwendetet Kamera zu kalibrieren. Dafür liefert ARToolkit mit den beiden Tools "calib_dist" und "calib_cparam" alle Mittel, die eigene Kamera zu kalibrieren. Die Prozedur besteht im Wesentlichen aus dem Aufnehmen von Bildern von regelmäßigen Mustern und der darauffolgenden Kennzeichnung der Markanten Punkte des Musters im Bild.
Bei "calib_dist" (steht für Verzerrungs-Kalibrierung) ist ein regelmäßiges Muster eine 6x4-Matrix aus Punkten mit gleichem Abstand. Davon werden verschiedene Bilder geschossen und danach die Punkte im Bild gekennzeichnet. Aus den gewonnenen Daten werden die Werte für die Verzerrung der Kamera errechnet und ausgegeben.

"calib_dist"-Muster

Diese Werte werden dann in das zweite Tool, "calib_cparam" (steht für Kameraparameter), eingegeben. Hier besteht das Muster aus einem 6x8-Raster. Die Prozedur ähnelt stark der des "calib_dist"-Tools erzeugt im Unterschied dazu aber eine Kameradaten-Datei, welche die Ergebnisse der Kamerakalibrierung beinhaltet. Diese kann nun in die Anwendung eingebunden werden.

"calib_cparam"-Muster

Multimarker

Bei ARToolkit gibt es sie Möglichkeit, mehrere Marker zu einem Verbund zusammenzufassen, um eine Position anhand von mehrere Markern errechnen zu können. Dies ist nötig, wenn man ausgedehnte Bereiche, z.B. einen ganzen Tisch, als Erkennungsraum nutzt. Es ist denn leicht zu erkennen, dass wenigstens ein Marker im Bild sein muss, damit das Tracking überhaupt funktioniert. Dies wird mit nur einem Marker und einer ausgedehnten Fläche unmöglich. Mit dem MultiMaker-Modul von ARToolkit kann von der Position eines Markers auf die Position des ganzen Markerverbundes geschlossen werden. Erreicht wird dies mit Hilfe einer Konfigurationsdatei, eine simple Textdatei, in der die Position der einzelnen Marker zueinander festgehalten wird. Zusätzlich erhöht das MultiMarker-Modul die Tracking-Stabilität da bei der gleichzeitigen Erkennung von mehreren Markern, die Trackingfehler ausgemittelt werden können.

# Anzahl der Marker
15
 
# marker1
multimarker/patt.marker1
40.0
0.0 0.0
1.0000 0.0000 0.0000 0.0
0.0000 1.0000 0.0000 0.0
0.0000 0.0000 1.0000 0.0
 
# marker2
multimarker/patt.marker2
40.0
0.0 0.0
1.0000 0.0000 0.0000 50.0
0.0000 1.0000 0.0000 0.0
0.0000 0.0000 1.0000 0.0
 
# marker3
multimarker/patt.marker3
40.0
0.0 0.0
1.0000 0.0000 0.0000 50.0
0.0000 1.0000 0.0000 50.0
0.0000 0.0000 1.0000 0.0
.
.
.

In dem obenstehenden Ausschnitt aus einer MultiMarker-Konfigurationsdatei werden zunächst drei Marker definiert. Kommentare werden mit einer voranstehenden Raute gekennzeichnet. Zunächst muss die Anzahl der Marker definiert werden. Darauf folgt die Angabe des Speicherortes des Markers relativ zum Ort der ausführbaren Programmdatei. Die MultiMarker-Konfigurationsdatei muss dabei im gleichen Verzeichnis wie die einzelnen Marker-Dateien liegen. Danach wird die Markerbreite und das Zentrum des Markers in Millimetern angegeben. In unserem Fall ist der Marker also vier Zentimeter breit und sein Zentrum liegt in der Mitte des quadratischen Markers. Der letzte Punkt der Marker-Information besteht aus der 3x4 Transformationsmatrix, die uns schon unter Punkt 3.2 begegnet ist. Die ersten drei Spalten bilden die Rotationsmatrix, bei der in unserem Beispiel keine Änderung der Rotationslage besteht. Die vierte Spalte gibt die Translation des Markers in X-, Y- und Z-Richtung an, wobei sich diese auf den Mittelpunkt des Markers bezieht. In unserem Fall liegt marker2 mit einem Zentimeter Abstand oberhalb von marker1, marker3 mit dem gleichen Abstand rechts von marker2.

Bezug zum Projekt

erste Erfolge mit dem ARToolkit
Zunächst wurde versucht, die Voraussetzungen für die Einrichtung der Entwicklungsumgebung für ARToolkit zu schaffen (siehe "Installation"). Danach sollten die mitgelieferten Beispielapplikationen zum Laufen gebracht werden, was an sich schon einige Zeit in Anspruch nahm. Darunter war auch eine Anwendung Namens "exview_ang", die schon von sich aus eine Ausgabe der Kamerapositionsdaten ausführte. Insofern erschien dieses Beispiel schon sehr vielversprechend. Dessen Quellcode wurde darauffolgend so modifiziert, dass zu den Postionsdaten auch die Rotationsdaten extrahiert wurden.

Danach wurde versucht, die verwendete Philips-USB-Kamera zu kalibrieren. Dies gelang auch relativ reibungslos nicht zuletzt wegen der guten Dokumentation auf der ARToolkit-Website.
Auf die Kalibrierung folgte das Einrichten eines MultiMarker-Setups, wie dies im vorangegangenen Punkt erläutert wurde. Es wurden eigene Marker entworfen, ausgedruckt und im System gespeichert. Diese wurden danach wurde in einer MultiMarker-Konfigurationsdatei zueinander in Beziehung gesetzt.
Nachdem all diese Punkte erfolgreich durchgeführt wurden und zudem die Kameradaten durch die Modifizierung eines Anwendungsbeispiels extrahiert werden konnten, stand im nächsten Schritt die Bereitstellung dieser Daten für eine externe 3D-Anwendung an.
Als Transportweg für die Kameradaten war zuerst angedacht, das OSC-Protokoll zu verwenden, was sich jedoch als schwierig herausstellte. Das Problem löste letztendlich die sog. Studierstube.

Studierstube

Bei der Recherche nach einer Möglichkeit, ARToolkit mir einer 3D-Anwendung zu verbinden, wurde die Studierstube ausgemacht. Es erschien uns einfacher, die Kameradaten mittels dem VRPN-Modul von Studierstube in eine 3D-Anwendung integrieren zu können als das mit OSC möglich gewesen wäre.

Studierstube ist ein frei erhältliches Framework zur die Entwicklung von Augmented-Reality-Anwendungen und wird als Projekt seit 1996 an der TU Wien, seit 2004 auch an der TU Graz entwickelt. Durch seinen modularen Aufbau ist es sehr flexibel und angesichts der gigantischen Menge an Modulen enorm mächtig – aber entsprechend schwer zu verstehen und zu konfigurieren. Für uns stellte es eine einfache Lösungsmöglichkeit dar, um die ARToolkit-Funktionen flexibel benutzen zu können, ohne eine einzige Zeile C-Code zu programmieren. Die interne Struktur von Studierstube umfasst von den Eingabekanälen bis hin zur eigenen minimalen Renderengine nahezu alle Elemente, die man für ein AR-System brauchen kann. Die Konfiguration erfolgt durch XML-Configfiles. Um also überhaupt die Syntax zu verstehen, mussten wir unsere XML-Kenntnisse erheblich auffrischen.
Die Kommunikation zwischen Modul und Studierstube wird durch sog. Events gelöst. Im Modul wird dafür eine EventSink erstellt, wenn Daten in Richtung Studierstube fließen müssen, umgekehrt muss eine EventSource erstellt werden, wenn Daten von der Studierstube entegegengenommen werden sollen. Studierstube bietet also den Rahmen für die Kommunikation verschiedener Module.

Installation

Studierstube bietet auf seiner Homepage den Download eines Installers für Studierstube Version 4, diejenige mit der ARwin arbeitet. Es werden standardmäßig die Module, wie OpenTracker, mitinstalliert. Jedoch müssen einige von ihnen erst kompiliert werden, andere sind schon fertig kompiliert in Studierstube integriert. Dieser Umstand ist von großer Bedeutung, was später noch erläutert wird.

Das Modul OpenTracker

Opentracker nennt sich die Trackersoftware-Komponente, die in Studierstube integriert ist. Die Trackersoftware hat die Aufgabe, Datenquellen zu abstrahieren, indem verschiedenste Koordinaten-Lieferanten (optische Tracker, Ultraschall etc.) unter dem selben Interface zusammengefasst werden, sodass es völlig irrelevant ist, woher die Daten in Wirklichkeit kommen.
Außerdem ist ein flexibles Routing und eine beliebige Zusammenfassung der Koordinatenströme möglich, so dass z.B. Daten von verschiedenen physikalischen Quellen gesammelt und zum Zwecke der Fehlerreduktion miteinander verglichen bzw. redundant dargestellt werden können. OpenTracker fungiert wie eine Art Matrix zwischen Ein- und Ausgabe-Kanälen.
Eingabekanäle können einfache Geräte wie Maus oder Tastatur sein, Software wie ARToolkit, Eingabemöglichkeiten wie die Konsole, Sprache oder eine Datei, aber auch andere VR-Geräte wie Flock of Birds oder P5-Glove. Diese werden einfach in OpenTracker eingebunden, die Daten werden zusammengefasst (merge) oder verändert (transform). Dabei kann eine Transformation einer Quelle abhängig von einer anderen geschehen. Danach werden die Daten in Datensenken geleitet, wo sie anderen Geräten zur Verfügung gestellt werden. So führt beispielsweise die ConsoleSink zu einer Ausgabe auf der Konsole oder eine EventSink kommuniziert mit Studierstube.
Die Konfigurierung von OpenTracker geschieht mit Hilfe einer XML-Konfigurationsdatei, d.h. das Programm wird von "außen" konfiguriert, es muss nicht in den Quellcode eingegriffen werden. Diese Variante stellt eine komfortable Möglichkeit dar, OpenTracker zu steuern.

exmplarische Übersicht über den Aufbau von OpenTracker
Installation

Die im Vergleich zu ARToolkit schlechtere Installationsanleitung verursachte einige Probleme, die gar nicht erst entstanden wäre, wenn die Dokumentation umfangreicher gewesen wäre. Daher stehen hier im Folgenden Anmerkungen zur Einrichtung von OpenTracker.
Die Reihenfolge der Kompilierung der einzelnen Teile muß unbedingt eingehalten werden. Es wird hier von OpenTracker mit der Einbindung des VRPN- und ARToolkitPlus-Moduls ausgegangen.

  • Zunächst muss die VRPN-Bibliothek heruntergleladen werden und das zugehörige VisualStudio-Projekt kompiliert werden.
  • Das VisualStudio-Projekt für ARToolkitPlus muss kompiliert werden. Es wird standartmäßig mitgeliefert und kann im Studierstube-Installationverzeichnis unter "ICG-Labs\Studierstube\ARToolkitPlus\build" gefunden werden.
  • Das VisualStudio-Projekt für PatGen, eine Anwendung zum Generieren von ID-basierten Trackingmarkern als Targa-Datei, muss kompiliert werden. Man findet es unter "ICG-Labs\Studierstube\ARToolkitPlus\tools\IdPatGen\build". Falls die dafür benötigte ARToolkitPlus.lib nicht gefunden wird, muss deren Speicherort in den Projektordnern angegeben werden. Dies gilt für alle diese Kompilierungsverfahren.
  • Das VisualStudio-Projekt für TinyXMLMod unter "ICG-Labs\Libraries\tinyXMLMod\build" muss kompiliert werden.
  • Jetzt kann endlich das VisualStudio-Projekt für OpenTracker geöffnet werden. Die Datei config_win.h unter den Header-Dateien öffnen und die Zeile "// #define USE_VRPN 1" einkommentieren. Wie der darüberstehende Kommentartext schon aussagt, sollte man nicht vergessen, die Umgebungsvariable VRPNROOT auf das Verzeichnis zu setzen, in der die kompilierte vrpn.lib liegt. In unserem Fall "ICG-Labs\Libraries\vrpn_07_03\vrpn\pc_win32\Debug"
  • Das Projekt "standalone" in der OpenTracker-Solution findet die Datei opentracker.lib nicht, weil diese (auch ein Ergebnis der OpenTracker-Solution) fälschlicherweise opentrackerlib.lib benannt wird.
  • Bei einer erfolgreichen Kompilierung des OpenTracker-Projektes werden eine OpenTracker.dll und eine OpenTracker.exe erzeugt. Da nun Studierstube mit einer vorkompilierten Version von OpenTracker installiert wird – wahrscheinlich um ein funktionierendes ARToolkitPlus-Beispiel mitliefern zu können – , müssen auch schon funktionierende Versionen dieser beiden Dateien existieren. Diese wurden jedoch ohne VRPN-Unterstützung kompiliert. Sie müssen von den gerade neu erstellten ersetzt werden, indem sie in den Ordner "ICG-Labs\bin" verschoben werden.
Die Konfigurationsdatei OpenTracker.xml

Wie weiter oben bereits erwähnt wird OpenTracker mit Hilfe einer XML-Konfigurationsdatei namens OpenTracker.xml konfiguriert. Sie besteht im Wesentlichen aus einem Konfigurationsteil und dem eigentlichen Arbeitsteil. Im Konfigurationsteil werden, wie der Name schon sagt, die Konfigurationen für die im Arbeitsteil kommenden Elemente gesetzt. Das untenstehende Beispiel besitzt unterhalb des Configuration-Element 4 Elemente für die Konfiguration des VRPN, des ARToolkitPlus, der Konsole und der Eventelemente. Nähere Informationen zu den einzelnen Konfigurationen kann man in der Node-Reference von OpenTracker finden.

Beispiel eines Konfigurationsteils einer opentracker.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE OpenTracker SYSTEM "opentracker.dtd">
<OpenTracker>
  <Configuration>
 
    <VRPNConfig port="3883" interface="localhost"/>
 
    <ARToolKitPlusConfig
    camera-parameter="./cameraCal/FlyCam.dat"
    undist-mode="lut"
    marker-mode="idbased"
    border-width="0.250"
    treshold="auto"
    pose-estimator="rpp"
    ov-cong="openvideo.xml"
    ov-sink="artoolkitPluSink" />
  
    <ConsoleConfig headerline="Sample Tracking Input" interval="1"  display="on" />
 
    <EventConfig keyevents="on" mouseevents="on"/>
 
  </Configuration>

Es seien hier nur ein paar wenige Anmerkungen zur Konfiguration gemacht, die jedoch aufgrund der wiederum schlechten Dokumentation im Zweifelsfall weiterhelfen können.

  • Die Document Type Definition "OpenTracker.dtd" wird defaultmäßig im selben Ordner wie die XML-Datei gesucht.
  • Der Quasi-Standart-Port für VRPN-Anwendungen ist 3883.
  • Die Angabe der border-width stellt den Anteil des Randes relativ zur Gesamtgröße des Markers dar. In diesem Fall macht der Rand also 25% vom gesamten Marker aus.
  • Dem Attribut "interval" im ConsoleConfig-Element muss "on" zugewiesen werden, wenn man Ausgaben auf der Console mit Hilfe einer Console-Sink anzeigen will. Dies stellt eine sehr gute Möglichkeit für das Debugging dar.

Im Arbeitsteil wird festgelegt, welche Quellen wie transformiert oder zusammengefügt werden und in welche Senken sie geleitet werden. Die XML-Datei muss "von Kind zu Eltern" gelesen werden. Auf das untenstehende Beispiel bezogen heißt das, dass mit der ARToolkitPlusSource begonnen wird. Ihre Daten werden über EventTransform, EventInvertTransform, und EventSink (über die Referenz "hansi") zur VRPNSink gebracht. Weiter unten gibt es noch eine Quelle, welche die Daten aus der eigenen VRPNSink aufnimmt und auf der Konsole ausgibt.

Beispiel eines Arbeitsteils einer opentracker.xml:

<EventSink tracking="otTrack">
  <EventInvertTransform>
    <EventTransform scale="1 1 1" rotationtype="euler" rotation="0 0 0" translation="0 0 0" DEF="hansi">
      <ARToolKitPlusSource center="0 0" size="0.08 0.08" tag-id="30"/>
    </EventTransform>
  </EventInvertTransform>
</EventSink>
 
<VRPNSink name="trackername" type="tracker" station="1">
  Referenzfehler: Ungültige Verwendung von <ref>: Der Parameter „name“ ist ungültig oder zu lang.
</VRPNSink>
 
<ConsoleSink comment="VRPN">
  <VRPNSource name="trackername@localhost:3883" type="tracker" station="1"/>
</ConsoleSink>
</OpenTracker>

ARToolkitPlus

Ein Grund dafür, dass Studierstube so schnell als Entwicklungstool herangezogen wurde war die Tatsache, dass sich ARToolkit in OpenTracker einbinden lässt. Doch nicht nur das. Es besteht sogar die Möglichkeit ARToolkitPlus, eine abgespeckte, aber zugleich im Detail erweiterte Version von ARToolkit, zu verwenden.

ARToolkitPlus ist keine Weiterentwicklung von ARToolkit, sondern eine Reduzierung auf die videobasierte Tracking-Komponente. Die wichtigsten Unterschiede zu ARToolkit sind:

  • Es wurde ein klassenbasiertes API in C++ statt vorher in C geschaffen.
  • Die Gestalt der Marker ist nicht mehr frei. Es können nur noch insgesamt 4096 bch-id-basierte oder 512 simple id-basierte Markerverwendet werden, was die Schnelligkeit und Robustheit der Erkennung enorm beschleunigt.
  • Kompatibilität der Kamerakalibrierung mit der GML MatLab Camera Calibration Toolbox.

Zugehörige Elemente in OpenTracker
Das Configuration-Element von ARToolkitPlus enthält unter anderem Attribute zur Angabe der Kamerakalibrierungsdatei, der Art der Marker (id- oder bch-basiert), der Randbreite oder die Art der Lageerkennung.

Typische Konfiguration von ARToolkitPlus:

<ARToolKitPlusConfig
camera-parameter="./cameraCal/FlyCam.dat"
undist-mode="lut"
marker-mode="idbased"
border-width="0.250"
treshold="auto"
pose-estimator="rpp"
ov-cong="openvideo.xml"
ov-sink="artoolkitPluSink" />

Es leuchtet schnell ein, dass ARToolkitPlus in OpenTracker ausschließlich als Quelle benutzt werden kann. In untenstehendem Beispiel wird der acht Zentimeter große Marker mit der ID 30 als Quelle benutzt, dessen Ursprung in der Mitte des Markers liegt.

<ARToolKitPlusSource center="0 0" size="0.08 0.08" tag-id="30"/>

Wie bei ARToolkit gibt ed bei ARToolkitPlus die Möglichkeit, mehrere Marker zu einem MultiMarker zusammenzufügen. Auch hier müssen deren relative Lage zueinander in einer Konfigurationsdateifestgehalten werden. Im Unterschied zu ARToolkit kann die Konfigurationsdatei bei ARToolkitPlus nicht mit einer Raute kommentiert werden. Auch die Leerzeichen müssen wie im folgenden Beispiel des Anfangs einer MultiMarker-Konfigurationsdatei gesetzt werden. An die Stelle des Speicherorts der einzelnen Marker sind die Nummer der ID des entsprechenden Marker gerückt.

15
 
30
0.08
0.0 0.0
1.0000 0.0000 0.0000 -0.4
0.0000 1.0000 0.0000 0.76
0.0000 0.0000 1.0000 0.0
 
32
0.08
0.0 0.0
1.0000 0.0000 0.0000 0.0
0.0000 1.0000 0.0000 0.76
0.0000 0.0000 1.0000 0.0

In der OpenTracker.xml wird statt der Einzelmarker-Quelle

<ARToolKitPlusSource center="0 0" size="0.08 0.08" tag-id="30"/>

die MultiMarker-Quelle

<ARToolKitPlusMultiMarkerSource cfg-le="./multimarker/MMsetup.cfg"/>

gesetzt.

Im Vergleich zum Einzelmarker muss nur noch die MultiMarker-Konfigurationsdatei angegeben werden. Alle anderen Informationen wie Größe und Ursprung sind in ihr enthalten.

Das VRPN-Element

Das "Virtual Reality Peripheral Network"-Protokoll ist ein Netzwerkprotokoll, das speziell für die Informationsübertragung in interaktiven Systemen entwickelt wurde. Da die Priorität in diesem Bereich eher auf der Schnelligkeit als auf der Übertragungssicherheit liegt, wird VRPN auf Transport-Ebene häufig via UDP betrieben. Jedes VRPN-Paket enthält ein Quaternion, das eindeutige Lageinformationen zu allen Achsen liefern kann, sowie einen 3-dimensionalen Vektor zur Positionsangabe. Außerdem ist in Form verschiedener IDs eine MIDI-Kanal-ähnliche Unterscheidung von Streams vorgesehen, so dass über einen physikalischen VRPN-Server-Port viele Geräte gleichzeitig ihre Koordinaten übertragen können. Die Protokoll-Spezifikationen liegen offen, weshalb VRPN eine sehr große Verbreitung vorweisen kann und uns als attraktiver Kandidat erschien, um die 3D-Engine zu steuern.
Das VRPN-Protokoll ist also vor allem dafür geeignet, VR-Anwendungen mit physikalischen Trackern zu verbinden. In unserem Fall bestand der physikalische Tracker aus OpenTracker bzw. ARToolkitPlus.
Mit der Möglichkeit, einen VRPN-Server in OpenTracker laufen zu lassen und damit die Kameradaten leicht einer 3D-Applikation mit einen VRPN-Client zur Verfügung zu stellen, war die Entscheidung endgültig gefallen, die Bildverarbeitung mit Hilfe der Studierstube und OpenTracker zu realisieren.

Im Configuration-Element der Opentracker.xml wird die Konfiguration der weiter unten stehenden VRPNSinks festgesetzt. Zu den Attributen gehören, wie das von einem Server erwartet wird, IP (hier interface genannt) und Port. Dabei ist anzumerken, dass hier der Quasi-Standart-Port für VRPN-Server, 3883 verwendet wird.

<VRPNCongig port="3883" interface="localhost"/>

Im Arbeitsteil der Opentracker.xml wird der Server mittels einer VRPNSink erstellt. Mit dem Trackernamen können die Einzelnen Tracker angesprochen werden, die Station wird an anderen Stellen auch als ID bezeichnet und stellt quasi den Kanal für den Datenstrom dar. Der Type kann entweder ein Tracker für die Angabe der drei Translations- und Rotationswerte (6 Degrees of Freedom) oder ein Button mit bis zu acht Knöpfen sein. Weitere Informationen können der OpenTracker-Dokumentation entnommen werden.

<VRPNSink name="trackername" type="tracker" station="1">
Referenzfehler: Ungültige Verwendung von <ref>: Der Parameter „name“ ist ungültig oder zu lang.
</VRPNSink>

Wenn alle Einstellungen richtig sind wird man die VRPN-Datensenke in Form eines VRPN-Serverprozesses in der netstat-Liste finden können. Dort kann man auch deutlich erkennen, dass VRPN auf einer niedrigeren Protokollschicht UDP verwendet.

Es leuchtet ein, dass die Angaben von Trackername, Type und Station auf der Serverseite denen auf der Client-Seite, der 3D-Anwendung, entsprechen müssen, wenn ein Datenstrom zustandekommen soll.

Kamerakalibrierung mit Matlab

Seit der Version 2.0 ist ARToolkitPlus kompatibel zum Kamera-Kalibrierungs-Modell, das auch in der Camera Calibration Toolbox für Matlab, ein weitaus elaborierteres Tool als jenes von ARToolkit, verwendet wird. Resultat ist auch bei dieser Prozedur eine Textdatei, welche die Kameraparameter angibt. Zwar wird an mehreren Stellen im Internet behauptet, dass ARToolkitPlus kompatibel zu den Kamerakalibrierungs-Dateien von ARToolkit sei. Dies konnte jedoch nicht bestätigt werden.

Die beiden zur Verfügung stehenden Kameras wurden mit der Camara Calibration Toolbox. Für einen Matlab-Einsteiger sei noch erwähnt, dass nicht alle Funktionen eines Matlab-"Toolbox" als klickbare Icons dargestellt werden, sondern vielmehr über die Matlab-Konsole direkt via Kommandoeingabe aufgerufen werden können bzw. müssen. Nach Entpacken des Toolbox im korrekten Verzeichnis und Registrierung des neuen Subverzeichnisses in den Matlab-Voreinstellungen startet der Aufruf "calib_gui" die grafische Oberfläche der Toolbox.

GUI der calib-Toolbox

Der komplette Prozess lässt sich sehr schnell beschreiben: Zunächst druckt man sich ein Schachbrettmuster auf ein Blatt Papier, wobei die Spaltenanzahl des Schachbrettmusters horizontal und vertikal gerade und ungerade sein muss (7x6, 10x7 etc.). Hierbei werden die Randspalten nicht gezählt, also zählt ein Schachbrett mit 11x8 Spalten als ein Muster mit 9x6 Spalten. Diese Reduktion entsteht deshalb, weil die Randspalten benötigt werden, um die Eckpunkte des "relevanten" Musterteils klar zu definieren.

ein 5x6-Schachbrett mit erkannten Eckpunkten

Der nächste Schritt besteht darin, mit der zu kalibrierenden Kamera ca. 25-30 Standbilder des Schachbretts aus möglichst unterschiedlichen Lagen aufzunehmen und in fortlaufender Nummerierung mit beliebigem Basisnamen zu speichern (Bild001.jpg, Bild002.jpg etc.).
Manövriert man mittels der Matlab-Shell in das Verzeichnis, in dem all die Bilder liegen, kann man sie mittels Click auf "Read Images" in den Arbeitsspeicher laden. Die Mustererkennung findet sodann mit "Extract Grid Corners" statt. Hierbei teilt man der Toolbox zunächst mit, wie viele Schachbrettspalten (gemäß der vorher beschriebenen Spaltenanzahl-Vorgabe) zu erwarten sind.
Mit einer geschätzten Trefferquote von 40% erkennt die Toolbox die Bilder von selbst, falls nicht, wird man zum manuellen Anklicken der Schachbrett-Eckpunkte aufgefordert. Die Kalibrierungsberechnung erfolgt nun mittels Klick auf "Calibration". Daraufhin kann man sich via "Reproject on Images" die erkannten Mustereckpunkte in Form von Kreuzchen auf den jeweiligen Bildern sowie abschließend eine Gesamtübersicht über den durchschnittlichen Fehler ("Reprojection Error") anzeigen lassen. Am ansprechendsten ist jedoch die Funktion "Show Extrinsic": Die erkannten Muster-Lagen bzw. Kamerapositionen werden in 3D-Ansicht dargestellt. Gegebenenfalls aufgetretene "Ausrutscher" werden hier sehr gut sichtbar und können erneut erkannt werden lassen bzw. neu definiert werden ("Extract Grid Corners").

Abweichungen der erkannten Punkte vom Ideal
3D-Darstellung der berechneten Kameraperspektiven

Ist man mit dem Resultat zufrieden, speichert ein Klick auf "Save" die extrahierten Parameter in die Datei "calib_results.m". Im letzten Schritt müssen die dort abgespeicherten Parameter nur noch in die für ARToolkit verständliche Form gebracht werden. Die Vorschrift für diese einfache Textdatei mit Endung ".cal" lautet folgendermaßen:

The ASCII-file containing the camera calibration parameters should look as follows:
[line1]: ARToolKitPlus_CamCal_Rev02
[line2]: xsize ysize cc_x cc_y fc_x fc_y kc1 kc2 kc3 kc3 kc5 kc6 iter
 
xsize, ysize: calibrated frame dimensions (does not have to match the frame dimensions at runtime)
cc_x, cc_y: principal point location (in pixels)
fc_x, fc_y: focal length (in pixels)
kc1..kc6: radial/tangential distortion coefficients (kc6 currently not in use)
ter: number of iterations for distortion compensation

Meine Kalibrationsdatei sah also folgendermaßen aus (der Zeilenumbruch ist hier zu vernachlässigen; es handelt sich um eine 2-zeilige Textdatei):

ARToolKitPlus_CamCal_Rev02
320 240 186.127259590654800 133.329984811754170 503.530893575840250
  505.981476906024800 -0.402040995061108 0.197068726870765
  -0.004242044509254 -0.002028942952795 0.000000000000000 0 1

Das Verhalten von ARToolkitPlus mit korrekt kalibrierter Kamera ist deutlich erkennbar sicherer und ruhiger als unter Verwendung der mitgelieferten (Standard-)Kalibrierungsdateien.

Image Based Lighting & HDR Image

Aufnahme des HDR-Panoramabildes im Präsentationsraum
Da dem Projekt eine realistische Anmutung verliehen werden wollten, war geplant, ein hochauflösendes High-Dynamic-Range-Umgebungsbild in das System zu integrieren, das für die möglichst genaue Beleuchtungsnachbildung sorgen sollte. Mit dieser "Image Based Lighting" genannten Methode sind sehr realistische Nachbildungen von realen Beleuchtungssituationen möglich. Prof. Jostmeier benutzt diese Technik für Standbilder in höchstmöglicher Qualität. Uns ließ jedoch der Gedanke nicht los, dies auch in einer Echtzeitanwendung einzusetzen. Diverse Echtzeit-Demos im Internet zeigten, dass dies offenbar möglich ist. Die Frage, welche 3D-Engine nun zur Ausgabe unserer Szene verwendet werden sollte, stand in direkter Abhängigkeit damit, ob diese Engine nun Image Based Lighting beherrschte bzw. zumindest in der Lage war, Panoramabilder darzustellen. Das menschliche Auge ist nicht in der Lage, mehr Farbabstufungen wahrzunehmen, als ein 24-Bit-Farbbild darstellen kann. Warum sollte beim Image Based Lighting also ein Bild mit 32 Bit Auflösung verwendet werden? Der Grund ist, dass die Farbabstufungsdetails, die fürs menschliche Auge nicht erkennbar sind, bei Reflektionen des Bildes auf 3D-Objekten eine große Rolle spielen: Bei jeder Reflektion wird Helligkeit absorbiert.

Während nun also ein 24-Bit-Bild samt seiner Lichtquellen einfach konstant dunkler werden würde und somit die Lichtquellen als graue Flächen erkennbar wären, treten bei HDR-Bildern noch weitere Details bei den Lichtquellen hervor, die in der normalen Helligkeit gar nicht "mehr" erkennbar waren. Spezielle Algorithmen sind in der Lage, auf Basis eines Panoramabildes Lichtquellen herauszurechnen und eine 3D-Szene damit filigran zu beleuchten.
Das beeindruckendste Beispiel der Verwendung von Image Based Lighting im Echtzeitbereich wurde direkt mit DirectX9-Bibliotheksfunktionen programmiert, bot uns also keine wirklich weiterverwendbare Basis. Außerdem fühlten wir uns damit überfordert, in blankem C++-Code eine Applikation zu schreiben – davon abgesehen dass man das Rad ein weiteres mal neu erfunden hätte.
Auf Anfrage bei Prof. Jostmeier wurde für uns ein HDR-Panoramabild des Präsentationsraumes aufgenommen.

HDR-Panoramabild des Präsentationsraums. Die Aufnahme daurte ca. 80 Minuten
Testrendering mit dem HDRI-Panoramabild des Präsentationsraums
Vergleich zwischen 24 Bit und 32 Bit Farbauflösung bei unterschiedlichen Helligkeitsstufen
Arwin bv hdri original.jpg Arwin bv hdri original.jpg
Arwin bv hdri24dunkel1.jpg Arwin bv hdri32dunkel1.jpg
Arwin bv hdri24dunkel2.jpg Arwin bv hdri32dunkel2.jpg
24 Bit 32 Bit

Auswahl der 3D-Engine

Zur Verwendung als 3D-Engine in unserem System erschienen die beiden Echtzeit-3D-Entwicklungsumgebungen Virtools und Quest3D am attraktivsten. Beide Lösungen beinhalten ein grafisches Programmierinterface, das von der Funktionsweise dem bekannten EyesWeb ähnelt, aber dementsprechend andere Denkweisen voraussetzt im Vergleich mit direkter Code-Programmierung. Das große Pro für Quest3D war, dass Vorgänger-Kommilitonen bereits ein Projekt mit Quest3D realisiert hatten und man dementsprechend auf einen gewissen Erfahrungsschatz hätten zugreifen können. Die Entscheidungsfindung für die 3D-Engine dauerte sehr lange, da ja neben den grundsätzlichen grafischen Fähigkeiten auch noch die – zu der Zeit noch völlig ungeklärten – Kommunikationsmöglichkeiten entdeckt und erforscht werden mussten, über die die mittels ARToolkit extrahierten Koordinaten in die Engine gelangen sollten.
Sowohl Quest3D als auch Virtools werden zusammen mit Software-Development-Kits ausgeliefert, die es ermöglichen sollen, eigene "Building Blocks" (Virtools) bzw. "Channels" (Quest3D), also Funktions-"Blöcke", die die jeweiligen Programmierumgebungen um eigene Funktionalitäten erweitern, zu entwickeln. Die anfängliche Strategie bestand aus der Entwicklung eines solchen Blocks, der seinerseits auf ARToolkit-Bibliotheksfunktionen zurückgriff und damit die benötigten Kamera-Koordinaten aus dem Echtzeit-Kamerabild extrahierte und als Datenstrom zurückgab. Die Tatsache, dass auf der Internetseite des Virtools-Herstellers ein Echtzeit-Demo einer Image-Based-Lighting-basierten Szene zum Download verfügbar war, lenkte die Entscheidung deutlich in Richtung Virtools.
Außerdem schienen uns die vielfältigen Fähigkeiten des Programms speziell im Game-Bereich (von der Physikengine über die künstliche Intelligenz bis hin zur Shaderprogrammierung) und auch im professionellen VR/Installationsbereich (Clustering, Stereo-Display-Fähigkeit) sehr interessant zu sein, auch wenn wir nicht für all die Fähigkeiten konkrete Einsatzmöglichkeiten im Projekt vor Augen hatten.

Virtools

Virtools von Dassault Systems ist ein äußerst umfangreiches Werkzeug für Echtzeit-3D-Systeme. Die Marke Virtools beinhaltet eine mächtige Authoringumgebung, eine sogenannte "Behavioural Engine", die in der Lage ist, verschiedensten Elementen einer Komposition Verhaltensweisen beizubringen und auf bestimmte Events zu reagieren, eine eigene Rendering Engine, die sich bereits ab Werk auf der Höhe der Zeit befindet und durch eigene Shaderprogrammierung noch in großem Maße erweitert werden kann, ein Browserplugin, das es ermöglicht, die erstellten Kompositionen auf Mac- und PC-Basis direkt im Internet zugänglich zu machen. Und schließlich ist noch ein Software-Development-Kit etnhalten, mit dem eigene Funktionsblöcke erstellt werden können. Außerdem gibt es in Form des VR-Players eine große Erweiterung speziell im Hinblick auf große VR-Systeme, die z.B. Clustering von mehreren Systemen, die Darstellung auf mehreren Bildschirmen/Beamern und viele verschiedene 3D-Eingabegeräte unterstützt. Dabei wird auch das im Zusammenhang mit Studierstube bereits erwähnte Protokoll VRPN unterstützt, wodurch es schließlich möglich ist, dank der Open-Source-Lizenz des Protokolls praktisch jedes Eingabegerät unter Virtools benutzbar zu machen.
Der Internetsupport ist dank recht guter Verbreitung gegeben, aber natürlich nicht in einem Maße, wie es z.B. bei Adobe Flash der Fall ist.

Image Based Lighting

Leider unterstützt die Renderengine das Schlüsselfeature Image Based Lighting, das uns ja erst Virtools richtig favorisieren ließ, nicht von Haus aus. Die Demonstration auf der Website zeigte uns zwar, dass es prinzipiell möglich ist, aber wie wir in den Internetforen herausfanden, versuchten schon mehrere Personen vor uns erfolglos, Image Based Lighting zu verwenden.
Das Ursprungs-Kompositions-File, das dem HDR-Car-Demo auf der Website zugrunde lag, ist offenbar ein allgemein gesuchtes Objekt der Begierde. Offenbar wurden hierbei eigene Shader über die Virtools-Shader-Language-Schnittstelle (VSL) direkt auf der Grafikkarte programmiert.
Das sprengte nun aber definitiv unseren Zeitrahmen und bewegte sich weit jenseits dessen, was wir an Detailtiefe an den Tag legen wollten. Also griffen wir schweren Herzens auf "herkömmliche" Lichtquellen zurück, um die Lichtsituation des Raumes nachzustellen (siehe 3D-Modllierung &arr; Virtools).

Referenzobjekte und Relationen

Es gibt häufig den Fall, dass eine bestimmte Berechnung in Relation zu einem anderen 3D-Entity ausgeführt werden muss. Das beste Beispiel hierfür ist die Positionierung der VRPN-Kamera im virtuellen Raum. Um die ankommenden Koordinaten korrekt in Relation zur Tischmitte zu interpretieren, könnte man die Tischplatte als Referenz-Entity nehmen. Allerdings ist nicht garantiert dass der Mittelpunkt, also der "Origin" eines Entitys immer genau in der Mitte liegt. Außerdem würde der Referenzpunkt verlorengehen, wenn man das Tisch-Objekt durch ein neues, angepasstes und anders modelliertes ersetzt, was in der Entwicklungsphase öfters vorkam. Die elegante Lösung ist, dass man sich ein 3D-Frame, also ein unsichtbares Dummy-Objekt, das praktisch nur aus einem Origin besteht, erstellt und als Referenz benutzt. Dabei ist nicht nur die Position, sondern auch die Rotation des 3D-Frames ausschlaggebend, da die "Zeigerichtung" der Achsen genau definiert ist und eine andere Rotationslage dementsprechend "gekippte" Kamerabewegungen zur Folge hätte. Beim Experimentieren mit den beweglichen Objekten (Kaffeetasse, Ohmlogo und Toolboxlogo) stellten wir fest, dass die Rotationslage nicht stimmte, wenn man den dazugehörigen Marker ins Bild hielt: Die Kaffetasse lag flach und die Logos standen senkrecht in der Tischplatte.

Referntial-3D-Frames für Tisch und Objekte

Abhilfe verschaffte hier der selbe Ansatz: Wir erstellten ein 3D-Frame und wiesen dem Objekt dieses Frame als sein "Parent" zu. Dies geschieht über den Building Block "Set Parent" bei Kompositionsstart. Ab dann folgt das Objekt allen Transformationen, die an seinem Referenzobjekt ausgeführt werden. Ein nützlicher Hinweis für solche Init-Scripte ist, dass man sie auch manuell jederzeit mit der Tastenkombination Alt-X ausführen kann.

Building Block "Set Parent"

Environment Mapping

CubeMap in der CubeCross-Darstellung
Die Enttäuschung, dass wir das Panoramabild nicht für Image-Based Lighting benutzen konnten, war sehr groß, aber wir wollten das Umgebungsbild wenigstens auf irgendeine Art und Weise einbauen. Eine Environment-Map ist ein 3-dimensionales Umgebungsbild, das z.B. in vielen 3D-Spielen meist in Form eines Himmels als Hintergrundbild benutzt wird. Das Darstellungsformat kann entweder ein Panoramabild sein oder aber eine CubeMap, d.h. eine Ansammlung von 6 quadratischen Texturen, die als Würfelseiten zu interpretieren sind. Wie wir auch erst nach langen rätselhaften Eskapaden feststellen mussten kann Virtools nur mit CubeMaps umgehen. Wir mussten also unser Raum-Panorama in eine CubeMap konvertieren. Dies geschieht, wie wir nach langer Recherche herausfanden, mit Hilfe der mittlerweile frei erhältlichen Software HDR-Shop und dem kostenlosen CubeMap-Generator von ATI. Mit HDR-Shop berechnet man aus dem Panoramabild ein Cube Cross, also im Prinzip einen aufgeschnittenen und entfalteten Würfel. Dieses Bild kann man in den ATI-Cube-Map-Generator importieren und die fertige CubeMap im erforderlichen .dds-Format exportieren. Im Cubemapgenerator können dann noch letzte Modifikationen am Pixelformat vorgenommen werden.
Konvertierungsdialog in HDR Shop
Panorama-Reflektion auf einer Metallkugel: Materialeffekt "TexGen with Referential"
Nun befindet sich also das Panoramabild im benutzbaren DDS-Format und kann in Virtools importiert werden. Zunächst wollten wir den Raum auf einer Metallkugel reflektieren lassen. Dies geschieht über den Materialeffekt "TexGen with Referential" im Modus "CubeMap Reflect". Als Referential trägt man die betrachtende Kamera ein, so dass aus jedem Blickwinkel die Reflektionen korrekt dargestellt werden. Außerdem ließen wir die Umgebungs-CubeMap auf den Fensterscheiben und halbtransparent auf der Tischplatte reflektieren. Das Vorgehen ist hierbei analog.

Antialiasing

In Virtools realisiert man das, indem man eine globale Variable der Render Engine auf die Anzahl der Antialiasing-Schritte setzt. Dies geht über Rechtsklick im Schematic-View eines beliebigen Scripts, [Import From Variable Manager] → [CK2_3D] → [Antialias].

Object Keep On Floor

Damit ein Objekt tatsächlich auf dem Tisch liegen bleibt, muss die berechnete Entfernung des Objektmarkers von der Kamera genau mit dem Wert übereinstimmen, der für die Entfernung von der Kamera vom Tisch ermittelt wird. Diese beiden Werte können durchaus variieren. Die Folge davon ist, dass die Objekte zwischendurch unter der Tischplatte verschwinden bzw. vom Tisch abheben können. Um dem Abhilfe zu verschaffen, wurden allen Einzelobjekten der Building-Block "Object Keep On Floor" zugewiesen und die Tischplatte via Object Setup mit dem Floor-Attribut ausgestattet. Damit nahmen wir zwar die Möglichkeit, Objekte wirklich vom Tisch "aufzuheben", aber zugunsten einer stabiler wirkenden Darstellung nahmen wir das gerne in Kauf. "Object Keep On Floor" ist einer der Building Blocks, die sich selbst loopen müssen, um bei jedem Frame erneut ausgeführt zu werden.

"Object Keep On Floor" hält das Referenz-3D-Frame des Ohmlogos auf dem Tisch

Schattenwurf von Objekten

Nur 3D-Objekte aus einem Stück korrekte Schatten werfen. Dies fiel beim Einbau des Tisches auf, bei dem die Beine und die Tischplatte jeweils einen Schatten warfen als würde das andere Objekt nicht existieren. Danach wurden die beiden Schatten von Beinen und Platte überlagert, was zu einem äußerst seltsamen Anblick führte. Es ist immer zu bedenken, dass Materialien von Objekten, die hinzugefügt werden, gleichnamige Materialien in der Komposition überschreiben, d.h. löschen.
Der entscheidende Schritt, dass jedem Objekt, das einen Schatten werfen soll, das Attribut "Shadow Stencil Caster" und jedem Objekt, auf dem Schatten zu sehen sein sollen, das Attribut "Shadow Caster Receiver", zugewiesen werden müssen.
Lichtquellen und Objekten muss also quasi konkret mitgeteilt werden, dass sie Schatten "verursachen" oder "empfangen" bzw. werfen.

ShadowStencil Building Block, der Lichtquellen als Schattenwerfer deklariert

Grafische Programmierung

Der geneigte EyesWeb-Benutzer ist mit dem Grundkonzept der grafischen Programmierung bereits vertraut: Es wird kein Programmcode in Textform erstellt, der die Kenntnis einer Syntax voraussetzt, sondern vielmehr werden einzelne Funktionsblöcke über Parameter- und Triggerleitungen miteinander zur Interaktion gebracht. Die dabei entstehenden Konstrukte werden "Scripts" genannt und werden für gewöhnlich beim Start der Komposition ausgeführt.
Die Scripts sind immer einem bestimmten Element (z.B. einem 3DEntity, einer Kamera, einer Lichtquelle etc. oder aber auch dem gesamten Level) zugeordnet. Die Leseweise ist strikt von links nach rechts. Vom Einstiegspunkt aus verlaufen die schwarz durchgezogenen Triggerleitungen in die Aktivierungs-Eingänge auf der linken Kante der "Building Blocks". Je nachdem, über welchen Eingang der Block aktiviert wird, verhält er sich anders und triggert gegebenenfalls einen seiner Ausgänge auf der rechten Kante, an denen ihrerseits wieder weitere Trigger-Leitungen zu Unterkonstrukten führen können. Gewissermaßen ist hiermit die "if"-Anweisung abgedeckt.
Die Zahl über jeder Triggerleitung markiert die Verzögerung dieser Verbindung in Frames. 0 bedeutet sofort, 1 bedeutet, dass der Endpunkt erst bei Eintritt ins nächste Frame der Engine aktiviert wird. Daneben existieren die blau gestrichelten Parameterleitungen, die von Parameterausgängen an den Unterkanten der Blöcke bzw. von Konstanten hin zu den Parametereingängen an den Block-Oberkanten führen. Dabei sind wie bei der "herkömmlichen" Programmierung auch die Datentypen zu beachten. Typkonvertierungen geschehen (falls benötigt) implizit und werden durch Grünfärbung der Leitungen verdeutlicht. So ist es z.B. möglich, von einem Vektor-Datentyp die Einzelparameter als Integers oder Floats zu extrahieren. In den meisten Fällen bewegt man sich allerdings im herkömmlichen Float- oder Integer-Format. Zuletzt bleiben noch die manuell einstellbaren Prioritäten der einzelnen Building Blocks zu erwähnen. Bei manchen Building Blocks ist es notwendig, die Priorisierung der Abarbeitung manuell einzustellen, im Normalfall ist es aber unnötig, daran etwas zu verändern.

Das Trackingscript und seine Bugs

das der VRPN-Kamera zugeordnete Tracking-Skript
Für das Projekt wurde die grafische Programmierung in erster Linie für einen Zweck wichtig:

Die Koordinaten sollten vom Virtools-internen VRPN-Client empfangen, ausgewertet und entsprechend der "Station"-Nummer des VRPN-Protokolls an die betreffenden Objekte in der Szene weitergeleitet werden. Der Grundaufbau des VRPN-Parsings war in einer mitgelieferten Komposition zur Kalibrierung von Eingabedevices bereits enthalten. Die Verknüpfung der Koordinatenstreams mit der entsprechenden Kamera bzw. dem entsprechenden 3D-Objekt wurde dann von uns nachträglich hinzugefügt. Außerdem habe ich einen Algorithmus entworfen, um eine Meldung und eine Warnung anzuzeigen, sobald der Koordinatenstrom für die Kamerakoordinaten eine bestimmte Zeit lang abreißt.

Bei Einstieg in das Script wird zunächst die VRPN-Kamera ("Besitzer" des gesamten Scripts) als die aktive Kamera definiert ("Set As Active Camera"). Außerdem wird ein Display-Font initialisiert und mit einem Textausgabeframe verknüpft, was für die spätere Fehlermeldungsausgabe wichtig wird (siehe roter Kasten). Schließlich beginnt der VRPN-relevante Funktionsteil: Mit "VRPN Settings" werden die VRPlayer-Settings in Form der Datei VRPack.cfg (Beschreibung im nächsten Abschnitt) geladen und anschließend wird mittels "VRPN-Init" das VRPN-Subsystem initialisiert.
"VRPN-Init" besitzt 2 Ausgänge: Der obere wird aktiviert, falls die Initialisierung erfolgreich verlief, der untere ist dementsprechend die Fehler-Rückfall-Klasse und endet in einem Loop. Der Grund dafür war uns nicht klar ersichtlich, aber derartige Loopkonstruktionen sind bei manchen Building-Blocks zur korrekten Funktion nötig. War die Initialisierung erfolgreich, wird die Aktivierungskette mittels eines Nop-Blocks aufgetrennt: Nop hat keine Funktion und leitet nur die Aktivierung weiter, wenn er aktiviert wird. Nop dient deshalb als praktische Vorschaltstufe, falls mehrere Prozessaktivierungen an denselben Ausgang gehängt werden sollen. Will man beispielsweise die kompletten Objektparsings im türkisen Block deaktivieren, muss man nur einen einzigen Nop-Block "abstecken".
Es folgt also die eigentliche Parsingarbeit: Der Building-Block "VRPN Tracker" lauscht am durch "VRPN Init" definierten VRPN-Server und gibt die Informationen, die auf seiner ID ankommen, bereits geparst als Positions-Vektor und Richtungs-Quaternion aus. Es besteht ein "VRPN Tracker" für jede existierende VRPN-Kanal-ID, also für jedes zu steuernde Objekt: Eine Kamera, eine Kaffeetasse, ein Ohm-Logo und ein Toolboxlogo. Die Objektkoordinatenströme (türkiser Kasten) sind die unveränderten Koordinaten aus ARToolkitPlus, die in Relation zur betrachtenden Kamera zu deuten sind (siehe Parameter VRPN Kamera, der als Referantial-Quelle eingesetzt wird). Sobald ein VRPN-Tracker also auf seiner ID Daten empfängt, wird der entsprechende Block aktiviert und gibt die Aktivierung über seinen Triggerausgang weiter an die Blöcke "Set Position" und "Set Quaternion Orientation", die ihrerseits die Position und Orientierung des angesprochenen Objekts mit den aktuell zur Verfügung stehenden Koordinaten updaten. Der Positionsvektor wird bei allen Objekten um den Faktor 10 skaliert (siehe Block "Multiplication"), da sonst die Änderungen zu gering im Verhältnis zur virtuellen Weltgröße ausfallen würden.
Analog funktioniert dies bei den "Weltkoordinaten" auf ID 1 (gelber Kasten). Der Koordinatenstrom auf ID 1 stammt von dem Multimarkersetup und wurde in Studierstube vorher invers transformiert, so dass sich genau die Kameraposition in Relation zur Tischmitte ergibt. Entsprechend muss die Positionierung der Kamera in Virtools auch in Relation zur virtuellen Tischmitte geschehen (sichtbar am Parameter "Referential Tischref"), da sonst die Mitte der virtuellen Welt als Nullpunkt gewählt würde, und die liegt in unserem Fall in einer Ecke des Raumes auf dem Boden.
Die elementaren Fähigkeiten wurden nun implementiert: Nun könnten bereits die Kamera bewegt und die Objekte korrekt ausgerichtet werden. Hier tritt aber leider ein unschöner Bug zu Tage, dessen Ursprung uns zwar genau bekannt ist, aber dessen Lösung unsere Fähigkeiten in der grafischen Programmierung weit überstieg: Wie erwähnt werden die Objekt-Streams und der Kamerasteuerungs-Stream auf separaten IDs übertragen und beim Auswerten die Objekte relativ zur Kamera interpretiert. Bei Systemstart ist z.B. nur ein Marker des Multimarker-Setups im Blickfeld der Kamera, so dass sich nur die Virtools-VRPN-Kamera bewegt. Alle anderen IDs in Studierstube übertragen NULL, sodass in Virtools die Objekte still auf dem Tisch liegen bleiben.
Kommt nun der erste bewegliche Objektmarker ins Bild, wird der Koordinatenstrom auf der entsprechenden ID gestartet und in Virtools bewegt sich das Objekt korrekt auf dem Tisch. Das Problem tritt allerdings dann auf, wenn dieser bewegliche Objektmarker wieder aus dem Blickfeld der Kamera genommen wird. Anstatt wieder NULL zu übertragen überträgt Studierstube ständig den letzten erfassten Koordinaten-Satz. Die Folge in Virtools ist fatal: Das entsprechende Objekt friert in konstanter Position relativ zur Kamera ein, weil ja die Position offenbar immer konstant bleibt, und so schwebt das Objekt über dem Tisch, wenn die Kamera weiter nach oben blickt.
Ein Algorithmus für dieses Problem wäre, die "Set Position"- und die "Set Quaternion Orientation"-Operationen für alle Objekte nur dann auszuführen, wenn der aktuelle Koordinatensatz sich vom vorherigen unterscheidet. Um den jeweils vorherigen Datensatz zu speichern könnte man auf Virtools-Arrays zurückgreifen. Am Abend vor der Projektpräsentation konnten noch geringe Fortschritte damit erzielt werden, wirklich fehlerfrei funktionierte es aber bis zum Schluss nicht.
Der letzte noch zu erwähnende Funktionsteil des Tracking-Scripts erfüllt den Zweck, eine Warnung einzublenden, sobald der Kamera-Koordinatenstrom abgerissen ist, um dem Benutzer Auskunft über die derzeitige Systemstabilität zu erteilen. Was relativ simpel klingt ist in der grafischen Programmierung mit einigen Tricks und Kniffen verbunden. Betrachtet man sich den Triggerausgang des "VRPN Tracker"-Blocks für die Kamera im gelben Kasten, entdeckt man 4 Triggerleitungen: Eine davon sorgt – wie bekannt – für das Setzen von Position und Orientierung der Kamera, sobald eine Koordinate ankommt. Die zweite führt in den ersten Eingang eines "Parameter Selector"-Blocks, der daraufhin den ersten seiner beiden Parameter-Konstanten (String okstatus mit Inhalt "") an das eingangs erläuterte Textanzeigefenster sendet. Es wird bei jeder Koordinate also ein leerer String – also nichts – als Text angezeigt. Die dritte Leitung führt in den Block "Hide". Dieser Block hat als Parameter ein Symbol, das einen Koordinatenaussetzer bildlich verdeutlichen soll. Kommt also eine Koordinate an, wird dieses Symbol ausgeblendet.
Die vierte Leitung ist nun der Trick bei der Sache: Sie führt zunächst in den Block "Stop & Go", der wie eine Art logisches "NOT" zu verstehen ist: Wenn er aktiviert wird, gibt er KEINE Aktivierung aus. Wird er aber NICHT aktiviert, gibt er mit jedem Frame Aktivierungen aus. Hiermit ist also die grundsätzliche Bedingungs-Abfrage bereits realisiert: Immer wenn ein Koordinatensatz ankommt, werden Fehlermeldung und Symbol ausgeblendet. "Stop & Go" sendet dementsprechend in jedem Frame Aktivierungen, wenn keine Koordinate während des aktuellen Frames ankam. Würde man also die Fehlermeldungseinblendung direkt an "Stop & Go" koppeln, würde die Fehlermeldung auch bei normalem Betrieb ständig aufflackern, weil die Framerate weit höher ist als die Frequenz, in der Koordinaten eintreffen.
Um dieses Problem zu beseitigen wird einen Counter hochgezählt: Erst wenn in 10 aufeinander folgenden Frames keine Koordinate empfangen, hat der Block "Counter" bis zum Maximalwert gezählt. Beim 11. Frame wird dann das Fehler-Symbol eingeblendet und via "Parameter Select" der zweite Parameter keinstream (Inhalt "Kein Stream") angezeigt.

Die VRPlayer-Komponente

Alle Virtual-Reality-Funktionalitäten sind in der VRPlayer-Komponente zusammengefasst, die z.B. auch eine eigene Lizenz benötigt. Es können also nicht ohne Weiteres Kompositionen auf mehreren Maschinen geclustert oder auf mehreren Displays dargestellt werden. Die Virtools- Authoring-Umgebung unterstützt aber immerhin den für uns relevanten VRPN-Teil.
Zur Konfiguration des VRPlayer-Subsystems der momentanen Komposition ist das Config-File VRPack.cfg zu Rate zu ziehen, das im selben Verzeichnis wie die Komposition liegen muss:

$include C:\Programme\Virtools\Virtools 4.0\VRPack\SystemConfig\VRPackMaster.cfg

Es wird also einfach nur die globale Config-Datei VRPackMaster.cfg referenziert. Man könnte in die VRPack.cfg aber auch kompositionsspezifische Änderungen eintragen. Die VRPackMaster.cfg macht im Prinzip das Gleiche erneut:

$include VRRemote.cfg
$include VRDevice.cfg
$include VRDisplay.cfg
$include VRDistrib.cfg
$include VRStereo.cfg

In unserem Fall ist vor allem die VRDevice.cfg von Bedeutung (gekürzte Fassung):

neutralPosition 0 0 0
axisPermute 0 1 2
axisSign 1 1 -1
#trackerScale 1
#neutralQuaternion 0.5 0.5 -0.5 0.5
 
vrpnTracker trackername@localhost:3883

Hier werden also prinzipielle Einstellungen zum vorliegenden VR-Device (in diesem Fall der VRPN-Tracker) vorgenommen: Mittels neutralPosition kann ein Offset definiert werden. axisPermute und axisSign ermöglichen Vertauschung und Inversion der 3 Koordinatenachsen. Zusammen mit der Konfiguration der Vorverarbeitung der Koordinaten in Studierstube wurde mit der Konfiguration dieser beiden Parameter vermutlich ein Viertel der gesamten Projektlaufzeit verbracht, da eine Fehlkonfiguration – so wie sie im Werkszustand vorlag – völlig unnachvollziehbare Auswirkungen auf das Verhalten der angesteuerten Objekte in der Szene hatte und wir dadurch sehr lange auf eine falsche Fährte gelockt wurden.
Die Bedeutung von neutralQuaternion ist analog zu neutralPosition. Mittels trackerScale lassen sich die Koordinaten global skalieren Schließlich bestimmt vrpnTracker, wo im Netzwerk der VRPN-Server zu finden ist.

Prinzipielle Tipps im Umgang mit Virtools

Virtools ist sehr mächtig und komplex. Es sind zwar viele Tendenzen vorhanden, das Handling so intuitiv wie möglich zu gestalten (z.B. funktionieren viele Operationen ausschließlich via Drag&Drop), aber dennoch kommt man nicht um das Lesen der Bedienungsanleitung herum. Manche sehr nützliche Funktionen, von deren Existenz man vorher nichts wusste, verbesserten den Workflow immens. Das gilt ja nun grundsätzlich für alle Programme, aber gerade bei Virtools, das eigentlich so erscheint, als könnte es sich selbst erklären, ist es besonders folgenschwer, die Anleitung nicht gelesen zu haben.
Es bestehen aber auch einige Ungereimtheiten auf technischer Seite: Manche Building-Blocks funktionieren erst, wenn man die Komposition abgespeichert und neu geladen hat, das manuelle Eintragen von Objekt-Koordinaten kann schonmal zum unwiderruflichen Verschwinden des Objekts führen und beim Import von Fremdformaten kommt es teilweise zu Konversionsfehlern, so dass diverse Texturen einfach türkis dargestellt werden, obwohl sie grau sind.
Trotz allem ist Virtools ein sehr empfehlenswertes Werkzeug, das einem unwahrscheinlich viele Funktionalitäten zur Verfügung stellt und sehr gut erweiterbar ist.