summaryrefslogtreecommitdiff
path: root/FESgui/src/ofApp.cpp
diff options
context:
space:
mode:
authorTim Redfern <tim@getdrop.com>2023-04-17 19:44:00 +0100
committerTim Redfern <tim@getdrop.com>2023-04-17 19:44:00 +0100
commit19be92e0aff674b95bdae72fe7a2e409fd1bf77a (patch)
tree079acfc11ffbff8f11b120649f5cb3a623e354d6 /FESgui/src/ofApp.cpp
parent5309ef89393aa56083d1c2238c517c3d576907ec (diff)
add to archive
Diffstat (limited to 'FESgui/src/ofApp.cpp')
-rw-r--r--FESgui/src/ofApp.cpp1064
1 files changed, 1064 insertions, 0 deletions
diff --git a/FESgui/src/ofApp.cpp b/FESgui/src/ofApp.cpp
new file mode 100644
index 0000000..a1c49be
--- /dev/null
+++ b/FESgui/src/ofApp.cpp
@@ -0,0 +1,1064 @@
+#include "ofApp.h"
+
+
+
+//====================== settings
+
+void ofApp::default_settings(){
+ warpframe[0]=glm::vec3(0,0,0);
+ warpframe[1]=glm::vec3(outputWindowSize.x,0,0);
+ warpframe[2]=glm::vec3(outputWindowSize.x,outputWindowSize.y,0);
+ warpframe[3]=glm::vec3(0,outputWindowSize.y,0);
+ outputPosition=ofPoint(0,0,0);
+ outputScale=1.0f;
+}
+
+void ofApp::save_settings(){
+ XML.setValue("WARP:p0:X", warpframe[0].x);
+ XML.setValue("WARP:p0:Y", warpframe[0].y);
+ XML.setValue("WARP:p1:X", warpframe[1].x);
+ XML.setValue("WARP:p1:Y", warpframe[1].y);
+ XML.setValue("WARP:p2:X", warpframe[2].x);
+ XML.setValue("WARP:p2:Y", warpframe[2].y);
+ XML.setValue("WARP:p3:X", warpframe[3].x);
+ XML.setValue("WARP:p3:Y", warpframe[3].y);
+
+ XML.setValue("SAFETY:p0:X", safety_frame[0].x);
+ XML.setValue("SAFETY:p0:Y", safety_frame[0].y);
+ XML.setValue("SAFETY:p1:X", safety_frame[1].x);
+ XML.setValue("SAFETY:p1:Y", safety_frame[1].y);
+ XML.setValue("SAFETY:p2:X", safety_frame[2].x);
+ XML.setValue("SAFETY:p2:Y", safety_frame[2].y);
+ XML.setValue("SAFETY:p3:X", safety_frame[3].x);
+ XML.setValue("SAFETY:p3:Y", safety_frame[3].y);
+
+ XML.setValue("POSITION:X", outputPosition.x);
+ XML.setValue("POSITION:Y", outputPosition.y);
+
+ XML.setValue("SCALE", outputScale);
+
+ if (XML.saveFile("settings.xml")){
+ cout << "settings.xml saved!" <<std::endl;
+ }
+ else {
+ cout << "could not save settings.xml!" <<std::endl;
+ }
+}
+
+void ofApp::setup_lasergui(int x, int y){
+
+ laser.setup(x,y);
+
+ bShowPositionInterface=false;
+ bOutputSelected=false;
+
+ outputOffsetScale=1.0f;
+ commandPressed=false;
+
+
+ select_warpframe=-1;
+ bDrawFrame=false;
+
+ select_safetyframe=-1;
+
+ if( XML.loadFile("settings.xml") ){
+ cout << "settings.xml loaded!" <<std::endl;
+
+ }
+ else{
+ cout << "unable to load settings.xml"<<std::endl;
+ }
+
+ warpframe[0]=glm::vec2(
+ XML.getValue("WARP:p0:X", 0),
+ XML.getValue("WARP:p0:Y", 0)
+ );
+ warpframe[1]=glm::vec2(
+ XML.getValue("WARP:p1:X", outputWindowSize.x),
+ XML.getValue("WARP:p1:Y", 0)
+ );
+ warpframe[2]=glm::vec2(
+ XML.getValue("WARP:p2:X", outputWindowSize.x),
+ XML.getValue("WARP:p2:Y", outputWindowSize.y)
+ );
+ warpframe[3]=glm::vec2(
+ XML.getValue("WARP:p3:X", 0),
+ XML.getValue("WARP:p3:Y", outputWindowSize.y)
+ );
+
+ safety_frame[0]=glm::vec3(
+ XML.getValue("SAFETY:p0:X", 0),
+ XML.getValue("SAFETY:p0:Y", 0),
+ 0
+ );
+ safety_frame[1]=glm::vec3(
+ XML.getValue("SAFETY:p1:X", outputWindowSize.x),
+ XML.getValue("SAFETY:p1:Y", 0),
+ 0
+ );
+ safety_frame[2]=glm::vec3(
+ XML.getValue("SAFETY:p2:X", outputWindowSize.x),
+ XML.getValue("SAFETY:p2:Y", outputWindowSize.y),
+ 0
+ );
+ safety_frame[3]=glm::vec3(
+ XML.getValue("SAFETY:p3:X", 0),
+ XML.getValue("SAFETY:p3:Y", outputWindowSize.y),
+ 0
+ );
+
+ outputPosition=ofPoint(
+ XML.getValue("POSITION:X", 0),
+ XML.getValue("POSITION:Y", 0),
+ 0
+ );
+
+ laser.set_centre(outputPosition);
+
+ outputScale=XML.getValue("SCALE", 1.0f);
+}
+
+void ofApp::setup(){
+
+ int frameRate=60;
+
+ ofSetFrameRate(frameRate);
+ ofBackground(0);
+
+ ofDisableArbTex(); //this is required for perlin filter
+ ofEnableSmoothing();
+ ofEnableAlphaBlending();
+ ofSetVerticalSync(true);
+
+ blockSize = SAMPLERATE / (frameRate*10); //80
+
+ ofSoundStreamListDevices();
+
+ soundStream.setup(this,0, 1, SAMPLERATE, blockSize, 1);
+
+ buffer=Buffer(SAMPLERATE);
+
+ //vScale=3.0f;
+ //hScale=8.0f;
+
+ //lineWidth=2.0f;
+
+ //panels are 210 wide
+
+ videoSourcePanel.setup("video sources","",5,5);
+ videoSourcePanel.add(captPreview.set("camera preview",true));
+ videoSourcePanel.add(captEnable.set("camera",false));
+ videoSourcePanel.add(videoOscEnable.set("oscilloscope",false));
+ videoSourcePanel.add(playerEnable.set("player",false));
+ videoSourcePanel.add(contoursVideoDraw.set("contours",false));
+ videoSourcePanel.add(SVGVideoDraw.set("SVG",false));
+ videoSourcePanel.add(textVideoDraw.set("text",false));
+ videoSourcePanel.add(video_speed.set("playback speed",1.0,0.0,3.0));
+
+ vectorSourcePanel.setup("vector sources","",5,370);
+ vectorSourcePanel.add(edit_safety.set("edit safety",false));
+ vectorSourcePanel.add(use_safety.set("use safety",true));
+ vectorSourcePanel.add(vectorOscEnable.set("oscilloscope",false));
+ vectorSourcePanel.add(contoursLaserDraw.set("contours",false));
+ vectorSourcePanel.add(SVGLaserDraw.set("SVG",false));
+ vectorSourcePanel.add(textLaserDraw.set("text",false));
+
+ setup_lasergui(970,500);
+
+ audiopanel.setup("oscilloscope","",5,220);
+ audiopanel.add(vScale.set("vertical",3.0,0.0,20.0)); //scaling
+ audiopanel.add(hScale.set("horizontal",1.0,0.1,10.0)); //ms
+ audiopanel.add(onset_threshold.set("onset threshold", 0.05f, 0.0f, 1.0f ));
+ audiopanel.add(use_onset.set("trigger onset",false));
+ audiopanel.add(onset_duration.set("duration", 10, 1, 100));
+
+ svggui.setup("SVG","",5,500);
+ svggui.add(shapes_randomise.set("randomise shapes", true));
+ svggui.add(shapes_amount.set("shapes amount", 0.2, 0.0, 1.0));
+ svggui.add(shapes_duration.set("shape duration", 5.0, 0, 10.0));
+ svggui.add(use_mask.set("use mask", true));
+ svggui.add(invert_mask.set("invert mask", false));
+
+ //segmenter
+ svggui.add(use_segmenter.set("use segmenter", false));
+ svggui.add(colour_segmenter.set("colour", false));
+ svggui.add(segmenter_speed.set("segmenter speed", 0.2, -1.0, 1.0));
+ svggui.add(segmenter_length.set("segmenter length", 0.2, 0.0, 1.0));
+ svggui.add(segmenter_number.set("segmenter number", 1, 1, 8));
+
+ text.setup(5,750);
+
+ drawingpanel.setup("drawing","",550,500);
+ drawingpanel.add(lineWidth.set("width",2.0,0.1,10.0));
+
+ useKinect=true;
+
+ if (useKinect) {
+ std::vector <ofxKinectV2::KinectDeviceInfo> deviceList = kinect.getDeviceList();
+ if (deviceList.size()){
+ useKinect=kinect.open(deviceList[0].serial);
+ }
+ else useKinect=false;
+ }
+
+ if (!useKinect) {
+ _video.initGrabber(1280, 720);
+ }
+
+ contourgui.setup("video contours","",550,550);
+ contourgui.add(video_outlines.set("enable",false));
+ contourgui.add(contour_adaptive.set("adaptive",false));
+ contourgui.add(contour_threshold.set("threshold", 140, 0, 255));
+ contourgui.add(contour_adaptive_window.set("window", 0.5, 0, 1.0));
+ contourgui.add(contour_simplify.set("simplify", 0.8, 0.0, 10.0));
+ //contourgui.add(contour_useColour.set("use colour",false)); //TODO
+
+ vectorTransforms.setup("vector transform","",550,750);
+ vectorTransforms.add(use_rotate.set("rotation",false));
+ vectorTransforms.add(xf_rotate.set("rotate speed", 0.0, -1.0, 1.0));
+ vectorTransforms.add(use_scale.set("scaling",false));
+ vectorTransforms.add(xf_scale_speed.set("scale speed", 1.0, 0.0, 10.0));
+ vectorTransforms.add(xf_scale_min.set("scale min", 1.0, 0.0, 3.0));
+ vectorTransforms.add(xf_scale_max.set("scale maz", 1.0, 0.0, 3.0));
+
+ perlin = new PerlinPhasingFilter(
+ outputWindowSize.x,
+ outputWindowSize.y,
+ 8.f
+ );
+
+ perlinpanel.setup("PerlinPhasingFilter","",760,500);
+ perlinpanel.add(perlinEnable.set("enable",false));
+ perlinpanel.add(perlinScale.set("scale",0.0,-1.0,1.0));
+ perlinpanel.add(perlinSpeed.set("speed",0.0,-1.0,1.0));
+ perlinpanel.add(perlinPixelWidth.set("pixel width",0.0,0.0,1.0));
+ perlinpanel.add(perlinPixelWidthSpeed.set("pixel speed",1.0,0.0,10.0));
+
+ preview.allocate(outputWindowSize.x,outputWindowSize.y);
+
+ gist.setUseForOnsetDetection(GIST_PEAK_ENERGY);
+ gist.setThreshold(GIST_PEAK_ENERGY, .05);//
+
+ ofAddListener(GistEvent::ON,this,&ofApp::onNoteOn);
+ ofAddListener(GistEvent::OFF,this,&ofApp::onNoteOff);
+
+ onset_frame=0;
+}
+
+//--------------------------------------------------------------
+void ofApp::updateOutput(ofEventArgs & args){
+ _player.setSpeed(video_speed);
+}
+
+void ofApp::update(){
+ laser.update();
+ text.update(onset_frame);
+
+ if (_player.isLoaded()){
+ _player.update();
+ }
+
+ if (captPreview||captEnable){
+ if (useKinect){
+ kinect.update();
+ if (kinect.isFrameNew()){
+ texRGB.setFromPixels(kinect.getPixels());
+ }
+ }
+ else {
+ _video.update();
+ texRGB.setFromPixels(_video.getPixels());
+ }
+ int tw=texRGB.getHeight()*1.333f;
+ int sl=(texRGB.getWidth()-tw)/2;
+ texRGB.crop(sl, 0, tw, texRGB.getHeight());
+ }
+
+ float interval=ofGetElapsedTimef()-prev_time;
+ rotate_amt+=interval*xf_rotate*5;
+
+ phase=fmod(phase+(interval*segmenter_speed),1); //for segmenter
+ prev_time=ofGetElapsedTimef();
+
+ while (phase<0.0f) {
+ phase+=1.0f;
+ }
+
+ scale_phase+=(interval*xf_scale_speed);
+
+ scale_amt=(((sin(scale_phase)*0.5)+0.5)*(xf_scale_max-xf_scale_min))+xf_scale_min;
+
+ gist.setThreshold(GIST_PEAK_ENERGY,onset_threshold);
+
+ onset_frame++;
+}
+
+//-------------------------------------------------------------- GUI
+void ofApp::draw(){
+ //draw the workspace window.
+ // 5 - 240 - panels
+ // 250 - 570 - sources (320x240)
+ // 580 - 1220 - preview (640x480)
+
+
+
+ ofBackground(0);
+
+ ofSetColor(255);
+
+
+ if (bShowPositionInterface){
+
+ glPushMatrix();
+
+ ofNoFill();
+
+ glTranslatef(20,20,0);
+
+ ofDrawRectangle(0,0,560,560);
+
+ glTranslatef(outputOffset.x,outputOffset.y,0);
+
+ glScalef(guiScale,guiScale,guiScale );
+
+ glTranslatef(2048.0f+outputPosition.x,2048.0f+outputPosition.y,0);
+
+ if (bOutputSelected) {
+ if (commandPressed) {
+ ofSetColor(0,255,0);
+ }
+ else {
+ ofSetColor(255,0,0);
+ }
+ }
+
+ ofDrawRectangle(
+ (-outputWindowSize.x/2)*outputScale*outputOffsetScale,
+ (-outputWindowSize.y/2)*outputScale*outputOffsetScale,
+ outputWindowSize.x*outputScale*outputOffsetScale,
+ outputWindowSize.y*outputScale*outputOffsetScale);
+
+ ofFill();
+
+ glPopMatrix();
+ }
+ else {
+ //draw gui, sources and preview
+
+ videoSourcePanel.draw();
+ vectorSourcePanel.draw();
+ audiopanel.draw();
+ drawingpanel.draw();
+ perlinpanel.draw();
+ contourgui.draw();
+ vectorTransforms.draw();
+ svggui.draw();
+ laser.drawgui();
+ text.drawgui();
+
+ float sourcescale=sourceframesize.x/outputWindowSize.x;
+
+ for (int i=0;i<4;i++){
+ glPushMatrix();
+ glTranslatef(210,249*i,0);
+ ofNoFill();
+ ofDrawRectangle(5,5,sourceframesize.x+4,sourceframesize.y+4);
+ ofFill();
+
+ glTranslatef(7,7,0);
+
+ //draw video sources within case statement
+ switch(i){
+ case 0:{
+ if (captPreview){
+ if (useKinect){
+ if (texRGB.isAllocated()){
+ texRGB.draw(0,0,sourceframesize.x,sourceframesize.y);
+ }
+ }
+ else {
+ texRGB.draw(0,0,sourceframesize.x,sourceframesize.y);
+ }
+ }
+ break;
+ }
+ case 1:{
+ if (_player.isLoaded()){
+ if (ofGetElapsedTimef()-videostart<2.54f){
+ int amt=(ofGetElapsedTimef()-videostart)*100;
+ ofSetColor(amt);
+ }
+ _player.draw(0,0,sourceframesize.x,sourceframesize.y);
+ ofSetColor(255);
+ }
+ break;
+ }
+ case 2:{
+ glPushMatrix();
+ glScalef(sourcescale,sourcescale,sourcescale);
+ for (auto shape=segmenters.begin();shape!=segmenters.end();shape++){
+ shape->getPoly().draw();
+ }
+ glPopMatrix();
+ ofSetColor(255);
+ break;
+ }
+ }
+
+
+
+ //draw vectors within case statement
+
+ glPopMatrix();
+ }
+
+ glPushMatrix();
+ glTranslatef(550,5,0);
+ ofNoFill();
+ ofDrawRectangle(0,0,previewframesize.x+4,previewframesize.y+4);
+ ofFill();
+
+ if (perlinEnable) perlin->begin();
+ preview.draw(2,2,previewframesize.x,previewframesize.y);
+ if (perlinEnable) perlin->end();
+
+ glPopMatrix();
+
+ }
+
+ ofSetWindowTitle(ofToString(phase, 3)+" "+ofToString(ofGetFrameRate(), 2)+" fps laser points: "+ofToString(laser.get_numpts()));
+}
+
+static float phase=0.0f;
+static float lastframetime=0.0f;
+static float scale=10.0f;
+static float pixelWidth=0.05f;
+
+static int num=0;
+
+void ofApp::drawOutput(ofEventArgs & args){
+/*
+ if (perlinScale!=ps){
+ perlin->updateParameter("scale", perlinScale);
+ ps=perlinScale;
+ //ofLog()<<"set perlin scale to "<<perlinScale;
+ }
+ */
+ //this is mental, phase will update but scale will not
+ //it's not related to name, or order - generating a change per interval like this works differently
+ float interval=ofGetElapsedTimef()-lastframetime;
+ lastframetime=ofGetElapsedTimef();
+ phase+=interval*perlinSpeed;
+ scale+=interval*perlinScale;
+ pixelWidth+=interval*perlinPixelWidth;
+ perlin->updateParameter("phase", phase);
+ perlin->updateParameter("scale", scale);
+ perlin->updateParameter("fractionalWidthOfPixel",0.05f+(sin(ofGetElapsedTimef()*perlinPixelWidthSpeed)*perlinPixelWidth));
+
+ //prepare vectors
+
+ float vpos=ofGetHeight()/2;
+
+ float scale=ofGetHeight()*vScale;
+
+ ofPolyline osc;
+
+ osc.addVertex(0,vpos+(buffer[0]*scale));
+
+ float i=0.0f;
+ float step=ofGetWidth()/(hScale*48);
+
+ while (i<(ofGetWidth()+step)){
+ i+=max(1.0f,(float)step);
+ osc.lineTo(i,vpos+(buffer[(int)i]*scale));
+ }
+
+ //render output to fbo and output
+
+ preview.begin();
+
+ ofBackground(0);
+ ofSetColor(255,255,255);
+
+
+ ofClear(0,0,0,0);
+
+ vector<colourPolyline> contouroutput;
+
+ if (captEnable||(_player.isLoaded()&&playerEnable)){
+ if (video_outlines){
+ //use capture or player to generate outlines
+ if (captEnable){
+ colorImg.setFromPixels(texRGB.getPixels());
+ }
+ else if (_player.isLoaded()&&playerEnable){
+ colorImg.setFromPixels(_player.getPixels());
+ }
+ ofPoint scale=ofPoint(outputWindowSize.x/colorImg.getWidth(),outputWindowSize.y/colorImg.getHeight());
+ if (grayImage.getWidth()!=colorImg.getWidth()||grayImage.getHeight()!=colorImg.getHeight()){
+ grayImage.clear();
+ }
+ grayImage=colorImg;
+ if(contour_adaptive){
+ grayImage.adaptiveThreshold(grayImage.getWidth()*contour_adaptive_window, contour_threshold,false,true);
+ }
+ else {
+ grayImage.threshold(contour_threshold);
+ }
+ contourFinder.findContours(grayImage, 20, (grayImage.getWidth()*grayImage.getHeight())/3, 10, true);
+ for (int i = 0; i < contourFinder.nBlobs; i++){
+ colourPolyline shape;
+ for (auto& point:contourFinder.blobs[i].pts){
+ ofVec3f p=point*scale;
+ ofColor c=colorImg.getPixels().getColor(point.x,point.y);
+ shape.addVertex(p,c); //contour_useColour?c:ofColor(laser_R,laser_G,laser_B));
+ }
+ shape.simplify(contour_simplify);
+ contouroutput.push_back(shape);
+ }
+ }
+ }
+
+ vector<colourPolyline> svgoutput;
+
+ if (SVGLaserDraw||SVGVideoDraw){
+ if (!use_onset||onset_frame<onset_duration||shapes_randomise){
+ if (shapes_randomise){
+ //if (framecounter==0){
+ // select_random_shapes();
+ // framecounter=shapes_duration;
+ //}
+ select_random_shapes(shapes_duration,!use_onset||onset_frame<onset_duration);
+ for (auto s:shape_selection){
+ if (use_segmenter){
+ auto segments=segmenters[s].getSegments(segmenter_number,segmenter_length,phase);
+ for (auto segment=segments.begin();segment!=segments.end();segment++){
+ //polyOutput.push_back(colourPolyline(*segment,ofColor(laser_R,laser_G,laser_B)));
+ svgoutput.push_back(*segment);
+ }
+ }
+ else {
+ //polyOutput.push_back(colourPolyline(segmenters[s].getPoly(),ofColor(laser_R,laser_G,laser_B)));
+ svgoutput.push_back(segmenters[s].getPoly());
+ }
+ }
+ framecounter--;
+ }
+ else {
+ for (auto shape=segmenters.begin();shape!=segmenters.end();shape++){
+ if (use_segmenter){
+ auto segments=shape->getSegments(segmenter_number,segmenter_length,phase);
+ for (auto segment=segments.begin();segment!=segments.end();segment++){
+ //polyOutput.push_back(colourPolyline(*segment,ofColor(laser_R,laser_G,laser_B)));
+ svgoutput.push_back(*segment);
+ }
+ }
+ else {
+ //polyOutput.push_back(colourPolyline(shape->getPoly(),ofColor(laser_R,laser_G,laser_B)));
+ svgoutput.push_back(shape->getPoly());
+ }
+ }
+ }
+ if (contour_useColour){
+ vector<colourPolyline> newPolys;
+ for (auto p: svgoutput){
+ newPolys.push_back(colourPolyline((ofPolyline)p,ofColor(255,255,255))); //laser_R,laser_G,laser_B))) ;
+ }
+ svgoutput=newPolys;
+ }
+ }
+ }
+
+ vector<colourPolyline> textoutput;
+
+ if (textVideoDraw||textLaserDraw){
+ textoutput = text.getOutlines(ofGetWidth()/2,ofGetHeight()/2);
+ /*
+ if (textoutput.size()!=num) {
+ ofLog()<<textoutput.size()<<" text shapes";
+ num=textoutput.size();
+ }
+ */
+
+ }
+
+ ofSetLineWidth(lineWidth);
+
+ if (contoursVideoDraw) {
+ for (auto c:contouroutput) c.draw();
+ }
+ else if (SVGVideoDraw) {
+ for (auto s:svgoutput) s.draw();
+ }
+ else if (textVideoDraw){
+ for (auto i:textoutput) i.draw();
+ }
+ else if (captEnable){
+ texRGB.draw(0,0,outputWindowSize.x,outputWindowSize.y);
+ }
+ else if (_player.isLoaded()&&playerEnable){
+ if (ofGetElapsedTimef()-videostart<2.54f){
+ int amt=(ofGetElapsedTimef()-videostart)*100;
+ ofSetColor(amt);
+ }
+ _player.draw(0,0,outputWindowSize.x,outputWindowSize.y);
+ }
+
+ if (videoOscEnable) osc.draw();
+
+ preview.end();
+
+ if (perlinEnable) perlin->begin();
+ //shader.begin();
+ preview.draw(0,0);
+ //shader.end();
+ if (perlinEnable) perlin->end();
+
+ vector<colourPolyline> output;
+
+ if (vectorOscEnable) output.push_back(osc);
+ else if (contoursLaserDraw) output=contouroutput;
+ else if (SVGLaserDraw) output=svgoutput;
+ else if (textLaserDraw) output=textoutput;
+
+ //laser transformation comes here
+
+ vector <colourPolyline> transformedOutput;
+
+ if (use_rotate||use_scale){
+ ofMatrix4x4 rm = ofMatrix4x4::newIdentityMatrix();
+ rm.translate(-outputWindowSize.x/2,-outputWindowSize.y/2,0);
+ if (use_rotate){
+ rm.rotateRad(rotate_amt,0,0,1);
+ }
+ if (use_scale){
+ rm.scale(scale_amt,scale_amt,scale_amt);
+ }
+ rm.translate(outputWindowSize.x/2,outputWindowSize.y/2,0);
+ for (auto& shape:output){
+ transformedOutput.push_back(lineTransformer::polyLineTransform(rm,shape));
+ }
+ }
+ else {
+ transformedOutput=output;
+ }
+
+ //laser warping comes here
+
+ glm::vec2 src[]={
+ glm::vec2(0,0),
+ glm::vec2(ofGetWidth(),0),
+ glm::vec2(ofGetWidth(),ofGetHeight()),
+ glm::vec2(0,ofGetHeight())
+ };
+
+ glm::vec2 mp=glm::vec2(outputWindowSize.x/2,outputWindowSize.y/2);
+
+ glm::vec2 scaled_dest[]={
+ ((warpframe[0]-mp)*outputScale*outputOffsetScale)+mp,
+ ((warpframe[1]-mp)*outputScale*outputOffsetScale)+mp,
+ ((warpframe[2]-mp)*outputScale*outputOffsetScale)+mp,
+ ((warpframe[3]-mp)*outputScale*outputOffsetScale)+mp
+ };
+
+ ofMatrix4x4 scaled_warp =lineTransformer::getPerspectiveTransformMatrix(src,scaled_dest);
+ ofMatrix4x4 warp =lineTransformer::getPerspectiveTransformMatrix(src,warpframe);
+
+ vector <colourPolyline> warpedOutput;
+ vector <colourPolyline> scaledWarpedOutput;
+
+ for (auto s:transformedOutput){
+ warpedOutput.push_back(lineTransformer::polyLineTransform(warp,s));
+ scaledWarpedOutput.push_back(lineTransformer::polyLineTransform(scaled_warp,s));
+ }
+
+ ofPolyline safety;
+ safety.addVertex(safety_frame[0]);
+ safety.addVertex(safety_frame[1]);
+ safety.addVertex(safety_frame[2]);
+ safety.addVertex(safety_frame[3]);
+ //safety.close(); //addVertex(safety_frame[0]);
+
+ ofPolyline warpedScaledSafety=lineTransformer::polyLineTransform(scaled_warp,safety);
+
+ warpedScaledSafety.close();
+
+ vector <colourPolyline> clippedOutput;
+
+ if (use_safety){
+ vector <ofPolyline> masks;
+ masks.push_back(warpedScaledSafety); //create polyline
+
+ for (auto& poly: scaledWarpedOutput)
+ {
+ clipper.Clear();
+ clipper.addPolylines(masks, ClipperLib::ptClip);
+ vector <ofPolyline> shapes; //TODO make clipper clip colourpolylines
+ shapes.push_back(poly);
+ clipper.addPolylines(shapes,ClipperLib::ptSubject);
+ vector <ofPolyline> clipped;
+ //if (invert_mask){
+ // clipped = clipper.getClippedLines(ClipperLib::ctDifference);
+ //}else {
+ clipped = clipper.getClippedLines(ClipperLib::ctIntersection);
+ //}
+ for (auto& clip: clipped)
+ {
+ clip.simplify(contour_simplify);
+ clippedOutput.push_back(colourPolyline(clip,poly.getColourAt(0)));
+ }
+ }
+ }
+ else {
+ clippedOutput=scaledWarpedOutput;
+ }
+
+ //laser sorting comes here
+
+ if (edit_safety){
+ lineTransformer::drawWarpFrame(safety_frame);
+ laser.draw(warpedScaledSafety);
+ }
+ else if (clippedOutput.size()) {
+ laser.draw(clippedOutput);
+ }
+ else {
+ colourPolyline blank;
+ for (int i=0;i<100;i++){
+ blank.addVertex(ofGetWidth()/2,ofGetHeight()/2,0,0,0);
+ }
+ laser.draw(blank);
+ }
+
+ if (bDrawFrame){
+ lineTransformer::drawWarpFrame(warpframe);
+ }
+}
+
+void ofApp::onNoteOn(GistEvent &e){
+ //ofLog() << "<<NOTE ON>>";
+ onset_frame=0;
+ onset_number++;
+ //noteOnRadius = 100;
+};
+
+
+void ofApp::onNoteOff(GistEvent &e){
+ //ofLog() << "<<NOTE OFF>>";
+ //turn off?
+ //noteOnRadius = 0;
+};
+
+void ofApp::audioIn(float * input, int blockSize, int nChannels){
+ buffer.add(input,blockSize);
+
+ vector<float>buf;
+ buf.assign(&input[0],&input[blockSize-1]);
+ gist.processAudio(buf, blockSize, nChannels,SAMPLERATE);
+}
+
+
+void ofApp::select_random_shapes(float duration,bool generate){
+ float timedelta=ofGetElapsedTimef()-last_frame_time;
+ last_frame_time=ofGetElapsedTimef();
+ //track how long each shape has been selected
+ for (int i=0;i<shape_selection_durations.size();i++){
+ if (shape_selection_durations[i]>0.0f){
+ shape_selection_durations[i]=shape_selection_durations[i]-timedelta;
+ }
+ }
+
+ shape_selection.clear();
+
+ for (int i=0;i<shape_selection_durations.size();i++){
+ if (shape_selection_durations[i]>0.0f){
+ shape_selection.insert(i);
+ }
+ }
+ std::stringstream strom;
+ for (auto& s:shape_selection){
+ strom << s <<":"<<shape_selection_durations[s]<<" ";
+ }
+
+ //cout << timedelta <<": decay selection: "<<shape_selection.size()<<" shapes (" << strom.str() <<") \n";
+ if (generate){
+
+ while (shape_selection.size()<(segmenters.size()*shapes_amount)){
+ int selection=rand()%segmenters.size();
+ if (shape_selection.find(selection)==shape_selection.end()){
+ shape_selection_durations[selection]=duration+ofRandom(1.0f);
+ shape_selection.insert(selection);
+ }
+ }
+ std::stringstream strm;
+ for (auto& s:shape_selection){
+ strm << s <<":"<<shape_selection_durations[s]<<" ";
+ }
+ }
+ //cout << "random selection: "<<shape_selection.size()<<" shapes (" << strm.str() <<") \n";
+}
+
+
+//--------------------------------------------------------------
+void ofApp::exit() {
+
+
+}
+
+
+
+//--------------------------------------------------------------
+void ofApp::outputKeyPressed(ofKeyEventArgs &args){
+
+ if (args.key=='f') {
+ ofToggleFullscreen();
+ preview.allocate(ofGetWidth(),ofGetHeight());
+ }
+
+ keyPressed(args);
+
+
+}
+
+void ofApp::keyPressed(ofKeyEventArgs &args){
+ if (args.key==OF_KEY_COMMAND){
+ commandPressed=true;
+ }
+
+ switch(args.key){
+ case '`':{
+ bShowPositionInterface=!bShowPositionInterface;
+ break;
+ }
+ case 'w':{
+ bDrawFrame=!bDrawFrame;
+ break;
+ }
+ case 'd':{
+ default_settings();
+ break;
+ }
+ case 's':{
+ save_settings();
+ break;
+ }
+ case '1':{
+ scale=1.0f;
+ break;
+ }
+ case '2':{
+ scale=2.0f;
+ break;
+ }
+ case '3':{
+ scale=3.0f;
+ break;
+ }
+ case '4':{
+ scale=4.0f;
+ break;
+ }
+ case '5':{
+ scale=5.0f;
+ break;
+ }
+ case '6':{
+ scale=6.0f;
+ break;
+ }
+ case '7':{
+ scale=7.0f;
+ break;
+ }
+ case '8':{
+ scale=8.0f;
+ break;
+ }
+ case '9':{
+ scale=9.0f;
+ break;
+ }
+ }
+}
+
+//--------------------------------------------------------------
+void ofApp::outputKeyReleased(ofKeyEventArgs &args){
+ keyReleased(args);
+}
+
+void ofApp::keyReleased(ofKeyEventArgs &args){
+ if (args.key==OF_KEY_COMMAND){
+ commandPressed=false;
+ }
+}
+
+
+//--------------------------------------------------------------
+void ofApp::mouseMoved(int x, int y ){
+}
+
+//--------------------------------------------------------------
+void ofApp::outputMouseDragged(ofMouseEventArgs & args){
+ if (select_warpframe>-1){
+ warpframe[select_warpframe]=glm::vec2(args.x,args.y);
+ }
+ if (select_safetyframe>-1){
+ safety_frame[select_safetyframe]=glm::vec3(args.x,args.y,0);
+ }
+
+}
+
+void ofApp::mouseDragged(int x, int y, int button){
+ if (bOutputSelected){
+ if (commandPressed){
+ float startDistance=((outputPosition*guiScale)+ofPoint(300,300)).distance(outputSelectionPoint);
+ float currentDistance=((outputPosition*guiScale)+ofPoint(300,300)).distance(ofPoint(x,y));
+ outputOffsetScale=currentDistance/startDistance;
+ }
+ else {
+ outputOffset=ofPoint(x,y)-outputSelectionPoint;
+ laser.set_centre(ofPoint(
+ outputPosition.x+(outputOffset.x/guiScale),
+ outputPosition.y+(outputOffset.y/guiScale)
+ ));
+ }
+ }
+}
+
+//--------------------------------------------------------------
+void ofApp::outputMousePressed(ofMouseEventArgs & args){
+ for (int i=0;i<4;i++){
+ if (ofPoint(args.x,args.y).distance(warpframe[i])<25){
+ select_warpframe=i;
+ }
+ }
+ if (edit_safety){
+ for (int i=0;i<4;i++){
+ if (ofPoint(args.x,args.y).distance(safety_frame[i])<25){
+ select_safetyframe=i;
+ }
+ }
+ }
+}
+
+void ofApp::mousePressed(int x, int y, int button){
+ if (bShowPositionInterface){
+ if (x>(300+((outputPosition.x-((outputWindowSize.x/2)*outputScale))*guiScale))&&
+ x<(300+((outputPosition.x+((outputWindowSize.x/2)*outputScale))*guiScale))&&
+ y>(300+((outputPosition.y-((outputWindowSize.y/2)*outputScale))*guiScale))&&
+ y<(300+((outputPosition.y+((outputWindowSize.y/2)*outputScale))*guiScale))
+ ){
+ outputSelectionPoint=ofPoint(x,y);
+ bOutputSelected=true;
+ }
+ }
+
+}
+
+//--------------------------------------------------------------
+void ofApp::outputMouseReleased(ofMouseEventArgs & args){
+ select_warpframe=-1;
+ select_safetyframe=-1;
+}
+
+void ofApp::mouseReleased(int x, int y, int button){
+ if (bOutputSelected){
+ if (commandPressed){
+ outputScale*=outputOffsetScale;
+ }
+ else {
+ outputPosition+=outputOffset/guiScale;
+ }
+ bOutputSelected=false;
+ outputOffset=ofPoint(0,0);
+ outputOffsetScale=1.0f;
+ }
+
+}
+
+//--------------------------------------------------------------
+void ofApp::mouseEntered(int x, int y){
+
+}
+
+//--------------------------------------------------------------
+void ofApp::mouseExited(int x, int y){
+
+}
+
+//--------------------------------------------------------------
+void ofApp::outputWindowResized(ofResizeEventArgs &resizeargs){
+
+}
+
+void ofApp::windowResized(int w, int h){
+
+}
+
+
+
+//--------------------------------------------------------------
+void ofApp::dragEvent(ofDragInfo dragInfo){
+ std::string filename=dragInfo.files[0];
+ for (int i=0;i<4;i++){
+ if (dragInfo.position.x>215&&dragInfo.position.x<540
+ &&dragInfo.position.y>249*i+5&&dragInfo.position.y<249*i+249){
+ ofLog()<<"slot "<<i<<" received "<<filename<<" : "<<dragInfo.position.x;
+
+ if (i==1) {
+ if (_player.load(filename)){
+ videostart=ofGetElapsedTimef();
+ }
+ }
+
+ if (i==2) {
+ svg.load(filename);
+ vector <ofPath> imagepaths= svg.getPaths();
+
+ std::stringstream strm;
+
+ if (imagepaths.size()){
+ segmenters.clear();
+ shape_selection_durations.clear();
+ for (auto& path:imagepaths){
+ path.setPolyWindingMode(OF_POLY_WINDING_ODD);
+
+ vector <ofPolyline> outlines= path.getOutline();
+ for (auto& outline:outlines){
+ strm << outline.size() << "->";
+ outline.simplify(contour_simplify);
+ strm << outline.size() << " ";
+ segmenters.push_back(colourLineSegmenter(outline,path.getStrokeColor()));
+ shape_selection_durations.push_back(0.0f);
+ }
+
+ strm << " , ";
+ }
+
+ std::stringstream strom;
+
+ shape_selection.clear();
+ while (shape_selection.size()<(segmenters.size()*shapes_amount)){
+ int selection=(int)ofRandom(0,segmenters.size());
+ shape_selection.insert(selection);
+ }
+ for (auto s:shape_selection){
+ float spawn=(ofRandom(0,(float)shapes_duration));
+ shape_selection_durations[s]=spawn;
+ strom << s << ":"<<spawn<<" ";
+ }
+ last_frame_time=ofGetElapsedTimef();
+ //cout << "SVG: selected paths [ "<<strom.str() << " ]" <<std::endl;
+ //cout << "SVG: found " << imagepaths.size() << " paths with " << segmenters.size() << " shapes [ " << strm.str() << " ]" <<std::endl;
+ //select_random_shapes(shapes_duration);
+ }
+ }
+
+ if (i==3) {
+ text.loadfile(filename);
+ }
+ }
+
+ }
+
+} \ No newline at end of file