Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Processing 2 Creative Coding Hotshot.pdf
Скачиваний:
10
Добавлен:
17.03.2016
Размер:
5.28 Mб
Скачать

The Stick Figure Dance Company

Objective Complete - Mini Debriefing

We have just learned how to use Kinect's skeleton tracking function. To get the coordinates of the limbs and joints, we added two new callback functions; one to be notified for when Kinect starts the calibration, and a second one when a user pose is detected.

To enable the user of our sketch to see the current status of the recognition and calibration, we added a little HUD display in step 5. Our HUD display is very similar to the sketch we created in the previous task, but because we don't want to use the entire window for displaying the depth map and user pixels, we need to convert the coordinates of our pixels and the indices of the pixel array.

We use the coordinates of the skeleton tracker in our drawDancer() method to draw a stick figure in step 8. The jointPositionSkeleton() method of the SimpleOpenNI context is used to load the joint positions into a PVector variable, which we use to draw the limbs with the line() method.

And finally, we made a simple dance floor for our stick figure to dance on in step 9 by drawing a gray rectangle. We used beginShape() and endShape() to define the shape, and added the coordinates of the corners using the vertex() method.

Classified Intel

The SimpleOpenNI context doesn't just provide the location of the joints, it also provides a direction vector. As we're only drawing a stick figure in this project to keep things simple, we haven't made use of this direction vector. But if you plan to control a more complicated figure like a rigged 3D model that you exported from a 3D modeling program like Blender, this information can be used to calculate the rotation and twist of the model's vertices.

You might also need this information if you need to test where an object got hit and in which direction it would fly away.

Dance! Dance! Dance!

In this final task of the stick figure dance company project, we finally come to the "company" part. So far, we've created one lonely stick figure dancer that is moving in its own little virtual world. And this is going out of fashion. We will now add some more dancers by cloning the one we've already created; to prevent our dancers from being indistinguishable, we will add a little variation here and there.

To make our code more readable, we will create a new class that holds our stick figure data and is responsible for drawing the body of one figure. This class is also used to store the color and size of each dancer.

46

Project 2

We will place the dancers in the draw() method and use the translate() method to draw each dancer in another location on the dancefloor.

Engage Thrusters

Let's add more dancers:

1.Open the sketch you created in the Making a dancer task, and add a new class by clicking on the little arrow icon on the right and choosing New Tab from the menu. The new class is called Figure, so name the tab accordingly and add the following code:

public class Figure {

}

2.Now add an array of PVector objects to your class (which will store the coordinates you get from the Kinect) and an array with the same size containing the names of the OpenNI constants that identify each joint.

public class Figure {

PVector[] joints;

int[] ni_names = new int[] { SimpleOpenNI.SKEL_HEAD, SimpleOpenNI.SKEL_NECK, SimpleOpenNI.SKEL_TORSO, SimpleOpenNI.SKEL_LEFT_SHOULDER, SimpleOpenNI.SKEL_LEFT_ELBOW, SimpleOpenNI.SKEL_LEFT_HAND, SimpleOpenNI.SKEL_RIGHT_SHOULDER, SimpleOpenNI.SKEL_RIGHT_ELBOW, SimpleOpenNI.SKEL_RIGHT_HAND, SimpleOpenNI.SKEL_LEFT_HIP, SimpleOpenNI.SKEL_LEFT_KNEE, SimpleOpenNI.SKEL_LEFT_FOOT, SimpleOpenNI.SKEL_RIGHT_HIP, SimpleOpenNI.SKEL_RIGHT_KNEE, SimpleOpenNI.SKEL_RIGHT_FOOT

};

}

3.To initialize the joints array, you need a constructor for your Figure class, which looks like this:

public Figure() {

joints = new PVector[15];

for( int i=0; i<joints.length; i++ ) {

47

The Stick Figure Dance Company

joints[i] = new PVector();

}

}

4.You also need to add some constants to your class to be able to identify the entries in the array of coordinates without having to know the numerical indices in the array.

public class Figure { static final int HEAD=0; static final int NECK=1; static final int TORSO=2;

static final int L_SHOULDER=3; static final int L_ELBOW=4; static final int L_HAND=5; static final int R_SHOULDER=6; static final int R_ELBOW=7; static final int R_HAND=8; static final int L_HIP=9; static final int L_KNEE=10; static final int L_FOOT=11; static final int R_HIP=12; static final int R_KNEE=13; static final int R_FOOT=14;

5.For each frame, the Kinect provides you with an updated set of coordinates; so you need to add an update() method that gets a reference to SimpleOpenNI context and userId. As you've added the names of the coordinates to an array, you can simply use a for loop to copy them to your PVector array.

public void update( SimpleOpenNI context, int userId ) { for ( int i=0; i<joints.length; i++) {

context.getJointPositionSkeleton( userId, ni_names[i], joints[i]);

}

}

6.You don't want every figure to look exactly the same, so you will have to scale each figure a little. Add the following variables to the class:

float sx = 1; float sy = 1; float sz = 1; color c = 0;

48

Project 2

7.Now add a function named randomize(), which initializes the values for scaling and chooses a color.

public void randomize() { sx = random( 0.9, 1.1 ); sy = random( 0.9, 1.1 ); sz = random( 0.9, 1.1 );

colorMode( HSB );

c = color( random( 255 ), 255, 255 ); colorMode( RGB );

}

8.You have initialized your randomization values and updated your coordinates; now you need to draw your stick figure. To simplify the drawing, you need to add a new method called drawLimb(), which gets the index of the first and second coordinate for which you want the line to be drawn.

public void drawLimb(int idx1, int idx2 ) {

line( joints[idx1].x, joints[idx1].y, joints[idx1].z, joints[idx2].x, joints[idx2].y, joints[idx2].z );

}

9.To implement the actual drawing of the stick figures, you need to create a draw() method in your Figure class. First, you need to set the drawing color to the random color you generated for your figure in the randomize() method, and then set the scaling to your sx, sy, and sz values.

public void draw() { strokeWeight( 2 ); stroke( c ); fill( c ); pushMatrix();

scale( sx, sy, sz );

10. Now you need to add the code to draw the head and the lines for the body.

pushMatrix();

translate( joints[HEAD].x, joints[HEAD].y, joints[HEAD].z ); scale( .5, .5, 1);

sphere( joints[HEAD].dist( joints[NECK] )); popMatrix();

drawLimb( NECK, HEAD ); drawLimb( NECK, L_SHOULDER );

49

The Stick Figure Dance Company

drawLimb( L_SHOULDER, L_ELBOW ); drawLimb( L_ELBOW, L_HAND );

drawLimb( NECK, R_SHOULDER ); drawLimb( R_SHOULDER, R_ELBOW ); drawLimb( R_ELBOW, R_HAND );

drawLimb( NECK, TORSO ); drawLimb( TORSO, L_HIP ); drawLimb( TORSO, R_HIP ); drawLimb( L_HIP, R_HIP );

drawLimb( L_HIP, L_KNEE ); drawLimb( L_KNEE, L_FOOT );

drawLimb( R_HIP, R_KNEE ); drawLimb( R_KNEE, R_FOOT ); popMatrix();

}

11.Switch back to the main tab of the sketch and change the figure variable you defined in the last task to a two-dimensional array of Figure objects.

Figure figures[][] = new Figure[5][4];

12.Now add the following lines in the setup() method to initialize the array. To make every little dancer look a bit different, call the randomize() method you added to the Figure class:

void setup() {

size( 1024, 768, P3D);

context = new SimpleOpenNI( this ); context.enableDepth();

context.enableUser( SimpleOpenNI.SKEL_PROFILE_ALL);

smooth();

lights();

for ( int i = 0; i<5; i++) { for ( int j=0; j<4; j++) {

figures[i][j] = new Figure(); figures[i][j].randomize();

}

}

}

50

Project 2

13.In the drawDancer() method, you need to call the update() function of every figure object that you have created. We need to use the translate() function to move each figure to a different position to make sure they aren't drawn on top of each other.

void drawDancer() {

if ( player != -1 && context.isTrackingSkeleton( player )) { for ( int j=-2; j< 3; j++ ) {

for ( int k = 0; k < 4; k++) { figures[j+2][k].update( context, player ); pushMatrix();

translate( 100*j, 0, -100*k); scale( .1 ); figures[j+2][k].draw(); popMatrix();

}

}

}

}

14.Now start your music, stand in front of the Kinect, and start dancing. Your little stick figures will copy all your awesome dance moves without ever getting tired. You can see my dance company in this screenshot:

51

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]