P5 und Motion-Capture: Visualisierung von MoCap-Daten in 3D mit OrbitControl
Punktwolke/Drahtgitter
Vergrößerungsfaktor

Die mit dem Qualisys-Motion-Capture-System des MediaLabs erfassten Daten lassen sich in P5 über die optional im Canvas einstellbare WEBGL-Umgebung auch als animierte Punkt- oder Drahtgitterfiguren interaktiv und in 3D darstellen (der Export der Daten im *.tsv-Format wird hier erläutert).

Zunächst werden die aus der *.tsv-Datei als Javascript-Arrays umgewandelten Daten als externes Javascript im Header der Seite eingebunden

<script src="header/Aufnahme2_ausschnitt.js"></script>

Im Script folgt nach der Deklarierung von einigen grundlegenden Variablen ...

var qualisys_frames_pro_sekunde = 100; // Frame-Rate der Motion-Capture-Datei
var punkt_oder_strich = 0; // Darstellung als Punktwolke oder Drahtgittermodell
var faktor=6; // Faktor, um den die Figur vergrößert oder verkleinert wird
var schalter=0; // Schalter um die dazugehörenden Videos ein- und auszuschalten
var vzeit=0; // aktuelle Zeit des Videos

... die Setup-Funktion mit der Definition des Canvas. Neben der Weite und Höhe wird mit dem Eintrag WEBGL die Web Graphics Library aktiviert, eine Umgebung in der in Javascript 3D-Visualisierungen möglich werden. Darüber hinaus wird die Variable i eingeführt, um mit jedem Framewechsel einen Zähler von 0 bis ans Ende des Javascript-Arrays zu zählen:

function setup(){
container=createCanvas(800,800, WEBGL); // Canvas mit 3D-Umgebung erstellen
container.parent('p5container'); // an DIV-Container anhängen
i=0; // Variable zum Hochzählen auf 0 setzen
}

In der Draw-Funktion ermöglicht der Eintrag orbitControl() eine Maussteuerung der Perspektive auf der X- und Y-Achse (linke Maustaste) bzw. eine Verschiebung der Figur längs der X- und Y-Achse (rechte Maustaste). Darüber hinaus kann mit dem Mausrad in die 3D-Szene hinein- und hinausgezoomt werden.
Dank der WEBGL-Umgebung können nun Punkte, Linien etc. dreidimensional d.h. mit X-,Y- und Z-Koordinate pro Punkt dargestellt werden. So wird
für jede Punktkombination der beim Motion-Capturen erfassten 42 Körperpunkte mit beginShape(POINTS); vertex(X,Y,Z);... endShape(); eine Figur als Punkte-Shape erstellt.
Da die 42 Körperpunkte beim Qualisys-System meist gleich benannt werden, lässt sich das hier entwickelte Script auf beliebige Exporte der Bewegungsdaten einer Person anwenden (es müssen nur die Javascript-Arrays und die Videos entsprechend ausgetauscht werden).
Über i wird pro Punkt auf die jeweilige Position des Arrays zugegriffen und mit der Anfangs deklarierten Variable faktor wird die Größe der Figur um einen beliebigen Faktor geändert, z.B. für den Kopf der Figur:

beginShape(POINTS); // Punkte-Shape für die Person aus den X-Y-Z-Koordinaten erstellen.
vertex(PersID_HeadTopX_array[i]/faktor, PersID_HeadTopY_array[i]/faktor, PersID_HeadTopZ_array[i]/faktor);
vertex(PersID_HeadFrontX_array[i]/faktor, PersID_HeadFrontY_array[i]/faktor, PersID_HeadFrontZ_array[i]/faktor);
vertex(PersID_HeadLX_array[i]/faktor, PersID_HeadLY_array[i]/faktor, PersID_HeadLZ_array[i]/faktor);
vertex(PersID_HeadRX_array[i]/faktor, PersID_HeadRY_array[i]/faktor, PersID_HeadRZ_array[i]/faktor);
endShape();

Über die Strichfarbe lassen sich die Punkt-Visualisierungen pro Körperteil beliebig einfärben (z.B. rot stroke(150,50,50); für den Kopf, blau stroke(50,50,150); für den Torso oder grün stroke(50,150,50); für die Arme etc.)

Über die anfangs deklarierte Variable punkt_oder_strich kann eingestellt werden, ob die Figur als Punktwolke (0) oder als Drahtgitter (1) oder als beides dargestellt werden soll (2).

Für die Drahtgitter-Darstellung müssen die jeweils entsprechenden Punkte via line(x1, y1, z1, x2, y2, z2) mit dreidimensionalen Linien verbunden werden. Dies bedeutet z.B. für den Kopf:

line(PersID_HeadTopX_array[i]/faktor, PersID_HeadTopY_array[i]/faktor, PersID_HeadTopZ_array[i]/faktor, PersID_HeadFrontX_array[i]/faktor, PersID_HeadFrontY_array[i]/faktor, PersID_HeadFrontZ_array[i]/faktor);
line(PersID_HeadTopX_array[i]/faktor, PersID_HeadTopY_array[i]/faktor, PersID_HeadTopZ_array[i]/faktor, PersID_HeadLX_array[i]/faktor, PersID_HeadLY_array[i]/faktor, PersID_HeadLZ_array[i]/faktor);
line(PersID_HeadTopX_array[i]/faktor, PersID_HeadTopY_array[i]/faktor, PersID_HeadTopZ_array[i]/faktor, PersID_HeadRX_array[i]/faktor, PersID_HeadRY_array[i]/faktor, PersID_HeadRZ_array[i]/faktor);
line(PersID_HeadFrontX_array[i]/faktor, PersID_HeadFrontY_array[i]/faktor, PersID_HeadFrontZ_array[i]/faktor, PersID_HeadLX_array[i]/faktor, PersID_HeadLY_array[i]/faktor, PersID_HeadLZ_array[i]/faktor);
line(PersID_HeadFrontX_array[i]/faktor, PersID_HeadFrontY_array[i]/faktor, PersID_HeadFrontZ_array[i]/faktor, PersID_HeadRX_array[i]/faktor, PersID_HeadRY_array[i]/faktor, PersID_HeadRZ_array[i]/faktor);
line(PersID_HeadLX_array[i]/faktor, PersID_HeadLY_array[i]/faktor, PersID_HeadLZ_array[i]/faktor, PersID_HeadRX_array[i]/faktor, PersID_HeadRY_array[i]/faktor, PersID_HeadRZ_array[i]/faktor);
line(PersID_HeadFrontX_array[i]/faktor, PersID_HeadFrontY_array[i]/faktor, PersID_HeadFrontZ_array[i]/faktor, PersID_SpineTopX_array[i]/faktor, PersID_SpineTopY_array[i]/faktor, PersID_SpineTopZ_array[i]/faktor);

Am Ende der Draw-Funktion wird i mit jedem Frame-Wechsel weiter hochgezählt. Da hier die Aufnahme im Qualisys-System mit 100 Werten pro Sekunde stattfand (über qualisys_frames_pro_sekunde in der Variable am Anfang des Scripts einstellbar) und die Frame-Rate bei P5 von der Rechner/Netz-Auslastung abhängig ist, sollte für eine flüssige Original-Bewegung ein Faktor ermittelt werden, mit dem i beim Hochzählen multipliziert werden muss:

framefaktor = qualisys_frames_pro_sekunde/round(frameRate());

Dann kann die Länge des z.B. PersID_HeadTopX_array als Maß dafür verwendet werden, für wie lange i multipliziert mit dem gerundeten framefaktor hochgezählt wird, bis es wieder auf 0 gesetzt wird:

if(i<PersID_HeadTopX_array.length){
i=i+1*round(framefaktor);
}else{
i=0;
}

Will man nun auch die beiden Videos Frame für Frame mit den Bewegungen der Punktwolken/Drahtgittermodelle synchronisieren, sollte am Ende jedes Durchlaufs (also am Ende der Draw-Funktion) der Wert von i an die Variable für die entsprechende Videozeit übergeben werden (also vzeit = i;) . Darüber hinaus sollten im HTML-Text zwei Videoplayer mit den jeweiligen Videos eingebunden werden:

<video id="meinvplayer" src="bilder/Aufnahme2_ausschnitt_3D.mp4" ontimeupdate="vzeitanzeige()" height="235" width="400" onClick=togglePlay(); style="cursor:pointer;" ></video>
<video id="meinvplayer_overlay" src="bilder/Aufnahme2_ausschnitt_3D_Overlay.mp4" height="235" width="400" onClick=togglePlay(); style="cursor:pointer;"></video>

Über den im Video-Tag eingesetzten Aufruf ontimeupdate="vzeitanzeige()" wird die Funktion function vzeitanzeige(){ ... } aufgerufen, die - nachdem sie beide Player via getElementById() auf der Seite gefunden hat - bei jedem Aufruf den zu vzeit passenden Frame den Playern zuweist.

Über die Funktion function togglePlay() {.. } schließlich werden die Videos gestartet und gestoppt (hier via onClick=togglePlay(); von den Videoplayern aus aufgerufen).

Soll das Aussehen (Punktwolke, Drahtgitter oder beides) und/oder die Größe des Modells verändert werden, so lässt sich dies am einfachsten über Schieberegler im HTML-Code der Seite bewerkstelligen (die über css beliebig gestaltet werden können):

<input type="range" min="0" max="2" value="0" class="slider" step="1" id="punktstrichslider" onchange=neuer_punktstrich(this.value);>

<input type="range" min="1" max="20" value="6" class="slider" step="0.1" id="faktorslider" onchange=neuer_faktor(20-this.value);>

Über type="range" wird hier die Art des Inputs als Schieberegler eingestellt, über min der Minimalwert, max der Maximalwert und value der aktuelle Wert, während über step die Schrittgröße des Reglers eingestellt wird und über die id der Name.

Über onchange=... wird bei jeder Änderung des Schiebereglers eine dazu passende Funktion im Script mit dem jeweils neu eingestellten Wert aufgerufen, in der der übergebene Wert der Variablen für die Auswahl der Darstellung (punkt_oder_strich) bzw. der Größe (faktor) zugewiesen wird:

function neuer_faktor(wert){faktor=wert;}
function neuer_punktstrich(wert){punkt_oder_strich=wert;}

 

Insgesamt sieht das Script dann folgendermaßen aus:

<script src="header/p5.js"></script>
<script src="header/p5.sound.js"></script>
<script src="header/Aufnahme2_ausschnitt.js"></script>

var qualisys_frames_pro_sekunde = 100;
var punkt_oder_strich = 0;
var faktor=6;

var schalter=0;
var vzeit=0;

function setup(){
container=createCanvas(800,800, WEBGL);
container.parent('p5container');
i=0;
}

function draw(){
cursor(HAND);

background(255,255,255);
orbitControl();

if(punkt_oder_strich==0 || punkt_oder_strich==2){
//--------Punktwolken-------------------------
stroke(150,50,50); strokeWeight(5);
beginShape(POINTS);
vertex(PersID_HeadTopX_array[i]/faktor, PersID_HeadTopY_array[i]/faktor, PersID_HeadTopZ_array[i]/faktor);
vertex(PersID_HeadFrontX_array[i]/faktor, PersID_HeadFrontY_array[i]/faktor, PersID_HeadFrontZ_array[i]/faktor);
vertex(PersID_HeadLX_array[i]/faktor, PersID_HeadLY_array[i]/faktor, PersID_HeadLZ_array[i]/faktor);
vertex(PersID_HeadRX_array[i]/faktor, PersID_HeadRY_array[i]/faktor, PersID_HeadRZ_array[i]/faktor);
endShape();

stroke(50,150,50);
beginShape(POINTS);
vertex(PersID_LShoulderTopX_array[i]/faktor, PersID_LShoulderTopY_array[i]/faktor, PersID_LShoulderTopZ_array[i]/faktor);
vertex(PersID_LShoulderBackX_array[i]/faktor, PersID_LShoulderBackY_array[i]/faktor, PersID_LShoulderBackZ_array[i]/faktor);
vertex(PersID_LArmX_array[i]/faktor, PersID_LArmY_array[i]/faktor, PersID_LArmZ_array[i]/faktor);
vertex(PersID_LElbowOutX_array[i]/faktor, PersID_LElbowOutY_array[i]/faktor, PersID_LElbowOutZ_array[i]/faktor);
vertex(PersID_LWristInX_array[i]/faktor, PersID_LWristInY_array[i]/faktor, PersID_LWristInZ_array[i]/faktor);
vertex(PersID_LWristOutX_array[i]/faktor, PersID_LWristOutY_array[i]/faktor, PersID_LWristOutZ_array[i]/faktor);
vertex(PersID_LHandOutX_array[i]/faktor, PersID_LHandOutY_array[i]/faktor, PersID_LHandOutZ_array[i]/faktor);

vertex(PersID_RShoulderTopX_array[i]/faktor, PersID_RShoulderTopY_array[i]/faktor, PersID_RShoulderTopZ_array[i]/faktor);
vertex(PersID_RShoulderBackX_array[i]/faktor, PersID_RShoulderBackY_array[i]/faktor, PersID_RShoulderBackZ_array[i]/faktor);
vertex(PersID_RArmX_array[i]/faktor, PersID_RArmY_array[i]/faktor, PersID_RArmZ_array[i]/faktor);
vertex(PersID_RElbowOutX_array[i]/faktor, PersID_RElbowOutY_array[i]/faktor, PersID_RElbowOutZ_array[i]/faktor);
vertex(PersID_RWristInX_array[i]/faktor, PersID_RWristInY_array[i]/faktor, PersID_RWristInZ_array[i]/faktor);
vertex(PersID_RWristOutX_array[i]/faktor, PersID_RWristOutY_array[i]/faktor, PersID_RWristOutZ_array[i]/faktor);
vertex(PersID_RHandOutX_array[i]/faktor, PersID_RHandOutY_array[i]/faktor, PersID_RHandOutZ_array[i]/faktor);
endShape();

stroke(50,50,150);
beginShape(POINTS);
vertex(PersID_ChestX_array[i]/faktor, PersID_ChestY_array[i]/faktor, PersID_ChestZ_array[i]/faktor);
vertex(PersID_SpineTopX_array[i]/faktor, PersID_SpineTopY_array[i]/faktor, PersID_SpineTopZ_array[i]/faktor);
vertex(PersID_BackLX_array[i]/faktor, PersID_BackLY_array[i]/faktor, PersID_BackLZ_array[i]/faktor);
vertex(PersID_BackRX_array[i]/faktor, PersID_BackRY_array[i]/faktor, PersID_BackRZ_array[i]/faktor);
endShape();

stroke(50,150,150);
beginShape(POINTS);
vertex(PersID_WaistLFrontX_array[i]/faktor, PersID_WaistLFrontY_array[i]/faktor, PersID_WaistLFrontZ_array[i]/faktor);
vertex(PersID_WaistLBackX_array[i]/faktor, PersID_WaistLBackY_array[i]/faktor, PersID_WaistLBackZ_array[i]/faktor);
vertex(PersID_LThighX_array[i]/faktor, PersID_LThighY_array[i]/faktor, PersID_LThighZ_array[i]/faktor);
vertex(PersID_LKneeOutX_array[i]/faktor, PersID_LKneeOutY_array[i]/faktor, PersID_LKneeOutZ_array[i]/faktor);
vertex(PersID_LShinX_array[i]/faktor, PersID_LShinY_array[i]/faktor, PersID_LShinZ_array[i]/faktor);
vertex(PersID_LAnkleOutX_array[i]/faktor, PersID_LAnkleOutY_array[i]/faktor, PersID_LAnkleOutZ_array[i]/faktor);
vertex(PersID_LForefootInX_array[i]/faktor, PersID_LForefootInY_array[i]/faktor, PersID_LForefootInZ_array[i]/faktor);
vertex(PersID_LToeTipX_array[i]/faktor, PersID_LToeTipY_array[i]/faktor, PersID_LToeTipZ_array[i]/faktor);
vertex(PersID_LForefootOutX_array[i]/faktor, PersID_LForefootOutY_array[i]/faktor, PersID_LForefootOutZ_array[i]/faktor);
vertex(PersID_LHeelBackX_array[i]/faktor, PersID_LHeelBackY_array[i]/faktor, PersID_LHeelBackZ_array[i]/faktor);

vertex(PersID_WaistRFrontX_array[i]/faktor, PersID_WaistRFrontY_array[i]/faktor, PersID_WaistRFrontZ_array[i]/faktor);
vertex(PersID_WaistRBackX_array[i]/faktor, PersID_WaistRBackY_array[i]/faktor, PersID_WaistRBackZ_array[i]/faktor);
vertex(PersID_RThighX_array[i]/faktor, PersID_RThighY_array[i]/faktor, PersID_RThighZ_array[i]/faktor);
vertex(PersID_RKneeOutX_array[i]/faktor, PersID_RKneeOutY_array[i]/faktor, PersID_RKneeOutZ_array[i]/faktor);
vertex(PersID_RShinX_array[i]/faktor, PersID_RShinY_array[i]/faktor, PersID_RShinZ_array[i]/faktor);
vertex(PersID_RAnkleOutX_array[i]/faktor, PersID_RAnkleOutY_array[i]/faktor, PersID_RAnkleOutZ_array[i]/faktor);
vertex(PersID_RForefootInX_array[i]/faktor, PersID_RForefootInY_array[i]/faktor, PersID_RForefootInZ_array[i]/faktor);
vertex(PersID_RToeTipX_array[i]/faktor, PersID_RToeTipY_array[i]/faktor, PersID_RToeTipZ_array[i]/faktor);
vertex(PersID_RForefootOutX_array[i]/faktor, PersID_RForefootOutY_array[i]/faktor, PersID_RForefootOutZ_array[i]/faktor);
vertex(PersID_RHeelBackX_array[i]/faktor, PersID_RHeelBackY_array[i]/faktor, PersID_RHeelBackZ_array[i]/faktor);
endShape();
}

//--------Strichmännchen-------------------------
if(punkt_oder_strich==1 || punkt_oder_strich==2){
stroke(150,150,150);strokeWeight(1);
line(PersID_HeadTopX_array[i]/faktor, PersID_HeadTopY_array[i]/faktor, PersID_HeadTopZ_array[i]/faktor, PersID_HeadFrontX_array[i]/faktor, PersID_HeadFrontY_array[i]/faktor, PersID_HeadFrontZ_array[i]/faktor);
line(PersID_HeadTopX_array[i]/faktor, PersID_HeadTopY_array[i]/faktor, PersID_HeadTopZ_array[i]/faktor, PersID_HeadLX_array[i]/faktor, PersID_HeadLY_array[i]/faktor, PersID_HeadLZ_array[i]/faktor);
line(PersID_HeadTopX_array[i]/faktor, PersID_HeadTopY_array[i]/faktor, PersID_HeadTopZ_array[i]/faktor, PersID_HeadRX_array[i]/faktor, PersID_HeadRY_array[i]/faktor, PersID_HeadRZ_array[i]/faktor);
line(PersID_HeadFrontX_array[i]/faktor, PersID_HeadFrontY_array[i]/faktor, PersID_HeadFrontZ_array[i]/faktor, PersID_HeadLX_array[i]/faktor, PersID_HeadLY_array[i]/faktor, PersID_HeadLZ_array[i]/faktor);
line(PersID_HeadFrontX_array[i]/faktor, PersID_HeadFrontY_array[i]/faktor, PersID_HeadFrontZ_array[i]/faktor, PersID_HeadRX_array[i]/faktor, PersID_HeadRY_array[i]/faktor, PersID_HeadRZ_array[i]/faktor);
line(PersID_HeadLX_array[i]/faktor, PersID_HeadLY_array[i]/faktor, PersID_HeadLZ_array[i]/faktor, PersID_HeadRX_array[i]/faktor, PersID_HeadRY_array[i]/faktor, PersID_HeadRZ_array[i]/faktor);
line(PersID_HeadFrontX_array[i]/faktor, PersID_HeadFrontY_array[i]/faktor, PersID_HeadFrontZ_array[i]/faktor, PersID_SpineTopX_array[i]/faktor, PersID_SpineTopY_array[i]/faktor, PersID_SpineTopZ_array[i]/faktor);
line(PersID_ChestX_array[i]/faktor, PersID_ChestY_array[i]/faktor, PersID_ChestZ_array[i]/faktor, PersID_SpineTopX_array[i]/faktor, PersID_SpineTopY_array[i]/faktor, PersID_SpineTopZ_array[i]/faktor);
line(PersID_ChestX_array[i]/faktor, PersID_ChestY_array[i]/faktor, PersID_ChestZ_array[i]/faktor, PersID_BackLX_array[i]/faktor, PersID_BackLY_array[i]/faktor, PersID_BackLZ_array[i]/faktor);
line(PersID_ChestX_array[i]/faktor, PersID_ChestY_array[i]/faktor, PersID_ChestZ_array[i]/faktor, PersID_BackRX_array[i]/faktor, PersID_BackRY_array[i]/faktor, PersID_BackRZ_array[i]/faktor);
line(PersID_SpineTopX_array[i]/faktor, PersID_SpineTopY_array[i]/faktor, PersID_SpineTopZ_array[i]/faktor, PersID_BackLX_array[i]/faktor, PersID_BackLY_array[i]/faktor, PersID_BackLZ_array[i]/faktor);
line(PersID_SpineTopX_array[i]/faktor, PersID_SpineTopY_array[i]/faktor, PersID_SpineTopZ_array[i]/faktor, PersID_BackRX_array[i]/faktor, PersID_BackRY_array[i]/faktor, PersID_BackRZ_array[i]/faktor);
line(PersID_BackLX_array[i]/faktor, PersID_BackLY_array[i]/faktor, PersID_BackLZ_array[i]/faktor, PersID_BackRX_array[i]/faktor, PersID_BackRY_array[i]/faktor, PersID_BackRZ_array[i]/faktor);
line(PersID_SpineTopX_array[i]/faktor, PersID_SpineTopY_array[i]/faktor, PersID_SpineTopZ_array[i]/faktor, PersID_LShoulderTopX_array[i]/faktor, PersID_LShoulderTopY_array[i]/faktor, PersID_LShoulderTopZ_array[i]/faktor);
line(PersID_SpineTopX_array[i]/faktor, PersID_SpineTopY_array[i]/faktor, PersID_SpineTopZ_array[i]/faktor, PersID_LShoulderBackX_array[i]/faktor, PersID_LShoulderBackY_array[i]/faktor, PersID_LShoulderBackZ_array[i]/faktor);
line(PersID_LShoulderTopX_array[i]/faktor, PersID_LShoulderTopY_array[i]/faktor, PersID_LShoulderTopZ_array[i]/faktor, PersID_LShoulderBackX_array[i]/faktor, PersID_LShoulderBackY_array[i]/faktor, PersID_LShoulderBackZ_array[i]/faktor);
line(PersID_LShoulderTopX_array[i]/faktor, PersID_LShoulderTopY_array[i]/faktor, PersID_LShoulderTopZ_array[i]/faktor, PersID_LArmX_array[i]/faktor, PersID_LArmY_array[i]/faktor, PersID_LArmZ_array[i]/faktor);
line(PersID_LShoulderBackX_array[i]/faktor, PersID_LShoulderBackY_array[i]/faktor, PersID_LShoulderBackZ_array[i]/faktor, PersID_LArmX_array[i]/faktor, PersID_LArmY_array[i]/faktor, PersID_LArmZ_array[i]/faktor);
line(PersID_LArmX_array[i]/faktor, PersID_LArmY_array[i]/faktor, PersID_LArmZ_array[i]/faktor, PersID_LElbowOutX_array[i]/faktor, PersID_LElbowOutY_array[i]/faktor, PersID_LElbowOutZ_array[i]/faktor);
line(PersID_LElbowOutX_array[i]/faktor, PersID_LElbowOutY_array[i]/faktor, PersID_LElbowOutZ_array[i]/faktor, PersID_LWristInX_array[i]/faktor, PersID_LWristInY_array[i]/faktor, PersID_LWristInZ_array[i]/faktor);
line(PersID_LElbowOutX_array[i]/faktor, PersID_LElbowOutY_array[i]/faktor, PersID_LElbowOutZ_array[i]/faktor, PersID_LWristOutX_array[i]/faktor, PersID_LWristOutY_array[i]/faktor, PersID_LWristOutZ_array[i]/faktor);
line(PersID_LHandOutX_array[i]/faktor, PersID_LHandOutY_array[i]/faktor, PersID_LHandOutZ_array[i]/faktor, PersID_LWristInX_array[i]/faktor, PersID_LWristInY_array[i]/faktor, PersID_LWristInZ_array[i]/faktor);
line(PersID_LHandOutX_array[i]/faktor, PersID_LHandOutY_array[i]/faktor, PersID_LHandOutZ_array[i]/faktor, PersID_LWristOutX_array[i]/faktor, PersID_LWristOutY_array[i]/faktor, PersID_LWristOutZ_array[i]/faktor);
line(PersID_LWristInX_array[i]/faktor, PersID_LWristInY_array[i]/faktor, PersID_LWristInZ_array[i]/faktor, PersID_LWristOutX_array[i]/faktor, PersID_LWristOutY_array[i]/faktor, PersID_LWristOutZ_array[i]/faktor);
line(PersID_SpineTopX_array[i]/faktor, PersID_SpineTopY_array[i]/faktor, PersID_SpineTopZ_array[i]/faktor, PersID_RShoulderTopX_array[i]/faktor, PersID_RShoulderTopY_array[i]/faktor, PersID_RShoulderTopZ_array[i]/faktor);
line(PersID_SpineTopX_array[i]/faktor, PersID_SpineTopY_array[i]/faktor, PersID_SpineTopZ_array[i]/faktor, PersID_RShoulderBackX_array[i]/faktor, PersID_RShoulderBackY_array[i]/faktor, PersID_RShoulderBackZ_array[i]/faktor);
line(PersID_RShoulderTopX_array[i]/faktor, PersID_RShoulderTopY_array[i]/faktor, PersID_RShoulderTopZ_array[i]/faktor, PersID_RShoulderBackX_array[i]/faktor, PersID_RShoulderBackY_array[i]/faktor, PersID_RShoulderBackZ_array[i]/faktor);
line(PersID_RShoulderTopX_array[i]/faktor, PersID_RShoulderTopY_array[i]/faktor, PersID_RShoulderTopZ_array[i]/faktor, PersID_RArmX_array[i]/faktor, PersID_RArmY_array[i]/faktor, PersID_RArmZ_array[i]/faktor);
line(PersID_RShoulderBackX_array[i]/faktor, PersID_RShoulderBackY_array[i]/faktor, PersID_RShoulderBackZ_array[i]/faktor, PersID_RArmX_array[i]/faktor, PersID_RArmY_array[i]/faktor, PersID_RArmZ_array[i]/faktor);
line(PersID_RArmX_array[i]/faktor, PersID_RArmY_array[i]/faktor, PersID_RArmZ_array[i]/faktor, PersID_RElbowOutX_array[i]/faktor, PersID_RElbowOutY_array[i]/faktor, PersID_RElbowOutZ_array[i]/faktor);
line(PersID_RElbowOutX_array[i]/faktor, PersID_RElbowOutY_array[i]/faktor, PersID_RElbowOutZ_array[i]/faktor, PersID_RWristInX_array[i]/faktor, PersID_RWristInY_array[i]/faktor, PersID_RWristInZ_array[i]/faktor);
line(PersID_RElbowOutX_array[i]/faktor, PersID_RElbowOutY_array[i]/faktor, PersID_RElbowOutZ_array[i]/faktor, PersID_RWristOutX_array[i]/faktor, PersID_RWristOutY_array[i]/faktor, PersID_RWristOutZ_array[i]/faktor);
line(PersID_RHandOutX_array[i]/faktor, PersID_RHandOutY_array[i]/faktor, PersID_RHandOutZ_array[i]/faktor, PersID_RWristInX_array[i]/faktor, PersID_RWristInY_array[i]/faktor, PersID_RWristInZ_array[i]/faktor);
line(PersID_RHandOutX_array[i]/faktor, PersID_RHandOutY_array[i]/faktor, PersID_RHandOutZ_array[i]/faktor, PersID_RWristOutX_array[i]/faktor, PersID_RWristOutY_array[i]/faktor, PersID_RWristOutZ_array[i]/faktor);
line(PersID_RWristInX_array[i]/faktor, PersID_RWristInY_array[i]/faktor, PersID_RWristInZ_array[i]/faktor, PersID_RWristOutX_array[i]/faktor, PersID_RWristOutY_array[i]/faktor, PersID_RWristOutZ_array[i]/faktor);
line(PersID_ChestX_array[i]/faktor, PersID_ChestY_array[i]/faktor, PersID_ChestZ_array[i]/faktor, PersID_WaistLFrontX_array[i]/faktor, PersID_WaistLFrontY_array[i]/faktor, PersID_WaistLFrontZ_array[i]/faktor);
line(PersID_ChestX_array[i]/faktor, PersID_ChestY_array[i]/faktor, PersID_ChestZ_array[i]/faktor, PersID_WaistRFrontX_array[i]/faktor, PersID_WaistRFrontY_array[i]/faktor, PersID_WaistRFrontZ_array[i]/faktor);
line(PersID_BackLX_array[i]/faktor, PersID_BackLY_array[i]/faktor, PersID_BackLZ_array[i]/faktor, PersID_WaistLBackX_array[i]/faktor, PersID_WaistLBackY_array[i]/faktor, PersID_WaistLBackZ_array[i]/faktor);
line(PersID_BackRX_array[i]/faktor, PersID_BackRY_array[i]/faktor, PersID_BackRZ_array[i]/faktor, PersID_WaistRBackX_array[i]/faktor, PersID_WaistRBackY_array[i]/faktor, PersID_WaistRBackZ_array[i]/faktor);
line(PersID_WaistRBackX_array[i]/faktor, PersID_WaistRBackY_array[i]/faktor, PersID_WaistRBackZ_array[i]/faktor, PersID_WaistLBackX_array[i]/faktor, PersID_WaistLBackY_array[i]/faktor, PersID_WaistLBackZ_array[i]/faktor);
line(PersID_WaistRFrontX_array[i]/faktor, PersID_WaistRFrontY_array[i]/faktor, PersID_WaistRFrontZ_array[i]/faktor, PersID_WaistLFrontX_array[i]/faktor, PersID_WaistLFrontY_array[i]/faktor, PersID_WaistLFrontZ_array[i]/faktor);
line(PersID_WaistLBackX_array[i]/faktor, PersID_WaistLBackY_array[i]/faktor, PersID_WaistLBackZ_array[i]/faktor, PersID_WaistLFrontX_array[i]/faktor, PersID_WaistLFrontY_array[i]/faktor, PersID_WaistLFrontZ_array[i]/faktor);
line(PersID_WaistRBackX_array[i]/faktor, PersID_WaistRBackY_array[i]/faktor, PersID_WaistRBackZ_array[i]/faktor, PersID_WaistRFrontX_array[i]/faktor, PersID_WaistRFrontY_array[i]/faktor, PersID_WaistRFrontZ_array[i]/faktor);
line(PersID_WaistRFrontX_array[i]/faktor, PersID_WaistRFrontY_array[i]/faktor, PersID_WaistRFrontZ_array[i]/faktor, PersID_RThighX_array[i]/faktor, PersID_RThighY_array[i]/faktor, PersID_RThighZ_array[i]/faktor);
line(PersID_WaistRBackX_array[i]/faktor, PersID_WaistRBackY_array[i]/faktor, PersID_WaistRBackZ_array[i]/faktor, PersID_RThighX_array[i]/faktor, PersID_RThighY_array[i]/faktor, PersID_RThighZ_array[i]/faktor);
line(PersID_WaistLFrontX_array[i]/faktor, PersID_WaistLFrontY_array[i]/faktor, PersID_WaistLFrontZ_array[i]/faktor, PersID_LThighX_array[i]/faktor, PersID_LThighY_array[i]/faktor, PersID_LThighZ_array[i]/faktor);
line(PersID_WaistLBackX_array[i]/faktor, PersID_WaistLBackY_array[i]/faktor, PersID_WaistLBackZ_array[i]/faktor, PersID_LThighX_array[i]/faktor, PersID_LThighY_array[i]/faktor, PersID_LThighZ_array[i]/faktor);
line(PersID_LKneeOutX_array[i]/faktor, PersID_LKneeOutY_array[i]/faktor, PersID_LKneeOutZ_array[i]/faktor, PersID_LShinX_array[i]/faktor, PersID_LShinY_array[i]/faktor, PersID_LShinZ_array[i]/faktor);
line(PersID_RKneeOutX_array[i]/faktor, PersID_RKneeOutY_array[i]/faktor, PersID_RKneeOutZ_array[i]/faktor, PersID_RShinX_array[i]/faktor, PersID_RShinY_array[i]/faktor, PersID_RShinZ_array[i]/faktor);
line(PersID_LKneeOutX_array[i]/faktor, PersID_LKneeOutY_array[i]/faktor, PersID_LKneeOutZ_array[i]/faktor, PersID_LThighX_array[i]/faktor, PersID_LThighY_array[i]/faktor, PersID_LThighZ_array[i]/faktor);
line(PersID_RKneeOutX_array[i]/faktor, PersID_RKneeOutY_array[i]/faktor, PersID_RKneeOutZ_array[i]/faktor, PersID_RThighX_array[i]/faktor, PersID_RThighY_array[i]/faktor, PersID_RThighZ_array[i]/faktor);
line(PersID_LShinX_array[i]/faktor, PersID_LShinY_array[i]/faktor, PersID_LShinZ_array[i]/faktor, PersID_LAnkleOutX_array[i]/faktor, PersID_LAnkleOutY_array[i]/faktor, PersID_LAnkleOutZ_array[i]/faktor);
line(PersID_LShinX_array[i]/faktor, PersID_LShinY_array[i]/faktor, PersID_LShinZ_array[i]/faktor, PersID_LHeelBackX_array[i]/faktor, PersID_LHeelBackY_array[i]/faktor, PersID_LHeelBackZ_array[i]/faktor);
line(PersID_LAnkleOutX_array[i]/faktor, PersID_LAnkleOutY_array[i]/faktor, PersID_LAnkleOutZ_array[i]/faktor, PersID_LForefootInX_array[i]/faktor, PersID_LForefootInY_array[i]/faktor, PersID_LForefootInZ_array[i]/faktor);
line(PersID_LAnkleOutX_array[i]/faktor, PersID_LAnkleOutY_array[i]/faktor, PersID_LAnkleOutZ_array[i]/faktor, PersID_LForefootOutX_array[i]/faktor, PersID_LForefootOutY_array[i]/faktor, PersID_LForefootOutZ_array[i]/faktor);
line(PersID_LForefootInX_array[i]/faktor, PersID_LForefootInY_array[i]/faktor, PersID_LForefootInZ_array[i]/faktor, PersID_LForefootOutX_array[i]/faktor, PersID_LForefootOutY_array[i]/faktor, PersID_LForefootOutZ_array[i]/faktor);
line(PersID_LAnkleOutX_array[i]/faktor, PersID_LAnkleOutY_array[i]/faktor, PersID_LAnkleOutZ_array[i]/faktor, PersID_LHeelBackX_array[i]/faktor, PersID_LHeelBackY_array[i]/faktor, PersID_LHeelBackZ_array[i]/faktor);
line(PersID_LAnkleOutX_array[i]/faktor, PersID_LAnkleOutY_array[i]/faktor, PersID_LAnkleOutZ_array[i]/faktor, PersID_LHeelBackX_array[i]/faktor, PersID_LHeelBackY_array[i]/faktor, PersID_LHeelBackZ_array[i]/faktor);
line(PersID_LForefootOutX_array[i]/faktor, PersID_LForefootOutY_array[i]/faktor, PersID_LForefootOutZ_array[i]/faktor, PersID_LHeelBackX_array[i]/faktor, PersID_LHeelBackY_array[i]/faktor, PersID_LHeelBackZ_array[i]/faktor);
line(PersID_LForefootInX_array[i]/faktor, PersID_LForefootInY_array[i]/faktor, PersID_LForefootInZ_array[i]/faktor, PersID_LHeelBackX_array[i]/faktor, PersID_LHeelBackY_array[i]/faktor, PersID_LHeelBackZ_array[i]/faktor);
line(PersID_LForefootOutX_array[i]/faktor, PersID_LForefootOutY_array[i]/faktor, PersID_LForefootOutZ_array[i]/faktor, PersID_LToeTipX_array[i]/faktor, PersID_LToeTipY_array[i]/faktor, PersID_LToeTipZ_array[i]/faktor);
line(PersID_LForefootInX_array[i]/faktor, PersID_LForefootInY_array[i]/faktor, PersID_LForefootInZ_array[i]/faktor, PersID_LToeTipX_array[i]/faktor, PersID_LToeTipY_array[i]/faktor, PersID_LToeTipZ_array[i]/faktor);
line(PersID_RShinX_array[i]/faktor, PersID_RShinY_array[i]/faktor, PersID_RShinZ_array[i]/faktor, PersID_RAnkleOutX_array[i]/faktor, PersID_RAnkleOutY_array[i]/faktor, PersID_RAnkleOutZ_array[i]/faktor);
line(PersID_RShinX_array[i]/faktor, PersID_RShinY_array[i]/faktor, PersID_RShinZ_array[i]/faktor, PersID_RHeelBackX_array[i]/faktor, PersID_RHeelBackY_array[i]/faktor, PersID_RHeelBackZ_array[i]/faktor);
line(PersID_RAnkleOutX_array[i]/faktor, PersID_RAnkleOutY_array[i]/faktor, PersID_RAnkleOutZ_array[i]/faktor, PersID_RForefootInX_array[i]/faktor, PersID_RForefootInY_array[i]/faktor, PersID_RForefootInZ_array[i]/faktor);
line(PersID_RAnkleOutX_array[i]/faktor, PersID_RAnkleOutY_array[i]/faktor, PersID_RAnkleOutZ_array[i]/faktor, PersID_RForefootOutX_array[i]/faktor, PersID_RForefootOutY_array[i]/faktor, PersID_RForefootOutZ_array[i]/faktor);
line(PersID_RForefootInX_array[i]/faktor, PersID_RForefootInY_array[i]/faktor, PersID_RForefootInZ_array[i]/faktor, PersID_RForefootOutX_array[i]/faktor, PersID_RForefootOutY_array[i]/faktor, PersID_RForefootOutZ_array[i]/faktor);
line(PersID_RAnkleOutX_array[i]/faktor, PersID_RAnkleOutY_array[i]/faktor, PersID_RAnkleOutZ_array[i]/faktor, PersID_RHeelBackX_array[i]/faktor, PersID_RHeelBackY_array[i]/faktor, PersID_RHeelBackZ_array[i]/faktor);
line(PersID_RAnkleOutX_array[i]/faktor, PersID_RAnkleOutY_array[i]/faktor, PersID_RAnkleOutZ_array[i]/faktor, PersID_RHeelBackX_array[i]/faktor, PersID_RHeelBackY_array[i]/faktor, PersID_RHeelBackZ_array[i]/faktor);
line(PersID_RForefootOutX_array[i]/faktor, PersID_RForefootOutY_array[i]/faktor, PersID_RForefootOutZ_array[i]/faktor, PersID_RHeelBackX_array[i]/faktor, PersID_RHeelBackY_array[i]/faktor, PersID_RHeelBackZ_array[i]/faktor);
line(PersID_RForefootInX_array[i]/faktor, PersID_RForefootInY_array[i]/faktor, PersID_RForefootInZ_array[i]/faktor, PersID_RHeelBackX_array[i]/faktor, PersID_RHeelBackY_array[i]/faktor, PersID_RHeelBackZ_array[i]/faktor);
line(PersID_RForefootOutX_array[i]/faktor, PersID_RForefootOutY_array[i]/faktor, PersID_RForefootOutZ_array[i]/faktor, PersID_RToeTipX_array[i]/faktor, PersID_RToeTipY_array[i]/faktor, PersID_RToeTipZ_array[i]/faktor);
line(PersID_RForefootInX_array[i]/faktor, PersID_RForefootInY_array[i]/faktor, PersID_RForefootInZ_array[i]/faktor, PersID_RToeTipX_array[i]/faktor, PersID_RToeTipY_array[i]/faktor, PersID_RToeTipZ_array[i]/faktor);
}

framefaktor = qualisys_frames_pro_sekunde/round(frameRate());
if(i<PersID_HeadTopX_array.length){i=i+1*round(framefaktor);}else{i=0;}
vzeit = i;
}

function vzeitanzeige(){
var meinvplayer = document.getElementById('meinvplayer');
var meinvplayer_overlay = document.getElementById('meinvplayer_overlay');
if (schalter==1) {
videozeit= vzeit/100;
} else {
videozeit= 0;
}
meinvplayer.currentTime = videozeit;
meinvplayer_overlay.currentTime = videozeit;
}

function togglePlay() {
if (schalter==0) {
document.getElementById('meinvplayer').play();
document.getElementById('meinvplayer_overlay').play();
schalter=1;
} else {
schalter=0;
}
}

function neuer_faktor(wert){faktor=wert;}
function neuer_punktstrich(wert){punkt_oder_strich=wert;}

</script>

 

<DIV id="p5container" style="width:800;border: 1px solid #333;box-shadow: 8px 8px 5px #444;padding: 8px 12px;background-color:ffffff"></DIV>

<video id="meinvplayer" src="bilder/Aufnahme2_ausschnitt_3D.mp4" ontimeupdate="vzeitanzeige()" height="235" width="400" onClick=togglePlay(); style="cursor:pointer;"></video>

<video id="meinvplayer_overlay" src="bilder/Aufnahme2_ausschnitt_3D_Overlay.mp4" height="235" width="400" onClick=togglePlay(); style="cursor:pointer;"></video>

<input type="range" min="0" max="2" value="0" class="slider" step="1" id="punktstrichslider" onchange=neuer_punktstrich(this.value);>

<input type="range" min="1" max="20" value="6" class="slider" step="0.1" id="faktorslider" onchange=neuer_faktor(20-this.value);>