rt300@0: #include "testApp.h" rt300@0: rt300@7: /* rt300@7: TODO list rt300@7: rt300@7: video out !!!!! rt300@7: rt300@7: ios buttons etc rt300@7: circular line string with invisible "identify" between two points rt300@7: rt300@7: symmetry touch mode rt300@7: rt300@7: new mesh popup menu rt300@7: type x,y rings spokes rt300@7: rt300@14: update to ofx0.8 rt300@7: rt300@7: save presets: rt300@7: create mesh methods: save to json, construct from json rt300@7: rt300@7: all the stuff in control (and off screen OSC ones) rt300@7: lump positions, constraints rt300@7: the scan path rt300@7: the touch mode rt300@7: the midi hit mode (rewrite this whole thing!) rt300@7: rt300@7: preset recall list rt300@7: rt300@7: modulation points: rt300@7: make filter rt300@7: new touch mode, drop modulation point rt300@7: pop up list of destinations (or drag line?) rt300@7: rt300@7: rt300@7: rt300@7: new super knobs rt300@7: new supermenus rt300@7: rt300@7: algorithmic scan path rt300@7: auto- join up scan path...? rt300@7: rt300@7: floating scan path, with interpolation rt300@7: rt300@7: band limited touch points (invisible springs connecting to mesh?) rt300@8: rt300@15: iphone rt300@7: */ rt300@0: extern GlobalForces globalForces; rt300@0: extern GlobalUI globalUI; rt300@3: extern ScanPath scanPath; rt300@10: extern PresetAlertViewController *presetAlertViewController; rt300@0: //-------------------------------------------------------------- rt300@8: void testApp::setup(){ rt300@13: rt300@0: theMesh = NULL; rt300@8: rt300@0: ofxAccelerometer.setup(); rt300@0: rt300@14: try{ rt300@14: receiver.setup( INPORT ); rt300@14: OscOK = true; rt300@14: } rt300@14: catch (std::runtime_error e){ rt300@14: cout << "OSC couldn't connect. Exception: " << e.what() << '\n'; rt300@14: OscOK = false; rt300@14: } rt300@0: rt300@14: try{ rt300@14: sender.setup( HOST, OUTPORT ); rt300@14: OscOK = true; rt300@14: } rt300@14: catch (std::runtime_error e){ rt300@14: cout << "OSC couldn't connect. Exception: " << e.what() << '\n'; rt300@14: OscOK = false; rt300@14: } rt300@14: rt300@0: ofBackground(0, 0, 0); rt300@0: ofSetFullscreen(true); rt300@0: ofSetFrameRate(60); rt300@0: rt300@0: timeStep = 1/ofGetFrameRate(); rt300@0: rt300@0: ofEnableSmoothing(); rt300@0: ofEnableAlphaBlending(); rt300@0: rt300@13: rt300@0: rt300@0: pitch = 60.0; rt300@0: phasorIncr = pitch/SAMPLE_RATE; rt300@0: globalForces.gravityAmt = 0.0; rt300@0: globalForces.avFilterAmt = 0.01; rt300@1: rt300@12: initialiseMidi(); rt300@0: // rt300@0: ofSoundStreamSetup(2,0,this, SAMPLE_RATE,256, 2); rt300@5: rt300@5: paused = false; rt300@5: audioOn = false; rt300@5: drawingOn = true; rt300@0: rt300@1: audioAccessFlag = false; rt300@1: meshConstructionFlag = false; rt300@13: rt300@14: ofxiPhoneSetOrientation( OF_ORIENTATION_90_RIGHT ); rt300@0: setupGui(); rt300@0: rt300@0: rt300@0: setupMesh(); rt300@3: scanPath.init(); rt300@3: rt300@3: globalUI.touchMode = globalUI.GRAB; rt300@3: scanPath.scanMode = scanPath.DISPLACEMENT; rt300@15: globalUI.borderSize = ofGetWidth()/8; rt300@5: ofSoundStreamStart(); rt300@3: rt300@3: paused = false; rt300@3: audioOn = true; rt300@8: rt300@15: //ofxiPhoneExternalDisplay::mirrorOn(); rt300@8: rt300@15: cout << "Width: " << ofGetWidth() << endl; rt300@15: cout << "Height: " << ofGetHeight() << endl; rt300@8: rt300@15: // stupid hack for control vis rt300@15: hideControls(); rt300@15: showControls(); rt300@13: //[ofxiPhoneGetGLView() updateDimensions]; rt300@8: rt300@8: rt300@0: } rt300@12: rt300@12: //-------------------------------------------------------------------------- rt300@12: void testApp::initialiseMidi(){ rt300@12: rt300@12: ///////////////////////// rt300@12: // MIDI rt300@12: rt300@12: midiChannel = 7; rt300@12: rt300@12: // enables the network midi session between iOS and Mac OSX on a rt300@12: // local wifi network rt300@12: // rt300@12: // in ofxMidi: open the input/outport network ports named "Session 1" rt300@12: // rt300@12: // on OSX: use the Audio MIDI Setup Utility to connect to the iOS device rt300@12: // rt300@12: ofxMidi::enableNetworking(); rt300@12: rt300@12: // list the number of available input & output ports rt300@12: ofxMidiIn::listPorts(); rt300@12: ofxMidiOut::listPorts(); rt300@12: rt300@12: // create and open input ports rt300@12: for(int i = 0; i < ofxMidiIn::getNumPorts(); ++i) { rt300@12: rt300@12: // new object rt300@12: inputs.push_back(new ofxMidiIn); rt300@12: rt300@12: // set this class to receive incoming midi events rt300@12: inputs[i]->addListener(this); rt300@12: rt300@12: // open input port via port number rt300@12: inputs[i]->openPort(i); rt300@12: } rt300@12: rt300@12: // create and open output ports rt300@12: for(int i = 0; i < ofxMidiOut::getNumPorts(); ++i) { rt300@12: rt300@12: // new object rt300@12: outputs.push_back(new ofxMidiOut); rt300@12: rt300@12: // open input port via port number rt300@12: outputs[i]->openPort(i); rt300@12: } rt300@12: rt300@12: // set this class to receieve midi device (dis)connection events rt300@12: ofxMidi::setConnectionListener(this); rt300@12: rt300@12: // END MIDI rt300@12: rt300@12: } rt300@12: rt300@9: //-------------------------------------------------------------- rt300@8: Json::Value testApp::convertToJsonForSaving(){ rt300@8: Json::Value root; rt300@8: rt300@8: root["pitch"] = pitch; // rt300@9: rt300@8: rt300@9: root["globalForces"] = globalForces.convertToJsonForSaving(); rt300@8: rt300@8: root["mesh"] = theMesh->convertToJsonForSaving(); rt300@8: rt300@8: return root; rt300@8: } rt300@10: // rt300@13: //-------------------------------------------------------------- rt300@10: void testApp::showPresetNameDialog(){ rt300@10: if(!presetAlertViewController.alertShowing){ // this is to stop wierd infinite loop in ios5 (simulator) rt300@10: [presetAlertViewController showPresetNamePrompt]; rt300@10: rt300@10: } rt300@10: rt300@10: } rt300@9: //-------------------------------------------------------------- rt300@12: void testApp::savePreset(const string name = "default" ){ rt300@12: static int presetNumber; rt300@12: rt300@12: presetNumber++; rt300@9: Json::Value jpreset = convertToJsonForSaving(); rt300@8: //save json to file rt300@9: string fname = ofxiPhoneGetDocumentsDirectory() + "presetFile"; rt300@8: rt300@9: // write to file rt300@9: rt300@9: ofFile logFile(fname,ofFile::WriteOnly); rt300@9: logFile << jpreset; rt300@9: logFile.close(); rt300@8: } rt300@9: //-------------------------------------------------------------- rt300@9: Json::Value testApp::loadPresetFile(){ rt300@9: Json::Value jpreset; rt300@9: //save json to file rt300@9: string fname = ofxiPhoneGetDocumentsDirectory() + "presetFile"; rt300@9: rt300@9: Json::Value root; rt300@9: Json::Reader reader; rt300@9: rt300@9: ///////////// rt300@9: // read file rt300@9: rt300@9: ifstream theFile(fname.c_str()); rt300@9: stringstream fileText; rt300@9: string line; rt300@9: if(!theFile){ rt300@9: cout<<"No preset file found\n"; rt300@9: return root; rt300@9: }else{ rt300@9: while(theFile){ rt300@9: theFile >> line; rt300@9: // cout << line; // lots!!!! rt300@9: fileText << line; rt300@9: } rt300@9: theFile.close(); rt300@9: } rt300@9: rt300@9: cout << "size of preset JSON string:" << fileText.str().length() << "BYTES \n"; rt300@9: rt300@9: bool parsingSuccessful = reader.parse( fileText.str(), root ); rt300@9: rt300@9: if ( !parsingSuccessful ) rt300@9: { rt300@9: // report to the user the failure and their locations in the document. rt300@9: std::cout << "Failed to parse preset JSON: \n" << reader.getFormattedErrorMessages(); rt300@9: return root; // will be null rt300@9: } rt300@9: rt300@9: return root; rt300@9: } rt300@9: //-------------------------------------------------------------- rt300@9: void testApp::constructPresetFromJson(Json::Value& presetJson){ rt300@8: rt300@8: // construct mesh with right type and size rt300@8: // impose saved constraints rt300@8: // make saved scanpath rt300@8: // recall global settings rt300@8: pitch = presetJson["pitch"].asDouble(); rt300@9: rt300@9: theMesh = new Mesh(presetJson["mesh"]); rt300@10: rt300@10: globalForces.setFromJson(presetJson["globalForces"]); rt300@9: } rt300@13: //-------------------------------------------------------------- rt300@9: void testApp::loadPreset(){ rt300@9: if(audioAccessFlag) return; // or rather wait ! rt300@9: meshConstructionFlag = TRUE; rt300@9: rt300@9: deleteMesh(); rt300@9: rt300@9: Json::Value jp = loadPresetFile(); rt300@9: rt300@9: constructPresetFromJson(jp); rt300@9: rt300@9: // check these stupid tyhings rt300@9: numTouches = 0; rt300@9: meshConstructionFlag = FALSE; rt300@9: paused = false; rt300@9: audioOn = true; rt300@9: drawingOn = true; rt300@9: ofSoundStreamStart(); rt300@9: rt300@9: cout << "PRESET WAS LOADED\n"; rt300@9: rt300@8: } rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: // App running stuff rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: void testApp::exit(){ rt300@0: ofSoundStreamClose(); rt300@0: rt300@0: // save everything... rt300@5: rt300@0: delete guiL; rt300@0: rt300@0: if(theMesh != NULL){ rt300@3: scanPath.clear(); rt300@0: delete theMesh; rt300@0: } rt300@0: rt300@0: } rt300@0: rt300@0: //-------------------------------------------------------------- rt300@0: void testApp::update(){ rt300@0: rt300@0: if(!paused){ rt300@0: if (theMesh != NULL){ rt300@0: theMesh->update(); rt300@5: rt300@0: } rt300@5: rt300@0: } rt300@0: handleMessages(); // !?!?? rt300@15: // if(ofxiPhoneExternalDisplay::isExternalScreenConnected()){ rt300@15: // if(!ofxiPhoneExternalDisplay::isMirroring()){ rt300@15: // ofxiPhoneExternalDisplay::mirrorOn(); rt300@15: // //printf("turned on Mirroring!\n"); rt300@15: // } rt300@15: // } rt300@8: rt300@0: } rt300@0: rt300@0: //-------------------------------------------------------------- rt300@0: void testApp::draw(){ rt300@0: if(drawingOn){ rt300@0: if(theMesh != NULL) rt300@0: theMesh->draw(); rt300@0: } rt300@8: if(controlsShowing){ rt300@8: drawSidePanels(); rt300@8: }else{ rt300@15: if (!controlsShowing) scanPath.draw(); // uncomment if you want to see the output waveform rt300@8: } rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: // background for UI rt300@0: void testApp::drawSidePanels(){ rt300@0: ofSetColor(123, 123, 123); rt300@15: ofRect(0, 0, globalUI.borderSize, ofGetHeight()); rt300@15: ofRect(ofGetWidth()-globalUI.borderSize, 0, globalUI.borderSize, ofGetHeight()); rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: void testApp::drawMessages(){ rt300@0: for ( int i=0; isetSpringConstant(0.8); rt300@5: theMesh->setMass(1); rt300@5: theMesh->setFriction(0.99991); rt300@5: rt300@5: numTouches = 0; rt300@5: meshConstructionFlag = FALSE; rt300@5: paused = false; rt300@5: audioOn = true; rt300@5: drawingOn = true; rt300@5: ofSoundStreamStart(); rt300@5: cout << "MESH SETUP\n"; rt300@5: } rt300@5: //-------------------------------------------------------------- rt300@0: void testApp::deleteMesh(){ rt300@0: // TODO - OTHER THREADS FUCK THIS UP rt300@1: if(audioAccessFlag) return; // or rather wait ! rt300@0: //stop everything rt300@5: rt300@5: scanPath.clear(); rt300@0: ofSoundStreamStop(); rt300@0: rt300@0: paused = true; rt300@0: audioOn = false; rt300@0: drawingOn = false; rt300@0: rt300@3: scanPath.clear(); rt300@0: // trash it rt300@0: delete theMesh; rt300@0: theMesh = NULL; rt300@0: rt300@0: cout << "MESH DELETED\n"; rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: void testApp::regenerateMesh(string meshType, int dim1, int dim2){ rt300@5: rt300@5: // more customisable version of setupMesh() rt300@5: if(audioAccessFlag) return; rt300@1: rt300@0: if (theMesh != NULL) return; rt300@0: rt300@0: if (meshType == "LineMesh"){ rt300@0: rt300@0: theMesh = new LineMesh(dim1); rt300@0: }else if (meshType == "DropletMesh"){ rt300@0: rt300@0: theMesh = new DropletMesh(dim1); rt300@0: }else if (meshType == "SpiderMesh"){ rt300@0: rt300@0: theMesh = new SpiderMesh(dim1,dim2); rt300@0: }else if (meshType == "SpiderCrossMesh"){ rt300@0: rt300@0: theMesh = new SpiderCrossMesh(dim1,dim2); rt300@0: }else if (meshType == "SquareCrossMesh"){ rt300@0: rt300@0: theMesh = new SquareCrossMesh(dim1,dim2); rt300@0: }else if (meshType == "TriangleMesh"){ rt300@0: rt300@0: theMesh = new TriangleMesh(dim1,dim2); rt300@0: }else if (meshType == "GroundedLineMesh"){ rt300@0: rt300@0: theMesh = new GroundedLineMesh(dim1); rt300@0: }else{ rt300@0: cout << "OSC message error: unrecognised mesh type" << endl; rt300@0: return; rt300@0: } rt300@0: ofSoundStreamStart(); rt300@0: drawingOn = true; rt300@0: paused = false; rt300@0: audioOn = true; rt300@0: cout << "MESH REGENERATED\n"; rt300@0: rt300@0: } rt300@0: rt300@0: rt300@0: rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: //------------------------KEYS (OSX)---------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: // all this is now osc messages rt300@0: void testApp::keyPressed(int key){ rt300@0: rt300@0: if (key == 'p'){ rt300@0: rt300@0: paused = !paused; rt300@0: } rt300@0: if (key == 's'){ rt300@0: theMesh->toggleSyrup(true); rt300@0: } rt300@0: if (key == 'f'){ rt300@0: theMesh->toggleSpringForces(false); rt300@0: } rt300@0: if (key == '='){ rt300@0: theMesh->increasePropagationSpeed(); rt300@0: } rt300@0: if (key == '-'){ rt300@0: theMesh->decreasePropagationSpeed(); rt300@0: } rt300@0: if (key == 'a'){ rt300@0: if(audioOn){ rt300@0: audioOn = false; rt300@0: }else{ rt300@0: audioOn = true; rt300@0: } rt300@0: } rt300@0: if (key == 'r'){ rt300@0: theMesh->resetPositions(); rt300@0: theMesh->resetVelocities(); rt300@0: rt300@0: } rt300@0: if (key == 'e'){ rt300@0: theMesh->constrain(.0,.0,Mesh::CONSTRAIN_EDGES); rt300@0: } rt300@0: if (key == 'c'){ rt300@0: theMesh->constrain(.0,.0,Mesh::CONSTRAIN_CORNERS); rt300@0: } rt300@0: if (key == 'u'){ rt300@0: theMesh->unconstrain(); rt300@0: } rt300@0: if (key == 'l'){ rt300@0: theMesh->setRestLength(); rt300@0: } rt300@0: if (key == '0'){ rt300@0: theMesh->zeroRestLength(); rt300@0: } rt300@0: if (key == 'd'){ rt300@0: drawingOn = !drawingOn; rt300@0: } rt300@0: } rt300@0: rt300@0: //--------------------------------------------------------------- rt300@0: rt300@0: void testApp::keyReleased(int key){ rt300@0: if (key == 's'){ rt300@0: theMesh->toggleSyrup(false); rt300@0: } rt300@0: if (key == 'f'){ rt300@0: theMesh->toggleSpringForces(true); rt300@0: } rt300@0: } rt300@0: rt300@0: rt300@0: rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: //------------------------TOUCH--------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: rt300@0: rt300@0: rt300@0: rt300@0: void testApp::touchDown(ofTouchEventArgs &touch){ rt300@0: if(theMesh == NULL) return; rt300@0: rt300@0: double dax, day; rt300@0: // touchDown rt300@0: //cout << "touchDown ID: " << touch.id << endl; rt300@0: if(globalUI.handleTouchDown(touch.x, touch.y)) return; rt300@0: rt300@0: rt300@0: addTouch(); rt300@0: rt300@0: rt300@0: rt300@0: dax = (double(touch.x) - globalUI.borderSize)/ofGetHeight(); rt300@0: day = double(touch.y)/ofGetHeight(); rt300@0: rt300@0: switch (globalUI.touchMode){ rt300@0: case globalUI.GRAB: rt300@0: theMesh->grab(dax,day,touch.id); rt300@0: break; rt300@0: case globalUI.INSCRIBE_PATH: rt300@0: // start a new path, with touch id? ie:polyphonic paths!??! rt300@0: break; rt300@0: case globalUI.FORCE_FIELD: rt300@0: globalForces.createForceTouchPoint(dax,day, touch.id); rt300@0: break; rt300@0: case globalUI.SPATIAL_HARMONIC: rt300@0: // work out rt300@0: theMesh->spatialHarmonic(numTouches, 0); rt300@0: break; rt300@0: case globalUI.CONSTRAIN: rt300@0: theMesh->constrain(dax,day,Mesh::CONSTRAIN_GRAB_REGION); rt300@0: break; rt300@0: case globalUI.UNCONSTRAIN: rt300@0: theMesh->unconstrain(dax,day,Mesh::CONSTRAIN_GRAB_REGION); rt300@0: break; rt300@0: case globalUI.VIBRATE: rt300@0: break; rt300@0: default: rt300@0: rt300@0: break; rt300@0: } rt300@0: rt300@0: rt300@0: } rt300@0: rt300@0: //-------------------------------------------------------------- rt300@0: void testApp::touchMoved(ofTouchEventArgs &touch){ rt300@0: if(theMesh == NULL) return; rt300@0: if(globalUI.handleTouchMove(touch.x, touch.y)) return; rt300@0: //cout << "touchMoved ID: " << touch.id << endl; rt300@0: rt300@0: rt300@0: double dax, day; rt300@0: dax = (double(touch.x) - globalUI.borderSize)/ofGetHeight(); rt300@0: day = double(touch.y)/ofGetHeight(); rt300@0: rt300@0: rt300@0: rt300@0: /* rt300@0: if(kslider->checkForTouch(touch.x, touch.y)){ rt300@0: cout << "kslider touched"; rt300@0: kslider->adjust(touch.x,touch.y); rt300@0: return; rt300@0: } rt300@0: */ rt300@0: rt300@0: switch (globalUI.touchMode){ rt300@0: case globalUI.GRAB: rt300@0: theMesh->drag(dax,day,touch.id); rt300@0: break; rt300@0: case globalUI.INSCRIBE_PATH: rt300@0: theMesh->inscribeScanPath(dax,day); rt300@0: break; rt300@0: case globalUI.FORCE_FIELD: rt300@0: //theMesh->forceField(dax,day,touch.id); rt300@13: rt300@0: globalForces.moveForceTouchPoint(dax,day, touch.id); rt300@0: break; rt300@0: case globalUI.SPATIAL_HARMONIC: rt300@0: // makes no sense rt300@0: break; rt300@0: case globalUI.CONSTRAIN: rt300@0: theMesh->constrain(dax,day,Mesh::CONSTRAIN_GRAB_REGION); rt300@0: break; rt300@0: case globalUI.UNCONSTRAIN: rt300@0: theMesh->unconstrain(dax,day,Mesh::CONSTRAIN_GRAB_REGION); rt300@0: break; rt300@0: case globalUI.VIBRATE: rt300@0: break; rt300@0: default: rt300@0: rt300@0: break; rt300@0: } rt300@0: } rt300@0: rt300@0: //-------------------------------------------------------------- rt300@0: void testApp::touchUp(ofTouchEventArgs &touch){ rt300@0: if(theMesh == NULL) return; rt300@0: if(globalUI.handleTouchUp(touch.x, touch.y)) return; rt300@0: rt300@0: rt300@0: removeTouch(); rt300@0: rt300@0: rt300@0: switch (globalUI.touchMode){ rt300@0: case globalUI.GRAB: rt300@0: theMesh->unGrab(touch.id); rt300@0: break; rt300@0: case globalUI.INSCRIBE_PATH: rt300@0: theMesh->disconnectDraw(); rt300@0: break; rt300@0: case globalUI.FORCE_FIELD: rt300@0: globalForces.removeForceTouchPoint(touch.id); rt300@0: break; rt300@0: case globalUI.SPATIAL_HARMONIC: rt300@0: break; rt300@0: case globalUI.CONSTRAIN: rt300@0: rt300@0: break; rt300@0: case globalUI.UNCONSTRAIN: rt300@0: rt300@0: break; rt300@0: case globalUI.VIBRATE: rt300@0: break; rt300@0: default: rt300@0: rt300@0: break; rt300@0: } rt300@0: rt300@0: } rt300@0: rt300@0: //-------------------------------------------------------------- rt300@0: void testApp::touchDoubleTap(ofTouchEventArgs &touch){ rt300@0: // pretty much useless. rt300@0: /* rt300@0: ofxOscMessage m; rt300@0: m.setAddress( "/test" ); rt300@0: m.addIntArg( 1 ); rt300@0: m.addFloatArg( 3.5f ); rt300@0: m.addStringArg( "hello" ); rt300@0: m.addFloatArg( ofGetElapsedTimef() ); rt300@0: sender.sendMessage( m ); rt300@0: */ rt300@0: rt300@0: //ofxiPhoneScreenGrab(NULL); rt300@0: } rt300@0: rt300@0: rt300@0: //-------------------------------------------------------------- rt300@0: void testApp::addTouch(){ rt300@0: numTouches++; rt300@14: //cout << "numtouches " << numTouches << endl; rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: void testApp::removeTouch(){ rt300@0: numTouches--; rt300@0: rt300@0: } rt300@0: rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: // MOUSE - NOT NEEDED FOR IPAD rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: void testApp::mouseMoved(int x, int y ){ rt300@0: //cout << "mouse moved " << x << 'y' << y << '\n'; rt300@0: /* rt300@0: double dax, day; rt300@0: rt300@0: // normalise rt300@0: dax = double(x)/ofGetWidth(); rt300@0: day = double(y)/ofGetHeight(); rt300@0: rt300@0: theMesh->checkHover(dax,day); rt300@0: rt300@0: */ rt300@0: } rt300@0: rt300@0: //-------------------------------------------------------------- rt300@0: void testApp::mouseDragged(int x, int y, int button){ rt300@0: //cout << "mouse DRAGGED " << x << 'y' << y << '\n'; rt300@0: /* rt300@0: double dax, day; rt300@0: dax = double(x)/ofGetWidth(); rt300@0: day = double(y)/ofGetHeight(); rt300@0: rt300@0: if(button == 0){ rt300@0: if(!paused){ rt300@0: theMesh->drag(dax,day, 0); rt300@0: }else{ rt300@0: // pause mode - draw a scan path! rt300@0: rt300@0: theMesh->drawScanPath(dax,day); rt300@0: audioOn = false; rt300@0: } rt300@0: }else if(button == 2){ rt300@0: rt300@0: } rt300@0: */ rt300@0: rt300@0: } rt300@0: rt300@0: //-------------------------------------------------------------- rt300@0: void testApp::mousePressed(int x, int y, int button){ rt300@0: /* rt300@0: double dax, day; rt300@0: // normalise rt300@0: dax = double(x)/ofGetWidth(); rt300@0: day = double(y)/ofGetHeight(); rt300@0: rt300@0: if(button == 0){ rt300@0: if(paused){ rt300@0: // draw a path rt300@0: audioOn = false; rt300@0: theMesh->deleteScanPath(); rt300@0: }else{ rt300@0: theMesh->grab(dax,day, 0); rt300@0: } rt300@0: }else if(button == 2){ rt300@0: theMesh->constrain(dax,day,Mesh::CONSTRAIN_GRAB_REGION); rt300@0: }else{ rt300@0: cout << "OTHER BUTTON?\n"; rt300@0: } rt300@0: */ rt300@0: rt300@0: rt300@0: } rt300@0: rt300@0: //-------------------------------------------------------------- rt300@0: void testApp::mouseReleased(int x, int y, int button){ rt300@0: /* rt300@0: if(button == 0){ rt300@0: theMesh->unGrab(0); rt300@0: }else if(button == 2){ rt300@0: }else{ rt300@0: cout << "butt other"; rt300@0: } rt300@0: */ rt300@0: rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------AUDIO----------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: void testApp::restartAudioStream(){ rt300@0: ofSoundStreamStart(); rt300@0: audioOn = true; rt300@0: rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: rt300@0: void testApp::audioReceived(float * input, int bufferSize, int nChannels){ rt300@0: rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: void testApp::audioRequested (float * output, int bufferSize, int nChannels){ rt300@0: float sample; rt300@0: static double phasor; rt300@4: rt300@1: if(meshConstructionFlag) return; rt300@5: // if no mesh , scanpath will still be there, but empty should be fine rt300@0: rt300@0: phasorIncr = pitch/SAMPLE_RATE; rt300@0: rt300@3: if(audioOn){ rt300@1: audioAccessFlag = TRUE; rt300@0: for (int i = 0; i < bufferSize; i++){ rt300@0: rt300@3: sample = float(scanPath.getNextSample(phasor)); rt300@0: rt300@0: // hipass to get rid of DC rt300@0: //sample = mydspTools.highpass1(sample); rt300@0: sample = mydspTools.butter(sample); rt300@14: // clip after volume rt300@14: sample = sample*globalForces.volume; rt300@14: if (sample >= 1.0){ rt300@14: sample = 0.999999999; rt300@14: }else if (sample <= -1.0){ rt300@14: sample = -0.999999999; rt300@14: } rt300@14: rt300@14: output[i*nChannels ] = sample; rt300@14: output[i*nChannels + 1] = sample; rt300@0: rt300@0: phasor += phasorIncr; rt300@0: rt300@0: if(phasor >= 1.0){ rt300@0: phasor -= 1.0; rt300@0: } rt300@1: } rt300@1: audioAccessFlag = FALSE; rt300@0: }else{ rt300@0: for (int i = 0; i < bufferSize; i++){ rt300@0: output[i*nChannels ] = 0.0; rt300@0: output[i*nChannels + 1] = 0.0; rt300@0: } rt300@0: } rt300@0: rt300@1: rt300@0: rt300@0: } rt300@0: rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------OSC MSGS-------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: rt300@0: void testApp::handleMessages(){ rt300@0: rt300@0: // hide old messages rt300@0: for ( int i=0; i 0){ rt300@0: cout << "note pitch = " << pitch << endl; rt300@0: pitch = 440.0/pow(2.0,((69.0 - double(note))/12.0)); rt300@0: theMesh->hit(0.5,0.5,velocity,globalForces.excitationType,globalForces.excitationShape); rt300@0: }else{ rt300@0: theMesh->damp(); rt300@0: } rt300@0: rt300@0: rt300@0: } rt300@0: else if ( m.getAddress() == "excitationStrength" ) rt300@0: { rt300@0: globalForces.excitationStrength = m.getArgAsFloat(0); rt300@0: rt300@0: rt300@0: } rt300@0: rt300@0: else if ( m.getAddress() == "excitationType" ) rt300@0: { rt300@0: rt300@0: // set MIDI twanger mode rt300@0: if(m.getArgAsString(0) == "POSITION"){ rt300@0: globalForces.excitationType = GlobalForces::POSITION; rt300@0: rt300@0: }else if (m.getArgAsString(0) == "VELOCITY"){ rt300@0: cout << "excitationType = VELOCITY" << endl; rt300@0: globalForces.excitationType = GlobalForces::VELOCITY; rt300@0: } rt300@0: } rt300@0: else if ( m.getAddress() == "excitationShape" ) rt300@0: { rt300@0: rt300@0: // set MIDI twanger twang shape rt300@0: if(m.getArgAsString(0) == "NOISE"){ rt300@0: globalForces.excitationShape = GlobalForces::NOISE; rt300@0: rt300@0: }else if (m.getArgAsString(0) == "GAUSS"){ rt300@0: cout << "excitationType = GAUSS" << endl; rt300@0: globalForces.excitationShape = GlobalForces::GAUSS; rt300@0: }else if (m.getArgAsString(0) == "SINE"){ rt300@0: cout << "excitationType = SINE" << endl; rt300@0: globalForces.excitationShape = GlobalForces::SINE; rt300@0: rt300@0: } rt300@0: // set size rt300@0: globalForces.exciteShapeX = m.getArgAsInt32(1); rt300@0: globalForces.exciteShapeY = m.getArgAsInt32(2); rt300@0: } rt300@0: rt300@0: // touchModes: {GRAB,FORCE_FIELD,SPATIAL_HARMONIC,CONSTRAIN,VIBRATE,INSCRIBE_PATH}; rt300@0: else if ( m.getAddress() == "touchMode" ) rt300@0: { rt300@0: rt300@0: // set touch mode rt300@0: if(m.getArgAsString(0) == "GRAB"){ rt300@0: globalUI.touchMode = globalUI.GRAB; rt300@0: rt300@0: }else if (m.getArgAsString(0) == "FORCE_FIELD"){ rt300@0: cout << "touchMode = FORCE_FIELD" << endl; rt300@0: globalUI.touchMode = globalUI.FORCE_FIELD; rt300@0: }else if (m.getArgAsString(0) == "SPATIAL_HARMONIC"){ rt300@0: //cout << "touchMode = SPATIAL_HARMONIC" << endl; rt300@0: globalUI.touchMode = globalUI.SPATIAL_HARMONIC; rt300@0: }else if (m.getArgAsString(0) == "CONSTRAIN"){ rt300@0: //cout << "touchMode = CONSTRAIN" << endl; rt300@0: globalUI.touchMode = globalUI.CONSTRAIN; rt300@0: }else if (m.getArgAsString(0) == "VIBRATE"){ rt300@0: //cout << "touchMode = VIBRATE" << endl; rt300@0: globalUI.touchMode = globalUI.VIBRATE; rt300@0: }else if (m.getArgAsString(0) == "UNCONSTRAIN"){ rt300@0: //cout << "touchMode = UNCONSTRAIN" << endl; rt300@0: globalUI.touchMode = globalUI.UNCONSTRAIN; rt300@0: }else if (m.getArgAsString(0) == "INSCRIBE_PATH"){ rt300@0: //cout << "touchMode = INSCRIBE_PATH" << endl; rt300@0: globalUI.touchMode = globalUI.INSCRIBE_PATH; rt300@0: theMesh->clearScanPath(); rt300@0: } rt300@0: } rt300@0: rt300@0: else if ( m.getAddress() == "pause" ) rt300@0: { rt300@0: paused = !paused; rt300@0: } rt300@0: else if ( m.getAddress() == "touchStrength" ) rt300@0: { rt300@0: for ( int i=0; iresetPositions(); rt300@0: theMesh->resetVelocities(); rt300@0: paused = true; rt300@0: audioOn = false; rt300@0: globalUI.touchMode = globalUI.INSCRIBE_PATH; rt300@0: theMesh->clearScanPath(); rt300@0: theMesh->update(); rt300@0: }else{ rt300@0: rt300@0: paused = false; rt300@0: audioOn = true; rt300@0: globalUI.touchMode = globalUI.GRAB; rt300@0: } rt300@0: rt300@0: } rt300@0: else if ( m.getAddress() == "clearScanPath" ) rt300@0: { rt300@0: theMesh->clearScanPath(); rt300@0: } rt300@0: else if ( m.getAddress() == "toggleForce" ) rt300@0: { rt300@0: theMesh->toggleSpringForces(); rt300@0: } rt300@0: else if ( m.getAddress() == "toggleGravity" ) rt300@0: { rt300@0: theMesh->toggleGravity(); rt300@0: } rt300@0: else if ( m.getAddress() == "resetPositions" ) rt300@0: { rt300@0: theMesh->resetPositions(); rt300@0: } rt300@0: else if ( m.getAddress() == "resetVelocities" ) rt300@0: { rt300@0: theMesh->resetVelocities(); rt300@0: } rt300@0: rt300@0: rt300@0: else if ( m.getAddress() == "reset" ) rt300@0: { rt300@0: theMesh->resetPositions(); rt300@0: theMesh->resetVelocities(); rt300@0: theMesh->update(); rt300@0: rt300@0: } rt300@0: else if ( m.getAddress() == "deleteMesh" ) rt300@0: { rt300@0: deleteMesh(); rt300@0: } rt300@0: else if ( m.getAddress() == "regenerate" ) rt300@0: { rt300@0: // ignore it - the mesh is not deleted rt300@0: rt300@0: rt300@0: } rt300@0: else if ( m.getAddress() == "zeroRestLength" ) rt300@0: { rt300@0: theMesh->zeroRestLength(); rt300@0: } rt300@0: else if ( m.getAddress() == "setThisRestLength" ) rt300@0: { rt300@0: theMesh->setRestLength(); rt300@0: } rt300@0: else if ( m.getAddress() == "setZeroAudioLine" ) rt300@0: { rt300@0: theMesh->setZeroAudioLine(); rt300@0: } rt300@0: else if ( m.getAddress() == "speedLimit" ) rt300@0: { rt300@0: for ( int i=0; itoggleSyrup(); rt300@0: } rt300@0: else if ( m.getAddress() == "toggleAudio" ) rt300@0: { rt300@0: if(audioOn){ rt300@0: ofSoundStreamStop(); rt300@0: audioOn = false; rt300@0: }else{ rt300@0: restartAudioStream(); rt300@0: } rt300@0: rt300@0: } rt300@0: rt300@0: else if ( m.getAddress() == "constrainEdges" ) rt300@0: { rt300@0: theMesh->constrain(.0,.0,Mesh::CONSTRAIN_EDGES); rt300@0: } rt300@0: else if ( m.getAddress() == "constrainCorners" ) rt300@0: { rt300@0: theMesh->constrain(.0,.0,Mesh::CONSTRAIN_CORNERS ); rt300@0: } rt300@0: else if ( m.getAddress() == "unconstrain" ) rt300@0: { rt300@0: theMesh->unconstrain(); rt300@0: } rt300@0: else if ( m.getAddress() == "mass" ) rt300@0: { rt300@0: for ( int i=0; isetMass(m.getArgAsInt32( i )); rt300@0: } rt300@0: else if( m.getArgType( i ) == OFXOSC_TYPE_FLOAT ) rt300@0: { rt300@0: theMesh->setMass(m.getArgAsFloat( i )<0.01?0.01:m.getArgAsFloat( i ) ); rt300@0: } rt300@0: rt300@0: } rt300@0: } rt300@0: else if ( m.getAddress() == "springk" ) rt300@0: { rt300@0: for ( int i=0; isetSpringConstant(m.getArgAsInt32( i )); rt300@0: } rt300@0: else if( m.getArgType( i ) == OFXOSC_TYPE_FLOAT ) rt300@0: { rt300@0: theMesh->setSpringConstant(m.getArgAsFloat( i )<0.01?0.01:m.getArgAsFloat( i ) ); rt300@0: } rt300@0: rt300@0: } rt300@0: } rt300@0: else if ( m.getAddress() == "friction" ) rt300@0: { rt300@0: for ( int i=0; isetFriction(m.getArgAsInt32( i )); rt300@0: } rt300@0: else if( m.getArgType( i ) == OFXOSC_TYPE_FLOAT ) rt300@0: { rt300@0: theMesh->setFriction(m.getArgAsFloat( i )<0.01?0.01:m.getArgAsFloat( i ) ); rt300@0: } rt300@0: rt300@0: } rt300@0: } rt300@0: //////////////// asym rt300@0: else if ( m.getAddress() == "massAsym" ) rt300@0: { rt300@0: for ( int i=0; isetMassAsym(m.getArgAsFloat( i )<0.01?0.01:m.getArgAsFloat( i ) ); rt300@0: } rt300@0: rt300@0: } rt300@0: } rt300@0: else if ( m.getAddress() == "springkAsym" ) rt300@0: { rt300@0: for ( int i=0; isetSpringConstantAsym(m.getArgAsFloat( i )<0.00?0.00:m.getArgAsFloat( i ) ); rt300@0: } rt300@0: rt300@0: } rt300@0: } rt300@0: else if ( m.getAddress() == "frictionAsym" ) rt300@0: { rt300@0: for ( int i=0; isetFrictionAsym(m.getArgAsFloat( i )<0.01?0.01:m.getArgAsFloat( i ) ); rt300@0: } rt300@0: rt300@0: } rt300@0: } rt300@0: else if ( m.getAddress() == "volume" ) rt300@0: { rt300@0: for ( int i=0; iaddSpacer(length-xInit, 2); rt300@15: //guiL->setUIColors(bgCol, outlineCol, outlineHiCol, fillCol, fillHicol, paddingCol, padOutlineCol); rt300@15: rt300@15: rt300@5: guiL->addWidgetDown(new ofxUILabel("Physics", OFX_UI_FONT_LARGE)); rt300@5: rt300@5: ofxUIWidget *slider; rt300@15: //ofxUISlider_<<#typename T#>>(<#string _name#>, <#T _min#>, <#T _max#>, <#T _value#>, <#float w#>, <#float h#>) rt300@15: slider = guiL->addWidgetDown(new ofxUISlider("SPRING K",0.0,0.8,0.4,length,widgetHeight)); rt300@5: slider->setDrawPadding(true); rt300@15: slider->setDrawPaddingOutline(true); rt300@15: slider->setColorFill(fillHicol); rt300@15: slider->setColorFillHighlight(fillHicol); rt300@5: rt300@15: slider = guiL->addWidgetDown(new ofxUISlider("GRAVITY", 0.0, 4.0, 0.0,length,widgetHeight )); rt300@5: slider->setDrawPadding(true); rt300@15: slider->setDrawPaddingOutline(true); rt300@15: slider->setColorFill(fillHicol); rt300@15: slider->setColorFillHighlight(fillHicol); rt300@15: rt300@15: slider = guiL->addWidgetDown(new ofxUISlider("HOMING",0.0,0.3,0.0,length,widgetHeight)); rt300@5: slider->setDrawPadding(true); rt300@15: slider->setDrawPaddingOutline(true); rt300@15: slider->setColorFill(fillHicol); rt300@15: slider->setColorFillHighlight(fillHicol); rt300@15: rt300@15: slider = guiL->addWidgetDown(new ofxUISlider("SMOOTHING", 0.0, 0.5, 0.01,length,widgetHeight)); rt300@5: slider->setDrawPadding(true); rt300@15: slider->setDrawPaddingOutline(true); rt300@15: slider->setColorFill(fillHicol); rt300@15: slider->setColorFillHighlight(fillHicol); rt300@5: rt300@5: rt300@5: guiL->addSpacer(length-xInit, 2); rt300@15: rt300@5: rt300@15: //guiL->setWidgetPosition(OFX_UI_WIDGET_POSITION_DOWN); rt300@15: slider = guiL->addSlider("PITCH", 2.0, 100.0, 80.0, length, heightS/2); rt300@5: slider->setDrawPadding(true); rt300@15: slider->setDrawPaddingOutline(true); rt300@15: slider->setColorFill(fillHicol); rt300@15: slider->setColorFillHighlight(fillHicol); rt300@15: rt300@5: ofAddListener(guiL->newGUIEvent, this, &testApp::guiLEvent); rt300@5: rt300@15: //guiL->setUIColors( ofColor(56,56,56), ofColor(255,255,56), ofColor(255,255,56), ofColor(0,0,255), ofColor(0,0,255), ofColor(0,0,255), ofColor(0,0,255) ); rt300@15: // RIGHT GUI ----------------------- rt300@5: rt300@15: guiR = new ofxUICanvas(ofGetWidth()-sidebarWidth, 0, sidebarWidth, ofGetHeight()-64); rt300@5: rt300@5: rt300@5: guiR->addSpacer(length-xInit, 2); rt300@5: rt300@5: vector names; rt300@5: names.push_back("GRAB"); rt300@5: names.push_back("FORCE"); rt300@5: names.push_back("SINE"); rt300@5: names.push_back("STICK"); rt300@5: names.push_back("UNSTICK"); rt300@5: names.push_back("NEWPATH"); rt300@5: rt300@5: rt300@5: ofxUIRadio* radio; rt300@15: radio = guiR->addRadio("TOUCH MODE", names, OFX_UI_ORIENTATION_VERTICAL, widgetHeight, widgetHeight); rt300@5: radio->setDrawPadding(true); rt300@15: radio->setColorFill(fillHicol); rt300@15: radio->setColorFillHighlight(fillHicol); rt300@5: rt300@15: slider = guiR->addWidgetDown(new ofxUISlider( "TOUCH AMT", -0.4, 4.0, 1.0,length,widgetHeight)); rt300@5: slider->setDrawPadding(true); rt300@15: slider->setColorFill(fillHicol); rt300@15: slider->setColorFillHighlight(fillHicol); rt300@5: rt300@5: guiR->addSpacer(length-xInit, 2); rt300@5: rt300@15: guiR->addToggle("PAUSE", false, widgetHeight, widgetHeight); rt300@15: guiR->addButton("RESET", false, widgetHeight, widgetHeight); rt300@15: guiR->addButton("NEW", false, widgetHeight, widgetHeight); rt300@15: guiR->addButton("SAVE", false, widgetHeight, widgetHeight); rt300@15: guiR->addButton("LOAD", false, widgetHeight, widgetHeight); rt300@5: rt300@5: ofAddListener(guiR->newGUIEvent, this, &testApp::guiREvent); rt300@5: //guiR->loadSettings(ofxiPhoneGetDocumentsDirectory() + "guiSettings.xml"); rt300@5: radio->activateToggle("GRAB"); rt300@5: rt300@8: // show hide ctrls rt300@15: guiSH = new ofxUICanvas(ofGetWidth() - sidebarWidth, ofGetHeight()-64, sidebarWidth, 64); rt300@8: rt300@8: rt300@8: guiSH->addSpacer(length-xInit, 2); rt300@15: ofxUIToggle* t = guiSH->addToggle("CTRLS", false, widgetHeight, widgetHeight); rt300@15: // turn toggle on rt300@15: t->setState(true); rt300@15: rt300@8: ofAddListener(guiSH->newGUIEvent, this, &testApp::guiSHEvent); rt300@8: rt300@5: } rt300@5: //-------------------------------------------------------------- rt300@5: void testApp::UIcallBack(int buttID){ rt300@5: cout << " BUTT ID " << buttID << "\n"; rt300@5: rt300@5: } rt300@15: void testApp::hideControls(){ rt300@15: cout << "CTRLS ooff"; rt300@15: guiR->setVisible(false); rt300@15: guiL->setVisible(false); rt300@15: controlsShowing = false; rt300@15: } rt300@15: void testApp::showControls(){ rt300@15: cout << "CTRLS onnn"; rt300@15: guiR->setVisible(true); rt300@15: guiL->setVisible(true); rt300@15: controlsShowing = true; rt300@15: } rt300@5: //-------------------------------------------------------------- rt300@8: void testApp::guiSHEvent(ofxUIEventArgs &e) rt300@8: { rt300@8: if(e.widget->getName() == "CTRLS"){ rt300@8: // ???? rt300@8: rt300@8: cout << ((ofxUIButton *)e.widget)->getValue(); rt300@8: rt300@8: if( ((ofxUIButton *)e.widget)->getValue() == 0) { rt300@15: hideControls(); rt300@8: }else{ rt300@15: showControls(); rt300@8: } rt300@8: rt300@8: } rt300@8: } rt300@8: rt300@8: //-------------------------------------------------------------- rt300@5: void testApp::guiREvent(ofxUIEventArgs &e) rt300@5: { rt300@5: if(e.widget->getName() == "TOUCH MODE") rt300@5: { rt300@5: cout << "TOUCH MODE"; rt300@5: rt300@5: } rt300@5: if(e.widget->getName() == "GRAB"){ rt300@5: cout << "GRAB"; rt300@5: globalUI.touchMode = globalUI.GRAB; rt300@5: }else if(e.widget->getName() == "FORCE"){ rt300@5: rt300@5: globalUI.touchMode = globalUI.FORCE_FIELD; rt300@5: }else if(e.widget->getName() == "STICK"){ rt300@5: rt300@5: globalUI.touchMode = globalUI.CONSTRAIN; rt300@5: }else if(e.widget->getName() == "UNSTICK"){ rt300@5: rt300@5: globalUI.touchMode = globalUI.UNCONSTRAIN; rt300@5: }else if(e.widget->getName() == "NEWPATH"){ rt300@5: if(globalUI.touchMode != globalUI.INSCRIBE_PATH){ rt300@5: theMesh->resetPositions(); rt300@5: theMesh->resetVelocities(); rt300@5: globalUI.touchMode = globalUI.INSCRIBE_PATH; rt300@5: theMesh->clearScanPath(); rt300@5: theMesh->update(); rt300@5: } rt300@5: }else if(e.widget->getName() == "SINE"){ rt300@5: globalUI.touchMode = globalUI.SPATIAL_HARMONIC; rt300@5: }else if(e.widget->getName() == "RESET"){ rt300@5: theMesh->resetAll(); rt300@5: numTouches = 0; rt300@5: }else if(e.widget->getName() == "NEW"){ rt300@5: // ???? rt300@5: rt300@5: cout << ((ofxUIButton *)e.widget)->getValue(); rt300@5: rt300@5: if( ((ofxUIButton *)e.widget)->getValue() == 0) { rt300@9: rt300@5: deleteMesh(); rt300@5: setupMesh(); rt300@5: }else{ rt300@9: rt300@5: } rt300@9: }else if(e.widget->getName() == "SAVE"){ rt300@9: // save the preset somehow rt300@9: if( ((ofxUIButton *)e.widget)->getValue() == 0) { rt300@9: savePreset(); rt300@9: } rt300@9: }else if(e.widget->getName() == "LOAD"){ rt300@9: // save the preset somehow rt300@9: if( ((ofxUIButton *)e.widget)->getValue() == 0) { rt300@9: loadPreset(); rt300@9: } rt300@5: }else if(e.widget->getName() == "PAUSE"){ rt300@5: paused = !paused; rt300@5: }else if(e.widget->getName() == "TOUCH AMT"){ rt300@5: ofxUISlider *slider = (ofxUISlider *) e.widget; rt300@5: slider->setDrawPadding(true); rt300@5: globalForces.touchStrength = slider->getScaledValue(); rt300@5: } rt300@5: rt300@5: } rt300@5: //-------------------------------------------------------------- rt300@5: void testApp::guiLEvent(ofxUIEventArgs &e) rt300@5: { rt300@5: if(e.widget->getName() == "SPRING K") rt300@5: { rt300@5: ofxUISlider *slider = (ofxUISlider *) e.widget; rt300@5: rt300@5: theMesh->setSpringConstant( slider->getScaledValue() ); rt300@5: }else if(e.widget->getName() == "GRAVITY") rt300@5: { rt300@5: ofxUISlider *slider = (ofxUISlider *) e.widget; rt300@5: slider->setDrawPadding(true); rt300@5: globalForces.gravityAmt = slider->getScaledValue(); rt300@5: //radio->getScaledValue() ); rt300@5: }else if(e.widget->getName() == "HOMING") rt300@5: { rt300@5: ofxUISlider *slider = (ofxUISlider *) e.widget; rt300@5: globalForces.homingAmt = slider->getScaledValue(); rt300@5: //radio->getScaledValue() ); rt300@5: }else if(e.widget->getName() == "SMOOTHING") rt300@5: { rt300@5: rt300@5: rt300@5: ofxUISlider *slider = (ofxUISlider *) e.widget; rt300@5: globalForces.avFilterAmt = slider->getScaledValue(); rt300@5: //radio->getScaledValue() ); rt300@5: }else if(e.widget->getName() == "FRICTION") rt300@5: { rt300@5: rt300@5: rt300@5: ofxUISlider *slider = (ofxUISlider *) e.widget; rt300@5: theMesh->setFriction(slider->getScaledValue()); rt300@5: //radio->getScaledValue() ); rt300@5: }else if(e.widget->getName() == "PITCH") rt300@5: { rt300@5: rt300@5: rt300@5: ofxUISlider *slider = (ofxUISlider *) e.widget; rt300@5: pitch = slider->getScaledValue(); rt300@5: //radio->getScaledValue() ); rt300@5: } rt300@5: rt300@5: rt300@5: } rt300@8: rt300@8: //-------------------------------------------------------------- rt300@13: rt300@8: void testApp::deviceOrientationChanged(int newOrientation){ rt300@8: rt300@8: cout << "orientation: " << newOrientation; rt300@13: rt300@8: if(newOrientation == 4){ rt300@13: ofxiPhoneSetOrientation( OF_ORIENTATION_90_RIGHT ); rt300@8: rt300@8: } rt300@13: rt300@8: } rt300@13: rt300@10: rt300@10: //------------------------------------------------------------------------- rt300@10: //-------------------------------------------------------------- rt300@10: rt300@10: #pragma mark MIDI rt300@10: void testApp::addMessage(string msg) { rt300@10: cout << msg << endl; rt300@10: messages.push_back(msg); rt300@10: while(messages.size() > maxMessages) rt300@10: messages.pop_front(); rt300@10: } rt300@10: rt300@10: //-------------------------------------------------------------- rt300@10: void testApp::newMidiMessage(ofxMidiMessage& msg) { rt300@10: // recieved one rt300@10: static int p; // remembers last note on rt300@10: int v; rt300@10: // look at what it is rt300@10: rt300@10: if(msg.status == MIDI_CONTROL_CHANGE){ rt300@10: int ctl_num = msg.control; rt300@10: int ctl_val = msg.value; rt300@10: // TODO route control change message here rt300@10: } rt300@10: rt300@10: if(msg.status == MIDI_NOTE_ON){ rt300@10: p = msg.pitch; rt300@10: v = msg.velocity; rt300@10: rt300@10: // TODO handle note on here rt300@10: if(v > 0){ rt300@12: //cout << "note pitch = " << p << endl; rt300@10: pitch = 440.0/pow(2.0,((69.0 - double(p))/12.0)); rt300@12: globalForces.excitationShape = GlobalForces::SINE; rt300@12: if(theMesh != NULL && !meshConstructionFlag){ rt300@12: theMesh->hit(0.5,0.5,v,globalForces.excitationType,globalForces.excitationShape); rt300@12: } rt300@10: }else{ rt300@10: //theMesh->damp(); rt300@10: } rt300@10: } rt300@10: if(msg.status == MIDI_NOTE_OFF){ rt300@10: if(msg.pitch == p){ rt300@10: //theMesh->damp(); rt300@10: } rt300@10: // otherwise ignore it, it's not the currenttly playing note rt300@10: } rt300@10: rt300@10: } rt300@10: rt300@10: //-------------------------------------------------------------- rt300@10: void testApp::midiInputAdded(string name, bool isNetwork) { rt300@10: stringstream msg; rt300@10: msg << "ofxMidi: input added: " << name << " network: " << isNetwork; rt300@10: cout << msg.str(); rt300@10: addMessage(msg.str()); rt300@10: rt300@10: // create and open a new input port rt300@10: ofxMidiIn * newInput = new ofxMidiIn; rt300@10: newInput->openPort(name); rt300@10: newInput->addListener(this); rt300@10: inputs.push_back(newInput); rt300@10: } rt300@10: rt300@10: //-------------------------------------------------------------- rt300@10: void testApp::midiInputRemoved(string name, bool isNetwork) { rt300@10: stringstream msg; rt300@10: msg << "ofxMidi: input removed: " << name << " network: " << isNetwork << endl; rt300@10: cout << msg.str(); rt300@10: addMessage(msg.str()); rt300@10: rt300@10: // close and remove input port rt300@10: vector::iterator iter; rt300@10: for(iter = inputs.begin(); iter != inputs.end(); ++iter) { rt300@10: ofxMidiIn * input = (*iter); rt300@10: if(input->getName() == name) { rt300@10: input->closePort(); rt300@10: input->removeListener(this); rt300@10: delete input; rt300@10: inputs.erase(iter); rt300@10: break; rt300@10: } rt300@10: } rt300@10: } rt300@10: rt300@10: //-------------------------------------------------------------- rt300@10: void testApp::midiOutputAdded(string name, bool isNetwork) { rt300@10: stringstream msg; rt300@10: msg << "ofxMidi: output added: " << name << " network: " << isNetwork << endl; rt300@10: cout << msg.str(); rt300@10: addMessage(msg.str()); rt300@10: rt300@10: // create and open new output port rt300@10: ofxMidiOut * newOutput = new ofxMidiOut; rt300@10: newOutput->openPort(name); rt300@10: outputs.push_back(newOutput); rt300@10: } rt300@10: rt300@10: //-------------------------------------------------------------- rt300@10: void testApp::midiOutputRemoved(string name, bool isNetwork) { rt300@10: stringstream msg; rt300@10: msg << "ofxMidi: output removed: " << name << " network: " << isNetwork << endl; rt300@10: cout << msg.str(); rt300@10: addMessage(msg.str()); rt300@10: rt300@10: // close and remove output port rt300@10: vector::iterator iter; rt300@10: for(iter = outputs.begin(); iter != outputs.end(); ++iter) { rt300@10: ofxMidiOut * output = (*iter); rt300@10: if(output->getName() == name) { rt300@10: output->closePort(); rt300@10: delete output; rt300@10: outputs.erase(iter); rt300@10: break; rt300@10: } rt300@10: } rt300@10: } rt300@10: //--------------------------------------------------------------