#pragma once #include "ofMain.h" #include "ofxSvg.h" #include "ofxGui.h" #include "ofxXmlSettings.h" #include "ofxHelios.h" #include "lineTransformer.h" #include "colourPolyline.h" class star{ public: star(ofVec2f p,ofVec2f v,float l){ pos=p; vel=v; birthday=ofGetElapsedTimef(); lifespan=l; } void update(vector& stars){ pos+=vel; } ofVec2f pos; ofVec2f vel; float birthday; float lifespan; }; class starSystem{ public: vector stars; ofVec2f centre; float radius; float rate; float speed; float lifespan; float agevar; float last; starSystem(ofVec2f c=ofVec2f(0,0), float _rad=100,float r=0.5,float s=5.0,float l=5.0,float v=1.0){ init(c,_rad,r,s,l,v); } void init(ofVec2f c, float _rad,float r,float s,float l,float v){ centre=c; radius=_rad; rate=r; speed=s; lifespan=l; agevar=v; } void update(){ float now=ofGetElapsedTimef(); float segment=now-last; last=now; for(auto it = stars.begin(); it != stars.end();) { if(now-it->birthday>it->lifespan){ //ofLog()<<"erase star"; it = stars.erase(it); } else { //ofLog()<<"update star"; it->update(stars); ++it; } } if (ofRandom(rate) getPoints(){ float now=ofGetElapsedTimef(); vector o; for(auto& s:stars){ colourPolyline l; //ofLog()<<"get star"; l.addVertex(centre.x+s.pos.x,centre.y+s.pos.y,ofColor(1.0f-((now-s.birthday)/s.lifespan)*128.0f)); l.addVertex(centre.x+s.pos.x+1,centre.y+s.pos.y+1,ofColor(1.0f-((now-s.birthday)/s.lifespan)*128.0f)); o.push_back(l); } return o; } }; class glyph{ public: glyph(char c,float w,vector lines){ glyph(c,w,lines,ofColor(0,0,0)); } glyph(char c,float w,vector lines,ofColor col){ code=c; width=w; outline=lines; colour=col; } void draw(float x, float y){ ofSetColor(colour); ofPushMatrix(); ofTranslate(x,y); for (auto& v:outline) v.draw(); ofPopMatrix(); } void randomiseColour(){ colour=ofColor::fromHsb(ofRandom(255.0),225,255); } char code; float width; vector outline; ofColor colour; }; class glyphWord{ public: glyphWord(){amount=1.0f;} vector glyphs; float amount; }; class glyphbanner{ ofXml SVGFont; vector words; vector outlines; ofVec2f centre; float lastUpdateTime; float playhead; float enspace; vector palette; struct { vector balanced={ ofColor::fromHex(0xE27D60), ofColor::fromHex(0x085DCB), ofColor::fromHex(0xE8A87C), ofColor::fromHex(0xC38D9E), ofColor::fromHex(0x41B3A3) }; vector uneasy={ ofColor::fromHex(0x2154B9), ofColor::fromHex(0xC45A62), ofColor::fromHex(0x95A28A), ofColor::fromHex(0x98546D), ofColor::fromHex(0xE9DADA), ofColor::fromHex(0x9FF3E9), ofColor::fromHex(0xD07B37), ofColor::fromHex(0x741710), ofColor::fromHex(0x102ADC), ofColor::fromHex(0x9FA1AC) }; }palettes; vector split(string s) { size_t pos_start = 0, pos_end; string token; vector res; while ((pos_end = s.find (" ", pos_start)) != string::npos) { token = s.substr (pos_start, pos_end - pos_start); pos_start = pos_end + 1; res.push_back (token); } res.push_back (s.substr (pos_start)); return res; } public: glyphbanner(){ palette=palettes.uneasy; }; void init(string message){ createWords(message); lastUpdateTime=ofGetElapsedTimef(); playhead=0.0f; } int length(){ int l=0; for (auto& w:words) { l+=w.glyphs.size(); } return l+max(0,(int)words.size()-1); } float width(){ float _w=0.0f; for (auto& w:words) { for (auto& g:w.glyphs) _w+=g.width; } return _w+max((float)(words.size()-1)*enspace,0.0f); } int glyphCount(){ int c=0; for (auto& w:words){ c+=w.glyphs.size(); } return c; } string text(){ string s; for (auto& w:words) { for (auto& g:w.glyphs) s+=ofToString(g.code); } return s; } void loadFont(filesystem::path path){ if( SVGFont.load(path) ){ vector w=words; clear(); createWords(w); enspace=getGlyph(' ').width; ofLog()<<"loaded "< m=split(message); for (auto& word: m){ glyphWord w; for (auto& c: word){ w.glyphs.push_back(getGlyph(c, usePalette? palette[ofRandom(palette.size())]: //112->231 hue sat 0->255 brightness 255 ofColor::fromHsb(ofRandom(119)+112,ofRandom(255),255) )); } words.push_back(w); } } void createWords(vector _words){ clear(); for (auto& _w:_words) { glyphWord w; for (auto& g: _w.glyphs){ w.glyphs.push_back(getGlyph(g.code,g.colour)); } words.push_back(w); } } glyph getGlyph(char c,ofColor col=ofColor(255,255,255)){ vector shapes; ofPolyline shape; string elementPath = "/svg/defs/font/glyph[@unicode='"+ofToString(c)+"']"; if(SVGFont.findFirst(elementPath) == 0 ){ elementPath = "/svg/defs/font/glyph[@unicode='?']"; } ofXml xmlElement = SVGFont.findFirst(elementPath); float charWidth = ofToFloat(xmlElement.getAttribute("horiz-adv-x").getValue()); vector splitGlyphPath = ofSplitString(xmlElement.getAttribute("d").getValue(), " ");//glyph path data in SVG looks like this: "M 139 -9.45 L 230 18.9 L 299 22.1 L 227 25.2" for(int i=0; i0){ theword++; } segment=(((float)theletter+words[theword].glyphs.size()+playhead-int(playhead))/words[theword].glyphs.size()); } //calculate params for word/letter anim for (int i=0;i& getOutlines(float s=1.0f){ outlines.clear(); float p=(-width())/2; for (auto& w:words){ for (auto& g:w.glyphs){ if (w.amount>0.0f){ for (auto& o:g.outline){ auto q=o; q.scale(s,-s); q.translate(glm::vec3(p*s,-ofGetHeight()/3,0)); outlines.push_back(colourPolyline(q,g.colour*w.amount)); } } p+=g.width; } p+=enspace; } return outlines; } }; class ofApp : public ofBaseApp{ public: void setup(); void update(); void draw(); void exit(); void keyPressed(ofKeyEventArgs &keyargs); void keyReleased(int key); void mouseMoved(int x, int y ); void mouseDragged(int x, int y, int button); void mousePressed(int x, int y, int button); void mouseReleased(int x, int y, int button); void mouseEntered(int x, int y); void mouseExited(int x, int y); void windowResized(int w, int h); void dragEvent(ofDragInfo dragInfo); void gotMessage(ofMessage msg); void default_settings(); void save_settings(); ofxHelios laser; ofDirectory fonts; int currentFont; string displaytext; glyphbanner banner; ofxPanel starsgui; ofParameter stars_x; ofParameter stars_y; ofParameter stars_radius; ofParameter stars_speed; ofParameter stars_life; ofxPanel textgui; ofParameter laser_scale; ofParameter laser_pos_x; ofParameter laser_pos_y; ofParameter text_speed; //======= laser gui ofxPanel lasergui; ofParameter laser_power; ofParameter laser_intensity; ofParameter laser_points; ofParameter laser_subdivide; ofParameter laser_blank_num; ofParameter laser_max_angle; ofxXmlSettings XML; starSystem stars; glm::vec2 warpframe[4]; int select_warpframe; bool bDrawFrame; ofPoint outputWindowSize; ofPoint outputPosition; float outputScale; };