Modifiers

My plugin has a modifier and an item instance with an item drawing interface. How can I get the modifier object inside the instance’s methods?

Read the modifier object from the appropriate item channel, and convert:

C++

CLxUser_ValueReference   ref;
LXtObjectID              obj;

chan.Object (m_item, "myModifierObjectChannelName", ref);
ref.GetObject (&obj);

CLxSpawner<MyModifierClass>      spawner ("myModSpawnName");
MyModifierClass         *mod;

mod = spawner.Cast ((ILxUnknownID)obj);

 // Do stuff to draw modifier here

lx::ObjRelease (obj);

How can my channel modifier read inputs at different times?

This is done by using methods on the Evaluation Interface. You need to cache this interface as part of your member data in your Allocate() method.

C++

                LxResult
CTimeOffset::cmod_Allocate (
                ILxUnknownID             cmod,
                ILxUnknownID             eval,
                ILxUnknownID             item,
                void                   **ppvData)
{
                m_eval.set (eval);
                ...
}

Then in the Evaluate() method you read the channels you want at the current time first (in this case the current time and an offset time value), then set the evaluation for an alternate time and read other inputs.

C++

                LxResult
CTimeOffset::cmod_Evaluate (
                ILxUnknownID             cmod,
                ILxUnknownID             attr,
                void                    *data)
{
                CLxLoc_ChannelModifier   chanMod (cmod);
                double                   time, dt, value;

                chanMod.ReadInputFloat (attr, INDEX_TIME,   &time);
                chanMod.ReadInputFloat (attr, INDEX_OFFSET, &dt);

                if (dt)
                                m_eval.SetAlternateTime (time + dt);

                chanMod.ReadInputFloat (attr, INDEX_INPUT, &value);
                ...
}

Can my modifier read from the setup action?

Yes. It’s the same process as in the previous answer, but using Evaluation::SetAlternateSetup().

C++

m_eval.SetAlternateSetup ();

If you want to clear the alternate and read from the current time and action again, use ClearAlternate().

C++

m_eval.ClearAlternate  ();

Why won’t my channel modifier write a matrix?

If you’re trying to write a matrix in a channel modifier, you might try something like this:

C++

chanMod.WriteOutputVal (attr, 0, (void **)(&outMatrixPtr));
for (int i = 0; i < 3; i++) {
                 for (int j = 0; j < 3; j++) {
                                  (*outMatrixPtr)[i][j] = m[i][j];
                 }
}

which wouldn’t work. For whatever reason, if you want to write to matrix outputs, you need to write to every link individually. So your code would need to look like this:

C++

chanMod.OutputCount (0, &outCount);
for (unsigned idx = 0; idx < outCount; idx++) {
                 chanMod.WriteOutputValByIndex (attr, 0, idx, (void **)(&outMatrixPtr));
                                  for (int i = 0; i < 3; i++) {
                                                   for (int j = 0; j < 3; j++) {
                                                                        (*outMatrixPtr)[i][j] = m[i][j];
                                                   }
                                  }
}

How can I make sure modifier is evaluated for every time change?

Time can be allocated as an input for the modifier. As changes to input channels invalidates modifiers and causes them to be re-evaluated, allocating time as an input to the modifier will cause the modifier to be invalidated and re-evaluated whenever time changes.

Allocate time as an input channel:

C++

CLxUser_Evaluation       ev (eval);
idx_currentTime = ev.AddTime();

In the modifier Evaluate function, read the current time.

C++

CLxUser_Attributes       at (attr);
double currentTime = at.Float(idx_currentTime);