summaryrefslogtreecommitdiff
path: root/rotord/src/nodes_maths.h
diff options
context:
space:
mode:
Diffstat (limited to 'rotord/src/nodes_maths.h')
-rw-r--r--rotord/src/nodes_maths.h220
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=&divide_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: