//-------------------------------------------------------------- void ofApp::update(){ float pulseSpeed = 10; maxVol = ofMap(snake.score, 0, 40, 0.3, 0.9, true); if (onTitle){ maxVol = 0.15; } if (gameOver && resetGameTimer < 0){ maxVol = 0.2; } if (debugMute) maxVol = 0; //turn everythign off for (int x=0; x<GRID_SIZE; x++){ for (int y=0; y<GRID_SIZE; y++){ grid[x][y] = false; gridf[x][y] = 0; } } if (!gameOver && !onTitle){ //did the snake eat the food? if (foodX == snake.curX && foodY == snake.curY){ snake.eat(); setFood(); } //update the snake if (!debugPause){ snake.update(); } //check if we're dead if (snake.justDied){ snake.justDied = false; endGame(); } //turn on the parts of the snake grid[snake.curX][snake.curY] = true; gridf[snake.curX][snake.curY] = 1; for (int i=0; i<snake.trailX.size(); i++){ grid[snake.trailX[i]][snake.trailY[i]] = true; gridf[snake.trailX[i]][snake.trailY[i]] = 0.5 + 0.5*abs(sin(ofGetElapsedTimef() * pulseSpeed + i *0.2) ); } //and the food grid[foodX][foodY] = 1;//ofGetFrameNum()%2==0; gridf[foodX][foodY] = ofGetFrameNum() % 6 > 2 ? 1 : 0; //gridf[foodX][foodY] = 0.5 + 0.5*abs(cos( ofGetElapsedTimef() * pulseSpeed * 3)); } if (gameOver && !onTitle){ if (resetGameTimer > 0){ gridf[snake.curX][snake.curY] = ofGetFrameNum() % 20 > 10; } else{ for (int x=0; x<GRID_SIZE; x++){ for (int y=0; y<GRID_SIZE; y++){ if (scoreGrid[x][y]){ gridf[x][y] = ofGetFrameNum() % 20 > 10; } } } } resetGameTimer--; if (resetGameTimer <= -showScoreTime){ onTitle = true; } } if (onTitle){ for (int x=0; x<GRID_SIZE; x++){ for (int y=0; y<GRID_SIZE; y++){ if (titleGrid[x][y]){ //gridf[x][y] = 0.5 + 0.5 * abs(sin(ofGetElapsedTimef() + x*GRID_SIZE+y)); gridf[x][y] = ofRandom(0.2,1);// ofRandomuf() < 0.8 ? 1 : 0; } } } } //also update and add the sparks if any are present for (int i=sparks.size()-1; i>=0; i--){ sparks[i].update(); if (sparks[i].deathTimer <= 0){ sparks.erase( sparks.begin()+i ); }else{ gridf[sparks[i].curX][sparks[i].curY] += sparks[i].curVal; gridf[sparks[i].curX][sparks[i].curY] = MIN(gridf[sparks[i].curX][sparks[i].curY], 1); } } }
//-------------------------------------------------------------- void GeneratedMesh::update(bool bEditorMode){ autoScalingXYZ(); //Udpate mesch if there are changes // add 3D mashes to ofxBullet shape //for(int i = 0; i < assimpModel.getNumMeshes(); i++) //{ //btVector3 myBtScale; //myBtScale.setX(scale.x); //myBtScale.setY(scale.y); //myBtScale.setZ(scale.z); //body.getRigidBody()->getCollisionShape()->setLocalScaling(myObjectScale);//->m_collisionShape //setImplicitShapeDimensions(myBtScale); //addMesh(assimpModel.getMesh(i), scale, true); //} if(position.x != last_positionX){ setPosition(position); last_positionX = position.x; } if(position.y != last_positionY){ setPosition(position); last_positionY = position.y; } if(position.z != last_positionZ){ setPosition(position); last_positionZ = position.z; } if(angleValX != last_angleValX){ setAngle2Rotate(angleValX, axis2RotateX); //, angleValY, axis2RotateY, angleValZ, axis2RotateZ); last_angleValX = angleValX; } if(angleValY != last_angleValY){ setAngle2Rotate(angleValY, axis2RotateY); // , angleValY, axis2RotateY, angleValZ, axis2RotateZ); last_angleValY = angleValY; } if(angleValZ != last_angleValZ){ setAngle2Rotate(angleValZ, axis2RotateZ); //, angleValY, axis2RotateY, angleValZ, axis2RotateZ); last_angleValZ = angleValZ; } if(bAnimate) { vector< ofVec3f >& verts = mesh.getVertices(); vector< ofVec3f >& overts = omesh.getVertices(); for( int i = 0; i < verts.size(); i++ ) { verts[i].y = ofSignedNoise( verts[i].x*0.025, verts[i].y*0.025 + verts[i].z*0.025, ofGetElapsedTimef() * 0.75 ) * 3; } body.updateMesh( this->world->world, mesh ); } //world.update( ofGetLastFrameTime(), 12 ); body.activate(); }
void CirclePacker::start() { _startTime = _completeTime = ofGetElapsedTimef(); startThread(true, true); // blocking, verbose }
void Thermal::update(){ if( ofGetElapsedTimef() > timer + 16) next(); }
//-------------------------------------------------------------- void testApp::mouseReleased(int x, int y, int button){ TPR.endDrawing(); playbackStartTime = ofGetElapsedTimef(); }
//-------------------------------------------------------------- void ofApp::mouseDragged(int x, int y, int button){ float timeT = ofGetElapsedTimef(); while (timeT > 5) timeT -= 5.0; stroke.addVertex(ofPoint(x,y), timeT); }
//-------------------------------------------------------------- void testApp::update(){ for(int i = 0 ; i< NUM_DEVICE ;i++) { string device_name = "Device_"+ofToString(i); float length = timeline.getKeyframeValue(device_name); string s = "k,"+ofToString(i)+","+ofToString(length); dataSet[i].length = length*ofGetHeight()*0.5; //ofLog(OF_LOG_VERBOSE,"Send to Serial : "+s); //serial.writeBytes((unsigned char*)s.c_str(),s.length()); } if(isTimelineShow) { cam.disableMouseInput(); } else { cam.enableMouseInput(); } nTimesRead = 0; nBytesRead = 0; int nRead = 0; // a temp variable to keep count per read unsigned char bytesReturned[NUM_BYTES]; memset(bytesReadString, 0, NUM_BYTES); memset(bytesReturned, 0, NUM_BYTES); while( (nRead = serial.readBytes( bytesReturned, NUM_BYTES)) > 0){ nTimesRead++; nBytesRead = nRead; }; memcpy(bytesReadString, bytesReturned, NUM_BYTES); if(strlen(bytesReadString)>0) { ofLog(OF_LOG_VERBOSE,"%s",bytesReadString); if(isSent) { float diff = ofGetElapsedTimef()-timeDiff; ofLog(OF_LOG_VERBOSE,"time difference :%f",diff); isSent = false; } } float diff = ofGetElapsedTimef()-count; for(int i = 0 ; i < NUM_DEVICE ; i ++) { switch(dataSet[i].dir) { case 'S':break; case'U': dataSet[i].length-=diff*dataSet[i].speed; break; case 'D': dataSet[i].length+=diff*dataSet[i].speed; break; } } count = ofGetElapsedTimef(); }
void ImageSynth::update(){ sumLevel = 0; scanX = (ofGetFrameNum() - startFrame) % int(synthImage.getWidth()); zscale = ofNoise(((ofGetElapsedTimef() - startFrame) * 2.0 - 1.0) / 10.0) * zscaleRatio; }
void testApp::doVision() { float startTime = ofGetElapsedTimef(); float img[VISION_WIDTH*VISION_HEIGHT]; float *distPix = kinect.getDistancePixels(); float kinectRangeFar = 4000; float kinectRangeNear = 500; float denom = (kinectRangeFar - kinectRangeNear) * (maxWaterDepth - waterThreshold); if(denom==0) denom = 0.0001; float subtractor = kinectRangeFar - waterThreshold*(kinectRangeFar - kinectRangeNear); for(int i = 0; i < VISION_WIDTH*VISION_HEIGHT; i++) { int x = i % VISION_WIDTH; int y = i / VISION_WIDTH; int ii = x*2 + y * 2 * KINECT_WIDTH; // this is slow //img[i] = ofMap(ofMap(distPix[i], 500, 4000, 1, 0), maxWaterDepth, waterThreshold, 1, 0); img[i] = (subtractor - distPix[ii])/denom; if(img[i]>1) img[i] = 0; if(img[i]<0) img[i] = 0; } depthImg.setFromPixels(img,VISION_WIDTH,VISION_HEIGHT); if(flipX || flipY) depthImg.mirror(flipY, flipX); rangeScaledImg = depthImg; for(int i = 0; i < blurIterations; i++) { rangeScaledImg.blur(2*blurSize+1); } if(erode) { rangeScaledImg.erode(); } if(dilate) { rangeScaledImg.dilate(); } if(accumulateBackground) { cvMax(bgImg.getCvImage(), rangeScaledImg.getCvImage(), bgImg.getCvImage()); bgImg.flagImageChanged(); backgroundAccumulationCount++; if(backgroundAccumulationCount>100) { accumulateBackground = false; backgroundAccumulationCount = 0; } } float *fgPix = rangeScaledImg.getPixelsAsFloats(); float *bgPix = bgImg.getPixelsAsFloats(); int numPix = VISION_WIDTH * VISION_HEIGHT; for(int i = 0; i < numPix; i++) { if(fgPix[i]<=bgPix[i]+backgroundHysteresis) { fgPix[i] = 0; } } rangeScaledImg.setFromPixels(fgPix, VISION_WIDTH, VISION_HEIGHT); maskedImg = rangeScaledImg; CvPoint points[NUM_MASK_POINTS]; for(int i = 0; i < NUM_MASK_POINTS; i++) { points[i] = cvPoint(mask[i].x, mask[i].y); } CvPoint fill[4]; fill[0] = cvPoint(0, 0); fill[1] = cvPoint(VISION_WIDTH, 0); fill[2] = cvPoint(VISION_WIDTH, VISION_HEIGHT); fill[3] = cvPoint(0, VISION_HEIGHT); CvPoint *allPoints[2]; allPoints[0] = points; allPoints[1] = fill; int numPoints[2]; numPoints[0] = NUM_MASK_POINTS; numPoints[1] = 4; // mask out the bit we're interested in cvFillPoly( maskedImg.getCvImage(), allPoints, numPoints, 2, cvScalar(0) ); maskedImg.flagImageChanged(); contourFinder.findContours(maskedImg, minBlobSize*minBlobSize, maxBlobSize*maxBlobSize, 20, false); // compare each blob against the other and eradicate any blobs that are too close to eachother if(blobs.size()>0) { for(int i = 0; i < contourFinder.blobs.size(); i++) { for(int j = i+1; j < contourFinder.blobs.size(); j++) { float dist = tricks::math::getClosestDistanceBetweenTwoContours( contourFinder.blobs[i].pts, contourFinder.blobs[j].pts, 3); // find which one is closest to any other blob and delete the other one if(dist<20) { float distToI = FLT_MAX; float distToJ = FLT_MAX; for(map<int,Blob>::iterator it = blobs.begin(); it!=blobs.end(); it++) { distToI = MIN(distToI, (*it).second.distanceSquared(ofVec2f(contourFinder.blobs[i].centroid))); distToJ = MIN(distToJ, (*it).second.distanceSquared(ofVec2f(contourFinder.blobs[j].centroid))); } if(distToI<distToJ) { // merge the jth into the ith, and delete the jth one mergeBlobIntoBlob(contourFinder.blobs[i], contourFinder.blobs[j]); contourFinder.blobs.erase(contourFinder.blobs.begin() + j); j--; } else { // merge the ith into the jth, and delete the ith one mergeBlobIntoBlob(contourFinder.blobs[j], contourFinder.blobs[i]); contourFinder.blobs.erase(contourFinder.blobs.begin() + i); i--; break; } } } } } blobTracker.trackBlobs(contourFinder.blobs); }
// selfSetup is called when the visual system is first instantiated // This will be called during a "loading" screen, so any big images or // geometry should be loaded here void CloudsVisualSystemFireworks::selfSetup() { //setupParticles FIREWORKS_NUM_PARTICLES = 200000; positions = new ofVec3f[ FIREWORKS_NUM_PARTICLES ]; velocities = new ofVec3f[ FIREWORKS_NUM_PARTICLES ]; lifeData = new ofFloatColor[ FIREWORKS_NUM_PARTICLES ]; indices = new ofIndexType[ FIREWORKS_NUM_PARTICLES ]; minVel = 0; maxVel = 200; float lifespan; float t = ofGetElapsedTimef(); vbo.setVertexData( &positions[0], FIREWORKS_NUM_PARTICLES, GL_DYNAMIC_DRAW ); vbo.setNormalData( &velocities[0], FIREWORKS_NUM_PARTICLES, GL_DYNAMIC_DRAW ); vbo.setIndexData( &indices[0], FIREWORKS_NUM_PARTICLES, GL_DYNAMIC_DRAW ); vbo.setColorData( &lifeData[0], FIREWORKS_NUM_PARTICLES, GL_DYNAMIC_DRAW ); colorSampleImage.loadImage( getVisualSystemDataPath() + "GUI/defaultColorPalette.png" ); loadFileToGeometry( getVisualSystemDataPath() + "animationTargets/dodecahedron.txt", dodecagedronPoints ); loadFileToGeometry( getVisualSystemDataPath() + "animationTargets/octahedron.txt", octahedronPoints ); loadFileToGeometry( getVisualSystemDataPath() + "animationTargets/tetrahedron.txt", tetrahedronPoints ); loadFileToGeometry( getVisualSystemDataPath() + "animationTargets/icosahedron.txt", icosahedronPoints ); //particle behavior fireworkGravity.set(0, -6 / 120., 0 ); particleGravity.set( 0, 40, 0); minVel = 4; maxVel = 60; maxFWVel = 2.4; //shader shader.load(getVisualSystemDataPath() + "shaders/base.vert", getVisualSystemDataPath() + "shaders/base.frag"); shader.begin(); shader.setUniform3f( "gravity", particleGravity.x, particleGravity.y, particleGravity.z ); shader.end(); startColor.set( .9, .95, 1.95, 1 ); endColor.set( .6, 1.3, .2, 1 ); spriteImage.loadImage(getVisualSystemDataPath() + "images/sphereNormal.png"); minLifeSpan = 2; maxLifeSpan = 4; //camera camSpeed = 2; //particle rendering bUpdateVbo = true; indexCount = 0; nextIndex = 0; numSprites = 0; nextFireworkExplosionTime = ofGetElapsedTimef() + 1; ofDisableArbTex(); // sprites["star"].loadImage( getVisualSystemDataPath() + "images/star.png" ); triangleImage.loadImage( getVisualSystemDataPath() + "images/triangle-sprite.png" ); squareImage.loadImage( getVisualSystemDataPath() + "images/square-sprite.png" ); circleImage.loadImage( getVisualSystemDataPath() + "images/circle-sprite.png" ); ofEnableArbTex(); camera.setPosition(0, 0, 0); camTarget.set( 0,0,300); glowFbo0.allocate( ofGetWidth(), ofGetHeight(), GL_RGB ); glowFbo1.allocate( glowFbo0.getWidth()/2, glowFbo0.getHeight()/2, GL_RGB );; glowFbo2.allocate( glowFbo1.getWidth()/2, glowFbo1.getHeight()/2, GL_RGB );; glowFbo3.allocate( glowFbo2.getWidth()/2, glowFbo2.getHeight()/2, GL_RGB );; glowFbo4.allocate( glowFbo3.getWidth()/2, glowFbo3.getHeight()/2, GL_RGB );; glowFbo5.allocate( glowFbo4.getWidth()/2, glowFbo4.getHeight()/2, GL_RGB );; glowFbo6.allocate( glowFbo5.getWidth()/2, glowFbo5.getHeight()/2, GL_RGB );; glowShader.load(getVisualSystemDataPath() + "shaders/post"); }
void FaceScanner::update() { m_grabber.update(); if(m_grabber.isFrameNew()) { if (m_shouldTrack) { m_tracker.update(toCv(m_grabber)); //----If we've found a face, we store its intrinsics and begin our scanning procedure if (m_tracker.getFound() && //Have we found a face? ofGetElapsedTimef() > 2.0f && //Has it been at least 2 seconds? m_tracker.getImageFeature(ofxFaceTracker::FACE_OUTLINE).getArea() > MIN_FACE_AREA) //If we've found a face, is it reasonably large? { ofLogNotice("Face Scanner") << "Found a face."; //----The FBOs are cleared IFF the last sequence drawn was the particle system (denoted by the boolean m_shouldClearAmbient) if (!m_shouldClearAmbient) m_inkRenderer->clear(); m_inkRenderer->setDrawMode(InkRenderer::FOLLOWERS); convertColor(m_grabber, m_thresh, CV_RGB2GRAY); m_faceOutline = m_tracker.getImageFeature(ofxFaceTracker::FACE_OUTLINE); m_faceCenter = m_faceOutline.getCentroid2D(); m_faceArea = m_faceOutline.getArea(); //This is a hack: something is wrong with the sign of the value returned by getArea() m_faceBoundingBox = m_faceOutline.getBoundingBox(); m_shouldTrack = false; m_drawFrameStart = ofGetElapsedTimef(); //When did this scan start? scan(200, 10); //Start at a threshold value of 200, and decrement by 5 for each iteration } else { //----If we don't see a face and it's been m_ambientTimeout seconds, enter ambient mode if ((ofGetElapsedTimef() - m_ambientFrameStart) >= m_ambientTimeout) { //----We only want to do these operations once, otherwise the FBOs will clear every frame, and the particle system will never be drawn if (m_shouldClearAmbient) { ofLogNotice("Face Scanner") << "Entering ambient mode."; //----We tell the InkRenderer to draw particles after clearing the FBOs and resetting the "draw counter" m_inkRenderer->setDrawMode(InkRenderer::PARTICLES); m_inkRenderer->clear(); m_shouldClearAmbient = false; } } } } else if ((ofGetElapsedTimef() - m_drawFrameStart) >= m_drawTimeout) { //----If we shouldn't be tracking, that means we've already found a face, so begin the countdown ofLogNotice("Face Scanner") << "Starting a new scan."; //----After this point, we might not see another face, so we record the current time and ready the InkRenderer for a particle simulation m_ambientFrameStart = ofGetElapsedTimef(); m_shouldClearAmbient = true; ofSaveScreen("screenshots/image_" + ofGetTimestampString() + ".png"); reset(); } } }
// or you can use selfDrawBackground to do 2D drawings that don't use the 3D camera void CloudsVisualSystemFireworks::selfDrawBackground() { glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); // mat->begin(); ofPushStyle(); ofEnableAlphaBlending(); ofBlendMode( OF_BLENDMODE_ADD ); ofEnablePointSprites(); glowFbo0.begin(); ofClear(0,0,0,255); camera.begin(); // glDisable( GL_DEPTH_TEST ); // ofSetColor(225, 235, 255, 30 ); // for (int i=0; i<rockets.size(); i++) { // rockets[i].draw(); // } shader.begin(); shader.setUniform1f( "time", ofGetElapsedTimef() ); shader.setUniform1f( "nearClip", camera.getNearClip() ); shader.setUniform1f( "farClip", camera.getFarClip() ); shader.setUniform3f("cameraPosition", camPos.x, camPos.y, camPos.z ); shader.setUniform4f("startColor", startColor.x, startColor.y, startColor.z, startColor.w ); shader.setUniform4f("endColor", endColor.x, endColor.y, endColor.z, endColor.w ); shader.setUniform3f( "gravity", particleGravity.x, particleGravity.y, particleGravity.z ); shader.setUniformTexture("triangleMap", triangleImage.getTextureReference(), 2 ); shader.setUniformTexture("squareMap", squareImage.getTextureReference(), 1 ); shader.setUniformTexture("circleMap", circleImage.getTextureReference(), 0 ); vbo.drawElements( GL_POINTS, numSprites ); shader.end(); // ofSetColor(255,0,0); // for (int i=0; i<emitterCount; i++) { // ofPushMatrix(); // ofTranslate( emitters[i].pos ); // // ofRect(-5, -5, 10, 10); // // ofPopMatrix(); // } camera.end(); glowFbo0.end(); ofPopStyle(); ofSetColor(255); int alpha = 255; glowFbo1.begin(); ofClear(0,0,0,alpha); glowFbo0.draw(0, 0, glowFbo1.getWidth(), glowFbo1.getHeight() ); glowFbo1.end(); glowFbo2.begin(); ofClear(0,0,0, alpha); glowFbo1.draw(0, 0, glowFbo2.getWidth(), glowFbo2.getHeight() ); glowFbo2.end(); glowFbo3.begin(); ofClear(0,0,0, alpha); glowFbo2.draw(0, 0, glowFbo3.getWidth(), glowFbo3.getHeight() ); glowFbo3.end(); glowFbo4.begin(); ofClear(0,0,0, alpha); glowFbo3.draw(0, 0, glowFbo4.getWidth(), glowFbo4.getHeight() ); glowFbo4.end(); glowFbo5.begin(); ofClear(0,0,0, alpha); glowFbo4.draw(0, 0, glowFbo5.getWidth(), glowFbo5.getHeight() ); glowFbo5.end(); glowFbo6.begin(); ofClear(0,0,0, alpha); glowFbo5.draw(0, 0, glowFbo6.getWidth(), glowFbo6.getHeight() ); glowFbo6.end(); glowShader.begin(); glowShader.setUniformTexture( "fbo", glowFbo0.getTextureReference(), 0); glowShader.setUniformTexture( "mm1", glowFbo1.getTextureReference(), 1); glowShader.setUniformTexture( "mm2", glowFbo2.getTextureReference(), 2); glowShader.setUniformTexture( "mm3", glowFbo3.getTextureReference(), 4); glowShader.setUniformTexture( "mm4", glowFbo4.getTextureReference(), 5); glowShader.setUniformTexture( "mm5", glowFbo5.getTextureReference(), 6); glowShader.setUniformTexture( "mm6", glowFbo6.getTextureReference(), 7); glowFbo0.draw(0, 0, ofGetWidth(), ofGetHeight() ); glowShader.end(); ofDisablePointSprites(); }
void CloudsVisualSystemFireworks::trailPoint( ofVec3f point, ofVec3f vel, int count ) { for(int i=0; i<count; i++){ emitFromPoint( point, vel, ofRandom(minLifeSpan, maxLifeSpan), ofGetElapsedTimef() ); } }
void CloudsVisualSystemFireworks::selfUpdate() { float t = ofGetElapsedTimef(); for (int i=emitters.size()-1; i>=0; i--) { emitters[i].update( t ); if( emitters[i].bStarted ) { emitters[i].pos += fireworkGravity * emitters[i].span * emitters[i].age * 10; ofVec3f p0 = emitters[i].pos; ofVec3f nScl = p0 * .01; float nx = ofSignedNoise(nScl.x + emitters[i].age, nScl.y, nScl.z); float ny = ofSignedNoise(nScl.x, nScl.y + emitters[i].age, nScl.z); float nz = ofSignedNoise(nScl.x, nScl.y, nScl.z + emitters[i].age); p0 += ofVec3f( nx, ny, nz ) * 10. * emitters[i].age; trailPoint( p0, emitters[i].vel, 4 ); } if(emitters[i].bEnded) { emitters.erase( emitters.begin() + i ); } } // for (int i=rockets.size()-1; i>=0; i--) // { // rockets[i].update( t ); // // if(rockets[i].bEnded) // { // rockets.erase( rockets.begin() + i ); // } // } //camera ofVec3f eul = camera.getOrientationEuler(); float xDamp = ofMap( abs(eul.x), 70, 90, 1, 0, true ); float noiseTimeScl = .1; float noiseOffsetScl = 800; float mouseScl = .25; float panScl = -5; float noiseValX = ofSignedNoise( ofGetElapsedTimef() * noiseTimeScl + 1. ) * noiseOffsetScl; float noiseValY = ofSignedNoise( ofGetElapsedTimef() * noiseTimeScl ) * noiseOffsetScl; float pan = ofMap(ofGetMouseX() + noiseValX, 0, ofGetWidth(), mouseScl, -mouseScl); float tilt = ofMap(ofGetMouseY() + noiseValY, 0, ofGetHeight(), -mouseScl, mouseScl) * xDamp; if(abs(eul.x) < 90) camera.tilt( tilt ); camera.pan( pan ); float roll = abs(pan) * pan * panScl; camera.roll( roll ); camera.move(0, abs(roll), 0); ofVec3f vel = camera.getLookAtDir(); camera.move( vel * camSpeed ); float targetDistance = 300; camTarget = vel * targetDistance + camera.getPosition(); //particles bool updateIndices = false; indexCount = 0; for(int i=0; i<FIREWORKS_NUM_PARTICLES; i++){ //if the age + lifespan is less then the current time we want to draw if(lifeData[i].r + lifeData[i].g > t){ indices[indexCount] = i; indexCount++; updateIndices = true; } } if(updateIndices){ vbo.updateIndexData( indices, indexCount ); } //fireworks... for (int i = spawnTime.size()-1; i>=0; i--) { //if it's alive apply gravity if(spawnTime[i] + 2 > t ){ spawnPos[i] += spawnVel[i]; spawnVel[i] += fireworkGravity; spawnVel[i] *= .99; trailPoint( spawnPos[i], spawnVel[i].normalized() ); } else { spawnPos.erase( spawnPos.begin()+i ); spawnVel.erase( spawnVel.begin()+i ); spawnTime.erase( spawnTime.begin()+i ); } } if( bUpdateVbo ) { updateVbo(); } if( nextFireworkExplosionTime < t ) { explodeFireWorkAtRandom(); } }
//will work offline void mpeClientTCP::useSimulationMode(int framesPerSecond) { simulatedFPS = framesPerSecond; simulationMode = true; lastFrameTime = ofGetElapsedTimef(); }
void ofxFFmpegVideoPlayer::play(){ bPlaying = true; timeOfLastNewFrame = ofGetElapsedTimef(); }
//-------------------------------------------------------------- // Reads and parses a message from the server. //-------------------------------------------------------------- void mpeClientTCP::read(string _serverInput) { out("Receiving: " + _serverInput); char c = _serverInput.at(0); if(c == 'R'){ if(frameCount != 0){ //we received a reset signal if(useMainThread){ shouldReset = true; } else{ reset(); } cout << "Received frame reset" << endl; } } else if (c == 'G' || c == 'B' || c == 'I') { if (!allConnected) { if (DEBUG) out("all connected!"); allConnected = true; } lastHeartbeatTime = ofGetElapsedTimef(); // split into frame message and data message vector<string> info = ofSplitString(_serverInput, ":"); vector<string> frameMessage = ofSplitString(info[0], ","); int fc = ofToInt(frameMessage[1]); if (frameLock && fc == frameCount) { frameCount++; // calculate new framerate float nowms = ofGetElapsedTimeMillis(); float ms = nowms - lastMs; fps += ((1000.f / ms) - fps)*.2; lastMs = nowms; if(!useMainThread){ //cout << "trigger frame " << frameCount << endl; ofxMPEEventArgs e; e.message = ""; e.frame = frameCount; ofNotifyEvent(ofxMPEEvents.mpeFrame, e); done(); } else { //cout << "trigger frame " << frameCount << endl; triggerFrame = true; } } //JG switched to after done event if (info.size() > 1) { // there is a message here with the frame event info.erase(info.begin()); //TODO: Track Byte/Int/Floats messages too for(int i = 0; i < info.size(); i++){ if(useMainThread){ dataMessage.push_back( info[i] ); } else{ ofxMPEEventArgs e; e.message = info[i]; e.frame = getFrameCount(); //cout << "sending message in update " << e.frame << " message " << e.message << endl; ofNotifyEvent(ofxMPEEvents.mpeMessage, e); } //cout << "MPE frame " << getFrameCount() << " receiving data message " << dataMessage[i] << endl; } } } }
//-------------------------------------------------------------- void flowToolsApp::update(){ deltaTime = ofGetElapsedTimef() - lastTime; lastTime = ofGetElapsedTimef(); simpleCam.update(); if (simpleCam.isFrameNew()) { ofPushStyle(); ofEnableBlendMode(OF_BLENDMODE_DISABLED); cameraFbo.begin(); if (doFlipCamera) simpleCam.draw(cameraFbo.getWidth(), 0, -cameraFbo.getWidth(), cameraFbo.getHeight()); // Flip Horizontal else simpleCam.draw(0, 0, cameraFbo.getWidth(), cameraFbo.getHeight()); cameraFbo.end(); ofPopStyle(); opticalFlow.setSource(cameraFbo.getTextureReference()); opticalFlow.update(deltaTime); velocityMask.setDensity(cameraFbo.getTextureReference()); velocityMask.setVelocity(opticalFlow.getOpticalFlow()); velocityMask.update(); } fluidSimulation.addVelocity(opticalFlow.getOpticalFlowDecay()); fluidSimulation.addDensity(velocityMask.getColorMask()); fluidSimulation.addTemperature(velocityMask.getLuminanceMask()); mouseForces.update(deltaTime); for (int i=0; i<mouseForces.getNumForces(); i++) { if (mouseForces.didChange(i)) { switch (mouseForces.getType(i)) { case FT_DENSITY: fluidSimulation.addDensity(mouseForces.getTextureReference(i), mouseForces.getStrength(i)); break; case FT_VELOCITY: fluidSimulation.addVelocity(mouseForces.getTextureReference(i), mouseForces.getStrength(i)); particleFlow.addFlowVelocity(mouseForces.getTextureReference(i), mouseForces.getStrength(i)); break; case FT_TEMPERATURE: fluidSimulation.addTemperature(mouseForces.getTextureReference(i), mouseForces.getStrength(i)); break; case FT_PRESSURE: fluidSimulation.addPressure(mouseForces.getTextureReference(i), mouseForces.getStrength(i)); break; case FT_OBSTACLE: fluidSimulation.addTempObstacle(mouseForces.getTextureReference(i)); default: break; } } } fluidSimulation.update(); if (particleFlow.isActive()) { particleFlow.setSpeed(fluidSimulation.getSpeed()); particleFlow.setCellSize(fluidSimulation.getCellSize()); particleFlow.addFlowVelocity(opticalFlow.getOpticalFlow()); particleFlow.addFluidVelocity(fluidSimulation.getVelocity()); // particleFlow.addDensity(fluidSimulation.getDensity()); particleFlow.setObstacle(fluidSimulation.getObstacle()); } particleFlow.update(); }
//-------------------------------------------------------------- void testApp::guiEvent(ofxUIEventArgs &e) { int kind = e.widget->getKind(); string name = e.widget->getName(); if(kind == OFX_UI_WIDGET_BUTTON) { ofxUIButton *button = (ofxUIButton *) e.widget; cout << name << "\t value: " << button->getValue() << endl; if(e.widget->getName() == "CLOCKWISE" && button->getValue()) { string message; vector<ofxUIToggle *> toggles = matrix->getToggles(); for(int i = 0 ; i < toggles.size() ; i++) { if(toggles[i]->getValue()) message+=ofToString(i)+",D;"; } serial.writeBytes((unsigned char*)message.c_str(),message.length()); ofLog(OF_LOG_VERBOSE,"serial.writeBytes "+message); timeDiff = ofGetElapsedTimef(); isSent = true; } else if(e.widget->getName() == "COUNTER_CLOCKWISE" && button->getValue()) { string message; vector<ofxUIToggle *> toggles = matrix->getToggles(); for(int i = 0 ; i < toggles.size() ; i++) { if(toggles[i]->getValue()) message+=ofToString(i)+",U;"; } serial.writeBytes((unsigned char*)message.c_str(),message.length()); ofLog(OF_LOG_VERBOSE,"serial.writeBytes "+message); timeDiff = ofGetElapsedTimef(); isSent = true; }else if(e.widget->getName() == "CLOCKWISE" || e.widget->getName() == "COUNTER_CLOCKWISE") { if(!button->getValue()) { string message; vector<ofxUIToggle *> toggles = matrix->getToggles(); for(int i = 0 ; i < toggles.size() ; i++) { if(toggles[i]->getValue()) message+=ofToString(i)+",S;"; } serial.writeBytes((unsigned char*)message.c_str(),message.length()); ofLog(OF_LOG_VERBOSE,"serial.writeBytes "+message); timeDiff = ofGetElapsedTimef(); isSent = true; } }else if(e.widget->getName() == "SEND" && button->getValue()) { ofxUIButton *button = (ofxUIButton*) e.widget; if(button->getValue()) { string message; vector<ofxUIToggle *> toggles = matrix->getToggles(); for(int i = 0 ; i < toggles.size() ; i++) { int output = ofMap(sliders[i]->getScaledValue(),0.0f,1.0f,range->getScaledValueLow(),range->getScaledValueHigh()); //printf("output %i",output); if(toggles[i]->getValue())message+=ofToString(i)+ ","+ ofToString(output) +";"; } serial.writeBytes((unsigned char*)message.c_str(),message.length()); ofLog(OF_LOG_VERBOSE,"serial.writeBytes "+message); timeDiff = ofGetElapsedTimef(); isSent = true; } }else if(e.widget->getName() == "SAVE" && button->getValue()) { gui->saveSettings("GUI/guiSettings.xml"); gui1->saveSettings("GUI/guiSettings1.xml"); }else if(e.widget->getName() == "RESET") { string s; for(int i = 0 ; i < NUM_DEVICE ; i++) { s += (ofToString(i)+","+"0;"); } serial.writeBytes((unsigned char*)s.c_str(),s.length()); } } else { if(e.widget->getName() == "FULLSCREEN") { ofxUIToggle *toggle = (ofxUIToggle *) e.widget; ofSetFullscreen(toggle->getValue()); } else if(e.widget->getName() == "LOG_LEVEL") { ofxUIDropDownList *ddlist = (ofxUIDropDownList *) e.widget; vector<ofxUIWidget *> &selected = ddlist->getSelected(); for(int i = 0; i < selected.size(); i++) { ofSetLogLevel((ofLogLevel)i); } } else if(e.widget->getName() == "DEVICE_LIST") { ofxUIDropDownList *ddlist = (ofxUIDropDownList *) e.widget; vector<ofxUIWidget *> &selected = ddlist->getSelected(); for(int i = 0; i < selected.size(); i++) { cout << "SELECTED: " << selected[i]->getName() << endl; serial.setup(i, 57600); break; } } } }
//------------------------------------------------------------- void snakeCharmer::draw(int _x ,int _y, ofColor outside, ofColor meshColor){ ofPolyline polyLine; polyLine.addVertices(pts); //if(forcePt>0.1){ polyLine = polyLine.getSmoothed(ofMap(forcePt, 0, .5, 6, 1)); //cout<<forcePt<<endl; pts = polyLine.getVertices(); //} ofPushMatrix(); ofTranslate(_x, _y); ofSetColor(255); ofNoFill(); ofBeginShape(); for(int i=0; i<pts.size(); i++){ if(i==pts.size()-1){ //ofSetColor(0,0,0); //ofCircle(pts[i]+5, 10); //ofCircle(pts[i]-5, 10); } if(i==0){ //ofSetColor(127); //ofCircle(pts[i], 30); //ofSetColor(255); // ofCircle(pts[i]+1, 10); } ofSetColor(255); //ofVertex(pts[i].x, pts[i].y, pts[i].z); } ofEndShape(false); oscillate=1; ofSetLineWidth(0.2); ofSetColor(outside); //SPIKES------------ if(drawSpikes){ //int stepSize = 2; //int scale = 5; ofVec3f a, b, tangent, normal, mappedA, mappedB; for (int i=0; i<pts.size()-stepSize; i=i+stepSize){ if (i>2) { a = polyLine.getVertices()[i]; b = polyLine.getVertices()[i+stepSize]; float newScale; if (i>stepSize) { //newScale = ofMap(a.distance(b), 0, 500, 5, maxVelScale, true); newScale = ofMap(widthPts[i], 0, 1, 0, 400); } tangent = b-a; tangent.getRotated(90, ofVec3f(0,0,1)); normal = tangent.getRotated(90,ofVec3f(0,0,1)); normal.normalize(); ofVec3f corner; //compute top side corner.x = a.x+ofClamp(ofDist(b.x,b.y,a.x,a.y),0,5)+normal.x*newScale+20*sin(noiseScale*ofSignedNoise((i*noiseSpeed)+ofGetElapsedTimef())); corner.y = a.y+ofClamp(ofDist(b.x,b.y,a.x,a.y),0,5)+normal.y*newScale+20*sin(noiseScale*ofSignedNoise((i*noiseSpeed)+ofGetElapsedTimef())); corner.z = a.z; ofLine(a+20*sin(noiseScale*ofSignedNoise((i*noiseSpeed)+ofGetElapsedTimef())),corner); normal = tangent.getRotated(-90,ofVec3f(0,0,1)); normal.normalize(); corner.x = a.x-ofClamp(ofDist(b.x,b.y,a.x,a.y),0,5)+normal.x*newScale-20*sin(-noiseScale*ofSignedNoise((i*noiseSpeed+0.01)+ofGetElapsedTimef())); corner.y = a.y-ofClamp(ofDist(b.x,b.y,a.x,a.y),0,5)+normal.y*newScale-20*sin(-noiseScale*ofSignedNoise((i*noiseSpeed+0.01)+ofGetElapsedTimef())); corner.z = a.z; //ofCircle(a, .5*ofDist(b.x,b.y,a.x,a.y)); //corner = a + normal*scale + 5*sin(1+(i*0.05)*ofGetElapsedTimef()); //corner.x = corner.x * sin(.5*ofGetElapsedTimef())*sin(ofGetElapsedTimef()); //corner.y = corner.y * cos(.7*ofGetElapsedTimef())*cos(ofGetElapsedTimef()); ofLine(a+20*sin(noiseScale*ofSignedNoise((i*noiseSpeed)+ofGetElapsedTimef())),corner); } } } // SKINNNN ofSetLineWidth(2); if (drawSkin){ ofPolyline outLines; ofPolyline inLines; //int stepSize = 2; // int scale = 5; ofVec3f a, b, tangent, normal, mappedA, mappedB; //outLines.addVertex(pts[1]); //inLines.addVertex(pts[1]); for (int i=0; i<pts.size()-stepSize; i=i+stepSize){ if(i>2){ //wonky on the first one...so skip it...need 2 for normalizing anyway a = polyLine.getVertices()[i]; b = polyLine.getVertices()[i+stepSize]; float newScale; if (i>stepSize) { //newScale = ofMap(a.distance(b), 0, 500, 5, maxVelScale, true); newScale = ofMap(widthPts[i], 0, 1, 0, 400); } tangent = b-a; tangent.getRotated(90, ofVec3f(0,0,1)); normal = tangent.getRotated(90,ofVec3f(0,0,1)); normal.normalize(); ofVec3f corner; //compute top side corner.x = a.x+ofClamp(ofDist(b.x,b.y,a.x,a.y),0,5)+normal.x*newScale+20*sin(noiseScale*ofSignedNoise((i*noiseSpeed)+ofGetElapsedTimef())); corner.y = a.y+ofClamp(ofDist(b.x,b.y,a.x,a.y),0,5)+normal.y*newScale+20*sin(noiseScale*ofSignedNoise((i*noiseSpeed)+ofGetElapsedTimef())); corner.z = a.z; //ofLine(a,corner); inLines.addVertex(corner); //compute bottom side normal = tangent.getRotated(-90,ofVec3f(0,0,1)); normal.normalize(); corner.x = a.x-ofClamp(ofDist(b.x,b.y,a.x,a.y),0,5)+normal.x*newScale-20*sin(-noiseScale*ofSignedNoise((i*noiseSpeed+0.01)+ofGetElapsedTimef())); corner.y = a.y-ofClamp(ofDist(b.x,b.y,a.x,a.y),0,5)+normal.y*newScale-20*sin(-noiseScale*ofSignedNoise((i*noiseSpeed+0.01)+ofGetElapsedTimef())); corner.z = a.z; //corner.x = corner.x * sin(.5*ofGetElapsedTimef())*sin(ofGetElapsedTimef()); //corner.y = corner.y * cos(.7*ofGetElapsedTimef())*cos(ofGetElapsedTimef()); outLines.addVertex(corner); //ofLine(a,corner); } } //outLines.addVertex(pts[vecSize-1]); //inLines.addVertex(pts[vecSize-1]); // ofPolyline outSmooth; // outSmooth = outLines.getSmoothed(2); //outSmooth.draw(); //outSmooth.clear(); ofSetColor(255); outLines.draw(); outLines.clear(); //outSmooth = inLines.getSmoothed(2); //outSmooth.draw(); inLines.draw(); inLines.clear(); } //filled in mesh if (drawMesh) { ofEnableAlphaBlending(); ofMesh mesh; mesh.setMode(OF_PRIMITIVE_TRIANGLE_STRIP); ofFloatColor meshFColor; meshFColor = meshColor; //cout << "------------------------------------NEW MESH with this many verts: " + ofToString(vecSize) <<endl; ofVec3f a, b, tangent, normal, mappedA, mappedB; for (int i=0; i<polyLine.getVertices().size()-stepSize; i=i+stepSize){ //a = pts[i]; //b = pts[i +stepSize]; if (i>polyLine.getVertices().size()-polyLine.getVertices().size()*.95) { //this is a hacky fix because something is happening at the tail end of the line that causes it to shoot off screen - what this does is tells it to only draw 95% of the line a = polyLine.getVertices()[i]; b = polyLine.getVertices()[i+stepSize]; //cout<<i<< " " << polyLine.getVertices()[i] <<endl; float newScale; if (i>stepSize) { //newScale = ofMap(a.distance(b), 0, 500, 5, maxVelScale, true); newScale = ofMap(widthPts[i], 0, 1, 0, 400); } tangent = b-a; tangent.getRotated(90, ofVec3f(0,0,1)); normal = tangent.getRotated(90,ofVec3f(0,0,1)); normal.normalize(); ofVec3f corner; //compute top side corner.x = a.x+ofClamp(ofDist(b.x,b.y,a.x,a.y),0,5)+normal.x*newScale+20*sin(noiseScale*ofSignedNoise((i*noiseSpeed)+ofGetElapsedTimef())); corner.y = a.y+ofClamp(ofDist(b.x,b.y,a.x,a.y),0,5)+normal.y*newScale+20*sin(noiseScale*ofSignedNoise((i*noiseSpeed)+ofGetElapsedTimef())); corner.z = a.z; //make tail end fade alpha //add top side point //mesh.addColor(ofFloatColor(meshColor.r/255,meshColor.g/255,meshColor.b/255,ofMap(i,0,polyLine.getVertices().size(),0.0,1))); meshFColor.a =ofMap(i,0,polyLine.getVertices().size(),0.0,1); mesh.addColor(meshFColor); mesh.addVertex(corner); //cout<<"Top Corner: " << ofToString(corner) << endl; //compute bottom side normal = tangent.getRotated(-90,ofVec3f(0,0,1)); normal.normalize(); corner.x = a.x-ofClamp(ofDist(b.x,b.y,a.x,a.y),0,5)+normal.x*newScale-20*sin(-noiseScale*ofSignedNoise((i*noiseSpeed+0.01)+ofGetElapsedTimef())); corner.y = a.y-ofClamp(ofDist(b.x,b.y,a.x,a.y),0,5)+normal.y*newScale-20*sin(-noiseScale*ofSignedNoise((i*noiseSpeed+0.01)+ofGetElapsedTimef())); corner.z = a.z; //mesh.addColor(ofFloatColor(float(meshColor.r/255),float(meshColor.g/255),float(meshColor.b/255),ofMap(i,0,polyLine.getVertices().size(),0.0,1))); meshFColor.a =ofMap(i,0,polyLine.getVertices().size(),0.0,1); mesh.addColor(meshFColor); mesh.addVertex(corner); // cout<<"Bottom Corner: " << ofToString(corner) << endl; //ofLine(a,corner); } } //cout<< vecSize << " " << meshColor<<endl; ofSetColor(255); mesh.draw(); } ofPopMatrix(); }
void wavesScene::updateParticles(){ for(int z = 0; z < 2; z++){ for (int i = 0; i < cvData[z]->blobs.size(); i++){ ofPoint avgVelSmoothed = cvData[z]->blobs[i].avgVelSmoothed; ofPolyline & line = cvData[z]->blobs[i].blob; // different ways to use it... //if (avgVelSmoothed.getNormalized().dot(ofPoint(0,-1)) > 0.7){ if (avgVelSmoothed.y < -1){ float mapMe = ofMap(avgVelSmoothed.y, mapVelmin, mapVelmax, 0.99, 0.9); for (int j = 0; j < line.size(); j++){ ofPoint pt = line[j]; pt = cvData[z]->remapForScreen(z == 0 ? SCREEN_LEFT : SCREEN_RIGHT, pt); ofPoint vel = cvData[z]->blobs[i].vel[j]; ofPoint velNorm = vel.getNormalized(); float dot = velNorm.dot(ofPoint(0,-1)); // up if (dot > dotValue && vel.length() > velLength && ofRandom(0,1) > mapMe){ // is this FACING up ? ofPoint tan = cvData[z]->blobs[i].blob.getTangentAtIndex(j).rotate(90, ofPoint(0,0,1)); if (tan.dot(ofPoint(0,-1)) > 0.1){ particleWithAge temp; temp.age = ofGetElapsedTimef(); temp.radius = ofRandom(1 * sf, 30 * sf); temp.setInitialCondition(pt.x, pt.y, vel.x * 0.1, vel.y*0.5); // reduce the x vel temp.damping = 0.01; particles.push_back(temp); if (particles.size() > 1000){ particles.erase(particles.begin()); } } } } } //line.draw(); } } ofRectangle target = cvData[0]->getScreenRemapRectangle(SCREEN_LEFT); ofRectangle screenCenter = RM->getRectForScreen(SCREEN_CENTER); ofRectangle screenTop = RM->getRectForScreen(SCREEN_TOP); ofRectangle screenLeft = RM->getRectForScreen(SCREEN_LEFT); ofRectangle screenRight = RM->getRectForScreen(SCREEN_RIGHT); ofRectangle deadRectLeft; deadRectLeft.set(screenLeft.x, screenTop.y+300, screenLeft.getWidth(), screenLeft.y - screenTop.y); ofRectangle deadRectRight; deadRectRight.set(screenRight.x, screenTop.y+300, screenLeft.getWidth(), screenLeft.y - screenTop.y); for (int i = 0; i < particles.size(); i++){ particles[i].resetForce(); particles[i].addDampingForce(); float r = screenLeft.getWidth()/2; float x = screenLeft.getCenter().x; float y = screenTop.getCenter().y+300; // check underwater particles by setting its id: underwater: 0 ofVec2f pPos = particles[i].pos; for (int k = 0; k < stencilWaves.waves[0].points.size(); k++){ ofVec2f wPos = stencilWaves.waves[0].points[k].p; int i_n = min(k+1, (int)stencilWaves.waves[0].points.size()-1); ofVec2f wPosNext = stencilWaves.waves[0].points[i_n].p; if(pPos.x > wPos.x && pPos.x < wPosNext.x){ if(pPos.y<wPos.y){ particles[i].id = 1; }else{ particles[i].id = 0; } } } } // add some noise! float time = ofGetElapsedTimef(); for (int i = 0; i < particles.size(); i++){ ofPoint pos = particles[i].pos; float speed = ofMap(time-particles[i].age, 1, 5, 1, 0, true); float xNoise = ofSignedNoise(pos.x * 0.1, pos.y * 0.1, i, time * 0.1); float yNoise = ofSignedNoise(pos.x * 0.1, pos.y * 0.1, i, time * 0.1 + 100000); particles[i].addForce(xNoise*0.2 * speed, -fabs(yNoise) * 0.2 * speed); } // get flow from the field: for (int i = 0; i < particles.size(); i++){ ofPoint vel = cvData[0]->getFlowAtScreenPos(SCREEN_LEFT, particles[i].pos); particles[i].addForce(vel.x*0.03, vel.y*0.03); } for (int i = 0; i < particles.size(); i++){ particles[i].update(); } updateParticlesMesh(); }
//-------------------------------------------------------------- void ofApp::draw(){ ofBackgroundGradient(ofColor(255), ofColor(200), OF_GRADIENT_BAR); ofSetColor(200); ofDrawBitmapString("ofxLeapMotion - Example App\nLeap Connected? " + ofToString(leap.isConnected()), 20, 20); // light.enable(); cam.begin(); // ofPushMatrix(); // ofRotate(90, 0, 0, 1); // ofSetColor(20); // ofDrawGridPlane(800, 20, false); // ofPopMatrix(); fingerType fingerTypes[] = {THUMB, INDEX, MIDDLE, RING, PINKY}; for(int i = 0; i < simpleHands.size(); i++){//手の数だけfor文を回す bool isLeft = simpleHands[i].isLeft; ofPoint handPos = simpleHands[i].handPos; hand[i]=handPos; ofPoint handNormal = simpleHands[i].handNormal; ofSetColor(0,100); ofDrawSphere(handPos.x, handPos.y, handPos.z, 20);//手の中心の座標に円を描画 //手の法線ベクトルを描画 // ofSetColor(255); // ofDrawArrow(handPos, handPos + 100*handNormal); for (int f=0; f<5; f++) {//手の関節を描画するためのfor文 ofPoint mcp = simpleHands[i].fingers[ fingerTypes[f] ].mcp; // metacarpal ofPoint pip = simpleHands[i].fingers[ fingerTypes[f] ].pip; // proximal ofPoint dip = simpleHands[i].fingers[ fingerTypes[f] ].dip; // distal ofPoint tip = simpleHands[i].fingers[ fingerTypes[f] ].tip; // fingertip //手の関節を描画 ofSetColor(120, 100);//手の関節の色 ofDrawSphere(mcp.x, mcp.y, mcp.z, 15); ofDrawSphere(pip.x, pip.y, pip.z, 15); ofDrawSphere(dip.x, dip.y, dip.z, 15); ofDrawSphere(tip.x, tip.y, tip.z, 15); //手の骨を描画 ofSetColor(150,100);//手の骨の色 ofSetLineWidth(10); ofLine(mcp.x, mcp.y, mcp.z, pip.x, pip.y, pip.z); ofLine(pip.x, pip.y, pip.z, dip.x, dip.y, dip.z); ofLine(dip.x, dip.y, dip.z, tip.x, tip.y, tip.z); }//手の関節を描画するためのfor文 }//手の数だけfor文を回す if(simpleHands.size()==2&&mode==true){//手を認識するまでの五秒間 gravity=0; ofSetColor(20,50); rad = ofDist(hand[0].x,hand[1].x, hand[0].y,hand[1].y); rad+=sqrt(pow( hand[1].z,2)+pow( hand[0].z,2)); ofDrawSphere((hand[0].x+hand[1].x)/2, (hand[0].y+hand[1].y)/2, (hand[0].z+hand[1].z)/2,rad/2-20); } if(mode==false && hand[3].y+gravity <= ofGetHeight()-500){//落ちる状態 gravity+=5; ofSetColor(20,50); ofDrawSphere(hand[3].x,hand[3].y-gravity,hand[3].z,rad2/2); }else if(drop==true && hand[3].y+gravity>ofGetHeight()-500){//下に到達した時 image[0].bind();//リンゴをbind() ofSetColor(255); ofDrawSphere(hand[3].x,hand[3].y-gravity,hand[3].z,rad2/2); image[0].unbind(); } cam.end(); // light.enable(); if(mode==true){//落ちるまでの五秒間 float time = ofGetElapsedTimef()-timeStart;//残り時間をカウント if(time>=6){//五秒経過するとき(その瞬間) mode=false;//0or1→2本を認識したときのスイッチのmodeをoffに(ここのサブルーチンに来ないように) hand[3].x=(hand[0].x+hand[1].x)/2;//球の中心座標を保存 hand[3].y=(hand[0].y+hand[1].y)/2; hand[3].z=(hand[0].z+hand[1].z)/2; rad2=rad;//半径を固定してコピー drop=true;//落ちている状態かどうかのboolをtrueにセット } ofSetColor(0); font.drawString(ofToString((int)(6-time))+"",150,250);//秒数表示 } }
//-------------------------------------------------------------- void RuleOne::draw(){ //BG------white paper with light blue gridded lines-------------------- ofBackground(255); ofSetColor( ofColor::lightBlue); ofSetLineWidth(1); for (int i = 0; i < ofGetWidth(); i = i + 20){ ofLine(i,0,i, ofGetHeight()); } for (int i = 0; i < ofGetHeight(); i = i + 20){ ofLine(0, i, ofGetWidth(), i); } //----------draw ellipses------------------------------ float sinOfTime = sin( ofGetElapsedTimef() ); float sinOfTimeMapped = ofMap( sinOfTime, -1, 1, 0, 255); float sinOfTime2 = sin( ofGetElapsedTimef() + PI); float sinOfTimeMapped2 = ofMap( sinOfTime2, -1, 1, 0, 255); sin(ofGetElapsedTimef()); // moves from -1 and 1 every 2Pi seconds float sinValue = sin(ofGetElapsedTimef()*2); ofColor c; c.set(ofColor::pink); c.lerp( ofColor::blue, ofMap(ofGetMouseX(), 0, ofGetWidth(), 0, 1, true)); ofSetColor(c); ofCircle(610,480+sinValue*17, 5); ofCircle(640,480+sinValue*15, 5); ofCircle(670,480+sinValue*20, 5); //----------draw letters----------------- moveup = 20; ofSetColor(255); Inst.draw(540,ofGetHeight()-60); letterheight = 380- moveup; float intalphaMapped = ofMap(moveZach, 20, ofGetWidth()-400, 0, 255); ofSetColor(224,103,99,intalphaMapped); IntroBlack.drawString(letterT, 235,letterheight); ofSetColor(245,155,181,intalphaMapped); IntroBlack.drawString(letterR, 405,letterheight); ofSetColor(200,221,109,intalphaMapped); IntroBlack.drawString(letterU, 605,letterheight); ofSetColor(98,196,215,intalphaMapped); IntroBlack.drawString(letterS, 805, letterheight); ofSetColor(245,155,181,intalphaMapped); IntroBlack.drawString(letterT2, 1005,letterheight); ofSetColor(brown); RuleOneeverything.draw(50,25); if (ofGetMousePressed() && ofGetMouseX()>100 && ofGetMouseX()<ofGetWidth()-305){ moveZach = ofGetMouseX(); } Zach.draw(moveZach-220,434,484/1.1,430/1.1); }
void testApp::keyPressed(int key) { // if(key == 'c') { // addEmail(); // } // if(key == 't') ofToggleFullscreen(); if(key == 'm'){ numCategories++; for(int i=0; i < emails.size(); i++){ emails[i].timeStamp = ofGetElapsedTimef(); } } if(key == 'n'){ if(numCategories > 1){ numCategories--; for(int i=0; i < emails.size(); i++){ emails[i].timeStamp = ofGetElapsedTimef(); } } } if(key == 'a'){ xShift-=10; resetAttractionPoints(numCategories); applyNewAttractionPoints(numCategories); cout << xShift << ", " << yShift << "\n"; } if(key == 's'){ xShift+=10; resetAttractionPoints(numCategories); applyNewAttractionPoints(numCategories); cout << xShift << ", " << yShift << "\n"; } if(key == 'w'){ yShift+=10; resetAttractionPoints(numCategories); applyNewAttractionPoints(numCategories); cout << xShift << ", " << yShift << "\n"; } if(key == 'z'){ yShift-=10; resetAttractionPoints(numCategories); applyNewAttractionPoints(numCategories); cout << xShift << ", " << yShift << "\n"; } if(key == 'o'){ unitRadius-=10; resetAttractionPoints(numCategories); applyNewAttractionPoints(numCategories); cout << "unit radius: " << unitRadius << "\n"; } if(key == 'p'){ unitRadius+=10; resetAttractionPoints(numCategories); applyNewAttractionPoints(numCategories); cout << "unit radius: " << unitRadius << "\n"; } }
//-------------------------------------------------------------- void testApp::draw(){ // -------------------------- draw the line TPR.draw(); // -------------------------- draw the point at the current time if (TPR.bHaveADrawing()){ // if we have a drawing to work with // figure out what time we are at, and make sure we playback cyclically (!) // use the duration here and make sure our timeToCheck is in the range of 0 - duration float timeToCheck = ofGetElapsedTimef() - playbackStartTime; while (timeToCheck > TPR.getDuration() && TPR.getDuration() > 0){ timeToCheck -= TPR.getDuration(); } // get the position and velocity at timeToCheck ofPoint pos = TPR.getPositionForTime(timeToCheck); ofPoint vel = TPR.getVelocityForTime(timeToCheck); // since velocity is a line, we want to know how long it is. float lengthOfVel = ofDist(0,0,vel.x, vel.y); float soundVolume = ofMap(lengthOfVel, 0,200, 0,1); loopingSound.setVolume(soundVolume); float pitch = ofMap(pos.y, 0, (float)ofGetHeight(), 2.5, 0.1); loopingSound.setSpeed(pitch); float pan = ofMap(pos.x, 0, (float)ofGetWidth(), -1, 1); loopingSound.setPan(pan); ofEnableAlphaBlending(); ofFill(); ofSetColor(lengthOfVel,lengthOfVel,lengthOfVel); ofCircle(pos.x, pos.y, 10+ lengthOfVel/5.0); //ofSetColor(55,0,255,lengthOfVel); ofCircle(ofRandom(pos.x-10,pos.x+10), pos.y, 2 + lengthOfVel/5.0); ofEnableAlphaBlending(); /*fingerMovie.draw(20,20); ofSetHexColor(0x000000); unsigned char * pixels = fingerMovie.getPixels(); // let's move through the "RGB" char array // using the red pixel to control the size of a circle. for (int i = 4; i < 320; i+=8){ for (int j = 4; j < 240; j+=8){ unsigned char r = pixels[(j * 320 + i)*3]; float val = 1 - ((float)r / 255.0f); ofCircle(400 +i,20+j,lengthOfVel/100.0); } } } ofSetHexColor(0xFFFFFF); fingerMovie.draw(20,20); ofSetHexColor(0x000000); unsigned char * pixels = fingerMovie.getPixels(); // let's move through the "RGB" char array // using the red pixel to control the size of a circle. for (int i = 4; i < 320; i+=8){ for (int j = 4; j < 240; j+=8){ unsigned char r = pixels[(j * 320 + i)*3]; float val = 1 - ((float)r / 255.0f); ofCircle(400 + i,20+j,10*val); }*/ } cam.draw(ofGetWidth()/2-160, ofGetHeight()/2-120); /*ofSetHexColor(0x000000); ofDrawBitmapString("press f to change",20,320); if(frameByframe) ofSetHexColor(0xCCCCCC); ofDrawBitmapString("mouse speed position",20,340); if(!frameByframe) ofSetHexColor(0xCCCCCC); else ofSetHexColor(0x000000); ofDrawBitmapString("keys <- -> frame by frame " ,190,340); ofSetHexColor(0x000000); ofDrawBitmapString("frame: " + ofToString(fingerMovie.getCurrentFrame()) + "/"+ofToString(fingerMovie.getTotalNumFrames()),20,380); ofDrawBitmapString("duration: " + ofToString(fingerMovie.getPosition()*fingerMovie.getDuration(),2) + "/"+ofToString(fingerMovie.getDuration(),2),20,400); ofDrawBitmapString("speed: " + ofToString(fingerMovie.getSpeed(),2),20,420); if(fingerMovie.getIsMovieDone()){ ofSetHexColor(0xFF0000); ofDrawBitmapString("end of movie",20,440); }*/ }
//------------------------------------------------------------------ void particleShader::update(){ //1 - APPLY THE FORCES BASED ON WHICH MODE WE ARE IN /* if( mode == PARTICLE_MODE_ATTRACT ){ ofPoint attractPt(ofGetMouseX(), ofGetMouseY()); frc = attractPt-pos; // we get the attraction force/vector by looking at the mouse pos relative to our pos frc.normalize(); //by normalizing we disregard how close the particle is to the attraction point vel *= drag; //apply drag vel += frc * 0.6; //apply force } else if( mode == PARTICLE_MODE_REPEL ){ ofPoint attractPt(ofGetMouseX(), ofGetMouseY()); frc = attractPt-pos; //let get the distance and only repel points close to the mouse float dist = frc.length(); frc.normalize(); vel *= drag; if( dist < 150 ){ vel += -frc * 0.6; //notice the frc is negative }else{ //if the particles are not close to us, lets add a little bit of random movement using noise. this is where uniqueVal comes in handy. frc.x = ofSignedNoise(uniqueVal, pos.y * 0.01, ofGetElapsedTimef()*0.2); frc.y = ofSignedNoise(uniqueVal, pos.x * 0.01, ofGetElapsedTimef()*0.2); vel += frc * 0.04; } } else if( mode == PARTICLE_MODE_NOISE ){ */ //lets simulate falling snow //the fake wind is meant to add a shift to the particles based on where in x they are //we add pos.y as an arg so to prevent obvious vertical banding around x values - try removing the pos.y * 0.006 to see the banding float fakeWindX = ofSignedNoise(pos.x * 0.003, pos.y * 0.006, ofGetElapsedTimef() * 0.6); frc.x = fakeWindX * 0.25 + ofSignedNoise(uniqueVal, pos.y * 0.04) * 0.6; frc.y = ofSignedNoise(uniqueVal, pos.x * 0.006, ofGetElapsedTimef()*0.2) * 0.09 + 0.18; vel *= drag; vel += frc * 0.4; //we do this so as to skip the bounds check for the bottom and make the particles go back to the top of the screen // if( pos.y + vel.y > ofGetHeight() ){ // pos.y -= ofGetHeight(); // } /* } else if( mode == PARTICLE_MODE_NEAREST_POINTS ){ if( attractPoints ){ //1 - find closest attractPoint ofPoint closestPt; int closest = -1; float closestDist = 9999999; for(unsigned int i = 0; i < attractPoints->size(); i++){ float lenSq = ( attractPoints->at(i)-pos ).lengthSquared(); if( lenSq < closestDist ){ closestDist = lenSq; closest = i; } } //2 - if we have a closest point - lets calcuate the force towards it if( closest != -1 ){ closestPt = attractPoints->at(closest); float dist = sqrt(closestDist); //in this case we don't normalize as we want to have the force proportional to distance frc = closestPt - pos; vel *= drag; //lets also limit our attraction to a certain distance and don't apply if 'f' key is pressed if( dist < 300 && dist > 40 && !ofGetKeyPressed('f') ){ vel += frc * 0.003; }else{ //if the particles are not close to us, lets add a little bit of random movement using noise. this is where uniqueVal comes in handy. frc.x = ofSignedNoise(uniqueVal, pos.y * 0.01, ofGetElapsedTimef()*0.2); frc.y = ofSignedNoise(uniqueVal, pos.x * 0.01, ofGetElapsedTimef()*0.2); vel += frc * 0.4; } } } } */ //2 - UPDATE OUR POSITION pos += vel; //3 - (optional) LIMIT THE PARTICLES TO STAY ON SCREEN //we could also pass in bounds to check - or alternatively do this at the ofApp level if( pos.x > ofGetWidth() ){ pos.x = ofGetWidth(); vel.x *= -1.0; }else if( pos.x < posIn2.x){ pos.x = posIn2.x; vel.x *= -1.0; } if( pos.y > ofGetHeight()+(radius*2) ){ //pos.y = ofGetHeight(); //vel.y *= -1.0; resetEnd(); } else if( pos.y < -(radius*2) ){ pos.y = -(radius*2); vel.y *= -1.0; } }
//--------------------------------- void GeneratedMesh::setup(ofxBulletWorldRigid &world, ofVec3f position, string url, ofVec3f ModelScale){ type = ShapeTypeAnimatedMesh; collisionTime = -120; ModelPath = url; this->position = position; this->world = &world; //rotation = btQuaternion(btVector3(0,1,0), ofDegToRad(-90)); //TODO to try with ofBtGetCylinderCollisionShape, for improve collision detection anisotropy = 4.; float fboDiv = 4.f; // ofSetMinMagFilters( GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR ); fbo.allocate( (float)ofGetWidth() / fboDiv, (float)ofGetWidth() / fboDiv, GL_RGB, 4 ); fbo.begin(); { ofClear(0, 0, 0, 255 ); ofSetColor( 11,90,121, 255); ofRect(0, 0, ofGetWidth(), ofGetHeight() ); ofSetColor(120, 140, 150, 255); int numIterations = 4; float inc = (float)fbo.getWidth() / ((float)numIterations); for( int i = 0; i < numIterations; i++ ) { float tx = (float)i*inc + inc; float ty = (float)i*inc + inc; ofSetColor(152,197,190, 255); ofSetLineWidth( 1.5 ); if( i % 2 == 0 ) ofSetLineWidth( 0.5 ); ofLine( tx, 0, tx, fbo.getHeight() ); ofLine( 0, ty, fbo.getWidth(), ty ); } } fbo.end(); ofSetLineWidth( 1 ); fbo.getTextureReference().bind(); glGenerateMipmap( fbo.getTextureReference().texData.textureTarget); ofSetMinMagFilters( GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR ); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy); // glSamplerParameterf( fbo.getTextureReference().texData.textureTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2 ); fbo.getTextureReference().unbind(); omesh = ofMesh::plane( 70, 70, 14, 14, OF_PRIMITIVE_TRIANGLES ); ofQuaternion rquat; rquat.makeRotate( 90, 1, 0, 0); ofSeedRandom(); float rseed = ofRandom(0, 10000); vector< ofVec3f >& verts = omesh.getVertices(); for( int i = 0; i < verts.size(); i++ ) { verts[i] = rquat * verts[i]; verts[i].y = ofSignedNoise( verts[i].x*0.02, verts[i].y*0.02 + verts[i].z*0.02, ofGetElapsedTimef() * 0.1 + rseed ) * 3; } vector< ofVec2f >& tcoords = omesh.getTexCoords(); for( int i = 0; i < tcoords.size(); i++ ) { tcoords[i].x *= 4.f; tcoords[i].y *= 4.f; } mesh = omesh; //ofEnableSeparateSpecularLight(); //save init values initScale = scale; // create ofxBullet shape //body.create(world.world, position, 0); // we set m=0 for kinematic body body.create( world.world, mesh, position, 0.f, ofVec3f(-10000, -10000, -10000), ofVec3f(10000,10000,10000) ); body.add(); body.enableKinematic(); body.setActivationState( DISABLE_DEACTIVATION ); bAnimate = true; body.add(); //body.setProperties(1., 0.); // .25 (more restituition means more energy) , .95 ( friction ) // to add force to the ball on collision set restitution to > 1 body.setProperties(3, .95); // restitution, friction body.setDamping( .25 ); //Set Rotation Objects setupRot(); body.activate(); setDefaultZ(); }
//-------------------------------------------------------------- void mpeClientTCP::threadedFunction() { out("Running!"); lastHeartbeatTime = ofGetElapsedTimef(); if(frameLock){ // let the server know that this client is ready to start send("S" + ofToString(id) + "," + clientName); } else{ //start a listener send("L"); } while(isThreadRunning()) { if(frameLock && simulationMode){ float now = ofGetElapsedTimef(); if(now - lastFrameTime > 1./simulatedFPS){ if(!useMainThread){ ofxMPEEventArgs e; e.message = ""; e.frame = frameCount; ofNotifyEvent(ofxMPEEvents.mpeFrame, e); } else { triggerFrame = true; } lastFrameTime = now; frameCount++; } ofSleepMillis(5); continue; } if (allConnected && ofGetElapsedTimef() - lastHeartbeatTime > 2.0) { //we lost connection... manually disconnect and join reset cycle if(tcpClient.close()){ ofLog(OF_LOG_ERROR, "mpeClientTCP -- server connection timed out. Closing and entering reconnect loop."); } else{ ofLog(OF_LOG_ERROR, "mpeClientTCP -- Error when closing TCP connection after timeout."); } } if(!tcpClient.isConnected()){ //we lost connection, start the retry loop and kill the thread lastConnectionAttempt = ofGetElapsedTimef(); ofAddListener(ofEvents.update, this, &mpeClientTCP::retryConnectionLoop); stopThread(true); if(useMainThread){ shouldReset = true; } else{ reset(); } if(DEBUG){ cout << "lost connection to server " << endl; } //break the loop because we'll need to restart return; } if (!useMainThread || (useMainThread && lock()) ) { string msg = tcpClient.receive(); if (msg.length() > 0 && lastmsg != msg) { read(msg); lastmsg = msg; } if(useMainThread){ unlock(); } } ofSleepMillis(5); } }
//-------------------------------------------------------------- void ofApp::playSoundbites(){ // if we've waited enough time... if (ofGetElapsedTimef() - lastSoundbiteTime >= timeBtwnSoundbites){ ofLogNotice("soundbites") << "triggering new sound..."; // get current layer visibility percentages vector<float> cLayersPctShown; for (int i=0; i<3; i++){ // don't use layer 3, only 0-2 cLayersPctShown.push_back(layers[i].pctShown); } // if this is the first time we've tracked, save now if (layersPctShown.size() != cLayersPctShown.size()){ layersPctShown = cLayersPctShown; } // compare to last soundbite's percentages // whichever layer increased most, trigger that one int bestLayer = 0; float largestDiff = 0.0; for (int i=0; i<cLayersPctShown.size(); i++){ float diff = cLayersPctShown[i] - layersPctShown[i]; if (diff >= largestDiff) { largestDiff = diff; bestLayer = i; // save layer with largest increase } } ofLogNotice("soundbites") << "chose layer " << bestLayer << " with % change: " << largestDiff; // if largest increase was less than 5% // weighted random choice of soundbite track if (largestDiff <= 0.01) { // random choice of layer with weighted probability // float rnd = ofRandom(1); if (rnd==1) rnd = 0.9999; // for (int i=0; i<cLayersPctShown.size(); i++){ // if (cLayersPctShown[i] > rnd){ // bestLayer = i; // } else { // rnd -= cLayersPctShown[i]; // } // } int rnd = ofRandom(0,3); if (rnd==3) rnd = 2; bestLayer = rnd; ofLogNotice("soundbites") << "randomly chose layer " << bestLayer << " with rnd of " << rnd; } layers[bestLayer].triggerSound(); // we play the sound layersPctShown = cLayersPctShown; // save layers % for next time lastSoundbiteTime = ofGetElapsedTimef(); // save time for wait calc timeBtwnSoundbites = ofRandom(5, 15); // new wait time for next round ofLogNotice("soundbites") << "played sound from layer " << bestLayer << ", will now wait " << timeBtwnSoundbites << " seconds"; } }
//assigns IDs to each blob in the contourFinder void BlobTracker::track(ContourFinder* newBlobs) { /********************************************************************* //Object tracking *********************************************************************/ for(std::map<int,Blob>::iterator tracked=trackedObjects.begin();tracked != trackedObjects.end(); ++tracked) {//iterate through the tracked blobs and check if any of these are present in current blob list, else delete it (mark id = -1) int id= tracked->second.id; bool isFound=false; // The variable to check if the blob is in the new blobs list or not for(std::vector<Blob>::iterator blob = newBlobs->objects.begin();blob!=newBlobs->objects.end();++blob) { if(blob->id == id) { isFound=true; break; } } if(!isFound) // current tracked blob was not found in the new blob list { trackedObjects[id].id = -1; } } //handle the object tracking if present for (int i = 0; i < newBlobs->nObjects; i++) { int ID = newBlobs->objects[i].id; int now = ofGetElapsedTimeMillis(); if(trackedObjects[ID].id == -1) //If this blob has appeared in the current frame { calibratedObjects[i]=newBlobs->objects[i]; calibratedObjects[i].D.x=0; calibratedObjects[i].D.y=0; calibratedObjects[i].maccel=0; //Camera to Screen Position Conversion calibrate->cameraToScreenPosition(calibratedObjects[i].centroid.x,calibratedObjects[i].centroid.y); calibrate->transformDimension(calibratedObjects[i].angleBoundingRect.width,calibratedObjects[i].angleBoundingRect.height); } else //Do all the calculations { float xOld = trackedObjects[ID].centroid.x; float yOld = trackedObjects[ID].centroid.y; float xNew = newBlobs->objects[i].centroid.x; float yNew = newBlobs->objects[i].centroid.y; //converting xNew and yNew to calibrated ones calibrate->cameraToScreenPosition(xNew,yNew); double dx = xNew-xOld; double dy = yNew-yOld; calibratedObjects[i] = newBlobs->objects[i]; calibratedObjects[i].D.x = dx; calibratedObjects[i].D.y = dy; calibratedObjects[i].maccel = sqrtf((dx*dx+dy*dy)/(now - trackedObjects[ID].lastTimeTimeWasChecked)); calibrate->cameraToScreenPosition(calibratedObjects[i].centroid.x,calibratedObjects[i].centroid.y); calibrate->transformDimension(calibratedObjects[i].angleBoundingRect.width,calibratedObjects[i].angleBoundingRect.height); } trackedObjects[ID] = newBlobs->objects[i]; trackedObjects[ID].lastTimeTimeWasChecked = now; trackedObjects[ID].centroid.x = calibratedObjects[i].centroid.x; trackedObjects[ID].centroid.y = calibratedObjects[i].centroid.y; } /**************************************************************************** //Finger tracking ****************************************************************************/ //initialize ID's of all blobs for(int i=0; i<newBlobs->nBlobs; i++) newBlobs->blobs[i].id=-1; // STEP 1: Blob matching // //go through all tracked blobs to compute nearest new point for(int i = 0; i < trackedBlobs.size(); i++) { /****************************************************************** * *****************TRACKING FUNCTION TO BE USED******************* * Replace 'trackKnn(...)' with any function that will take the * current track and find the corresponding track in the newBlobs * 'winner' should contain the index of the found blob or '-1' if * there was no corresponding blob *****************************************************************/ int winner = trackKnn(newBlobs, &(trackedBlobs[i]), 3, 0); if(winner == -1) //track has died, mark it for deletion { //SEND BLOB OFF EVENT TouchEvents.messenger = trackedBlobs[i]; if(isCalibrating) { TouchEvents.RAWmessenger = trackedBlobs[i]; TouchEvents.notifyRAWTouchUp(NULL); } calibrate->transformDimension(TouchEvents.messenger.boundingRect.width, TouchEvents.messenger.boundingRect.height); calibrate->cameraToScreenPosition(TouchEvents.messenger.centroid.x, TouchEvents.messenger.centroid.y); //erase calibrated blob from map calibratedBlobs.erase(TouchEvents.messenger.id); TouchEvents.notifyTouchUp(NULL); //mark the blob for deletion trackedBlobs[i].id = -1; } else //still alive, have to update { //if winning new blob was labeled winner by another track\ //then compare with this track to see which is closer if(newBlobs->blobs[winner].id!=-1) { //find the currently assigned blob int j; //j will be the index of it for(j=0; j<trackedBlobs.size(); j++) { if(trackedBlobs[j].id==newBlobs->blobs[winner].id) break; } if(j==trackedBlobs.size())//got to end without finding it { newBlobs->blobs[winner].id = trackedBlobs[i].id; newBlobs->blobs[winner].age = trackedBlobs[i].age; newBlobs->blobs[winner].sitting = trackedBlobs[i].sitting; newBlobs->blobs[winner].downTime = trackedBlobs[i].downTime; newBlobs->blobs[winner].color = trackedBlobs[i].color; newBlobs->blobs[winner].lastTimeTimeWasChecked = trackedBlobs[i].lastTimeTimeWasChecked; trackedBlobs[i] = newBlobs->blobs[winner]; } else //found it, compare with current blob { double x = newBlobs->blobs[winner].centroid.x; double y = newBlobs->blobs[winner].centroid.y; double xOld = trackedBlobs[j].centroid.x; double yOld = trackedBlobs[j].centroid.y; double xNew = trackedBlobs[i].centroid.x; double yNew = trackedBlobs[i].centroid.y; double distOld = (x-xOld)*(x-xOld)+(y-yOld)*(y-yOld); double distNew = (x-xNew)*(x-xNew)+(y-yNew)*(y-yNew); //if this track is closer, update the ID of the blob //otherwise delete this track.. it's dead if(distNew<distOld) //update { newBlobs->blobs[winner].id = trackedBlobs[i].id; newBlobs->blobs[winner].age = trackedBlobs[i].age; newBlobs->blobs[winner].sitting = trackedBlobs[i].sitting; newBlobs->blobs[winner].downTime = trackedBlobs[i].downTime; newBlobs->blobs[winner].color = trackedBlobs[i].color; newBlobs->blobs[winner].lastTimeTimeWasChecked = trackedBlobs[i].lastTimeTimeWasChecked; //TODO-------------------------------------------------------------------------- //now the old winning blob has lost the win. //I should also probably go through all the newBlobs //at the end of this loop and if there are ones without //any winning matches, check if they are close to this //one. Right now I'm not doing that to prevent a //recursive mess. It'll just be a new track. //SEND BLOB OFF EVENT TouchEvents.messenger = trackedBlobs[j]; if(isCalibrating) { TouchEvents.RAWmessenger = trackedBlobs[j]; TouchEvents.notifyRAWTouchUp(NULL); } calibrate->transformDimension(TouchEvents.messenger.boundingRect.width, TouchEvents.messenger.boundingRect.height); calibrate->cameraToScreenPosition(TouchEvents.messenger.centroid.x, TouchEvents.messenger.centroid.y); //erase calibrated blob from map calibratedBlobs.erase(TouchEvents.messenger.id); TouchEvents.notifyTouchUp(NULL); //mark the blob for deletion trackedBlobs[j].id = -1; //------------------------------------------------------------------------------ } else //delete { //SEND BLOB OFF EVENT TouchEvents.messenger = trackedBlobs[i]; if(isCalibrating) { TouchEvents.RAWmessenger = trackedBlobs[i]; TouchEvents.notifyRAWTouchUp(NULL); } calibrate->transformDimension(TouchEvents.messenger.boundingRect.width, TouchEvents.messenger.boundingRect.height); calibrate->cameraToScreenPosition(TouchEvents.messenger.centroid.x, TouchEvents.messenger.centroid.y); //erase calibrated blob from map calibratedBlobs.erase(TouchEvents.messenger.id); TouchEvents.notifyTouchUp(NULL); //mark the blob for deletion trackedBlobs[i].id = -1; } } } else //no conflicts, so simply update { newBlobs->blobs[winner].id = trackedBlobs[i].id; newBlobs->blobs[winner].age = trackedBlobs[i].age; newBlobs->blobs[winner].sitting = trackedBlobs[i].sitting; newBlobs->blobs[winner].downTime = trackedBlobs[i].downTime; newBlobs->blobs[winner].color = trackedBlobs[i].color; newBlobs->blobs[winner].lastTimeTimeWasChecked = trackedBlobs[i].lastTimeTimeWasChecked; } } } // AlexP // save the current time since we will be using it a lot int now = ofGetElapsedTimeMillis(); // STEP 2: Blob update // //--Update All Current Tracks //remove every track labeled as dead (ID='-1') //find every track that's alive and copy it's data from newBlobs for(int i = 0; i < trackedBlobs.size(); i++) { if(trackedBlobs[i].id == -1) //dead { //erase track trackedBlobs.erase(trackedBlobs.begin()+i, trackedBlobs.begin()+i+1); i--; //decrement one since we removed an element } else //living, so update it's data { for(int j = 0; j < newBlobs->nBlobs; j++) { if(trackedBlobs[i].id == newBlobs->blobs[j].id) { //update track ofPoint tempLastCentroid = trackedBlobs[i].centroid; // assign the new centroid to the old trackedBlobs[i] = newBlobs->blobs[j]; trackedBlobs[i].lastCentroid = tempLastCentroid; ofPoint tD; //get the Differences in position tD.set(trackedBlobs[i].centroid.x - trackedBlobs[i].lastCentroid.x, trackedBlobs[i].centroid.y - trackedBlobs[i].lastCentroid.y); //calculate the acceleration float posDelta = sqrtf((tD.x*tD.x)+(tD.y*tD.y)); // AlexP // now, filter the blob position based on MOVEMENT_FILTERING value // the MOVEMENT_FILTERING ranges [0,15] so we will have that many filtering steps // Here we have a weighted low-pass filter // adaptively adjust the blob position filtering strength based on blob movement // http://www.wolframalpha.com/input/?i=plot+1/exp(x/15)+and+1/exp(x/10)+and+1/exp(x/5)+from+0+to+100 float a = 1.0f - 1.0f / expf(posDelta / (1.0f + (float)MOVEMENT_FILTERING*10)); trackedBlobs[i].centroid.x = a * trackedBlobs[i].centroid.x + (1-a) * trackedBlobs[i].lastCentroid.x; trackedBlobs[i].centroid.y = a * trackedBlobs[i].centroid.y + (1-a) * trackedBlobs[i].lastCentroid.y; //get the Differences in position trackedBlobs[i].D.set(trackedBlobs[i].centroid.x - trackedBlobs[i].lastCentroid.x, trackedBlobs[i].centroid.y - trackedBlobs[i].lastCentroid.y); //if( abs((int)trackedBlobs[i].D.x) > 1 || abs((int)trackedBlobs[i].D.y) > 1) { // printf("\nUNUSUAL BLOB @ %f\n-----------------------\ntrackedBlobs[%i]\nD = (%f, %f)\nXY= (%f, %f)\nlastTimeTimeWasChecked = %f\nsitting = %f\n", // ofGetElapsedTimeMillis(), // i, // trackedBlobs[i].D.x, trackedBlobs[i].D.y, // trackedBlobs[i].centroid.x, trackedBlobs[i].centroid.y, // trackedBlobs[i].lastTimeTimeWasChecked, // trackedBlobs[i].downTime, // trackedBlobs[i].sitting // ); // } //calculate the acceleration again tD = trackedBlobs[i].D; trackedBlobs[i].maccel = sqrtf((tD.x* tD.x)+(tD.y*tD.y)) / (now - trackedBlobs[i].lastTimeTimeWasChecked); //calculate the age trackedBlobs[i].age = ofGetElapsedTimef() - trackedBlobs[i].downTime; //set sitting (held length) if(trackedBlobs[i].maccel < 7) { //1 more frame of sitting if(trackedBlobs[i].sitting != -1) trackedBlobs[i].sitting = ofGetElapsedTimef() - trackedBlobs[i].downTime; } else trackedBlobs[i].sitting = -1; //printf("time: %f\n", ofGetElapsedTimeMillis()); //printf("%i age: %f, downTimed at: %f\n", i, trackedBlobs[i].age, trackedBlobs[i].downTime); //if blob has been 'holding/sitting' for 1 second send a held event if(trackedBlobs[i].sitting > 1.0f) { //SEND BLOB HELD EVENT TouchEvents.messenger = trackedBlobs[i]; if(isCalibrating) { TouchEvents.RAWmessenger = trackedBlobs[i]; TouchEvents.notifyRAWTouchHeld(NULL); } //calibrated values calibrate->transformDimension(TouchEvents.messenger.boundingRect.width, TouchEvents.messenger.boundingRect.height); calibrate->cameraToScreenPosition(TouchEvents.messenger.centroid.x, TouchEvents.messenger.centroid.y); calibrate->cameraToScreenPosition(TouchEvents.messenger.lastCentroid.x, TouchEvents.messenger.lastCentroid.y); //Calibrated dx/dy TouchEvents.messenger.D.set(trackedBlobs[i].centroid.x - trackedBlobs[i].lastCentroid.x, trackedBlobs[i].centroid.y - trackedBlobs[i].lastCentroid.y); //calibrated acceleration ofPoint tD = TouchEvents.messenger.D; TouchEvents.messenger.maccel = sqrtf((tD.x*tD.x)+(tD.y*tD.y)) / (now - TouchEvents.messenger.lastTimeTimeWasChecked); TouchEvents.messenger.lastTimeTimeWasChecked = now; //add to calibration map calibratedBlobs[TouchEvents.messenger.id] = TouchEvents.messenger; //held event only happens once so set to -1 trackedBlobs[i].sitting = -1; TouchEvents.notifyTouchHeld(NULL); } else { //printf("(%f, %f) -> (%f, %f) \n", trackedBlobs[i].lastCentroid.x, trackedBlobs[i].lastCentroid.y, trackedBlobs[i].centroid.x, trackedBlobs[i].centroid.y); //SEND BLOB MOVED EVENT TouchEvents.messenger = trackedBlobs[i]; if(isCalibrating) { TouchEvents.RAWmessenger = trackedBlobs[i]; TouchEvents.notifyRAWTouchMoved(NULL); } //calibrated values calibrate->transformDimension(TouchEvents.messenger.boundingRect.width, TouchEvents.messenger.boundingRect.height); calibrate->cameraToScreenPosition(TouchEvents.messenger.centroid.x, TouchEvents.messenger.centroid.y); calibrate->cameraToScreenPosition(TouchEvents.messenger.lastCentroid.x, TouchEvents.messenger.lastCentroid.y); //Calibrated dx/dy TouchEvents.messenger.D.set(trackedBlobs[i].centroid.x - trackedBlobs[i].lastCentroid.x, trackedBlobs[i].centroid.y - trackedBlobs[i].lastCentroid.y); //printf("d(%0.4f, %0.4f)\n", TouchEvents.messenger.D.x, TouchEvents.messenger.D.y); //calibrated acceleration ofPoint tD = TouchEvents.messenger.D; TouchEvents.messenger.maccel = sqrtf((tD.x*tD.x)+(tD.y*tD.y)) / (now - TouchEvents.messenger.lastTimeTimeWasChecked); TouchEvents.messenger.lastTimeTimeWasChecked = now; //add to calibration map calibratedBlobs[TouchEvents.messenger.id] = TouchEvents.messenger; TouchEvents.notifyTouchMoved(NULL); } // AlexP // The last lastTimeTimeWasChecked is updated at the end after all acceleration values are calculated trackedBlobs[i].lastTimeTimeWasChecked = now; } } } } // STEP 3: add tracked blobs to TouchEvents //--Add New Living Tracks //now every new blob should be either labeled with a tracked ID or\ //have ID of -1... if the ID is -1... we need to make a new track for(int i = 0; i < newBlobs->nBlobs; i++) { if(newBlobs->blobs[i].id==-1) { //add new track newBlobs->blobs[i].id=IDCounter++; newBlobs->blobs[i].downTime = ofGetElapsedTimef(); //newBlobs->blobs[i].lastTimeTimeWasChecked = ofGetElapsedTimeMillis(); //random color for blob. Could be useful? newBlobs->blobs[i].color.r = ofRandom(0, 255); newBlobs->blobs[i].color.g = ofRandom(0, 255); newBlobs->blobs[i].color.b = ofRandom(0, 255); //Add to blob messenger TouchEvents.messenger = newBlobs->blobs[i]; if(isCalibrating) { TouchEvents.RAWmessenger = newBlobs->blobs[i]; TouchEvents.notifyRAWTouchDown(NULL); } calibrate->transformDimension(TouchEvents.messenger.boundingRect.width, TouchEvents.messenger.boundingRect.height); calibrate->cameraToScreenPosition(TouchEvents.messenger.centroid.x, TouchEvents.messenger.centroid.y); //add to calibrated blob map calibratedBlobs[TouchEvents.messenger.id] = TouchEvents.messenger; //Send Event TouchEvents.notifyTouchDown(NULL); trackedBlobs.push_back(newBlobs->blobs[i]); } } }