... | ... | @@ -5,14 +5,14 @@ Zu Beginn des Projekts wurde folgender Zeitplan aufgestellt: |
|
|
|
|
|

|
|
|
|
|
|
Zuerst sollten die Grundlagen für die Umsetzung geschaffen werden: Ein extra Fenster und Unterstützung für das glTF-Format. Danach waren zwei Blöcke geplant in denen inkrementell die Funktionaliät der Konfiguration hinzugefügt werden sollte sowie die Benutzungsoberfläche und die Modelle erstellt werden sollten. Am Schluss sollte die Exportierfunktion implementiert werden.
|
|
|
Zuerst sollten die Grundlagen für die Umsetzung geschaffen werden: Ein extra Fenster und Unterstützung für das glTF-Format. Danach waren zwei Blöcke geplant in denen inkrementell die Funktionalität der Konfiguration hinzugefügt werden sollte sowie die Benutzungsoberfläche und die Modelle erstellt werden sollten. Am Schluss sollte die Exportierfunktion implementiert werden.
|
|
|
|
|
|
Während sich manche Teile etwas nach hinten verschoben, konnte der Zeitplan einigermaßen eingehalten werden. Einzig die Erstellung des UIs wurde etwasspäter als geplant begonnen, da die Einarbeitung in CSS und HTML aufwändiger als gedacht war.
|
|
|
Während sich manche Teile etwas nach hinten verschoben, konnte der Zeitplan einigermaßen eingehalten werden. Einzig die Erstellung des UIs wurde später als geplant begonnen, da die Einarbeitung in CSS und HTML aufwändiger als gedacht war.
|
|
|
|
|
|
Die Einzige Funktion, die aus Zeitgründen nicht implementiert werden konnte, war der Export des Avatars als glTF-Datei. Der Export als Profilbild, sowie als Konfigurationsdatei ist jedoch vorhanden.
|
|
|
|
|
|
# Konzept
|
|
|
Zu Beginn des Projekts wurden einige Konzeptzeichnungen erstellt und erstest Feedback eingeholt.
|
|
|
Zu Beginn des Projekts wurden einige Konzeptzeichnungen erstellt und erstes Feedback eingeholt.
|
|
|
|
|
|
## UI Zeichnungen
|
|
|
|
... | ... | @@ -52,11 +52,11 @@ Der Avatarkonfigurator ist, wie der 3D-Viewer, eine [ThreeJS](https://threejs.or |
|
|
|
|
|
Da ein IFrame ein eigenes Dokument darstellt muss mit Hilfe von `inject*` Funktionen dem Konfigurator der eigene Nutzer, der aktuelle Raum und der SocketIO-Socket übergeben werden.
|
|
|
|
|
|
Ursrünglich war geplant, den Server nicht zu verändern um Merge-Konflikten vorzubeuen. Im Laufe der Zeit zeigte sich aber, dass dies nicht möglich war, da SocketIO auf eine Client-Server Struktur setzt und daher Clients nicht direkt miteinander kommunizieren können.
|
|
|
Ursprünglich war geplant, den Server nicht zu verändern um Merge-Konflikten vorzubeugen. Im Laufe der Zeit zeigte sich aber, dass dies nicht möglich war, da SocketIO auf eine Client-Server Struktur setzt und daher Clients nicht direkt miteinander kommunizieren können.
|
|
|
|
|
|
## Laden des Avatar Configurators
|
|
|
## Laden des Avatarkonfigurators
|
|
|
|
|
|
Um den Avatar Configurator anzuzeigen wird, wie beim 3D Viewer ein IFrame Objekt genutzt. Dieses lädt beim Aufruf des Konfigurators in Accelerator die entsprechende Hauptseite des Konfigurators: `public/AvatarConfigurator/index.html`
|
|
|
Um den Avatarkonfigurator anzuzeigen wird, wie beim 3D Viewer ein IFrame Objekt genutzt. Dieses lädt beim Aufruf des Konfigurators in Accelerator die entsprechende Hauptseite des Konfigurators: `public/AvatarConfigurator/index.html`
|
|
|
|
|
|

|
|
|
|
... | ... | @@ -67,7 +67,7 @@ Um dem Konfigurator mitzuteilen, wer der eigene Nutzer ist, in welchem Raum er s |
|
|
### main.js
|
|
|
Bindet Methoden für das Einfügen des eigenen Nutzers, des eigenen Raumes und des SocketIO-Sockets an das DOM `window` Objekt. Diese werden dann von `uiEvents.js` beim Laden des Konfigurators mit den entsprechenden Parametern aufgerufen.
|
|
|
|
|
|
Ausserdem fügt main.js Avatare für bereits vorhandene Client im Raum hinzu.
|
|
|
Außerdem fügt main.js Avatare für bereits vorhandene Clients im Raum hinzu.
|
|
|
|
|
|
### Rendering/Rendering.js
|
|
|
Übernimmt die Initialisierung von ThreeJS und das Rendering. Dazu zählen:
|
... | ... | @@ -79,7 +79,7 @@ Ausserdem fügt main.js Avatare für bereits vorhandene Client im Raum hinzu. |
|
|
Übernimmt den Down- und Upload von Avatarkonfigurationen.
|
|
|
|
|
|
### UI/Editing.js
|
|
|
Übernimmt die Körperteilauswahl und deren Färung. Reagiert auf click-Events der Auswahl für die Körperteile und deren Farben.
|
|
|
Übernimmt die Körperteilauswahl und deren Färbung. Reagiert auf click-Events der Auswahl für die Körperteile und deren Farben.
|
|
|
|
|
|
### UI/FocusManagement.js
|
|
|
Übernimmt das Wechseln zwischen den verschiedenen Avataren.
|
... | ... | @@ -91,7 +91,7 @@ Ausserdem fügt main.js Avatare für bereits vorhandene Client im Raum hinzu. |
|
|
Übernimmt das Verwalten des eigenen Nutzers.
|
|
|
|
|
|
### AvatarManagement.js
|
|
|
Verwaltet die Avatare. Fügt neue Avatare für neue Clients hinzu und löscht Avatare für Clients, die den Raum verlassen. Hier wird auch die Körperteil- und Farbverwaltung der Avatare realisiert. Sendet ausserdem entsprechende Netzwerkupdates via SocketHandling.js
|
|
|
Verwaltet die Avatare. Fügt neue Avatare für neue Clients hinzu und löscht Avatare für Clients, die den Raum verlassen. Hier wird auch die Körperteil- und Farbverwaltung der Avatare realisiert. Sendet außerdem entsprechende Netzwerkupdates via SocketHandling.js
|
|
|
|
|
|
### SocketHandling.js
|
|
|
Übernimmt das Senden und Empfangen von SocketIO-Events. Sendet auch die Nachricht um das Profilbild zu aktualisieren.
|
... | ... | @@ -109,7 +109,7 @@ Alle SocketIO-Events werden in window DOM Events umgewandelt. Dadurch muss kein |
|
|
|
|
|
## Kommunikation zwischen Clients und mit dem Server
|
|
|
|
|
|
Zur Kommunkation wirden drei SocketIO Events und zwei expressjs-Routen verwendet.
|
|
|
Zur Kommunikation werden drei SocketIO Events und zwei expressjs-Routen verwendet.
|
|
|
|
|
|
| Event | Ausgelöst von | Behandelt in |
|
|
|
|-------|---------------|--------------|
|
... | ... | @@ -117,7 +117,7 @@ Zur Kommunkation wirden drei SocketIO Events und zwei expressjs-Routen verwendet |
|
|
| removePeer | server.js | SocketHandling.js |
|
|
|
| avatarConfiguratorMessage | SocketHandling.js | SocketHandling.js |
|
|
|
|
|
|
`addPeer` und `removePeer` sind Events die vom Server gesendet werden, sobald ein neuer Teilnehmer einen Raum betritt bzw. verlässt. `avatarConfiguratorMessage` ist ein Meta-Event, das zur Kommunikation der Konfiguratoren untereinander verwendet wird. Innerhalb von `avatarConfiguratorMessage` wird das eigentliche Event spezifiziert. Dieser Ansatz wurde gewählt, um möglichst wenig am Server-Code ändern zu müssen, da der Server jedliche Events weiterleiten muss und Clients nicht direkt miteinander kommunizieren sollten.
|
|
|
`addPeer` und `removePeer` sind Events die vom Server gesendet werden, sobald ein neuer Teilnehmer einen Raum betritt bzw. verlässt. `avatarConfiguratorMessage` ist ein Meta-Event, das zur Kommunikation der Konfiguratoren untereinander verwendet wird. Innerhalb von `avatarConfiguratorMessage` wird das eigentliche Event spezifiziert. Dieser Ansatz wurde gewählt, um möglichst wenig am Server-Code ändern zu müssen, da der Server jegliche Events weiterleiten muss und Clients nicht direkt miteinander kommunizieren sollten.
|
|
|
|
|
|
| Route | Verb | Aufgerufen von | Request behandelt in | Antwort behandelt in |
|
|
|
|-------|------|--------|--------------|-------------|
|
... | ... | @@ -126,16 +126,16 @@ Zur Kommunkation wirden drei SocketIO Events und zwei expressjs-Routen verwendet |
|
|
|
|
|
Die Route `/rooms` wurde dem Server hinzugefügt, um alle Räume abfragen zu können. Dies ist nötig um auch Teilnehmer die vor einem anderen Client bereits im Raum waren, im Konfigurator anzeigen zu können.
|
|
|
|
|
|
Die bereits exisitierende Route `/upload` ist unter Anderem für das Setzen des eigenen Profilbildes verantwortlich. Um nicht nur mit Bild*dateien*, sondern auch Bild*daten* in Form von einer base64 enkodierten DataURLs umgehen zu können, wurde der Server um die entsprechende Funktion erweitert.
|
|
|
Die bereits existierende Route `/upload` ist unter Anderem für das Setzen des eigenen Profilbildes verantwortlich. Um nicht nur mit Bild*dateien*, sondern auch Bild*daten* in Form von einer base64 enkodierten DataURLs umgehen zu können, wurde der Server um die entsprechende Funktion erweitert.
|
|
|
|
|
|
## Zustandsverwaltung der Avatare auf dem Server
|
|
|
|
|
|
Um die Zustände von bereits exisitierenden Avataren an neu hinzugekommene Clients schicken zu können, wurde im Server dem `allRoomAttr` für jeden Raum ein neues Objekt `avatarStates` hinzugefügt. Diese Zustände werden mit jedem entsprechenden `avatarConfiguratorMessage`-Event aktualisiert. Verlässt ein Client einen Raum wird auch dessen Avatarzustand gelöscht.
|
|
|
Um die Zustände von bereits existierenden Avataren an neu hinzugekommene Clients schicken zu können, wurde im Server dem `allRoomAttr` für jeden Raum ein neues Objekt `avatarStates` hinzugefügt. Diese Zustände werden mit jedem entsprechenden `avatarConfiguratorMessage`-Event aktualisiert. Verlässt ein Client einen Raum wird auch dessen Avatarzustand gelöscht.
|
|
|
|
|
|
## Anlaufstellen für Veränderungen (Ich will...)
|
|
|
|
|
|
### Einen neuen Button in das UI einfügen
|
|
|
Das UI wird in `index.html` definiert. Das Styling bezieht sich immer auf absolute Koordinaten, da auch das Fenster des IFrames eine feste Größe hat. Auf Events wird in den `UI/*` Modulen reagiert. Hier werden am Anfang vom Code immer die ID's der UI-Elemente definiert, welche dann mit `document.querySelector` abgerufen werden und mit `addEventListener` auf ein Event reagiert werden kann.
|
|
|
Das UI wird in `index.html` definiert. Das Styling bezieht sich immer auf absolute Koordinaten, da auch das Fenster des IFrames eine feste Größe hat. Auf Events wird in den `UI/*` Modulen reagiert. Hier werden am Anfang vom Code immer die IDs der UI-Elemente definiert, welche dann mit `document.querySelector` abgerufen werden und mit `addEventListener` auf ein Event reagiert werden kann.
|
|
|
|
|
|
### Die Darstellung der Szene ändern (Kamera, Beleuchtung)
|
|
|
Die Darstellung und die Hauptkamera wird in `Rendering.js` definiert.
|
... | ... | @@ -144,10 +144,10 @@ Die Darstellung und die Hauptkamera wird in `Rendering.js` definiert. |
|
|
Dies wird von `UI/ProfilePicHandling` übernommen. Dazu definiert das Modul eine eigene Kamera, mit der dann nur ein einzelner Frame gerendert wird. Die Bilddaten werden in Form einer DataURL mit PNG-Encoding weiterverwendet.
|
|
|
|
|
|
### Die Materials der 3D Objekte verändern
|
|
|
Alle Objekte werden von `AvatarManagement.js` verwaltet. Wichtig ist, dass jedesmal, wenn ein neues Objekt hinzugefügt wird, die Materials geklont werden, da sonst mehrere Avatare auf das gleiche Event reagieren würden. Dies geschieht in `addUser` und `updateAvatarFromStateIndices`.
|
|
|
Alle Objekte werden von `AvatarManagement.js` verwaltet. Wichtig ist, dass jedes mal, wenn ein neues Objekt hinzugefügt wird, die Materials geklont werden, da sonst mehrere Avatare auf das gleiche Event reagieren würden. Dies geschieht in `addUser` und `updateAvatarFromStateIndices`.
|
|
|
|
|
|
### Ein neues Körperteil hinzufügen oder ein altes verändern
|
|
|
Alle 3D Modelle sind in `public/AvatarConfigurator/Models` im glTF-Format gespeichert. **Es wird auch nur glTF als Format unterstützt!** Welche Modelle tatsächlich geladen werden, wird von `public/AvatarConfigurator/configuration.json` bestimmt. Wichtig ist, dass das Objekt `configuration.baseModelAttachments` beim Aufruf von `AvatarManagement.initialize` gelöscht wird. Dieses Vorgehen wurde gewählt, damit die Struktur von `configuration.json` direkt mit der Struktur von `AvatarManagement.models` übereinstimmt. Es können in den einzelnen Kategorieen also beliebig Modelle hinzugefügt, verändert oder entfernt werden. Wird allerdings die Struktur von `configuration.json` verändert, muss dies auch in `AvatarManagement` beachtet werden.
|
|
|
Alle 3D Modelle sind in `public/AvatarConfigurator/Models` im glTF-Format gespeichert. **Es wird auch nur glTF als Format unterstützt!** Welche Modelle tatsächlich geladen werden, wird von `public/AvatarConfigurator/configuration.json` bestimmt. Wichtig ist, dass das Objekt `configuration.baseModelAttachments` beim Aufruf von `AvatarManagement.initialize` gelöscht wird. Dieses Vorgehen wurde gewählt, damit die Struktur von `configuration.json` direkt mit der Struktur von `AvatarManagement.models` übereinstimmt. Es können in den einzelnen Kategorien also beliebig Modelle hinzugefügt, verändert oder entfernt werden. Wird allerdings die Struktur von `configuration.json` verändert, muss dies auch in `AvatarManagement` beachtet werden.
|
|
|
|
|
|
### Eine neue Körperteilkategorie hinzufügen
|
|
|
Das Zuteilen der Körperteile ist indexbasiert. Will man eine neue Kategorie einfügen, so muss dies in `AvatarManagement` and folgenden Stellen geschehen:
|
... | ... | @@ -163,5 +163,4 @@ Zugleich muss auch die Struktur von `public/AvatarConfigurator/configuration.jso |
|
|
# Evaluation
|
|
|
|
|
|
## Bekannte Probleme
|
|
|
* Die Konfiguratoransicht wird immer dann, wenn der Moderator eine andere Ansicht (Präsentation, Youtube etc.) wählt, ausgeblendet.
|
|
|
# Fazit |
|
|
\ No newline at end of file |