Channel Modifier (metaclass)

The channel modifier SDK has been completely overhauled for MODO 10. Old channel modifiers will still function exactly as before and can continue to be compiled with the updated SDK, but new modifiers should use the improved SDK. This metaclass supports creating C++ channel modifiers.

Sample

This example is a C++ channel modifier that takes one input float and outputs twice that value. The client’s code is a sub-class of CLxChannelModifier which declares the channels for the modifier in init_chan() (derived from ‘’CLxChannels’’) and performs the computation in eval() (derived from ‘’CLxChannelModManager’’). The wrapper code binds the channels to the Value objects in the class which can be read and written during evaluation.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class COperator :
                public CLxChannelModifier
{
    public:
        CLxUser_Value            v_input, v_output;

                void
        init_chan (
                CLxAttributeDesc        &desc)
        {
                COperator               *op = 0;

                desc.add ("input", LXsTYPE_FLOAT);
                desc.chanmod_chan (LXfCHMOD_INPUT, &op->v_input);

                desc.add ("output", LXsTYPE_FLOAT);
                desc.chanmod_chan (LXfCHMOD_OUTPUT, &op->v_output);
        }

                void
        eval ()
        {
                double           val;

                v_input.GetFlt (&val);
                v_output.SetFlt (val * 2.0);
        }
};

static CLxMetaRoot_ChannelModifier<COperator>    meta ("cmDoubler");

        void
initialize ()
{
        meta.initialize ();
}

Some things to note. In defining channels we use the chanmod_chan() method. That associates value objects with channels for binding. The metaclass is actually a composite, consisting of a Channels metaclass and a ChannelModManager metaclass assembled into a subtree. We also use the CLxMetaRoot_ChannelModifier template rather than ‘’CLxMeta_ChannelModifier’’. This just saves us a step and creates all the relevant metaclasses under a root which can just be initialized directly without needing to be added.

Other Bindings

In addition to Value objects, input channels can also be bound to ValueArray objects, allowing multi-link channels to be read individually.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
        CLxUser_ValueArray       v_multi;
        [...]
                desc.add ("multi", LXsTYPE_FLOAT);
                desc.chanmod_chan (LXfCHMOD_INPUT | LXfCHMOD_MULTILINK, &op->v_multi);
        [...]
                v_multi.Count (&n);
                for (i = 0; i < n; i++) {
                        v_multi.GetFloat(i, &val);
                        sum += val;
                }

Channels can also be bound to Matrix objects, and writing to a Matrix output now automatically propagates to all outputs so only a single result needs to be generated.

1
2
3
4
5
6
        CLxUser_Matrix   v_matrix;
        [...]
                desc.add ("outMat", LXsTYPE_MATRIX4);
                desc.chanmod_chan (LXfCHMOD_OUTPUT, &op->v_matrix);
        [...]
                v_matrix.Set4 (resultMatrix);

Channel modifiers can also read from time. There’s no channel needed for this, just a float to get the result.

1
2
3
4
5
6
        CLxUser_Value    v_time;
        [...]
                desc.chanmod_time (&op->v_time);
        [...]
                double t;
                v_time.GetFlt (&t);