Browse files

new examples and fixes for 3D sketches after Ravensbourne Digital Sto…

…rytelling 3D conference in March 2012
  • Loading branch information...
1 parent b05702f commit 03bde651290b06097f19652c48f0c5a8121694af @pixelpusher committed Mar 27, 2012
Showing with 3,180 additions and 179 deletions.
  1. +100 −90 MarioFireBall3D/MarioFireBall3D.pde
  2. +1 −1 MarioFireBall3D/ParticleSwarm.pde
  3. +45 −68 MarioFireBall3D/SwarmStuff.pde
  4. +264 −0 SkeletonObjectsExample3D/BodyPart.java
  5. +77 −0 SkeletonObjectsExample3D/BodyPartFactory.java
  6. +36 −0 SkeletonObjectsExample3D/BodyPartRenderer.java
  7. +498 −0 SkeletonObjectsExample3D/BoxRenderer.pde
  8. +525 −0 SkeletonObjectsExample3D/DrawingStuff.pde
  9. +157 −0 SkeletonObjectsExample3D/FourPointBodyPart.java
  10. +82 −0 SkeletonObjectsExample3D/OnePointBodyPart.java
  11. +164 −0 SkeletonObjectsExample3D/OpenNIEvents.pde
  12. +440 −0 SkeletonObjectsExample3D/ParticleBodyPartRenderer.pde
  13. +98 −0 SkeletonObjectsExample3D/Skeleton.java
  14. +435 −0 SkeletonObjectsExample3D/SkeletonObjectsExample3D.pde
  15. +109 −0 SkeletonObjectsExample3D/TwoPointBodyPart.java
  16. +140 −0 SkeletonObjectsExample3D/Vec2D.pde
  17. BIN SkeletonObjectsExample3D/data/FieryMarioBody.png
  18. BIN SkeletonObjectsExample3D/data/FieryMarioHead.png
  19. BIN SkeletonObjectsExample3D/data/FieryMarioLeftArm.png
  20. BIN SkeletonObjectsExample3D/data/FieryMarioLeftLeg.png
  21. BIN SkeletonObjectsExample3D/data/doughnutbody.png
  22. BIN SkeletonObjectsExample3D/data/doughnutbottomarm1.png
  23. BIN SkeletonObjectsExample3D/data/doughnutbottomarm2.png
  24. BIN SkeletonObjectsExample3D/data/doughnutleg.png
  25. BIN SkeletonObjectsExample3D/data/doughnuttoparm.png
  26. BIN SkeletonObjectsExample3D/data/mario_bg.png
  27. BIN SkeletonObjectsExample3D/data/mario_fireball.png
  28. BIN SkeletonObjectsExample3D/data/toparm.png
  29. BIN SkeletonObjectsExample3D/data/topleg.png
  30. BIN SkeletonObjectsExample3D/kinect2012-3-27_11.40.36.png
  31. BIN SkeletonObjectsExample3D/kinect2012-3-27_11.55.53.png
  32. BIN SkeletonObjectsExample3D/kinect2012-3-27_11.56.57.png
  33. +9 −20 _3DMouseBarTest/_3DMouseBarTest.pde
View
190 MarioFireBall3D/MarioFireBall3D.pde
@@ -24,21 +24,27 @@ TriangleMesh origMesh, mesh;
AxisAlignedCylinder cyl;
PeasyCam cam;
+color userColors[];
+
float MESH_X_SCALE = 10.0;
float MESH_Y_SCALE = 10.0;
GLGraphicsOffScreen leftBuffer, rightBuffer;
float panAmt = -4.6;
float panAngle = -0.04;
float depthScale;
+IntVector userList;
+
+PVector[] userCoMs;
-void init() {
+void init()
+{
frame.dispose();
frame.setUndecorated(true);
super.init();
}
-ImageParticleSwarm swarm;
+ImageParticleSwarm swarms[];
ParticleExpander particleExpander;
@@ -58,7 +64,6 @@ boolean mouseWasDown = false;
float MIN_DIST = 2.0f;
float weight=0;
-LinkedList<ImageParticleSwarm> swarms;
GLTexture fireballTex;
// images for body parts and background:
@@ -92,7 +97,7 @@ PVector rightFootPos = new PVector();
// Kinect-specific variables
SimpleOpenNI context;
-MoveDetect md;
+MoveDetect[] md;
int currentId = -1;
@@ -115,7 +120,31 @@ void setup()
//cam.pan(-panAmt, 0);
context = new SimpleOpenNI(this);
- md = new MoveDetect();
+ md = new MoveDetect[16];
+
+ for (int m=0; m<md.length; m++)
+ md[m] = new MoveDetect();
+
+ userCoMs = new PVector[16];
+ for (int v=0; v<userCoMs.length; v++)
+// for (PVector v : userCoMs)
+ userCoMs[v] = new PVector();
+
+ userList = new IntVector();
+
+ userColors = new color[16];
+
+ swarms = new ImageParticleSwarm[16];
+
+ for (int s=0; s < swarms.length; s++)
+ {
+ swarms[s] = null;
+ }
+
+ for (int i=0; i<16; i++)
+ {
+ userColors[i] = color(random(0, 255), random(0, 255), random(0, 255));
+ }
// enable depthMap generation
context.enableDepth();
@@ -134,7 +163,7 @@ void setup()
depthScale = height/4f;
// create fireball particle "swarm"
- swarms = new LinkedList<ImageParticleSwarm>();
+
particleExpander = new ParticleExpander();
// fire trail
@@ -163,7 +192,6 @@ void setup()
void drawIntoBuffer(GLGraphicsOffScreen buffer)
{
-
buffer.beginDraw();
buffer.camera();
//buffer.lights();
@@ -173,6 +201,18 @@ void drawIntoBuffer(GLGraphicsOffScreen buffer)
buffer.fill(255, 180);
buffer.noStroke();
renderer = buffer;
+
+ for (int u=0; u< userList.size(); u++)
+ {
+ int user = userList.get(u);
+ PVector pos = userCoMs[user];
+
+ buffer.pushMatrix();
+ buffer.translate(pos.x, pos.y, pos.z);
+ fill(userColors[user]);
+ buffer.ellipse(0, 0, 200, 200);
+ buffer.popMatrix();
+ }
//renderRectFromVectors( leftElbowPos, leftHandPos, 20);
renderRectFromVectors( facePos, neckPos, 20);
@@ -195,11 +235,17 @@ void drawIntoBuffer(GLGraphicsOffScreen buffer)
int currentTime = millis();
- for (ImageParticleSwarm swarm : swarms)
+
+ for (int s = 0; s < swarms.length; s++)
{
- if (go)
- swarm.update(particleExpander, currentTime);
- swarm.render(buffer);
+ ImageParticleSwarm swarm = swarms[s];
+
+ if (swarm != null)
+ {
+ if (go)
+ swarm.update(particleExpander, currentTime);
+ swarm.render(buffer);
+ }
}
buffer.setDepthMask(true);
@@ -222,6 +268,7 @@ float worldZtoScreenZ(float z)
}
+
/////////////////////////////////////////////
// DRAW
//
@@ -231,12 +278,25 @@ void draw()
// update the Kinect cam
context.update();
-// for (int i=1; i<3; i++)
-if (currentId > -1)
+ int userCount = context.getNumberOfUsers();
+ if (userCount > 0)
{
- int i = currentId;
-
+ context.getUsers(userList);
+
+ for (int u=0; u< userList.size(); u++)
+ {
+ int user = userList.get(u);
+ context.getCoM(user, userCoMs[user]);
+
+ int i = user;
+
+ // for (int i=1; i<3; i++)
+ //if (currentId > -1)
+ // {
+ // int i = currentId;
+
+
// draw the skeleton if it's available
if (context.isTrackingSkeleton(i))
{
@@ -282,22 +342,22 @@ if (currentId > -1)
if (go)
{
// calculate new joint movement function sample
- md.jointMovementFunction(i, SimpleOpenNI.SKEL_LEFT_HAND);
+ md[i].jointMovementFunction(i, SimpleOpenNI.SKEL_LEFT_HAND);
- if (md.swipeStart == 1)
+ if (md[i].swipeStart == 1)
{
handJerked();
//println("ONSET START:::::" + millis());
}
- else if (md.onsetState == 1)
+ else if (md[i].onsetState == 1)
{
handMoved();
}
else
- if (md.swipeEnd == 1)
+ if (md[i].swipeEnd == 1)
{
- newSwarm(fireballTex, triMesh);
+ newSwarm(fireballTex, triMesh, i);
//println("ONSET END:::::" + millis());
}
}
@@ -333,27 +393,9 @@ if (currentId > -1)
// end for each user detected
}
-
-
- // draw particle systems
- // rotate around center of screen (accounted for in mouseDragged() function)
-
- /*
- drawHandPositions();
-
-
- // draw mesh as polygon (in white)
- drawMesh();
-
- // draw mesh unique points only (in green)
- drawMeshUniqueVerts();
- */
-
- // udpate rotation
- // rotation.addSelf(0.014, 0.0237);
- if (go)
- rotation.set(map(md.prev_x, 0, 640, -0.01, 0.01), 0.0057);
- // popMatrix();
+ }
+ // if (go)
+ // rotation.set(map(mouseX, 0, 640, -0.01, 0.01), 0.0057);
CameraState camState = cam.getState();
@@ -371,8 +413,8 @@ if (currentId > -1)
image(context.sceneImage(), width/2, 0, width/2, height);
}
cam.endHUD();
- //noTint();
-
+ //noTint();
+
cam.rotateX(-rotation.x);
cam.rotateY(-rotation.y);
@@ -406,57 +448,35 @@ void vertex(Vec3D v) {
-
-
-// draw the skeleton with the selected joints
-void drawSkeleton(int userId)
-{
- stroke(255);
- strokeWeight(2);
-
- context.drawLimb(userId, SimpleOpenNI.SKEL_HEAD, SimpleOpenNI.SKEL_NECK);
-
- context.drawLimb(userId, SimpleOpenNI.SKEL_NECK, SimpleOpenNI.SKEL_LEFT_SHOULDER);
- context.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER, SimpleOpenNI.SKEL_LEFT_ELBOW);
- context.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_ELBOW, SimpleOpenNI.SKEL_LEFT_HAND);
-
- context.drawLimb(userId, SimpleOpenNI.SKEL_NECK, SimpleOpenNI.SKEL_RIGHT_SHOULDER);
- context.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER, SimpleOpenNI.SKEL_RIGHT_ELBOW);
- context.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_ELBOW, SimpleOpenNI.SKEL_RIGHT_HAND);
-
- context.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER, SimpleOpenNI.SKEL_TORSO);
- context.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER, SimpleOpenNI.SKEL_TORSO);
-
- context.drawLimb(userId, SimpleOpenNI.SKEL_TORSO, SimpleOpenNI.SKEL_LEFT_HIP);
- context.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_HIP, SimpleOpenNI.SKEL_LEFT_KNEE);
- context.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_KNEE, SimpleOpenNI.SKEL_LEFT_FOOT);
-
- context.drawLimb(userId, SimpleOpenNI.SKEL_TORSO, SimpleOpenNI.SKEL_RIGHT_HIP);
- context.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_HIP, SimpleOpenNI.SKEL_RIGHT_KNEE);
- context.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_KNEE, SimpleOpenNI.SKEL_RIGHT_FOOT);
-}
-
-
// -----------------------------------------------------------------
// SimpleOpenNI events
void onNewUser(int userId)
{
println("onNewUser - userId: " + userId);
println(" start pose detection");
- if (currentId == -1)drawBG = true;
+ // if (currentId == -1) drawBG = true;
context.startPoseDetection("Psi", userId);
}
void onLostUser(int userId)
{
println("onLostUser - userId: " + userId);
- if (userId == currentId)
- {
- currentId = -1;
+
+ swarms[userId].destroy();
+ swarms[userId] = null;
+
+ context.getUsers(userList);
+
+ if ( userList.size() < 1)
drawBG = true;
- }
+
+ // if (userId == currentId)
+ // {
+ // currentId = -1;
+ // drawBG = true;
+ // }
}
void onStartCalibration(int userId)
@@ -474,7 +494,7 @@ void onEndCalibration(int userId, boolean successfull)
context.startTrackingSkeleton(userId);
drawBG = false;
currentId = userId;
- md.reset();
+ md[userId].reset();
}
else
{
@@ -550,17 +570,7 @@ void keyReleased()
{
switch(keyCode)
{
- case UP:
- md.SMOOTHING += 0.05;
- break;
-
- case DOWN:
- md.SMOOTHING -= 0.05;
- break;
}
-
- md.SMOOTHING = constrain(md.SMOOTHING, 0.0f, 1.0f);
- println("SMOOTHING: " + md.SMOOTHING);
}
}
View
2 MarioFireBall3D/ParticleSwarm.pde
@@ -208,7 +208,7 @@ class ImageParticleSwarm
void update(ParticleBehaviour particleBehaviour, int currentTime )
{
- if (mAlive)
+ if (mAlive && glmodel != null)
{
int timeDiff = currentTime-mCreationTime;
if (timeDiff >= mLifeTime)
View
113 MarioFireBall3D/SwarmStuff.pde
@@ -1,36 +1,15 @@
-ImageParticleSwarm newSwarm(GLTexture tex, TriangleMesh mesh)
+ImageParticleSwarm newSwarm(GLTexture tex, TriangleMesh mesh, int id)
{
- swarm = new ImageParticleSwarm(this, tex);
- /*
- if (swarm.makeModel( handPositions ))
- {
- swarms.add( swarm );
+ if (swarms[id] != null) swarms[id].destroy();
- if (swarms.size() > 10)
- {
- ImageParticleSwarm first = swarms.removeFirst();
- first.destroy();
- }
- }
- */
+ swarms[id] = new ImageParticleSwarm(this, tex);
- if (swarm.makeModel( mesh ))
- {
- swarms.add( swarm );
-
- if (swarms.size() > 10)
- {
- ImageParticleSwarm first = swarms.removeFirst();
- first.destroy();
- }
- }
+ swarms[id].makeModel( mesh );
// clear tri mesh
mesh.clear();
-
- return swarm;
-
- // handPositions.clear();
+
+ return swarms[id];
}
@@ -51,8 +30,8 @@ void handJerked()
q.set(pos);
//println("JERKED");
-
-//handPositions.add(pos);
+
+ //handPositions.add(pos);
}
@@ -61,27 +40,28 @@ void handMoved()
// get 3D rotated mouse position
Vec3D pos=new Vec3D(leftHandPos.x-width/4, leftHandPos.y-height/4, leftHandPos.z);
//pos.scaleSelf(1.5);
-/*
+ /*
text("new pos:" + pos,20,30);
-
- pushMatrix();
- translate(pos.x+width/4,pos.y+height/4);
- image(fireballTex, 0,0, 32, 32);
- popMatrix();
-*/
+
+ pushMatrix();
+ translate(pos.x+width/4,pos.y+height/4);
+ image(fireballTex, 0,0, 32, 32);
+ popMatrix();
+ */
pos.rotateX(rotation.x);
pos.rotateY(rotation.y);
+
// use distance to previous point as target stroke weight
weight+=(sqrt(pos.distanceTo(prev))*2-weight)*0.1;
// define offset points for the triangle strip
-// println("weight " + weight + " / " + MIN_DIST );
+ // println("weight " + weight + " / " + MIN_DIST );
if (weight > MIN_DIST)
{
- // handPositions.add(pos);
-
+ // handPositions.add(pos);
+
Vec3D a=pos.add(0, 0, weight);
Vec3D b=pos.add(0, 0, -weight);
@@ -92,17 +72,16 @@ void handMoved()
prev=pos;
p=a;
q=b;
-
+
//prev.set(pos);
}
/*
if (triMesh.getNumVertices() > 600)
- {
- newSwarm();
- }
- */
-
+ {
+ newSwarm();
+ }
+ */
}
@@ -113,7 +92,7 @@ void drawMesh(GLGraphicsOffScreen buffer) {
buffer.noStroke();
//buffer.pushMatrix();
//buffer.scale(1,1,5);
- buffer.fill(255,180,20, 80);
+ buffer.fill(255, 180, 20, 80);
buffer.beginShape(TRIANGLES);
// iterate over all faces/triangles of the mesh
for (Iterator i=triMesh.faces.iterator(); i.hasNext();) {
@@ -125,42 +104,40 @@ void drawMesh(GLGraphicsOffScreen buffer) {
}
buffer.endShape();
//buffer.popMatrix();
-
}
void drawMeshUniqueVerts(GLGraphicsOffScreen buffer) {
-// noStroke();
-buffer.stroke(255,80);
-buffer.strokeWeight(6);
+ // noStroke();
+ buffer.stroke(255, 80);
+ buffer.strokeWeight(6);
-buffer.beginShape(POINTS);
+ buffer.beginShape(POINTS);
// get unique vertices, use with indices
float[] triVerts = triMesh.getUniqueVerticesAsArray();
for (int i=0; i < triVerts.length; i += 3)
{
-/* pushMatrix();
- translate(triVerts[i], triVerts[i+1], triVerts[i+2]);
- image(tex,0,0,32,32);
- popMatrix();
- */
+ /* pushMatrix();
+ translate(triVerts[i], triVerts[i+1], triVerts[i+2]);
+ image(tex,0,0,32,32);
+ popMatrix();
+ */
buffer.vertex(triVerts[i], triVerts[i+1], triVerts[i+2]);
}
buffer.endShape();
}
/*
void drawHandPositions()
-{
-
- for (Vec3D v : handPositions)
- {
- pushMatrix();
- translate(v.x,v.y,v.z);
- image(fireballTex, 0,0, 32, 32);
- popMatrix();
- }
-}
-*/
-
+ {
+
+ for (Vec3D v : handPositions)
+ {
+ pushMatrix();
+ translate(v.x,v.y,v.z);
+ image(fireballTex, 0,0, 32, 32);
+ popMatrix();
+ }
+ }
+ */
View
264 SkeletonObjectsExample3D/BodyPart.java
@@ -0,0 +1,264 @@
+import SimpleOpenNI.*;
+import processing.core.PImage;
+import processing.core.PVector;
+import processing.core.PApplet.*;
+
+public abstract class BodyPart
+{
+ /*
+ BodyPart setPadding(float l, float r, float t, float b);
+
+ BodyPart setTopPadding(float padPercent);
+ BodyPart setBottomPadding(float padPercent);
+ BodyPart setLeftPadding(float padPercent);
+ BodyPart setRightPadding(float padPercent);
+
+ BodyPart setType(int id); // Skeleton part id form SimpleOpenNI
+
+ BodyPart setTexture(PImage _tex);
+ PImage getTexture(PImage _tex);
+ */
+
+ static final int HEAD = 0;
+ static final int NECK = 1;
+ static final int LEFT_ARM_UPPER = 2;
+ static final int LEFT_ARM_LOWER = 3;
+ static final int RIGHT_ARM_UPPER = 4;
+ static final int RIGHT_ARM_LOWER = 5;
+ static final int TORSO = 6;
+ static final int LEFT_LEG_UPPER = 7;
+ static final int LEFT_LEG_LOWER = 8;
+ static final int RIGHT_LEG_UPPER = 9;
+ static final int RIGHT_LEG_LOWER = 10;
+ static final int PELVIS = 11;
+ static final int RIGHT_HAND = 12;
+ static final int LEFT_HAND = 13;
+ static final int OTHER = 14;
+
+
+ static final String[] NAMES = { "HEAD", "NECK", "LEFT_ARM_UPPER", "LEFT_ARM_LOWER", "RIGHT_ARM_UPPER", "RIGHT_ARM_LOWER",
+ "TORSO", "LEFT_LEG_UPPER", "LEFT_LEG_LOWER", "RIGHT_LEG_UPPER", "RIGHT_LEG_LOWER", "PELVIS", "RIGHT_HAND", "LEFT_HAND", "OTHER" };
+
+ protected PImage tex;
+ protected float padR, padL, padT, padB;
+ public boolean reversed;
+ public boolean depthDisabled;
+
+ protected SimpleOpenNI context;
+ protected int skeletonId;
+ protected int type;
+
+ public PVector offsetPercent; // offset for this body part (percentage-wise, in screen coords)
+ public PVector offsetCalculated;
+
+ static public boolean checkTypeIsValid(int _type)
+ {
+ if (_type >= BodyPart.HEAD && _type <= BodyPart.OTHER)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * this must be overridden by subclasses that actually implement this
+ */
+ public abstract BodyPart update();
+
+ /*
+ * This must be overridden by subclasses that actually implement this
+ * Uses lerp() or some other method to give a bit of lag to the new movement
+ * for each body part's joint point
+ */
+ public abstract BodyPart update(float[] lag);
+
+ public abstract PVector getJoint(int type);
+ public abstract PVector getPrevJoint(int type);
+
+ /*
+ * Useful for getting the screen depth for a given world depth
+ */
+ float worldDepthToScreen(float z)
+ {
+ // base depth on the width of the context
+ return context.depthImage().width * ((Math.abs(z) < 1E-5) ? 0f : 525.0f/z);
+ //return (Math.abs(z) < 1E-5) ? 0f : 525.0f/z;
+ }
+
+ public BodyPart setContext(SimpleOpenNI _context)
+ {
+ context = _context;
+ return this;
+ }
+
+ public SimpleOpenNI getContext()
+ {
+ return context;
+ }
+
+ public BodyPart setSkeletonId(int _skeletonId)
+ {
+ skeletonId = _skeletonId;
+ return this;
+ }
+
+ public int getSkeletonId()
+ {
+ return skeletonId;
+ }
+
+ // TODO: should this be an enum?? -Evan
+ //
+ public BodyPart setType(int _type) throws BodyPartTypeNotValidException
+ {
+ if (BodyPart.checkTypeIsValid(_type))
+ type = _type;
+ else throw new BodyPartTypeNotValidException(_type);
+
+ return this;
+ }
+
+ public int getType()
+ {
+ return type;
+ }
+
+ public BodyPart setOffsetX(int percent)
+ {
+ offsetPercent.x = percent;
+ return this;
+ }
+
+ public BodyPart setOffsetY(int percent)
+ {
+ offsetPercent.y = percent;
+ return this;
+ }
+
+ public BodyPart setOffsetZ(int percent)
+ {
+ offsetPercent.z = percent;
+ return this;
+ }
+
+ public float getScreenOffsetX()
+ {
+ return offsetCalculated.x;
+ }
+ public float getScreenOffsetY()
+ {
+ return offsetCalculated.y;
+ }
+ public float getScreenOffsetZ()
+ {
+ return offsetCalculated.z;
+ }
+
+
+ public BodyPart setPadding(float l, float r, float t, float b)
+ {
+ padR = r;
+ padL = l;
+ padB = b;
+ padT = t;
+ return this;
+ }
+
+ public float[] getPadding()
+ {
+ return new float[] {
+ padR, padL, padT, padB
+ };
+ }
+
+ public BodyPart setTopPadding(float padPercent)
+ {
+ padT = padPercent;
+ return this;
+ }
+ public float getTopPadding()
+ {
+ return padT;
+ }
+
+
+ public BodyPart setBottomPadding(float padPercent)
+ {
+ padB = padPercent;
+ return this;
+ }
+ public float getBottomPadding()
+ {
+ return padB;
+ }
+
+
+ public BodyPart setLeftPadding(float padPercent)
+ {
+ padL = padPercent;
+ return this;
+ }
+ public float getLeftPadding()
+ {
+ return padL;
+ }
+
+
+ public BodyPart setRightPadding(float padPercent)
+ {
+ padR = padPercent;
+ return this;
+ }
+ public float getRightPadding()
+ {
+ return padR;
+ }
+
+ public BodyPart setReversed(boolean r) // Skeleton part id form SimpleOpenNI
+ {
+ reversed = r;
+ return this;
+ }
+
+ public boolean getReversed() // Skeleton part id form SimpleOpenNI
+ {
+ return reversed;
+ }
+
+ public BodyPart disableDepth(boolean r) // Skeleton part id form SimpleOpenNI
+ {
+ depthDisabled = r;
+ return this;
+ }
+
+ public boolean getDepthDisabled() // Skeleton part id form SimpleOpenNI
+ {
+ return depthDisabled;
+ }
+
+ public BodyPart setTexture(PImage _tex)
+ {
+ tex = _tex;
+ return this;
+ }
+
+ public PImage getTexture()
+ {
+ return tex;
+ }
+
+
+ public class BodyPartTypeNotValidException extends RuntimeException
+ {
+ BodyPartTypeNotValidException() {
+ super();
+ }
+ BodyPartTypeNotValidException(int i)
+ {
+ super("Bad body part type: " + i);
+ }
+ BodyPartTypeNotValidException(String s) {
+ super(s);
+ }
+ }
+}
+
View
77 SkeletonObjectsExample3D/BodyPartFactory.java
@@ -0,0 +1,77 @@
+/*
+ * Singleton factory for creating BodyParts
+ */
+
+import SimpleOpenNI.*;
+import processing.core.PImage;
+import processing.core.PVector;
+
+
+
+public class BodyPartFactory
+{
+ // Private constructor prevents instantiation from other classes
+ private BodyPartFactory() {
+ }
+
+ /**
+ * SingletonHolder is loaded on the first execution of Singleton.getInstance()
+ * or the first access to SingletonHolder.INSTANCE, not before.
+ */
+ private static class SingletonHolder
+ {
+ public static final BodyPartFactory instance = new BodyPartFactory();
+ }
+
+ public static BodyPartFactory getInstance()
+ {
+ return SingletonHolder.instance;
+ }
+
+
+ public static BodyPart makeBodyPart(int part1ID, int type)
+ {
+ return (BodyPart)(new OnePointBodyPart(part1ID, type));
+ }
+
+ public static BodyPart makeBodyPart(int part1ID, int part2ID, int type)
+ {
+ return (BodyPart)(new TwoPointBodyPart(part1ID, part2ID, type));
+ }
+
+
+ public static BodyPart makeBodyPart(int part1ID, int part2ID, int part3ID, int part4ID, int type)
+ {
+ return (BodyPart)(new FourPointBodyPart(part1ID, part2ID, part3ID, part4ID, type));
+ }
+
+
+ public static BodyPart createPartForSkeleton(Skeleton skeleton, int part1ID, int type)
+ {
+ BodyPart bp = makeBodyPart(part1ID, type).setSkeletonId(skeleton.id).setContext(skeleton.context);
+ skeleton.addBodyPart(bp);
+
+ return bp;
+ }
+
+ public static BodyPart createPartForSkeleton(Skeleton skeleton, int part1ID, int part2ID, int type)
+ {
+ BodyPart bp = makeBodyPart(part1ID, part2ID, type).setSkeletonId(skeleton.id).setContext(skeleton.context);
+ skeleton.addBodyPart(bp);
+
+ return bp;
+ }
+
+
+ public static BodyPart createPartForSkeleton(Skeleton skeleton, int part1ID, int part2ID, int part3ID, int part4ID, int type)
+ {
+ BodyPart bp = makeBodyPart(part1ID, part2ID, part3ID, part4ID, type).setSkeletonId(skeleton.id).setContext(skeleton.context);
+ skeleton.addBodyPart(bp);
+
+ return bp;
+ }
+
+
+ // end class BodyPartFactory
+}
+
View
36 SkeletonObjectsExample3D/BodyPartRenderer.java
@@ -0,0 +1,36 @@
+
+//
+// BASE INTERFACE
+//
+
+import processing.core.PGraphics;
+
+public interface BodyPartRenderer
+{
+ // public PGraphics renderer;
+ // public BodyPartRenderer(PGraphics g);
+
+ /*
+ * set the internal renderer for drawing things
+ */
+ public void setRenderer(PGraphics g);
+
+ /*
+ * set this to render specific skeleton - sets the internal render target to Skeleton s
+ */
+ public void setSkeleton(Skeleton s);
+
+ /*
+ * render the current internal render target (Skeleton or otherwise)
+ */
+ public void render();
+
+ /*
+ * render a full skeleton, part-by-part
+ */
+ public void render(Skeleton skeleton);
+ /*
+ * render a single body part
+ */
+ public void render(BodyPart bodyPart);
+}
View
498 SkeletonObjectsExample3D/BoxRenderer.pde
@@ -0,0 +1,498 @@
+/////////////////////////////////////
+//
+// BASE 2D RENDERER (RECTANGLES AND TEXTURES)
+//
+//
+
+import toxi.geom.*;
+import toxi.geom.mesh.*;
+import toxi.processing.*;
+
+
+public class BoxRenderer implements BodyPartRenderer
+{
+ private PGraphics renderer;
+ private Skeleton mSkeleton;
+ private PApplet app;
+ private float rendererScaleW, rendererScaleH;
+
+ public ToxiclibsSupport gfx;
+
+ TriangleMesh origMesh, mesh;
+
+ public void initRenderer(PApplet _app)
+ {
+ app = _app;
+ gfx=new ToxiclibsSupport(app);
+ mSkeleton = null;
+ origMesh =(TriangleMesh)new AABB(new Vec3D(), 1).toMesh();
+ origMesh.transform(new Matrix4x4().translateSelf(0, 0, 1));
+ }
+
+ public BoxRenderer(PGraphics g)
+ {
+ renderer = g;
+// rendererScaleW = renderer.width/((float)app.g.width);
+// rendererScaleH = renderer.height/((float)app.g.height);
+ }
+
+ public void setRenderer(PGraphics g)
+ {
+ renderer = g;
+ rendererScaleW = renderer.width/((float)app.width);
+ rendererScaleH = renderer.height/((float)app.height);
+ }
+
+ public void setSkeleton(Skeleton s)
+ {
+ mSkeleton = s;
+ }
+
+ public void render()
+ {
+ render(mSkeleton);
+ }
+
+ /*
+ * render a full skeleton, part-by-part
+ */
+ void render(Skeleton skeleton)
+ {
+ if (skeleton != null && skeleton.calibrated) // first check if there is anything to draw!
+ {
+ // these draw based on percentages (so they scale to the body parts)
+ for (BodyPart bodyPart : skeleton.mBodyParts)
+ {
+ render( bodyPart );
+ }
+ }
+ }
+
+
+ /*
+ * render a single body part
+ */
+ void render(BodyPart bodyPart)
+ {
+ renderer.pushMatrix();
+ //renderer.translate(-renderer.width/2, -renderer.height/2, 0);
+// renderer.scale(2,2,1);
+
+
+ renderer.translate(bodyPart.getScreenOffsetX(), bodyPart.getScreenOffsetY(), bodyPart.getScreenOffsetZ());
+
+
+ if (bodyPart instanceof OnePointBodyPart)
+ {
+ PImage tex = bodyPart.getTexture();
+ OnePointBodyPart obp = (OnePointBodyPart)bodyPart;
+
+ Vec3D p1 = new Vec3D(obp.screenPoint1.x, obp.screenPoint1.y, obp.screenPoint1.z);
+
+ renderer.pushMatrix();
+ gfx.setGraphics(renderer);
+
+ if (obp.depthDisabled)
+ {
+ hint(DISABLE_DEPTH_TEST);
+ }
+
+
+ // scale properly
+ Vec3D meshScale = new Vec3D(10, 10, 10);
+
+ float w = renderer.width*(obp.getLeftPadding()+obp.getRightPadding());
+ float h = renderer.height*(obp.getTopPadding()+obp.getBottomPadding());
+
+ // scale from point to point
+ mesh = origMesh.getScaled(new Vec3D(w, h, h));
+
+ gfx.translate(p1);
+ gfx.mesh(mesh, false, 10);
+
+
+ // if (tex != null)
+ // {
+ // }
+ // else
+ // {
+ // }
+ if (obp.depthDisabled)
+ {
+ hint(ENABLE_DEPTH_TEST);
+ }
+ renderer.popMatrix();
+ }
+
+ else if (bodyPart instanceof TwoPointBodyPart)
+ {
+ TwoPointBodyPart tbp = (TwoPointBodyPart)bodyPart;
+
+ renderMeshFromVectors(tbp.screenPoint1, tbp.screenPoint2, tbp.getLeftPadding(), tbp.getRightPadding(),
+ tbp.getTopPadding(), tbp.getBottomPadding(), tbp.getTexture(), tbp.getReversed() );
+ }
+ else if (bodyPart instanceof FourPointBodyPart)
+ {
+ FourPointBodyPart fbp = (FourPointBodyPart)bodyPart;
+
+ renderMeshFromVectors(fbp.screenPoint1, fbp.screenPoint2, fbp.screenPoint3, fbp.screenPoint4,
+ fbp.getLeftPadding(), fbp.getRightPadding(), fbp.getTopPadding(), fbp.getBottomPadding(),
+ fbp.getTexture(), fbp.getReversed() );
+ }
+
+ renderer.popMatrix();
+ }
+
+ // utility function to make typing easier
+ Vec3D Vec3DFromPVector(PVector v)
+ {
+ Vec3D v3d = new Vec3D(v.x, v.y, v.z);
+ return v3d;
+ }
+
+
+ void renderMeshFromVectors(PVector screenPoint1, PVector screenPoint2, float leftPadding, float rightPadding,
+ float topPadding, float bottomPadding, PImage tex, boolean reversed)
+ {
+ Vec3D p1 = Vec3DFromPVector(screenPoint1);
+ Vec3D p2 = Vec3DFromPVector(screenPoint2);
+
+ float diff = p2.distanceTo(p1)/2;
+ float scaleX = diff*(leftPadding+rightPadding);
+ float scaleY = diff*(topPadding+bottomPadding);
+
+ //Vec3D meshScale = Vec3D(diff*(leftPadding+rightPadding), diff*(topPadding+bottomPadding), diff);
+ drawMeshBetween(p1, p2, scaleX, scaleY, origMesh, renderer);
+
+ }
+
+void renderMeshFromVectors(PVector screenPoint1, PVector screenPoint2, PVector screenPoint3, PVector screenPoint4, float leftPadding, float rightPadding,
+ float topPadding, float bottomPadding, PImage tex, boolean reversed)
+ {
+ Vec3D p1 = Vec3DFromPVector(screenPoint1);
+ Vec3D p2 = Vec3DFromPVector(screenPoint2);
+
+ float diff = p2.distanceTo(p1);
+ float scaleX = diff*(leftPadding+rightPadding);
+ float scaleY = diff*(topPadding+bottomPadding);
+
+ //Vec3D meshScale = Vec3D(diff*(leftPadding+rightPadding), diff*(topPadding+bottomPadding), diff);
+ drawMeshBetween(p1, p2, scaleX, scaleY, origMesh, renderer);
+
+ }
+
+
+ public void drawMeshBetween(Vec3D p1, Vec3D p2, float scaleX, float scaleY, TriangleMesh mesh, PGraphics buffer)
+ {
+ //place p1-p2 vector diff at origin
+ gfx.setGraphics(buffer);
+
+ Vec3D meshDiff = p2.sub(p1);
+ float meshMag = meshDiff.magnitude();
+ Vec3D dir = meshDiff.getNormalized();
+
+ // scale properly
+ Vec3D meshScale = new Vec3D(scaleX, scaleY, meshMag/2);
+
+ // scale from point to point
+ mesh = mesh.getScaled(meshScale);
+
+ // get current rotation
+ float[] axis=Quaternion.getAlignmentQuat(dir, Vec3D.Z_AXIS).toAxisAngle();
+
+ buffer.noStroke();
+ buffer.pushMatrix();
+
+ // move to 1st points
+ gfx.translate(p1);
+
+ // align the Z axis of the box with the direction vector
+ buffer.rotate(axis[0], axis[1], axis[2], axis[3]);
+
+
+ // draw rotated coordinate system
+ gfx.origin(new Vec3D(), 100);
+ gfx.mesh(mesh, false, 10);
+ buffer.popMatrix();
+ }
+
+
+
+
+ void renderRectFromVectors(PVector p1, PVector p2, float padLeft, float padRight, float padTop, float padBottom, PImage tex, boolean reversed)
+ {
+ // rotate the screen the angle btw the two vectors and then draw it rightside-up
+ float angle = atan2(p2.y-p1.y, p2.x-p1.x);
+
+ float w2 = (p1.x - p2.x)*0.5f;
+ float h2 = (p1.y - p2.y)*0.5f;
+ float xCenter = p1.x - w2;
+ float yCenter = p1.y - h2;
+
+ // height of the shape
+ //float xdiff = p1.x-p2.x;
+ //float ydiff = p1.y-p2.y;
+ //float h = sqrt( xdiff*xdiff + ydiff*ydiff);
+ float h = p1.dist(p2);
+
+ float widthPadding = h*(padLeft+padRight);
+
+ float totalHeight = h + h*(padTop+padBottom);
+
+ // save drawing state
+ renderer.pushMatrix();
+
+ // rotations are at 0,0 by default, but we want to rotate around the center
+ // of this shape
+
+ renderer.translate(xCenter, yCenter, (p1.z+p2.z)/2);
+ //renderer.ellipse(0, 0, 20, 20);
+
+ // rotate
+ renderer.rotate(angle);
+
+ // center screen
+ renderer.translate(-h*padTop-h*0.5f, -padLeft*h);
+
+ renderRect(totalHeight, widthPadding, p1.z, p2.z, tex, reversed);
+
+ renderer.popMatrix();
+ }
+
+
+ void renderRect(float w, float h, PImage tex)
+ {
+ renderRect(w, h, tex, false);
+ }
+
+
+
+
+ void renderRect(float w, float h, PImage tex, boolean reversed)
+ {
+ renderer.textureMode(NORMALIZED);
+ int r = reversed ? 1 : 0;
+
+ // now draw rightside up
+ renderer.beginShape(TRIANGLES);
+ if (tex != null)
+ {
+ renderer.noStroke();
+ renderer.texture(tex);
+ renderer.vertex(0, 0, 1-r, 0);
+ renderer.vertex(w, 0, 1-r, 1);
+ renderer.vertex(w, h, r-0, 1);
+
+ renderer.vertex(w, h, r-0, 1);
+ renderer.vertex(0, h, r-0, 0);
+ renderer.vertex(0, 0, 1-r, 0);
+ }
+ else
+ {
+ renderer.vertex(0, 0);
+ renderer.vertex(w, 0);
+ renderer.vertex(w, h);
+
+ renderer.vertex(w, h);
+ renderer.vertex(0, h);
+ renderer.vertex(0, 0);
+ }
+ renderer.endShape(CLOSE);
+ }
+
+
+
+ void renderRect(float w, float h, float d1, float d2, PImage tex, boolean reversed)
+ {
+ int r = reversed ? 1 : 0;
+
+ renderer.textureMode(NORMALIZED);
+
+ // now draw rightside up
+ renderer.beginShape(TRIANGLES);
+ if (tex != null)
+ {
+ renderer.noStroke();
+ renderer.texture(tex);
+ renderer.vertex(0, 0, d1, 1-r, 0);
+ renderer.vertex(w, 0, d1, 1-r, 1);
+ renderer.vertex(w, h, d2, r-0, 1);
+
+ renderer.vertex(w, h, d2, r-0, 1);
+ renderer.vertex(0, h, d2, r-0, 0);
+ renderer.vertex(0, 0, d1, 1-r, 0);
+ }
+ else
+ {
+ renderer.vertex(0, 0);
+ renderer.vertex(w, 0);
+ renderer.vertex(w, h);
+
+ renderer.vertex(w, h);
+ renderer.vertex(0, h);
+ renderer.vertex(0, 0);
+ }
+ renderer.endShape(CLOSE);
+ }
+
+
+ // untextured rectagle between 4 points
+ void renderRectFromVectors(PVector p1, PVector p2, PVector p3, PVector p4)
+ {
+ renderRectFromVectors( p1, p2, p3, p4, 0, 0, null);
+ }
+
+
+ // textured rectangle between 4 points
+ void renderRectFromVectors(PVector p1, PVector p2, PVector p3, PVector p4, PImage tex)
+ {
+ renderRectFromVectors( p1, p2, p3, p4, 0, 0, tex);
+ }
+
+
+ //
+ // Render a clockwise list of vectors as a (optionally) textured rectangle with padding
+ //
+ void renderRectFromVectors(PVector p1, PVector p2, PVector p3, PVector p4, float padX, float padY, PImage tex, boolean reversed)
+ {
+ float pX1 = padX*(p2.x-p1.x);
+ float pX2 = padX*(p3.x-p4.x);
+
+ float pY1 = padY*(p4.y-p1.y);
+ float pY2 = padY*(p3.y-p2.y);
+
+ renderer.beginShape(TRIANGLES);
+ if (tex != null)
+ {
+ renderer.noStroke();
+ renderer.texture(tex);
+ renderer.vertex(p1.x-pX1, p1.y-pY1, 0, 0);
+ renderer.vertex(p2.x+pX1, p2.y-pY2, 100, 0);
+ renderer.vertex(p3.x+pX2, p3.y+pY1, 100, 100);
+
+ renderer.vertex(p3.x+pX2, p3.y+pY1, 100, 100);
+ renderer.vertex(p4.x-pX2, p4.y+pY2, 0, 100);
+ renderer.vertex(p1.x-pX1, p1.y-pY1, 0, 0);
+ }
+ else
+ {
+ renderer.vertex(p1.x-pX1, p1.y-pY1);
+ renderer.vertex(p2.x+pX1, p2.y-pY2);
+ renderer.vertex(p3.x+pX2, p3.y+pY1);
+
+ renderer.vertex(p3.x+pX2, p3.y+pY1);
+ renderer.vertex(p4.x-pX2, p4.y+pY2);
+ renderer.vertex(p1.x-pX1, p1.y-pY1);
+ }
+ renderer.endShape();
+ }
+
+
+ //
+ // Render a clockwise list of vectors as a (optionally) textured rectangle with padding
+ //
+ void renderRectFromVectors(PVector p1, PVector p2, PVector p3, PVector p4, float padL, float padR, float padT, float padB, PImage tex, boolean reversed)
+ {
+ float WT = p2.x-p1.x;
+ float WB = p3.x-p4.x;
+
+ float padWidthLT = padL*WT;
+ float padWidthLB = padL*WB;
+
+ float padWidthRT = padR*WT;
+ float padWidthRB = padR*WB;
+
+
+ float HL = p4.y-p1.y;
+ float HR = p3.y-p2.y;
+
+ float padHeightTL = padT*HL;
+ float padHeightTR = padT*HR;
+
+ float padHeightBL = padB*HL;
+ float padHeightBR = padB*HR;
+
+ renderer.beginShape(TRIANGLES);
+ if (tex != null)
+ {
+ renderer.noStroke();
+ renderer.texture(tex);
+ renderer.vertex(p1.x-padWidthLT, p1.y-padHeightTL, 0, 0);
+ renderer.vertex(p2.x+padWidthRT, p2.y-padHeightTR, 100, 0);
+ renderer.vertex(p3.x+padWidthRB, p3.y+padHeightBR, 100, 100);
+
+ renderer.vertex(p3.x+padWidthRB, p3.y+padHeightBR, 100, 100);
+ renderer.vertex(p4.x-padWidthLB, p4.y+padHeightBL, 0, 100);
+ renderer.vertex(p1.x-padWidthLT, p1.y-padHeightTL, 0, 0);
+ }
+ else
+ {
+ renderer.vertex(p1.x-padWidthLT, p1.y-padHeightTL);
+ renderer.vertex(p2.x+padWidthRT, p2.y-padHeightTR);
+ renderer.vertex(p3.x+padWidthRB, p3.y+padHeightBR);
+
+ renderer.vertex(p3.x+padWidthRB, p3.y+padHeightBR);
+ renderer.vertex(p4.x-padWidthLB, p4.y+padHeightBL);
+ renderer.vertex(p1.x-padWidthLT, p1.y-padHeightTL);
+ }
+ renderer.endShape();
+ }
+
+
+ //
+ // Render a clockwise list of vectors as a rectangle with padding
+ //
+ void renderRectFromVectors(PVector p1, PVector p2, PVector p3, PVector p4, int padX, int padY)
+ {
+ renderRectFromVectors( p1, p2, p3, p4, padX, padY, null);
+ }
+
+ //
+ // Render a clockwise list of vectors as an (optionally) textured rectangle with padding
+ //
+ void renderRectFromVectors(PVector p1, PVector p2, PVector p3, PVector p4, int padX, int padY, PImage tex)
+ {
+ renderRectFromVectors( p1, p2, p3, p4, padX, padX, padY, padY, tex, false);
+ }
+
+ //
+ // ignores reversed for now
+ //
+ void renderRectFromVectors(PVector p1, PVector p2, PVector p3, PVector p4, int padXLeft, int padXRight, int padYTop, int padYBottom, PImage tex, boolean reversed)
+ {
+
+ float pX1 = padXLeft;
+ float pX2 = padXRight;
+
+ float pY1 = padYTop;
+ float pY2 = padYBottom;
+
+ renderer.beginShape(TRIANGLES);
+ if (tex != null)
+ {
+ renderer.noStroke();
+ renderer.texture(tex);
+ renderer.vertex(p1.x-pX1, p1.y-pY1, p1.z, 0, 0);
+ renderer.vertex(p2.x+pX1, p2.y-pY1, p2.z, 100, 0);
+ renderer.vertex(p3.x+pX2, p3.y+pY2, p3.z, 100, 100);
+
+ renderer.vertex(p3.x+pX2, p3.y+pY2, p3.z, 100, 100);
+ renderer.vertex(p4.x-pX2, p4.y+pY2, p4.z, 0, 100);
+ renderer.vertex(p1.x-pX1, p1.y-pY1, p1.z, 0, 0);
+ }
+ else
+ {
+ renderer.vertex(p1.x-pX1, p1.y-pY1, p1.z);
+ renderer.vertex(p2.x+pX1, p2.y-pY1, p2.z);
+ renderer.vertex(p3.x+pX2, p3.y+pY2, p3.z);
+
+ renderer.vertex(p3.x+pX2, p3.y+pY2, p3.z);
+ renderer.vertex(p4.x-pX2, p4.y+pY2, p4.z);
+ renderer.vertex(p1.x-pX1, p1.y-pY1, p1.z);
+ }
+ renderer.endShape();
+ }
+
+ // end class BodyPartRenderer
+}
+
View
525 SkeletonObjectsExample3D/DrawingStuff.pde
@@ -0,0 +1,525 @@
+/////////////////////////////////////
+//
+// BASE 2D RENDERER (RECTANGLES AND TEXTURES)
+//
+//
+
+public class BasicBodyPartRenderer implements BodyPartRenderer
+{
+ private PGraphics renderer;
+ private Skeleton mSkeleton;
+
+ public BasicBodyPartRenderer(PGraphics g)
+ {
+ renderer = g;
+ mSkeleton = null;
+ }
+
+ public void setRenderer(PGraphics g)
+ {
+ renderer = g;
+ }
+
+ public void setSkeleton(Skeleton s)
+ {
+ mSkeleton = s;
+ }
+
+ public void render()
+ {
+ render(mSkeleton);
+ }
+
+ /*
+ * render a full skeleton, part-by-part
+ */
+ void render(Skeleton skeleton)
+ {
+ if (skeleton != null && skeleton.calibrated) // first check if there is anything to draw!
+ {
+ // these draw based on percentages (so they scale to the body parts)
+ for (BodyPart bodyPart : skeleton.mBodyParts)
+ {
+ render( bodyPart );
+ }
+ }
+ }
+
+
+ /*
+ * render a single body part
+ */
+ void render(BodyPart bodyPart)
+ {
+ renderer.pushMatrix();
+ renderer.translate(bodyPart.getScreenOffsetX(), bodyPart.getScreenOffsetY(), bodyPart.getScreenOffsetZ());
+
+ if (bodyPart instanceof OnePointBodyPart)
+ {
+ PImage tex = bodyPart.getTexture();
+ OnePointBodyPart obp = (OnePointBodyPart)bodyPart;
+
+ renderer.pushMatrix();
+ renderer.translate(obp.screenPoint1.x, obp.screenPoint1.y, obp.screenPoint1.z);
+
+ float w = renderer.width*(obp.getLeftPadding()+obp.getRightPadding());
+ float h = renderer.height*(obp.getTopPadding()+obp.getBottomPadding());
+
+ if (obp.depthDisabled)
+ {
+ hint(DISABLE_DEPTH_TEST);
+ }
+
+ if (tex != null)
+ {
+ renderer.imageMode(CENTER);
+ renderer.image(tex, 0, 0, w, h);
+ }
+ else
+ {
+ fill(255);
+ renderer.rectMode(CENTER);
+ renderer.rect(0, 0, w, h);
+ }
+ if (obp.depthDisabled)
+ {
+ hint(ENABLE_DEPTH_TEST);
+ }
+ renderer.popMatrix();
+ }
+ else if (bodyPart instanceof TwoPointBodyPart)
+ {
+ TwoPointBodyPart tbp = (TwoPointBodyPart)bodyPart;
+ renderRectFromVectors(tbp.screenPoint1, tbp.screenPoint2, tbp.getLeftPadding(), tbp.getRightPadding(),
+ tbp.getTopPadding(), tbp.getBottomPadding(), tbp.getTexture(), tbp.getReversed() );
+ }
+ else if (bodyPart instanceof FourPointBodyPart)
+ {
+ FourPointBodyPart fbp = (FourPointBodyPart)bodyPart;
+
+ renderRectFromVectors(fbp.screenPoint1, fbp.screenPoint2, fbp.screenPoint3, fbp.screenPoint4,
+ fbp.getLeftPadding(), fbp.getRightPadding(), fbp.getTopPadding(), fbp.getBottomPadding(),
+ fbp.getTexture(), fbp.getReversed() );
+ }
+
+ renderer.popMatrix();
+ }
+
+
+ // simple, no texture
+ void renderRectFromVectors(PVector p1, PVector p2, int widthPadding)
+ {
+ renderRectFromVectors(p1, p2, widthPadding, 0, null, false);
+ }
+
+
+ // simple, with texture
+ void renderRectFromVectors(PVector p1, PVector p2, int widthPadding, PImage tex )
+ {
+ renderRectFromVectors(p1, p2, widthPadding, 0, tex, false);
+ }
+
+ // simple, with texture
+ void renderRectFromVectors(PVector p1, PVector p2, int widthPadding, PImage tex, boolean reversed )
+ {
+ renderRectFromVectors(p1, p2, widthPadding, 0, tex, reversed);
+ }
+
+
+ // no texture
+ void renderRectFromVectors(PVector p1, PVector p2, int widthPadding, int lengthPadding)
+ {
+ renderRectFromVectors(p1, p2, widthPadding, lengthPadding, null, false);
+ }
+
+ // no reverse
+ void renderRectFromVectors(PVector p1, PVector p2, int widthPadding, int lengthPadding, PImage tex)
+ {
+ renderRectFromVectors(p1, p2, widthPadding, lengthPadding, tex, false);
+ }
+
+
+ //
+ // this draws a textured rectangle between two points with an absolute width and height in pixels,
+ // optionally reversed in x direction
+ //
+
+ void renderRectFromVectors(PVector p1, PVector p2, int widthPadding, int lengthPadding, PImage tex, boolean reversed)
+ {
+ // rotate the screen the angle btw the two vectors and then draw it rightside-up
+ float angle = atan2(p2.y-p1.y, p2.x-p1.x);
+ float xdiff = p1.x-p2.x;
+ float ydiff = p1.y-p2.y;
+
+ float w2 = (p1.x - p2.x)*0.5f;
+ float h2 = (p1.y - p2.y)*0.5f;
+ float xCenter = p1.x - w2;
+ float yCenter = p1.y - h2;
+
+ // height of the shape
+ float h = sqrt( xdiff*xdiff + ydiff*ydiff) + lengthPadding*2.0f;
+
+ //renderer.ellipse(xCenter, yCenter, 10, 10);
+
+ renderer.pushMatrix();
+
+ // rotations are at 0,0 by default, but we want to rotate around the center
+ // of this shape
+ renderer.translate(xCenter, yCenter);
+ //ellipse(0, 0, 20, 20);
+
+ // rotate
+ renderer.rotate(angle);
+
+ // center screen
+ renderer.translate( -h*0.5f, -widthPadding/2);
+
+ renderRect(h, widthPadding, p1.z, p2.z, tex, reversed);
+
+ renderer.popMatrix();
+
+ // another way to do it...
+ // center screen
+ // translate( -h*0.5f, widthPadding);
+ //
+ // rotate(-HALF_PI);
+ // tex.render(0,0,widthPadding*2.0f,h);
+ // popMatrix();
+
+
+ // for debugging...
+ // stroke(0);
+ // strokeWeight(1.0);
+ // fill(0, 60);
+ // ellipse(p1.x, p1.y, 10, 10);
+ // ellipse(p2.x, p2.y, 10, 10);
+ }
+
+
+ //
+ // this draws a textured rectangle between two points with an *relative* width and height in pixels
+ //
+
+
+ void renderRectFromVectors(PVector p1, PVector p2, float padSidePercent)
+ {
+ renderRectFromVectors(p1, p2, padSidePercent, 0.0, null, false);
+ }
+
+ void renderRectFromVectors(PVector p1, PVector p2, float padSidePercent, boolean reversed)
+ {
+ renderRectFromVectors(p1, p2, padSidePercent, 0.0, null, reversed);
+ }
+
+ // simple, no texture
+ void renderRectFromVectors(PVector p1, PVector p2, float padSidePercent, PImage tex)
+ {
+ renderRectFromVectors(p1, p2, padSidePercent, 0, tex, false);
+ }
+
+ void renderRectFromVectors(PVector p1, PVector p2, float padSidePercent, PImage tex, boolean reversed)
+ {
+ renderRectFromVectors(p1, p2, padSidePercent, 0.0, tex, reversed);
+ }
+
+
+ void renderRectFromVectors(PVector p1, PVector p2, float padSidePercent, float padEndPercent)
+ {
+ renderRectFromVectors(p1, p2, padSidePercent, padEndPercent, null, false);
+ }
+
+
+ void renderRectFromVectors(PVector p1, PVector p2, float padW, float padH, PImage tex)
+ {
+ renderRectFromVectors( p1, p2, padW, padW, padH, padH, tex, false);
+ }
+
+
+ void renderRectFromVectors(PVector p1, PVector p2, float padW, float padH, PImage tex, boolean reversed)
+ {
+ renderRectFromVectors( p1, p2, padW, padW, padH, padH, tex, reversed);
+ }
+
+
+ void renderRectFromVectors(PVector p1, PVector p2, float padLeft, float padRight, float padTop, float padBottom, PImage tex)
+ {
+ renderRectFromVectors( p1, p2, padLeft, padRight, padTop, padBottom, tex, false);
+ }
+
+ void renderRectFromVectors(PVector p1, PVector p2, float padLeft, float padRight, float padTop, float padBottom, PImage tex, boolean reversed)
+ {
+ // rotate the screen the angle btw the two vectors and then draw it rightside-up
+ float angle = atan2(p2.y-p1.y, p2.x-p1.x);
+
+ float w2 = (p1.x - p2.x)*0.5f;
+ float h2 = (p1.y - p2.y)*0.5f;
+ float xCenter = p1.x - w2;
+ float yCenter = p1.y - h2;
+
+ // height of the shape
+ //float xdiff = p1.x-p2.x;
+ //float ydiff = p1.y-p2.y;
+ //float h = sqrt( xdiff*xdiff + ydiff*ydiff);
+ float h = p1.dist(p2);
+
+ float widthPadding = h*(padLeft+padRight);
+
+ float totalHeight = h + h*(padTop+padBottom);
+
+ // save drawing state
+ renderer.pushMatrix();
+
+ // rotations are at 0,0 by default, but we want to rotate around the center
+ // of this shape
+
+ renderer.translate(xCenter, yCenter);
+ //renderer.ellipse(0, 0, 20, 20);
+
+ // rotate
+ renderer.rotate(angle);
+
+ // center screen
+ renderer.translate(-h*padTop-h*0.5f, -padLeft*h);
+
+ renderRect(totalHeight, widthPadding, p1.z, p2.z, tex, reversed);
+
+ renderer.popMatrix();
+ }
+
+
+ void renderRect(float w, float h, PImage tex)
+ {
+ renderRect(w, h, tex, false);
+ }
+
+
+
+
+ void renderRect(float w, float h, PImage tex, boolean reversed)
+ {
+ renderer.textureMode(NORMALIZED);
+ int r = reversed ? 1 : 0;
+
+ // now draw rightside up
+ renderer.beginShape(TRIANGLES);
+ if (tex != null)
+ {
+ renderer.noStroke();
+ renderer.texture(tex);
+ renderer.vertex(0, 0, 1-r, 0);
+ renderer.vertex(w, 0, 1-r, 1);
+ renderer.vertex(w, h, r-0, 1);
+
+ renderer.vertex(w, h, r-0, 1);
+ renderer.vertex(0, h, r-0, 0);
+ renderer.vertex(0, 0, 1-r, 0);
+ }
+ else
+ {
+ renderer.vertex(0, 0);
+ renderer.vertex(w, 0);
+ renderer.vertex(w, h);
+
+ renderer.vertex(w, h);
+ renderer.vertex(0, h);
+ renderer.vertex(0, 0);
+ }
+ renderer.endShape(CLOSE);
+ }
+
+
+
+ void renderRect(float w, float h, float d1, float d2, PImage tex, boolean reversed)
+ {
+ int r = reversed ? 1 : 0;
+
+ renderer.textureMode(NORMALIZED);
+
+ // now draw rightside up
+ renderer.beginShape(TRIANGLES);
+ if (tex != null)
+ {
+ renderer.noStroke();
+ renderer.texture(tex);
+ renderer.vertex(0, 0, d1, 1-r, 0);
+ renderer.vertex(w, 0, d1, 1-r, 1);
+ renderer.vertex(w, h, d2, r-0, 1);
+
+ renderer.vertex(w, h, d2, r-0, 1);
+ renderer.vertex(0, h, d2, r-0, 0);
+ renderer.vertex(0, 0, d1, 1-r, 0);
+ }
+ else
+ {
+ renderer.vertex(0, 0);
+ renderer.vertex(w, 0);
+ renderer.vertex(w, h);
+
+ renderer.vertex(w, h);
+ renderer.vertex(0, h);
+ renderer.vertex(0, 0);
+ }
+ renderer.endShape(CLOSE);
+ }
+
+
+ // untextured rectagle between 4 points
+ void renderRectFromVectors(PVector p1, PVector p2, PVector p3, PVector p4)
+ {
+ renderRectFromVectors( p1, p2, p3, p4, 0, 0, null);
+ }
+
+
+ // textured rectangle between 4 points
+ void renderRectFromVectors(PVector p1, PVector p2, PVector p3, PVector p4, PImage tex)
+ {
+ renderRectFromVectors( p1, p2, p3, p4, 0, 0, tex);
+ }
+
+
+ //
+ // Render a clockwise list of vectors as a (optionally) textured rectangle with padding
+ //
+ void renderRectFromVectors(PVector p1, PVector p2, PVector p3, PVector p4, float padX, float padY, PImage tex, boolean reversed)
+ {
+ float pX1 = padX*(p2.x-p1.x);
+ float pX2 = padX*(p3.x-p4.x);
+
+ float pY1 = padY*(p4.y-p1.y);
+ float pY2 = padY*(p3.y-p2.y);
+
+ renderer.beginShape(TRIANGLES);
+ if (tex != null)
+ {
+ renderer.noStroke();
+ renderer.texture(tex);
+ renderer.vertex(p1.x-pX1, p1.y-pY1, 0, 0);
+ renderer.vertex(p2.x+pX1, p2.y-pY2, 100, 0);
+ renderer.vertex(p3.x+pX2, p3.y+pY1, 100, 100);
+
+ renderer.vertex(p3.x+pX2, p3.y+pY1, 100, 100);
+ renderer.vertex(p4.x-pX2, p4.y+pY2, 0, 100);
+ renderer.vertex(p1.x-pX1, p1.y-pY1, 0, 0);
+ }
+ else
+ {
+ renderer.vertex(p1.x-pX1, p1.y-pY1);
+ renderer.vertex(p2.x+pX1, p2.y-pY2);
+ renderer.vertex(p3.x+pX2, p3.y+pY1);
+
+ renderer.vertex(p3.x+pX2, p3.y+pY1);
+ renderer.vertex(p4.x-pX2, p4.y+pY2);
+ renderer.vertex(p1.x-pX1, p1.y-pY1);
+ }
+ renderer.endShape();
+ }
+
+
+ //
+ // Render a clockwise list of vectors as a (optionally) textured rectangle with padding
+ //
+ void renderRectFromVectors(PVector p1, PVector p2, PVector p3, PVector p4, float padL, float padR, float padT, float padB, PImage tex, boolean reversed)
+ {
+ float WT = p2.x-p1.x;
+ float WB = p3.x-p4.x;
+
+ float padWidthLT = padL*WT;
+ float padWidthLB = padL*WB;
+
+ float padWidthRT = padR*WT;
+ float padWidthRB = padR*WB;
+
+
+ float HL = p4.y-p1.y;
+ float HR = p3.y-p2.y;
+
+ float padHeightTL = padT*HL;
+ float padHeightTR = padT*HR;
+
+ float padHeightBL = padB*HL;
+ float padHeightBR = padB*HR;
+
+ renderer.beginShape(TRIANGLES);
+ if (tex != null)
+ {
+ renderer.noStroke();
+ renderer.texture(tex);
+ renderer.vertex(p1.x-padWidthLT, p1.y-padHeightTL, p1.z, 0, 0);
+ renderer.vertex(p2.x+padWidthRT, p2.y-padHeightTR, p2.z, 100, 0);
+ renderer.vertex(p3.x+padWidthRB, p3.y+padHeightBR, p3.z, 100, 100);
+
+ renderer.vertex(p3.x+padWidthRB, p3.y+padHeightBR, p3.z, 100, 100);
+ renderer.vertex(p4.x-padWidthLB, p4.y+padHeightBL, p4.z, 0, 100);
+ renderer.vertex(p1.x-padWidthLT, p1.y-padHeightTL, p1.z, 0, 0);
+ }
+ else
+ {
+ renderer.vertex(p1.x-padWidthLT, p1.y-padHeightTL);
+ renderer.vertex(p2.x+padWidthRT, p2.y-padHeightTR);
+ renderer.vertex(p3.x+padWidthRB, p3.y+padHeightBR);
+
+ renderer.vertex(p3.x+padWidthRB, p3.y+padHeightBR);
+ renderer.vertex(p4.x-padWidthLB, p4.y+padHeightBL);
+ renderer.vertex(p1.x-padWidthLT, p1.y-padHeightTL);
+ }
+ renderer.endShape();
+ }
+
+
+ //
+ // Render a clockwise list of vectors as a rectangle with padding
+ //
+ void renderRectFromVectors(PVector p1, PVector p2, PVector p3, PVector p4, int padX, int padY)
+ {
+ renderRectFromVectors( p1, p2, p3, p4, padX, padY, null);
+ }
+
+ //
+ // Render a clockwise list of vectors as an (optionally) textured rectangle with padding
+ //
+ void renderRectFromVectors(PVector p1, PVector p2, PVector p3, PVector p4, int padX, int padY, PImage tex)
+ {
+ renderRectFromVectors( p1, p2, p3, p4, padX, padX, padY, padY, tex, false);
+ }
+
+ //
+ // ignores reversed for now
+ //
+ void renderRectFromVectors(PVector p1, PVector p2, PVector p3, PVector p4, int padXLeft, int padXRight, int padYTop, int padYBottom, PImage tex, boolean reversed)
+ {
+
+ float pX1 = padXLeft;
+ float pX2 = padXRight;
+
+ float pY1 = padYTop;
+ float pY2 = padYBottom;
+
+ renderer.beginShape(TRIANGLES);
+ if (tex != null)
+ {
+ renderer.noStroke();
+ renderer.texture(tex);
+ renderer.vertex(p1.x-pX1, p1.y-pY1, p1.z, 0, 0);
+ renderer.vertex(p2.x+pX1, p2.y-pY1, p2.z, 100, 0);
+ renderer.vertex(p3.x+pX2, p3.y+pY2, p3.z, 100, 100);
+
+ renderer.vertex(p3.x+pX2, p3.y+pY2, p3.z, 100, 100);
+ renderer.vertex(p4.x-pX2, p4.y+pY2, p4.z, 0, 100);
+ renderer.vertex(p1.x-pX1, p1.y-pY1, p1.z, 0, 0);
+ }
+ else
+ {
+ renderer.vertex(p1.x-pX1, p1.y-pY1, p1.z);
+ renderer.vertex(p2.x+pX1, p2.y-pY1, p2.z);
+ renderer.vertex(p3.x+pX2, p3.y+pY2, p3.z);
+
+ renderer.vertex(p3.x+pX2, p3.y+pY2, p3.z);
+ renderer.vertex(p4.x-pX2, p4.y+pY2, p4.z);
+ renderer.vertex(p1.x-pX1, p1.y-pY1, p1.z);
+ }
+ renderer.endShape();
+ }
+
+ // end class BodyPartRenderer
+}
+
View
157 SkeletonObjectsExample3D/FourPointBodyPart.java
@@ -0,0 +1,157 @@
+import SimpleOpenNI.*;
+import processing.core.PImage;
+import processing.core.PVector;
+
+
+public class FourPointBodyPart extends BodyPart
+{
+ public PVector worldPoint1, screenPoint1;
+ public PVector worldPoint2, screenPoint2;
+ public PVector worldPoint3, screenPoint3;
+ public PVector worldPoint4, screenPoint4;
+
+ public PVector pworldPoint1, pscreenPoint1;
+ public PVector pworldPoint2, pscreenPoint2;
+ public PVector pworldPoint3, pscreenPoint3;
+ public PVector pworldPoint4, pscreenPoint4;
+
+ private int joint1ID, joint2ID, joint3ID, joint4ID;
+
+ //
+ // Basic contructor
+ //
+ public FourPointBodyPart(int _joint1ID, int _joint2ID, int _joint3ID, int _joint4ID, int type )
+ {
+ setType(type);
+
+ worldPoint1 = new PVector();
+ screenPoint1 = new PVector();
+
+ pworldPoint1 = new PVector();
+ pscreenPoint1 = new PVector();
+
+ worldPoint2 = new PVector();
+ screenPoint2 = new PVector();
+
+ pworldPoint2 = new PVector();
+ pscreenPoint2 = new PVector();
+
+ worldPoint3 = new PVector();
+ screenPoint3 = new PVector();
+
+ pworldPoint3 = new PVector();
+ pscreenPoint3 = new PVector();
+
+ worldPoint4 = new PVector();
+ screenPoint4 = new PVector();
+
+ pworldPoint4 = new PVector();
+ pscreenPoint4 = new PVector();
+
+ offsetPercent = new PVector();
+ offsetCalculated = new PVector();
+
+ joint1ID = _joint1ID;
+ joint2ID = _joint2ID;
+ joint3ID = _joint3ID;
+ joint4ID = _joint4ID;
+
+ tex = null;
+ context = null;
+
+ padR = padL = padT = padB = 0f;
+ }
+
+
+ public PVector getJoint(int type)
+ {
+ if (joint1ID == type)
+ return screenPoint1;
+ else if (joint2ID == type)
+ return screenPoint2;
+ else if (joint3ID == type)
+ return screenPoint3;
+ else return screenPoint4;
+ }
+
+ public PVector getPrevJoint(int type)
+ {
+ if (joint1ID == type)
+ return pscreenPoint1;
+ else if (joint2ID == type)
+ return pscreenPoint2;
+ else if (joint3ID == type)
+ return pscreenPoint3;
+ else return pscreenPoint4;
+ }
+
+ public BodyPart update()
+ {
+ pscreenPoint1.set(screenPoint1);
+ pscreenPoint2.set(screenPoint2);
+ pscreenPoint3.set(screenPoint3);
+ pscreenPoint4.set(screenPoint4);
+
+ // get joint positions in 3D world for the tracked limbs
+ context.getJointPositionSkeleton(skeletonId, joint1ID, worldPoint1);
+ context.getJointPositionSkeleton(skeletonId, joint2ID, worldPoint2);
+ context.getJointPositionSkeleton(skeletonId, joint3ID, worldPoint3);
+ context.getJointPositionSkeleton(skeletonId, joint4ID, worldPoint4);
+
+ context.convertRealWorldToProjective(worldPoint1, screenPoint1);
+ screenPoint1.z = worldDepthToScreen(screenPoint1.z);
+
+ context.convertRealWorldToProjective(worldPoint2, screenPoint2);
+ screenPoint2.z = worldDepthToScreen(screenPoint2.z);
+
+ context.convertRealWorldToProjective(worldPoint3, screenPoint3);
+ screenPoint3.z = worldDepthToScreen(screenPoint3.z);
+
+ context.convertRealWorldToProjective(worldPoint4, screenPoint4);
+ screenPoint4.z = worldDepthToScreen(screenPoint4.z);
+
+ // now calculate offsets in screen coords
+ offsetCalculated.x = offsetPercent.x*(screenPoint1.x+screenPoint2.x)*0.5f;
+ offsetCalculated.y = offsetPercent.y*(screenPoint1.y+screenPoint4.y)*0.5f;
+ offsetCalculated.z = offsetPercent.z*(screenPoint1.z+screenPoint4.z)*0.5f;
+
+ return this;
+ }
+
+ //
+ // TODO: make this real
+ //
+ public BodyPart update(float[] lag)
+ {
+ pscreenPoint1.set(screenPoint1);
+ pscreenPoint2.set(screenPoint2);
+ pscreenPoint3.set(screenPoint3);
+ pscreenPoint4.set(screenPoint4);
+
+ // get joint positions in 3D world for the tracked limbs
+ context.getJointPositionSkeleton(skeletonId, joint1ID, worldPoint1);
+ context.getJointPositionSkeleton(skeletonId, joint2ID, worldPoint2);
+ context.getJointPositionSkeleton(skeletonId, joint3ID, worldPoint3);
+ context.getJointPositionSkeleton(skeletonId, joint4ID, worldPoint4);
+
+ context.convertRealWorldToProjective(worldPoint1, screenPoint1);
+ screenPoint1.z = worldDepthToScreen(screenPoint1.z);
+
+ context.convertRealWorldToProjective(worldPoint2, screenPoint2);
+ screenPoint2.z = worldDepthToScreen(screenPoint2.z);
+
+ context.convertRealWorldToProjective(worldPoint3, screenPoint3);
+ screenPoint3.z = worldDepthToScreen(screenPoint3.z);
+
+ context.convertRealWorldToProjective(worldPoint4, screenPoint4);
+ screenPoint4.z = worldDepthToScreen(screenPoint4.z);
+
+ // now calculate offsets in screen coords
+ offsetCalculated.x = offsetPercent.x*(screenPoint1.x+screenPoint2.x)*0.5f;
+ offsetCalculated.y = offsetPercent.y*(screenPoint1.y+screenPoint4.y)*0.5f;
+ offsetCalculated.z = offsetPercent.z*(screenPoint1.z+screenPoint4.z)*0.5f;
+
+ return this;
+ }
+}
+
View
82 SkeletonObjectsExample3D/OnePointBodyPart.java
@@ -0,0 +1,82 @@
+import SimpleOpenNI.*;
+import processing.core.PImage;
+import processing.core.PVector;
+
+
+public class OnePointBodyPart extends BodyPart
+{
+ public PVector worldPoint1, screenPoint1, pworldPoint1, pscreenPoint1;
+
+ private int joint1ID;
+
+ //
+ // Basic contructor
+ //
+ public OnePointBodyPart(int _joint1ID, int type )
+ {
+ setType(type);
+
+ worldPoint1 = new PVector();
+ screenPoint1 = new PVector();
+
+ pworldPoint1 = new PVector();
+ pscreenPoint1 = new PVector();
+
+ offsetPercent = new PVector();
+ offsetCalculated = new PVector();
+
+ joint1ID = _joint1ID;
+
+ tex = null;
+ context = null;
+
+ padR = padL = padT = padB = 0f;
+ }
+
+
+ public PVector getJoint(int type)
+ {
+ return screenPoint1;
+ }
+
+ public PVector getPrevJoint(int type)
+ {
+ return pscreenPoint1;
+ }
+
+
+ public BodyPart update()
+ {
+ pscreenPoint1.set(screenPoint1);
+
+ // get joint positions in 3D world for the tracked limbs
+ context.getJointPositionSkeleton(skeletonId, joint1ID, worldPoint1);
+
+ context.convertRealWorldToProjective(worldPoint1, screenPoint1);
+ screenPoint1.z = worldDepthToScreen(screenPoint1.z);
+
+ // now calculate offsets in screen coords
+ offsetCalculated.x = offsetPercent.x*screenPoint1.x;
+ offsetCalculated.y = offsetPercent.y*screenPoint1.y;
+ offsetCalculated.z = offsetPercent.z*screenPoint1.z;
+
+ return this;
+ }
+
+ public BodyPart update(float[] lag)
+ {
+ // get joint positions in 3D world for the tracked limbs
+ context.getJointPositionSkeleton(skeletonId, joint1ID, worldPoint1);
+
+ context.convertRealWorldToProjective(worldPoint1, screenPoint1);
+ screenPoint1.z = worldDepthToScreen(screenPoint1.z);
+
+ // now calculate offsets in screen coords
+ offsetCalculated.x = lag[0]*offsetCalculated.x + (1f-lag[0])*offsetPercent.x*screenPoint1.x;
+ offsetCalculated.y = lag[0]*offsetCalculated.y + (1f-lag[0])*offsetPercent.y*screenPoint1.y;
+ offsetCalculated.z = lag[0]*offsetCalculated.z + (1f-lag[0])*offsetPercent.z*screenPoint1.z;
+
+ return this;
+ }
+}
+
View
164 SkeletonObjectsExample3D/OpenNIEvents.pde
@@ -0,0 +1,164 @@
+
+boolean drawBG = true;
+
+
+// -----------------------------------------------------------------
+// SimpleOpenNI event handlers -- these add and remove skeletons from our list
+
+void onNewUser(int userId)
+{
+ println("onNewUser - userId: " + userId);
+ println(" start pose detection");
+
+ context.startPoseDetection("Psi", userId);
+
+
+ // add to list of skeletons if this id doesn't already exist
+ ListIterator<Skeleton> iterator = skeletons.listIterator();
+
+ boolean found = false;
+
+ while ( !found && iterator.hasNext () )
+ {
+ Skeleton s = iterator.next();
+ if (s.id == userId)
+ {
+ // we're already tracking this skeleton
+ found = true;
+ s.calibrated = false;
+ break;
+ }
+ }
+
+ // start tracking this one if not found in our list
+ if (!found)
+ {
+ iterator.add(new Skeleton(context, userId) );
+
+ // reset iterator
+ currentSkeletonIter = skeletons.listIterator();
+ if ( currentSkeletonIter.hasNext() )
+ currentSkeleton = currentSkeletonIter.next();
+ else
+ currentSkeleton = null;
+ }
+}
+
+
+void onLostUser(int userId)
+{
+ println("onLostUser - userId: " + userId);
+
+
+ context.getUsers(userList);
+
+ if ( userList.size() < 1)
+ drawBG = true;
+
+ // add to list of skeletons if this id doesn't already exist
+ ListIterator<Skeleton> iterator = skeletons.listIterator();
+
+ boolean found = false;
+
+ while ( !found && iterator.hasNext () )
+ {
+ Skeleton s = iterator.next();
+ if (s.id == userId)
+ {
+ iterator.remove();
+
+ // reset iterator
+ currentSkeletonIter = skeletons.listIterator();
+
+ if ( currentSkeletonIter.hasNext() )
+ currentSkeleton = currentSkeletonIter.next();
+ else
+ currentSkeleton = null;
+
+ break;
+ }
+ }
+}
+
+
+
+void onStartCalibration(int userId)
+{
+ println("onStartCalibration - userId: " + userId);
+
+ boolean found = false;
+
+ ListIterator<Skeleton> iterator = skeletons.listIterator();
+
+ while ( !found && iterator.hasNext () )
+ {
+ Skeleton s = iterator.next();
+ if (s.id == userId)
+ {
+ s.calibrated = false;
+ found = true;
+ break;
+ }
+ }
+}
+
+
+void onEndCalibration(int userId, boolean successful)
+{
+ println("onEndCalibration - userId: " + userId + ", successful: " + successful);
+
+ if (successful)
+ {
+ println(" User calibrated !!!");
+ context.startTrackingSkeleton(userId);
+
+ // stop drawing depth image
+ drawDepthImage = false;
+ drawBG = false;
+ }
+ else
+ {
+ println(" Failed to calibrate user !!!");
+ println(" Start pose detection");
+ context.startPoseDetection("Psi", userId);
+ }
+
+ boolean found = false;
+
+ ListIterator<Skeleton> iterator = skeletons.listIterator();
+
+ while ( !found && iterator.hasNext () )
+ {
+ Skeleton s = iterator.next();
+ if (s.id == userId)
+ {
+ s.calibrated = successful;
+ found = true;
+
+ // set as current skeleton
+ if (successful)
+ {
+ currentSkeleton = s;
+ buildSkeleton(currentSkeleton);
+ }
+
+ break;
+ }
+ }
+}
+
+
+void onStartPose(String pose, int userId)
+{
+ println("onStartPose - userId: " + userId + ", pose: " + pose);
+ println(" stop pose detection");
+
+ context.stopPoseDetection(userId);
+ context.requestCalibrationSkeleton(userId, true);
+}
+
+void onEndPose(String pose, int userId)
+{
+ println("onEndPose - userId: " + userId + ", pose: " + pose);
+}
+
View
440 SkeletonObjectsExample3D/ParticleBodyPartRenderer.pde
@@ -0,0 +1,440 @@
+/////////////////////////////////////
+//
+// PARTICLES RENDERER
+//
+//
+
+float boneMinDist = 80*80;
+float boneDistFactor = 0.1f;
+float particleMassAttractFactor = 0.2f;
+
+