8. Dezember 2011
Dies ist ein letzter Stand vor der Abschlusspräsentation, mit funktionierender Kinect-Integration.- Neue Funktionen
-
'q' to toggle input (Mouse or Kinect)
/* -------------------------------------------------------------------------- * Graphic Design Basics - Mouse Animation / Interaktion * -------------------------------------------------------------------------- * prog: Beni Achermann (based on Max Rheiner's examples 🙂 * date: 17/11/2011 * ---------------------------------------------------------------------------- */ // Importieren der Fullscreen-Library import fullscreen.*; // Initialisieren der HandCapture / simpleOpenNI Klasse HandCapture handCapture; boolean drawFlag=false; FullScreen fullScreen; ArrayList zeichen = new ArrayList(); // erstellen einer neuen ArrayList // PVector variables for the function that allows moving signs around PVector p1Move = new PVector(); PVector p2Move = new PVector(); // PVector variables for the animations caused by moving the cursor PVector p1 = new PVector(); PVector p2 = new PVector(); boolean drag = false; boolean infoPanel = true; int gridSize = 7; // 7*7 creates a grid of 49 signs int rand; int randInitial; int formNumber = 1; boolean inputToggle = false; void setup() { size(1024,768); smooth(); rectMode(CENTER); ellipseMode(CENTER); frameRate(20); // Kinect / OpenNI handCapture = new HandCapture(this); randInitial = 70; rand = randInitial; noCursor(); loop(); // interesting effects if turned off! // Populate the zeichen array for (int i=0; i<gridSize*gridSize;i++) { zeichen.add(new Zeichen(0, 0)); } fullScreen = new FullScreen(this); fullScreen.enter(); } // end of setup void draw() { // pushStyle(); // visual help for fullscreen mode // rectMode(CORNER); // noFill(); // stroke(255,0,0); // strokeWeight(3); // rect(0,0,width,height); // popStyle(); float trackerX; float trackerY; float trackerZ; // Kinect / OpenNI handCapture.update(); pushMatrix(); PVector handPos = handCapture.handPos(); float handX = map(handPos.x,0,640,0,width); float handY = map(handPos.y,0,480,0,height); float handZ = map(handPos.z,0,480,0,height); popMatrix(); if(inputToggle) { trackerX = mouseX; trackerY = mouseY; trackerZ = 0; pushStyle(); fill(255); text("Mouse", width-100,30); popStyle(); } else { trackerX = handX; trackerY = handY; trackerZ = handZ; pushStyle(); fill(255); text("Kinect", width-100,30); //text(handZ, width-200,60); popStyle(); // if(handCapture.isHandTracked()) // { // // draw a red dot at the position of Die Hand // // pushStyle(); // stroke(255,0,0); // strokeWeight(8); // point(handX,handY); // popStyle(); // } } float xStep; float yStep; xStep = (width - 2 * rand) / (float)(gridSize-1); yStep = (height - 2 * rand) / (float)(gridSize-1); // ghosting pushStyle(); rectMode(CORNER); fill(0, 0, 0, 40); noStroke(); rect(0, 0, width, height); popStyle(); if (drag) { // zeichne die abschussrichtung pushStyle(); stroke(0, 255, 0); line(p1Move.x, p1Move.y, p2Move.x, p2Move.y); popStyle(); } // zeichne die Zeichen 🙂 pushMatrix(); translate(rand, rand); for (int i=0; i<gridSize;i++) { pushMatrix(); for (int j=0; j<gridSize;j++) { // Start of stuff needed for cursor animation float adjustedMouseX = trackerX - width / 4; float adjustedMouseY = trackerY - height / 4; float posX = j * xStep+rand; float posY = i * yStep+rand; float distValueAdj = sqrt(sq((adjustedMouseX-posX))+sq((adjustedMouseY-posY))); float distValue = sqrt(sq((trackerX-posX))+sq((trackerY-posY))); //float angleMouse = atan2(mouseVect.y - matrix[i].y, mouseVect.x - matrix[i].x); float distValueZ = sqrt(sq((trackerZ-posX))+sq((trackerZ-posY))); p1.set (posX, posY, 0); p2.set (adjustedMouseX, adjustedMouseY, 0); PVector dir = PVector.sub(p2, p1); // end of stuff needed for cursor animation // Zeichen ball = (Zeichen) zeichen.get(j); ball.draw(0, 0, distValue, distValueAdj, distValueZ); translate(xStep, 0.0f); } popMatrix(); translate(0.0f, yStep); } popMatrix(); displayInfoPanel(); } void mousePressed() { drag = true; p1Move.set(mouseX, mouseY, 0); p2Move.set(mouseX, mouseY, 0); } void mouseDragged() { p2Move.set(mouseX, mouseY, 0); } void displayInfoPanel() { if (infoPanel) { pushMatrix(); pushStyle(); // background / shadow (grey rectangle) fill(60); strokeJoin(ROUND); stroke(60); strokeWeight(12); rect(width/2+3, height/2+3, width/2, height/4); // foreground / background for text (white rectangle) fill(255); strokeJoin(ROUND); stroke(255); strokeWeight(12); rect(width/2, height/2, width/2, height/4); infoPanelText(width/2,height/2 - 80); popMatrix(); popStyle(); } else { } } void infoPanelText(int textX, int textY) { String[] textInfo = { "move the cursor to trigger animations", "'i' to hide or display this panel", "'w' and 'e' to switch forms", " ", "'a' and 'd' to change distance between signs", "'r' to reset distance to initial value", " ", "'s' to save a screenshot", "'q' to toggle input (Mouse or Kinect)", " ", "Distance: " + rand, "Form: " + formNumber, }; String superText = ""; for(int i = 0; i < textInfo.length; i++) { superText += textInfo[i]+"\r\n"; } fill(0); textAlign(CENTER); text(superText, textX, textY); } // end of infoPanelText void mouseReleased() { drag = false; // abschuss staerke berechnen PVector dir = PVector.sub(p2Move, p1Move); // laenge verkuerzen dir.mult(.09); // der ball wird neu ausgerichtet Zeichen temp = new Zeichen(100, 100); temp.set(p1Move, dir, .993); // zeichen.add(temp); } // KEYBOARD FUNCTIONS void keyPressed() { switch(key) { case 's': saveFrame("screenshot-####.png"); // Speichern eines Screenshots auf Druck von S println("Saved screenshot-##.png"); redraw(); break; case 'd': rand+=40; if (rand > 390) { // If rand ist bigger than % rand = randInitial; //...set it back to 10 } println("Increased distance from rand to " + rand); redraw(); break; case 'a': rand-=40; if (rand < randInitial) { // If rand ist smaller than 10 rand = 390; //...set it back to % } println("Increased rand to " + rand); redraw(); break; case 'w': formNumber++; if (formNumber > 7) { // If formNumber ist bigger than 6 formNumber = 1; //...set it back to 1 } println("Form: " + formNumber); redraw(); break; case 'e': formNumber--; if (formNumber < 1) { // If formNumber is smaller than 1 formNumber = 6; //...set it back to 6 } println("Form: " + formNumber); redraw(); break; case 'i': if (infoPanel) { infoPanel = false; println("Hiding information screen"); } else { infoPanel = true; println("Displaying information screen"); } redraw(); break; case 'r': rand = randInitial; redraw(); break; case 'q': if (inputToggle) { inputToggle = false; println("Switched to Kinect input"); } else { inputToggle = true; println("Switched to Mouse input"); } redraw(); break; } } // hand events void onCreateHands(int handId,PVector pos,float time) { handCapture.onCreateHands(handId,pos,time); } void onUpdateHands(int handId,PVector pos,float time) { handCapture.onUpdateHands(handId,pos,time); } void onDestroyHands(int handId,float time) { handCapture.onDestroyHands(handId,time); } void onRecognizeGesture(String strGesture, PVector idPosition, PVector endPosition) { handCapture.onRecognizeGesture(strGesture,idPosition,endPosition); } void onProgressGesture(String strGesture, PVector position,float progress) { handCapture.onProgressGesture(strGesture,position,progress); }
import SimpleOpenNI.*; class HandCapture { import SimpleOpenNI.*; class HandCapture { SimpleOpenNI _context; boolean _drawFlag=false; PVector _handVec = new PVector(); String _lastGesture = ""; PVector _screenPos = new PVector(); PApplet _parent; boolean _handsTrackFlag = false; HandCapture(PApplet parent) { _parent = parent; _context = new SimpleOpenNI(_parent); // mirror is by default enabled _context.setMirror(true); // enable depthMap _context.enableDepth(); // enable camera _context.enableRGB(); _context.enableHands(); _context.enableGesture(); _context.addGesture("RaiseHand"); // align depth data to image data _context.alternativeViewPointDepthToImage(); } boolean isHandTracked() { return _handsTrackFlag; } PVector handPos() { return _screenPos; } PVector handPos3d() { return _handVec; } PImage depthImage() { return _context.depthImage(); } PImage rgbImage() { return _context.rgbImage(); } int width() { return _context.depthWidth(); } int height() { return _context.depthHeight(); } void update() { _context.update(); _context.convertRealWorldToProjective(_handVec,_screenPos); } void onCreateHands(int handId, PVector pos, float time) { _handsTrackFlag = true; _handVec = pos; } void onUpdateHands(int handId, PVector pos, float time) { _handVec = pos; } void onDestroyHands(int handId, float time) { _handsTrackFlag = false; _context.addGesture(_lastGesture); } void onRecognizeGesture(String strGesture, PVector idPosition, PVector endPosition) { _lastGesture = strGesture; _context.removeGesture(strGesture); _context.startTrackingHands(endPosition); } void onProgressGesture(String strGesture, PVector position, float progress) { } }
/* -------------------------------------------------------------------------- * Zeichenklasse * -------------------------------------------------------------------------- * prog: Beni Achermann * date: 24/11/2011 * ---------------------------------------------------------------------------- */ class Zeichen { PVector _pos; PVector _dir; float _dampV; int _w; int _h; int formSize = 90; float dist; float distValueGlobal; float distValueZ; float distValueAdjGlobal; float scaler; // konstruktor Zeichen(int x, int y) { _pos = new PVector(width/2, height/2); _dir = new PVector(0, 0); _dampV = 1; } // setzt die neue pos + richtung + daempfung void set(PVector pos, PVector dir, float dampV) { _pos = pos.get(); _dir.add(dir); _dampV = dampV; } // erneuert die aktuelle position void calcPos() { // aktuelle position verschieben _pos.add(_dir); // bewegungs vektor veraendert _dir.mult(_dampV); // teste horizontal if (_pos.x + _w/2 > width) { _dir.x *= -1; _pos.x = width - _w/2; } else if (_pos.x - _w/2 < 0) { _dir.x *= -1; _pos.x = _w/2; } // teste vertikal if (_pos.y + _h/2 > height) { _dir.y *= -1; _pos.y = height - _w/2; } else if (_pos.y - _h/2 < 0) { _dir.y *= -1; _pos.y = _h/2; } } // zeichnet die Zeichen void draw(int x, int y, float _distValue, float _distValueAdj, float _distValueZ) { distValueGlobal = _distValue; distValueZ = _distValueZ; distValueAdjGlobal = _distValueAdj; calcPos(); switchingZeichen(x, y); } // CODE FOR CONSTRUCTING THE BASIC FORMS void switchingZeichen(float x, float y) { if (formNumber == 1) { // white ellipse & with smaller black one in it, innit. drawSign1(x, y); } if (formNumber == 2) { // the symbol from aufgabe 04 drawSign2(x, y); } if (formNumber == 3) { // very small ellipses (dots) in a grid pushMatrix(); drawSign3(x-formSize/2, y-formSize/2); // x/y - formSize/2 because all other forms are automatically centered popMatrix(); } if (formNumber == 4) { // ellipse with outline drawSign4(x, y); } if (formNumber == 5) { // lineament ======= drawSign5(x-formSize/2, y-formSize/2); } if (formNumber == 6) { // geknicktes Lineament \/\/\/\/\/\/\/ drawSign6(x-formSize/2, y-formSize/2); } if (formNumber == 7) { //very small ellipses (dots) in a grid drawSign7(x-formSize/2, y-formSize/2); } } void drawSign1(float x, float y) { // white ellipse & with smaller black one in it, innit. dist = map(distValueGlobal, 0, width, 0, 100); // mouse animation scaler = map(distValueGlobal, 0, width, 0, 1.5); // mouse animation pushMatrix(); scale(scaler); // mouse animation pushStyle(); fill(255); ellipse(0, 0, formSize, formSize); fill(0); noStroke(); translate(map(distValueGlobal, 0, width, -10, 10),map(distValueGlobal, 0, width, -5, 5)); ellipse(0, 0, formSize/3, formSize/3); popStyle(); popMatrix(); } void drawSign2(float x, float y) { // the symbol from aufgabe 04 pushStyle(); scale(map(distValueGlobal, 0, width, 0.1, 2.0)); circleFilledWhiteOutlineBlack(x, y, 1.0, 0.0, 4); popStyle(); pushStyle(); rotate(map(distValueGlobal, 0, width, 1, 30)); circleFilledBlack(x+formSize/2, y, 1.0, 0.0, 0); popStyle(); pushStyle(); scale(map(distValueGlobal, 0, width, -2.0, 2.0)); circleFilledBlack(x, y, 0.5, 0.0, 0); popStyle(); pushStyle(); rotate(map(distValueGlobal, 0, width, 1, 30)); circleFilledWhite(x+7, y, 0.5, 0.0, 0); popStyle(); } void drawSign3(float x, float y) { //very small ellipses (dots) in a grid dist = map(distValueGlobal, 0, width, 0, 5); for (int i = 1; i < 9; i++) { pushMatrix(); for (int j = 1; j < 9; j++) { pushStyle(); fill(255); noStroke(); ellipse(x, y, 4, 4); popStyle(); scale(dist); } popMatrix(); translate(15, 15); } } void drawSign4(float x, float y) { // ellipse with outline dist = map(distValueGlobal, 0, width * 1.41, 0, 100); pushStyle(); stroke(2); fill(255); ellipse(x, y, dist, formSize); scale(map(distValueGlobal, 0, width, -3, 2.1)); ellipse(x, y, dist/2, formSize/2); popStyle(); } void drawSign5(float x, float y) { // lineament ======= dist = map(distValueGlobal, 0, width * 1.41, 0, 15); pushMatrix(); for (int i = 1; i <= 9; i++) { // lines pushStyle(); stroke(255); strokeWeight(1); line(x, y, formSize/2, y); translate(0, dist); popStyle(); } popMatrix(); } void drawSign6(float x, float y) { // geknicktes Lineament \/\/\/\/\/\/\/ // map nimmt den eingehenden Wert (distValueGlobal), welcher sich in einem Range zwischen // 0 und der Weite des Dokuments befindet. // Dieser Wert wird dann in den Range zwischen 0 und 100 umgerechnet. float distX; float distY; distX = map(distValueGlobal, 0, width, -formSize/3, formSize/3); distY = map(distValueGlobal, 0, width, -30, 30); pushMatrix(); for (int i = 1; i <= 9; i++) { pushStyle(); stroke(255); strokeWeight(1); line(x, y, distX, y+distY); line(distX, y+distY, formSize/2, y); translate(0, 10); popStyle(); } popMatrix(); } void drawSign7(float x, float y) { //very small ellipses (dots) in a grid //rect(x,y,formSize,formSize); dist = map(distValueGlobal, 0, width * 3, 1, 10); for (int i = 1; i < 9; i++) { pushMatrix(); for (int j = 1; j < 9; j++) { pushStyle(); fill(255); noStroke(); ellipse(x, y, 2, 2); popStyle(); translate(0, dist); } popMatrix(); translate(dist, 0); } } void circleFilledWhite (float translateX, float translateY, float scaleValue, float rotateValue, int strokeWeightValue) { pushMatrix(); translate(translateX, translateY); scale(scaleValue); rotate(rotateValue); noStroke(); fill(255); ellipse(0, 0, formSize, formSize); popMatrix(); } void circleFilledWhiteOutlineBlack(float translateX, float translateY, float scaleValue, float rotateValue, int strokeWeightValue) { pushMatrix(); translate(translateX, translateY); scale(scaleValue); rotate(rotateValue); fill(0); strokeWeight(strokeWeightValue); fill(255); ellipse(0, 0, formSize, formSize); popMatrix(); } void circleFilledBlack (float translateX, float translateY, float scaleValue, float rotateValue, int strokeWeightValue) { pushMatrix(); translate(translateX, translateY); scale(scaleValue); rotate(rotateValue); fill(0); noStroke(); ellipse(0, 0, formSize, formSize); popMatrix(); } } // end of class