// segment names static final int HEAD_NECK=0; static final int LEFT_SHOULDER_LEFT_ELBOW=1; static final int LEFT_ELBOW_LEFT_HAND=2; static final int LEFT_HIP_LEFT_KNEE=3; static final int LEFT_KNEE_LEFT_FOOT=4; static final int RIGHT_SHOULDER_RIGHT_ELBOW=5; static final int RIGHT_ELBOW_RIGHT_HAND=6; static final int RIGHT_HIP_RIGHT_KNEE=7; static final int RIGHT_KNEE_RIGHT_FOOT=8; static final int SHOULDERS_HIPS=9; static final int LEFT_HIP_RIGHT_HIP=10; int[] attachX = { -20, // left arm -65, -65, // left leg -50, -45, // right arm 65, 65, // right leg 50, 45, 0, 0, 0 }; int[] attachY = { -20, // left arm -10, -5, // left leg 30, 40, // right arm -10, -5, // right leg 30, 40, 0, 0, 0 }; class PaperDoll { // joint names static final int HEAD=0; static final int NECK=1; static final int LEFT_SHOULDER=2; static final int LEFT_ELBOW=3; static final int LEFT_HAND=4; static final int RIGHT_SHOULDER=5; static final int RIGHT_ELBOW=6; static final int RIGHT_HAND=7; static final int LEFT_HIP=8; static final int LEFT_KNEE=9; static final int LEFT_FOOT=10; static final int RIGHT_HIP=11; static final int RIGHT_KNEE=12; static final int RIGHT_FOOT=13; //static final int numSegments = 2; //static final int numLimbs=5; static final int numSegments=15; float[] x = new float[numSegments]; float[] y = new float[numSegments]; float[] angle = new float[numSegments]; float[] len = new float[numSegments]; int[] texNums = new int[numSegments]; //float[][] x = new float[numLimbs][numSegments]; //float[][] y = new float[numLimbs][numSegments]; //float[][] = new PVector[numLimbs][numSegments]; //float[][] angle = new float[numLimbs][numSegments]; //float[][] len = new float[numLimbs][numSegments]; float segLength = 100; float targetX, targetY; PImage bodyTextures[] = new PImage[11]; //int[][] texNums = new int[numLimbs][numSegments]; PaperDoll() { // assign texture indices texNums[0]=SHOULDERS_HIPS; texNums[1]=LEFT_SHOULDER_LEFT_ELBOW; texNums[2]=LEFT_ELBOW_LEFT_HAND; texNums[3]=LEFT_HIP_LEFT_KNEE; texNums[4]=LEFT_KNEE_LEFT_FOOT; texNums[5]=RIGHT_SHOULDER_RIGHT_ELBOW; texNums[6]=RIGHT_ELBOW_RIGHT_HAND; texNums[7]=RIGHT_HIP_RIGHT_KNEE; texNums[8]=RIGHT_KNEE_RIGHT_FOOT; texNums[9]=HEAD_NECK; } void constrainCoords(float sx[], float sy[]) { // assign torso coords float x1, y1, x2, y2; x1=(sx[LEFT_SHOULDER]+sx[RIGHT_SHOULDER])/2.0; y1=(sy[LEFT_SHOULDER]+sy[RIGHT_SHOULDER])/2.0; x2=(sx[LEFT_HIP]+sx[RIGHT_HIP])/2.0; y2=(sy[LEFT_HIP]+sy[RIGHT_HIP])/2.0; x[HEAD_NECK]=x1; y[HEAD_NECK]=y1; angle[SHOULDERS_HIPS]=atan2(y2-y1, x2-x1); angle[HEAD_NECK]=angle[SHOULDERS_HIPS]-PI; float dx=0.15*(float)doll.bodyTextures[SHOULDERS_HIPS].width*cos((angle[SHOULDERS_HIPS]-HALF_PI)); float dy=0.15*(float)doll.bodyTextures[SHOULDERS_HIPS].width*sin((angle[SHOULDERS_HIPS]-HALF_PI)); x[LEFT_SHOULDER_LEFT_ELBOW]=x1-dx; y[LEFT_SHOULDER_LEFT_ELBOW]=y1-dy; x[RIGHT_SHOULDER_RIGHT_ELBOW]=x1+dx; y[RIGHT_SHOULDER_RIGHT_ELBOW]=y1-dy; x[LEFT_HIP_LEFT_KNEE]=x2-dx; y[LEFT_HIP_LEFT_KNEE]=y2+dy; x[RIGHT_HIP_RIGHT_KNEE]=x2+dx; y[RIGHT_HIP_RIGHT_KNEE]=y2+dy; // reachLimbs reachLimbs(); } void reachLimbs() { // left arm reachSegment(LEFT_SHOULDER_LEFT_ELBOW, sx[LEFT_HAND], sy[LEFT_HAND]); reachSegment(LEFT_ELBOW_LEFT_HAND, targetX, targetY); positionSegment(LEFT_SHOULDER_LEFT_ELBOW, LEFT_ELBOW_LEFT_HAND); // right arm reachSegment(RIGHT_SHOULDER_RIGHT_ELBOW, sx[RIGHT_HAND], sy[RIGHT_HAND]); reachSegment(RIGHT_ELBOW_RIGHT_HAND, targetX, targetY); positionSegment(RIGHT_SHOULDER_RIGHT_ELBOW, RIGHT_ELBOW_RIGHT_HAND); // left leg reachSegment(LEFT_HIP_LEFT_KNEE, sx[LEFT_FOOT], sy[LEFT_FOOT]); reachSegment(LEFT_KNEE_LEFT_FOOT, targetX, targetY); positionSegment(LEFT_HIP_LEFT_KNEE, LEFT_KNEE_LEFT_FOOT); // right leg reachSegment(RIGHT_HIP_RIGHT_KNEE, sx[RIGHT_FOOT], sy[RIGHT_FOOT]); reachSegment(RIGHT_KNEE_RIGHT_FOOT, targetX, targetY); positionSegment(RIGHT_HIP_RIGHT_KNEE, RIGHT_KNEE_RIGHT_FOOT); } void reachSegment(int seg, float xin, float yin) { float dx = xin - x[seg]; float dy = yin - y[seg]; angle[seg] = atan2(dy, dx); targetX = xin - cos(angle[seg]) * len[seg];//segLength; targetY = yin - sin(angle[seg]) * len[seg];//segLength; } void positionSegment(int seg1, int seg2) { x[seg2] = x[seg1] + cos(angle[seg1]) * len[seg1];//segLength; y[seg2] = y[seg1] + sin(angle[seg1]) * len[seg1];//segLength; } void drawDoll() { drawTorso(); drawHead(); drawLimbs(); } void drawTorso() { int tex=SHOULDERS_HIPS; noStroke(); beginShape(); texture(doll.bodyTextures[tex]); vertex(x[LEFT_SHOULDER_LEFT_ELBOW], y[LEFT_SHOULDER_LEFT_ELBOW], 0.0, 0.0, 0.0); vertex(x[LEFT_HIP_LEFT_KNEE], y[LEFT_HIP_LEFT_KNEE], 0.0, 0.0, (float)doll.bodyTextures[tex].height); vertex(x[RIGHT_HIP_RIGHT_KNEE], y[RIGHT_HIP_RIGHT_KNEE], 0.0, (float)doll.bodyTextures[tex].width, (float)doll.bodyTextures[tex].height); vertex(x[RIGHT_SHOULDER_RIGHT_ELBOW], y[RIGHT_SHOULDER_RIGHT_ELBOW], (float) doll.bodyTextures[tex].width, 0.0); endShape(); } void drawHead() { // calc head coords // from neck position and head angle int tex=HEAD_NECK; float tw=0.3*(float)doll.bodyTextures[tex].width*cos((angle[HEAD_NECK]-HALF_PI));//doll.bodyTextures[currtex].width; float th=0.3*(float)doll.bodyTextures[tex].width*sin((angle[HEAD_NECK]-HALF_PI)); float x2=x[HEAD_NECK]-attachX[HEAD_NECK]; float y2=y[HEAD_NECK]-attachY[HEAD_NECK]; float x1=x2+len[HEAD_NECK]*cos(angle[HEAD_NECK]); float y1=y2+len[HEAD_NECK]*sin(angle[HEAD_NECK]); // draw head noStroke(); beginShape(); texture(doll.bodyTextures[tex]); vertex(x1, y1, 0.0, 0.0, 0.0); vertex(x2, y2, 0.0, 0.0, (float)doll.bodyTextures[tex].height); vertex(x2+tw, y2+th, 0.0, (float)doll.bodyTextures[tex].width, (float)doll.bodyTextures[tex].height); vertex(x1+tw, y1+th, 0.0, (float) doll.bodyTextures[tex].width, 0.0); endShape(); } void drawLimbs() { // left arm drawTexturedSegment(LEFT_SHOULDER_LEFT_ELBOW, x[LEFT_SHOULDER_LEFT_ELBOW], y[LEFT_SHOULDER_LEFT_ELBOW], angle[LEFT_SHOULDER_LEFT_ELBOW]); drawTexturedSegment(LEFT_ELBOW_LEFT_HAND, x[LEFT_ELBOW_LEFT_HAND], y[LEFT_ELBOW_LEFT_HAND], angle[LEFT_ELBOW_LEFT_HAND]); // right arm drawTexturedSegment(RIGHT_SHOULDER_RIGHT_ELBOW, x[RIGHT_SHOULDER_RIGHT_ELBOW], y[RIGHT_SHOULDER_RIGHT_ELBOW], angle[RIGHT_SHOULDER_RIGHT_ELBOW]); drawTexturedSegment(RIGHT_ELBOW_RIGHT_HAND, x[RIGHT_ELBOW_RIGHT_HAND], y[RIGHT_ELBOW_RIGHT_HAND], angle[RIGHT_ELBOW_RIGHT_HAND]); // left leg drawTexturedSegment(LEFT_HIP_LEFT_KNEE, x[LEFT_HIP_LEFT_KNEE], y[LEFT_HIP_LEFT_KNEE], angle[LEFT_HIP_LEFT_KNEE]); drawTexturedSegment(LEFT_KNEE_LEFT_FOOT, x[LEFT_KNEE_LEFT_FOOT], y[LEFT_KNEE_LEFT_FOOT], angle[LEFT_KNEE_LEFT_FOOT]); // right leg drawTexturedSegment(RIGHT_HIP_RIGHT_KNEE, x[RIGHT_HIP_RIGHT_KNEE], y[RIGHT_HIP_RIGHT_KNEE], angle[RIGHT_HIP_RIGHT_KNEE]); drawTexturedSegment(RIGHT_KNEE_RIGHT_FOOT, x[RIGHT_KNEE_RIGHT_FOOT], y[RIGHT_KNEE_RIGHT_FOOT], angle[RIGHT_KNEE_RIGHT_FOOT]); } void drawTexturedSegment(int seg, float x, float y, float a) { int currtex = texNums[seg]; x=x-attachX[seg]; y=y-attachY[seg]; float tw=0.15*(float)doll.bodyTextures[currtex].width*cos((a-HALF_PI));//doll.bodyTextures[currtex].width; float th=0.15*(float)doll.bodyTextures[currtex].width*sin((a-HALF_PI)); float x2=x+len[seg]*cos(a); float y2=y+len[seg]*sin(a); noStroke(); beginShape(); texture(doll.bodyTextures[currtex]); vertex(x-tw, y-th, 0.0, 0.0, 0.0); vertex(x2-tw, y2-th, 0.0, 0.0, (float)doll.bodyTextures[currtex].height); vertex(x2+tw, y2+th, 0.0, (float)doll.bodyTextures[currtex].width, (float)doll.bodyTextures[currtex].height); vertex(x+tw, y+th, 0.0, (float) doll.bodyTextures[currtex].width, 0.0); endShape(); } void loadBodyTextures() { //String basepath = "/Users/rtwomey/Pictures/kpuppet/rauschenberg_"; String basepath = "/Users/rtwomey/Pictures/puppet/warrior_princess_screen/"; bodyTextures[HEAD_NECK]=loadImage(basepath+"HEAD_NECK.png"); bodyTextures[LEFT_SHOULDER_LEFT_ELBOW]=loadImage(basepath+"LEFT_SHOULDER_LEFT_ELBOW.png"); bodyTextures[LEFT_ELBOW_LEFT_HAND]=loadImage(basepath+"LEFT_ELBOW_LEFT_HAND.png"); bodyTextures[LEFT_HIP_LEFT_KNEE]=loadImage(basepath+"LEFT_HIP_LEFT_KNEE.png"); bodyTextures[LEFT_KNEE_LEFT_FOOT]=loadImage(basepath+"LEFT_KNEE_LEFT_FOOT.png"); bodyTextures[RIGHT_SHOULDER_RIGHT_ELBOW]=loadImage(basepath+"RIGHT_SHOULDER_RIGHT_ELBOW.png"); bodyTextures[RIGHT_ELBOW_RIGHT_HAND]=loadImage(basepath+"RIGHT_ELBOW_RIGHT_HAND.png"); bodyTextures[RIGHT_HIP_RIGHT_KNEE]=loadImage(basepath+"RIGHT_HIP_RIGHT_KNEE.png"); bodyTextures[RIGHT_KNEE_RIGHT_FOOT]=loadImage(basepath+"RIGHT_KNEE_RIGHT_FOOT.png"); bodyTextures[SHOULDERS_HIPS]=loadImage(basepath+"SHOULDERS_HIPS.png"); //bodyTextures[LEFT_HIP_RIGHT_HIP]=loadImage(basepath+"LEFT_HIP_RIGHT_HIP.jpg"); println("done loading body textures."); float sf=0.3; len[HEAD_NECK]=bodyTextures[HEAD_NECK].height*sf; len[LEFT_SHOULDER_LEFT_ELBOW]=bodyTextures[LEFT_SHOULDER_LEFT_ELBOW].height*sf; len[RIGHT_SHOULDER_RIGHT_ELBOW]=bodyTextures[RIGHT_SHOULDER_RIGHT_ELBOW].height*sf; len[LEFT_ELBOW_LEFT_HAND]=bodyTextures[LEFT_ELBOW_LEFT_HAND].height*sf; len[RIGHT_ELBOW_RIGHT_HAND]=bodyTextures[RIGHT_ELBOW_RIGHT_HAND].height*sf; len[LEFT_HIP_LEFT_KNEE]=bodyTextures[LEFT_HIP_LEFT_KNEE].height*sf; len[RIGHT_HIP_RIGHT_KNEE]=bodyTextures[RIGHT_HIP_RIGHT_KNEE].height*sf; len[LEFT_KNEE_LEFT_FOOT]=bodyTextures[LEFT_KNEE_LEFT_FOOT].height*sf; len[RIGHT_KNEE_RIGHT_FOOT]=bodyTextures[RIGHT_KNEE_RIGHT_FOOT].height*sf; len[SHOULDERS_HIPS]=bodyTextures[SHOULDERS_HIPS].height*sf; } }