class ILxEnvelope

The envelope interface provides access to the overall attributes of the envelope shape, evaluation, and a keyframe accessor.

Public Functions

unsigned IsInt(LXtObjectID self)

The IsInt() method returns 1 for integer-valued type envelopes, 0 otherwise.

LxResult Enumerator(LXtObjectID self, void **ppvObj)

This method allocates a new keyframe enumerator, allowing multiple clients to query the same envelope.

LxResult EvaluateF(LXtObjectID self, double time, double *value)

These two methods allow the envelope to be evaluated. The input value is given as “time” although it is any independent parameter. the correct method must be called based on the envelopes numeric type.

LxResult EvaluateI(LXtObjectID self, double time, int *value)
unsigned int EndBehavior(LXtObjectID self, unsigned int side)

The envelopes end behavior is read and set with these methods. The side can be IN or OUT to select the behavior for times prior to the first key frame or the behavior after the last keyframe, respectively. The behavior for both can be set by specifying BOTH.

LxResult SetEndBehavior(LXtObjectID self, unsigned int behavior, unsigned int side)
LxResult Clear(LXtObjectID self)

For envelopes which can be edited this removes all the keys.

unsigned int Interpolation(LXtObjectID self)
LxResult SetInterpolation(LXtObjectID self, unsigned int type)
bool GetKeyframe(CLxLoc_Keyframe *key)

User Class Only: The user class for envelopes adds a method to spawn an enumerator directly to a keyframe user object. It returns true for success.

int IntValue(double time)

User Class Only: It also adds alternate methods for evaluating the envelope at a given time.

double Value(double time)
typedef unsigned LXtEndBehavior

The end behaviors determine what value the envelope takes outside the range of keyframes. See Also: LXtEndBehavior

  • RESET A default value, or may be just zero.

  • CONSTANT The value of the first or last keyframe. For first or last keys set to “Auto” or “Auto Flat” the slopes of the keys will be adjusted to provide a smooth interpolation to or from the behavior.

  • REPEAT The values in the keyframe range repeating continuously.

  • OSCILLATE Like repeat, but the values run forwards and backward alternately. For first or last keys set to “Auto” or “Auto Flat” the slopes of the keys will be adjusted to provide a smooth interpolation to or from the behavior.

  • OFFSETREPEAT Like repeat, but the values are offset in each cycle by the difference between the first and last keyframes. For first or last keys set to “Auto” or “Auto Flat” the slopes of the keys will be adjusted to provide a smooth interpolation to or from the behavior.

  • LINEAR Linear interpolation from the slope at the nearest keyframe.

  • NONE Indicates that the envelope does not exist before or after the explicit keyframe range. This isbe used by motion evaluation code to decide whether to use the envelope for a channel or to look up the parent envelope or default value.

  • CONSTANT_KEEP_SLOPE As for constant except that the slopes of the first or last keys are not changed.

  • OSCILLATE_KEEP_SLOPE As for oscillate except that the slopes of the first or last keys are not changed.

  • OFFSETREPEAT_KEEP_SLOPE As for offset repeat except that the slopes of the first or last keys are not changed.


















class ILxKeyframe

Public Functions

LxResult First(LXtObjectID self)

The keyframe interface has a state which is a current key, so it acts as an iterator. The next four methods set the current key based on its position in the sequence, or relative to the current key. They return LXe_NOTFOUND on errors.

LxResult Last(LXtObjectID self)
LxResult Next(LXtObjectID self)
LxResult Previous(LXtObjectID self)
LxResult Find(LXtObjectID self, double time, unsigned int side)

Find() selects a key at or near the current time. If side is IN then the key prior or equal to the time will become current. OUT gets the key after the given time. For BOTH the key must be exactly at the requested time.

LxResult GetTime(LXtObjectID self, double *time)

The time (or other independent parameter) of the key can be read with this method.

LxResult GetBroken(LXtObjectID self, unsigned int *breaks, unsigned int *side)

This method returns flags for which attributes of the key are broken and are different for the incoming and outgoing sides of the key. If the value of the key itself is broken, the side flag indicates which side of the key controls the value exactly at the given time.

LxResult GetValueF(LXtObjectID self, double *value, unsigned int side)

Read the value of the key as a float or int for either side of the key. For unbroken keys this will be the same.

LxResult GetValueI(LXtObjectID self, int *value, unsigned int side)
LxResult GetSlopeType(LXtObjectID self, LXtSlopeType *type, unsigned int *weighted, unsigned int side)

The slope type, slope and weight may likewise be read for the current key.

LxResult GetSlope(LXtObjectID self, double *slope, unsigned int side)
LxResult GetWeight(LXtObjectID self, double *weight, unsigned int side)
LxResult SetTime(LXtObjectID self, double time)

This alters the time (or independent parameter) of the key, potentially changing its relative position in the sequence of keys.

LxResult SetValueF(LXtObjectID self, double value, unsigned int side)

These methods allow the various parameters of the keyframe to be set. Breaking and unbreaking are controlled implicitly with the ‘side’ parameter. Setting the side to IN or OUT will break the parameter and only affect the specified side. Setting the side to BOTH will unbreak the parameter. The last side set when breaking the value will be the controlling side for the key.

LxResult SetValueI(LXtObjectID self, int value, unsigned int side)
LxResult SetSlope(LXtObjectID self, double slope, unsigned int side)
LxResult SetSlopeType(LXtObjectID self, LXtSlopeType type, unsigned int side)
LxResult SetWeight(LXtObjectID self, double weight, unsigned int reset, unsigned int side)

This will set the weight for the key unless ‘reset’ is true, in which case the weight will be set back to automatic.

LxResult AddF(LXtObjectID self, double time, double value)

These methods allow keys to be created at the given time (or other independent parameter) and value.

LxResult AddI(LXtObjectID self, double time, int value)
LxResult Delete(LXtObjectID self)

This deletes the current key.

CLxUser_Keyframe(CLxLoc_Envelope &env)

User Class Only: The keyframe user class has a special constructor that takes an envelope user object, from which the enumerator is extracted.

bool fromEnvObject(ILxUnknownID obj)

User Class Only: There is also a function to set the enumerator given any COM object. The method will clear the enumerator and return false if the object does not present an ILxEnvelope interface.

double Time()

User Class Only: Easier method for getting the time (or independent parameter) of the key. This should be fine as long as you know there is a valid current key.

LxResult Value(double *val)

User Class Only: Alternate methods for reading the value in the 90% case of an unbroken key.

double Value()
LxResult Value(int *val)
int IntValue()
unsigned int Broken()

User Class Only: The breaking and controlling side can be read independently.

unsigned int ActiveSide()
double Slope(unsigned int side)

User Class Only: The other key attributes can be read without error checking, although sidedness tends to be important for these so that is provided.

LXtSlopeType SlopeType(unsigned int side)
bool Weighted(unsigned int side)
double Weight(unsigned int side)



typedef unsigned LXtSlopeType

The slope can have one of the following values.

  • LXiSLOPE_DIRECT the slope of the tangent is set based on the value stored in the key.

  • LXiSLOPE_AUTO the slope of the tangent is calculated automatically with regard to surrounding keys. This is similar to the slope adjustments made by TCB curves.

  • LXiSLOPE_LINEAR_IN the slope of the tangent is calculated to align with the previous key’s value.

  • LXiSLOPE_LINEAR_OUT the slope of the tangent is calculated to align with the next key’s value.

  • LXiSLOPE_FLAT the slope of the tangent is set to zero.

  • LXiSLOPE_AUTOFLAT the same as auto but if a neighboring key has the same value as the key the slope is set to zero.

  • LXiSLOPE_STEPPED Maintains the value of the previous key between pairs of keys.










Gradient filters can have two distinct types; Modify and Generate. Generate type filters are expected to compute a new gradient value, ignoring anything below it in the stack, whereas Modify type filters are provided with the computed value of all filters below it in the stack, and it is expected to modify and return the value. A multi-sample filter is a variant on the Modify filter, but instead of being passed a single evaluated sample from further down the stack, the MultiSample method is passed a GradientFilter from lower in the stack, allowing multiple samples at arbitrary times to be evaluated. Finally, Envelope filters are a special type of Generate filter, that are generated from keyframed envelope data.





class ILxGradientFilter

A gradient usually contains keyframe data that exists in an envelope that can be directly modified by the user. However gradients can be dynamically generated and modified using Gradient Filters. Gradient Filters are added to a stack, and when evaluated, the stack is recursively evaluated to compute the final value for a specific sample. When reading a Gradient channel in an evaluated context, a Gradient Filter object will be returned. Evaluating this filter for it’s value, will return the final computed state, regardless of whether the gradient is composed from keyframes, filters, or a combination of the two.

Public Functions

unsigned int Type(LXtObjectID self)
double Generate(LXtObjectID self, double time)

If the Gradient Filter is a GENERATE type filter, the Generate method will be called to create a value for a specific “time” sample.

double Evaluate(LXtObjectID self, double time, double value)

If the Gradient Filter is a EVALUATE type filter, the Evaluate method will be called to modify an existing value for a specific “time” sample.

double MultiSample(LXtObjectID self, double time, LXtObjectID other)

If the Gradient Filter is a MULTISAMPLE type filter, the MultiSample method will be called to modify an existing value at an arbitary time sample.


class ILxGradientFilter1

Public Functions

double Evaluate(LXtObjectID self, double inVal)
LxResult AddRef(LXtObjectID self)
LxResult Release(LXtObjectID self)


Gradient filters can be applied as non-destructive layers on top of a gradient channel. Gradient Layers are a special item type that are not displayed in the user interface. Gradient layers are automatically generated from any Gradient Filter server that marks itself as a layer, so should not be implemented directly. The filter must present an ILxAttributes interface to allow channels on the item to be created.




To mark a gradient filter as a gradient layer, the following server tag must be added to the server. The value of the tag does not matter.