afterglow.effects.params
A general mechanism for passing dynamic parameters to effect functions and assigners allowing for dynamic values to be computed either when an effect creates its assigners, or when the assigners are resolving DMX values. Parameters can be calculated based on the show metronome snapshot, show variables (which can be bound to OSC and MIDI mappings), and other, not-yet-imagined things.
bind-keyword-param
macro
(bind-keyword-param value type-expected default)
(bind-keyword-param value type-expected default param-name)
If an input to a dynamic parameter has been passed as a keyword, treat that as a reference to a variable in *show*. If that variable currently holds a dynamic parameter, try to bind it directly (throw an exception if the types do not match). Otherwise, build a new variable param to bind to future values of that show variable, and return that, logging a warning if the current value (if any) of the show variable is of an incompatible type for the parameter being bound. If the input parameter is not a keyword, simply validate its type.
bind-keyword-param*
(bind-keyword-param* param type-expected default param-name)
Helper function that does the work of the bind-keyword-param macro, which passes it the name of the parameter being bound for nice error messages.
build-aim-param
(build-aim-param & {:keys [x y z frame-dynamic], :or {x 0, y 0, z 2, frame-dynamic :default}})
Returns a dynamic aiming parameter for use with aim-effect. If no arguments are supplied, returns a static direction aiming towards a spot on the floor two meters towards the audience from the center of the light show. Keywords :x
, :y
, and :z
can be used to specify a target point in the frame of reference of the light show.
All incoming parameter values may be literal or dynamic, and may be keywords, which will be dynamically bound to variables in *show*.
If you do not specify an explicit value for :frame-dynamic
, this aim parameter will be frame dynamic if it has any incoming parameters which themselves are.
build-aim-transformer
(build-aim-transformer aim transform & {:keys [frame-dynamic], :or {frame-dynamic :default}})
Returns a dynamic aiming parameter for use with aim-effect which evaluates an incoming aiming parameter and transforms it according to a Transform3D
parameter.
All incoming parameter values may be literal or dynamic, and may be keywords, which will be dynamically bound to variables in *show*.
If you do not specify an explicit value for :frame-dynamic
, this aim parameter will be frame dynamic if it has any incoming parameters which themselves are.
build-color-param
(build-color-param & {:keys [color r g b h s l adjust-hue adjust-saturation adjust-lightness frame-dynamic], :or {color default-color, frame-dynamic :default}})
Returns a dynamic color parameter. If supplied, :color
is passed to interpret-color to establish the base color to which other arguments are applied. The default base color is black, in the form of all zero values for r
, g
, b
, h
, s
, and l
. To this base it will then assign values passed in for individual color parameters.
All incoming parameter values may be literal or dynamic, and may be keywords, which will be dynamically bound to variables in *show*.
Not all parameter combinations make sense, of course: you will probably want to stick with either some of :h
, :s
, and :l
, or some of :r
, :g
, and :b
. If values from both are supplied, the :r
, :g
, and/or :b
assignments will occur first, then then any :h
, :s
, and :l
assignments will be applied to the resulting color.
Finally, if any adjustment values have been supplied for hue, saturation or lightness, they will be added to the corresponding values (rotating around the hue circle, clamped to the legal range for the others).
If you do not specify an explicit value for :frame-dynamic
, this color parameter will be frame dynamic if it has any incoming parameters which themselves are.
build-direction-param
(build-direction-param & {:keys [x y z frame-dynamic], :or {x 0, y 0, z 1, frame-dynamic :default}})
Returns a dynamic direction parameter for use with direction-effect. If no arguments are supplied, returns a static direction facing directly out towards the audience. Keywords :x
, :y
, and :z
can be used to specify a vector in the frame of reference of the light show.
All incoming parameter values may be literal or dynamic, and may be keywords, which will be dynamically bound to variables in *show*.
If you do not specify an explicit value for :frame-dynamic
, this direction parameter will be frame dynamic if it has any incoming parameters which themselves are.
build-direction-param-from-pan-tilt
(build-direction-param-from-pan-tilt & {:keys [pan tilt radians frame-dynamic], :or {pan 0, tilt 0, frame-dynamic :default}})
An alternative to build-direction-param for cases in which angles are more convenient than a vector, but when you still want to use a direction-effect, probably because you want to be able to fade to or from another direction-effect. (In cases where you don’t need to do that, it is simpler to use a pan-tilt-effect with build-pan-tilt-param and actually have the effect work with pan and tilt angles, the way most lighting software does.)
Returns a dynamic direction parameter specified in terms of pan and tilt angles away from facing directly out towards the audience. If no arguments are supplied, returns a static direction facing directly out towards the audience. Keywords :pan
and :tilt
can be used to specify angles to turn around the Y and X axes respectively (see show space for a diagram of these axes). For human friendliness, the angles are assumed to be in degrees unless keyword :radians
is supplied with a true value.
The values passed for :pan
and :tilt
may be dynamic, or may be keywords, which will be dynamically bound to variables in *show*.
If you do not specify an explicit value for :frame-dynamic
, the resulting direction parameter will be frame dynamic if it has any incoming parameters which themselves are.
build-direction-transformer
(build-direction-transformer direction transform & {:keys [frame-dynamic], :or {frame-dynamic :default}})
Returns a dynamic direction parameter for use with direction-effect which evaluates an incoming direction parameter and transforms it according to a Transform3D
parameter.
All incoming parameter values may be literal or dynamic, and may be keywords, which will be dynamically bound to variables in *show*.
If you do not specify an explicit value for :frame-dynamic
, this direction parameter will be frame dynamic if it has any incoming parameters which themselves are.
build-pan-tilt-param
(build-pan-tilt-param & {:keys [pan tilt radians frame-dynamic], :or {pan 0, tilt 0, frame-dynamic :default}})
Returns a dynamic pan/tilt parameter for use with pan-tilt-effect, specified in terms of pan and tilt angles away from facing directly out towards the audience. If no arguments are supplied, returns a static orientation facing directly out towards the audience. Keywords :pan
and :tilt
can be used to specify angles to turn around the Y and X axes respectively (see show space for a diagram of these axes). For human friendliness, the angles are assumed to be in degrees unless keyword :radians
is supplied with a true value.
The values passed for :pan
and :tilt
may be dynamic, or may be keywords, which will be dynamically bound to variables in *show*.
If you do not specify an explicit value for :frame-dynamic
, the resulting pan/tilt parameter will be frame dynamic if it has any incoming parameters which themselves are.
Note that if you want to be able to fade the effect you are creating to or from a direction-effect, you need to create a direction-effect rather than a pan-tilt-effect, and you can instead use build-direction-param-from-pan-tilt to set its direction.
build-param-formula
(build-param-formula param-type calc-fn & input-params)
A helper function to create a dynamic parameter that involves some sort of calculation based on the values of another group of dynamic parameters. The result type reported by the resulting parameter will be param-type
.
Whenever the parameter’s value is needed, it will evaluate all of the parameters passed as input-params
, and call calc-fn
with their current values, returning its result, which must have the type specified by param-type
.
The compound dynamic parameter will be frame dynamic if any of its input parameters are.
build-spatial-param
(build-spatial-param fixtures-or-heads f & {:keys [min max frame-dynamic], :or {frame-dynamic :default}})
Returns a dynamic number parameter related to the physical arrangement of the supplied fixtures or heads. First the heads of any fixtures passed in fixtures-or-heads
are included. Then function f
is called for all fixtures or heads, passing in the fixture or head. It must return a literal number or dynamic number parameter.
If you pass a value with either :max
or :min
as optional keyword parameters, this activates result scaling. (If you pass only a :max
value, :min
defaults to zero; if you pass only :min
, then :max
defaults to 255. If you pass neither, scaling is not performed, and the results from f
are returned unchanged.) With scaling active, when it comes time to evaluate this spatial parameter, any dynamic number parameters are evaluated, and the resulting numbers are scaled as a group (after evaluating f
for every participating head or fixture) so they fall within the range [:start
-:end
].
Useful things that f
can do include calculating the distance of the head from some point, either in 3D or along an axis, its angle from some line, and so on. These can allow the creation of lighting gradients across all or part of a show. Spatial parameters make excellent building blocks for color, direction and aim parameters, as shown in the effect examples.
If you do not specify an explicit value for :frame-dynamic
, this spatial parameter will be frame dynamic if any values returned by f
are dynamic parameters which themselves are frame dynamic.
build-step-param
(build-step-param & {:keys [interval interval-ratio fade-fraction fade-curve starting], :or {interval :beat, interval-ratio 1, fade-fraction 0, fade-curve :linear, starting (when *show* (metro-snapshot (:metronome *show*)))}})
Returns a number parameter that increases over time, ideal for convenient control of chases.
With no arguments, the parameter will evaluate to one at the beat closest when it was created, and will increase by one for each beat that passes, with no fades (fractional states).
The optional keyword argument :interval
can be supplied with the value :bar
or :phrase
to change the timing so that it instead relates to bars or phrases. Supplying a value with :interval-ratio
will run the step parameter at the specified fraction or multiple of the chosen interval (beat, bar, or phrase), as illustrated in the Ratios section of the Oscillator documentation.
If fading between steps is desired, the optional keyword argument :fade-fraction
can be supplied with a non-zero value (up to but no greater than 1
). This specifies what fraction of each interval is involved in fading to or from the next value.
See the graphs in the Step Parameters documentation for a visual illustration of how these parameters work.
A fade fraction of 0
provides the default behavior of an instant jump between values with no fading. A fade fraction of 1
means that each value continually fades into the next, and is never steady. A fade fraction of 0.5
would mean that the value is stable half the time, and fading for the other half: during the middle of the interval, the value is steady at its assigned value; once the final quarter of the interval begins, the value starts fading up, reaching the halfway point as the interval ends, and the fade continues through the first quarter of the next interval, finally stabilizing for the next middle section. Smaller fade fractions mean shorter periods of stability and slower fades, while larger fractions yield longer periods of steady values, and quicker fades.
A smoother look can be obtained by using a sine curve to smooth the start and end of each fade, by passing the optional keyword argument :fade-curve
with the value :sine
. (Again, see the graphs to get a visual feel for what this does.)
If the timing should start at an instant other than when the step parameter was created, a metronome snapshot containing the desired start point can be passed with the optional keyword argument :starting
.
All incoming parameters may be dynamic. Step parameters are always frame-dynamic.
build-variable-param
(build-variable-param variable & {:keys [frame-dynamic type default transform-fn], :or {frame-dynamic true, type Number, default 0}})
Create a dynamic parameter whose value is determined by the value held in a variable of *show* at the time evaluation is performed. Unless :frame-dynamic
is passed a false value, this evaluation will happen every frame.
If no type-compatible value is found in the show variable, a default value is returned. That will be the number zero, unless otherwise specified by :default
. The type expected (and returned) by this parameter will be numeric, unless a different value is passed for :type
, (in which case a new type-compatible :default
value must be specified).
If the named show variable already holds a dyamic parameter at the time this variable parameter is created, the binding is short-circuited to return that existing parameter rather than creating a new one, so the type must be compatible. If :transform-fn
is supplied, it will be called with the value of the variable and its return value will be used as the value of the dynamic parameter. It must return a compatible type or its result will be discarded.
check-type
(check-type value type-expected name)
Ensure that a parameter is of a particular type, or that it satisfies IParam and, when evaluated, returns that type, throwing an exception otherwise. Used by the validate-param-type macros to do the actual type checking.
frame-dynamic-param?
(frame-dynamic-param? arg)
Checks whether the argument is an IParam which is dynamic to the frame level.
interpret-color
(interpret-color color)
Accept a color as either a jolby/colors object, an IParam which will produce a color, a keyword, which will be bound to a show variable by the caller, or a string which is passed to the jolby/colors create-color
function.
IParam
protocol
A dynamic parameter which gets evaluated during the run of a light show, with access to the show and its metronome snapshot.
members
evaluate
(evaluate this show snapshot head)
Determine the value of this parameter at a given moment (identified by snapshot
) of the show
. If the parameter is being evaluated for a specific fixture head, that will be passed in head
. If no fixure context is available, head
will be nil
.
frame-dynamic?
(frame-dynamic? this)
If true
, this parameter varies at every frame of the show, and must be invoked by effect assigners for each frame of DMX data generated. If false
, the value can be determined at the time an effect is created, and passed as a constant to the assigners.
resolve-non-frame-dynamic-elements
(resolve-non-frame-dynamic-elements this show snapshot head)
Called when an effect is created using this parameter. If the parameter is not frame-dynamic, this function should return the parameter’s final resolution to a constant of the type returned by result-type
; otherwise, it should return a version of the parameter where any of its own non frame-dynamic input parameters have been resolved.
If the parameter is being evaluated for a specific fixture head, that will be passed in head
. If no fixure context is available, head
will be nil
.
result-type
(result-type this)
The type of value that will be returned when this parameter is resolved.
resolve-param
(resolve-param arg show snapshot)
(resolve-param arg show snapshot head)
Takes an argument which may be a raw value, or may be an IParam. If it is the latter, evaluates it and returns the resulting value. Otherwise just returns the value that was passed in.
resolve-unless-frame-dynamic
(resolve-unless-frame-dynamic arg show snapshot)
(resolve-unless-frame-dynamic arg show snapshot head)
If the first argument is an IParam which is not dynamic all the way to the frame level, return the result of resolving it now. If it is dynamic to the frame level, ask it to resolve any non frame-dynamic elements. Otherwise return it unchanged. If head
is supplied, and the parameter can use it at resolution time, then pass it along.
validate-optional-param-type
macro
(validate-optional-param-type value type-expected)
(validate-optional-param-type value type-expected name)
Ensure that a parameter, if not nil
, satisfies a predicate, or that it satisfies IParam and, when evaluated, returns a type that passes that predicate, throwing an exception otherwise.
validate-param-type
macro
(validate-param-type value type-expected)
(validate-param-type value type-expected name)
Ensure that a parameter satisfies a predicate, or that it satisfies IParam and, when evaluated, returns a type that passes that predicate, throwing an exception otherwise.
vector-from-pan-tilt
(vector-from-pan-tilt pan tilt)
Convert a pan and tilt value (angles in radians away from facing directly out towards the audience) to the corresponding aiming vector.