For this piece the motion definitely came first. I most experimented with ways of conveying the body through lines while getting to know Mocap in Processing, the video underneath is one of the more refined outcomes of my experimentation. With my series of experimentations in place, I thought through each and wanted to build a form of narrative in which this digital body wills itself into existence from an initial form as a plane. From this I came to the final piece, which moves toward the viewer just as the walking motion does, urging itself onwards into existence as the viewer scrolls through.
I am mildly pleased with the outcome, but not happy. I feel that greater blending between the states with more steps would make this a more cohesive transition.
// Based off of Template provided on 60212 Fall 2018 Website // Renders a BVH file with Processing v3.4 // Note: mouseX controls the camera. // Based off of com.rhizomatiks.bvh // Golan Levin, September 2018 PBvh myBrekelBvh; PBvh secondBrekelBvh; PBvh thirdBrekelBvh; PBvh fourthBrekelBvh; PBvh fifthBrekelBvh; boolean bDrawMeat = true; boolean bDrawLineConnectingHands = false; boolean bDrawCircleAtOrigin = false; boolean bDrawLineToBoneInScreenspace = false; float boneScreenX; float boneScreenY; int xCamera = 500; int yCamera = 500; int zCamera = 500; int distance = 3200; int distanceFinal = 4000; int distanceWalkout = 4400; //------------------------------------------------ void setup() { size( 1280, 720, P3D ); // Load a BVH file recorded with a Kinect v2, made in Brekel Pro Body v2. myBrekelBvh = new PBvh( loadStrings("walk_bold.bvh" ) ); secondBrekelBvh = new PBvh( loadStrings("walk-cycle.bvh") ); } //------------------------------------------------ void draw() { lights() ; background(0, 0, 0); pushMatrix(); setMyCamera(); // Position the camera. See code below. //drawMyGround(); // Draw the ground. See code below. updateAndDrawBody(); // Update and render the BVH file. See code below. popMatrix(); drawHelpInfo(); drawLineToHead(); } void keyPressed() { switch (key) { case 'M': case 'm': bDrawMeat = !bDrawMeat; break; case 'L': case 'l': bDrawLineConnectingHands = !bDrawLineConnectingHands; break; case 'O': case 'o': bDrawCircleAtOrigin = !bDrawCircleAtOrigin; break; case 'H': case 'h': bDrawLineToBoneInScreenspace = !bDrawLineToBoneInScreenspace; break; case 'w': yCamera += 50; break; case 's': yCamera -= 50; break; case 'd': xCamera += 50; break; case 'a': xCamera -= 50; break; case 'f': zCamera += 50; break; case 'g': zCamera -= 50; break; } } //------------------------------------------------ void updateAndDrawBody() { pushMatrix(); translate(width/2, height/2, 0); // position the body in space scale(-1, -1, 1); // correct for the coordinate system orientation myBrekelBvh.update(millis()); // update the BVH playback pushMatrix(); stroke(255, 0, 0); //myBrekelBvh.draw(); // one way to draw the BVH file (see PBvh.pde) popMatrix(); if (bDrawMeat) { myBrekelBvh.drawBones(); // a different way to draw the BVH file } if (bDrawLineConnectingHands) { drawLineConnectingHands(); } if (bDrawCircleAtOrigin) { drawCircleAtOrigin(); } if (bDrawLineToBoneInScreenspace) { myBrekelBvh.calculateScreenspaceLocationOfBone("Head"); } popMatrix(); pushMatrix(); translate(width/2, height/2, 0); // position the body in space scale(-1, -1, 1); // correct for the coordinate system orientation myBrekelBvh.update(millis()); // update the BVH playback pushMatrix(); stroke(255, 0, 0); //myBrekelBvh.draw(); // one way to draw the BVH file (see PBvh.pde) popMatrix(); if (bDrawMeat) { secondBrekelBvh.drawBones(); // a different way to draw the BVH file } if (bDrawLineConnectingHands) { drawLineConnectingHands(); } if (bDrawCircleAtOrigin) { drawCircleAtOrigin(); } if (bDrawLineToBoneInScreenspace) { secondBrekelBvh.calculateScreenspaceLocationOfBone("Head"); } popMatrix(); } //------------------------------------------------ void drawHelpInfo() { fill(255); float ty = 20; float dy = 15; //text("BVH Loader for Processing 3.4", 20, ty+=dy); //text("Displays files recorded with Kinect v2 + Brekel Pro Body 2", 20, ty+=dy); //text("", 20, ty+=dy); //text("Press 'M' to toggle meat", 20, ty+=dy); //text("Press 'L' to draw line connecting hands", 20, ty+=dy); //text("Press 'O' to draw circle at Origin", 20, ty+=dy); //text("Press 'H' to draw line from mouse to Head", 20, ty+=dy); } //------------------------------------------------ void drawLineToHead() { if (bDrawLineToBoneInScreenspace) { stroke(0, 255, 255); strokeWeight(3); line (mouseX, mouseY, boneScreenX, boneScreenY); } } //------------------------------------------------ void drawCircleAtOrigin() { fill(255); stroke(255, 0, 0); strokeWeight(4); ellipse(0, 0, 20, 20); } //------------------------------------------------ void drawLineConnectingHands() { // This example code shows how to reach into the skeleton // in order to get specific joint locations (in 3D) PVector[] boneLocationsFirst = new PVector[19]; PVector[] boneLocationsSecond = new PVector[19]; for (int i = 0; i < 19; i ++){ int currentIndex = i; BvhBone currentBoneFirst = myBrekelBvh.parser.getBones().get(currentIndex); PVector currentBonePosFirst = currentBoneFirst.absPos; BvhBone currentBoneSecond = secondBrekelBvh.parser.getBones().get(currentIndex); PVector currentBonePosSecond = currentBoneSecond.absPos; boneLocationsFirst[i] = currentBonePosFirst; boneLocationsSecond[i] = currentBonePosSecond; } for (int j = 0; j < 19; j ++){ for (int z = 0; z < 19; z ++){ PVector currentPosFirst = boneLocationsFirst[j]; PVector secondPosFirst = boneLocationsFirst[z]; PVector currentPosSecond = boneLocationsSecond[j]; PVector secondPosSecond = boneLocationsSecond[z]; stroke(255, 255, 255); strokeWeight(1); // Body Lines pushMatrix(); if (j == 1) { for (int a = 1; a < 4; a ++){ line( 7 * boneLocationsFirst[a].x, 7 * boneLocationsFirst[a].y, boneLocationsFirst[a].z + distance, 7 * boneLocationsFirst[a+1].x, 7 *boneLocationsFirst[a+1].y, boneLocationsFirst[a+1].z + distance); } } if (j == 5) { line( 7 * boneLocationsFirst[3].x, 7 * boneLocationsFirst[3].y, boneLocationsFirst[3].z + distance, 7 * boneLocationsFirst[5].x, 7 * boneLocationsFirst[5].y, boneLocationsFirst[5].z + distance); for (int b = 5; b < 8; b ++){ line( 7 * boneLocationsFirst[b].x, 7 * boneLocationsFirst[b].y, boneLocationsFirst[b].z + distance, 7 * boneLocationsFirst[b+1].x, 7 * boneLocationsFirst[b+1].y, boneLocationsFirst[b+1].z + distance); } } if (j == 9) { line( 7 * boneLocationsFirst[3].x, 7 * boneLocationsFirst[3].y, boneLocationsFirst[3].z + distance, 7 * boneLocationsFirst[9].x, 7 *boneLocationsFirst[9].y, boneLocationsFirst[9].z + distance); for (int c = 9; c < 12; c ++){ line( 7 * boneLocationsFirst[c].x, 7 * boneLocationsFirst[c].y, boneLocationsFirst[c].z + distance, 7 * boneLocationsFirst[c+1].x, 7 *boneLocationsFirst[c+1].y, boneLocationsFirst[c+1].z + distance); } } if (j == 13) { line( 7 * boneLocationsFirst[1].x, 7 * boneLocationsFirst[1].y, boneLocationsFirst[1].z + distance, 7 * boneLocationsFirst[13].x, 7 *boneLocationsFirst[13].y, boneLocationsFirst[13].z + distance); for (int d = 13; d < 15; d ++){ line( 7 * boneLocationsFirst[d].x, 7 * boneLocationsFirst[d].y, boneLocationsFirst[d].z + distance, 7 * boneLocationsFirst[d+1].x, 7 *boneLocationsFirst[d+1].y, boneLocationsFirst[d+1].z + distance); } } if (j == 16) { line( 7 * boneLocationsFirst[1].x, 7 * boneLocationsFirst[1].y, boneLocationsFirst[1].z + distance, 7 * boneLocationsFirst[16].x, 7 *boneLocationsFirst[16].y, boneLocationsFirst[16].z + distance); for (int e = 16; e < 18; e ++){ line( 7 * boneLocationsFirst[e].x, 7 * boneLocationsFirst[e].y, boneLocationsFirst[e].z + distance, 7 * boneLocationsFirst[e+1].x, 7 *boneLocationsFirst[e+1].y, boneLocationsFirst[e+1].z + distance); } } /* translate(0, 0, distance); ellipse(7 * boneLocationsFirst[4].x, 7 * boneLocationsFirst[4].y + 30, 20, 20); */ popMatrix(); ////---------------------- pushMatrix(); if (j == 1) { for (int a = 1; a < 4; a ++){ line( 8 * boneLocationsFirst[a].x, 8 * boneLocationsFirst[a].y, boneLocationsFirst[a].z + distanceFinal, 8 * boneLocationsFirst[a+1].x, 8 *boneLocationsFirst[a+1].y, boneLocationsFirst[a+1].z + distanceFinal); } } if (j == 5) { line( 8 * boneLocationsFirst[3].x, 8 * boneLocationsFirst[3].y, boneLocationsFirst[3].z + distanceFinal, 8 * boneLocationsFirst[5].x, 8 * boneLocationsFirst[5].y, boneLocationsFirst[5].z + distanceFinal); for (int b = 5; b < 8; b ++){ line( 8 * boneLocationsFirst[b].x, 8 * boneLocationsFirst[b].y, boneLocationsFirst[b].z + distanceFinal, 8 * boneLocationsFirst[b+1].x, 8 * boneLocationsFirst[b+1].y, boneLocationsFirst[b+1].z + distanceFinal); } } if (j == 9) { line( 8 * boneLocationsFirst[3].x, 8 * boneLocationsFirst[3].y, boneLocationsFirst[3].z + distanceFinal, 8 * boneLocationsFirst[9].x, 8 *boneLocationsFirst[9].y, boneLocationsFirst[9].z + distanceFinal); for (int c = 9; c < 12; c ++){ line( 8 * boneLocationsFirst[c].x, 8 * boneLocationsFirst[c].y, boneLocationsFirst[c].z + distanceFinal, 8 * boneLocationsFirst[c+1].x, 8 *boneLocationsFirst[c+1].y, boneLocationsFirst[c+1].z + distanceFinal); } } if (j == 13) { line( 8 * boneLocationsFirst[1].x, 8 * boneLocationsFirst[1].y, boneLocationsFirst[1].z + distanceFinal, 8 * boneLocationsFirst[13].x, 8 *boneLocationsFirst[13].y, boneLocationsFirst[13].z + distanceFinal); for (int d = 13; d < 15; d ++){ line( 8 * boneLocationsFirst[d].x, 8 * boneLocationsFirst[d].y, boneLocationsFirst[d].z + distanceFinal, 8 * boneLocationsFirst[d+1].x, 8 *boneLocationsFirst[d+1].y, boneLocationsFirst[d+1].z + distanceFinal); } } if (j == 16) { line( 8 * boneLocationsFirst[1].x, 8 * boneLocationsFirst[1].y, boneLocationsFirst[1].z + distanceFinal, 8 * boneLocationsFirst[16].x, 8 *boneLocationsFirst[16].y, boneLocationsFirst[16].z + distanceFinal); for (int e = 16; e < 18; e ++){ line( 8 * boneLocationsFirst[e].x, 8 * boneLocationsFirst[e].y, boneLocationsFirst[e].z + distanceFinal, 8 * boneLocationsFirst[e+1].x, 8 *boneLocationsFirst[e+1].y, boneLocationsFirst[e+1].z + distanceFinal); } } /* translate(0, 0, distance); ellipse(7 * boneLocationsFirst[4].x, 7 * boneLocationsFirst[4].y + 30, 20, 20); */ popMatrix(); // Points of body to backside origin pushMatrix(); translate(0, 0, 2400); line( 6 * currentPosFirst.x, 6 * currentPosFirst.y, currentPosFirst.z, 0, 0 , -400); popMatrix(); // Points of body to backside origin pushMatrix(); translate(0, 0, 3200); line( 6 * currentPosFirst.x, 6 * currentPosFirst.y, currentPosFirst.z, 0, 0 , -400); popMatrix(); //BaseLine pushMatrix(); stroke(255); line( currentPosFirst.x + 10000, currentPosFirst.y, currentPosFirst.z - 400, currentPosSecond.x - 10000, currentPosSecond.y, currentPosSecond.z - 400); popMatrix(); //Lines extrapolating to one direction pushMatrix(); stroke(255); line( currentPosFirst.x + 10, currentPosFirst.y, currentPosFirst.z, currentPosFirst.x - 10, currentPosFirst.y, currentPosFirst.z); popMatrix(); /* //Lines extrapolating to one direction pushMatrix(); stroke(255); line( currentPosFirst.x + 50, currentPosFirst.y, currentPosFirst.z + 100, currentPosFirst.x - 50, currentPosFirst.y, currentPosFirst.z + 100); popMatrix(); //Lines extrapolating to one direction pushMatrix(); stroke(255); line( currentPosFirst.x + 25, currentPosFirst.y, currentPosFirst.z + 200, currentPosFirst.x - 25, currentPosFirst.y, currentPosFirst.z + 200); popMatrix(); //Lines extrapolating to one direction pushMatrix(); stroke(255); line( currentPosFirst.x + 10, currentPosFirst.y, currentPosFirst.z + 300, currentPosFirst.x - 10, currentPosFirst.y, currentPosFirst.z + 300); popMatrix();*/ //Lines in First Body line( 2 * currentPosFirst.x, 2 * currentPosFirst.y, currentPosFirst.z + 400, 2 * secondPosFirst.z, 2 * secondPosFirst.y, secondPosFirst.z + 400); for (int k = 0; k < 8; k ++){ //Tutu float angle = map(k, 0, 8, 0, TWO_PI); /*if (k % 2 == 0){ stroke(255, 0, 0);} else{ stroke(0, 0, 255);}*/ stroke(255); line( 3 * currentPosFirst.x, 3 * currentPosFirst.y, currentPosFirst.z + 800, 100 * cos(angle), 50, 100 * sin(angle) + 800); /*line( 5 * currentPosSecond.x, 5 * currentPosSecond.y, currentPosSecond.z, 100 * cos(angle), 50, 100 * sin(angle));*/ pushMatrix(); /*if (k % 2 == 0){ stroke(0, 255, 0);} else{ stroke(255, 0, 0);}*/ stroke(255); line( 4 * currentPosFirst.x, 4 * currentPosFirst.y, currentPosFirst.z + 1600, 100 * sin(angle), (100 * cos(angle)), 100 * cos(angle) + 1200); popMatrix(); /*pushMatrix(); translate(0, 0, 1200); stroke(255, 0, 0); ellipse(4 * currentPosFirst.x, 4 * currentPosFirst.y, 10, 10); popMatrix();*/ /*pushMatrix(); translate(0, 0, 2000); stroke(255); ellipse(5 * currentPosFirst.x, 5 * currentPosFirst.y, 5, 5); popMatrix(); */ /*pushMatrix(); translate(0, 0, 2000); stroke(255, 0, 0); ellipse(6 * currentPosFirst.x, 6 * currentPosFirst.y, 50, 50); popMatrix(); pushMatrix(); translate(0, 0, 2000); stroke(255, 0, 0); ellipse(6 * currentPosFirst.x, 6 * currentPosFirst.y, 100, 100); popMatrix(); */ /*pushMatrix(); stroke(255); line( 4 * currentPosFirst.x, 4 * currentPosFirst.y, currentPosFirst.z + 600, 5 * currentPosFirst.x, 5 * currentPosFirst.y, currentPosFirst.z + 1000); translate(0,0, 10000); ellipse(currentPosFirst.x, currentPosFirst.y, 50, 50); popMatrix(); */ } } } } /*pushMatrix(); if (k % 2 == 0){ stroke(0, 255, 0);} else{ stroke(255, 0, 0);} line( currentPosFirst.x, currentPosFirst.y, currentPosFirst.z , 100 * sin(angle), (100 * sin(angle)) + (100 * cos(angle)), 100 * cos(angle)); popMatrix();*/ //Lines extrapolating to one direction to Origin /*pushMatrix(); if (k == 0){ stroke(0, 255, 0);} else if (k == 1){ stroke(255, 0, 0);} else { stroke(0, 0, 255);} translate(-(60*k), 0, 0); line( currentPosSecond.x + (60 * k), currentPosSecond.y, currentPosSecond.z, 0, 200, 200); popMatrix(); */ //------------------------------------------------ void setMyCamera() { // Adjust the position of the camera float eyeX = 650; // x-coordinate for the eye float eyeY = yCamera; //height/2.0f - 200; // y-coordinate for the eye float eyeZ = mouseY * 8; // z-coordinate for the eye float centerX = width/2.0f; // x-coordinate for the center of the scene float centerY = height/2.0f; // y-coordinate for the center of the scene float centerZ = -400; // z-coordinate for the center of the scene float upX = 0; // usually 0.0, 1.0, or -1.0 float upY = 1; // usually 0.0, 1.0, or -1.0 float upZ = 0; // usually 0.0, 1.0, or -1.0 camera(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ); } //------------------------------------------------ void drawMyGround() { // Draw a grid in the center of the ground pushMatrix(); translate(width/2, height/2, 0); // position the body in space scale(-1, -1, 1); stroke(100); strokeWeight(1); float gridSize = 400; int nGridDivisions = 10; for (int col=0; col<=nGridDivisions; col++) { float x = map(col, 0, nGridDivisions, -gridSize, gridSize); line (x, 0, -gridSize, x, 0, gridSize); } for (int row=0; row<=nGridDivisions; row++) { float z = map(row, 0, nGridDivisions, -gridSize, gridSize); line (-gridSize, 0, z, gridSize, 0, z); } popMatrix(); } |