summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Redfern <redfernt@gmail.com>2023-04-19 09:46:58 +0100
committerTim Redfern <redfernt@gmail.com>2023-04-19 09:46:58 +0100
commitbeaeeb0a47d1e4a0b62264263dd319dc49d6a2f9 (patch)
tree5e85a5e8e8a26690b5a34ed8524ce9fa1c066ae3
parentc8e83cad88fb1ac9ababbee5673e910befcd2d95 (diff)
add vectorplugins unit
-rw-r--r--nextus/src/vectorPlugin.cpp192
-rw-r--r--nextus/src/vectorPlugin.h114
2 files changed, 306 insertions, 0 deletions
diff --git a/nextus/src/vectorPlugin.cpp b/nextus/src/vectorPlugin.cpp
new file mode 100644
index 0000000..03b7eaa
--- /dev/null
+++ b/nextus/src/vectorPlugin.cpp
@@ -0,0 +1,192 @@
+#include "vectorPlugin.h"
+
+void svgPanel::load(string filename){
+
+ ofxSVG svg;
+ svg.load(filename);
+
+ //normalise the SVG paths to a square format
+
+ float dimension=max(svg.getWidth(),svg.getHeight());
+
+ glm::vec2 src[]={
+ glm::vec2(0,0),
+ glm::vec2(dimension,0),
+ glm::vec2(dimension,dimension),
+ glm::vec2(0,dimension)
+ };
+
+ glm::vec2 dst[]={ //PONK coords
+ glm::vec2(-1,-1),
+ glm::vec2(1,-1),
+ glm::vec2(1,1),
+ glm::vec2(-1,1)
+ };
+
+ ofMatrix4x4 xform=lineTransformer::getPerspectiveTransformMatrix(src,dst);
+
+ 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); //?necessary
+ //strm << outline.size() << " ";
+ ofPolyline xformed=lineTransformer::polyLineTransform(xform,outline);
+ ofColor c1=path.getStrokeColor();
+ ofColor colour=path.getFillColor();
+ if (colour.r==colour.g&&colour.g==colour.b){
+ colour=c1;
+ }
+
+ segmenters.push_back(
+ colourLineSegmenter(
+ xformed,
+ 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);
+ ofLog()<<"loaded SVG "<<filename<<", "<<segmenters.size()<<" paths";
+
+ }
+ else {
+ ofLog()<<"could not load SVG "<<filename;
+ }
+}
+
+void svgPanel::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){
+
+ //the toggle was pressed
+ //simulate a button
+ generate_shapes=false;
+
+ 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";
+}
+
+
+vector<colourPolyline> svgPanel::getAllLines(){
+ vector<colourPolyline> output;
+ for (auto& shape:segmenters){
+ output.push_back(shape.getPoly());
+ }
+ return output;
+}
+
+vector<colourPolyline> svgPanel::getLines(){
+ vector<colourPolyline> output;
+ return output;
+ //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,generate_shapes); //from audio !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++){
+ //output.push_back(colourPolyline(*segment,ofColor(laser_R,laser_G,laser_B)));
+ output.push_back(*segment);
+ }
+ }
+ else {
+ //output.push_back(colourPolyline(segmenters[s].getPoly(),ofColor(laser_R,laser_G,laser_B)));
+ output.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++){
+ //output.push_back(colourPolyline(*segment,ofColor(laser_R,laser_G,laser_B)));
+ output.push_back(*segment);
+ }
+ }
+ else {
+ //output.push_back(colourPolyline(shape->getPoly(),ofColor(laser_R,laser_G,laser_B)));
+ output.push_back(shape->getPoly());
+ }
+ }
+ }
+ /*
+ this should happen at output stage?
+
+ if (contour_useColour){
+ vector<colourPolyline> newPolys;
+ for (auto p: output){
+ newPolys.push_back(colourPolyline((ofPolyline)p,ofColor(laser_R,laser_G,laser_B))) ;
+ }
+ output=newPolys;
+ }
+ */
+ //}
+
+} \ No newline at end of file
diff --git a/nextus/src/vectorPlugin.h b/nextus/src/vectorPlugin.h
new file mode 100644
index 0000000..8a3f557
--- /dev/null
+++ b/nextus/src/vectorPlugin.h
@@ -0,0 +1,114 @@
+#pragma once
+
+#include "ofMain.h"
+#include "ofxGui.h"
+#include "ofxSVG.h"
+#include "ofxClipper.h"
+#include "ofxPONK.h"
+#include "lineTransformer.h"
+#include "lineSegmenter.h"
+
+static ofVec2f DISPLAYSIZE(200,200);
+
+class vectorPanel {
+ public:
+ vectorPanel(
+ string _title="",
+ ofVec2f _size=DISPLAYSIZE,
+ ofVec2f _pos=ofPoint(5,5))
+ {
+ size=_size;
+ position=_pos;
+ panel.setup(_title,"",0,size.y+5);
+ }
+ void draw(){
+ ofPushMatrix();
+ ofTranslate(position);
+ ofSetColor(255);
+ ofNoFill();
+ ofDrawRectangle(0,0,size.x,size.y);
+ panel.draw();
+ ofPushMatrix();
+ ofTranslate(size/2);
+ ofScale(DISPLAYSIZE.x/2.0f);
+ vector<colourPolyline> lines=getLines();
+ for (auto& line:lines){
+ line.draw();
+ }
+ ofPopMatrix();
+ ofPopMatrix();
+ }
+ virtual vector<colourPolyline> getLines() {};
+
+ protected:
+ ofVec2f size;
+ ofPoint position;
+ ofxPanel panel;
+};
+
+class defaultPanel: public vectorPanel{
+ //the minimum panel that can be instanced
+ public:
+ defaultPanel(
+ string _title="",
+ ofVec2f _size=DISPLAYSIZE,
+ ofVec2f _pos=ofPoint(5,5)
+ ) : vectorPanel(_title,_size,_pos){}
+ vector<colourPolyline> getLines(){
+ vector<colourPolyline> output;
+ return output;
+ }
+};
+
+class svgPanel: public vectorPanel{
+ public:
+ svgPanel(
+ string _title="",
+ ofVec2f _size=DISPLAYSIZE,
+ ofVec2f _pos=ofPoint(5,5)
+ ) : vectorPanel(_title,_size,_pos){
+ //panel.add(ofxLabel().setup("SHAPES",""));
+ panel.add(shapes_randomise.set("randomise",false));
+ panel.add(generate_shapes.set("generate",false));
+ panel.add(shapes_amount.set("amount",0.2,0.0,1.0));
+ panel.add(shapes_duration.set("duration",5.0,0,10.0));
+ panel.add(use_segmenter.set("SEGMENTER",false));
+ panel.add(shapes_randomise.set("randomise",false));
+ panel.add(segmenter_speed.set("speed",0.2,-1.0,1.0));
+ panel.add(segmenter_length.set("length",0.2,0.0,1.0));
+ panel.add(segmenter_number.set("number",1,1,8));
+ }
+ void load(string filename);
+ void select_random_shapes(float duration,bool generate);
+ vector<colourPolyline> getAllLines();
+ vector<colourPolyline> getLines();
+
+ private:
+ //ofxFloatSlider contour_simplify;
+
+ //svg gui
+ ofParameter<bool> shapes_randomise;
+ ofParameter<bool> generate_shapes; //manual version of audio driven version
+ ofParameter<float> shapes_amount;
+ ofParameter<float> shapes_duration;
+ //ofxToggle use_mask;
+ //ofxToggle invert_mask;
+
+ //segmenter
+ ofParameter<bool> use_segmenter;
+ //ofxToggle colour_segmenter;
+ ofParameter<float> segmenter_speed;
+ ofParameter<float> segmenter_length;
+ ofParameter<int> segmenter_number;
+
+
+ vector <colourLineSegmenter> segmenters;
+ vector <float> shape_selection_durations;
+ set <int> shape_selection;
+ int framecounter;
+ float phase; //,prev_time; //to calculate phase
+ //float rotate_amt;
+ //float scale_phase,scale_amt;
+
+ float last_frame_time;
+}; \ No newline at end of file