diff options
Diffstat (limited to 'rotord/src/nodes_maths.h')
| -rw-r--r-- | rotord/src/nodes_maths.h | 220 |
1 files changed, 88 insertions, 132 deletions
diff --git a/rotord/src/nodes_maths.h b/rotord/src/nodes_maths.h index d4b8eac..4ec2cf9 100644 --- a/rotord/src/nodes_maths.h +++ b/rotord/src/nodes_maths.h @@ -4,6 +4,7 @@ #include "rotor.h" #include <libnoise/noise.h> #include <libnoise/mathconsts.h> +#include "Poco/Logger.h" namespace Rotor { #define COMPARISON_Equal 1 @@ -14,54 +15,40 @@ namespace Rotor { #define COMPARISON_Less_or_equal 6 class Comparison: public Signal_node { public: - Comparison(){}; - Comparison(map<string,string> &settings) { + Comparison(){ + create_signal_input("signal","Signal"); + create_parameter("value","number","Value or signal for operation","Value",0.0f); + create_attribute("operator","Operator for comparison","operator","==",{"==","!=",">","<",">=","<="}); + description="Compares the signal with a value or signal according to the operator"; + }; + Comparison(map<string,string> &settings):Comparison() { base_settings(settings); - value=find_setting(settings,"value",0.0f); - string _op=find_setting(settings,"operator","=="); - if (_op=="==") op=COMPARISON_Equal; - if (_op=="!=") op=COMPARISON_Not_equal; - if (_op==">") op=COMPARISON_Greater; - if (_op=="<") op=COMPARISON_Less; - if (_op==">=") op=COMPARISON_Greater_or_equal; - if (_op=="<=") op=COMPARISON_Less_or_equal; } - void link_params() { - 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) { - if (inputs.size()) { //there should there be a way to specify number of inputs in the code rather than in xml - if (inputs[0]->connection) { - float in= (((Signal_node*)inputs[0]->connection)->get_output(time)); - switch (op) { - case COMPARISON_Equal: - return fequal(value,in)?1.0f:0.0f; - break; - case COMPARISON_Not_equal: - return fequal(value,in)?0.0f:1.0f; - break; - case COMPARISON_Greater: - return fgreater(value,in)?1.0f:0.0f; - break; - case COMPARISON_Less: - return fless(value,in)?1.0f:0.0f; - break; - case COMPARISON_Greater_or_equal: - return fgreater_or_equal(value,in)?1.0f:0.0f; - break; - case COMPARISON_Less_or_equal: - return fless_or_equal(value,in)?1.0f:0.0f; - break; - } - } - } + const float output(const Time_spec &time) { + switch (attributes["operator"]->intVal) { + case COMPARISON_Equal: + return fequal(parameters["value"]->value,inputs[0]->get(time))?1.0f:0.0f; + break; + case COMPARISON_Not_equal: + return fequal(parameters["value"]->value,inputs[0]->get(time))?0.0f:1.0f; + break; + case COMPARISON_Greater: + return fgreater(parameters["value"]->value,inputs[0]->get(time))?1.0f:0.0f; + break; + case COMPARISON_Less: + return fless(parameters["value"]->value,inputs[0]->get(time))?1.0f:0.0f; + break; + case COMPARISON_Greater_or_equal: + return fgreater_or_equal(parameters["value"]->value,inputs[0]->get(time))?1.0f:0.0f; + break; + case COMPARISON_Less_or_equal: + return fless_or_equal(parameters["value"]->value,inputs[0]->get(time))?1.0f:0.0f; + break; + } + return 0.0f; } - int op; - float value; }; #define ARITHMETIC_plus 1 #define ARITHMETIC_minus 2 @@ -75,70 +62,58 @@ namespace Rotor { #define ARITHMETIC_jolt 10 class Arithmetic: public Signal_node { public: - Arithmetic(){}; - Arithmetic(map<string,string> &settings) { + Arithmetic(){ + create_signal_input("signal","Signal"); + create_parameter("value","number","Value or signal for operation","Value",1.0f); + create_attribute("operator","operator for image","Operator","+",{"+","-","*","/","%","^","sin","cos","ease","jolt"}); + title="Arithmetic"; + description="Performs arithmetic on a signal with a signal or value"; + }; + Arithmetic(map<string,string> &settings):Arithmetic() { base_settings(settings); - value=find_setting(settings,"value",0.0f); - string _op=find_setting(settings,"operator","+"); - if (_op=="+"||_op=="plus"||_op=="add") op=ARITHMETIC_plus; - if (_op=="-"||_op=="minus"||_op=="subtract") op=ARITHMETIC_minus; - if (_op=="*"||_op=="x"||_op=="multiply") op=ARITHMETIC_multiply; - if (_op=="/"||_op=="divide") op=ARITHMETIC_divide; - if (_op=="%"||_op=="mod"||_op=="modulo"||_op=="modulus") op=ARITHMETIC_modulo; - if (_op=="^"||_op=="power") op=ARITHMETIC_pow; - if (_op=="sin"||_op=="sine") op=ARITHMETIC_sin; - if (_op=="cos"||_op=="cos") op=ARITHMETIC_cos; - if (_op=="ease") op=ARITHMETIC_ease; - if (_op=="jolt") op=ARITHMETIC_jolt; - } - void link_params() { - for (auto p:parameter_inputs){ - p->receiver=nullptr; - if (p->parameter=="value") p->receiver=&value; - } }; Arithmetic* clone(map<string,string> &_settings) { return new Arithmetic(_settings);}; const float output(const Time_spec &time) { - if (op==ARITHMETIC_divide||op==ARITHMETIC_modulo){ + if (attributes["operator"]->intVal==ARITHMETIC_divide||attributes["operator"]->intVal==ARITHMETIC_modulo){ if (value==0.0f) { - Logger& logger = Logger::get("Rotor"); + Poco::Logger& logger = Poco::Logger::get("Rotor"); logger.error("Arithmetic node: caught division by zero, frame "+time.frame()); return 0.0f; } } if (inputs.size()) { //there should there be a way to specify number of inputs in the code rather than in xml if (inputs[0]->connection) { - float in= (((Signal_node*)inputs[0]->connection)->get_output(time)); - switch (op) { + float in= inputs[0]->get(time); + switch (attributes["operator"]->intVal) { case ARITHMETIC_plus: - return in+value; + return in+parameters["value"]->value; break; case ARITHMETIC_minus: - return in-value; + return in-parameters["value"]->value; break; case ARITHMETIC_multiply: - return in*value; + return in*parameters["value"]->value; break; case ARITHMETIC_divide: - return in/value; + return in/parameters["value"]->value; break; case ARITHMETIC_modulo: - return fmod(in,value); + return fmod(in,parameters["value"]->value); break; case ARITHMETIC_pow: - return pow(in,value); + return pow(in,parameters["value"]->value); break; case ARITHMETIC_sin: - return sin(in)*value; + return sin(in)*parameters["value"]->value; break; case ARITHMETIC_cos: - return cos(in)*value; + return cos(in)*parameters["value"]->value; break; case ARITHMETIC_ease: - return ((1.0-value)*in)+(value*(0.5f+((cos((fmod(in,1.0f)+1.0f)*M_PI))*0.5f))); + return ((1.0-parameters["value"]->value)*in)+(parameters["value"]->value*(0.5f+((cos((fmod(in,1.0f)+1.0f)*M_PI))*0.5f))); break; case ARITHMETIC_jolt: - return ((1.0-value)*in)+(value*(0.5f+((sin((fmod(in,1.0f)+1.0f)*M_PI))*0.5f))); + return ((1.0-parameters["value"]->value)*in)+(parameters["value"]->value*(0.5f+((sin((fmod(in,1.0f)+1.0f)*M_PI))*0.5f))); break; } } @@ -148,49 +123,32 @@ namespace Rotor { int op; float value; }; - class Signal_divide: public Signal_node { - public: - Signal_divide(){}; - Signal_divide(map<string,string> &settings) { - base_settings(settings); - divide_amount=ofToFloat(find_setting(settings,"amount")); - for (auto p:parameter_inputs){ - if (p->parameter=="amount") p->receiver=÷_amount; - } - }; - Signal_divide* clone(map<string,string> &_settings) { return new Signal_divide(_settings);}; - const float output(const Time_spec &time) { - if (inputs.size()) { //there should there be a way to specify number of inputs in the code rather than in xml - if (inputs[0]->connection) { - return (((Signal_node*)inputs[0]->connection)->get_output(time))/divide_amount; - } - } - return 0.0f; - } - float divide_amount; - }; class Is_new_integer: public Signal_node { public: - Is_new_integer(){}; - Is_new_integer(map<string,string> &settings) { + Is_new_integer(){ + title="New integer"; + description="Outputs 1 on the frame that a signal becomes a new integer"; + create_signal_input("signal","Signal"); + }; + Is_new_integer(map<string,string> &settings):Is_new_integer() { base_settings(settings); }; Is_new_integer* clone(map<string,string> &_settings) { return new Is_new_integer(_settings);}; const float output(const Time_spec &time) { - if (inputs[0]->connection) { - float s1=(((Signal_node*)(inputs[0]->connection))->get_output(time)); - float s2=(((Signal_node*)(inputs[0]->connection))->get_output(time.lastframe())); - if (((int)s1)>((int)s2)) { - return 1.0f; - } + if (((int)inputs[0]->get(time))>((int)inputs[0]->get(time.lastframe()))) { + return 1.0f; } return 0.0f; } }; class On_off: public Signal_node { public: - On_off(){}; - On_off(map<string,string> &settings) { + On_off(){ + title="On off"; + description="Outputs 1 if the integer floor of the signal is even"; + create_signal_input("signal","Signal"); + }; + On_off(map<string,string> &settings):On_off() { base_settings(settings); }; On_off* clone(map<string,string> &_settings) { return new On_off(_settings);}; @@ -228,47 +186,45 @@ namespace Rotor { return fnv1a(*ptr , hash); } class Random: public Signal_node { - //randomises integer while keeping fraction public: - Random(){}; + Random(){ + title="Random"; + description="Randomises integer part of signal (seedable)"; + create_signal_input("signal","Signal"); + create_parameter("seed","number","Seed value","Seed",1.0f); + }; Random(map<string,string> &settings) { base_settings(settings); - seed=(Seed+find_setting(settings,"seed",0)); }; Random* clone(map<string,string> &_settings) { return new Random(_settings);}; const float output(const Time_spec &time) { - if (inputs.size()) { - if (inputs[0]->connection) { - - //hash the integer part and add the fractional part back on - float o=(((Signal_node*)inputs[0]->connection)->get_output(time)); - uint32_t m=(int)o; - return ((float)(fnv1a(m,seed)%((uint32_t)time.duration)))+(o-m); - } - } - return 0.0f; + uint32_t seed=Seed+parameters["seed"]->value; + //hash the integer part and add the fractional part back on + float o=inputs[0]->get(time); + uint32_t m=(int)o; + return ((float)(fnv1a(m,seed)%((uint32_t)time.duration)))+(o-m); } - uint32_t seed; - private: }; class Noise: public Signal_node { //fractal noise public: - Noise(){}; + Noise(){ + title="Noise"; + description="Fractal noise (seedable)"; + create_signal_input("signal","Signal"); + create_parameter("seed","number","Seed value","Seed",1.0f); + }; Noise(map<string,string> &settings) { base_settings(settings); seed=find_setting(settings,"seed",0); }; Noise* clone(map<string,string> &_settings) { return new Noise(_settings);}; const float output(const Time_spec &time) { - if (inputs.size()) { - if (inputs[0]->connection) { - float o=(((Signal_node*)inputs[0]->connection)->get_output(time)); - - return o; - } - } - return 0.0f; + uint32_t seed=Seed+parameters["seed"]->value; + //hash the integer part and add the fractional part back on + float o=inputs[0]->get(time); + uint32_t m=(int)o; + return ((float)(fnv1a(m,seed)%((uint32_t)time.duration)))+(o-m); } uint32_t seed; private: |
