# $p0 ; period (in pixels)
# $p1 ; amplitude
# $p2 ; amplitude modulation cycles (0=none, number cycles during frame sequence)
# $p3 ; modulation type linear/sinusoidal (dropdown)
# $p4 ; direction (bool: horiz=0 vert=1)
# $p5 ; edge type (dropdown: smear, wrap, blank)
# $p6 ; sine wave (radio group 1)
# $p7 ; triangle (radio group 1)
# $p8 ; velocity (0=constant, else number of pixels shifted each frame)
# Note: GIMP's Ripple plug-in does not directly support either phase shifting
# or negative amplitudes. To implement phase shifting, it is therefore
# necessary to resize the drawable by the amount of the shift. To
# accommodate negative amplitudes, the effect is also phase shifted
# by half the period.
#
# next-modulation and rfx-ripple-phase are each a pair containing
# the current value and the increment amount. Both need to be defined
# globally and therefore can not be defined within a lambda/let.
#
# In the case of rfx-ripple-phase, the value is an offset in the
# range 0 <= X < period (period is in pixels).
#
# In the case of rfx-modulation, the value is an offset that is in the
# range 0 <= X < 1. The script then determines the scaling of
# the actual ripple amplitude based upon the evaluation of either
# the triangle or sinusoidal.
#
&rfx_sendmsg (
qq{
(begin
(if (= $frame $start)
(define next-modulation (make-progressor 0 (* $p2 (/ (succ (- $end $start)))) 1.0)) )
(if (= $frame $start)
(define next-phase (make-progressor 0
(if (> $p8 0)
(- $p0 $p8)
(- $p8) )
$p0 )) )
(let ((period $p0)
(amplitude $p1)
(mod-cycles $p2)
(mod-linear $p3)
(direction $p4)
(edge $p5)
(sine $p6)
(triangle $p7)
(velocity (- $p8))
(phase-offset (next-phase))
(curr-modulation (next-modulation))
)
(let* ((input-file (string-append "$curtmpdir" DIR-SEPARATOR "$in"))
(image (car (gimp-file-load RUN-NONINTERACTIVE input-file input-file)))
(layer (car (gimp-image-get-active-layer image))) )
; calculate layer offfset owing to animated phase
(set! amplitude
(* amplitude
(if (zero? mod-cycles)
1
(let ((fract (- curr-modulation (truncate curr-modulation))))
(if mod-linear
(cond
((< fract 0.25)
(* amplitude fract 4) )
((< fract 0.50)
(* amplitude (- 1 (* (- fract 0.25) 4))) )
((< fract 0.75)
(* amplitude (- (* amplitude (- fract 0.5) 4))) )
(else
(- (* amplitude (- fract 0.75) 4) 1) )))
(sin (* 2 *pi* fract)) ))))
(when (< amplitude 0)
(set! phase-offset (+ phase-offset (/ period 2)))
(if (>= phase-offset period)
(set! phase-offset (- phase-offset period)) ))
(set! amplitude (abs amplitude))
(unless (zero? phase-offset)
(if (zero? direction)
(gimp-layer-resize layer
$width
(+ phase-offset $height)
0
phase-offset )
(gimp-layer-resize layer
(+ phase-offset $width)
$height
phase-offset
0 )))
(plug-in-ripple RUN-NONINTERACTIVE image layer
period
amplitude
direction
edge
sine
TRUE ; always use antialias
FALSE ; we don't need tilability
)
(gimp-layer-resize-to-image-size layer)
(rfx-save-frame image "$out")
)
)
)
}
);