User Guide: Effect Wrappers

From AFXWiki
Jump to: navigation, search

Contents


Effect wrappers are what make it possible for the effects engine to make use of special effects developed outside of the AFX framework. An important assumption made in the effects engine is that it does not need to know much about specific building-block effects in order to combine them into layered effects. To the engine, most effects are just black boxes that need to be told when and where to do whatever it is that they do.

As the name implies, Effect Wrappers wrap around or enclose existing effects and make them all look the same to the rest of the engine. In object-oriented programming terms, they provide a kind of after-the-fact polymorphism between effect types. One effect may be a particle emitter, and another may be a sound effect, but they both need to occur at certain places and at certain times and the engine treats them both as generic effects.

For each building-block effect used in an AFX choreographer, a corresponding effect wrapper is created using an afxEffectWrapperData datablock. afxEffectWrapperData recognizes a large number of different building-block effects and it can be extended to recognize more with the addition of some customized code. The specific type of building-block effect enclosed by an effect wrapper is determined by the type of datablock specified by the effect field.

In addition to making all building-block effects look the same to the effects engine, effect wrappers associate additional information with each effect. This information includes constraint sources, conditional execution parameters, and per-effect timing parameters.

New in AFX 2: New timing features: lifetimeBias, fadeInEase, fadeOutEase. effectEnabled field. VisibilityKeys, groupIndex, inheritGroupTiming.

Constraint Sources

Effects get their positions and orientations from other scene objects, fixed points and transforms, and even other running effects. In other words, effects are constrained to follow the movement and orientation of other objects, called constraint sources. The constraint system provides something very much like object mounting, but with more flexibility.

Each effect can reference several different constraint sources, which are specified in afxEffectWrapperData. The most common are the position and orientation constraint sources, which directly determine an effect's position and orientation. There is also a secondary position constraint source, usually used as a target for aiming an effect.

Read more about the AFX constraint system in the Constraint System section. Also, the Transform Modifier section discusses how to further refine constraint values using procedural animation modules.

Conditional Execution

Effects can dynamically adapt to runtime conditions and settings using conditional execution. This means that individual effects can be configured to run only if certain conditions are satisfied, otherwise they are ignored.

With conditional execution you can:

  • Display a smaller explosion when hitting a tree instead of a player.
  • Enable more effect lighting for nighttime missions.
  • Increase effect complexity for higher level magic spells.
  • Reduce effect complexity according to a user's level of detail setting.

Read more about conditional execution and how it relates to choreographers in the Effects Choreographers sections.

New in AFX 2: The kind of conditional execution described here is somewhat crude in that entire effects must be swapped in and out based on the execution conditions. For many situations, it may be preferable to use the more fine-grained runtime launch parametrization capabilities available with AFX 2.

Effect Timing

The effects engine handles effect timing in hierarchical fashion. At the top, each choreographer manages a single chunk of time covering the entire duration of a compound effect. Within a choreographer, timing is handled by one or more phrases, each with its own independent timeline. Finally, each phrase contains a list of effects wrappers, each with per-effect timing parameters. It's here, within the effects wrappers, where most of the timing details for effects are specified.

Each effect wrapper has several parameters that control the enclosed effect's timing. They include lifetime, delay, fadeInTime, fadeOutTime, and residueLifetime. Each is a floating-point type representing time in seconds.

Timing Parameters

lifetime

Specifies the duration of an effect in seconds. At the end of an effect's lifetime, it does not disappear instantly, but begins its fade-out which lasts for the duration specified by fadeOutTime.

The lifetime parameter has the default value of $AFX::INFINITE_TIME which means that the effect will remain active until it is explicitly stopped by something external to the effect. Typically, effects with infinite lifetimes are stopped when the phrase containing them ends.

  • Default Value: $AFX::INFINITE_TIME

delay

Offsets the start of an effect from the start of the phrase that contains it. This is how the timing of an effect is positioned within the timeline of its phrase.

  • Default Value: 0.0

fadeInTime

The amount of time it takes for an effect to fade in from invisible to full visibility. This duration overlaps the lifetime parameter with the fade-in beginning at the start of the effect's lifetime.

For non-visual effects, fades may have an alternative, non-visual interpretation (e.g. for Sound Effects, the volume fades in and out).

Most fades are implemented using simple linear interpolation.

  • Default Value: 0.0

fadeOutTime

The amount of time it takes for an effect to fade out from full visibility to invisible. Unlike fadeInTime, this duration does not overlap with the lifetime parameter, but begins to fade out right at the end of the effect's lifetime. This is because some effects are ended by an external event with timing that cannot be predicted in advance. In such cases, the effect should not vanish instantly, but rather fade-out naturally.

For effects with a positive residueLifetime, the fade out is moved from the end of lifetime to the end of residueLifetime.

For non-visual effects, fades may have an alternative, non-visual interpretation (e.g. for Sound Effects, the volume fades in and out).

Most fades are implemented using simple linear interpolation.

  • Default Value: 0.0

residueLifetime

Specifies an extended lifetime for an effect, potentially beyond the life of its choreographer. If residueLifetime is a positive value, the effect does not fade at the end of lifetime, but is instead placed under the control of the residue manager, and its fadeOutTime is set to occur at the end of its residueLifetime. This is useful when you want something like a scorched earth texture to stick around much longer than the duration of the main effect.

Note: This parameter is only useful for effect types that the residue manager supports, currently only Zodiacs and Model Effects.

  • Default Value: 0.0

lifetimeBias

A multiplier which is applied to the other timing fields: lifetime, fadeInTime, and fadeOutTime. It has no effect on delay or residueLifetime. It is useful when used with field substitutions, since it scales the three timing values as a group with a single substitution.

  • Default Value: 1.0
  • New in AFX 2

fadeInEase

A pair of values for shaping the curve used to interpolate the current fade amount while fading in.

The values here partition the range from 0 to 1 into three sections. The section before the first value is the ease-in section and the section following the second value is the ease-out section. The section between the two values is the linear section.

The default value of "0.0 1.0" results in linear interpolation. Raising the first value increases the length of the ease-in while lowering the second value increases the length of the ease-out. A value of "0.2 0.8" provides a good balance of eases and linear interpolation.

  • Default Value: "0.0 1.0"
  • New in AFX 2

fadeOutEase

A pair of values for shaping the curve used to interpolate the current fade amount while fading out.

The values here partition the range from 0 to 1 into three sections. The section before the first value is the ease-in section and the section following the second value is the ease-out section. The section between the two values is the linear section.

The default value of "0.0 1.0" results in linear interpolation. Raising the first value increases the length of the ease-in while lowering the second value increases the length of the ease-out. A value of "0.2 0.8" provides a good balance of eases and linear interpolation.

  • Default Value: "0.0 1.0"
  • New in AFX 2

Examples of Effect Timing

Figure 1 shows a diagram of a typical effect's timing parameters and how they relate to the timeline of the phrase that contains the effect. The delay parameter positions the effect within the phrase timeline as an offset from the phrase's zero time. The effect itself begins after the delay duration, and continues for an explicit lifetime duration and then fades off over the fadeOutTime duration.


Afx wrapper timing fig1.jpg

Figure 1: Typical Effect Timing


While fadeInTime overlaps the beginning of lifetime, fadeOutTime does not, starting right at the end of lifetime. This means that the actual effect's lifetime, the time it actually exists and is visible, is the total of lifetime + fadeOutTime. This is potentially confusing, but there is a reason for it.

An important aspect of AFX effect timing is that not all durations are known or knowable at the start of a compound effect. For example, the length of the delivery phrase in afxMagicSpell is often determined by the flight of a projectile, the duration of which depends on the distance to a target and the speed of the projectile. Therefore, effects in the delivery phrase are often specified with infinite lifetimes. This keeps them active until the spell's projectile hits something, ending the delivery phrase, and forcing an end to all its effects with infinite lifetimes. Since, fadeOutTime is outside of lifetime, effects that are stopped at the end of a phrase still fade out smoothly.

This is illustrated in Figure 2, below. Notice how the infinite lifetime ends and the fade-out begins right at the end of the phrase timeline.


Afx wrapper timing fig2.jpg

Figure 2: Infinite Lifetime Timing


Some types of effects can specify a long lasting extended lifetime using the residueLifetime parameter. At the end of lifetime, if residueLifetime is positive, control of the effect is transferred from the effect's choreographer to the Residue Manager which will manage the effect over a potentially lengthy period of time.


Afx wrapper timing fig3.jpg

Figure 3: Example Using residueLifetime


When an effect has a positive residueLifetime, its fadeOutTime follows residueLifetime rather than lifetime, as shown in Figure 3.

Figure 4 illustrates how the varied timing of multiple effects might look within a single choreographer phrase. Notice that effects within a phrase can overlap the end of the phrase's timeline and remain active beyond the phrase ending. When the end of a phrase is reached, all active effects with infinite timelines are told to begin their fade-outs, but other effects are allowed to continue until the end of their explicit lifetimes.


Afx wrapper timing fig4.jpg

Figure 4: Effects Timing in a Phrase



Previous: User Guide: Building-block Effects

Next: User Guide: Effects Choreographers

Up: AFX: Official Online Documentation