summaryrefslogtreecommitdiff
path: root/rotord/rotor.h
diff options
context:
space:
mode:
Diffstat (limited to 'rotord/rotor.h')
-rwxr-xr-xrotord/rotor.h79
1 files changed, 59 insertions, 20 deletions
diff --git a/rotord/rotor.h b/rotord/rotor.h
index d5dc60e..e128fd5 100755
--- a/rotord/rotor.h
+++ b/rotord/rotor.h
@@ -2,6 +2,8 @@
nodes can have many inputs but only 1 output
image nodes that use an image as input can pass on the incoming image only if its unchanged.
+
+TODO - parameter class that automatically links variable to correctly named inputs
*/
#include <unordered_map>
@@ -210,6 +212,18 @@ namespace Rotor {
}
return *this;
}
+ Image & add_wrap(const Image &other) {
+ if (other.w!=w||other.h!=h) {
+ cerr<<"Rotor: cannot add images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl;
+ }
+ else {
+ for (int i=0;i<w*h*3;i++){
+ //creates rainbow overload
+ RGBdata[i]=(unsigned char)(((int)other.RGBdata[i]+(int)RGBdata[i]));
+ }
+ }
+ return *this;
+ }
Image * operator*(const float &amount) {
Image *other=new Image();
other->setup(w,h);
@@ -264,11 +278,7 @@ namespace Rotor {
public:
Parameter_input(const string &_param,const string &_desc): Signal_input(_desc),receiver(nullptr),parameter(_param){};
float *receiver;
- void update(const Time_spec& time){ //gets input and updates variable
- if (receiver){
- *receiver=((Signal_node*)connection)->get_output(time);
- }
- }
+ void update(const Time_spec& time);
string parameter;
};
class Node{
@@ -304,7 +314,8 @@ namespace Rotor {
public:
vector<Image_input*> image_inputs; //image node also has image inputs and outputs
void create_image_input(const string &description) {image_inputs.push_back(new Image_input(description));};
- virtual Image *get_output(const Frame_spec &frame)=0;
+ Image *get_output(const Frame_spec &frame) { update_params((Time_spec)frame); return output(frame); };
+ virtual const Image *output(const Frame_spec &frame)=0;
Image *get_preview(const Frame_spec &frame);
Image *image; //this can be privately allocated or just passed on as the node see fit
private:
@@ -382,6 +393,9 @@ namespace Rotor {
if (_op=="<") op=COMPARISON_Less;
if (_op==">=") op=COMPARISON_Greater_or_equal;
if (_op=="<=") op=COMPARISON_Less_or_equal;
+ for (auto p:parameter_inputs){
+ if (p->parameter=="value") p->receiver=&value;
+ }
};
Comparison* clone(map<string,string> &_settings) { return new Comparison(_settings);};
const float output(const Time_spec &time) {
@@ -432,6 +446,9 @@ namespace Rotor {
if (_op=="*") op=ARITHMETIC_multiply;
if (_op=="/") op=ARITHMETIC_divide;
if (_op=="%") op=ARITHMETIC_modulo;
+ for (auto p:parameter_inputs){
+ if (p->parameter=="value") p->receiver=&value;
+ }
};
Arithmetic* clone(map<string,string> &_settings) { return new Arithmetic(_settings);};
const float output(const Time_spec &time) {
@@ -468,6 +485,9 @@ namespace Rotor {
Signal_divide(map<string,string> &settings) {
base_settings(settings);
divide_amount=ofToFloat(find_setting(settings,"amount"));
+ for (auto p:parameter_inputs){
+ if (p->parameter=="divide_amount") p->receiver=&divide_amount;
+ }
};
Signal_divide* clone(map<string,string> &_settings) { return new Signal_divide(_settings);};
const float output(const Time_spec &time) {
@@ -537,7 +557,7 @@ namespace Rotor {
};
~Testcard(){ delete image;};
Testcard* clone(map<string,string> &_settings) { return new Testcard(_settings);};
- Image *get_output(const Frame_spec &frame){
+ Image *output(const Frame_spec &frame){
if (image->setup(frame.w,frame.h)) {
}
@@ -567,7 +587,7 @@ namespace Rotor {
};
~Invert(){ delete image;};
Invert* clone(map<string,string> &_settings) { return new Invert(_settings);};
- Image *get_output(const Frame_spec &frame){
+ Image *output(const Frame_spec &frame){
if (inputs.size()) {
if (image_inputs[0]->connection){
if (inputs[0]->connection) {
@@ -602,7 +622,7 @@ namespace Rotor {
exporter=new libav::Exporter();
};
~Video_output(){ delete exporter; };
- Image *get_output(const Frame_spec &frame){
+ Image *output(const Frame_spec &frame){
if (image_inputs[0]->connection) {
return ((Image_node*)(image_inputs[0]->connection))->get_output(frame);
}
@@ -616,21 +636,21 @@ namespace Rotor {
libav::Exporter *exporter;
libav::Audioloader audioloader;
};
- class Video_input: public Image_node {
+ class Video_loader: public Image_node {
//video input using gstreamer
//seems slow
//TODO: scaling
public:
- Video_input(){};
- Video_input(map<string,string> &settings) {
+ Video_loader(){};
+ Video_loader(map<string,string> &settings) {
base_settings(settings);
player=new ofGstVideoPlayer();
image=new Image();
};
- ~Video_input(){ delete player; delete image;};
+ ~Video_loader(){ delete player; delete image;};
bool load(const string &filename);
- Image *get_output(const Frame_spec &frame);
- Video_input* clone(map<string,string> &_settings) { return new Video_input(_settings);};
+ Image *output(const Frame_spec &frame);
+ Video_loader* clone(map<string,string> &_settings) { return new Video_loader(_settings);};
private:
ofGstVideoPlayer *player;
Image *image;
@@ -644,7 +664,7 @@ namespace Rotor {
};
~Video_cycler(){};
bool load(const string &filename);
- Image *get_output(const Frame_spec &frame){
+ Image *output(const Frame_spec &frame){
int which_input=0;
if (inputs[0]->connection) {
which_input=((int)((Signal_node*)inputs[0]->connection)->get_output((Time_spec)frame))%image_inputs.size();
@@ -667,6 +687,13 @@ namespace Rotor {
base_settings(settings);
levels_settings(settings);
image=new Image();
+ for (auto p:parameter_inputs){
+ if (p->parameter=="black_in") p->receiver=&black_in;
+ if (p->parameter=="white_in") p->receiver=&white_in;
+ if (p->parameter=="gamma") p->receiver=&gamma;
+ if (p->parameter=="black_out") p->receiver=&black_out;
+ if (p->parameter=="white_out") p->receiver=&white_out;
+ }
};
~Luma_levels(){if (LUT) {delete[] LUT;} if (image) {delete image;} };
void levels_settings(map<string,string> &settings){
@@ -695,7 +722,7 @@ namespace Rotor {
out.RGBdata[i]=LUT[in.RGBdata[i]];
}
}
- Image *get_output(const Frame_spec &frame){
+ Image *output(const Frame_spec &frame){
if (image_inputs.size()) {
if (image_inputs[0]->connection){
if (LUT) {
@@ -710,7 +737,6 @@ namespace Rotor {
protected:
unsigned char *LUT;
Image *image;
- private:
float black_in,white_in,gamma,black_out,white_out;
};
class Echo_trails: public Luma_levels {
@@ -751,9 +777,20 @@ namespace Rotor {
levels_settings(settings);
image=new Image();
lastframe=-1;
+ mode=find_setting(settings,"mode",0.0f);
+ for (auto p:parameter_inputs){
+ if (p->parameter=="black_in") p->receiver=&black_in;
+ if (p->parameter=="white_in") p->receiver=&white_in;
+ if (p->parameter=="gamma") p->receiver=&gamma;
+ if (p->parameter=="black_out") p->receiver=&black_out;
+ if (p->parameter=="white_out") p->receiver=&white_out;
+
+ //TODO: control an integer
+ if (p->parameter=="mode") p->receiver=&mode;
+ }
};
~Echo_trails(){if (image) {delete image;} };
- Image *get_output(const Frame_spec &frame){
+ Image *output(const Frame_spec &frame){
//check if cache is valid
if (frame.w!=image->w||frame.h!=image->h){ //or framerate changed?
//clear cache and start over
@@ -801,7 +838,8 @@ namespace Rotor {
//cerr<<"Rotor: about to apply image ("<<images[absframe].w<<"x"<<images[absframe].h<<")"<<endl;
if (fless(fadeto,1.0f)){
Image *temp=*images[absframe]*((float)number/((fadeto*number)+((1.0-fadeto)*i)));
- (*image)+=*temp;
+ if (mode<0.5) (*image)+=*temp;
+ else (*image)=image->add_wrap(*temp);
delete temp;
}
else (*image)+=*images[absframe];
@@ -824,6 +862,7 @@ namespace Rotor {
int number;
int interval,total,lastframe; //number of frames between displayed echoes
unordered_map<int,Image*> images;
+ float mode; //TODO make int, enum string parameter types
};
//-------------------------------------------------------------------
class Node_factory{