diff options
Diffstat (limited to 'rotord/rotor.h')
| -rwxr-xr-x | rotord/rotor.h | 73 |
1 files changed, 60 insertions, 13 deletions
diff --git a/rotord/rotor.h b/rotord/rotor.h index 66ad804..7e623b2 100755 --- a/rotord/rotor.h +++ b/rotord/rotor.h @@ -113,6 +113,7 @@ namespace Rotor { }; class Time_spec{ public: + Time_spec(){}; Time_spec(float _time,float _framerate){ time=_time; framerate=_framerate; }; float time; float framerate; @@ -120,14 +121,17 @@ namespace Rotor { return Time_spec(time-(1.0f/framerate),framerate); } }; - class Frame_spec{ + class Frame_spec: public Time_spec{ public: Frame_spec(float _time,float _framerate,int _w,int _h){ time=_time; framerate=_framerate; w=_w; h=_h;}; - float time; //this hould probably be implemented with a num/denom scheme eventually for accuracy - float framerate; + //float time; //this hould probably be implemented with a num/denom scheme eventually for accuracy + //float framerate; int h,w; - Frame_spec lastframe(){ - return Frame_spec(time-(1.0f/framerate),framerate,w,h); + //Frame_spec lastframe(){ + // return Frame_spec(time-(1.0f/framerate),framerate,w,h); + //} + int frame(){ + return (int)((time*framerate)+0.5); //rounded to the nearest frame } }; class Image{ @@ -515,16 +519,19 @@ namespace Rotor { Luma_levels(){LUT=nullptr;image=nullptr;}; Luma_levels(map<string,string> &settings) { base_settings(settings); + levels_settings(settings); + image=new Image(); + }; + ~Luma_levels(){if (LUT) {delete[] LUT;} if (image) {delete image;} }; + void levels_settings(map<string,string> &settings){ black_in=find_setting(settings,"black_in",0.0f); white_in=find_setting(settings,"white_in",1.0f); gamma=find_setting(settings,"gamma",1.0f); black_out=find_setting(settings,"black_out",0.0f); white_out=find_setting(settings,"white_out",1.0f); LUT=nullptr; - image=new Image(); generate_LUT(); - }; - ~Luma_levels(){if (LUT) {delete[] LUT;} if (image) {delete image;} }; + } void generate_LUT(){ if (LUT) delete[] LUT; LUT=new unsigned char[256]; @@ -549,12 +556,13 @@ namespace Rotor { return nullptr; } Luma_levels* clone(map<string,string> &_settings) { return new Luma_levels(_settings);}; - private: + protected: unsigned char *LUT; Image *image; + private: float black_in,white_in,gamma,black_out,white_out; }; - class Echo_trails: public Image_node { + class Echo_trails: public Luma_levels { //draw trail frames additively that fade off over time //the hard thing here is how to cache frames, if its done cleverly it could have no impact when //used linearly @@ -570,31 +578,70 @@ namespace Rotor { //load new frames //do the calculations + //new set of pointers? or track frames by absolute frame number? + //with relative pointers and switching frames, could use auto_ptr? + + //this cache mechanism should maybe be inheritable too? + + //it could be hugely beneficial to only do the LUT once? + //although maybe the way to do the fading is to have a LUT for each frame? + //2 inputs - "This frame" and "keyed" //hmm, that is clumsy, could it inherit from luma_levels + + //or is it actually best to use alpha keying after all! public: Echo_trails(){}; Echo_trails(map<string,string> &settings) { base_settings(settings); duration=find_setting(settings,"duration",1.0f); number=find_setting(settings,"number",1); + levels_settings(settings); image=new Image(); + w=h=0; }; ~Echo_trails(){if (image) {delete image;} }; Image *get_output(const Frame_spec &frame){ + //cache frames + if (frame.w!=w||frame.h!=h){ //or framerate changed? + //clear cache and start over + images.clear(); + //calculate frame interval + w=frame.w; + h=frame.h; + interval=(int)((duration/number)*frame.framerate); + total=interval*number; + } + int thisframe=frame.frame(); + //reorder cache and throw out any obsolete frames + auto i = std::begin(images); + while (i != std::end(images)) { + // check if the image is in the range we need + if (thisframe-i.first>total||thisframe-i.first<0) + i = images.erase(i); + else + ++i; + } image->setup(frame.w,frame.h); if (image_inputs.size()) { if (image_inputs[0]->connection){ - return image; + if (LUT) { + Image *in= (((Image_node*)image_inputs[0]->connection)->get_output(frame)); + for (int i=0;i<frame.w*frame.h*3;i++){ + image->RGBdata[i]=LUT[in->RGBdata[i]]; + } + return image; + } } } return nullptr; } Echo_trails* clone(map<string,string> &_settings) { return new Echo_trails(_settings);}; private: - Image *image; float duration; - int number; + int number,w,h; + int interval,total; //number of frames between displayed echoes + unordered_map<int,Image> images; }; //------------------------------------------------------------------- class Node_factory{ |
