diff --git a/packages/nodegraph/include/nodegraph/core/NodeGraphBase.h b/packages/nodegraph/include/nodegraph/core/NodeGraphBase.h index 39fd3e70..50b824f7 100644 --- a/packages/nodegraph/include/nodegraph/core/NodeGraphBase.h +++ b/packages/nodegraph/include/nodegraph/core/NodeGraphBase.h @@ -245,6 +245,7 @@ namespace l::nodegraph { std::vector mCustom; }; + // Use this when the operation requires dynamic input parameters or when the input data can be sampled scarcily (not every sample etc) class NodeGraphOp2 : public NodeGraphOp { public: NodeGraphOp2(NodeGraphBase* node, std::string_view name) : diff --git a/packages/nodegraph/include/nodegraph/core/NodeGraphData.h b/packages/nodegraph/include/nodegraph/core/NodeGraphData.h index 04dd9d6f..d2aa9602 100644 --- a/packages/nodegraph/include/nodegraph/core/NodeGraphData.h +++ b/packages/nodegraph/include/nodegraph/core/NodeGraphData.h @@ -111,7 +111,7 @@ namespace l::nodegraph { }; /*********************************************************************************/ enum class InputTypeBase { - SAMPLED = 0, // todo: make it interpolate in smaller custom buffers + SAMPLED = 0, // interpolate in a buffer the size of a ProcessSubGraph(size) call. The actual size is defined by the lod factor of the output buffer. SAMPLED_RWA, // todo: add a smoothed sampled variant. Will replace interp_rwa and interp_rwa_ms as we will add a separate config for passing ticks or millis CONSTANT_ARRAY, // Same here, will be replaced CUSTOM_INTERP_TWEEN, // custom input vars should not be used at all diff --git a/packages/nodegraph/include/nodegraph/operations/NodeGraphOpLogic.h b/packages/nodegraph/include/nodegraph/operations/NodeGraphOpLogic.h index 7bc7785b..bd1846f7 100644 --- a/packages/nodegraph/include/nodegraph/operations/NodeGraphOpLogic.h +++ b/packages/nodegraph/include/nodegraph/operations/NodeGraphOpLogic.h @@ -36,10 +36,15 @@ namespace l::nodegraph { } virtual ~GraphLogicalAnd() = default; - virtual void Process(int32_t, std::vector& inputs, std::vector& outputs) override { - bool input1 = inputs.at(0).Get() != 0.0f; - bool input2 = inputs.at(1).Get() != 0.0f; - outputs.at(0).mOutput = (input1 && input2) ? 1.0f : 0.0f; + virtual void Process(int32_t numSamples, std::vector& inputs, std::vector& outputs) override { + auto input1 = inputs.at(0).GetIterator(numSamples); + auto input2 = inputs.at(1).GetIterator(numSamples); + auto output = outputs.at(0).GetIterator(); + for (int32_t i = 0; i < numSamples; i++) { + bool bool1 = (*input1++) != 0.0f; + bool bool2 = (*input2++) != 0.0f; + *output++ = (bool1 && bool2) ? 1.0f : 0.0f; + } } }; @@ -55,10 +60,15 @@ namespace l::nodegraph { } virtual ~GraphLogicalOr() = default; - virtual void Process(int32_t, std::vector& inputs, std::vector& outputs) override { - bool input1 = inputs.at(0).Get() != 0.0f; - bool input2 = inputs.at(1).Get() != 0.0f; - outputs.at(0).mOutput = (input1 || input2) ? 1.0f : 0.0f; + virtual void Process(int32_t numSamples, std::vector& inputs, std::vector& outputs) override { + auto input1 = inputs.at(0).GetIterator(numSamples); + auto input2 = inputs.at(1).GetIterator(numSamples); + auto output = outputs.at(0).GetIterator(); + for (int32_t i = 0; i < numSamples; i++) { + bool bool1 = (*input1++) != 0.0f; + bool bool2 = (*input2++) != 0.0f; + *output++ = (bool1 || bool2) ? 1.0f : 0.0f; + } } }; @@ -74,10 +84,15 @@ namespace l::nodegraph { } virtual ~GraphLogicalXor() = default; - virtual void Process(int32_t, std::vector& inputs, std::vector& outputs) override { - bool input1 = inputs.at(0).Get() != 0.0f; - bool input2 = inputs.at(1).Get() != 0.0f; - outputs.at(0).mOutput = (input1 ^ input2) ? 1.0f : 0.0f; + virtual void Process(int32_t numSamples, std::vector& inputs, std::vector& outputs) override { + auto input1 = inputs.at(0).GetIterator(numSamples); + auto input2 = inputs.at(1).GetIterator(numSamples); + auto output = outputs.at(0).GetIterator(); + for (int32_t i = 0; i < numSamples; i++) { + bool bool1 = (*input1++) != 0.0f; + bool bool2 = (*input2++) != 0.0f; + *output++ = (bool1 ^ bool2) ? 1.0f : 0.0f; + } } }; diff --git a/packages/nodegraph/include/nodegraph/operations/NodeGraphOpNumeric.h b/packages/nodegraph/include/nodegraph/operations/NodeGraphOpNumeric.h index 41cd599a..3acb53d1 100644 --- a/packages/nodegraph/include/nodegraph/operations/NodeGraphOpNumeric.h +++ b/packages/nodegraph/include/nodegraph/operations/NodeGraphOpNumeric.h @@ -30,17 +30,16 @@ namespace l::nodegraph { { AddInput("In 1"); AddInput("In 2"); + AddInput("Lod", 0.0f, 1, 0.0f, 8.0f); AddOutput("Out"); } virtual ~GraphNumericAdd() = default; virtual void Process(int32_t numSamples, std::vector& inputs, std::vector& outputs) override { auto input0 = inputs.at(0).GetIterator(numSamples); auto input1 = inputs.at(1).GetIterator(numSamples); - auto output = outputs.at(0).GetIterator(numSamples); - - if (numSamples > 1) { - ASSERT(numSamples == outputs.at(0).GetSize()); - } + auto lodExp = inputs.at(2).Get(); + auto lodFactor = l::math::functions::pow(2.0f, l::math::functions::round(lodExp)); + auto output = outputs.at(0).GetIterator(numSamples, lodFactor); for (int32_t i = 0; i < numSamples; i++) { *output++ = *input0++ + *input1++; @@ -56,6 +55,7 @@ namespace l::nodegraph { { AddInput("In 1"); AddInput("In 2"); + AddInput("Lod", 0.0f, 1, 0.0f, 8.0f); AddOutput("Out"); } @@ -63,11 +63,9 @@ namespace l::nodegraph { virtual void Process(int32_t numSamples, std::vector& inputs, std::vector& outputs) override { auto input0 = inputs.at(0).GetIterator(numSamples); auto input1 = inputs.at(1).GetIterator(numSamples); - auto output = outputs.at(0).GetIterator(numSamples); - - if (numSamples > 1) { - ASSERT(numSamples == outputs.at(0).GetSize()); - } + auto lodExp = inputs.at(2).Get(); + auto lodFactor = l::math::functions::pow(2.0f, l::math::functions::round(lodExp)); + auto output = outputs.at(0).GetIterator(numSamples, lodFactor); for (int32_t i = 0; i < numSamples; i++) { *output++ = *input0++ * *input1++; @@ -83,17 +81,16 @@ namespace l::nodegraph { { AddInput("In 1"); AddInput("In 2"); + AddInput("Lod", 0.0f, 1, 0.0f, 8.0f); AddOutput("Out"); } virtual ~GraphNumericSubtract() = default; virtual void Process(int32_t numSamples, std::vector& inputs, std::vector& outputs) override { auto input0 = inputs.at(0).GetIterator(numSamples); auto input1 = inputs.at(1).GetIterator(numSamples); - auto output = outputs.at(0).GetIterator(numSamples); - - if (numSamples > 1) { - ASSERT(numSamples == outputs.at(0).GetSize()); - } + auto lodExp = inputs.at(2).Get(); + auto lodFactor = l::math::functions::pow(2.0f, l::math::functions::round(lodExp)); + auto output = outputs.at(0).GetIterator(numSamples, lodFactor); for (int32_t i = 0; i < numSamples; i++) { *output++ = *input0++ - *input1++; @@ -108,17 +105,16 @@ namespace l::nodegraph { NodeGraphOp(node, "Negate") { AddInput("In"); + AddInput("Lod", 0.0f, 1, 0.0f, 8.0f); AddOutput("Out"); } virtual ~GraphNumericNegate() = default; virtual void Process(int32_t numSamples, std::vector& inputs, std::vector& outputs) override { auto input0 = inputs.at(0).GetIterator(numSamples); - auto output = outputs.at(0).GetIterator(numSamples); - - if (numSamples > 1) { - ASSERT(numSamples == outputs.at(0).GetSize()); - } + auto lodExp = inputs.at(1).Get(); + auto lodFactor = l::math::functions::pow(2.0f, l::math::functions::round(lodExp)); + auto output = outputs.at(0).GetIterator(numSamples, lodFactor); for (int32_t i = 0; i < numSamples; i++) { *output++ = - *input0++; @@ -133,17 +129,16 @@ namespace l::nodegraph { NodeGraphOp(node, "Integral") { AddInput("In", 0.0f, 1); + AddInput("Lod", 0.0f, 1, 0.0f, 8.0f); AddOutput("Out", 0.0f, 1); } virtual ~GraphNumericIntegral() = default; virtual void Process(int32_t numSamples, std::vector& inputs, std::vector& outputs) override { auto input0 = inputs.at(0).GetIterator(numSamples); - auto output = outputs.at(0).GetIterator(numSamples); - - if (numSamples > 1) { - ASSERT(numSamples == outputs.at(0).GetSize()); - } + auto lodExp = inputs.at(1).Get(); + auto lodFactor = l::math::functions::pow(2.0f, l::math::functions::round(lodExp)); + auto output = outputs.at(0).GetIterator(numSamples, lodFactor); for (int32_t i = 0; i < numSamples; i++) { mOutput += *input0++; @@ -163,6 +158,7 @@ namespace l::nodegraph { AddInput("In 1"); AddInput("In 2"); AddInput("In 3"); + AddInput("Lod", 0.0f, 1, 0.0f, 8.0f); AddOutput("Out"); } @@ -171,11 +167,9 @@ namespace l::nodegraph { auto input0 = inputs.at(0).GetIterator(numSamples); auto input1 = inputs.at(1).GetIterator(numSamples); auto input2 = inputs.at(2).GetIterator(numSamples); - auto output = outputs.at(0).GetIterator(numSamples); - - if (numSamples > 1) { - ASSERT(numSamples == outputs.at(0).GetSize()); - } + auto lodExp = inputs.at(3).Get(); + auto lodFactor = l::math::functions::pow(2.0f, l::math::functions::round(lodExp)); + auto output = outputs.at(0).GetIterator(numSamples, lodFactor); for (int32_t i = 0; i < numSamples; i++) { *output++ = *input0++ * *input1++ * *input2++; @@ -192,6 +186,7 @@ namespace l::nodegraph { AddInput("In 1"); AddInput("In 2"); AddInput("In 3"); + AddInput("Lod", 0.0f, 1, 0.0f, 8.0f); AddOutput("Out"); } @@ -200,11 +195,9 @@ namespace l::nodegraph { auto input0 = inputs.at(0).GetIterator(numSamples); auto input1 = inputs.at(1).GetIterator(numSamples); auto input2 = inputs.at(2).GetIterator(numSamples); - auto output = outputs.at(0).GetIterator(numSamples); - - if (numSamples > 1) { - ASSERT(numSamples == outputs.at(0).GetSize()); - } + auto lodExp = inputs.at(3).Get(); + auto lodFactor = l::math::functions::pow(2.0f, l::math::functions::round(lodExp)); + auto output = outputs.at(0).GetIterator(numSamples, lodFactor); for (int32_t i = 0; i < numSamples; i++) { *output++ = *input0++ * *input1++ + *input2++; @@ -219,6 +212,7 @@ namespace l::nodegraph { NodeGraphOp(node, "Round") { AddInput("In"); + AddInput("Lod", 0.0f, 1, 0.0f, 8.0f); AddOutput("Out"); } @@ -226,12 +220,10 @@ namespace l::nodegraph { virtual void Process(int32_t numSamples, std::vector& inputs, std::vector& outputs) override { outputs.at(0).mOutput = l::math::functions::round(inputs.at(0).Get()); - auto input0 = inputs.at(2).GetIterator(numSamples); - auto output = outputs.at(0).GetIterator(numSamples); - - if (numSamples > 1) { - ASSERT(numSamples == outputs.at(0).GetSize()); - } + auto input0 = inputs.at(0).GetIterator(numSamples); + auto lodExp = inputs.at(1).Get(); + auto lodFactor = l::math::functions::pow(2.0f, l::math::functions::round(lodExp)); + auto output = outputs.at(0).GetIterator(numSamples, lodFactor); for (int32_t i = 0; i < numSamples; i++) { *output++ = l::math::functions::round(*input0++); diff --git a/packages/nodegraph/source/common/core/NodeGraphOutput.cpp b/packages/nodegraph/source/common/core/NodeGraphOutput.cpp index 27762df8..744ff2f7 100644 --- a/packages/nodegraph/source/common/core/NodeGraphOutput.cpp +++ b/packages/nodegraph/source/common/core/NodeGraphOutput.cpp @@ -31,7 +31,7 @@ namespace l::nodegraph { } NodeDataIterator NodeGraphOutput::GetIterator(int32_t size, float lod) { - if (mOutputLod == 1.0f && lod > 1.0f) { + if (lod >= 1.0f && lod <= size) { mOutputLod = lod; } float stepPerIndex = size == 1 ? 0.0f : 1.0f / mOutputLod;