Als der Arbeitsstand weit genug war, um ein fertiges Datenset mit 3D-Koordinationsdaten aufzuzeigen, mussten wir natürlich überprüfen, wie sie qualitativ ausgegeben wurden. Hierfür eigneten sich gut die Creative Coding Frameworks Processing oder p5.js, um einen schnellen Sketch zu entwerfen, der die Daten ausplottet. Daher wurde sich für ein Webtool p5 entschieden, da man das einfach online einbetten und mit anderen Mitwirkenden teilen kann.

Hier wurde also die .CSV eingelesen, die aus dem 3D-baseline Tool ausgegeben worden ist. Um die irrelevanten Zahlen herauszufiltern wurde folgendes Array angewandt, dass die Iteratioinsrehenfolge im Code auf die relevanten Zahlenstellen in der .CSV verweist. Hier ist wieder zu beachten, dass eine Stelle für 3 Zahlen (x, y, z) steht:

var relevant = [
0, // Hüfte Mitte 0
1, // Hüfte Links 1
2, // Knie Links 2
3, // Fuß Links 3
/*4,5,*/
6, // Hüfte Rechts 4
7, // Knie Rechts 5
8, // Fuß Rechts 6
/*9,10,11,*/
12, // Torso 7
13, // Nacken 8
14, // Hals 9
15, // Kopf 10
/*,16*/
17, // Schulter Rechts 11
18, // Ellbogen Rechts 12
19, // Hand Rechts 13
/*20,21, 22, 23, 24,*/
25, // Schulter Links 14
26, // Ellbogen links 15
27 // Hand Links 16
/*,28*/];

Es ergeben sich also die genannten 17 Stellen, die vom Sketch durch iteriert werden. Die Iteration läuft in mehreren Schritten ab. Zunächst wurde festgelegt, dass die Framerate des Sketches 60 Bilder pro Sekunde beträgt, mit: frameRate(60);. Um dann in jedem Frame des Sketches auch nur einen Frame der CSV auszulesen, wurde eine Variable erstellt, die sich jeden Frame um 1 erhöht und sich automatisch zurücksetzt, wenn die Frames der CSV Datei zuende gehen. So kann das zum Beispiel aussehen:

var index = 0;
var pose = out[index].split(",");
if (index < out.length-1)
index ++;
else
index = 0;

Mit der Variablen pose wird also ein Array aufgemacht, das durch die split-Funktion und dem index-Input immer die Koordinationsdaten des aktuellen Frames beinhaltet. Das bietet die Basis, um diese Koordinaten dem 3D-Raum zuzuordnen. Ein simples Skelett der 3D-Bewegung ergibt sich nun durch den nächsten Schritt der Iteration, indem pro Frame alle Joints des Skeletts nacheinander platziert werden. Das wird mit einer for-Schleife gemacht, die das relevant-Array abtastet. Jede Stelle aus dem relevant array muss hier verdreifacht werden, um in dreier schritten von Joint zu Joint zu kommen. SO ist 0*3 = 0, es werden also die Stellen 0, 1, 2 für die x, y, z Positionen des ersten Joints angesprochen; 1*3 = 3 entspricht den Stellen 3, 4, 5 und so weiter:

for (j=0; j<relevant.length; j+=1)
{
  var x = parseFloat(pose[relevant[j]*3]);
  var y = parseFloat(pose[relevant[j]*3+1]);
  var z = parseFloat(pose[relevant[j]*3+2]);
  translate(x, y, z);
  sphere(jointsize);
}

So wird eine Kugel an die 3D-Position von jedem Joint gesetzt und es ergibt sich die Grundlage für gestalterische Experimente. Eine einfache Variante, um die Gestaltung der CSV-Ergebnisse schnell verständlich zu machen, sind Verbindungslinien, die sich von Joint zu Joint ziehen. So werden aus einzelnen schwebenden Kugeln schnell eine humanoide Form, die man verstehen kann. Dazu muss ein zweites Set x, y, z – Daten erstellt werden, um eine Linie zu zeichnen. Im folgenden Beispiel werden für die Joints des linken Beins (Stellen 1, 2, 3 im relevant-Array) eine Linie gezogen, die sie zum Joint verbindet, der im relevant Array eine Stelle zu vor kommt Daher relevant[j - 1]. Der Fuß wird also mit dem Knie, das Knie mit der linken Hüfte, und die linke Hüfte mit dem Root-Joint der Hüfte verbunden:

for (j=0; j<relevant.length; j+=1)
{
  var x = parseFloat(pose[relevant[j]*3]);
  var y = parseFloat(pose[relevant[j]*3+1]);
  var z = parseFloat(pose[relevant[j]*3+2]);

  if (j > 0 && j < 4) {
    var xl = parseFloat(pose[relevant[j - 1] * 3]);
    var yl = parseFloat(pose[relevant[j - 1] * 3 + 1]);
    var zl = parseFloat(pose[relevant[j - 1] * 3 + 2]);

    stroke(strokecolor);
    strokeWeight(strokeweight);
    line(x, y, z, xl, yl, zl);

  }

  sphere(jointsize);

}

Die Positionierung der Joints im Array erlaubt es leider nicht, immer mit j – 1 zu verbinden, daher sind einge if-Abfragen nötig, um die humaniode Figur zu erstellen:

j – 1: if (j > 0 && j < 4 ||
           j > 4 && j < 7 ||
           j > 7 && j < 11 ||
           j > 11 && j < 14 ||
           j > 14 && j < 17)
j - 4: if (j == 4)
j - 7: if (j == 7)
j – 3: if (j == 11)
j – 6: if (j == 14)

Darüber hinaus kann man mit

viele noch viele andere visuelle Varianten erzeugen. Zum Beispiel lassen sich mit beginShape(); und vertex() Polygone erstellen, oder mit Vektoren und dem Lerp-Befehl 3-dimensionale Zwischenschritte zwsichen den Joints generieren.

Das Tool hat dem Projekt als Qualitätsüberprüfung und gestalterisches Concepting Tool geholfen, da diese Struktur, die Daten auszulesen, auch später im Projekt in C# für Unity eingearbeitetes werden konnte.

https://www.openprocessing.org/sketch/578388

Es wurde noch eine zweite Version des Webtools erstellt, um einen späteren Datensatz zu visualisieren, in dem die überflüssigen Werte schon rausgelöscht waren. Dazu wurde hier noch der Low-Pass Filter implementiert, der zum smoothen der Daten angewandt wurde.

https://www.openprocessing.org/sketch/685683