comment { Classes by David Makin for Ultrafractal 5 and later.

Dave's Website
makinmagic@tiscali.co.uk

This version 4th November 2012.
Added Trap Shape Modulus, (trap position)Transform Modulus, (trap position)Offset Matrix Transform, Quick Image and Adjustment Layers and fixed Image Import. 31/12/2011
Updated "MMF Image Import" to allow merging of two imaes among other thongs ;)
4th July 2009.
Added the "Inside" and "Max. distance" colouring options to the directional distance estimator colouring.
2nd July 2009.
Added the "Directional Distance Estimator" colouring. It's essentially ray-tracing in 2D - it's still WIP as I will be adding extra options such as separate colouring formula plug-in options for 'inside' areas and for areas >'max. distance'. 6th May 2009.
Added the "Adjustment Layer" classes and updated the MMF Image Import class and the Layer classes so it is used - e.g. now your individual layers in the MMF Layered colouring can be adjusted prior to use in the MMF Layered layer stack merging.
4th May 2009.
Added the MMF Gradient user gradient class - can be used in MMF Layered, MMF Field Estimator, Extended Cilia and Two Colourings.
Also updated MMF Field Estimator, Extended Cilia and Two Colourings so that when using image mapping in direct colouring mode then the options other than "Image All" now work the same way as "Image All" i.e. allowing colour merging. Plus added 'Image Brightness' as an option for these and the option of mapping the Image modes to a user gradient rather than UF's gradient.
25th March 2009.
Added the symmetry option and a "fix" to the DLA fractal colouring.
Added the convergent and periodic colouring options to the Standard Distance Estimator colouring.
10th December 2008.
Minor improvements to exponential smoothing in Field Estimator.
Added the Switch Magnet 2 formula.

6th December 2008.
Added the Switch Magnet 1 formula.
Added the "fix" to the Magnet 1 Distance Estimator.

29th November 2008
Fixed the default version in Field Estimator. Added more correct distance \ estimation in Magnet 2 Distance Estimator and a fix for some Julias in \ the Nova Distance Estimator.

27th November 2008
Added MMF Nova Distance Estimator. Again designed for use in MMF Field
Estimator but will work as a normal class colouring.

26th November 2008
Added MMF Transfer Merge - allows up to 10 transfers to be combined.

25th November 2008
Added MMF Magnet 2 Distance Estimator. Again it's not truly accurate as a
distance estimator but the algorithm is based on distance estimation and
produces useful colourings.

24th November 2008
Added MMF Magnet 1 Distance Estimator. It's not an accurate distance
estimation but it is based on the normal distance estimation calculations.
The distance estimation angles work quite well.

23rd November 2008
Added the Distance Estimator Base class and the Standard Distance Estimator
and Newton Distance Estimator. Added options to Field Estimator for
convergent formulas.

14th November 2008
Added the "Points per Stimulus" parameter to the DLA Inspired colouring.

12th November 2008
Minor parameter additions to the Field Estimator colouring that make it possible to correct errors in the Field Lines algorithm.

3rd November 2008
Minor fixes to MMF Field Estimator and MMF Two Colourings (backwardly
compatible).

2nd November 2008
Updated the MMF Field Estimator class to include texturing.
Added the new MMF Two Colourings class that allows you to combine any two
gradient colourings in use as the horizontal and vertical mapping values
for mapping images into your fractal.

1st November 2008
Added the MMF Image Import class. Corrected an issue in Cilia colouring for
when using conveergent cilia (backwardly compatible). Changed MMF Smooth
Orbit Traps so that when using image colouring but not using texturing then
any smooth iteration value will be merged in if selected - this change
could potentially break older UPRs that were using the MMF Image colouring.
If you have a problem simply disable 'Add the smooth iteration count". Also
added a version parameter to MMF Smooth Orbit Traps to prevent this sort of
problem occuring again.
Also added some more merge modes to MMF Extended Colour Merge and MMF RGB
Colour Merge.

25th October 2008
Added image mapping to MMF Extended Cilia. Allows separate images for
convergent and divergent areas. Basically works the same as the image
method used in the MMF Colour Selector. When used as a gradient colouring
you can colour the image using the brightness, red, green, blue, alpha,
hue, saturation or brightness values from the image. When used as a direct
colouring you get the exact image instead of the brightness version and
adding the smooth iteration colour or zbasins in this case is done using
colour merging.
Also updated the MMF Layered colouring formula so that for layers using
gradient colourings you can choose to use the gradient colouring in direct
mode. This allows full use of gradient colourings where the gradient mode
and direct mode behaviours differ - such as MMF Extended Cilia whrn using
image mapping.

24th October 2008
Added the "Image Hue" "Image Saturation" and "Image Luminance" options to
the MMF Colour Selector image trap option. Fixed some minor documentation
issues

23rd October 2008
Extended the Smooth Orbit Trap Colouring and the MMF Colour Selector to
include image trap colouring. When used as a gradient colouring you can
colour the image using the red, green, blue, alpha or brightness values
from the image. When used as a direct colouring you get the exact image
instead of the brightness version and texturing in this case is done using
colour merging.

22nd October 2008
Added the "Soft Quantize" modes to MMF Extended Colour Merge and
MMF RGB Colour Merge and fixed the Quantize and Gamma parameters for
MMF RGB Colour Merge so they always appear when they are used.

20th October 2008
Added the "Brightness" and "Colour" merge modes to the MMF Extended Colour
Merge class - as used in the MMF Layered direct colouring.

17th October 2008
Made the "MMF Multi Layer" and "MMF Layer Merge" classes obsolete.
You should now use the "MMF Layered" direct colouring and the layer
classes used in that instead of using the others.
13th October 2008

Updates to the MMF Extended Colour Merge and MMF Layer Merge classes.
Added the following Merge Mode:
Stamp, Soft Dodge, Soft Burn, Inverse Dodge, Inverse Burn, Glow, Heat,
Inverse Fade Down, Inverse Fade Up, Inverse Contrast Down,
Inverse Contrast Up, Inverse Reverse Contrast Down,
Inverse Reverse Contrast Up, Inverse Fade, Inverse Reverse Fade,
Inverse Contrast, Inverse Reverse Contrast, Inverse Quantize,
Inverse Reverse Quantize, Inv. Gamma, Inv. Inverse Gamma,
Inv. Reverse Gamma, Inv. Rev. Inv. Gamma, Inv. Combined Gamma,
Inv. Rev. Combined Gamma and Inverse Stamp.

Updated the Multi Layer colouring so that it has built-in single
colour or gradient colourings and so "solid colour" works properly
with a solid colour parameter added when using user gradients.
10th October 2008
Added MMF_UserGradient, MMF_DefaultGradient, MMF_Gradient101,
MMF_LayerMergeBase, MMF_LayerMerge, MMF_GradientLayerMerge,
MMF_MultiLayerBase, MMF_MultiLayerNone and MMF_MultiLayer.
Changed MMF_ExtendedColorMerge - added the clamp option and
some new merge modes: Fade, Reverse Fade, Contrast, Reverse Contrast
Quantize, Reverse Quantize, Gamma, Inverse Gamma, Reverse Gamma,
Rev. Inv. Gamma, Combined Gamma and Rev. Combined Gamma. Changed MMF_MixedLighting - Fixed so that 'Light transfer' works when
not using perturbation.

15th September 2008 (update from the 11th)
Added rotation on the DLA fractal plug-ins for dead points and seeding.
Added an extra "detection" option in the Smart stimuli DLA plug-ins.
Added "Diamond" seeding to DLA.
Added extra sampling options for the DLA lighting.

11th September 2008
Added classes for Diffusion Limited Aggregation style fractals.

Original version May 2008

} class MMF_DirectionalDE(common.ulb:GradientColoring) { ; ; Updated 4th July 2009
; - Added the "inside" and "maxdist" colouring options
; First version 2nd July 2009.
; public: import "Standard.ulb" ; @param pparent usually "this" from the parent or zero func MMF_DirectionalDE(Generic pparent) GradientColoring.GradientColoring(pparent) m_form = new @p_form(this) m_inside = 0 m_maxdist = 0 if @setinside==2 m_inside = new @p_inside(this) endif if @setmaxdist>=2 m_maxdist = new @p_maxdist(this) endif ilpower = 1.0/log(cabs(m_form.GetUpperBailout())) endfunc ; @param pz the initial z value (unused) ; @param ppixel the pixel value func Init(complex pz, complex ppixel) m_pixel = ppixel m_solid = false endfunc ; @param pz the z value (unused) ; do nothing func Iterate(complex pz) endfunc ; @param pz the final z value (unused) ; Here we repeatedly iterate the chosen formula to get the directional ; distance estimate, essentially 2D ray-tracing. float func ResultIndex(complex pz) complex d = @vector complex zold complex z0 = (0,0) float mx[@iter+6] float found = @maxdist float a = 0.0 float dz = 0.0 float da = 0.0 float t = 0.0 int i int j int n = 0 if @method==1 d = @point-m_pixel endif d = d/cabs(d) if @reverse d = -d endif doinside = false domaxdist = false i = @iter+5 repeat if @control==1 && @steps==1 mx[i] = 1e200 else mx[i]=1/(0.03125*#width*#magn) ; Never step more than 8 pixels at once endif until (i=i-1)<0 repeat pz = m_form.Init(m_pixel+a*d) i = 0 repeat zold = pz pz = m_form.Iterate(pz) until (i=i+1)>=@iter || m_form.IsBailedOut(pz) if i<@iter if @colourby==1 z0 = pz elseif i>1 dz = |pz| dz = i - log(0.5*log(dz))/log(log(dz)/log(|zold|)) elseif @isexp==0 dz = i - log(0.5*log(|pz|))*ilpower else dz = i - log(0.5*log(|pz|))/log(cabs(@power)) endif pz = m_form.Init(m_pixel+(a+1.0/(#width*2.5*#magn/@accuracy))*d) j = 0 repeat zold = pz pz = m_form.Iterate(pz) until (j=j+1)>=@iter || m_form.IsBailedOut(pz) if j<@iter if @colourby==1 a = (#pi + atan2(pz/(pz-z0)))/(2.0*#pi) else if j>1 da = |pz| da = j - log(0.5*log(da))/log(log(da)/log(|zold|)) elseif @isexp==0 da = j - log(0.5*log(|pz|))*ilpower else da = j - log(0.5*log(|pz|))/log(cabs(@power)) endif da = 1.0/(1.0+(#width*2.5*#magn/@accuracy)*abs(t=da-dz)) if da>1/(0.25*#width*#magn/@accuracy) || t<0 if da>mx[i] da = mx[i] else mx[i] = da if da>mx[i+1] da = mx[i+1] endif endif if da=@iter || a>=@maxdist \ || ((@control==0 || @control==2) \ && da<=1/(0.25*#width*#magn/@accuracy)) \ || ((@control==1 || @control==2) \ && n>=@steps) \ || (@control==3 && n>=@steps \ && da<=1/(0.25*#width*#magn/@accuracy)) if @colourby==1 if i<@iter found = a elseif @setinside==0 m_solid = true elseif @setinside==1 found = @maxdist else doinside = true endif elseif a<@maxdist && (i<@iter || n>1) found = a if @setmaxdist==3 domaxdist = true endif elseif i>=@iter if @setinside==0 m_solid = true elseif @setinside==1 found = @maxdist else doinside = true endif elseif @setmaxdist==1 m_solid = true elseif @setmaxdist>1 domaxdist = true endif if domaxdist || doinside pz = m_form.Init(m_pixel) if domaxdist m_maxdist.Init(pz,m_pixel) else m_inside.Init(pz,m_pixel) endif i = 0 repeat pz = m_form.Iterate(pz) if doinside m_inside.Iterate(pz) elseif !m_form.IsBailedOut(pz) m_maxdist.Iterate(pz) endif until (i=i+1)>=@iter || m_form.IsBailedOut(pz) if doinside found = m_inside.ResultIndex(pz) m_solid = m_inside.IsSolid() elseif @setmaxdist==3 && found<@maxdist if (!(m_solid = m_maxdist.IsSolid())) found = ( found*(@maxdist-found) \ + m_maxdist.ResultIndex(pz)*found )/@maxdist endif else found = m_maxdist.ResultIndex(pz) m_solid = m_maxdist.IsSolid() endif endif return found endfunc private: Formula m_form GradientColoring m_inside GradientColoring m_maxdist float ilpower bool doinside bool domaxdist default: title = "MMF Directional Distance Estimator" int param v_mmfdirectionalde caption = "Version (MMF Directional DE)" enum = "1.0" "1.1" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam int param method caption = "Direction" enum = "Vector" "Point" default = 1 endparam complex param vector caption = "Vector" default = (1,-1) hint = "Anything but (0,0) is OK." visible = @method==0 endparam complex param point caption = "Point" default = (0,0) hint = "Any value is OK." visible = @method==1 endparam bool param reverse caption = "Reverse direction" default = false hint = "Does what it says :)" endparam int param colourby caption = "Colour by" enum = "Distance" "Initial Angle" default = 0 hint = "Errors when using 'Initial Angle' can be avoided by decreasing \ the value of the 'Accuracy' parameter." endparam int param setinside caption = "Inside method" enum = "Solid colour" "Max. distance" "Inside Colouring" default = 0 hint = "Choose how to colour the 'inside'." endparam GradientColoring param p_inside caption = "Inside Colouring" default = Standard_OrbitTraps hint = "Use any colouring designed for 'inside' areas." visible = @setinside==2 endparam int param setmaxdist caption = "Max. distance method" enum = "Max. distance" "Solid colour" "Outside Colouring" "Mix" default = 0 hint = "Choose how to colour areas outside the max. distance. Selecting \ 'Mix' means that the 'Outside Colouring' will be mixed with the \ directional DE distance value such that the further from the \ 'inside' then the more significant the outside colouring will be." endparam GradientColoring param p_maxdist caption = "Outside Colouring" default = MMF_SmoothOrbitTraps hint = "Use any colouring designed for 'outside' areas." visible = @colourby==0 && @setmaxdist>1 && (@control!=1 || @steps>1) endparam int param control caption = "Approach method" enum = "Closeness" "Num. steps" "Either" "Both" default = 0 hint = "When using closeness the distance will be calculated to the \ specified 'Accuracy'. If you specify 'Num. steps' then the \ distance algorithm will be repeated for exactly the number of \ 'Steps' specified for each pixel. If you select 'Either' then the \ distance used will be when either the closeness or number of \ steps condition is met and if using 'Both' then the distance will \ only be used when both the closeness and number of steps \ conditions are met." visible = @colourby==0 endparam float param accuracy caption = "Accuracy" default = 0.1 min = 0.0 hint = "The value is in 'pixel' units, the smaller the value the more \ accurate the results but the longer the render will take. Note \ that the 'Accuracy' value is used in the calculations even when \ you have the 'Approach method' set to 'Num. steps' or when \ 'Colour by' is set to 'Initial Angle'. Also note that increasing \ the divergent bailout in the 'Fractal Formula' parameters \ below will also increase the accuracy - often increasing the \ bailout allows you to use larger values for this parameter in \ such a way that renders are faster but still accurate - for \ example on the standard Mandelbrot try this parameter set to 1.0 \ with the fractal formula bailout set to 256. However using \ values >1.0 for this parameter will lose resolution." endparam int param steps caption = "Steps" default = 20 min = 1 hint = "The more steps allowed then the more accurate the results but the \ longer the render will take. Note that setting the 'Approach \ Method' to 'Num. steps' with 'Steps' set to 1 effectively gives \ an alternative colouring method based on iteration density." visible = @colourby==0 && @control!=0 endparam float param maxdist caption = "Maximum Distance" default = 1.0 visible = @colourby==0 hint = "Reducing the value will produce larger areas of solid colour but \ can dramatically reduce rendering times." endparam int param iter caption = "Iterations" default = 100 min = 10 hint = "Minimum is 10. Increase the value to fill the holes in the \ centres of spirals when you zoom in." endparam int param isexp caption = "Get Exponent value" enum = "From fractal formula" "From parameter" default = 0 hint = "For many chosen 'Fractal Formula's the correct exponent can be \ gotten from the fractal formula but in some cases you may have \ to specify a correct value manually (especially when the fractal \ formula includes transforms etc.). Note that the exponent value \ is only actually required for areas that bailout on the very first \ iteration." endparam complex param power caption = "Power/Exponent" default = (2,0) hint = "This should be the power/exponent for the 'Fractal Formula' \ below i.e. it's the usual 'iteration smoothing' exponent." visible = @isexp>0 endparam Formula param p_form caption = "Fractal Formula" default = MMF_SwitchStandard hint = "Choose the formula to use, the parameters you choose for the \ formula need to make it divergent for correct use of the \ directional DE colouring. Also the larger the divergent bailout \ value then the more accurate the DE results." endparam } class MMF_UserGradient(common.ulb:Generic) { public: ;

; @param pparent typically 'this' from the parent or zero func MMF_UserGradient(Generic pparent) m_Parent = pparent endfunc ;

; @param i gradient index ; @return colour from gradient color func GetColour(float i) return RGBA(0,0,0,1) endfunc default: int param v_mmfgradientbase caption = "Version (MMF_GradientBase)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_mmfgradientbase < 100 endparam } class MMF_DefaultGradient(MMF_UserGradient) { public: import "common.ulb" ;

; @param pparent typically 'this' from the parent or zero func MMF_UserGradient(Generic pparent) m_Parent = pparent endfunc ;

; @param i gradient index ; @return colour from gradient color func GetColour(float i) return gradient(i) endfunc default: title = "MMF Default Gradient" } class MMF_Gradient101(MMF_UserGradient) { import "common.ulb" ;

; @param pparent typically 'this' from the parent or zero func MMF_Gradient101(Generic pparent) m_Parent = pparent m_Transfer = new @f_transfer(this) col[1] = @col1 pstn[1] = @pos1/400.0 col[2] = @col2 pstn[2] = @pos2/400.0 col[3] = @col3 pstn[3] = @pos3/400.0 col[4] = @col4 pstn[4] = @pos4/400.0 col[5] = @col5 pstn[5] = @pos5/400.0 col[6] = @col6 pstn[6] = @pos6/400.0 col[7] = @col7 pstn[7] = @pos7/400.0 col[8] = @col8 pstn[8] = @pos8/400.0 col[9] = @col9 pstn[9] = @pos9/400.0 col[10] = @col10 pstn[10] = @pos10/400.0 col[11] = @col11 pstn[11] = @pos11/400.0 col[12] = @col12 pstn[12] = @pos12/400.0 col[13] = @col13 pstn[13] = @pos13/400.0 col[14] = @col14 pstn[14] = @pos14/400.0 col[15] = @col15 pstn[15] = @pos15/400.0 col[16] = @col16 pstn[16] = @pos16/400.0 col[17] = @col17 pstn[17] = @pos17/400.0 col[18] = @col18 pstn[18] = @pos18/400.0 col[19] = @col19 pstn[19] = @pos19/400.0 col[20] = @col20 pstn[20] = @pos20/400.0 col[21] = @col21 pstn[21] = @pos21/400.0 col[22] = @col22 pstn[22] = @pos22/400.0 col[23] = @col23 pstn[23] = @pos23/400.0 col[24] = @col24 pstn[24] = @pos24/400.0 col[25] = @col25 pstn[25] = @pos25/400.0 col[26] = @col26 pstn[26] = @pos26/400.0 col[27] = @col27 pstn[27] = @pos27/400.0 col[28] = @col28 pstn[28] = @pos28/400.0 col[29] = @col29 pstn[29] = @pos29/400.0 col[30] = @col30 pstn[30] = @pos30/400.0 col[31] = @col31 pstn[31] = @pos31/400.0 col[32] = @col32 pstn[32] = @pos32/400.0 col[33] = @col33 pstn[33] = @pos33/400.0 col[34] = @col34 pstn[34] = @pos34/400.0 col[35] = @col35 pstn[35] = @pos35/400.0 col[36] = @col36 pstn[36] = @pos36/400.0 col[37] = @col37 pstn[37] = @pos37/400.0 col[38] = @col38 pstn[38] = @pos38/400.0 col[39] = @col39 pstn[39] = @pos39/400.0 col[40] = @col40 pstn[40] = @pos40/400.0 col[41] = @col41 pstn[41] = @pos41/400.0 col[42] = @col42 pstn[42] = @pos42/400.0 col[43] = @col43 pstn[43] = @pos43/400.0 col[44] = @col44 pstn[44] = @pos44/400.0 col[45] = @col45 pstn[45] = @pos45/400.0 col[46] = @col46 pstn[46] = @pos46/400.0 col[47] = @col47 pstn[47] = @pos47/400.0 col[48] = @col48 pstn[48] = @pos48/400.0 col[49] = @col49 pstn[49] = @pos49/400.0 col[50] = @col50 pstn[50] = @pos50/400.0 col[51] = @col51 pstn[51] = @pos51/400.0 col[52] = @col52 pstn[52] = @pos52/400.0 col[53] = @col53 pstn[53] = @pos53/400.0 col[54] = @col54 pstn[54] = @pos54/400.0 col[55] = @col55 pstn[55] = @pos55/400.0 col[56] = @col56 pstn[56] = @pos56/400.0 col[57] = @col57 pstn[57] = @pos57/400.0 col[58] = @col58 pstn[58] = @pos58/400.0 col[59] = @col59 pstn[59] = @pos59/400.0 col[60] = @col60 pstn[60] = @pos60/400.0 col[61] = @col61 pstn[61] = @pos61/400.0 col[62] = @col62 pstn[62] = @pos62/400.0 col[63] = @col63 pstn[63] = @pos63/400.0 col[64] = @col64 pstn[64] = @pos64/400.0 col[65] = @col65 pstn[65] = @pos65/400.0 col[66] = @col66 pstn[66] = @pos66/400.0 col[67] = @col67 pstn[67] = @pos67/400.0 col[68] = @col68 pstn[68] = @pos68/400.0 col[69] = @col69 pstn[69] = @pos69/400.0 col[70] = @col70 pstn[70] = @pos70/400.0 col[71] = @col71 pstn[71] = @pos71/400.0 col[72] = @col72 pstn[72] = @pos72/400.0 col[73] = @col73 pstn[73] = @pos73/400.0 col[74] = @col74 pstn[74] = @pos74/400.0 col[75] = @col75 pstn[75] = @pos75/400.0 col[76] = @col76 pstn[76] = @pos76/400.0 col[77] = @col77 pstn[77] = @pos77/400.0 col[78] = @col78 pstn[78] = @pos78/400.0 col[79] = @col79 pstn[79] = @pos79/400.0 col[80] = @col80 pstn[80] = @pos80/400.0 col[81] = @col81 pstn[81] = @pos81/400.0 col[82] = @col82 pstn[82] = @pos82/400.0 col[83] = @col83 pstn[83] = @pos83/400.0 col[84] = @col84 pstn[84] = @pos84/400.0 col[85] = @col85 pstn[85] = @pos85/400.0 col[86] = @col86 pstn[86] = @pos86/400.0 col[87] = @col87 pstn[87] = @pos87/400.0 col[88] = @col88 pstn[88] = @pos88/400.0 col[89] = @col89 pstn[89] = @pos89/400.0 col[90] = @col90 pstn[90] = @pos90/400.0 col[91] = @col91 pstn[91] = @pos91/400.0 col[92] = @col92 pstn[92] = @pos92/400.0 col[93] = @col93 pstn[93] = @pos93/400.0 col[94] = @col94 pstn[94] = @pos94/400.0 col[95] = @col95 pstn[95] = @pos95/400.0 col[96] = @col96 pstn[96] = @pos96/400.0 col[97] = @col97 pstn[97] = @pos97/400.0 col[98] = @col98 pstn[98] = @pos98/400.0 col[99] = @col99 pstn[99] = @pos99/400.0 col[100] = @col100 pstn[100] = @pos100/400.0 int i = 0 repeat col[i] = col[i+1] pstn[i] = pstn[i+1] until (i=i+1)>=100 col[100] = @col101 pstn[100] = @pos101/400.0 if @numcols>1 i = 0 repeat float min = pstn[i] int k = i int j = i + 1 repeat if pstn[j]=@numcols if k!=i color tc = col[i] col[i] = col[k] col[k] = tc float tv = pstn[i] pstn[i] = pstn[k] pstn[k] = tv endif until (i=i+1)>=@numcols-1 endif endfunc ;

; @param i gradient index ; @return colour from gradient color func GetColour(float i) if @showpalette i = real(#screenpixel)/#width else i = m_Transfer.Iterate(i) endif if @numcols==1 return col[0] endif if @rept if (i = i%1)<0.0 i = i + 1.0 endif elseif i<0.0 i = 0.0 elseif i>399.0/400.0 i = 399.0/400.0 endif int j = -1 int k = 0 repeat j = j + 1 until pstn[j]>i || j>=@numcols if j>=@numcols j = 0 k = @numcols - 1 elseif (k=j-1)<0 k = @numcols - 1 endif float d = pstn[j] - pstn[k] float v = i - pstn[k] if d<0.0 d = 1.0 + d if d==0.0 d = 1.0 endif endif if v<0.0 v = 1.0 + v endif if @smooth ; Our point is between p1 at x1 with height h1 and p2 at x2 with height h2 ; First if h1==h2 then h==h1 ; Else get gradient g1 at p1 and g2 at p2 and use: ; ; h = ax^3 + bx^2 + cx + d ; g = 3*a*x^2 + 2*b*x + c ; ; h1 = a*x1^3 +b*x1^2 + c*x1 + d ; g1 = 3*a*x1^2 + 2*b*x1 + c ; h2 = a*x2^3 + b*x2^2 + c*x2 + d ; g2 = 3*a*x2^2 + 2*b*x2 + c ; ; But we can use 0 for x1 and (x2-x1) for x2, giving: ; ; h1 = d ; g1 = c ; h2 = a*(x2-x1)^3 + b*(x2-x1)^2 + c*(x2-x1) + d ; g2 = 3*a*(x2-x1)^2 + 2*b*(x2-x1) + c ; ; Hence: ; ; a*(x2-x1)^3 + b*(x2-x1)^2 + g1*(x2-x1) + h1 = h2 ; 3*a*(x2-x1)^2 + 2*b*(x2-x1) + g1 = g2 ; ; a = (g2 - g1 - 2*b*(x2-x1))/(3*(x2-x1)^2) ; ; (g2-g1)(x2-x1)/3 - 2*b*(x2-x1)^2/3 + b*(x2-x1)^2 + g1*(x2-x1) + h1 = h2 ; ; (2*g1+g2)(x2-x1)/3 + b*(x2-x1)^2/3 + h1 = h2 ; ; b = 3*(h2-h1)/(x2-x1)^2 - (2*g1+g2)/(x2-x1) ; ; h1 float r1 = red(col[k]) float g1 = green(col[k]) float b1 = blue(col[k]) float a1 = alpha(col[k]) ; h2 float r2 = red(col[j]) float g2 = green(col[j]) float b2 = blue(col[j]) float a2 = alpha(col[j]) if r1==r2 && g1==g2 && b1==b2 && a1==a2 return col[k] endif ; g1 float gr1 = 0.0 float gg1 = 0.0 float gb1 = 0.0 float ga1 =0.0 ; g2 float gr2 = 0.0 float gg2 = 0.0 float gb2 = 0.0 float ga2 = 0.0 ; temp gradients float id = 1.0/d float tr = (red(col[j])-red(col[k]))*id float tg = (green(col[j])-green(col[k]))*id float tb = (blue(col[j])-blue(col[k]))*id float ta = (alpha(col[j])-alpha(col[k]))*id int l = k - 1 int m = j + 1 if l<0 l = @numcols - 1 if pstn[k]==0.0 && pstn[l]==1.0 l = k endif endif if m>=@numcols m = 0 if pstn[j]==1.0 && pstn[m]==0.0 m = j endif endif if pstn[l]==pstn[k] gr1 = gg1 = gb1 = ga1 = 0.0 else float d1 = pstn[k] - pstn[l] if d1<0.0 d1 = d1 + 1.0 endif d1 = 1.0/d1 gr1 = (red(col[k])-red(col[l]))*d1 gg1 = (green(col[k])-green(col[l]))*d1 gb1 = (blue(col[k])-blue(col[l]))*d1 ga1 = (alpha(col[k])-alpha(col[l]))*d1 if (gr1>=0.0 && tr<=0.0) || (gr1<=0.0 && tr>=0.0) gr1 = 0.0 else gr1 = 0.5*(gr1 + tr) endif if (gg1>=0.0 && tg<=0.0) || (gg1<=0.0 && tg>=0.0) gg1 = 0.0 else gg1 = 0.5*(gg1 + tg) endif if (gb1>=0.0 && tb<=0.0) || (gb1<=0.0 && tb>=0.0) gb1 = 0.0 else gb1 = 0.5*(gb1 + tb) endif if (ga1>=0.0 && ta<=0.0) || (ga1<=0.0 && ta>=0.0) ga1 = 0.0 else ga1 = 0.5*(ga1 + ta) endif endif if pstn[m]==pstn[j] gr2 = gg2 = gb2 = ga2 = 0.0 else float d1 = pstn[m] - pstn[j] if d1<0.0 d1 = d1 + 1.0 endif d1 = 1.0/d1 gr2 = (red(col[m])-red(col[j]))*d1 gg2 = (green(col[m])-green(col[j]))*d1 gb2 = (blue(col[m])-blue(col[j]))*d1 ga2 = (alpha(col[m])-alpha(col[j]))*d1 if (gr2>=0.0 && tr<=0.0) || (gr2<=0.0 && tr>=0.0) gr2 = 0.0 else gr2 = 0.5*(gr2 + tr) endif if (gg2>=0.0 && tg<=0.0) || (gg2<=0.0 && tg>=0.0) gg2 = 0.0 else gg2 = 0.5*(gg2 + tg) endif if (gb2>=0.0 && tb<=0.0) || (gb2<=0.0 && tb>=0.0) gb2 = 0.0 else gb2 = 0.5*(gb2 + tb) endif if (ga2>=0.0 && ta<=0.0) || (ga2<=0.0 && ta>=0.0) ga2 = 0.0 else ga2 = 0.5*(ga2 + ta) endif endif ; b = 3*(h2-h1)/(x2-x1)^2 - (2*g1+g2)/(x2-x1) ; a = (g2 - g1 - 2*b*(x2-x1))/(3*(x2-x1)^2) ; h = ax^3 + bx^2 + cx + d float a = 0.0 float b = 0.0 if r1!=r2 b = 3*(r2-r1)*sqr(id) - (2*gr1+gr2)*id a = (gr2-gr1-2.0*b*d)*sqr(id)/3 r1 = a*v^3 + b*sqr(v) + gr1*v + r1 endif if g1!=g2 b = 3*(g2-g1)*sqr(id) - (2*gg1+gg2)*id a = (gg2-gg1-2.0*b*d)*sqr(id)/3 g1 = a*v^3 + b*sqr(v) + gg1*v + g1 endif if b1!=b2 b = 3*(b2-b1)*sqr(id) - (2*gb1+gb2)*id a = (gb2-gb1-2.0*b*d)*sqr(id)/3 b1 = a*v^3 + b*sqr(v) + gb1*v + b1 endif if a1!=a2 b = 3*(a2-a1)*sqr(id) - (2*ga1+ga2)*id a = (ga2-ga1-2.0*b*d)*sqr(id)/3 a1 = a*v^3 + b*sqr(v) + ga1*v + a1 endif return RGBA(r1,g1,b1,a1) else return col[k] + (col[j] - col[k])*v/d endif endfunc private: Transfer m_Transfer color col[101] float pstn[101] default: title = "MMF Gradient 101" rating = recommended int param v_mmfgradient101 caption = "Version (MMF Gradient 101)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam heading caption = "Gradient Control" endheading Transfer param f_transfer caption = "Gradient Transfer" default = DefaultGradientTransfer hint = "Use to modify the value from the colouring before the colour \ is looked up in the gradient." visible = !@showpalette endparam bool param rept caption = "Repeat Gradient ?" default = true endparam bool param smooth caption = "Smooth Curves ?" default = true endparam bool param showpalette caption = "Show Gradient Only" default = false hint = "When enabled the gradient is shown as vertical stripes on the \ fractal, position 0.0 to the left and 1.0 to the right." endparam int param numcols caption = "Number of Key Colours" default = 4 min = 1 max = 101 hint = "You can specify from 1 to 101 key colours in your gradient, \ each of which can be at any position in the gradient from \ >=0.0 to <=400.0" endparam heading caption = "Key Colour 1" endheading color param col1 caption = "Colour" default = RGBA(0,0,0.52156862745098039215686274509804,1) endparam float param pos1 caption = "Gradient Index" default = 0.0 min = 0.0 max = 400.0 endparam heading caption = "Key Colour 2" visible = @numcols>=2 endheading color param col2 caption = "Colour" default = RGBA(1,1,1,1) visible = @numcols>=2 endparam float param pos2 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=2 endparam heading caption = "Key Colour 3" visible = @numcols>=3 endheading color param col3 caption = "Colour" default = RGBA(1,0.70980392156862745098039215686275,0,1) visible = @numcols>=3 endparam float param pos3 caption = "Gradient Index" default = 200.0 min = 0.0 max = 400.0 visible = @numcols>=3 endparam heading caption = "Key Colour 4" visible = @numcols>=4 endheading color param col4 caption = "Colour" default = RGBA(0.61176470588235294117647058823529,0,0,1) visible = @numcols>=4 endparam float param pos4 caption = "Gradient Index" default = 300.0 min = 0.0 max = 400.0 visible = @numcols>=4 endparam heading caption = "Key Colour 5" visible = @numcols>=5 endheading color param col5 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=5 endparam float param pos5 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=5 endparam heading caption = "Key Colour 6" visible = @numcols>=6 endheading color param col6 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=6 endparam float param pos6 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=6 endparam heading caption = "Key Colour 7" visible = @numcols>=7 endheading color param col7 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=7 endparam float param pos7 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=7 endparam heading caption = "Key Colour 8" visible = @numcols>=8 endheading color param col8 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=8 endparam float param pos8 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=8 endparam heading caption = "Key Colour 9" visible = @numcols>=9 endheading color param col9 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=9 endparam float param pos9 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=9 endparam heading caption = "Key Colour 10" visible = @numcols>=10 endheading color param col10 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=10 endparam float param pos10 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=10 endparam heading caption = "Key Colour 11" visible = @numcols>=11 endheading color param col11 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=11 endparam float param pos11 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=11 endparam heading caption = "Key Colour 12" visible = @numcols>=12 endheading color param col12 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=12 endparam float param pos12 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=12 endparam heading caption = "Key Colour 13" visible = @numcols>=13 endheading color param col13 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=13 endparam float param pos13 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=13 endparam heading caption = "Key Colour 14" visible = @numcols>=14 endheading color param col14 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=14 endparam float param pos14 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=14 endparam heading caption = "Key Colour 15" visible = @numcols>=15 endheading color param col15 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=15 endparam float param pos15 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=15 endparam heading caption = "Key Colour 16" visible = @numcols>=16 endheading color param col16 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=16 endparam float param pos16 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=16 endparam heading caption = "Key Colour 17" visible = @numcols>=17 endheading color param col17 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=17 endparam float param pos17 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=17 endparam heading caption = "Key Colour 18" visible = @numcols>=18 endheading color param col18 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=18 endparam float param pos18 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=18 endparam heading caption = "Key Colour 19" visible = @numcols>=19 endheading color param col19 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=19 endparam float param pos19 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=19 endparam heading caption = "Key Colour 20" visible = @numcols>=20 endheading color param col20 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=20 endparam float param pos20 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=20 endparam heading caption = "Key Colour 21" visible = @numcols>=21 endheading color param col21 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=21 endparam float param pos21 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=21 endparam heading caption = "Key Colour 22" visible = @numcols>=22 endheading color param col22 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=22 endparam float param pos22 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=22 endparam heading caption = "Key Colour 23" visible = @numcols>=23 endheading color param col23 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=23 endparam float param pos23 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=23 endparam heading caption = "Key Colour 24" visible = @numcols>=24 endheading color param col24 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=24 endparam float param pos24 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=24 endparam heading caption = "Key Colour 25" visible = @numcols>=25 endheading color param col25 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=25 endparam float param pos25 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=25 endparam heading caption = "Key Colour 26" visible = @numcols>=26 endheading color param col26 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=26 endparam float param pos26 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=26 endparam heading caption = "Key Colour 27" visible = @numcols>=27 endheading color param col27 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=27 endparam float param pos27 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=27 endparam heading caption = "Key Colour 28" visible = @numcols>=28 endheading color param col28 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=28 endparam float param pos28 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=28 endparam heading caption = "Key Colour 29" visible = @numcols>=29 endheading color param col29 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=29 endparam float param pos29 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=29 endparam heading caption = "Key Colour 30" visible = @numcols>=30 endheading color param col30 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=30 endparam float param pos30 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=30 endparam heading caption = "Key Colour 31" visible = @numcols>=31 endheading color param col31 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=31 endparam float param pos31 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=31 endparam heading caption = "Key Colour 32" visible = @numcols>=32 endheading color param col32 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=32 endparam float param pos32 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=32 endparam heading caption = "Key Colour 33" visible = @numcols>=33 endheading color param col33 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=33 endparam float param pos33 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=33 endparam heading caption = "Key Colour 34" visible = @numcols>=34 endheading color param col34 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=34 endparam float param pos34 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=34 endparam heading caption = "Key Colour 35" visible = @numcols>=35 endheading color param col35 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=35 endparam float param pos35 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=35 endparam heading caption = "Key Colour 36" visible = @numcols>=36 endheading color param col36 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=36 endparam float param pos36 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=36 endparam heading caption = "Key Colour 37" visible = @numcols>=37 endheading color param col37 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=37 endparam float param pos37 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=37 endparam heading caption = "Key Colour 38" visible = @numcols>=38 endheading color param col38 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=38 endparam float param pos38 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=38 endparam heading caption = "Key Colour 39" visible = @numcols>=39 endheading color param col39 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=39 endparam float param pos39 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=39 endparam heading caption = "Key Colour 40" visible = @numcols>=40 endheading color param col40 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=40 endparam float param pos40 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=40 endparam heading caption = "Key Colour 41" visible = @numcols>=41 endheading color param col41 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=41 endparam float param pos41 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=41 endparam heading caption = "Key Colour 42" visible = @numcols>=42 endheading color param col42 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=42 endparam float param pos42 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=42 endparam heading caption = "Key Colour 43" visible = @numcols>=43 endheading color param col43 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=43 endparam float param pos43 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=43 endparam heading caption = "Key Colour 44" visible = @numcols>=44 endheading color param col44 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=44 endparam float param pos44 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=44 endparam heading caption = "Key Colour 45" visible = @numcols>=45 endheading color param col45 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=45 endparam float param pos45 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=45 endparam heading caption = "Key Colour 46" visible = @numcols>=46 endheading color param col46 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=46 endparam float param pos46 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=46 endparam heading caption = "Key Colour 47" visible = @numcols>=47 endheading color param col47 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=47 endparam float param pos47 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=47 endparam heading caption = "Key Colour 48" visible = @numcols>=48 endheading color param col48 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=48 endparam float param pos48 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=48 endparam heading caption = "Key Colour 49" visible = @numcols>=49 endheading color param col49 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=49 endparam float param pos49 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=49 endparam heading caption = "Key Colour 50" visible = @numcols>=50 endheading color param col50 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=50 endparam float param pos50 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=50 endparam heading caption = "Key Colour 51" visible = @numcols>=51 endheading color param col51 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=51 endparam float param pos51 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=51 endparam heading caption = "Key Colour 52" visible = @numcols>=52 endheading color param col52 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=52 endparam float param pos52 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=52 endparam heading caption = "Key Colour 53" visible = @numcols>=53 endheading color param col53 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=53 endparam float param pos53 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=53 endparam heading caption = "Key Colour 54" visible = @numcols>=54 endheading color param col54 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=54 endparam float param pos54 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=54 endparam heading caption = "Key Colour 55" visible = @numcols>=55 endheading color param col55 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=55 endparam float param pos55 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=55 endparam heading caption = "Key Colour 56" visible = @numcols>=56 endheading color param col56 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=56 endparam float param pos56 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=56 endparam heading caption = "Key Colour 57" visible = @numcols>=57 endheading color param col57 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=57 endparam float param pos57 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=57 endparam heading caption = "Key Colour 58" visible = @numcols>=58 endheading color param col58 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=58 endparam float param pos58 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=58 endparam heading caption = "Key Colour 59" visible = @numcols>=59 endheading color param col59 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=59 endparam float param pos59 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=59 endparam heading caption = "Key Colour 60" visible = @numcols>=60 endheading color param col60 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=60 endparam float param pos60 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=60 endparam heading caption = "Key Colour 61" visible = @numcols>=61 endheading color param col61 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=61 endparam float param pos61 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=61 endparam heading caption = "Key Colour 62" visible = @numcols>=62 endheading color param col62 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=62 endparam float param pos62 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=62 endparam heading caption = "Key Colour 63" visible = @numcols>=63 endheading color param col63 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=63 endparam float param pos63 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=63 endparam heading caption = "Key Colour 64" visible = @numcols>=64 endheading color param col64 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=64 endparam float param pos64 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=64 endparam heading caption = "Key Colour 65" visible = @numcols>=65 endheading color param col65 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=65 endparam float param pos65 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=65 endparam heading caption = "Key Colour 66" visible = @numcols>=66 endheading color param col66 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=66 endparam float param pos66 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=66 endparam heading caption = "Key Colour 67" visible = @numcols>=67 endheading color param col67 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=67 endparam float param pos67 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=67 endparam heading caption = "Key Colour 68" visible = @numcols>=68 endheading color param col68 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=68 endparam float param pos68 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=68 endparam heading caption = "Key Colour 69" visible = @numcols>=69 endheading color param col69 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=69 endparam float param pos69 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=69 endparam heading caption = "Key Colour 70" visible = @numcols>=70 endheading color param col70 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=70 endparam float param pos70 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=70 endparam heading caption = "Key Colour 71" visible = @numcols>=71 endheading color param col71 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=71 endparam float param pos71 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=71 endparam heading caption = "Key Colour 72" visible = @numcols>=72 endheading color param col72 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=72 endparam float param pos72 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=72 endparam heading caption = "Key Colour 73" visible = @numcols>=73 endheading color param col73 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=73 endparam float param pos73 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=73 endparam heading caption = "Key Colour 74" visible = @numcols>=74 endheading color param col74 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=74 endparam float param pos74 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=74 endparam heading caption = "Key Colour 75" visible = @numcols>=75 endheading color param col75 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=75 endparam float param pos75 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=75 endparam heading caption = "Key Colour 76" visible = @numcols>=76 endheading color param col76 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=76 endparam float param pos76 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=76 endparam heading caption = "Key Colour 77" visible = @numcols>=77 endheading color param col77 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=77 endparam float param pos77 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=77 endparam heading caption = "Key Colour 78" visible = @numcols>=78 endheading color param col78 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=78 endparam float param pos78 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=78 endparam heading caption = "Key Colour 79" visible = @numcols>=79 endheading color param col79 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=79 endparam float param pos79 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=79 endparam heading caption = "Key Colour 80" visible = @numcols>=80 endheading color param col80 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=80 endparam float param pos80 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=80 endparam heading caption = "Key Colour 81" visible = @numcols>=81 endheading color param col81 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=81 endparam float param pos81 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=81 endparam heading caption = "Key Colour 82" visible = @numcols>=82 endheading color param col82 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=82 endparam float param pos82 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=82 endparam heading caption = "Key Colour 83" visible = @numcols>=83 endheading color param col83 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=83 endparam float param pos83 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=83 endparam heading caption = "Key Colour 84" visible = @numcols>=84 endheading color param col84 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=84 endparam float param pos84 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=84 endparam heading caption = "Key Colour 85" visible = @numcols>=85 endheading color param col85 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=85 endparam float param pos85 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=85 endparam heading caption = "Key Colour 86" visible = @numcols>=86 endheading color param col86 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=86 endparam float param pos86 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=86 endparam heading caption = "Key Colour 87" visible = @numcols>=87 endheading color param col87 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=87 endparam float param pos87 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=87 endparam heading caption = "Key Colour 88" visible = @numcols>=88 endheading color param col88 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=88 endparam float param pos88 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=88 endparam heading caption = "Key Colour 89" visible = @numcols>=89 endheading color param col89 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=89 endparam float param pos89 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=89 endparam heading caption = "Key Colour 90" visible = @numcols>=90 endheading color param col90 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=90 endparam float param pos90 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=90 endparam heading caption = "Key Colour 91" visible = @numcols>=91 endheading color param col91 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=91 endparam float param pos91 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=91 endparam heading caption = "Key Colour 92" visible = @numcols>=92 endheading color param col92 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=92 endparam float param pos92 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=92 endparam heading caption = "Key Colour 93" visible = @numcols>=93 endheading color param col93 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=93 endparam float param pos93 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=93 endparam heading caption = "Key Colour 94" visible = @numcols>=94 endheading color param col94 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=94 endparam float param pos94 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=94 endparam heading caption = "Key Colour 95" visible = @numcols>=95 endheading color param col95 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=95 endparam float param pos95 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=95 endparam heading caption = "Key Colour 96" visible = @numcols>=96 endheading color param col96 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=96 endparam float param pos96 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=96 endparam heading caption = "Key Colour 97" visible = @numcols>=97 endheading color param col97 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=97 endparam float param pos97 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=97 endparam heading caption = "Key Colour 98" visible = @numcols>=98 endheading color param col98 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=98 endparam float param pos98 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=98 endparam heading caption = "Key Colour 99" visible = @numcols>=99 endheading color param col99 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=99 endparam float param pos99 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=99 endparam heading caption = "Key Colour 100" visible = @numcols>=100 endheading color param col100 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=100 endparam float param pos100 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=100 endparam heading caption = "Key Colour 101" visible = @numcols>=101 endheading color param col101 caption = "Colour" default = RGBA(1,0,0,1) visible = @numcols>=101 endparam float param pos101 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 visible = @numcols>=101 endparam } class MMF_KeyColourBase(common.ulb:Generic) { import "common.ulb" func MMF_KeyColourBase(Generic pparent) m_Parent = pparent endfunc int func GetNumCols() return 0 endfunc color func GetNextColour() return RGBA(0,0,0,1) endfunc float func GetNextIndex() return 0 endfunc default: int param v_mmfkeycolourbase caption = "Version (MMF_KeyColourBase)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_mmfkeycolourbase < 100 endparam } class MMF_NullKeyColour(MMF_KeyColourBase) { default: title = "Null Key Colour" } class MMF_OneKeyColour(MMF_KeyColourBase) { import "common.ulb" func MMF_OneKeyColour(Generic pparent) m_Parent = pparent endfunc int func GetNumCols() return 1 endfunc color func GetNextColour() return @colour endfunc float func GetNextIndex() return 0.0025*@index endfunc default: title = "One Key Colour" int param v_mmfonekeycolour caption = "Version (MMF_OneKeyColour)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_mmfonekeycolour < 100 endparam color param colour caption = "Colour" default = RGBA(0,0,0,1) endparam float param index caption = "Gradient Index" default = 0.0 min = 0.0 max = 400.0 endparam } class MMF_TwoKeyColours(MMF_KeyColourBase) { import "common.ulb" func MMF_TwoKeyColours(Generic pparent) m_Parent = pparent cols = indexes = 0 endfunc int func GetNumCols() cols = indexes = 0 return 2 endfunc color func GetNextColour() if cols==0 cols = 1 return @colour0 endif cols = 0 return @colour1 endfunc float func GetNextIndex() if indexes==0 indexes = 1 return 0.0025*@index0 endif indexes = 0 return 0.0025*@index1 endfunc private: int cols int indexes default: title = "Two Key Colours" int param v_mmftwokeycolours caption = "Version (MMF_TwoKeyColours)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_mmftwokeycolours < 100 endparam heading endheading color param colour0 caption = "Colour" default = RGBA(0,0,0,1) endparam float param index0 caption = "Gradient Index" default = 0.0 min = 0.0 max = 400.0 endparam heading endheading color param colour1 caption = "Colour" default = RGBA(1,1,1,1) endparam float param index1 caption = "Gradient Index" default = 400.0 min = 0.0 max = 400.0 endparam } class MMF_ThreeKeyColours(MMF_KeyColourBase) { import "common.ulb" func MMF_ThreeKeyColours(Generic pparent) m_Parent = pparent cols = indexes = 0 endfunc int func GetNumCols() cols = indexes = 0 return 3 endfunc color func GetNextColour() if cols==0 cols = 1 return @colour0 elseif cols==1 cols = 2 return @colour1 endif cols = 0 return @colour2 endfunc float func GetNextIndex() if indexes==0 indexes = 1 return 0.0025*@index0 elseif indexes==1 indexes = 2 return 0.0025*@index1 endif indexes = 0 return 0.0025*@index2 endfunc private: int cols int indexes default: title = "Three Key Colours" int param v_mmfthreekeycolours caption = "Version (MMF_ThreeKeyColours)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_mmfthreekeycolours < 100 endparam heading endheading color param colour0 caption = "Colour" default = RGBA(1,0,0,1) endparam float param index0 caption = "Gradient Index" default = 0.0 min = 0.0 max = 400.0 endparam heading endheading color param colour1 caption = "Colour" default = RGBA(0,1,0,1) endparam float param index1 caption = "Gradient Index" default = 200.0 min = 0.0 max = 400.0 endparam heading endheading color param colour2 caption = "Colour" default = RGBA(0,0,1,1) endparam float param index2 caption = "Gradient Index" default = 400.0 min = 0.0 max = 400.0 endparam } class MMF_FourKeyColours(MMF_KeyColourBase) { import "common.ulb" func MMF_FourKeyColours(Generic pparent) m_Parent = pparent cols = indexes = 0 col[0] = @colour0 col[1] = @colour1 col[2] = @colour2 col[3] = @colour3 col[4] = @colour4 col[5] = @colour5 col[6] = @colour6 col[7] = @colour7 col[8] = @colour8 col[9] = @colour9 index[0] = @index0 index[1] = @index1 index[2] = @index2 index[3] = @index3 index[4] = @index4 index[5] = @index5 index[6] = @index6 index[7] = @index7 index[8] = @index8 index[9] = @index9 endfunc int func GetNumCols() cols = indexes = 0 return @numcols+4 endfunc color func GetNextColour() color c = col[cols] if (cols=cols+1)>=@numcols+4 cols = 0 endif return c endfunc float func GetNextIndex() float i = index[indexes] if (indexes=indexes+1)>@numcols+4 indexes = 0 endif return 0.0025*i endfunc private: color col[10] float index[10] int cols int indexes default: title = "4 to 10 Key Colours" int param v_mmffourkeycolours caption = "Version (MMF_FourKeyColours)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_mmffourkeycolours < 100 endparam int param numcols caption = "#Key colours" enum = "4" "5" "6" "7" "8" "9" "10" default = 0 endparam heading endheading color param colour0 caption = "Colour" default = RGBA(0,0,0.52156862745098039215686274509804,1) endparam float param index0 caption = "Gradient Index" default = 0.0 min = 0.0 max = 400.0 endparam heading endheading color param colour1 caption = "Colour" default = RGBA(1,1,1,1) endparam float param index1 caption = "Gradient Index" default = 100.0 min = 0.0 max = 400.0 endparam heading endheading color param colour2 caption = "Colour" default = RGBA(1,0.70980392156862745098039215686275,0,1) endparam float param index2 caption = "Gradient Index" default = 200.0 min = 0.0 max = 400.0 endparam heading endheading color param colour3 caption = "Colour" default = RGBA(0.61176470588235294117647058823529,0,0,1) endparam float param index3 caption = "Gradient Index" default = 300.0 min = 0.0 max = 400.0 endparam heading visible = @numcols>0 endheading color param colour4 caption = "Colour" default = RGBA(1,1,0,1) visible = @numcols>0 endparam float param index4 caption = "Gradient Index" default = 50.0 min = 0.0 max = 400.0 visible = @numcols>0 endparam heading visible = @numcols>1 endheading color param colour5 caption = "Colour" default = RGBA(0,1,1,1) visible = @numcols>1 endparam float param index5 caption = "Gradient Index" default = 150.0 min = 0.0 max = 400.0 visible = @numcols>1 endparam heading visible = @numcols>2 endheading color param colour6 caption = "Colour" default = RGBA(1,0,1,1) visible = @numcols>2 endparam float param index6 caption = "Gradient Index" default = 250.0 min = 0.0 max = 400.0 visible = @numcols>2 endparam heading visible = @numcols>3 endheading color param colour7 caption = "Colour" default = RGBA(1,1,1,1) visible = @numcols>3 endparam float param index7 caption = "Gradient Index" default = 350.0 min = 0.0 max = 400.0 visible = @numcols>3 endparam heading visible = @numcols>4 endheading color param colour8 caption = "Colour" default = RGBA(1,0.5,1,1) visible = @numcols>4 endparam float param index8 caption = "Gradient Index" default = 75.0 min = 0.0 max = 400.0 visible = @numcols>4 endparam heading visible = @numcols>5 endheading color param colour9 caption = "Colour" default = RGBA(0.5,1,1,1) visible = @numcols>5 endparam float param index9 caption = "Gradient Index" default = 325.0 min = 0.0 max = 400.0 visible = @numcols>5 endparam } class MMF_MultiKeyColours(MMF_KeyColourBase) { import "common.ulb" func MMF_MultiKeyColours(Generic pparent) m_Parent = pparent m_KeyColour[0] = new @f_keycolour0(this) m_KeyColour[1] = new @f_keycolour1(this) m_KeyColour[2] = new @f_keycolour2(this) m_KeyColour[3] = new @f_keycolour3(this) m_KeyColour[4] = new @f_keycolour4(this) m_KeyColour[5] = new @f_keycolour5(this) m_KeyColour[6] = new @f_keycolour6(this) m_KeyColour[7] = new @f_keycolour7(this) m_KeyColour[8] = new @f_keycolour8(this) m_KeyColour[9] = new @f_keycolour9(this) cols = indexes = 0 int i = 0 repeat total[i] = 0 until (i=i+1)>=10 endfunc int func GetNumCols() int t = 0 int i = 0 cols = 0 indexes = 0 repeat t = total[i] = t + m_KeyColour[i].GetNumCols() until (i=i+1)>=@numcols+2 return t endfunc color func GetNextColour() color c = RGBA(0,0,0,1) int i = 0 repeat if cols=@numcols+2 if (cols=cols+1)>=total[@numcols+1] cols = 0 endif return c endfunc float func GetNextIndex() float index = 0 int i = 0 repeat if indexes=@numcols+2 if (indexes=indexes+1)>=total[@numcols+1] indexes = 0 endif return index endfunc private: MMF_KeyColourBase m_KeyColour[10] int cols int indexes int total[10] default: title = "Multi Key Colours" int param v_mmfmultikeycolours caption = "Version (MMF_MultiKeyColours)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_mmfmultikeycolours < 100 endparam int param numcols caption = "# Key Colour entries" enum = "2" "3" "4" "5" "6" "7" "8" "9" "10" default = 0 min = 0 endparam MMF_KeyColourBase param f_keycolour0 caption = "Key Colour" default = MMF_OneKeyColour endparam MMF_KeyColourBase param f_keycolour1 caption = "Key Colour" default = MMF_OneKeyColour endparam MMF_KeyColourBase param f_keycolour2 caption = "Key Colour" default = MMF_NullKeyColour visible = @numcols>0 endparam MMF_KeyColourBase param f_keycolour3 caption = "Key Colour" default = MMF_NullKeyColour visible = @numcols>1 endparam MMF_KeyColourBase param f_keycolour4 caption = "Key Colour" default = MMF_NullKeyColour visible = @numcols>2 endparam MMF_KeyColourBase param f_keycolour5 caption = "Key Colour" default = MMF_NullKeyColour visible = @numcols>3 endparam MMF_KeyColourBase param f_keycolour6 caption = "Key Colour" default = MMF_NullKeyColour visible = @numcols>4 endparam MMF_KeyColourBase param f_keycolour7 caption = "Key Colour" default = MMF_NullKeyColour visible = @numcols>5 endparam MMF_KeyColourBase param f_keycolour8 caption = "Key Colour" default = MMF_NullKeyColour visible = @numcols>6 endparam MMF_KeyColourBase param f_keycolour9 caption = "Key Colour" default = MMF_NullKeyColour visible = @numcols>7 endparam } class MMF_Gradient(MMF_UserGradient) { import "common.ulb" ;

; @param pparent typically 'this' from the parent or zero func MMF_Gradient(Generic pparent) int i m_Parent = pparent m_Transfer = new @f_transfer(this) m_KeyColours = new @f_keycolours(this) ; calculate numcols and assign values numcols = m_KeyColours.GetNumCols() if numcols==0 col[0] = rgba(0,0,0,1) else if numcols>500 $define DEBUG print(numcols," colours defined, the max. is 500. Some will be ignored.") numcols = 500 endif i = 0 repeat col[i] = m_KeyColours.GetNextColour() pstn[i] = m_KeyColours.GetNextIndex() until (i=i+1)>=numcols endif if numcols>1 i = 0 repeat float min = pstn[i] int k = i int j = i + 1 repeat if pstn[j]=numcols if k!=i color tc = col[i] col[i] = col[k] col[k] = tc float tv = pstn[i] pstn[i] = pstn[k] pstn[k] = tv endif until (i=i+1)>=numcols-1 endif endfunc ;

; @param i gradient index ; @return colour from gradient color func GetColour(float i) if @showpalette i = real(#screenpixel)/#width else i = m_Transfer.Iterate(i) endif if numcols<=1 return col[0] endif if @rept if (i = i%1)<0.0 i = i + 1.0 endif elseif i<0.0 i = 0.0 elseif i>399.0/400.0 i = 399.0/400.0 endif int j = -1 int k = 0 repeat j = j + 1 until pstn[j]>i || j>=numcols if j>=numcols j = 0 k = numcols - 1 elseif (k=j-1)<0 k = numcols - 1 endif float d = pstn[j] - pstn[k] float v = i - pstn[k] if d<0.0 d = 1.0 + d if d==0.0 d = 1.0 endif endif if v<0.0 v = 1.0 + v endif if @smooth ; Our point is between p1 at x1 with height h1 and p2 at x2 with height h2 ; First if h1==h2 then h==h1 ; Else get gradient g1 at p1 and g2 at p2 and use: ; ; h = ax^3 + bx^2 + cx + d ; g = 3*a*x^2 + 2*b*x + c ; ; h1 = a*x1^3 +b*x1^2 + c*x1 + d ; g1 = 3*a*x1^2 + 2*b*x1 + c ; h2 = a*x2^3 + b*x2^2 + c*x2 + d ; g2 = 3*a*x2^2 + 2*b*x2 + c ; ; But we can use 0 for x1 and (x2-x1) for x2, giving: ; ; h1 = d ; g1 = c ; h2 = a*(x2-x1)^3 + b*(x2-x1)^2 + c*(x2-x1) + d ; g2 = 3*a*(x2-x1)^2 + 2*b*(x2-x1) + c ; ; Hence: ; ; a*(x2-x1)^3 + b*(x2-x1)^2 + g1*(x2-x1) + h1 = h2 ; 3*a*(x2-x1)^2 + 2*b*(x2-x1) + g1 = g2 ; ; a = (g2 - g1 - 2*b*(x2-x1))/(3*(x2-x1)^2) ; ; (g2-g1)(x2-x1)/3 - 2*b*(x2-x1)^2/3 + b*(x2-x1)^2 + g1*(x2-x1) + h1 = h2 ; ; (2*g1+g2)(x2-x1)/3 + b*(x2-x1)^2/3 + h1 = h2 ; ; b = 3*(h2-h1)/(x2-x1)^2 - (2*g1+g2)/(x2-x1) ; ; h1 float r1 = red(col[k]) float g1 = green(col[k]) float b1 = blue(col[k]) float a1 = alpha(col[k]) ; h2 float r2 = red(col[j]) float g2 = green(col[j]) float b2 = blue(col[j]) float a2 = alpha(col[j]) if r1==r2 && g1==g2 && b1==b2 && a1==a2 return col[k] endif ; g1 float gr1 = 0.0 float gg1 = 0.0 float gb1 = 0.0 float ga1 =0.0 ; g2 float gr2 = 0.0 float gg2 = 0.0 float gb2 = 0.0 float ga2 = 0.0 ; temp gradients float id = 1.0/d float tr = (red(col[j])-red(col[k]))*id float tg = (green(col[j])-green(col[k]))*id float tb = (blue(col[j])-blue(col[k]))*id float ta = (alpha(col[j])-alpha(col[k]))*id int l = k - 1 int m = j + 1 if l<0 l = numcols - 1 if pstn[k]==0.0 && pstn[l]==1.0 l = k endif endif if m>=numcols m = 0 if pstn[j]==1.0 && pstn[m]==0.0 m = j endif endif if pstn[l]==pstn[k] gr1 = gg1 = gb1 = ga1 = 0.0 else float d1 = pstn[k] - pstn[l] if d1<0.0 d1 = d1 + 1.0 endif d1 = 1.0/d1 gr1 = (red(col[k])-red(col[l]))*d1 gg1 = (green(col[k])-green(col[l]))*d1 gb1 = (blue(col[k])-blue(col[l]))*d1 ga1 = (alpha(col[k])-alpha(col[l]))*d1 if (gr1>=0.0 && tr<=0.0) || (gr1<=0.0 && tr>=0.0) gr1 = 0.0 else gr1 = 0.5*(gr1 + tr) endif if (gg1>=0.0 && tg<=0.0) || (gg1<=0.0 && tg>=0.0) gg1 = 0.0 else gg1 = 0.5*(gg1 + tg) endif if (gb1>=0.0 && tb<=0.0) || (gb1<=0.0 && tb>=0.0) gb1 = 0.0 else gb1 = 0.5*(gb1 + tb) endif if (ga1>=0.0 && ta<=0.0) || (ga1<=0.0 && ta>=0.0) ga1 = 0.0 else ga1 = 0.5*(ga1 + ta) endif endif if pstn[m]==pstn[j] gr2 = gg2 = gb2 = ga2 = 0.0 else float d1 = pstn[m] - pstn[j] if d1<0.0 d1 = d1 + 1.0 endif d1 = 1.0/d1 gr2 = (red(col[m])-red(col[j]))*d1 gg2 = (green(col[m])-green(col[j]))*d1 gb2 = (blue(col[m])-blue(col[j]))*d1 ga2 = (alpha(col[m])-alpha(col[j]))*d1 if (gr2>=0.0 && tr<=0.0) || (gr2<=0.0 && tr>=0.0) gr2 = 0.0 else gr2 = 0.5*(gr2 + tr) endif if (gg2>=0.0 && tg<=0.0) || (gg2<=0.0 && tg>=0.0) gg2 = 0.0 else gg2 = 0.5*(gg2 + tg) endif if (gb2>=0.0 && tb<=0.0) || (gb2<=0.0 && tb>=0.0) gb2 = 0.0 else gb2 = 0.5*(gb2 + tb) endif if (ga2>=0.0 && ta<=0.0) || (ga2<=0.0 && ta>=0.0) ga2 = 0.0 else ga2 = 0.5*(ga2 + ta) endif endif ; b = 3*(h2-h1)/(x2-x1)^2 - (2*g1+g2)/(x2-x1) ; a = (g2 - g1 - 2*b*(x2-x1))/(3*(x2-x1)^2) ; h = ax^3 + bx^2 + cx + d float a = 0.0 float b = 0.0 if r1!=r2 b = 3*(r2-r1)*sqr(id) - (2*gr1+gr2)*id a = (gr2-gr1-2.0*b*d)*sqr(id)/3 r1 = a*v^3 + b*sqr(v) + gr1*v + r1 endif if g1!=g2 b = 3*(g2-g1)*sqr(id) - (2*gg1+gg2)*id a = (gg2-gg1-2.0*b*d)*sqr(id)/3 g1 = a*v^3 + b*sqr(v) + gg1*v + g1 endif if b1!=b2 b = 3*(b2-b1)*sqr(id) - (2*gb1+gb2)*id a = (gb2-gb1-2.0*b*d)*sqr(id)/3 b1 = a*v^3 + b*sqr(v) + gb1*v + b1 endif if a1!=a2 b = 3*(a2-a1)*sqr(id) - (2*ga1+ga2)*id a = (ga2-ga1-2.0*b*d)*sqr(id)/3 a1 = a*v^3 + b*sqr(v) + ga1*v + a1 endif return RGBA(r1,g1,b1,a1) else return col[k] + (col[j] - col[k])*v/d endif endfunc private: Transfer m_Transfer MMF_KeyColourBase m_KeyColours color col[500] float pstn[500] int numcols default: title = "MMF Gradient" rating = recommended int param v_mmfgradient caption = "Version (MMF Gradient)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam heading caption = "Gradient Control" endheading Transfer param f_transfer caption = "Gradient Transfer" default = DefaultGradientTransfer hint = "Use to modify the value from the colouring before the colour \ is looked up in the gradient." visible = !@showpalette endparam bool param rept caption = "Repeat Gradient ?" default = true endparam bool param smooth caption = "Smooth Curves ?" default = true endparam bool param showpalette caption = "Show Gradient Only" default = false hint = "When enabled the gradient is shown as vertical stripes on the \ fractal, position 0.0 to the left and 1.0 to the right." endparam MMF_KeyColourBase param f_keycolours caption = "Key Colours" default = MMF_FourKeyColours hint = "You can use up to 500 separate colours via the key colour \ plug-ins. Note that plug-ins containing more than one key \ colour parameter can be nested." endparam } class MMF_LayerMergeBase(common.ulb:Generic) { ; PLEASE NOTE This class is obsolete/deprecated.
; Instead of using this class and its derived classes you should use
; the Layer class and its derived classes.
public: ;

; @param pparent typically 'this' from the parent or zero func MMF_LayerMergeBase(Generic pparent) Generic.Generic(pparent) endfunc ;

; @param pbottom the base color ; @param ptop the top color ; @return merged color color func Merge(color pbottom, color ptop) return ptop endfunc ;

; @param pbottom the base color ; @param ptop the top color ; @return layer merged color color func FullMerge(color pbottom, color ptop) if @f_invertcompose if @f_invertmerge return compose(ptop, \ blend(pbottom,Merge(ptop,pbottom),alpha(ptop)), \ @f_opacity) else return compose(ptop, \ blend(ptop,Merge(pbottom,ptop),alpha(pbottom)), \ @f_opacity) endif elseif @f_invertmerge return compose(pbottom, \ blend(pbottom,Merge(ptop,pbottom),alpha(ptop)), \ @f_opacity) else return compose(pbottom, \ blend(ptop,Merge(pbottom,ptop),alpha(pbottom)), \ @f_opacity) endif endfunc ;

; @param clr the base color ; @param index the gradient index for the top colour ; @return layer merged color color func GradientMerge(color clr,float index) return FullMerge(clr, gradient(index)) endfunc ;

; @param clr the base color ; @return layer merged color color func SolidMerge(color clr) return FullMerge(clr, @f_solid) endfunc default: rating = notRecommended int param v_mmflayermergebase caption = "Version (MMF_LayerMergeBase)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_mmflayermergebase < 100 endparam heading text = "PLEASE NOTE that this class is obsolete/deprecated. If you are \ using the old 'MMF Multi Layer' formula and you are creating a \ new UPR then you should switch to using 'MMF Layered' instead." endheading color param f_solid caption = "Solid Colour" default = RGBA(0,0,0,1) endparam bool param f_invertmerge caption = "Inverted Merge" default = false hint = "When enabled this layer is treated as the lower layer in the \ merge instead of as the upper layer, this inverts the way the \ RGBA values are treated." endparam bool param f_invertcompose caption = "Inverted Compose" default = false hint = "When enabled this layer is treated as the lower layer in the \ compose instead of as the upper layer, so reduced opacity \ fades to this layer's colour instead of the underlying colour." endparam float param f_opacity caption = "Layer Opacity" default = 1.0 hint = "The normal range to use is from 0.0 to 1.0." endparam } class MMF_LayerMerge(MMF_LayerMergeBase) { ; PLEASE NOTE This class is obsolete/deprecated.
; Instead of using this class and its derived classes you should use
; the Layer class and its derived classes.
; Note that this class is not intended for use with gradients.
; If GradientMerge is called then UF's in-built gradient will be used.
; For layer gradients the MMF_GradientLayerMerge class should be used instead.
public: import "common.ulb" ;

; @param pparent typically 'this' from the parent or zero func MMF_LayerMerge(Generic pparent) MMF_LayerMergeBase.MMF_LayerMergeBase(pparent) endfunc ;

; @param pbottom the base color ; @param ptop the top color ; @return merged color color func Merge(color pbottom, color ptop) if @p_modeselect=="MMF Merge Modes" if @clamp float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<0.0 r = 0.0 elseif r>1.0 r = 1.0 endif if g<0.0 g = 0.0 elseif g>1.0 g = 1.0 endif if b<0.0 b = 0.0 elseif b>1.0 b = 1.0 endif ptop = rgba(r,g,b,alpha(ptop)) r = red(pbottom) g = green(pbottom) b = blue(pbottom) if r<0.0 r = 0.0 elseif r>1.0 r = 1.0 endif if g<0.0 g = 0.0 elseif g>1.0 g = 1.0 endif if b<0.0 b = 0.0 elseif b>1.0 b = 1.0 endif pbottom = rgba(r,g,b,alpha(pbottom)) endif if @p_mmfmergemode=="Exclusion" return rgba(red(pbottom) + red(ptop) - 2*red(pbottom)*red(ptop), \ green(pbottom) + green(ptop) - 2*green(pbottom)*green(ptop), \ blue(pbottom) + blue(ptop) - 2*blue(pbottom)*blue(ptop), \ alpha(ptop) ) elseif @p_mmfmergemode=="Fade Down" return rgba( red(ptop) * (1 - red(ptop) + red(pbottom)), \ green(ptop) * (1 - green(ptop) + green(pbottom)), \ blue(ptop) * (1 - blue(ptop) + blue(pbottom)), alpha(ptop) ) elseif @p_mmfmergemode=="Fade Up" return rgba(red(pbottom) + red(ptop)*(red(ptop) - red(pbottom)), \ green(pbottom) + green(ptop)*(green(ptop) - green(pbottom)), \ blue(pbottom) + blue(ptop)*(blue(ptop) - blue(pbottom)), \ alpha(ptop) ) elseif @p_mmfmergemode=="Contrast Down" return rgba( 0.5 + red(ptop)*(red(pbottom) - 0.5), \ 0.5 + green(ptop)*(green(pbottom) - 0.5), \ 0.5 + blue(ptop)*(blue(pbottom) - 0.5), alpha(ptop) ) elseif @p_mmfmergemode=="Contrast Up" float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<0.5 r = r - 2.0*red(ptop)*r*(0.5 - r) else r = r + 2.0*red(ptop)*(1.0 - r)*(r - 0.5) endif if g<0.5 g = g - 2.0*green(ptop)*g*(0.5 - g) else g = g + 2.0*green(ptop)*(1.0 - g)*(g - 0.5) endif if b<0.5 b = b - 2.0*blue(ptop)*b*(0.5 - b) else b = b + 2.0*blue(ptop)*(1.0 - b)*(b - 0.5) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Dodge" ; Here we clamp the maximum returned to 1.0 because of the special case ; when the color channel in ptop is one (or more). float r = 1.0 - red(ptop) float g = 1.0 - green(ptop) float b = 1.0 - blue(ptop) if red(pbottom)<=0 r = 0.0 elseif r<=0.0 r = 1.0 else r = red(pbottom)/r if r>1.0 r = 1.0 endif endif if green(pbottom)<=0 g = 0 elseif g<=0.0 g = 1.0 else g = green(pbottom)/g if g>1.0 g = 1.0 endif endif if blue(pbottom)<=0 b = 0 elseif b<=0.0 b = 1.0 else b = blue(pbottom)/b if b>1.0 b = 1.0 endif endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Burn" ; Here we clamp the minimum returned to 0 because of the special case ; when the color channel in ptop is zero (or less). float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<=0.0 r = 0.0 else r = 1.0 - (1.0 - red(pbottom))/r if r<0.0 r = 0.0 endif endif if g<=0.0 g = 0.0 else g = 1.0 - (1.0 - green(pbottom))/g if g<0.0 g = 0.0 endif endif if b<=0.0 b = 0.0 else b = 1.0 - (1.0 - blue(pbottom))/b if b<0.0 b = 0.0 endif endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Negation" return rgba( 1.0 - abs(1.0 - red(ptop) - red(pbottom)), \ 1.0 - abs(1.0 - green(ptop) - green(pbottom)), \ 1.0 - abs(1.0 - blue(ptop) - blue(pbottom)), alpha(ptop) ) elseif @p_mmfmergemode=="Reflect" ; Here we clamp the maximum returned to 1.0 because of the special case ; when the color channel in ptop is one (or more). float r = 1.0 - red(ptop) float g = 1.0 - green(ptop) float b = 1.0 - blue(ptop) if red(pbottom)<=0 r = 0.0 elseif r<=0.0 r = 1.0 else r = sqr(red(pbottom))/r if r>1.0 r = 1.0 endif endif if green(pbottom)<=0 g = 0.0 elseif g<=0.0 g = 1.0 else g = sqr(green(pbottom))/g if g>1.0 g = 1.0 endif endif if blue(pbottom)<=0 b = 0.0 elseif b<=0.0 b = 1.0 else b = sqr(blue(pbottom))/b if b>1.0 b = 1.0 endif endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Freeze" ; Here we clamp the minimum returned to 0 because of the special case ; when the color channel in ptop is zero (or less). float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<=0.0 r = 0.0 else r = 1.0 - sqr(1.0 - red(pbottom))/r if r<0.0 r = 0.0 endif endif if g<=0.0 g = 0.0 else g = 1.0 - sqr(1.0 - green(pbottom))/g if g<0.0 g = 0.0 endif endif if b<=0.0 b = 0.0 else b = 1.0 - sqr(1.0 - blue(pbottom))/b if b<0.0 b = 0.0 endif endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Rev. Contrast Down" return rgba( 0.5 + (1.0 - red(ptop))*(red(pbottom) - 0.5), \ 0.5 + (1.0 - green(ptop))*(green(pbottom) - 0.5), \ 0.5 + (1.0 - blue(ptop))*(blue(pbottom) - 0.5), alpha(ptop) ) elseif @p_mmfmergemode=="Rev. Contrast Up" float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<0.5 r = r - 2.0*(1.0 - red(ptop))*r*(0.5 - r) else r = r + 2.0*(1.0 - red(ptop))*(1.0 - r)*(r - 0.5) endif if g<0.5 g = g - 2.0*(1.0 - green(ptop))*g*(0.5 - g) else g = g + 2.0*(1.0 - green(ptop))*(1.0 - g)*(g - 0.5) endif if b<0.5 b = b - 2.0*(1.0 - blue(ptop))*b*(0.5 - b) else b = b + 2.0*(1.0 - blue(ptop))*(1.0 - b)*(b - 0.5) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Fade" float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<0.5 r = 2.0 * r * (0.5 - r + red(pbottom)) else r = red(pbottom) + 2.0 * (r - 0.5)*(r - red(pbottom)) endif if g<0.5 g = 2.0 * g * (0.5 - g + green(pbottom)) else g = green(pbottom) + 2.0 * (g - 0.5)*(g - green(pbottom)) endif if b<0.5 b = 2.0 * b * (0.5 - b + blue(pbottom)) else b = blue(pbottom) + 2.0 * (b - 0.5)*(b - blue(pbottom)) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Reverse Fade" float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<0.5 r = red(pbottom) + 2.0 * r * (r - red(pbottom)) else r = red(pbottom) + 2.0 * (1.0 - r)*(r - red(pbottom)) endif if g<0.5 g = green(pbottom) + 2.0 * g * (g - green(pbottom)) else g = green(pbottom) + 2.0 * (1.0 - g)*(g - green(pbottom)) endif if b<0.5 b = blue(pbottom) + 2.0 * b * (b - blue(pbottom)) else b = blue(pbottom) + 2.0 * (1.0 - b)*(b - blue(pbottom)) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Contrast" || @p_mmfmergemode=="Reverse Contrast" float r1 = red(ptop) float g1 = green(ptop) float b1 = blue(ptop) if @p_mmfmergemode=="Reverse Contrast" r1 = 1.0 - r1 g1 = 1.0 - g1 b1 = 1.0 - b1 endif if r1<0.5 r1 = 0.5 + 2.0 * r1 * (red(pbottom) - 0.5) else r1 = 2.0 * (r1 - 0.5) float r = red(pbottom) if r<0.5 r1 = r - 2.0*r1*r*(0.5 - r) else r1 = r + 2.0*r1*(1.0 - r)*(r - 0.5) endif endif if g1<0.5 g1 = 0.5 + 2.0 * g1 * (green(pbottom) - 0.5) else g1 = 2.0 * (g1 - 0.5) float g = green(pbottom) if g<0.5 g1 = g - 2.0*g1*g*(0.5 - g) else g1 = g + 2.0*g1*(1.0 - g)*(g - 0.5) endif endif if b1<0.5 b1 = 0.5 + 2.0 * b1 * (blue(pbottom) - 0.5) else b1 = 2.0 * (b1 - 0.5) float b = blue(pbottom) if b<0.5 b1 = b - 2.0*b1*b*(0.5 - b) else b1 = b + 2.0*b1*(1.0 - b)*(b - 0.5) endif endif return rgba(r1,g1,b1,alpha(ptop)) elseif @p_mmfmergemode=="Quantize" int nr = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + red(ptop)) - 1.0)) - 1 int ng = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + green(ptop)) - 1.0)) - 1 int nb = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + blue(ptop)) - 1.0)) - 1 return rgba(floor(red(pbottom)*(nr+0.999))/nr, \ floor(green(pbottom)*(ng+0.999))/ng, \ floor(blue(pbottom)*(nb+0.999))/nb,alpha(ptop)) elseif @p_mmfmergemode=="Reverse Quantize" int nr = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - red(ptop)) - 1.0)) - 1 int ng = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - green(ptop)) - 1.0)) - 1 int nb = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - blue(ptop)) - 1.0)) - 1 return rgba(floor(red(pbottom)*(nr+0.999))/nr, \ floor(green(pbottom)*(ng+0.999))/ng, \ floor(blue(pbottom)*(nb+0.999))/nb,alpha(ptop)) elseif @p_mmfmergemode=="Gamma" return rgba(red(pbottom)^(@mingamma+(@maxgamma-@mingamma)*red(ptop)), \ green(pbottom)^(@mingamma+(@maxgamma-@mingamma)*green(ptop)), \ blue(pbottom)^(@mingamma+(@maxgamma-@mingamma)*blue(ptop)), \ alpha(ptop)) elseif @p_mmfmergemode=="Inverse Gamma" return rgba(red(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*red(ptop))), \ green(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*green(ptop))), \ blue(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*blue(ptop))), \ alpha(ptop)) elseif @p_mmfmergemode=="Reverse Gamma" return rgba(red(pbottom)^(@mingamma+(@maxgamma-@mingamma)*(1.0-red(ptop))), \ green(pbottom)^(@mingamma+(@maxgamma-@mingamma)*(1.0-green(ptop))), \ blue(pbottom)^(@mingamma+(@maxgamma-@mingamma)*(1.0-blue(ptop))), \ alpha(ptop)) elseif @p_mmfmergemode=="Rev. Inv. Gamma" return rgba(red(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-red(ptop)))), \ green(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-green(ptop)))), \ blue(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-blue(ptop)))), \ alpha(ptop)) elseif @p_mmfmergemode=="Combined Gamma" float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<0.5 r = red(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-red(ptop))) else r = red(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(red(ptop)-0.5))) endif if g<0.5 g = green(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-green(ptop))) else g = green(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(green(ptop)-0.5))) endif if b<0.5 b = blue(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-blue(ptop))) else b = blue(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(blue(ptop)-0.5))) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Rev. Comb. Gamma" float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<0.5 r = red(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-red(ptop)))) else r = red(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(red(ptop)-0.5)) endif if g<0.5 g = green(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-green(ptop)))) else g = green(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(green(ptop)-0.5)) endif if b<0.5 b = blue(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-blue(ptop)))) else b = blue(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(blue(ptop)-0.5)) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Stamp" float r = red(pbottom) + 2.0*red(ptop) - 1.0 float g = green(pbottom) + 2.0*green(ptop) - 1.0 float b = blue(pbottom) + 2.0*blue(ptop) - 1.0 if r<0.0 r = 0.0 elseif r>1.0 r = 1.0 endif if g<0.0 g = 0.0 elseif g>1.0 g = 1.0 endif if b<0.0 b = 0.0 elseif b>1.0 b = 1.0 endif return RGBA(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Soft Dodge" float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<=0 r = 0 elseif r+red(ptop)<=1.0 if red(ptop)>=1.0 r = 1.0 elseif (r = 0.5*r/(1.0 - red(ptop)))>1.0 r = 1.0 endif elseif (r = 1.0 - 0.5*(1.0 - red(ptop))/r)<0.0 r = 0.0 endif if g<=0 g = 0 elseif g+green(ptop)<=1.0 if green(ptop)>=1.0 g = 1.0 elseif (g = 0.5*g/(1.0 - green(ptop)))>1.0 g = 1.0 endif elseif (g = 1.0 - 0.5*(1.0 - green(ptop))/g)<0.0 g = 0.0 endif if b<=0 b = 0 elseif b+blue(ptop)<=1.0 if blue(ptop)>=1.0 b = 1.0 elseif (b = 0.5*b/(1.0 - blue(ptop)))>1.0 b = 1.0 endif elseif (b = 1.0 - 0.5*(1.0 - blue(ptop))/b)<0.0 b = 0.0 endif return RGBA(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Soft Burn" float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<=0 r = 0 elseif r+red(pbottom)<=1.0 if red(pbottom)>=1.0 r = 1.0 elseif (r = 0.5*r/(1.0 - red(pbottom)))>1.0 r = 1.0 endif elseif (r = 1.0 - 0.5*(1.0 - red(pbottom))/r)<0.0 r = 0.0 endif if g<=0 g = 0 elseif g+green(pbottom)<=1.0 if green(pbottom)>=1.0 g = 1.0 elseif (g = 0.5*g/(1.0 - green(pbottom)))>1.0 g = 1.0 endif elseif (g = 1.0 - 0.5*(1.0 - green(pbottom))/g)<0.0 g = 0.0 endif if b<=0 b = 0 elseif b+blue(pbottom)<=1.0 if blue(pbottom)>=1.0 b = 1.0 elseif (b = 0.5*b/(1.0 - blue(pbottom)))>1.0 b = 1.0 endif elseif (b = 1.0 - 0.5*(1.0 - blue(pbottom))/b)<0.0 b = 0.0 endif return RGBA(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inverse Dodge" ; Here we clamp the maximum returned to 1.0 because of the special case ; when the color channel in ptop is one (or more). float r = 1.0 - red(pbottom) float g = 1.0 - green(pbottom) float b = 1.0 - blue(pbottom) if red(ptop)<=0 r = 0 elseif r<=0.0 r = 1.0 else r = red(ptop)/r if r>1.0 r = 1.0 endif endif if green(ptop)<=0 g = 0 elseif g<=0.0 g = 1.0 else g = green(ptop)/g if g>1.0 g = 1.0 endif endif if blue(ptop)<=0 b = 0 elseif b<=0.0 b = 1.0 else b = blue(ptop)/b if b>1.0 b = 1.0 endif endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inverse Burn" ; Here we clamp the minimum returned to 0 because of the special case ; when the color channel in ptop is zero (or less). float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<=0.0 r = 0.0 else r = 1.0 - (1.0 - red(ptop))/r if r<0.0 r = 0.0 endif endif if g<=0.0 g = 0.0 else g = 1.0 - (1.0 - green(ptop))/g if g<0.0 g = 0.0 endif endif if b<=0.0 b = 0.0 else b = 1.0 - (1.0 - blue(ptop))/b if b<0.0 b = 0.0 endif endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Glow" ; Here we clamp the maximum returned to 1.0 because of the special case ; when the color channel in ptop is one (or more). float r = 1.0 - red(pbottom) float g = 1.0 - green(pbottom) float b = 1.0 - blue(pbottom) if red(ptop)<=0 r = 0.0 elseif r<=0.0 r = 1.0 else r = sqr(red(ptop))/r if r>1.0 r = 1.0 endif endif if green(ptop)<=0 g = 0.0 elseif g<=0.0 g = 1.0 else g = sqr(green(ptop))/g if g>1.0 g = 1.0 endif endif if blue(ptop)<=0 b = 0.0 elseif b<=0.0 b = 1.0 else b = sqr(blue(ptop))/b if b>1.0 b = 1.0 endif endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Heat" ; Here we clamp the minimum returned to 0 because of the special case ; when the color channel in ptop is zero (or less). float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<=0.0 r = 0.0 else r = 1.0 - sqr(1.0 - red(ptop))/r if r<0.0 r = 0.0 endif endif if g<=0.0 g = 0.0 else g = 1.0 - sqr(1.0 - green(ptop))/g if g<0.0 g = 0.0 endif endif if b<=0.0 b = 0.0 else b = 1.0 - sqr(1.0 - blue(ptop))/b if b<0.0 b = 0.0 endif endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inv. Fade Down" return rgba( red(pbottom) * (1 - red(pbottom) + red(ptop)), \ green(pbottom) * (1 - green(pbottom) + green(ptop)), \ blue(pbottom) * (1 - blue(pbottom) + blue(ptop)), alpha(ptop) ) elseif @p_mmfmergemode=="Inv. Fade Up" return rgba(red(ptop) + red(pbottom)*(red(pbottom) - red(ptop)), \ green(ptop) + green(pbottom)*(green(pbottom) - green(ptop)), \ blue(ptop) + blue(pbottom)*(blue(pbottom) - blue(ptop)), \ alpha(ptop) ) elseif @p_mmfmergemode=="Inv. Contrast Down" return rgba( 0.5 + red(pbottom)*(red(ptop) - 0.5), \ 0.5 + green(pbottom)*(green(ptop) - 0.5), \ 0.5 + blue(pbottom)*(blue(ptop) - 0.5), alpha(ptop) ) elseif @p_mmfmergemode=="Inv. Contrast Up" float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<0.5 r = r - 2.0*red(pbottom)*r*(0.5 - r) else r = r + 2.0*red(pbottom)*(1.0 - r)*(r - 0.5) endif if g<0.5 g = g - 2.0*green(pbottom)*g*(0.5 - g) else g = g + 2.0*green(pbottom)*(1.0 - g)*(g - 0.5) endif if b<0.5 b = b - 2.0*blue(pbottom)*b*(0.5 - b) else b = b + 2.0*blue(pbottom)*(1.0 - b)*(b - 0.5) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inv. Rev. Con. Down" return rgba( 0.5 + (1.0 - red(pbottom))*(red(ptop) - 0.5), \ 0.5 + (1.0 - green(pbottom))*(green(ptop) - 0.5), \ 0.5 + (1.0 - blue(pbottom))*(blue(ptop) - 0.5), alpha(ptop) ) elseif @p_mmfmergemode=="Inv. Rev. Con. Up" float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<0.5 r = r - 2.0*(1.0 - red(pbottom))*r*(0.5 - r) else r = r + 2.0*(1.0 - red(pbottom))*(1.0 - r)*(r - 0.5) endif if g<0.5 g = g - 2.0*(1.0 - green(pbottom))*g*(0.5 - g) else g = g + 2.0*(1.0 - green(pbottom))*(1.0 - g)*(g - 0.5) endif if b<0.5 b = b - 2.0*(1.0 - blue(pbottom))*b*(0.5 - b) else b = b + 2.0*(1.0 - blue(pbottom))*(1.0 - b)*(b - 0.5) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inverse Fade" float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<0.5 r = 2.0 * r * (0.5 - r + red(ptop)) else r = red(ptop) + 2.0 * (r - 0.5)*(r - red(ptop)) endif if g<0.5 g = 2.0 * g * (0.5 - g + green(ptop)) else g = green(ptop) + 2.0 * (g - 0.5)*(g - green(ptop)) endif if b<0.5 b = 2.0 * b * (0.5 - b + blue(ptop)) else b = blue(ptop) + 2.0 * (b - 0.5)*(b - blue(ptop)) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inv. Rev. Fade" float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<0.5 r = red(ptop) + 2.0 * r * (r - red(ptop)) else r = red(ptop) + 2.0 * (1.0 - r)*(r - red(ptop)) endif if g<0.5 g = green(ptop) + 2.0 * g * (g - green(ptop)) else g = green(ptop) + 2.0 * (1.0 - g)*(g - green(ptop)) endif if b<0.5 b = blue(ptop) + 2.0 * b * (b - blue(ptop)) else b = blue(ptop) + 2.0 * (1.0 - b)*(b - blue(ptop)) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inverse Contrast" \ || @p_mmfmergemode=="Inv. Rev. Contrast" float r1 = red(pbottom) float g1 = green(pbottom) float b1 = blue(pbottom) if @p_mmfmergemode=="Inv. Rev. Contrast" r1 = 1.0 - r1 g1 = 1.0 - g1 b1 = 1.0 - b1 endif if r1<0.5 r1 = 0.5 + 2.0 * r1 * (red(ptop) - 0.5) else r1 = 2.0 * (r1 - 0.5) float r = red(ptop) if r<0.5 r1 = r - 2.0*r1*r*(0.5 - r) else r1 = r + 2.0*r1*(1.0 - r)*(r - 0.5) endif endif if g1<0.5 g1 = 0.5 + 2.0 * g1 * (green(ptop) - 0.5) else g1 = 2.0 * (g1 - 0.5) float g = green(ptop) if g<0.5 g1 = g - 2.0*g1*g*(0.5 - g) else g1 = g + 2.0*g1*(1.0 - g)*(g - 0.5) endif endif if b1<0.5 b1 = 0.5 + 2.0 * b1 * (blue(ptop) - 0.5) else b1 = 2.0 * (b1 - 0.5) float b = blue(ptop) if b<0.5 b1 = b - 2.0*b1*b*(0.5 - b) else b1 = b + 2.0*b1*(1.0 - b)*(b - 0.5) endif endif return rgba(r1,g1,b1,alpha(ptop)) elseif @p_mmfmergemode=="Inverse Quantize" int nr = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + red(pbottom)) - 1.0)) - 1 int ng = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + green(pbottom)) - 1.0)) - 1 int nb = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + blue(pbottom)) - 1.0)) - 1 return rgba(floor(red(ptop)*(nr+0.999))/nr, \ floor(green(ptop)*(ng+0.999))/ng, \ floor(blue(ptop)*(nb+0.999))/nb,alpha(ptop)) elseif @p_mmfmergemode=="Inv. Rev. Quantize" int nr = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - red(pbottom)) - 1.0)) - 1 int ng = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - green(pbottom)) - 1.0)) - 1 int nb = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - blue(pbottom)) - 1.0)) - 1 return rgba(floor(red(ptop)*(nr+0.999))/nr, \ floor(green(ptop)*(ng+0.999))/ng, \ floor(blue(ptop)*(nb+0.999))/nb,alpha(ptop)) elseif @p_mmfmergemode=="Inv. Gamma" return rgba(red(ptop)^(@mingamma+(@maxgamma-@mingamma)*red(pbottom)), \ green(ptop)^(@mingamma+(@maxgamma-@mingamma)*green(pbottom)), \ blue(ptop)^(@mingamma+(@maxgamma-@mingamma)*blue(pbottom)), \ alpha(ptop)) elseif @p_mmfmergemode=="Inv. Inverse Gamma" return rgba(red(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*red(pbottom))), \ green(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*green(pbottom))), \ blue(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*blue(pbottom))), \ alpha(ptop)) elseif @p_mmfmergemode=="Inv. Reverse Gamma" return rgba(red(ptop)^(@mingamma+(@maxgamma-@mingamma)*(1.0-red(pbottom))), \ green(ptop)^(@mingamma+(@maxgamma-@mingamma)*(1.0-green(pbottom))), \ blue(ptop)^(@mingamma+(@maxgamma-@mingamma)*(1.0-blue(pbottom))), \ alpha(ptop)) elseif @p_mmfmergemode=="Inv. Rev. Inv. Gamma" return rgba(red(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-red(pbottom)))), \ green(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-green(pbottom)))), \ blue(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-blue(pbottom)))), \ alpha(ptop)) elseif @p_mmfmergemode=="Inv. Combined Gamma" float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<0.5 r = red(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-r)) else r = red(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(r-0.5))) endif if g<0.5 g = green(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-g)) else g = green(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(g-0.5))) endif if b<0.5 b = blue(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-b)) else b = blue(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(b-0.5))) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inv. Rev. Comb. Gamma" float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<0.5 r = red(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-r))) else r = red(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(r-0.5)) endif if g<0.5 g = green(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-g))) else g = green(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(g-0.5)) endif if b<0.5 b = blue(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-b))) else b = blue(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(b-0.5)) endif return rgba(r,g,b,alpha(ptop)) else;if @p_mmfmergemode=="Inverse Stamp" float r = red(ptop) + 2.0*red(pbottom) - 1.0 float g = green(ptop) + 2.0*green(pbottom) - 1.0 float b = blue(ptop) + 2.0*blue(pbottom) - 1.0 if r<0.0 r = 0.0 elseif r>1.0 r = 1.0 endif if g<0.0 g = 0.0 elseif g>1.0 g = 1.0 endif if b<0.0 b = 0.0 elseif b>1.0 b = 1.0 endif return RGBA(r,g,b,alpha(ptop)) endif ; @p_mmfmergemode else;if @pmodeselect=="Original Merge Modes" return @f_mergemode(pbottom, ptop) endif ; @p_modeselect endfunc default: title = "MMF Layer Merge" rating = notRecommended int param v_mmflayermerge caption = "Version (MMF Layer Merge)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam int param p_modeselect caption = "Merge Modes to choose from" enum = "Original Merge Modes" "MMF Merge Modes" default = 0 hint = "Choose from different collections of merge modes." endparam color func f_mergemode caption = "Merge Mode" default = mergemultiply() hint = "Sets the method used to merge input colors with." visible = @p_modeselect=="Original Merge Modes" endfunc bool param clamp caption = "Clamp Values" default = false hint = "When enabled the RGB values in both the top and bottom colours \ are clamped to the range 0<=v<=1. Should not be necessary most \ of the time." visible = @p_modeselect=="MMF Merge Modes" endparam int param p_mmfmergemode caption = "MMF Merge Mode" enum = "Exclusion" "Fade Down" "Fade Up" "Contrast Down" "Contrast Up" \ "Dodge" "Burn" "Negation" "Reflect" "Freeze" "Rev. Contrast Down" \ "Rev. Contrast Up" "Fade" "Reverse Fade" "Contrast" \ "Reverse Contrast" "Quantize" "Reverse Quantize" "Gamma" \ "Inverse Gamma" "Reverse Gamma" "Rev. Inv. Gamma" "Combined Gamma" \ "Rev. Comb. Gamma" "Stamp" "Soft Dodge" "Soft Burn" \ "Inverse Dodge" "Inverse Burn" "Glow" "Heat" "Inv. Fade Down" \ "Inv. Fade Up" "Inv. Contrast Down" "Inv. Contrast Up" \ "Inv. Rev. Con. Down" "Inv. Rev. Con. Up" "Inverse Fade" \ "Inv. Rev. Fade" "Inverse Contrast" "Inv. Rev. Contrast" \ "Inverse Quantize" "Inv. Rev. Quantize" "Inv. Gamma" \ "Inv. Inverse Gamma" "Inv. Reverse Gamma" "Inv. Rev. Inv. Gamma" \ "Inv. Combined Gamma" "Inv. Rev. Comb. Gamma" "Inverse Stamp" default = 0 hint = "Extra merge modes, just try them out !" visible = @p_modeselect=="MMF Merge Modes" endparam int param qmin caption = "Minimum Quantize" default = 2 min = 2 hint = "Sets the minimum number of colour levels used after merging." visible = @p_modeselect=="MMF Merge Modes" && \ (@p_mmfmergemode=="Quantize" || @p_mmfmergemode=="Reverse Quantize") endparam int param qmax caption = "Maximum Quantize" default = 32 min = 2 hint = "Sets the maximum number of colour levels used after merging. \ Should be set larger than 'Minimum Quantize' for correct use." visible = @p_modeselect=="MMF Merge Modes" && \ (@p_mmfmergemode=="Quantize" || @p_mmfmergemode=="Reverse Quantize") endparam float param mingamma caption = "Minimum Gamma" default = 1.0 min = 1.0 hint = "Sets the minimum gamma to be used, use 1.0 for 'no change'." visible = @p_modeselect=="MMF Merge Modes" && \ (@p_mmfmergemode=="Gamma" || @p_mmfmergemode=="Inverse Gamma" \ || @p_mmfmergemode=="Reverse Gamma" \ || @p_mmfmergemode=="Rev. Inv. Gamma" \ || @p_mmfmergemode=="Combined Gamma" \ || @p_mmfmergemode=="Rev. Comb. Gamma") endparam float param maxgamma caption = "Maximum Gamma" default = 2.0 min = 1.0 hint = "Sets the maximum gamma to be used. Should be set larger than \ 'Minimum Gamma' for correct use." visible = @p_modeselect=="MMF Merge Modes" && \ (@p_mmfmergemode=="Gamma" || @p_mmfmergemode=="Inverse Gamma" \ || @p_mmfmergemode=="Reverse Gamma" \ || @p_mmfmergemode=="Rev. Inv. Gamma" \ || @p_mmfmergemode=="Combined Gamma" \ || @p_mmfmergemode=="Rev. Comb. Gamma") endparam } class MMF_GradientLayerMerge(MMF_LayerMerge) { ; PLEASE NOTE This class is obsolete/deprecated.
; Instead of using this class and its derived classes you should use
; the Layer class and its derived classes.
public: import "common.ulb" ;

; @param pparent typically 'this' from the parent or zero func MMF_GradientLayerMerge(Generic pparent) MMF_LayerMergeBase.MMF_LayerMergeBase(pparent) if @f_grad==0 m_Gradient = new @f_gradient(this) endif endfunc ;

; @param clr the base color ; @param index the gradient index for the top colour ; @return layer merged color color func GradientMerge(color clr,float index) if @f_grad==0 return FullMerge(clr, m_Gradient.GetColour(index)) else return FullMerge(clr, gradient(index)) endif endfunc private: MMF_UserGradient m_Gradient default: title = "MMF Layer Merge with Gradient" rating = notRecommended int param v_mmfgradientlayermerge caption = "Version (MMF Layer Merge with Gradient)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam int param f_grad caption = "Gradient to use" enum = "Custom Gradient" "UF's Gradient" default = 0 endparam MMF_UserGradient param f_gradient caption = "Layer Gradient" default = MMF_Gradient hint = "Allows you to customise the colours for this layer." visible = @f_grad==0 endparam } class MMF_MultiLayerBase(common.ulb:DirectColoring) { public: ;

; @param pz the z value ; @param clr the colour to use as the base layer colour ; @return colour color func ResultUsingBaseColor(complex pz, color clr) return clr endfunc default: int param v_mmfmultilayerbase caption = "Version (MMF_MultiLayerBase)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_mmfmultilayerbase < 100 endparam } class MMF_MultiLayerNone(MMF_MultiLayerBase) { default: title = "MMF No Layers" heading text = "This is just a dummy, to add extra layers select a multi-layer \ colouring formula such as 'MMF Layered' from mmf.ulb." endheading int param MMF_MultiLayerNone caption = "Version (MMF Multi Layer None)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam } class MMF_QuickGradient(common.ulb:GradientColoring) { public: ; @param pparent usually "this" from the parent or zero func MMF_QuickGradient(Generic pparent) GradientColoring.GradientColoring(pparent) endfunc ; @param pz ; @return gradient index float func ResultIndex(complex pz) if @type=="Linear" if @offset return 16.5 + 0.25*(real(m_Pixel)*cos(@angle*(#pi/180)) \ - imag(m_Pixel)*sin(@angle*(#pi/180))) else return 16.5 + 0.25*(real(m_Pixel)*cos(@angle*(#pi/180) - #angle) \ - imag(m_Pixel)*sin(@angle*(#pi/180) - #angle)) endif elseif @type=="Cone" if @offset pz = cos(@angle*(#pi/180)) + flip(sin(@angle*(#pi/180))) else pz = cos(@angle*(#pi/180) - #angle) \ + flip(sin(@angle*(#pi/180) - #angle)) endif if @usecentre m_Pixel = m_Pixel - #center else m_Pixel = m_Pixel - @centre endif pz = real(m_Pixel)*real(pz) - imag(m_Pixel)*imag(pz) \ + flip(real(m_Pixel)*imag(pz) + imag(m_Pixel)*real(pz)) return 0.5 - atan2(pz) / (2 * #pi) elseif @usecentre return cabs(m_Pixel - #center) else return cabs(m_Pixel - @centre) endif endfunc default: title = "MMF Quick Gradient" int param type caption = "Gradient Type" enum = "Linear" "Circular" "Cone" default = 0 endparam bool param offset caption = "Offset from UF Angle ?" default = true hint = "When enabled the rotation angle you supply will be added to your \ default UF rotation angle, when disabled the angle is always \ from the horizontal." visible = @type==0 || @type==2 endparam float param angle caption = "Angle (degrees)" default = 0.0 hint = "The angle for the gradient." visible = @type==0 || @type==2 endparam bool param usecentre caption = "Use Screen Centre ?" default = true visible = @type==1 || @type==2 endparam complex param centre caption = "Circle Centre" default = (0,0) visible = (@type==1 || @type==2) && !@usecentre endparam } class AdjustmentLayer(common.ulb:Generic) { public: ;

; @param pparent typically 'this' from the parent or zero func AdjustmentLayer(Generic pparent) Generic.Generic(pparent) endfunc ;

; @param pbottom the base color ; @return adjusted color color func Adjust(color pbottom) return pbottom endfunc default: int param v_adjustmentlayer caption = "Version (AdjustmentLayer)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_adjustmentlayer < 100 endparam } class MMF_AdjustmentLayer(AdjustmentLayer) { public: import "common.ulb" ;

; @param pparent typically 'this' from the parent or zero func MMF_AdjustmentLayer(Generic pparent) Generic.Generic(pparent) m_Adjust = new @f_adjust(this) endfunc ;

; @param pbottom the base color ; @return adjusted color color func Adjust(color pbottom) color ptop if @adjusttype==0 ptop = RGB(@adjred, @adjgreen, @adjblue) else ptop = @f_adjustcolour endif ptop = compose(pbottom, m_Adjust.Merge(pbottom, ptop), @f_opacity) return RGBA(red(ptop), green(ptop), blue(ptop), alpha(pbottom)) endfunc private: ColorMerge m_Adjust default: title = "MMF Adjustment Layer" param v_mmfadjustmentlayer caption = "Version (MMF Adjustment Layer)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam int param adjusttype caption = "Colour or RGB" enum = "RGB values" "Colour Parameter" default = 1 hint = "This option is specifically added so that if you choose \ 'RGB values' you can 'explore' them and see changes to the image \ as you change the RGB. The option may become redundant in a \ future version of UF." endparam float param adjred caption = "Red Value" default = 1.0 hint = "The red part of the adjust colour (0 to 1)." visible = @adjusttype==0 endparam float param adjgreen caption = "Green Value" default = 1.0 hint = "The green part of the adjust colour (0 to 1)." visible = @adjusttype==0 endparam float param adjblue caption = "Blue Value" default = 1.0 hint = "The blue part of the adjust colour (0 to 1)." visible = @adjusttype==0 endparam color param f_adjustcolour caption = "Adjust Layer Colour" default = RGB(1,1,1) hint = "Allows you to apply overall adjustments to your colouring." visible = @adjusttype==1 endparam ColorMerge param f_adjust caption = "Adjustment Layer Merge" default = MMF_ExtendedColorMerge hint = "How the adjust colour is applied to the layer." endparam float param f_opacity caption = "Adjustment Opacity" default = 1.0 hint = "Use to modify the adjustment opacity, the normal range is from \ 0 to 1." endparam } class Layer(common.ulb:Generic) { public: ;

; @param pparent typically 'this' from the parent or zero func Layer(Generic pparent) Generic.Generic(pparent) m_Merge = new @f_merge(this) if @adjustlayer m_Adjustment = new @f_adjustment(this) endif endfunc ;

; @param pbottom the base color ; @param ptop the top color ; @return layer merged color color func FullMerge(color pbottom, color ptop) if @f_invertcompose if @f_invertmerge pbottom = m_Merge.FullMerge(ptop, pbottom, @f_opacity) else pbottom = compose(ptop, \ blend(ptop,m_Merge.Merge(pbottom,ptop),alpha(pbottom)), \ @f_opacity) endif elseif @f_invertmerge pbottom = compose(pbottom, \ blend(pbottom,m_Merge.Merge(ptop,pbottom),alpha(ptop)), \ @f_opacity) else pbottom = m_Merge.FullMerge(pbottom, ptop, @f_opacity) endif if @adjustlayer pbottom = m_Adjustment.Adjust(pbottom) endif return pbottom endfunc ;

; @param clr the base color ; @param index the gradient index for the top colour ; @return layer merged color color func GradientMerge(color clr,float index) return FullMerge(clr, gradient(index)) endfunc ;

; @param clr the base color ; @return layer merged color color func SolidMerge(color clr) return FullMerge(clr, @f_solid) endfunc private: ColorMerge m_Merge AdjustmentLayer m_Adjustment default: int param v_layer caption = "Version (Layer)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_layer < 100 endparam color param f_solid caption = "Solid Colour" default = RGBA(0,0,0,1) endparam bool param f_invertmerge caption = "Inverted Merge" default = false hint = "When enabled this layer is treated as the lower layer in the \ merge instead of as the upper layer, this inverts the way the \ RGBA values are treated." endparam bool param f_invertcompose caption = "Inverted Compose" default = false hint = "When enabled this layer is treated as the lower layer in the \ compose instead of as the upper layer, so reduced opacity \ fades to this layer's colour instead of the underlying colour." endparam float param f_opacity caption = "Layer Opacity" default = 1.0 hint = "The normal range to use is from 0.0 to 1.0." endparam ColorMerge param f_merge caption = "Layer Merge" default = MMF_ExtendedColorMerge endparam bool param adjustlayer caption = "Add Adjust layer" default = false hint = "Enable to add an adjustment layer in a given colour to merge \ on top of this layer prior to combining the result with the other \ layers. This allows you to tweak the colours of this layer, for \ instance adjusting the gamma, or colourising etc." endparam AdjustmentLayer param f_adjustment caption = "Adjustment layer" default = MMF_AdjustmentLayer hint = "Use to tweak the layer colours." visible = @adjustlayer endparam } class DirectLayer(Layer) { ; Note that this class is not intended for use with gradients.
; If GradientMerge is called then UF's in-built gradient will be used.
; For layer gradients the GradientLayer class should be used instead.
public: import "common.ulb" ;

; @param pparent typically 'this' from the parent or zero func DirectLayer(Generic pparent) Layer.Layer(pparent) endfunc default: int param v_directlayer caption = "Version (DirectLayer)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_directlayer < 100 endparam } class GradientLayer(Layer) { public: import "common.ulb" ;

; @param pparent typically 'this' from the parent or zero func GradientLayer(Generic pparent) Layer.Layer(pparent) if @f_grad==0 m_Gradient = new @f_gradient(this) endif endfunc ;

; @param clr the base color ; @param index the gradient index for the top colour ; @return layer merged color color func GradientMerge(color clr,float index) if @f_grad==0 return FullMerge(clr, m_Gradient.GetColour(index)) else return FullMerge(clr, gradient(index)) endif endfunc private: MMF_UserGradient m_Gradient default: int param v_gradientlayer caption = "Version (GradientLayer)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_gradientlayer < 100 endparam int param f_grad caption = "Gradient to use" enum = "Custom Gradient" "UF's Gradient" default = 0 endparam MMF_UserGradient param f_gradient caption = "Layer Gradient" default = MMF_Gradient hint = "Allows you to customise the colours for this layer." visible = @f_grad==0 endparam bool param adjustlayer caption = "Add Adjust layer" default = false hint = "Enable to add an adjustment layer in a given colour to merge \ on top of this layer prior to combining the result with the other \ layers. This allows you to tweak the colours of this layer, for \ instance adjusting the gamma, or colourising etc." endparam AdjustmentLayer param f_adjustment caption = "Adjustment layer" default = MMF_AdjustmentLayer hint = "Use to tweak the layer colours." visible = @adjustlayer endparam } class MMF_DirectLayer(DirectLayer) { public: import "common.ulb" ;

; @param pparent typically 'this' from the parent or zero func MMF_DirectLayer(Generic pparent) DirectLayer.DirectLayer(pparent) endfunc default: title = "MMF Direct Layer" param v_mmfdirectlayer caption = "Version (MMF Direct Layer)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam } class MMF_GradientLayer(GradientLayer) { public: import "common.ulb" ;

; @param pparent typically 'this' from the parent or zero func MMF_GradientLayer(Generic pparent) GradientLayer.GradientLayer(pparent) endfunc default: title = "MMF Gradient Layer" param v_mmfgradientlayer caption = "Version (MMF Gradient Layer)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam } class MMF_Layered(MMF_MultiLayerBase) { ;

This colouring allows you to use multiple colouring layers for a single ; fractal formula. This gives 3 main advantages over normal UF layering:
; 1. The main fractal formula calculation is only done once no matter how ; many layers you use in this colouring.
; 2. You may use the extended "MMF" merge modes for merging the layers.
; 3. You can use the exact same colouring on different layers at different ; positions in the layer "stack" each using separate merge modes and palettes. ; Doing so means that the colouring value for the layers concerned is only ; calculated once.
; The only real disadvantages are that this layer colouring only works as a ; direct colouring and the custom palettes available for each layer are not ; quite as straightforward to use as the standard UF palette.

import "common.ulb" import "Standard.ulb" ;

; @param pparent typically 'this' from the parent or zero func MMF_Layered(Generic pparent) DirectColoring.DirectColoring(pparent) int i = 0 repeat m_Use[i] = false m_QuickGradient[i] = 0 until (i=i+1)>=10 m_Use[10] = false if @colour0>0 && @colour0<11 m_Use[@colour0-1] = true endif if @colour1>0 && @colour1<11 m_Use[@colour1-1] = true endif if @colour2>0 && @colour2<11 m_Use[@colour2-1] = true endif if @colour3>0 && @colour3<11 m_Use[@colour3-1] = true endif if @colour4>0 && @colour4<11 m_Use[@colour4-1] = true endif if @colour5>0 && @colour5<11 m_Use[@colour5-1] = true endif if @colour6>0 && @colour6<11 m_Use[@colour6-1] = true endif if @colour7>0 && @colour7<11 m_Use[@colour7-1] = true endif if @colour8>0 && @colour8<11 m_Use[@colour8-1] = true endif if @colour9>0 && @colour9<11 m_Use[@colour9-1] = true endif if m_Use[0] m_Colouring[0] = new @f_colouring0(this) m_Direct[0] = @f_direct0 endif if m_Use[1] m_Colouring[1] = new @f_colouring1(this) m_Direct[1] = @f_direct1 endif if m_Use[2] m_Colouring[2] = new @f_colouring2(this) m_Direct[2] = @f_direct2 endif if m_Use[3] m_Colouring[3] = new @f_colouring3(this) m_Direct[3] = @f_direct3 endif if m_Use[4] m_Colouring[4] = new @f_colouring4(this) m_Direct[4] = @f_direct4 endif if m_Use[5] m_Colouring[5] = new @f_colouring5(this) m_Direct[5] = @f_direct5 endif if m_Use[6] m_Colouring[6] = new @f_colouring6(this) m_Direct[6] = @f_direct6 endif if m_Use[7] m_Colouring[7] = new @f_colouring7(this) m_Direct[7] = @f_direct7 endif if m_Use[8] m_Colouring[8] = new @f_colouring8(this) m_Direct[8] = @f_direct8 endif if m_Use[9] m_Colouring[9] = new @f_colouring9(this) m_Direct[9] = @f_direct9 endif if @f_colouring10!=MMF_MultiLayerNone m_Use[10] = true m_LayerColouring = MMF_MultiLayerBase(m_Colouring[10] = new @f_colouring10(this)) endif if @colour0>0 if @colour0==11 m_Layer0 = new @f_layer0(this) elseif @colour0==12 m_QuickGradient[0] = new @f_quickgradient0(this) m_Layer0 = new @f_gradientlayer0(this) elseif GradientColoring(m_Colouring[@colour0-1]) && !m_Direct[@colour0-1] m_Layer0 = new @f_gradientlayer0(this) else m_Layer0 = new @f_layer0(this) endif endif if @colour1>0 if @colour1==11 m_Layer1 = new @f_layer1(this) elseif @colour1==12 m_QuickGradient[1] = new @f_quickgradient1(this) m_Layer1 = new @f_gradientlayer1(this) elseif GradientColoring(m_Colouring[@colour1-1]) && !m_Direct[@colour1-1] m_Layer1 = new @f_gradientlayer1(this) else m_Layer1 = new @f_layer1(this) endif endif if @colour2>0 if @colour2==11 m_Layer2 = new @f_layer2(this) elseif @colour2==12 m_QuickGradient[2] = new @f_quickgradient2(this) m_Layer2 = new @f_gradientlayer2(this) elseif GradientColoring(m_Colouring[@colour2-1]) && !m_Direct[@colour2-1] m_Layer2 = new @f_gradientlayer2(this) else m_Layer2 = new @f_layer2(this) endif endif if @colour3>0 if @colour3==11 m_Layer3 = new @f_layer3(this) elseif @colour3==12 m_QuickGradient[3] = new @f_quickgradient3(this) m_Layer3 = new @f_gradientlayer3(this) elseif GradientColoring(m_Colouring[@colour3-1]) && !m_Direct[@colour3-1] m_Layer3 = new @f_gradientlayer3(this) else m_Layer3 = new @f_layer3(this) endif endif if @colour4>0 if @colour4==11 m_Layer4 = new @f_layer4(this) elseif @colour4==12 m_QuickGradient[4] = new @f_quickgradient4(this) m_Layer4 = new @f_gradientlayer4(this) elseif GradientColoring(m_Colouring[@colour4-1]) && !m_Direct[@colour4-1] m_Layer4 = new @f_gradientlayer4(this) else m_Layer4 = new @f_layer4(this) endif endif if @colour5>0 if @colour5==11 m_Layer5 = new @f_layer5(this) elseif @colour5==12 m_QuickGradient[5] = new @f_quickgradient5(this) m_Layer5 = new @f_gradientlayer5(this) elseif GradientColoring(m_Colouring[@colour5-1]) && !m_Direct[@colour5-1] m_Layer5 = new @f_gradientlayer5(this) else m_Layer5 = new @f_layer5(this) endif endif if @colour6>0 if @colour6==11 m_Layer6 = new @f_layer6(this) elseif @colour6==12 m_QuickGradient[6] = new @f_quickgradient6(this) m_Layer6 = new @f_gradientlayer6(this) elseif GradientColoring(m_Colouring[@colour6-1]) && !m_Direct[@colour6-1] m_Layer6 = new @f_gradientlayer6(this) else m_Layer6 = new @f_layer6(this) endif endif if @colour7>0 if @colour7==11 m_Layer7 = new @f_layer7(this) elseif @colour7==12 m_QuickGradient[7] = new @f_quickgradient7(this) m_Layer7 = new @f_gradientlayer7(this) elseif GradientColoring(m_Colouring[@colour7-1]) && !m_Direct[@colour7-1] m_Layer7 = new @f_gradientlayer7(this) else m_Layer7 = new @f_layer7(this) endif endif if @colour8>0 if @colour8==11 m_Layer8 = new @f_layer8(this) elseif @colour8==12 m_QuickGradient[8] = new @f_quickgradient8(this) m_Layer8 = new @f_gradientlayer8(this) elseif GradientColoring(m_Colouring[@colour8-1]) && !m_Direct[@colour8-1] m_Layer8 = new @f_gradientlayer8(this) else m_Layer8 = new @f_layer8(this) endif endif if @colour9>0 if @colour9==11 m_Layer9 = new @f_layer9(this) elseif @colour9==12 m_QuickGradient[9] = new @f_quickgradient9(this) m_Layer9 = new @f_gradientlayer9(this) elseif GradientColoring(m_Colouring[@colour9-1]) && !m_Direct[@colour9-1] m_Layer9 = new @f_gradientlayer9(this) else m_Layer9 = new @f_layer9(this) endif endif endfunc ;

; Initialisation (per pixel)
; @param pz initial z from the formula ; @param ppixel the location (normally #pixel) func Init(complex pz, complex ppixel) int i = 0 repeat if m_Use[i] m_Colouring[i].Init(pz, ppixel) endif if m_QuickGradient[i] m_QuickGradient[i].Init(pz, ppixel) endif until (i=i+1)>=10 if m_Use[10] m_Colouring[10].Init(pz, ppixel) endif endfunc ;

; @param pz the z value func Iterate(complex pz) int i = 0 repeat if m_Use[i] m_Colouring[i].Iterate(pz) endif until (i=i+1)>=11 endfunc ;

; @param pz the z value ; @param clr the colour to use as the base colour ; @return the colour color func ResultUsingBaseColor(complex pz, color clr) bool m_Solid[10] int i = 0 repeat if m_Use[i] if GradientColoring(m_Colouring[i]) && !m_Direct[i] GradientColoring tmpGC = GradientColoring(m_Colouring[i]) m_Index[i] = tmpGC.ResultIndex(pz) else m_Colour[i] = m_Colouring[i].Result(pz) endif m_Solid[i] = m_Colouring[i].IsSolid() endif until (i=i+1)>=10 if @colour0>0 if @colour0==11 clr = m_Layer0.FullMerge(clr, @clr0) elseif @colour0==12 clr = m_Layer0.GradientMerge(clr, m_QuickGradient[0].ResultIndex(pz)) elseif m_Solid[@colour0-1] clr = m_Layer0.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour0-1]) && !m_Direct[@colour0-1] clr = m_Layer0.GradientMerge(clr, m_Index[@colour0-1]) else clr = m_Layer0.FullMerge(clr, m_Colour[@colour0-1]) endif endif if @colour1>0 if @colour1==11 clr = m_Layer1.FullMerge(clr, @clr1) elseif @colour1==12 clr = m_Layer1.GradientMerge(clr, m_QuickGradient[1].ResultIndex(pz)) elseif m_Solid[@colour1-1] clr = m_Layer1.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour1-1]) && !m_Direct[@colour1-1] clr = m_Layer1.GradientMerge(clr, m_Index[@colour1-1]) else clr = m_Layer1.FullMerge(clr, m_Colour[@colour1-1]) endif endif if @colour2>0 if @colour2==11 clr = m_Layer2.FullMerge(clr, @clr2) elseif @colour2==12 clr = m_Layer2.GradientMerge(clr, m_QuickGradient[2].ResultIndex(pz)) elseif m_Solid[@colour2-1] clr = m_Layer2.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour2-1]) && !m_Direct[@colour2-1] clr = m_Layer2.GradientMerge(clr, m_Index[@colour2-1]) else clr = m_Layer2.FullMerge(clr, m_Colour[@colour2-1]) endif endif if @colour3>0 if @colour3==11 clr = m_Layer3.FullMerge(clr, @clr3) elseif @colour3==12 clr = m_Layer3.GradientMerge(clr, m_QuickGradient[3].ResultIndex(pz)) elseif m_Solid[@colour3-1] clr = m_Layer3.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour3-1]) && !m_Direct[@colour3-1] clr = m_Layer3.GradientMerge(clr, m_Index[@colour3-1]) else clr = m_Layer3.FullMerge(clr, m_Colour[@colour3-1]) endif endif if @colour4>0 if @colour4==11 clr = m_Layer4.FullMerge(clr, @clr4) elseif @colour4==12 clr = m_Layer4.GradientMerge(clr, m_QuickGradient[4].ResultIndex(pz)) elseif m_Solid[@colour4-1] clr = m_Layer4.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour4-1]) && !m_Direct[@colour4-1] clr = m_Layer4.GradientMerge(clr, m_Index[@colour4-1]) else clr = m_Layer4.FullMerge(clr, m_Colour[@colour4-1]) endif endif if @colour5>0 if @colour5==11 clr = m_Layer5.FullMerge(clr, @clr5) elseif @colour5==12 clr = m_Layer5.GradientMerge(clr, m_QuickGradient[5].ResultIndex(pz)) elseif m_Solid[@colour5-1] clr = m_Layer5.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour5-1]) && !m_Direct[@colour5-1] clr = m_Layer5.GradientMerge(clr, m_Index[@colour5-1]) else clr = m_Layer5.FullMerge(clr, m_Colour[@colour5-1]) endif endif if @colour6>0 if @colour6==11 clr = m_Layer6.FullMerge(clr, @clr6) elseif @colour6==12 clr = m_Layer6.GradientMerge(clr, m_QuickGradient[6].ResultIndex(pz)) elseif m_Solid[@colour6-1] clr = m_Layer6.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour6-1]) && !m_Direct[@colour6-1] clr = m_Layer6.GradientMerge(clr, m_Index[@colour6-1]) else clr = m_Layer6.FullMerge(clr, m_Colour[@colour6-1]) endif endif if @colour7>0 if @colour7==11 clr = m_Layer7.FullMerge(clr, @clr7) elseif @colour7==12 clr = m_Layer7.GradientMerge(clr, m_QuickGradient[7].ResultIndex(pz)) elseif m_Solid[@colour7-1] clr = m_Layer7.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour7-1]) && !m_Direct[@colour7-1] clr = m_Layer7.GradientMerge(clr, m_Index[@colour7-1]) else clr = m_Layer7.FullMerge(clr, m_Colour[@colour7-1]) endif endif if @colour8>0 if @colour8==11 clr = m_Layer8.FullMerge(clr, @clr8) elseif @colour8==12 clr = m_Layer8.GradientMerge(clr, m_QuickGradient[8].ResultIndex(pz)) elseif m_Solid[@colour8-1] clr = m_Layer8.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour8-1]) && !m_Direct[@colour8-1] clr = m_Layer8.GradientMerge(clr, m_Index[@colour8-1]) else clr = m_Layer8.FullMerge(clr, m_Colour[@colour8-1]) endif endif if @colour9>0 if @colour9==11 clr = m_Layer9.FullMerge(clr, @clr9) elseif @colour9==12 clr = m_Layer9.GradientMerge(clr, m_QuickGradient[9].ResultIndex(pz)) elseif m_Solid[@colour9-1] clr = m_Layer9.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour9-1]) && !@f_direct9 clr = m_Layer9.GradientMerge(clr, m_Index[@colour9-1]) else clr = m_Layer9.FullMerge(clr, m_Colour[@colour9-1]) endif endif if m_Use[10] clr = m_LayerColouring.ResultUsingBaseColor(pz, clr) endif return clr endfunc ;

; @param pz the z value ; @return the colour color func Result(complex pz) return ResultUsingBaseColor(pz, @basecolour) endfunc private: Coloring m_Colouring[11] GradientColoring m_QuickGradient[10] MMF_MultiLayerBase m_LayerColouring Layer m_Layer0 Layer m_Layer1 Layer m_Layer2 Layer m_Layer3 Layer m_Layer4 Layer m_Layer5 Layer m_Layer6 Layer m_Layer7 Layer m_Layer8 Layer m_Layer9 color m_Colour[10] float m_Index[10] bool m_Use[11] bool m_Direct[10] default: title = "MMF Layered" rating = recommended param v_mmflayered caption = "Version (MMF Layered)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam MMF_MultiLayerBase param f_colouring10 caption = "More Layers" default = MMF_MultiLayerNone hint = "Use to add more layers." endparam heading enabled = false endheading param colour9 caption = "Layer 9 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 0 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 9" visible = @colour9>0 endheading color param clr9 caption = "Layer 9 Colour" default = RGBA(1,1,1,1) visible = @colour9==11 endparam MMF_QuickGradient param f_quickgradient9 caption = "Layer 9 Gradient Colouring" visible = @colour9==12 endparam DirectLayer param f_layer9 caption = "Layer Merge" default = MMF_DirectLayer visible = ((@colour9==1 && (@f_colouring0==DirectColoring || @f_direct0)) \ || (@colour9==2 && (@f_colouring1==DirectColoring || @f_direct1)) \ || (@colour9==3 && (@f_colouring2==DirectColoring || @f_direct2)) \ || (@colour9==4 && (@f_colouring3==DirectColoring || @f_direct3)) \ || (@colour9==5 && (@f_colouring4==DirectColoring || @f_direct4)) \ || (@colour9==6 && (@f_colouring5==DirectColoring || @f_direct5)) \ || (@colour9==7 && (@f_colouring6==DirectColoring || @f_direct6)) \ || (@colour9==8 && (@f_colouring7==DirectColoring || @f_direct7)) \ || (@colour9==9 && (@f_colouring8==DirectColoring || @f_direct8)) \ || (@colour9==10 && (@f_colouring9==DirectColoring || @f_direct9)) \ || @colour9==11) endparam GradientLayer param f_gradientlayer9 caption = "Gradient Layer Merge" default = MMF_GradientLayer visible = ((@colour9==1 && @f_colouring0==GradientColoring && !@f_direct0) \ || (@colour9==2 && @f_colouring1==GradientColoring && !@f_direct1) \ || (@colour9==3 && @f_colouring2==GradientColoring && !@f_direct2) \ || (@colour9==4 && @f_colouring3==GradientColoring && !@f_direct3) \ || (@colour9==5 && @f_colouring4==GradientColoring && !@f_direct4) \ || (@colour9==6 && @f_colouring5==GradientColoring && !@f_direct5) \ || (@colour9==7 && @f_colouring6==GradientColoring && !@f_direct6) \ || (@colour9==8 && @f_colouring7==GradientColoring && !@f_direct7) \ || (@colour9==9 && @f_colouring8==GradientColoring && !@f_direct8) \ || (@colour9==10 && @f_colouring9==GradientColoring && !@f_direct9) \ || @colour9==12) endparam heading enabled = false visible = @colour9>0 endheading param colour8 caption = "Layer 8 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 0 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 8" visible = @colour8>0 endheading color param clr8 caption = "Layer 8 Colour" default = RGBA(1,1,1,1) visible = @colour8==11 endparam MMF_QuickGradient param f_quickgradient8 caption = "Layer 8 Gradient Colouring" visible = @colour8==12 endparam DirectLayer param f_layer8 caption = "Layer Merge" default = MMF_DirectLayer visible = ((@colour8==1 && (@f_colouring0==DirectColoring || @f_direct0)) \ || (@colour8==2 && (@f_colouring1==DirectColoring || @f_direct1)) \ || (@colour8==3 && (@f_colouring2==DirectColoring || @f_direct2)) \ || (@colour8==4 && (@f_colouring3==DirectColoring || @f_direct3)) \ || (@colour8==5 && (@f_colouring4==DirectColoring || @f_direct4)) \ || (@colour8==6 && (@f_colouring5==DirectColoring || @f_direct5)) \ || (@colour8==7 && (@f_colouring6==DirectColoring || @f_direct6)) \ || (@colour8==8 && (@f_colouring7==DirectColoring || @f_direct7)) \ || (@colour8==9 && (@f_colouring8==DirectColoring || @f_direct8)) \ || (@colour8==10 && (@f_colouring9==DirectColoring || @f_direct9)) \ || @colour8==11) endparam GradientLayer param f_gradientlayer8 caption = "Gradient Layer Merge" default = MMF_GradientLayer visible = ((@colour8==1 && @f_colouring0==GradientColoring && !@f_direct0) \ || (@colour8==2 && @f_colouring1==GradientColoring && !@f_direct1) \ || (@colour8==3 && @f_colouring2==GradientColoring && !@f_direct2) \ || (@colour8==4 && @f_colouring3==GradientColoring && !@f_direct3) \ || (@colour8==5 && @f_colouring4==GradientColoring && !@f_direct4) \ || (@colour8==6 && @f_colouring5==GradientColoring && !@f_direct5) \ || (@colour8==7 && @f_colouring6==GradientColoring && !@f_direct6) \ || (@colour8==8 && @f_colouring7==GradientColoring && !@f_direct7) \ || (@colour8==9 && @f_colouring8==GradientColoring && !@f_direct8) \ || (@colour8==10 && @f_colouring9==GradientColoring && !@f_direct9) \ || @colour8==12) endparam heading enabled = false visible = @colour8>0 endheading param colour7 caption = "Layer 7 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 0 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 7" visible = @colour7>0 endheading color param clr7 caption = "Layer 7 Colour" default = RGBA(1,1,1,1) visible = @colour7==11 endparam MMF_QuickGradient param f_quickgradient7 caption = "Layer 7 Gradient Colouring" visible = @colour7==12 endparam DirectLayer param f_layer7 caption = "Layer Merge" default = MMF_DirectLayer visible = ((@colour7==1 && (@f_colouring0==DirectColoring || @f_direct0)) \ || (@colour7==2 && (@f_colouring1==DirectColoring || @f_direct1)) \ || (@colour7==3 && (@f_colouring2==DirectColoring || @f_direct2)) \ || (@colour7==4 && (@f_colouring3==DirectColoring || @f_direct3)) \ || (@colour7==5 && (@f_colouring4==DirectColoring || @f_direct4)) \ || (@colour7==6 && (@f_colouring5==DirectColoring || @f_direct5)) \ || (@colour7==7 && (@f_colouring6==DirectColoring || @f_direct6)) \ || (@colour7==8 && (@f_colouring7==DirectColoring || @f_direct7)) \ || (@colour7==9 && (@f_colouring8==DirectColoring || @f_direct8)) \ || (@colour7==10 && (@f_colouring9==DirectColoring || @f_direct9)) \ || @colour7==11) endparam GradientLayer param f_gradientlayer7 caption = "Gradient Layer Merge" default = MMF_GradientLayer visible = ((@colour7==1 && @f_colouring0==GradientColoring && !@f_direct0) \ || (@colour7==2 && @f_colouring1==GradientColoring && !@f_direct1) \ || (@colour7==3 && @f_colouring2==GradientColoring && !@f_direct2) \ || (@colour7==4 && @f_colouring3==GradientColoring && !@f_direct3) \ || (@colour7==5 && @f_colouring4==GradientColoring && !@f_direct4) \ || (@colour7==6 && @f_colouring5==GradientColoring && !@f_direct5) \ || (@colour7==7 && @f_colouring6==GradientColoring && !@f_direct6) \ || (@colour7==8 && @f_colouring7==GradientColoring && !@f_direct7) \ || (@colour7==9 && @f_colouring8==GradientColoring && !@f_direct8) \ || (@colour7==10 && @f_colouring9==GradientColoring && !@f_direct9) \ || @colour7==12) endparam heading enabled = false visible = @colour7>0 endheading param colour6 caption = "Layer 6 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 0 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 6" visible = @colour6>0 endheading color param clr6 caption = "Layer 6 Colour" default = RGBA(1,1,1,1) visible = @colour6==11 endparam MMF_QuickGradient param f_quickgradient6 caption = "Layer 6 Gradient Colouring" visible = @colour6==12 endparam DirectLayer param f_layer6 caption = "Layer Merge" default = MMF_DirectLayer visible = ((@colour6==1 && (@f_colouring0==DirectColoring || @f_direct0)) \ || (@colour6==2 && (@f_colouring1==DirectColoring || @f_direct1)) \ || (@colour6==3 && (@f_colouring2==DirectColoring || @f_direct2)) \ || (@colour6==4 && (@f_colouring3==DirectColoring || @f_direct3)) \ || (@colour6==5 && (@f_colouring4==DirectColoring || @f_direct4)) \ || (@colour6==6 && (@f_colouring5==DirectColoring || @f_direct5)) \ || (@colour6==7 && (@f_colouring6==DirectColoring || @f_direct6)) \ || (@colour6==8 && (@f_colouring7==DirectColoring || @f_direct7)) \ || (@colour6==9 && (@f_colouring8==DirectColoring || @f_direct8)) \ || (@colour6==10 && (@f_colouring9==DirectColoring || @f_direct9)) \ || @colour6==11) endparam GradientLayer param f_gradientlayer6 caption = "Gradient Layer Merge" default = MMF_GradientLayer visible = ((@colour6==1 && @f_colouring0==GradientColoring && !@f_direct0) \ || (@colour6==2 && @f_colouring1==GradientColoring && !@f_direct1) \ || (@colour6==3 && @f_colouring2==GradientColoring && !@f_direct2) \ || (@colour6==4 && @f_colouring3==GradientColoring && !@f_direct3) \ || (@colour6==5 && @f_colouring4==GradientColoring && !@f_direct4) \ || (@colour6==6 && @f_colouring5==GradientColoring && !@f_direct5) \ || (@colour6==7 && @f_colouring6==GradientColoring && !@f_direct6) \ || (@colour6==8 && @f_colouring7==GradientColoring && !@f_direct7) \ || (@colour6==9 && @f_colouring8==GradientColoring && !@f_direct8) \ || (@colour6==10 && @f_colouring9==GradientColoring && !@f_direct9) \ || @colour6==12) endparam heading enabled = false visible = @colour6>0 endheading param colour5 caption = "Layer 5 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 0 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 5" visible = @colour5>0 endheading color param clr5 caption = "Layer 5 Colour" default = RGBA(1,1,1,1) visible = @colour5==11 endparam MMF_QuickGradient param f_quickgradient5 caption = "Layer 5 Gradient Colouring" visible = @colour5==12 endparam DirectLayer param f_layer5 caption = "Layer Merge" default = MMF_DirectLayer visible = ((@colour5==1 && (@f_colouring0==DirectColoring || @f_direct0)) \ || (@colour5==2 && (@f_colouring1==DirectColoring || @f_direct1)) \ || (@colour5==3 && (@f_colouring2==DirectColoring || @f_direct2)) \ || (@colour5==4 && (@f_colouring3==DirectColoring || @f_direct3)) \ || (@colour5==5 && (@f_colouring4==DirectColoring || @f_direct4)) \ || (@colour5==6 && (@f_colouring5==DirectColoring || @f_direct5)) \ || (@colour5==7 && (@f_colouring6==DirectColoring || @f_direct6)) \ || (@colour5==8 && (@f_colouring7==DirectColoring || @f_direct7)) \ || (@colour5==9 && (@f_colouring8==DirectColoring || @f_direct8)) \ || (@colour5==10 && (@f_colouring9==DirectColoring || @f_direct9)) \ || @colour5==11) endparam GradientLayer param f_gradientlayer5 caption = "Gradient Layer Merge" default = MMF_GradientLayer visible = ((@colour5==1 && @f_colouring0==GradientColoring && !@f_direct0) \ || (@colour5==2 && @f_colouring1==GradientColoring && !@f_direct1) \ || (@colour5==3 && @f_colouring2==GradientColoring && !@f_direct2) \ || (@colour5==4 && @f_colouring3==GradientColoring && !@f_direct3) \ || (@colour5==5 && @f_colouring4==GradientColoring && !@f_direct4) \ || (@colour5==6 && @f_colouring5==GradientColoring && !@f_direct5) \ || (@colour5==7 && @f_colouring6==GradientColoring && !@f_direct6) \ || (@colour5==8 && @f_colouring7==GradientColoring && !@f_direct7) \ || (@colour5==9 && @f_colouring8==GradientColoring && !@f_direct8) \ || (@colour5==10 && @f_colouring9==GradientColoring && !@f_direct9) \ || @colour5==12) endparam heading enabled = false visible = @colour5>0 endheading param colour4 caption = "Layer 4 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 0 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 4" visible = @colour4>0 endheading color param clr4 caption = "Layer 4 Colour" default = RGBA(1,1,1,1) visible = @colour4==11 endparam MMF_QuickGradient param f_quickgradient4 caption = "Layer 4 Gradient Colouring" visible = @colour4==12 endparam DirectLayer param f_layer4 caption = "Layer Merge" default = MMF_DirectLayer visible = ((@colour4==1 && (@f_colouring0==DirectColoring || @f_direct0)) \ || (@colour4==2 && (@f_colouring1==DirectColoring || @f_direct1)) \ || (@colour4==3 && (@f_colouring2==DirectColoring || @f_direct2)) \ || (@colour4==4 && (@f_colouring3==DirectColoring || @f_direct3)) \ || (@colour4==5 && (@f_colouring4==DirectColoring || @f_direct4)) \ || (@colour4==6 && (@f_colouring5==DirectColoring || @f_direct5)) \ || (@colour4==7 && (@f_colouring6==DirectColoring || @f_direct6)) \ || (@colour4==8 && (@f_colouring7==DirectColoring || @f_direct7)) \ || (@colour4==9 && (@f_colouring8==DirectColoring || @f_direct8)) \ || (@colour4==10 && (@f_colouring9==DirectColoring || @f_direct9)) \ || @colour4==11) endparam GradientLayer param f_gradientlayer4 caption = "Gradient Layer Merge" default = MMF_GradientLayer visible = ((@colour4==1 && @f_colouring0==GradientColoring && !@f_direct0) \ || (@colour4==2 && @f_colouring1==GradientColoring && !@f_direct1) \ || (@colour4==3 && @f_colouring2==GradientColoring && !@f_direct2) \ || (@colour4==4 && @f_colouring3==GradientColoring && !@f_direct3) \ || (@colour4==5 && @f_colouring4==GradientColoring && !@f_direct4) \ || (@colour4==6 && @f_colouring5==GradientColoring && !@f_direct5) \ || (@colour4==7 && @f_colouring6==GradientColoring && !@f_direct6) \ || (@colour4==8 && @f_colouring7==GradientColoring && !@f_direct7) \ || (@colour4==9 && @f_colouring8==GradientColoring && !@f_direct8) \ || (@colour4==10 && @f_colouring9==GradientColoring && !@f_direct9) \ || @colour4==12) endparam heading enabled = false visible = @colour4>0 endheading param colour3 caption = "Layer 3 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 0 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 3" visible = @colour3>0 endheading color param clr3 caption = "Layer 3 Colour" default = RGBA(1,1,1,1) visible = @colour3==11 endparam MMF_QuickGradient param f_quickgradient3 caption = "Layer 3 Gradient Colouring" visible = @colour3==12 endparam DirectLayer param f_layer3 caption = "Layer Merge" default = MMF_DirectLayer visible = ((@colour3==1 && (@f_colouring0==DirectColoring || @f_direct0)) \ || (@colour3==2 && (@f_colouring1==DirectColoring || @f_direct1)) \ || (@colour3==3 && (@f_colouring2==DirectColoring || @f_direct2)) \ || (@colour3==4 && (@f_colouring3==DirectColoring || @f_direct3)) \ || (@colour3==5 && (@f_colouring4==DirectColoring || @f_direct4)) \ || (@colour3==6 && (@f_colouring5==DirectColoring || @f_direct5)) \ || (@colour3==7 && (@f_colouring6==DirectColoring || @f_direct6)) \ || (@colour3==8 && (@f_colouring7==DirectColoring || @f_direct7)) \ || (@colour3==9 && (@f_colouring8==DirectColoring || @f_direct8)) \ || (@colour3==10 && (@f_colouring9==DirectColoring || @f_direct9)) \ || @colour3==11) endparam GradientLayer param f_gradientlayer3 caption = "Gradient Layer Merge" default = MMF_GradientLayer visible = ((@colour3==1 && @f_colouring0==GradientColoring && !@f_direct0) \ || (@colour3==2 && @f_colouring1==GradientColoring && !@f_direct1) \ || (@colour3==3 && @f_colouring2==GradientColoring && !@f_direct2) \ || (@colour3==4 && @f_colouring3==GradientColoring && !@f_direct3) \ || (@colour3==5 && @f_colouring4==GradientColoring && !@f_direct4) \ || (@colour3==6 && @f_colouring5==GradientColoring && !@f_direct5) \ || (@colour3==7 && @f_colouring6==GradientColoring && !@f_direct6) \ || (@colour3==8 && @f_colouring7==GradientColoring && !@f_direct7) \ || (@colour3==9 && @f_colouring8==GradientColoring && !@f_direct8) \ || (@colour3==10 && @f_colouring9==GradientColoring && !@f_direct9) \ || @colour3==12) endparam heading enabled = false visible = @colour3>0 endheading param colour2 caption = "Layer 2 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 0 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 2" visible = @colour2>0 endheading color param clr2 caption = "Layer 2 Colour" default = RGBA(1,1,1,1) visible = @colour2==11 endparam MMF_QuickGradient param f_quickgradient2 caption = "Layer 2 Gradient Colouring" visible = @colour2==12 endparam DirectLayer param f_layer2 caption = "Layer Merge" default = MMF_DirectLayer visible = ((@colour2==1 && (@f_colouring0==DirectColoring || @f_direct0)) \ || (@colour2==2 && (@f_colouring1==DirectColoring || @f_direct1)) \ || (@colour2==3 && (@f_colouring2==DirectColoring || @f_direct2)) \ || (@colour2==4 && (@f_colouring3==DirectColoring || @f_direct3)) \ || (@colour2==5 && (@f_colouring4==DirectColoring || @f_direct4)) \ || (@colour2==6 && (@f_colouring5==DirectColoring || @f_direct5)) \ || (@colour2==7 && (@f_colouring6==DirectColoring || @f_direct6)) \ || (@colour2==8 && (@f_colouring7==DirectColoring || @f_direct7)) \ || (@colour2==9 && (@f_colouring8==DirectColoring || @f_direct8)) \ || (@colour2==10 && (@f_colouring9==DirectColoring || @f_direct9)) \ || @colour2==11) endparam GradientLayer param f_gradientlayer2 caption = "Gradient Layer Merge" default = MMF_GradientLayer visible = ((@colour2==1 && @f_colouring0==GradientColoring && !@f_direct0) \ || (@colour2==2 && @f_colouring1==GradientColoring && !@f_direct1) \ || (@colour2==3 && @f_colouring2==GradientColoring && !@f_direct2) \ || (@colour2==4 && @f_colouring3==GradientColoring && !@f_direct3) \ || (@colour2==5 && @f_colouring4==GradientColoring && !@f_direct4) \ || (@colour2==6 && @f_colouring5==GradientColoring && !@f_direct5) \ || (@colour2==7 && @f_colouring6==GradientColoring && !@f_direct6) \ || (@colour2==8 && @f_colouring7==GradientColoring && !@f_direct7) \ || (@colour2==9 && @f_colouring8==GradientColoring && !@f_direct8) \ || (@colour2==10 && @f_colouring9==GradientColoring && !@f_direct9) \ || @colour2==12) endparam heading enabled = false visible = @colour2>0 endheading param colour1 caption = "Layer 1 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 2 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 1" visible = @colour1>0 endheading color param clr1 caption = "Layer 1 Colour" default = RGBA(1,1,1,1) visible = @colour1==11 endparam MMF_QuickGradient param f_quickgradient1 caption = "Layer 1 Gradient Colouring" visible = @colour1==12 endparam DirectLayer param f_layer1 caption = "Layer Merge" default = MMF_DirectLayer visible = ((@colour1==1 && (@f_colouring0==DirectColoring || @f_direct0)) \ || (@colour1==2 && (@f_colouring1==DirectColoring || @f_direct1)) \ || (@colour1==3 && (@f_colouring2==DirectColoring || @f_direct2)) \ || (@colour1==4 && (@f_colouring3==DirectColoring || @f_direct3)) \ || (@colour1==5 && (@f_colouring4==DirectColoring || @f_direct4)) \ || (@colour1==6 && (@f_colouring5==DirectColoring || @f_direct5)) \ || (@colour1==7 && (@f_colouring6==DirectColoring || @f_direct6)) \ || (@colour1==8 && (@f_colouring7==DirectColoring || @f_direct7)) \ || (@colour1==9 && (@f_colouring8==DirectColoring || @f_direct8)) \ || (@colour1==10 && (@f_colouring9==DirectColoring || @f_direct9)) \ || @colour1==11) endparam GradientLayer param f_gradientlayer1 caption = "Gradient Layer Merge" default = MMF_GradientLayer visible = ((@colour1==1 && @f_colouring0==GradientColoring && !@f_direct0) \ || (@colour1==2 && @f_colouring1==GradientColoring && !@f_direct1) \ || (@colour1==3 && @f_colouring2==GradientColoring && !@f_direct2) \ || (@colour1==4 && @f_colouring3==GradientColoring && !@f_direct3) \ || (@colour1==5 && @f_colouring4==GradientColoring && !@f_direct4) \ || (@colour1==6 && @f_colouring5==GradientColoring && !@f_direct5) \ || (@colour1==7 && @f_colouring6==GradientColoring && !@f_direct6) \ || (@colour1==8 && @f_colouring7==GradientColoring && !@f_direct7) \ || (@colour1==9 && @f_colouring8==GradientColoring && !@f_direct8) \ || (@colour1==10 && @f_colouring9==GradientColoring && !@f_direct9) \ || @colour1==12) endparam heading enabled = false visible = @colour1>0 endheading param colour0 caption = "Layer 0 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 1 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 0" visible = @colour0>0 endheading color param clr0 caption = "Layer 0 Colour" default = RGBA(1,1,1,1) visible = @colour0==11 endparam MMF_QuickGradient param f_quickgradient0 caption = "Layer 0 Gradient Colouring" visible = @colour0==12 endparam DirectLayer param f_layer0 caption = "Layer Merge" default = MMF_DirectLayer visible = ((@colour0==1 && (@f_colouring0==DirectColoring || @f_direct0)) \ || (@colour0==2 && (@f_colouring1==DirectColoring || @f_direct1)) \ || (@colour0==3 && (@f_colouring2==DirectColoring || @f_direct2)) \ || (@colour0==4 && (@f_colouring3==DirectColoring || @f_direct3)) \ || (@colour0==5 && (@f_colouring4==DirectColoring || @f_direct4)) \ || (@colour0==6 && (@f_colouring5==DirectColoring || @f_direct5)) \ || (@colour0==7 && (@f_colouring6==DirectColoring || @f_direct6)) \ || (@colour0==8 && (@f_colouring7==DirectColoring || @f_direct7)) \ || (@colour0==9 && (@f_colouring8==DirectColoring || @f_direct8)) \ || (@colour0==10 && (@f_colouring9==DirectColoring || @f_direct9)) \ || @colour0==11) endparam GradientLayer param f_gradientlayer0 caption = "Gradient Layer Merge" default = MMF_GradientLayer visible = ((@colour0==1 && @f_colouring0==GradientColoring && !@f_direct0) \ || (@colour0==2 && @f_colouring1==GradientColoring && !@f_direct1) \ || (@colour0==3 && @f_colouring2==GradientColoring && !@f_direct2) \ || (@colour0==4 && @f_colouring3==GradientColoring && !@f_direct3) \ || (@colour0==5 && @f_colouring4==GradientColoring && !@f_direct4) \ || (@colour0==6 && @f_colouring5==GradientColoring && !@f_direct5) \ || (@colour0==7 && @f_colouring6==GradientColoring && !@f_direct6) \ || (@colour0==8 && @f_colouring7==GradientColoring && !@f_direct7) \ || (@colour0==9 && @f_colouring8==GradientColoring && !@f_direct8) \ || (@colour0==10 && @f_colouring9==GradientColoring && !@f_direct9) \ || @colour0==12) endparam heading caption = "Base Colour" text = "Only used if below the lowest layer." endheading color param basecolour caption = "Base Colour" default = RGBA(0,0,0,0) hint = "Note that if there are 'Layer' parameters below this parameter in \ the parameter list then this colour is unused i.e. this colour \ is only used if it is part of the lowest 10 layers." endparam heading caption = "Colouring 9" visible = @colour0==10 || @colour1==10 || @colour2==10 || @colour3==10 \ || @colour4==10 || @colour5==10 || @colour6==10 || @colour7==10 \ || @colour8==10 || @colour9==10 endheading bool param f_direct9 caption = "Use in Direct Mode" default = false hint = "Some gradient colourings behave differently when used in direct \ mode rather than gradient mode. Enabling this option will use \ the gradient colouring in direct colouring mode." visible = (@colour0==10 || @colour1==10 || @colour2==10 || @colour3==10 \ || @colour4==10 || @colour5==10 || @colour6==10 || @colour7==10 \ || @colour8==10 || @colour9==10) && @f_Colouring9==GradientColoring endparam Coloring param f_Colouring9 caption = "Colouring 9" default = Standard_Gradient visible = @colour0==10 || @colour1==10 || @colour2==10 || @colour3==10 \ || @colour4==10 || @colour5==10 || @colour6==10 || @colour7==10 \ || @colour8==10 || @colour9==10 endparam heading caption = "Colouring 8" visible = @colour0==9 || @colour1==9 || @colour2==9 || @colour3==9 \ || @colour4==9 || @colour5==9 || @colour6==9 || @colour7==9 \ || @colour8==9 || @colour9==9 endheading bool param f_direct8 caption = "Use in Direct Mode" default = false hint = "Some gradient colourings behave differently when used in direct \ mode rather than gradient mode. Enabling this option will use \ the gradient colouring in direct colouring mode." visible = (@colour0==9 || @colour1==9 || @colour2==9 || @colour3==9 \ || @colour4==9 || @colour5==9 || @colour6==9 || @colour7==9 \ || @colour8==9 || @colour9==9) && @f_Colouring8==GradientColoring endparam Coloring param f_Colouring8 caption = "Colouring 8" default = Standard_Gradient visible = @colour0==9 || @colour1==9 || @colour2==9 || @colour3==9 \ || @colour4==9 || @colour5==9 || @colour6==9 || @colour7==9 \ || @colour8==9 || @colour9==9 endparam heading caption = "Colouring 7" visible = @colour0==8 || @colour1==8 || @colour2==8 || @colour3==8 \ || @colour4==8 || @colour5==8 || @colour6==8 || @colour7==8 \ || @colour8==8 || @colour9==8 endheading bool param f_direct7 caption = "Use in Direct Mode" default = false hint = "Some gradient colourings behave differently when used in direct \ mode rather than gradient mode. Enabling this option will use \ the gradient colouring in direct colouring mode." visible = (@colour0==8 || @colour1==8 || @colour2==8 || @colour3==8 \ || @colour4==8 || @colour5==8 || @colour6==8 || @colour7==8 \ || @colour8==8 || @colour9==8) && @f_Colouring7==GradientColoring endparam Coloring param f_Colouring7 caption = "Colouring 7" default = Standard_Gradient visible = @colour0==8 || @colour1==8 || @colour2==8 || @colour3==8 \ || @colour4==8 || @colour5==8 || @colour6==8 || @colour7==8 \ || @colour8==8 || @colour9==8 endparam heading caption = "Colouring 6" visible = @colour0==7 || @colour1==7 || @colour2==7 || @colour3==7 \ || @colour4==7 || @colour5==7 || @colour6==7 || @colour7==7 \ || @colour8==7 || @colour9==7 endheading bool param f_direct6 caption = "Use in Direct Mode" default = false hint = "Some gradient colourings behave differently when used in direct \ mode rather than gradient mode. Enabling this option will use \ the gradient colouring in direct colouring mode." visible = (@colour0==7 || @colour1==7 || @colour2==7 || @colour3==7 \ || @colour4==7 || @colour5==7 || @colour6==7 || @colour7==7 \ || @colour8==7 || @colour9==7) && @f_Colouring6==GradientColoring endparam Coloring param f_Colouring6 caption = "Colouring 6" default = Standard_Gradient visible = @colour0==7 || @colour1==7 || @colour2==7 || @colour3==7 \ || @colour4==7 || @colour5==7 || @colour6==7 || @colour7==7 \ || @colour8==7 || @colour9==7 endparam heading caption = "Colouring 5" visible = @colour0==6 || @colour1==6 || @colour2==6 || @colour3==6 \ || @colour4==6 || @colour5==6 || @colour6==6 || @colour7==6 \ || @colour8==6 || @colour9==6 endheading bool param f_direct5 caption = "Use in Direct Mode" default = false hint = "Some gradient colourings behave differently when used in direct \ mode rather than gradient mode. Enabling this option will use \ the gradient colouring in direct colouring mode." visible = (@colour0==6 || @colour1==6 || @colour2==6 || @colour3==6 \ || @colour4==6 || @colour5==6 || @colour6==6 || @colour7==6 \ || @colour8==6 || @colour9==6) && @f_Colouring5==GradientColoring endparam Coloring param f_Colouring5 caption = "Colouring 5" default = Standard_Gradient visible = @colour0==6 || @colour1==6 || @colour2==6 || @colour3==6 \ || @colour4==6 || @colour5==6 || @colour6==6 || @colour7==6 \ || @colour8==6 || @colour9==6 endparam heading caption = "Colouring 4" visible = @colour0==5 || @colour1==5 || @colour2==5 || @colour3==5 \ || @colour4==5 || @colour5==5 || @colour6==5 || @colour7==5 \ || @colour8==5 || @colour9==5 endheading bool param f_direct4 caption = "Use in Direct Mode" default = false hint = "Some gradient colourings behave differently when used in direct \ mode rather than gradient mode. Enabling this option will use \ the gradient colouring in direct colouring mode." visible = (@colour0==5 || @colour1==5 || @colour2==5 || @colour3==5 \ || @colour4==5 || @colour5==5 || @colour6==5 || @colour7==5 \ || @colour8==5 || @colour9==5) && @f_Colouring4==GradientColoring endparam Coloring param f_Colouring4 caption = "Colouring 4" default = Standard_Gradient visible = @colour0==5 || @colour1==5 || @colour2==5 || @colour3==5 \ || @colour4==5 || @colour5==5 || @colour6==5 || @colour7==5 \ || @colour8==5 || @colour9==5 endparam heading caption = "Colouring 3" visible = @colour0==4 || @colour1==4 || @colour2==4 || @colour3==4 \ || @colour4==4 || @colour5==4 || @colour6==4 || @colour7==4 \ || @colour8==4 || @colour9==4 endheading bool param f_direct3 caption = "Use in Direct Mode" default = false hint = "Some gradient colourings behave differently when used in direct \ mode rather than gradient mode. Enabling this option will use \ the gradient colouring in direct colouring mode." visible = (@colour0==4 || @colour1==4 || @colour2==4 || @colour3==4 \ || @colour4==4 || @colour5==4 || @colour6==4 || @colour7==4 \ || @colour8==4 || @colour9==4) && @f_Colouring3==GradientColoring endparam Coloring param f_Colouring3 caption = "Colouring 3" default = Standard_Gradient visible = @colour0==4 || @colour1==4 || @colour2==4 || @colour3==4 \ || @colour4==4 || @colour5==4 || @colour6==4 || @colour7==4 \ || @colour8==4 || @colour9==4 endparam heading caption = "Colouring 2" visible = @colour0==3 || @colour1==3 || @colour2==3 || @colour3==3 \ || @colour4==3 || @colour5==3 || @colour6==3 || @colour7==3 \ || @colour8==3 || @colour9==3 endheading bool param f_direct2 caption = "Use in Direct Mode" default = false hint = "Some gradient colourings behave differently when used in direct \ mode rather than gradient mode. Enabling this option will use \ the gradient colouring in direct colouring mode." visible = (@colour0==3 || @colour1==3 || @colour2==3 || @colour3==3 \ || @colour4==3 || @colour5==3 || @colour6==3 || @colour7==3 \ || @colour8==3 || @colour9==3) && @f_Colouring2==GradientColoring endparam Coloring param f_Colouring2 caption = "Colouring 2" default = Standard_Gradient visible = @colour0==3 || @colour1==3 || @colour2==3 || @colour3==3 \ || @colour4==3 || @colour5==3 || @colour6==3 || @colour7==3 \ || @colour8==3 || @colour9==3 endparam heading caption = "Colouring 1" visible = @colour0==2 || @colour1==2 || @colour2==2 || @colour3==2 \ || @colour4==2 || @colour5==2 || @colour6==2 || @colour7==2 \ || @colour8==2 || @colour9==2 endheading bool param f_direct1 caption = "Use in Direct Mode" default = false hint = "Some gradient colourings behave differently when used in direct \ mode rather than gradient mode. Enabling this option will use \ the gradient colouring in direct colouring mode." visible = (@colour0==2 || @colour1==2 || @colour2==2 || @colour3==2 \ || @colour4==2 || @colour5==2 || @colour6==2 || @colour7==2 \ || @colour8==2 || @colour9==2) && @f_Colouring1==GradientColoring endparam Coloring param f_Colouring1 caption = "Colouring 1" default = Standard_OrbitTraps visible = @colour0==2 || @colour1==2 || @colour2==2 || @colour3==2 \ || @colour4==2 || @colour5==2 || @colour6==2 || @colour7==2 \ || @colour8==2 || @colour9==2 endparam heading caption = "Colouring 0" visible = @colour0==1 || @colour1==1 || @colour2==1 || @colour3==1 \ || @colour4==1 || @colour5==1 || @colour6==1 || @colour7==1 \ || @colour8==1 || @colour9==1 endheading bool param f_direct0 caption = "Use in Direct Mode" default = false hint = "Some gradient colourings behave differently when used in direct \ mode rather than gradient mode. Enabling this option will use \ the gradient colouring in direct colouring mode." visible = (@colour0==1 || @colour1==1 || @colour2==1 || @colour3==1 \ || @colour4==1 || @colour5==1 || @colour6==1 || @colour7==1 \ || @colour8==1 || @colour9==1) && @f_Colouring0==GradientColoring endparam Coloring param f_Colouring0 caption = "Colouring 0" default = Standard_Smooth visible = @colour0==1 || @colour1==1 || @colour2==1 || @colour3==1 \ || @colour4==1 || @colour5==1 || @colour6==1 || @colour7==1 \ || @colour8==1 || @colour9==1 endparam } class MMF_MultiLayer(MMF_MultiLayerBase) { ; PLEASE NOTE This class is obsolete/deprecated.
; Instead of using this class and its derived classes you should use
; the MMF Layered class and its derived classes.
public: import "common.ulb" import "Standard.ulb" ;

; @param pparent typically 'this' from the parent or zero func MMF_MultiLayer(Generic pparent) DirectColoring.DirectColoring(pparent) int i = 0 repeat m_Use[i] = false m_QuickGradient[i] = 0 until (i=i+1)>=10 m_Use[10] = false if @colour0>0 && @colour0<11 m_Use[@colour0-1] = true endif if @colour1>0 && @colour1<11 m_Use[@colour1-1] = true endif if @colour2>0 && @colour2<11 m_Use[@colour2-1] = true endif if @colour3>0 && @colour3<11 m_Use[@colour3-1] = true endif if @colour4>0 && @colour4<11 m_Use[@colour4-1] = true endif if @colour5>0 && @colour5<11 m_Use[@colour5-1] = true endif if @colour6>0 && @colour6<11 m_Use[@colour6-1] = true endif if @colour7>0 && @colour7<11 m_Use[@colour7-1] = true endif if @colour8>0 && @colour8<11 m_Use[@colour8-1] = true endif if @colour9>0 && @colour9<11 m_Use[@colour9-1] = true endif if m_Use[0] m_Colouring[0] = new @f_colouring0(this) endif if m_Use[1] m_Colouring[1] = new @f_colouring1(this) endif if m_Use[2] m_Colouring[2] = new @f_colouring2(this) endif if m_Use[3] m_Colouring[3] = new @f_colouring3(this) endif if m_Use[4] m_Colouring[4] = new @f_colouring4(this) endif if m_Use[5] m_Colouring[5] = new @f_colouring5(this) endif if m_Use[6] m_Colouring[6] = new @f_colouring6(this) endif if m_Use[7] m_Colouring[7] = new @f_colouring7(this) endif if m_Use[8] m_Colouring[8] = new @f_colouring8(this) endif if m_Use[9] m_Colouring[9] = new @f_colouring9(this) endif if @f_colouring10!=MMF_MultiLayerNone m_Use[10] = true m_LayerColouring = MMF_MultiLayerBase(m_Colouring[10] = new @f_colouring10(this)) endif if @colour0>0 if @colour0==11 m_Merge0 = new @f_merge0(this) elseif @colour0==12 m_QuickGradient[0] = new @f_quickgradient0(this) m_Merge0 = new @f_gradientmerge0(this) elseif GradientColoring(m_Colouring[@colour0-1]) m_Merge0 = new @f_gradientmerge0(this) else m_Merge0 = new @f_merge0(this) endif endif if @colour1>0 if @colour1==11 m_Merge1 = new @f_merge1(this) elseif @colour1==12 m_QuickGradient[1] = new @f_quickgradient1(this) m_Merge1 = new @f_gradientmerge1(this) elseif GradientColoring(m_Colouring[@colour1-1]) m_Merge1 = new @f_gradientmerge1(this) else m_Merge1 = new @f_merge1(this) endif endif if @colour2>0 if @colour2==11 m_Merge2 = new @f_merge2(this) elseif @colour2==12 m_QuickGradient[2] = new @f_quickgradient2(this) m_Merge2 = new @f_gradientmerge2(this) elseif GradientColoring(m_Colouring[@colour2-1]) m_Merge2 = new @f_gradientmerge2(this) else m_Merge2 = new @f_merge2(this) endif endif if @colour3>0 if @colour3==11 m_Merge3 = new @f_merge3(this) elseif @colour3==12 m_QuickGradient[3] = new @f_quickgradient3(this) m_Merge3 = new @f_gradientmerge3(this) elseif GradientColoring(m_Colouring[@colour3-1]) m_Merge3 = new @f_gradientmerge3(this) else m_Merge3 = new @f_merge3(this) endif endif if @colour4>0 if @colour4==11 m_Merge4 = new @f_merge4(this) elseif @colour4==12 m_QuickGradient[4] = new @f_quickgradient4(this) m_Merge4 = new @f_gradientmerge4(this) elseif GradientColoring(m_Colouring[@colour4-1]) m_Merge4 = new @f_gradientmerge4(this) else m_Merge4 = new @f_merge4(this) endif endif if @colour5>0 if @colour5==11 m_Merge5 = new @f_merge5(this) elseif @colour5==12 m_QuickGradient[5] = new @f_quickgradient5(this) m_Merge5 = new @f_gradientmerge5(this) elseif GradientColoring(m_Colouring[@colour5-1]) m_Merge5 = new @f_gradientmerge5(this) else m_Merge5 = new @f_merge5(this) endif endif if @colour6>0 if @colour6==11 m_Merge6 = new @f_merge6(this) elseif @colour6==12 m_QuickGradient[6] = new @f_quickgradient6(this) m_Merge6 = new @f_gradientmerge6(this) elseif GradientColoring(m_Colouring[@colour6-1]) m_Merge6 = new @f_gradientmerge6(this) else m_Merge6 = new @f_merge6(this) endif endif if @colour7>0 if @colour7==11 m_Merge7 = new @f_merge7(this) elseif @colour7==12 m_QuickGradient[7] = new @f_quickgradient7(this) m_Merge7 = new @f_gradientmerge7(this) elseif GradientColoring(m_Colouring[@colour7-1]) m_Merge7 = new @f_gradientmerge7(this) else m_Merge7 = new @f_merge7(this) endif endif if @colour8>0 if @colour8==11 m_Merge8 = new @f_merge8(this) elseif @colour8==12 m_QuickGradient[8] = new @f_quickgradient8(this) m_Merge8 = new @f_gradientmerge8(this) elseif GradientColoring(m_Colouring[@colour8-1]) m_Merge8 = new @f_gradientmerge8(this) else m_Merge8 = new @f_merge8(this) endif endif if @colour9>0 if @colour9==11 m_Merge9 = new @f_merge9(this) elseif @colour9==12 m_QuickGradient[9] = new @f_quickgradient9(this) m_Merge9 = new @f_gradientmerge9(this) elseif GradientColoring(m_Colouring[@colour9-1]) m_Merge9 = new @f_gradientmerge9(this) else m_Merge9 = new @f_merge9(this) endif endif endfunc ;

; Initialisation (per pixel)
; @param pz initial z from the formula ; @param ppixel the location (normally #pixel) func Init(complex pz, complex ppixel) int i = 0 repeat if m_Use[i] m_Colouring[i].Init(pz, ppixel) endif if m_QuickGradient[i] m_QuickGradient[i].Init(pz, ppixel) endif until (i=i+1)>=10 if m_Use[10] m_Colouring[10].Init(pz, ppixel) endif endfunc ;

; @param pz the z value func Iterate(complex pz) int i = 0 repeat if m_Use[i] m_Colouring[i].Iterate(pz) endif until (i=i+1)>=11 endfunc ;

; @param pz the z value ; @param clr the colour to use as the base colour ; @return the colour color func ResultUsingBaseColor(complex pz, color clr) bool m_Solid[10] int i = 0 repeat if m_Use[i] if GradientColoring(m_Colouring[i]) GradientColoring tmpGC = GradientColoring(m_Colouring[i]) m_Index[i] = tmpGC.ResultIndex(pz) else m_Colour[i] = m_Colouring[i].Result(pz) endif if @v_mmfmultilayer>0 m_Solid[i] = m_Colouring[i].IsSolid() endif endif until (i=i+1)>=10 if @colour0>0 if @colour0==11 clr = m_Merge0.FullMerge(clr, @clr0) elseif @colour0==12 clr = m_Merge0.GradientMerge(clr, m_QuickGradient[0].ResultIndex(pz)) elseif @v_mmfmultilayer>0 && m_Solid[@colour0-1] clr = m_Merge0.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour0-1]) clr = m_Merge0.GradientMerge(clr, m_Index[@colour0-1]) else clr = m_Merge0.FullMerge(clr, m_Colour[@colour0-1]) endif endif if @colour1>0 if @colour1==11 clr = m_Merge1.FullMerge(clr, @clr1) elseif @colour1==12 clr = m_Merge1.GradientMerge(clr, m_QuickGradient[1].ResultIndex(pz)) elseif @v_mmfmultilayer>0 && m_Solid[@colour1-1] clr = m_Merge1.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour1-1]) clr = m_Merge1.GradientMerge(clr, m_Index[@colour1-1]) else clr = m_Merge1.FullMerge(clr, m_Colour[@colour1-1]) endif endif if @colour2>0 if @colour2==11 clr = m_Merge2.FullMerge(clr, @clr2) elseif @colour2==12 clr = m_Merge2.GradientMerge(clr, m_QuickGradient[2].ResultIndex(pz)) elseif @v_mmfmultilayer>0 && m_Solid[@colour2-1] clr = m_Merge2.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour2-1]) clr = m_Merge2.GradientMerge(clr, m_Index[@colour2-1]) else clr = m_Merge2.FullMerge(clr, m_Colour[@colour2-1]) endif endif if @colour3>0 if @colour3==11 clr = m_Merge3.FullMerge(clr, @clr3) elseif @colour3==12 clr = m_Merge3.GradientMerge(clr, m_QuickGradient[3].ResultIndex(pz)) elseif @v_mmfmultilayer>0 && m_Solid[@colour3-1] clr = m_Merge3.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour3-1]) clr = m_Merge3.GradientMerge(clr, m_Index[@colour3-1]) else clr = m_Merge3.FullMerge(clr, m_Colour[@colour3-1]) endif endif if @colour4>0 if @colour4==11 clr = m_Merge4.FullMerge(clr, @clr4) elseif @colour4==12 clr = m_Merge4.GradientMerge(clr, m_QuickGradient[4].ResultIndex(pz)) elseif @v_mmfmultilayer>0 && m_Solid[@colour4-1] clr = m_Merge4.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour4-1]) clr = m_Merge4.GradientMerge(clr, m_Index[@colour4-1]) else clr = m_Merge4.FullMerge(clr, m_Colour[@colour4-1]) endif endif if @colour5>0 if @colour5==11 clr = m_Merge5.FullMerge(clr, @clr5) elseif @colour5==12 clr = m_Merge5.GradientMerge(clr, m_QuickGradient[5].ResultIndex(pz)) elseif @v_mmfmultilayer>0 && m_Solid[@colour5-1] clr = m_Merge5.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour5-1]) clr = m_Merge5.GradientMerge(clr, m_Index[@colour5-1]) else clr = m_Merge5.FullMerge(clr, m_Colour[@colour5-1]) endif endif if @colour6>0 if @colour6==11 clr = m_Merge6.FullMerge(clr, @clr6) elseif @colour6==12 clr = m_Merge6.GradientMerge(clr, m_QuickGradient[6].ResultIndex(pz)) elseif @v_mmfmultilayer>0 && m_Solid[@colour6-1] clr = m_Merge6.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour6-1]) clr = m_Merge6.GradientMerge(clr, m_Index[@colour6-1]) else clr = m_Merge6.FullMerge(clr, m_Colour[@colour6-1]) endif endif if @colour7>0 if @colour7==11 clr = m_Merge7.FullMerge(clr, @clr7) elseif @colour7==12 clr = m_Merge7.GradientMerge(clr, m_QuickGradient[7].ResultIndex(pz)) elseif @v_mmfmultilayer>0 && m_Solid[@colour7-1] clr = m_Merge7.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour7-1]) clr = m_Merge7.GradientMerge(clr, m_Index[@colour7-1]) else clr = m_Merge7.FullMerge(clr, m_Colour[@colour7-1]) endif endif if @colour8>0 if @colour8==11 clr = m_Merge8.FullMerge(clr, @clr8) elseif @colour8==12 clr = m_Merge8.GradientMerge(clr, m_QuickGradient[8].ResultIndex(pz)) elseif @v_mmfmultilayer>0 && m_Solid[@colour8-1] clr = m_Merge8.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour8-1]) clr = m_Merge8.GradientMerge(clr, m_Index[@colour8-1]) else clr = m_Merge8.FullMerge(clr, m_Colour[@colour8-1]) endif endif if @colour9>0 if @colour9==11 clr = m_Merge9.FullMerge(clr, @clr9) elseif @colour9==12 clr = m_Merge9.GradientMerge(clr, m_QuickGradient[9].ResultIndex(pz)) elseif @v_mmfmultilayer>0 && m_Solid[@colour9-1] clr = m_Merge9.SolidMerge(clr) elseif GradientColoring(m_Colouring[@colour9-1]) clr = m_Merge9.GradientMerge(clr, m_Index[@colour9-1]) else clr = m_Merge9.FullMerge(clr, m_Colour[@colour9-1]) endif endif if m_Use[10] clr = m_LayerColouring.ResultUsingBaseColor(pz, clr) endif return clr endfunc ;

; @param pz the z value ; @return the colour color func Result(complex pz) return ResultUsingBaseColor(pz, @basecolour) endfunc private: Coloring m_Colouring[11] GradientColoring m_QuickGradient[10] MMF_MultiLayerBase m_LayerColouring MMF_LayerMerge m_Merge0 MMF_LayerMerge m_Merge1 MMF_LayerMerge m_Merge2 MMF_LayerMerge m_Merge3 MMF_LayerMerge m_Merge4 MMF_LayerMerge m_Merge5 MMF_LayerMerge m_Merge6 MMF_LayerMerge m_Merge7 MMF_LayerMerge m_Merge8 MMF_LayerMerge m_Merge9 color m_Colour[10] float m_Index[10] bool m_Use[11] default: title = "MMF Multi Layer" rating = notRecommended heading text = "PLEASE NOTE that this colouring is obsolete/deprecated. If \ creating a new UPR then you should use colourings such as \ 'MMF Layered' instead." endheading int param v_mmfmultilayer caption = "Version (MMF Multi Layer)" enum = "1.0" "1.1" default = 1 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = @v_mmfmultilayer<1 endparam MMF_MultiLayerBase param f_colouring10 caption = "More Layers" default = MMF_MultiLayerNone hint = "Use to add more layers." endparam heading enabled = false endheading int param colour9 caption = "Layer 9 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 0 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 9" visible = @colour9>0 endheading color param clr9 caption = "Layer 9 Colour" default = RGBA(1,1,1,1) visible = @colour9==11 endparam MMF_QuickGradient param f_quickgradient9 caption = "Layer 9 Gradient Colouring" visible = @colour9==12 endparam heading text = "Please note that you have chosen a Layer Merge that includes \ gradient options on a layer that is using a Direct mode \ colouring. The gradient parameters in the Layer Merge will be \ ignored - it's better to use a Layer Merge that is not \ 'with Gradient'." visible = ((@colour9==1 && @f_colouring0!=GradientColoring) \ || (@colour9==2 && @f_colouring1!=GradientColoring) \ || (@colour9==3 && @f_colouring2!=GradientColoring) \ || (@colour9==4 && @f_colouring3!=GradientColoring) \ || (@colour9==5 && @f_colouring4!=GradientColoring) \ || (@colour9==6 && @f_colouring5!=GradientColoring) \ || (@colour9==7 && @f_colouring6!=GradientColoring) \ || (@colour9==8 && @f_colouring7!=GradientColoring) \ || (@colour9==9 && @f_colouring8!=GradientColoring) \ || (@colour9==10 && @f_colouring9!=GradientColoring) \ || @colour9==11) && @f_merge9==MMF_GradientLayerMerge endheading MMF_LayerMerge param f_merge9 caption = "Layer Merge" default = MMF_LayerMerge visible = (@colour9==1 && @f_colouring0==DirectColoring) \ || (@colour9==2 && @f_colouring1==DirectColoring) \ || (@colour9==3 && @f_colouring2==DirectColoring) \ || (@colour9==4 && @f_colouring3==DirectColoring) \ || (@colour9==5 && @f_colouring4==DirectColoring) \ || (@colour9==6 && @f_colouring5==DirectColoring) \ || (@colour9==7 && @f_colouring6==DirectColoring) \ || (@colour9==8 && @f_colouring7==DirectColoring) \ || (@colour9==9 && @f_colouring8==DirectColoring) \ || (@colour9==10 && @f_colouring9==DirectColoring) \ || @colour9==11 endparam MMF_GradientLayerMerge param f_gradientmerge9 caption = "Gradient Layer Merge" default = MMF_GradientLayerMerge visible = (@colour9==1 && @f_colouring0==GradientColoring) \ || (@colour9==2 && @f_colouring1==GradientColoring) \ || (@colour9==3 && @f_colouring2==GradientColoring) \ || (@colour9==4 && @f_colouring3==GradientColoring) \ || (@colour9==5 && @f_colouring4==GradientColoring) \ || (@colour9==6 && @f_colouring5==GradientColoring) \ || (@colour9==7 && @f_colouring6==GradientColoring) \ || (@colour9==8 && @f_colouring7==GradientColoring) \ || (@colour9==9 && @f_colouring8==GradientColoring) \ || (@colour9==10 && @f_colouring9==GradientColoring) \ || @colour9==12 endparam heading enabled = false visible = @colour9>0 endheading int param colour8 caption = "Layer 8 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 0 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 8" visible = @colour8>0 endheading color param clr8 caption = "Layer 8 Colour" default = RGBA(1,1,1,1) visible = @colour8==11 endparam MMF_QuickGradient param f_quickgradient8 caption = "Layer 8 Gradient Colouring" visible = @colour8==12 endparam heading text = "Please note that you have chosen a Layer Merge that includes \ gradient options on a layer that is using a Direct mode \ colouring. The gradient parameters in the Layer Merge will be \ ignored - it's better to use a Layer Merge that is not \ 'with Gradient'." visible = ((@colour8==1 && @f_colouring0!=GradientColoring) \ || (@colour8==2 && @f_colouring1!=GradientColoring) \ || (@colour8==3 && @f_colouring2!=GradientColoring) \ || (@colour8==4 && @f_colouring3!=GradientColoring) \ || (@colour8==5 && @f_colouring4!=GradientColoring) \ || (@colour8==6 && @f_colouring5!=GradientColoring) \ || (@colour7==7 && @f_colouring6!=GradientColoring) \ || (@colour8==8 && @f_colouring7!=GradientColoring) \ || (@colour8==9 && @f_colouring8!=GradientColoring) \ || (@colour8==10 && @f_colouring9!=GradientColoring) \ || @colour8==11) && @f_merge8==MMF_GradientLayerMerge endheading MMF_LayerMerge param f_merge8 caption = "Layer Merge" default = MMF_LayerMerge visible = (@colour8==1 && @f_colouring0==DirectColoring) \ || (@colour8==2 && @f_colouring1==DirectColoring) \ || (@colour8==3 && @f_colouring2==DirectColoring) \ || (@colour8==4 && @f_colouring3==DirectColoring) \ || (@colour8==5 && @f_colouring4==DirectColoring) \ || (@colour8==6 && @f_colouring5==DirectColoring) \ || (@colour8==7 && @f_colouring6==DirectColoring) \ || (@colour8==8 && @f_colouring7==DirectColoring) \ || (@colour8==9 && @f_colouring8==DirectColoring) \ || (@colour8==10 && @f_colouring9==DirectColoring) \ || @colour8==11 endparam MMF_GradientLayerMerge param f_gradientmerge8 caption = "Gradient Layer Merge" default = MMF_GradientLayerMerge visible = (@colour8==1 && @f_colouring0==GradientColoring) \ || (@colour8==2 && @f_colouring1==GradientColoring) \ || (@colour8==3 && @f_colouring2==GradientColoring) \ || (@colour8==4 && @f_colouring3==GradientColoring) \ || (@colour8==5 && @f_colouring4==GradientColoring) \ || (@colour8==6 && @f_colouring5==GradientColoring) \ || (@colour8==7 && @f_colouring6==GradientColoring) \ || (@colour8==8 && @f_colouring7==GradientColoring) \ || (@colour8==9 && @f_colouring8==GradientColoring) \ || (@colour8==10 && @f_colouring9==GradientColoring) \ || @colour8==12 endparam heading enabled = false visible = @colour8>0 endheading int param colour7 caption = "Layer 7 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 0 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 7" visible = @colour7>0 endheading color param clr7 caption = "Layer 7 Colour" default = RGBA(1,1,1,1) visible = @colour7==11 endparam MMF_QuickGradient param f_quickgradient7 caption = "Layer 7 Gradient Colouring" visible = @colour7==12 endparam heading text = "Please note that you have chosen a Layer Merge that includes \ gradient options on a layer that is using a Direct mode \ colouring. The gradient parameters in the Layer Merge will be \ ignored - it's better to use a Layer Merge that is not \ 'with Gradient'." visible = ((@colour7==1 && @f_colouring0!=GradientColoring) \ || (@colour7==2 && @f_colouring1!=GradientColoring) \ || (@colour7==3 && @f_colouring2!=GradientColoring) \ || (@colour7==4 && @f_colouring3!=GradientColoring) \ || (@colour7==5 && @f_colouring4!=GradientColoring) \ || (@colour7==6 && @f_colouring5!=GradientColoring) \ || (@colour7==7 && @f_colouring6!=GradientColoring) \ || (@colour7==8 && @f_colouring7!=GradientColoring) \ || (@colour7==9 && @f_colouring8!=GradientColoring) \ || (@colour7==10 && @f_colouring9!=GradientColoring) \ || @colour7==11) && @f_merge7==MMF_GradientLayerMerge endheading MMF_LayerMerge param f_merge7 caption = "Layer Merge" default = MMF_LayerMerge visible = (@colour7==1 && @f_colouring0==DirectColoring) \ || (@colour7==2 && @f_colouring1==DirectColoring) \ || (@colour7==3 && @f_colouring2==DirectColoring) \ || (@colour7==4 && @f_colouring3==DirectColoring) \ || (@colour7==5 && @f_colouring4==DirectColoring) \ || (@colour7==6 && @f_colouring5==DirectColoring) \ || (@colour7==7 && @f_colouring6==DirectColoring) \ || (@colour7==8 && @f_colouring7==DirectColoring) \ || (@colour7==9 && @f_colouring8==DirectColoring) \ || (@colour7==10 && @f_colouring9==DirectColoring) \ || @colour7==11 endparam MMF_GradientLayerMerge param f_gradientmerge7 caption = "Gradient Layer Merge" default = MMF_GradientLayerMerge visible = (@colour7==1 && @f_colouring0==GradientColoring) \ || (@colour7==2 && @f_colouring1==GradientColoring) \ || (@colour7==3 && @f_colouring2==GradientColoring) \ || (@colour7==4 && @f_colouring3==GradientColoring) \ || (@colour7==5 && @f_colouring4==GradientColoring) \ || (@colour7==6 && @f_colouring5==GradientColoring) \ || (@colour7==7 && @f_colouring6==GradientColoring) \ || (@colour7==8 && @f_colouring7==GradientColoring) \ || (@colour7==9 && @f_colouring8==GradientColoring) \ || (@colour7==10 && @f_colouring9==GradientColoring) \ || @colour7==12 endparam heading enabled = false visible = @colour7>0 endheading int param colour6 caption = "Layer 6 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 0 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 6" visible = @colour6>0 endheading color param clr6 caption = "Layer 6 Colour" default = RGBA(1,1,1,1) visible = @colour6==11 endparam MMF_QuickGradient param f_quickgradient6 caption = "Layer 6 Gradient Colouring" visible = @colour6==12 endparam heading text = "Please note that you have chosen a Layer Merge that includes \ gradient options on a layer that is using a Direct mode \ colouring. The gradient parameters in the Layer Merge will be \ ignored - it's better to use a Layer Merge that is not \ 'with Gradient'." visible = ((@colour6==1 && @f_colouring0!=GradientColoring) \ || (@colour6==2 && @f_colouring1!=GradientColoring) \ || (@colour6==3 && @f_colouring2!=GradientColoring) \ || (@colour6==4 && @f_colouring3!=GradientColoring) \ || (@colour6==5 && @f_colouring4!=GradientColoring) \ || (@colour6==6 && @f_colouring5!=GradientColoring) \ || (@colour6==7 && @f_colouring6!=GradientColoring) \ || (@colour6==8 && @f_colouring7!=GradientColoring) \ || (@colour6==9 && @f_colouring8!=GradientColoring) \ || (@colour6==10 && @f_colouring9!=GradientColoring) \ || @colour6==11) && @f_merge6==MMF_GradientLayerMerge endheading MMF_LayerMerge param f_merge6 caption = "Layer Merge" default = MMF_LayerMerge visible = (@colour6==1 && @f_colouring0==DirectColoring) \ || (@colour6==2 && @f_colouring1==DirectColoring) \ || (@colour6==3 && @f_colouring2==DirectColoring) \ || (@colour6==4 && @f_colouring3==DirectColoring) \ || (@colour6==5 && @f_colouring4==DirectColoring) \ || (@colour6==6 && @f_colouring5==DirectColoring) \ || (@colour6==7 && @f_colouring6==DirectColoring) \ || (@colour6==8 && @f_colouring7==DirectColoring) \ || (@colour6==9 && @f_colouring8==DirectColoring) \ || (@colour6==10 && @f_colouring9==DirectColoring) \ || @colour6==11 endparam MMF_GradientLayerMerge param f_gradientmerge6 caption = "Gradient Layer Merge" default = MMF_GradientLayerMerge visible = (@colour6==1 && @f_colouring0==GradientColoring) \ || (@colour6==2 && @f_colouring1==GradientColoring) \ || (@colour6==3 && @f_colouring2==GradientColoring) \ || (@colour6==4 && @f_colouring3==GradientColoring) \ || (@colour6==5 && @f_colouring4==GradientColoring) \ || (@colour6==6 && @f_colouring5==GradientColoring) \ || (@colour6==7 && @f_colouring6==GradientColoring) \ || (@colour6==8 && @f_colouring7==GradientColoring) \ || (@colour6==9 && @f_colouring8==GradientColoring) \ || (@colour6==10 && @f_colouring9==GradientColoring) \ || @colour6==12 endparam heading enabled = false visible = @colour6>0 endheading int param colour5 caption = "Layer 5 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 0 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 5" visible = @colour5>0 endheading color param clr5 caption = "Layer 5 Colour" default = RGBA(1,1,1,1) visible = @colour5==11 endparam MMF_QuickGradient param f_quickgradient5 caption = "Layer 5 Gradient Colouring" visible = @colour5==12 endparam heading text = "Please note that you have chosen a Layer Merge that includes \ gradient options on a layer that is using a Direct mode \ colouring. The gradient parameters in the Layer Merge will be \ ignored - it's better to use a Layer Merge that is not \ 'with Gradient'." visible = ((@colour5==1 && @f_colouring0!=GradientColoring) \ || (@colour5==2 && @f_colouring1!=GradientColoring) \ || (@colour5==3 && @f_colouring2!=GradientColoring) \ || (@colour5==4 && @f_colouring3!=GradientColoring) \ || (@colour5==5 && @f_colouring4!=GradientColoring) \ || (@colour5==6 && @f_colouring5!=GradientColoring) \ || (@colour5==7 && @f_colouring6!=GradientColoring) \ || (@colour5==8 && @f_colouring7!=GradientColoring) \ || (@colour5==9 && @f_colouring8!=GradientColoring) \ || (@colour5==10 && @f_colouring9!=GradientColoring) \ || @colour5==11) && @f_merge5==MMF_GradientLayerMerge endheading MMF_LayerMerge param f_merge5 caption = "Layer Merge" default = MMF_LayerMerge visible = (@colour5==1 && @f_colouring0==DirectColoring) \ || (@colour5==2 && @f_colouring1==DirectColoring) \ || (@colour5==3 && @f_colouring2==DirectColoring) \ || (@colour5==4 && @f_colouring3==DirectColoring) \ || (@colour5==5 && @f_colouring4==DirectColoring) \ || (@colour5==6 && @f_colouring5==DirectColoring) \ || (@colour5==7 && @f_colouring6==DirectColoring) \ || (@colour5==8 && @f_colouring7==DirectColoring) \ || (@colour5==9 && @f_colouring8==DirectColoring) \ || (@colour5==10 && @f_colouring9==DirectColoring) \ || @colour5==11 endparam MMF_GradientLayerMerge param f_gradientmerge5 caption = "Gradient Layer Merge" default = MMF_GradientLayerMerge visible = (@colour5==1 && @f_colouring0==GradientColoring) \ || (@colour5==2 && @f_colouring1==GradientColoring) \ || (@colour5==3 && @f_colouring2==GradientColoring) \ || (@colour5==4 && @f_colouring3==GradientColoring) \ || (@colour5==5 && @f_colouring4==GradientColoring) \ || (@colour5==6 && @f_colouring5==GradientColoring) \ || (@colour5==7 && @f_colouring6==GradientColoring) \ || (@colour5==8 && @f_colouring7==GradientColoring) \ || (@colour5==9 && @f_colouring8==GradientColoring) \ || (@colour5==10 && @f_colouring9==GradientColoring) \ || @colour5==12 endparam heading enabled = false visible = @colour5>0 endheading int param colour4 caption = "Layer 4 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 0 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 4" visible = @colour4>0 endheading color param clr4 caption = "Layer 4 Colour" default = RGBA(1,1,1,1) visible = @colour4==11 endparam MMF_QuickGradient param f_quickgradient4 caption = "Layer 4 Gradient Colouring" visible = @colour4==12 endparam heading text = "Please note that you have chosen a Layer Merge that includes \ gradient options on a layer that is using a Direct mode \ colouring. The gradient parameters in the Layer Merge will be \ ignored - it's better to use a Layer Merge that is not \ 'with Gradient'." visible = ((@colour4==1 && @f_colouring0!=GradientColoring) \ || (@colour4==2 && @f_colouring1!=GradientColoring) \ || (@colour4==3 && @f_colouring2!=GradientColoring) \ || (@colour4==4 && @f_colouring3!=GradientColoring) \ || (@colour4==5 && @f_colouring4!=GradientColoring) \ || (@colour4==6 && @f_colouring5!=GradientColoring) \ || (@colour4==7 && @f_colouring6!=GradientColoring) \ || (@colour4==8 && @f_colouring7!=GradientColoring) \ || (@colour4==9 && @f_colouring8!=GradientColoring) \ || (@colour4==10 && @f_colouring9!=GradientColoring) \ || @colour4==11) && @f_merge4==MMF_GradientLayerMerge endheading MMF_LayerMerge param f_merge4 caption = "Layer Merge" default = MMF_LayerMerge visible = (@colour4==1 && @f_colouring0==DirectColoring) \ || (@colour4==2 && @f_colouring1==DirectColoring) \ || (@colour4==3 && @f_colouring2==DirectColoring) \ || (@colour4==4 && @f_colouring3==DirectColoring) \ || (@colour4==5 && @f_colouring4==DirectColoring) \ || (@colour4==6 && @f_colouring5==DirectColoring) \ || (@colour4==7 && @f_colouring6==DirectColoring) \ || (@colour4==8 && @f_colouring7==DirectColoring) \ || (@colour4==9 && @f_colouring8==DirectColoring) \ || (@colour4==10 && @f_colouring9==DirectColoring) \ || @colour4==11 endparam MMF_GradientLayerMerge param f_gradientmerge4 caption = "Gradient Layer Merge" default = MMF_GradientLayerMerge visible = (@colour4==1 && @f_colouring0==GradientColoring) \ || (@colour4==2 && @f_colouring1==GradientColoring) \ || (@colour4==3 && @f_colouring2==GradientColoring) \ || (@colour4==4 && @f_colouring3==GradientColoring) \ || (@colour4==5 && @f_colouring4==GradientColoring) \ || (@colour4==6 && @f_colouring5==GradientColoring) \ || (@colour4==7 && @f_colouring6==GradientColoring) \ || (@colour4==8 && @f_colouring7==GradientColoring) \ || (@colour4==9 && @f_colouring8==GradientColoring) \ || (@colour4==10 && @f_colouring9==GradientColoring) \ || @colour4==12 endparam heading enabled = false visible = @colour4>0 endheading int param colour3 caption = "Layer 3 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 0 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 3" visible = @colour3>0 endheading color param clr3 caption = "Layer 3 Colour" default = RGBA(1,1,1,1) visible = @colour3==11 endparam MMF_QuickGradient param f_quickgradient3 caption = "Layer 3 Gradient Colouring" visible = @colour3==12 endparam heading text = "Please note that you have chosen a Layer Merge that includes \ gradient options on a layer that is using a Direct mode \ colouring. The gradient parameters in the Layer Merge will be \ ignored - it's better to use a Layer Merge that is not \ 'with Gradient'." visible = ((@colour3==1 && @f_colouring0!=GradientColoring) \ || (@colour3==2 && @f_colouring1!=GradientColoring) \ || (@colour3==3 && @f_colouring2!=GradientColoring) \ || (@colour3==4 && @f_colouring3!=GradientColoring) \ || (@colour3==5 && @f_colouring4!=GradientColoring) \ || (@colour3==6 && @f_colouring5!=GradientColoring) \ || (@colour3==7 && @f_colouring6!=GradientColoring) \ || (@colour3==8 && @f_colouring7!=GradientColoring) \ || (@colour3==9 && @f_colouring8!=GradientColoring) \ || (@colour3==10 && @f_colouring9!=GradientColoring) \ || @colour3==11) && @f_merge3==MMF_GradientLayerMerge endheading MMF_LayerMerge param f_merge3 caption = "Layer Merge" default = MMF_LayerMerge visible = (@colour3==1 && @f_colouring0==DirectColoring) \ || (@colour3==2 && @f_colouring1==DirectColoring) \ || (@colour3==3 && @f_colouring2==DirectColoring) \ || (@colour3==4 && @f_colouring3==DirectColoring) \ || (@colour3==5 && @f_colouring4==DirectColoring) \ || (@colour3==6 && @f_colouring5==DirectColoring) \ || (@colour3==7 && @f_colouring6==DirectColoring) \ || (@colour3==8 && @f_colouring7==DirectColoring) \ || (@colour3==9 && @f_colouring8==DirectColoring) \ || (@colour3==10 && @f_colouring9==DirectColoring) \ || @colour3==11 endparam MMF_GradientLayerMerge param f_gradientmerge3 caption = "Gradient Layer Merge" default = MMF_GradientLayerMerge visible = (@colour3==1 && @f_colouring0==GradientColoring) \ || (@colour3==2 && @f_colouring1==GradientColoring) \ || (@colour3==3 && @f_colouring2==GradientColoring) \ || (@colour3==4 && @f_colouring3==GradientColoring) \ || (@colour3==5 && @f_colouring4==GradientColoring) \ || (@colour3==6 && @f_colouring5==GradientColoring) \ || (@colour3==7 && @f_colouring6==GradientColoring) \ || (@colour3==8 && @f_colouring7==GradientColoring) \ || (@colour3==9 && @f_colouring8==GradientColoring) \ || (@colour3==10 && @f_colouring9==GradientColoring) \ || @colour3==12 endparam heading enabled = false visible = @colour3>0 endheading int param colour2 caption = "Layer 2 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 0 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 2" visible = @colour2>0 endheading color param clr2 caption = "Layer 2 Colour" default = RGBA(1,1,1,1) visible = @colour2==11 endparam MMF_QuickGradient param f_quickgradient2 caption = "Layer 2 Gradient Colouring" visible = @colour2==12 endparam heading text = "Please note that you have chosen a Layer Merge that includes \ gradient options on a layer that is using a Direct mode \ colouring. The gradient parameters in the Layer Merge will be \ ignored - it's better to use a Layer Merge that is not \ 'with Gradient'." visible = ((@colour2==1 && @f_colouring0!=GradientColoring) \ || (@colour2==2 && @f_colouring1!=GradientColoring) \ || (@colour2==3 && @f_colouring2!=GradientColoring) \ || (@colour2==4 && @f_colouring3!=GradientColoring) \ || (@colour2==5 && @f_colouring4!=GradientColoring) \ || (@colour2==6 && @f_colouring5!=GradientColoring) \ || (@colour2==7 && @f_colouring6!=GradientColoring) \ || (@colour2==8 && @f_colouring7!=GradientColoring) \ || (@colour2==9 && @f_colouring8!=GradientColoring) \ || (@colour2==10 && @f_colouring9!=GradientColoring) \ || @colour2==11) && @f_merge2==MMF_GradientLayerMerge endheading MMF_LayerMerge param f_merge2 caption = "Layer Merge" default = MMF_LayerMerge visible = (@colour2==1 && @f_colouring0==DirectColoring) \ || (@colour2==2 && @f_colouring1==DirectColoring) \ || (@colour2==3 && @f_colouring2==DirectColoring) \ || (@colour2==4 && @f_colouring3==DirectColoring) \ || (@colour2==5 && @f_colouring4==DirectColoring) \ || (@colour2==6 && @f_colouring5==DirectColoring) \ || (@colour2==7 && @f_colouring6==DirectColoring) \ || (@colour2==8 && @f_colouring7==DirectColoring) \ || (@colour2==9 && @f_colouring8==DirectColoring) \ || (@colour2==10 && @f_colouring9==DirectColoring) \ || @colour2==11 endparam MMF_GradientLayerMerge param f_gradientmerge2 caption = "Gradient Layer Merge" default = MMF_GradientLayerMerge visible = (@colour2==1 && @f_colouring0==GradientColoring) \ || (@colour2==2 && @f_colouring1==GradientColoring) \ || (@colour2==3 && @f_colouring2==GradientColoring) \ || (@colour2==4 && @f_colouring3==GradientColoring) \ || (@colour2==5 && @f_colouring4==GradientColoring) \ || (@colour2==6 && @f_colouring5==GradientColoring) \ || (@colour2==7 && @f_colouring6==GradientColoring) \ || (@colour2==8 && @f_colouring7==GradientColoring) \ || (@colour2==9 && @f_colouring8==GradientColoring) \ || (@colour2==10 && @f_colouring9==GradientColoring) \ || @colour2==12 endparam heading enabled = false visible = @colour2>0 endheading int param colour1 caption = "Layer 1 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 2 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 1" visible = @colour1>0 endheading color param clr1 caption = "Layer 1 Colour" default = RGBA(1,1,1,1) visible = @colour1==11 endparam MMF_QuickGradient param f_quickgradient1 caption = "Layer 1 Gradient Colouring" visible = @colour1==12 endparam heading text = "Please note that you have chosen a Layer Merge that includes \ gradient options on a layer that is using a Direct mode \ colouring. The gradient parameters in the Layer Merge will be \ ignored - it's better to use a Layer Merge that is not \ 'with Gradient'." visible = ((@colour1==1 && @f_colouring0!=GradientColoring) \ || (@colour1==2 && @f_colouring1!=GradientColoring) \ || (@colour1==3 && @f_colouring2!=GradientColoring) \ || (@colour1==4 && @f_colouring3!=GradientColoring) \ || (@colour1==5 && @f_colouring4!=GradientColoring) \ || (@colour1==6 && @f_colouring5!=GradientColoring) \ || (@colour1==7 && @f_colouring6!=GradientColoring) \ || (@colour1==8 && @f_colouring7!=GradientColoring) \ || (@colour1==9 && @f_colouring8!=GradientColoring) \ || (@colour1==10 && @f_colouring9!=GradientColoring) \ || @colour1==11) && @f_merge1==MMF_GradientLayerMerge endheading MMF_LayerMerge param f_merge1 caption = "Layer Merge" default = MMF_LayerMerge visible = (@colour1==1 && @f_colouring0==DirectColoring) \ || (@colour1==2 && @f_colouring1==DirectColoring) \ || (@colour1==3 && @f_colouring2==DirectColoring) \ || (@colour1==4 && @f_colouring3==DirectColoring) \ || (@colour1==5 && @f_colouring4==DirectColoring) \ || (@colour1==6 && @f_colouring5==DirectColoring) \ || (@colour1==7 && @f_colouring6==DirectColoring) \ || (@colour1==8 && @f_colouring7==DirectColoring) \ || (@colour1==9 && @f_colouring8==DirectColoring) \ || (@colour1==10 && @f_colouring9==DirectColoring) \ || @colour1==11 endparam MMF_GradientLayerMerge param f_gradientmerge1 caption = "Gradient Layer Merge" default = MMF_GradientLayerMerge visible = (@colour1==1 && @f_colouring0==GradientColoring) \ || (@colour1==2 && @f_colouring1==GradientColoring) \ || (@colour1==3 && @f_colouring2==GradientColoring) \ || (@colour1==4 && @f_colouring3==GradientColoring) \ || (@colour1==5 && @f_colouring4==GradientColoring) \ || (@colour1==6 && @f_colouring5==GradientColoring) \ || (@colour1==7 && @f_colouring6==GradientColoring) \ || (@colour1==8 && @f_colouring7==GradientColoring) \ || (@colour1==9 && @f_colouring8==GradientColoring) \ || (@colour1==10 && @f_colouring9==GradientColoring) \ || @colour1==12 endparam heading enabled = false visible = @colour1>0 endheading int param colour0 caption = "Layer 0 Colouring" enum = "None" "Colouring 0" "Colouring 1" "Colouring 2" "Colouring 3" \ "Colouring 4" "Colouring 5" "Colouring 6" "Colouring 7" \ "Colouring 8" "Colouring 9" "Single Colour" "Gradient Colouring" default = 1 hint = "To enable this layer just select one of the 10 colourings to \ use on the layer." endparam heading caption = "Layer 0" visible = @colour0>0 endheading color param clr0 caption = "Layer 0 Colour" default = RGBA(1,1,1,1) visible = @colour0==11 endparam MMF_QuickGradient param f_quickgradient0 caption = "Layer 0 Gradient Colouring" visible = @colour0==12 endparam heading text = "Please note that you have chosen a Layer Merge that includes \ gradient options on a layer that is using a Direct mode \ colouring. The gradient parameters in the Layer Merge will be \ ignored - it's better to use a Layer Merge that is not \ 'with Gradient'." visible = ((@colour0==1 && @f_colouring0!=GradientColoring) \ || (@colour0==2 && @f_colouring1!=GradientColoring) \ || (@colour0==3 && @f_colouring2!=GradientColoring) \ || (@colour0==4 && @f_colouring3!=GradientColoring) \ || (@colour0==5 && @f_colouring4!=GradientColoring) \ || (@colour0==6 && @f_colouring5!=GradientColoring) \ || (@colour0==7 && @f_colouring6!=GradientColoring) \ || (@colour0==8 && @f_colouring7!=GradientColoring) \ || (@colour0==9 && @f_colouring8!=GradientColoring) \ || (@colour0==10 && @f_colouring9!=GradientColoring) \ || @colour0==11) && @f_merge0==MMF_GradientLayerMerge endheading MMF_LayerMerge param f_merge0 caption = "Layer Merge" default = MMF_LayerMerge visible = (@colour0==1 && @f_colouring0!=GradientColoring) \ || (@colour0==2 && @f_colouring1!=GradientColoring) \ || (@colour0==3 && @f_colouring2!=GradientColoring) \ || (@colour0==4 && @f_colouring3!=GradientColoring) \ || (@colour0==5 && @f_colouring4!=GradientColoring) \ || (@colour0==6 && @f_colouring5!=GradientColoring) \ || (@colour0==7 && @f_colouring6!=GradientColoring) \ || (@colour0==8 && @f_colouring7!=GradientColoring) \ || (@colour0==9 && @f_colouring8!=GradientColoring) \ || (@colour0==10 && @f_colouring9!=GradientColoring) \ || @colour0==11 endparam MMF_GradientLayerMerge param f_gradientmerge0 caption = "Gradient Layer Merge" default = MMF_GradientLayerMerge visible = (@colour0==1 && @f_colouring0==GradientColoring) \ || (@colour0==2 && @f_colouring1==GradientColoring) \ || (@colour0==3 && @f_colouring2==GradientColoring) \ || (@colour0==4 && @f_colouring3==GradientColoring) \ || (@colour0==5 && @f_colouring4==GradientColoring) \ || (@colour0==6 && @f_colouring5==GradientColoring) \ || (@colour0==7 && @f_colouring6==GradientColoring) \ || (@colour0==8 && @f_colouring7==GradientColoring) \ || (@colour0==9 && @f_colouring8==GradientColoring) \ || (@colour0==10 && @f_colouring9==GradientColoring) \ || @colour0==12 endparam heading caption = "Base Colour" text = "Only used if below the lowest layer." endheading color param basecolour caption = "Base Colour" default = RGBA(0,0,0,0) hint = "Note that if there are 'Layer' parameters below this parameter in \ the parameter list then this colour is unused i.e. this colour \ is only used if it is part of the lowest 10 layers." endparam heading caption = "Colouring 9" visible = @colour0==10 || @colour1==10 || @colour2==10 || @colour3==10 \ || @colour4==10 || @colour5==10 || @colour6==10 || @colour7==10 \ || @colour8==10 || @colour9==10 endheading Coloring param f_Colouring9 caption = "Colouring 9" default = Standard_Gradient visible = @colour0==10 || @colour1==10 || @colour2==10 || @colour3==10 \ || @colour4==10 || @colour5==10 || @colour6==10 || @colour7==10 \ || @colour8==10 || @colour9==10 endparam heading caption = "Colouring 8" visible = @colour0==9 || @colour1==9 || @colour2==9 || @colour3==9 \ || @colour4==9 || @colour5==9 || @colour6==9 || @colour7==9 \ || @colour8==9 || @colour9==9 endheading Coloring param f_Colouring8 caption = "Colouring 8" default = Standard_Gradient visible = @colour0==9 || @colour1==9 || @colour2==9 || @colour3==9 \ || @colour4==9 || @colour5==9 || @colour6==9 || @colour7==9 \ || @colour8==9 || @colour9==9 endparam heading caption = "Colouring 7" visible = @colour0==8 || @colour1==8 || @colour2==8 || @colour3==8 \ || @colour4==8 || @colour5==8 || @colour6==8 || @colour7==8 \ || @colour8==8 || @colour9==8 endheading Coloring param f_Colouring7 caption = "Colouring 7" default = Standard_Gradient visible = @colour0==8 || @colour1==8 || @colour2==8 || @colour3==8 \ || @colour4==8 || @colour5==8 || @colour6==8 || @colour7==8 \ || @colour8==8 || @colour9==8 endparam heading caption = "Colouring 6" visible = @colour0==7 || @colour1==7 || @colour2==7 || @colour3==7 \ || @colour4==7 || @colour5==7 || @colour6==7 || @colour7==7 \ || @colour8==7 || @colour9==7 endheading Coloring param f_Colouring6 caption = "Colouring 6" default = Standard_Gradient visible = @colour0==7 || @colour1==7 || @colour2==7 || @colour3==7 \ || @colour4==7 || @colour5==7 || @colour6==7 || @colour7==7 \ || @colour8==7 || @colour9==7 endparam heading caption = "Colouring 5" visible = @colour0==6 || @colour1==6 || @colour2==6 || @colour3==6 \ || @colour4==6 || @colour5==6 || @colour6==6 || @colour7==6 \ || @colour8==6 || @colour9==6 endheading Coloring param f_Colouring5 caption = "Colouring 5" default = Standard_Gradient visible = @colour0==6 || @colour1==6 || @colour2==6 || @colour3==6 \ || @colour4==6 || @colour5==6 || @colour6==6 || @colour7==6 \ || @colour8==6 || @colour9==6 endparam heading caption = "Colouring 4" visible = @colour0==5 || @colour1==5 || @colour2==5 || @colour3==5 \ || @colour4==5 || @colour5==5 || @colour6==5 || @colour7==5 \ || @colour8==5 || @colour9==5 endheading Coloring param f_Colouring4 caption = "Colouring 4" default = Standard_Gradient visible = @colour0==5 || @colour1==5 || @colour2==5 || @colour3==5 \ || @colour4==5 || @colour5==5 || @colour6==5 || @colour7==5 \ || @colour8==5 || @colour9==5 endparam heading caption = "Colouring 3" visible = @colour0==4 || @colour1==4 || @colour2==4 || @colour3==4 \ || @colour4==4 || @colour5==4 || @colour6==4 || @colour7==4 \ || @colour8==4 || @colour9==4 endheading Coloring param f_Colouring3 caption = "Colouring 3" default = Standard_Gradient visible = @colour0==4 || @colour1==4 || @colour2==4 || @colour3==4 \ || @colour4==4 || @colour5==4 || @colour6==4 || @colour7==4 \ || @colour8==4 || @colour9==4 endparam heading caption = "Colouring 2" visible = @colour0==3 || @colour1==3 || @colour2==3 || @colour3==3 \ || @colour4==3 || @colour5==3 || @colour6==3 || @colour7==3 \ || @colour8==3 || @colour9==3 endheading Coloring param f_Colouring2 caption = "Colouring 2" default = Standard_Gradient visible = @colour0==3 || @colour1==3 || @colour2==3 || @colour3==3 \ || @colour4==3 || @colour5==3 || @colour6==3 || @colour7==3 \ || @colour8==3 || @colour9==3 endparam heading caption = "Colouring 1" visible = @colour0==2 || @colour1==2 || @colour2==2 || @colour3==2 \ || @colour4==2 || @colour5==2 || @colour6==2 || @colour7==2 \ || @colour8==2 || @colour9==2 endheading Coloring param f_Colouring1 caption = "Colouring 1" default = Standard_OrbitTraps visible = @colour0==2 || @colour1==2 || @colour2==2 || @colour3==2 \ || @colour4==2 || @colour5==2 || @colour6==2 || @colour7==2 \ || @colour8==2 || @colour9==2 endparam heading caption = "Colouring 0" visible = @colour0==1 || @colour1==1 || @colour2==1 || @colour3==1 \ || @colour4==1 || @colour5==1 || @colour6==1 || @colour7==1 \ || @colour8==1 || @colour9==1 endheading Coloring param f_Colouring0 caption = "Colouring 0" default = Standard_Smooth visible = @colour0==1 || @colour1==1 || @colour2==1 || @colour3==1 \ || @colour4==1 || @colour5==1 || @colour6==1 || @colour7==1 \ || @colour8==1 || @colour9==1 endparam } class MMF_SmoothOrbitTraps(common.ulb:GradientColoring) { ; ; Written by David Makin based on normal Orbit Traps by Damien Jones
; Started May 2008
;

; Note that you can use any normal trap plug-ins with this formula ; but you'll only get smoothing for Trap Modes derived from ; MMF_TrapModeSmooth or MMF_TrapModeSmoothWithThreshold, generally ; that means Trap Modes with "Smooth" in the title such as those ; in mmf.ulb.
; public: import "common.ulb" import "dmj5.ulb" ; Constructor - note the inititialisation of smoothing variables
; if necessary.
; @param pparent the parent, generally "this" for the parent, or zero func MMF_SmoothOrbitTraps(Generic pparent) GradientColoring.GradientColoring(pparent) m_TrapSelect = new @f_trapselect(this) m_TrapTransform = new @f_traptransform(this) m_TrapShape = new @f_trapshape(this) m_TrapTransfer = new @f_traptransfer(this) m_TrapMode = new @f_trapmode(this) m_TrapTexture = new @f_traptexture(this) m_TrapColoring = new @f_trapcoloring(this) m_FinalTransfer = new @f_finaltransfer(this) m_IterTransfer = new @f_itertransfer(this) m_TrapShape.SetThreshold(@p_threshold) m_TrapMode.SetThreshold(@p_threshold) if @smoothing<3 && (@f_trapmode==MMF_TrapModeSmooth \ || @f_trapmode==MMF_TrapModeSmoothWithThreshold \ || @f_additer) il = real(1.0/log(@power)) ; for divergent smoothing lp = log(0.5*log(@bailout)) ilp = il*lp cil = real(1/log(@cpower)) ; for convergent smoothing clp = log(-0.5*log(@smallbail)) cilp = cil*clp endif if @f_trapcoloring==MMF_TrapColoring \ && @f_traptexture==DMJ_TrapShapeFlat MMF_TrapColoring(m_TrapColoring).SetTextureFlag(false) endif m_texture = 0.0 endfunc ; Initialisation (per pixel)
; Standard colour Init()
; This version:

; Note that if the texturing is set to position only and texturing ; is enabled then the texture Iterate() function is called here.
; @param pz initial z from the formula ; @param ppixel the location (normally #pixel) func Init(complex pz, complex ppixel) GradientColoring.Init(pz, ppixel) m_TrapSelectSequence = m_TrapSelect.InitDefault() m_TrapTransform.Init(pz) m_TrapShape.Init(pz) m_TrapTransfer.Init(pz) m_TrapMode.Init(pz) m_TrapTexture.Init(pz) m_FinalTransfer.Init(pz) m_IterTransfer.Init(pz) if @smoothing<3 && (@f_trapmode==MMF_TrapModeSmooth \ || @f_trapmode==MMF_TrapModeSmoothWithThreshold \ || @f_additer) m_zold = m_zolder = pz m_zolderok = m_zoldok = false endif m_notlast = true if @p_texturepositiononly && @f_traptexture!=DMJ_TrapShapeFlat m_texture = m_TrapTexture.Iterate(ppixel) endif endfunc ;

; Note that the texture calculation is skipped if there's no texture ; (using DMJ_TrapShapeFlat) or texturing is position only
; @param pz the z value func Iterate(complex pz) GradientColoring.Iterate(pz) if @smoothing<3 && (@f_trapmode==MMF_TrapModeSmooth \ || @f_trapmode==MMF_TrapModeSmoothWithThreshold \ || @f_additer) \ && m_notlast m_zolder = m_zold m_zold = pz m_zolderok = m_zoldok m_zoldok = true endif m_TrapSelectSequence = m_TrapSelect.Iterate(m_TrapSelectSequence) if ((@f_trapselect==DMJ_TrapSelect && m_TrapSelectSequence>0.5) \ || m_TrapSelectSequence > @p_trapselectthreshold) complex zt = m_TrapTransform.Iterate(pz) float distance = m_TrapShape.Iterate(zt) float texture = m_texture distance = m_TrapTransfer.Iterate(distance) zt = m_TrapShape.GetTransformedPoint() if @f_traptexture!=DMJ_TrapShapeFlat && !@p_texturepositiononly texture = m_TrapShape.GetTextureValue() if (@p_textureposttransform) texture = texture + m_TrapTexture.Iterate(zt) else texture = texture + m_TrapTexture.Iterate(pz) endif texture = (texture + m_TrapTexture.GetTextureValue()) \ * @p_texturestrength endif if (!m_TrapTransform.IsSolid()) m_TrapMode.Iterate(pz, zt, distance, texture) else m_TrapMode.IterateSilent() endif else if @f_TrapShape==MMF_TrapShapeZold && @f_fixzold complex zt = m_TrapTransform.Iterate(pz) MMF_TrapShapeZold(m_TrapShape).IterateSilentZold(zt) else if @f_TrapTransform==MMF_TrapTransformZold MMF_TrapTransformZold(m_TrapTransform).IterateSilentZold(pz) else m_TrapTransform.IterateSilent() endif m_TrapShape.IterateSilent() endif m_TrapTransfer.IterateSilent() m_TrapMode.IterateSilent() if @f_traptexture!=DMJ_TrapShapeFlat && !@p_texturepositiononly m_TrapTexture.IterateSilent() endif endif endfunc ;

; Note that if "Process final iteration" is enabled then Iterate() ; is called first one last time using the final value of pz.
; @param pz the final z value ; @return index value float func ResultIndex(complex pz) float result if @processlast m_notlast = false Iterate(pz) endif GradientColoring.ResultIndex(pz) m_TrapMode.Result() m_Solid = @p_usesolid && m_TrapMode.IsSolid() result = m_TrapColoring.Result(m_TrapMode) float f = 0.0 if @smoothing<3 && (@f_trapmode==MMF_TrapModeSmooth \ || @f_trapmode==MMF_TrapModeSmoothWithThreshold \ || @f_additer) float m if (@smoothing==0 || @smoothing==2) && |pz - m_zold|>1 \ && (m=|pz|)>=@bailout m = log(m) if @dauto && m_zoldok f = @fudge*real(lp - log(0.5*m))/log(m/log(|m_zold|)) else f = @fudge*real(ilp - il*log(0.5*m)) endif elseif (@smoothing==1 || @smoothing==2) \ && ( (|pz - m_zold|<=@smallbail && !@cfixed) \ || (|pz - @cfixedval|<=@smallbail && @cfixed) ) if @cfixed m = log(|pz - @cfixedval|) if @cauto && m_zoldok f = @fudgec*real(clp - log(-0.5*m)) \ /log(m/log(|m_zold-@cfixedval|)) else f = @fudgec*real(cilp - cil*log(-0.5*m)) endif elseif @cauto && m_zolderok m = log(|pz - m_zold|) f = @fudgec*real(clp - log(-0.5*m)) \ /log(m/log(|m_zold-m_zolder|)) elseif m_zoldok f = @fudgec*real(cilp - cil*log(-0.5*log(|pz - m_zold|))) endif endif if (@f_TrapMode==MMF_TrapModeSmooth \ || @f_trapmode==MMF_TrapModeSmoothWithThreshold) && f!=0.0 if @f_TrapMode==MMF_TrapModeSmooth MMF_TrapModeSmooth(m_TrapMode).OldResult() else MMF_TrapModeSmoothWithThreshold(m_TrapMode).OldResult() endif result = result + f*(result - m_TrapColoring.Result(m_TrapMode)) endif endif if @f_additer if @processlast return m_FinalTransfer.Iterate(result) \ + m_IterTransfer.Iterate(0.05*(m_Iterations + f)) else return m_FinalTransfer.Iterate(result) \ + m_IterTransfer.Iterate(0.05*(1.0 + m_Iterations + f)) endif else return m_FinalTransfer.Iterate(result) endif endfunc ;

; Note that if "Process final iteration" is enabled then Iterate() ; is called first one last time using the final value of pz.
; @param pz the final z value ; @return color value color func Result(complex pz) MMF_TrapColoring mmftc if (mmftc = MMF_TrapColoring(m_TrapColoring)) if mmftc.UseColor() float result color icol if @processlast m_notlast = false Iterate(pz) endif GradientColoring.ResultIndex(pz) m_TrapMode.Result() m_Solid = @p_usesolid && m_TrapMode.IsSolid() icol = mmftc.ResultColor(m_TrapMode) result = mmftc.ResultTexture(m_TrapMode) float f = 0.0 if @smoothing<3 && (@f_trapmode==MMF_TrapModeSmooth \ || @f_trapmode==MMF_TrapModeSmoothWithThreshold \ || @f_additer) float m if (@smoothing==0 || @smoothing==2) && |pz - m_zold|>1 \ && (m=|pz|)>=@bailout m = log(m) if @dauto && m_zoldok f = @fudge*real(lp - log(0.5*m))/log(m/log(|m_zold|)) else f = @fudge*real(ilp - il*log(0.5*m)) endif elseif (@smoothing==1 || @smoothing==2) \ && ( (|pz - m_zold|<=@smallbail && !@cfixed) \ || (|pz - @cfixedval|<=@smallbail && @cfixed) ) if @cfixed m = log(|pz - @cfixedval|) if @cauto && m_zoldok f = @fudgec*real(clp - log(-0.5*m)) \ /log(m/log(|m_zold-@cfixedval|)) else f = @fudgec*real(cilp - cil*log(-0.5*m)) endif elseif @cauto && m_zolderok m = log(|pz - m_zold|) f = @fudgec*real(clp - log(-0.5*m)) \ /log(m/log(|m_zold-m_zolder|)) elseif m_zoldok f = @fudgec*real(cilp - cil*log(-0.5*log(|pz - m_zold|))) endif endif if (@f_TrapMode==MMF_TrapModeSmooth \ || @f_trapmode==MMF_TrapModeSmoothWithThreshold) && f!=0.0 if @f_TrapMode==MMF_TrapModeSmooth MMF_TrapModeSmooth(m_TrapMode).OldResult() else MMF_TrapModeSmoothWithThreshold(m_TrapMode).OldResult() endif icol = icol + (icol - mmftc.ResultColor(m_TrapMode))*f result = result + f*(result - mmftc.ResultTexture(m_TrapMode)) endif endif if @f_additer if @f_traptexture==DMJ_TrapShapeFlat mmftc.SetTextureFlag(true) if @processlast result = m_IterTransfer.Iterate(0.05*(m_Iterations + f)) else result = m_IterTransfer.Iterate(0.05*(1.0 + m_Iterations + f)) endif elseif @processlast result = m_FinalTransfer.Iterate(result) \ + m_IterTransfer.Iterate(0.05*(m_Iterations + f)) else result = m_FinalTransfer.Iterate(result) \ + m_IterTransfer.Iterate(0.05*(1.0 + m_Iterations + f)) endif else result = m_FinalTransfer.Iterate(result) endif icol = mmftc.MergeResult(icol,result) if @smoothing<3 && @f_traptexture==DMJ_TrapShapeFlat && @f_additer mmftc.SetTextureFlag(false) endif return icol endif endif return gradient(ResultIndex(pz)) endfunc protected: Generator m_TrapSelect UserTransform m_TrapTransform TrapShape m_TrapShape Transfer m_TrapTransfer TrapMode m_TrapMode TrapShape m_TrapTexture TrapColoring m_TrapColoring Transfer m_FinalTransfer Transfer m_IterTransfer float m_texture float m_TrapSelectSequence private: complex m_zold complex m_zolder float il ; for divergent smoothing float lp float ilp float cil ; for convergent smoothing float clp float cilp bool m_zoldok bool m_zolderok bool m_notlast default: title = "MMF Smooth Orbit Traps (Gradient)" rating = recommended int param v_mmfsmoothorbittraps caption = "Version (MMF Smooth Orbit Traps)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam heading caption = "Information" text = "Note that you can use any normal trap plug-ins with \ this colouring but you'll only get smoothing for Trap \ Modes written for it - generally trap modes with 'Smooth' \ in the title, e.g. in mmf.ulb. \ This colouring class is mainly intended for \ use on 'outside' areas, i.e. areas where bailout occurs, \ but for some of the mmf.ulb trap shapes it is required \ for 'inside' areas in preference to standard orbit trap \ formulas. If used 'inside' then it's best to select \ 'Neither' as the 'Smoothing method' and not to enable \ 'Process final iteration'. Note that when not wanting \ any texturing you should always set 'Trap Texture' to \ dmj5.ulb->Flat Texture." endheading heading caption = "Smoothing parameters" endheading int param smoothing caption = "Smoothing method" enum = "Divergent" "Convergent" "Both" "Neither" default = 0 hint = "Choose the smoothing that matches your main formula type \ e.g. 'Divergent' for z^2+c, 'Convergent' for Newton, \ 'Both' for Magnet formulas. If using this colouring for \ 'inside' areas then it's best to select 'Neither'." endparam heading text = "Divergent Smoothing parameters" visible = @smoothing==0 || @smoothing==2 endheading float param bailout caption = "Bailout" default = 128.0 hint = "This should match the bailout in the fractal formula." visible = @smoothing==0 || @smoothing==2 endparam bool param dauto caption = "Auto-power" default = true hint = "When enabled should produce smoothing for most divergent \ areas without you needing to set the divergent power value \ for the colouring." visible = @smoothing==0 || @smoothing==2 endparam complex param power caption = "Power/exponent/degree" default = (2,0) hint = "This should match the power/degree/exponent in the \ fractal formula. When using 'Auto-power' it's only used \ for areas that bailed on the first or second iteration." visible = @smoothing==0 || @smoothing==2 endparam float param fudge caption = "Scaling fudge" default = 1.0 hint = "This is a scaling fudge value, it's used to scale \ the calculated iteration fraction when the value \ doesn't reach 1, it's unlikely to be required for \ divergent smoothing but I added it just in case. If \ 'Auto-power' or the best value you can find for \ the power parameter don't produce smooth results then \ modifying this value may help." visible = @smoothing==0 || @smoothing==2 endparam heading text = "Convergent Smoothing parameters" visible = @smoothing==1 || @smoothing==2 endheading float param smallbail caption = "Bailout" default = 1e-5 hint = "This should match the small bailout in your fractal formula." visible = @smoothing==1 || @smoothing==2 endparam bool param cauto caption = "Auto-power" default = true hint = "When enabled should produce smoothing for most convergent \ areas without you needing to set a convergent power value \ for the colouring." visible = @smoothing==1 || @smoothing==2 endparam complex param cpower caption = "Power/exponent/degree" default = (2,0) hint = "This should match the power (exponent/degree) for the \ convergent areas of your main fractal formula. When \ using 'Auto-power' it's only used for areas that bailed \ on the first or second iteration." visible = @smoothing==1 || @smoothing==2 endparam float param fudgec caption = "Scaling Fudge" default = 1.0 hint = "This is a scaling fudge value, it's used to scale \ the calculated iteration fraction when the value \ doesn't reach 1. If 'Auto-power' or the best value you can \ find for the 'Convergent Power' parameter don't \ produce smooth results then modifying this value \ should help." visible = @smoothing==1 || @smoothing==2 endparam bool param cfixed caption = "Absolute convergence" default = false hint = "For when using a main formula that tests for convergence by \ using (only) |#z-value| rather than |#z-zold|, a typical \ example would be a Magnet formula where |#z-1.0| is often \ used. When enabled set the value of 'Convergence root' \ appropriately." visible = @smoothing==1 || @smoothing==2 endparam complex param cfixedval caption = "Convergence root" default = (1,0) hint = "Use (1.0,0) for some Magnet formulas." visible = (@smoothing==1 || @smoothing==2) && @cfixed endparam heading caption = "Trapping parameters" endheading bool param processlast caption = "Process final iteration" default = true hint = "When enabled then the final (bailed out) value of z is \ trapped in addition to the previous values. Should not \ be enabled if colouring 'inside'." endparam Generator param f_trapselect caption = "Trap Iteration" default = DMJ_TrapSelect expanded = false endparam float param p_trapselectthreshold caption = "Threshold" default = 0.5 hint = "When using a Generator other than a TrapSelect type, values \ could range anywhere from 0 to 1. This threshold sets which \ values will be interpreted as 'do not trap' and which will be \ interpreted as 'trap'." visible = (@f_trapselect != DMJ_TrapSelect) endparam UserTransform param f_traptransform caption = "Trap Position" default = TrapTransform hint = "This transform is commonly used to set the position of the \ trap. You can load any Transform object here, but if you \ replace the TrapTransform you will lose the ability to \ position the trap. To regain that ability, use the \ TransformMerge class here so you can load any Transform \ and still be able to use a TrapTransform object." expanded = false endparam TrapShape param f_trapshape caption = "Trap Shape" default = MMF_TrapShapeTriangleInequality hint = "The trap shape sets the overall shape of the trap. Its only \ task is to measure the distance from any point to the trap \ shape." endparam bool param f_fixzold caption = "Fix zold ?" default = true hint = "When enabled this improves the functionality of your trap \ shape when skipping iterations but can cause problems when \ combined with some Trap Positions so you may disable it if \ necessary." visible = @f_TrapShape==MMF_TrapShapeZold endparam Transfer param f_traptransfer caption = "Trap Transfer" default = TrapTransfer hint = "A transfer allows you to manipulate the distances provided \ by the trap shape." expanded = false endparam TrapMode param f_trapmode caption = "Trap Mode" default = MMF_TrapModeSmoothAverage endparam heading text = "Warning - The currently selected Trap Mode will not be \ smoothed. You should use a Trap Mode with 'Smooth' in the \ title." visible = @f_trapmode!=MMF_TrapModeSmooth \ && @f_trapmode!=MMF_TrapModeSmoothWithThreshold endheading float param p_threshold caption = "Trap Threshold" default = 1.0 hint = "This is the overall size or thickness of the trap area. \ (Some trap modes may not use the threshold value.)" visible = (@f_trapmode == TrapModeWithThreshold) endparam bool param p_usesolid caption = "Use Solid Color" default = false hint = "If checked, any areas not inside any trap shape will be \ colored using the solid color." endparam TrapShape param f_traptexture caption = "Trap Texture" default = DMJ_TrapShapeFlat hint = "A trap shape that is used as a texture. Textures do not \ change the shape of the trap but may change its coloring." endparam bool param p_texturepositiononly caption = "Texture from location only" default = false hint = "When enabled the texturing is based on the location. \ This is equivalent to basing the texture on #pixel. \ The rendering time is reduced \ considerably when this is enabled. Note that when \ used the texture density will be completely \ independant of the trap shape but may still change \ depending on the trap mode." visible = @f_traptexture!=DMJ_TrapShapeFlat endparam bool param p_textureposttransform caption = "Use Transformed Coordinate" default = false hint = "If checked, texturing will be based on the final transformed \ coordinate used in the trap shape (i.e. it will follow the \ trap shape, rather than being separate from it)." visible = (@f_traptexture != DMJ_TrapShapeFlat) \ && !@p_texturepositiononly endparam float param p_texturestrength caption = "Texture Amount" default = 1.0 hint = "Sets the overall amount of texture to be used. Larger \ numbers will increase the effect of the texture. A value \ of 0 will remove the effects of the texture." visible = (@f_traptexture != DMJ_TrapShapeFlat) \ && !@p_texturepositiononly endparam TrapColoring param f_trapcoloring caption = "Trap Color Mode" default = MMF_TrapColoring endparam Transfer param f_finaltransfer caption = "Final Transfer" default = MMF_TrapTransfer hint = "Allows you to manipulate the final combined value of \ the trap colour and the texturing." endparam param f_additer caption = "Add the smooth iteration count" default = false endparam Transfer param f_itertransfer caption = "Iteration Transfer" default = MMF_TrapTransfer hint = "Allows you to manipulate the final combined value of \ the trap colour and the texturing." visible = @f_additer endparam } class MMF_TrapTransformZold(common.ulb:UserTransform) { ; Base class for trap transforms requiring zold and/or zolder
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_TrapTransformZold(Generic pparent) UserTransform.UserTransform(pparent) endfunc ; Initialise m_zolder, m_zold, m_zolderok and m_zoldok
; @param pz the z value func Init(complex pz) UserTransform.Init(pz) m_zolder = m_zold = pz m_zolderok = m_zoldok = false endfunc ;

Note that derived functions should update zold, zolder, zoldok ; and zolderok as necessary
; @param pz the z value ; @return new z complex func Iterate(complex pz) m_Iterations = m_Iterations + 1 return pz endfunc ; Here the "old" flags are set to false
func IterateSilent() m_Iterations = m_Iterations + 1 m_zolderok = m_zoldok = false endfunc ;

This is basically IterateSilent extended so that the values of ; zold and zolder are kept up to date.
; @param pz the z value func IterateSilentZold(complex pz) m_Iterations = m_Iterations + 1 m_zolder = m_zold m_zold = pz m_zolderok = m_zoldok m_zoldok = true endfunc protected: complex m_zold complex m_zolder bool m_zoldok bool m_zolderok default: int param v_mmftraptransformzold caption = "Version (MMF_TrapTransformZold)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_mmftraptransformzold < 100 endparam heading text = "This transform is designed for use with formulas that \ understand the use of zold and zolder such as MMF Smooth \ Orbit Traps from mmf.ulb or similar formulas but will \ work with reduced functionality in other situations." endheading } class MMF_TrapTransformInterpolation(MMF_TrapTransformZold) { ; Trapping based on interpolation of a*zold^p1 + b*zold^p2
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_TrapTransformInterpolation(Generic pparent) MMF_TrapTransformZold.MMF_TrapTransformZold(pparent) endfunc ; Sets the m_gotold variable to false i.e. "no old trapped values" ; @param pz the initial z value func Init(complex pz) MMF_TrapTransformZold.Init(pz) m_gotold = false endfunc ; @param pz the z value complex func Iterate(complex pz) complex zt = (0,0) complex a = (0,0) complex b = (0,0) bool gotz = false ; m_Iterations = m_Iterations + 1 not used in this transform if (@usevar=="Predict1" || @usevar=="Predict2") \ && m_gotold && m_zoldok if @usevar=="Predict1" zt = m_oa*m_zold^@pwr1 + m_ob*m_zold^@pwr2 else zt = m_oa*m_zold^@pwr1 + @valb*m_zold^@pwr2 endif gotz = true endif m_gotold = false if @usevar=="Just a" || @usevar=="Just b" || @usevar=="Combined" \ || @usevar=="Predict1" if m_zolderok if @pwr1!=(0,0) if @pwr2!=(0,0) a = m_zold^@pwr1*m_zolder^@pwr2 - m_zolder^@pwr1*m_zold^@pwr2 else a = m_zold^@pwr1 - m_zolder^@pwr1 endif elseif @pwr2!=(0,0) a = m_zolder^@pwr2 - m_zold^@pwr2 endif m_gotold = true endif elseif m_zoldok if @pwr1!=(0,0) a = m_zold^@pwr1 else a = 1.0 endif m_gotold = true endif if m_gotold if @usevar=="Just a" || @usevar=="Just b" || @usevar=="Combined" \ || @usevar=="Predict1" a = 1.0/a if @pwr1!=(0,0) if @pwr2!=(0,0) if @usevar!="Just a" b = (m_zold^(@pwr1+1.0) - pz*m_zolder^@pwr1)*a endif if @usevar!="Just b" a = (pz*m_zolder^@pwr2 - m_zold^(@pwr2+1.0))*a endif else if @usevar!="Just a" b = (m_zold^(@pwr1+1.0) - pz*m_zolder^@pwr1)*a endif if @usevar!="Just b" a = (pz - m_zold)*a endif endif elseif @pwr2!=(0,0) if @usevar!="Just a" b = (m_zold - pz)*a endif if @usevar!="Just b" a = (pz*m_zolder^@pwr2 - m_zold^(@pwr2+1.0))*a endif endif elseif @pwr2!=(0,0) a = (pz - @valb*m_zold^@pwr2)/a else a = (pz - @valb)/a endif if @usevar=="Predict1" || @usevar=="Predict2" m_oa = a m_ob = b endif endif if ((@usevar=="Just a" || @usevar=="Just b" || @usevar=="Combined" \ || @usevar=="Fixed b") && m_gotold) || ((@usevar=="Predict1" \ || @usevar=="Predict2") && gotz) if @usevar=="Predict1" || @usevar=="Predict2" a = zt if @trapz a = pz - zt endif endif if @usevar!="Just b" if @fna==1 a = log(a) elseif @fna==2 a = sin(a) elseif @fna==3 a = cos(a) elseif @fna==4 a = tan(a) elseif @fna==5 a = sinh(a) elseif @fna==6 a = cosh(a) elseif @fna==7 a = tanh(a) elseif @fna==8 a = exp(a) elseif @fna==9 a = sqrt(a) elseif @fna==10 a = a^(1.0/3.0) elseif @fna==11 a = a*a elseif @fna==12 a = a^3.0 endif endif if @usevar=="Just b" || @usevar=="Combined" if @fnb==1 b = log(b) elseif @fnb==2 b = sin(b) elseif @fnb==3 b = cos(b) elseif @fnb==4 b = tan(b) elseif @fnb==5 b = sinh(b) elseif @fnb==6 b = cosh(b) elseif @fnb==7 b = tanh(b) elseif @fnb==8 b = exp(b) elseif @fnb==9 b = sqrt(b) elseif @fnb==10 b = b^(1.0/3.0) elseif @fnb==11 b = b*b elseif @fnb==12 b = b^3.0 endif endif if @usevar=="Just b" zt = b elseif @usevar=="Combined" if @mix=="Minimum" if |a|<=|b| zt = a else zt = b endif elseif @mix=="Maximum" if |a|>|b| zt = a else zt = b endif else;if @mix=="Mix %age" zt = (0.01*@percent)*a + (1.0 - 0.01*@percent)*b endif else zt = a endif m_solid = false else zt = pz m_solid = true endif m_zolder = m_zold m_zold = pz m_zolderok = m_zoldok m_zoldok = true return zt endfunc ; Set the "old" flags to false func IterateSilent() ; m_Iterations = m_Iterations + 1 not used in this transform
m_zolderok = m_zoldok = m_gotold = false endfunc ; Keep the "old" z values up to date, set the m_gotold flag to false ; @param pz the z value func IterateSilentZold(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform
m_zolder = m_zold m_zold = pz m_zolderok = m_zoldok m_zoldok = true m_gotold = false endfunc private: complex m_oa complex m_ob bool m_gotold default: title = "Interpolation Transform" heading text = "The interpolation requires that the transform is used \ in an iterated manner, so in situations where the \ transform is applied in a 'one-shot' manner interpolation \ is not applicable." endheading complex param pwr1 caption = "Power 1" default = (2,0) hint = "n1 in 'a*z^n1 + b*z^n2'. Note that if it is (0,0) then the \ interpolation formula becomes 'a + b*z^n2'." endparam complex param pwr2 caption = "Power 2" default = (1,0) hint = "n2 in 'a*z^n1 + b*z^n2'. Note that if it is (0,0) then the \ interpolation formula becomes 'a*z^n1 + b'." endparam int param usevar caption = "Variable/s to use" enum = "Just a" "Just b" "Combined" "Fixed b" "Predict1" "Predict2" default = 0 hint = " \ 'Combined' calculates values using a and b separately and then \ allows you to set the final value by combining the two \ separate values. 'Fixed b' allows you to specify a fixed value \ for b in a*z^n1 + b*z^n2 and colours based on a. \ Predict1 calculates both a and b and uses the values from \ the previous iteration to interpolate z and traps the \ interpolated value. Predict2 is the same \ as Predict1 but uses the 'Fixed b' interpolation method." endparam bool param trapz caption = "Trap z ?" default = false hint = "Normally just the interpolated value is used for \ 'Predict1' and 'Predict2' but you can choose to trap \ the actual z value to the predicted z value instead." visible = @usevar>3 endparam complex param valb caption = "Value of b" default = (0,0) visible = @usevar==3 || @usevar==5 endparam int param mix caption = "Colour mixing" enum = "Minimum" "Maximum" "Mix %age" default = 0 visible = @usevar==2 endparam float param percent caption = "Mix %age" default = 50.0 hint = "100% uses the value from a only, 0% uses the value from b only." visible = @usevar==2 && @mix==2 endparam int param fna caption = "Function for a (or interpolated z)" enum = "Ident" "Log" "Sin" "Cos" "Tan" "Sinh" "Cosh" "Tanh" "Exp" \ "Sqrt" "Cubert" "Square" "Cube" default = 0 hint = "Applied to the calculated value of a or the interpolated \ z value before use in any trapping or colouring." visible = @usevar!=1 endparam int param fnb caption = "Function for b" enum = "Ident" "Log" "Sin" "Cos" "Tan" "Sinh" "Cosh" "Tanh" "Exp" \ "Sqrt" "Cubert" "Square" "Cube" default = 0 hint = "Applied to the calculated value of b before use in any \ trapping or colouring." visible = @usevar>0 && @usevar<3 endparam } class MMF_TrapModeSmooth(common.ulb:TrapMode) { ; ; This is a generic trap mode class for use with MMF_SmoothOrbitTraps.
;

It takes a sequence of complex point pairs (untransformed ; and transformed) and distances and produces a final result, ; storing old values for smoothing.
; public: ; @param pparent the parent, generally "this" for the parent, or zero func MMF_TrapModeSmooth(Generic pparent) TrapMode.TrapMode(pparent) endfunc ; call this at the beginning of each sequence ; @param pz the initial z value func Init(complex pz) m_Iterations = 0 m_Solid = false int j = 3 repeat m_UntransformedPoints[j] = m_OldUntransformedPoints[j] = (0,0) m_TransformedPoints[j] = m_OldTransformedPoints[j] = (0,0) m_IterationPoints[j] = m_OldIterationPoints[j] = 0 m_Distances[j] = m_OldDistances[j] = 0.0 m_Textures[j] = m_OldTextures[j] = 0.0 until (j=j-1)<0 m_wastrapped = false endfunc ; call this for each point ;

Note that derived functions should always copy all used ; parameters to the "old" versions when they are changed as here.

; m_wastrapped should be set to true in the derived ; function when the main (current) values get changed
; @param pz the z value ; @param pzt the transformed z value ; @param pdistance the trap distance ; @param ptexture tyhe texture value func Iterate(complex pz, complex pzt, float pdistance, float ptexture) if m_wastrapped m_OldDistances[0] = m_Distances[0] m_OldTextures[0] = m_Textures[0] m_OldUntransformedPoints[0] = m_UntransformedPoints[0] m_OldTransformedPoints[0] = m_TransformedPoints[0] m_OldIterationPoints[0] = m_IterationPoints[0] endif m_Iterations = m_Iterations + 1 endfunc ; call this for each point that is ignored (for smooth orbit traps)
; if the last point was trapped then copy the current values into ; the "old" ones func IterateSilent() if m_wastrapped m_OldDistances[0] = m_Distances[0] m_OldTextures[0] = m_Textures[0] m_OldUntransformedPoints[0] = m_UntransformedPoints[0] m_OldTransformedPoints[0] = m_TransformedPoints[0] m_OldIterationPoints[0] = m_IterationPoints[0] m_wastrapped = false endif m_Iterations = m_Iterations + 1 endfunc ; call this to compute final results ; func Result() ; endfunc ; call this to compute penultimate results ;

Should be called only after the usual result has been returned ; by the appropriate Get function.
func OldResult() ; Note that in some cases if less than two values were trapped this
; should be skipped i.e. old result should be the same as result
m_Distances[0] = m_OldDistances[0] m_Textures[0] = m_OldTextures[0] m_UntransformedPoints[0] = m_OldUntransformedPoints[0] m_TransformedPoints[0] = m_OldTransformedPoints[0] m_IterationPoints[0] = m_OldIterationPoints[0] m_Iterations = m_Iterations - 1 endfunc protected: complex m_OldUntransformedPoints[4] complex m_OldTransformedPoints[4] float m_OldIterationPoints[4] float m_OldDistances[4] float m_OldTextures[4] bool m_wastrapped default: int param v_mmf_trapmodesmooth caption = "Version (MMF_TrapModeSmooth)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_mmf_trapmodesmooth < 100 endparam } class MMF_TrapModeSmoothWithThreshold(common.ulb:TrapModeWithThreshold) { ; ; Essentially a variant of TrapModeSmooth that is thresholdable

; Derived from TrapModeThreshold to ensure that the threshold parameter ; will be visible if used with non-smoothed orbit traps.
; public: ; @param pparent the parent, generally "this" for the parent, or zero func MMF_TrapModeSmoothWithThreshold(Generic pparent) TrapModeWithThreshold.TrapModeWithThreshold(pparent) endfunc ; call this at the beginning of each sequence
; @param pz the initial z value func Init(complex pz) m_Iterations = 0 m_Solid = false int j = 3 repeat m_UntransformedPoints[j] = m_OldUntransformedPoints[j] = (0,0) m_TransformedPoints[j] = m_OldTransformedPoints[j] = (0,0) m_IterationPoints[j] = m_OldIterationPoints[j] = 0 m_Distances[j] = m_OldDistances[j] = 0.0 m_Textures[j] = m_OldTextures[j] = 0.0 until (j=j-1)<0 m_wastrapped = false endfunc ; call this for each point ;

Note that derived functions should always copy all used ; parameters to the "old" versions when they are changed as here.

; m_wastrapped should be set to true in the derived ; function when the main (current) values get changed
; @param pz the z value ; @param pzt the transformed z value ; @param pdistance the trap distance ; @param ptexture tyhe texture value func Iterate(complex pz, complex pzt, float pdistance, float ptexture) if m_wastrapped m_OldDistances[0] = m_Distances[0] m_OldTextures[0] = m_Textures[0] m_OldUntransformedPoints[0] = m_UntransformedPoints[0] m_OldTransformedPoints[0] = m_TransformedPoints[0] m_OldIterationPoints[0] = m_IterationPoints[0] endif m_Iterations = m_Iterations + 1 endfunc ; call this for each point that is ignored (for smooth orbit traps)
; if the last point was trapped then copy the current values into ; the "old" ones func IterateSilent() if m_wastrapped m_OldDistances[0] = m_Distances[0] m_OldTextures[0] = m_Textures[0] m_OldUntransformedPoints[0] = m_UntransformedPoints[0] m_OldTransformedPoints[0] = m_TransformedPoints[0] m_OldIterationPoints[0] = m_IterationPoints[0] m_wastrapped = false endif m_Iterations = m_Iterations + 1 endfunc ; call this to compute penultimate results

; This should only be called after previously calling Result() ; and getting the actual result value using the Trap Color Mode ; since the original result values are destroyed by this call.
func OldResult() ; Note that in some cases if less than two values were trapped this ; should be skipped i.e. old result should be the same as result
m_Distances[0] = m_OldDistances[0] m_Textures[0] = m_OldTextures[0] m_UntransformedPoints[0] = m_OldUntransformedPoints[0] m_TransformedPoints[0] = m_OldTransformedPoints[0] m_IterationPoints[0] = m_OldIterationPoints[0] m_Iterations = m_Iterations - 1 endfunc protected: complex m_OldUntransformedPoints[4] complex m_OldTransformedPoints[4] float m_OldIterationPoints[4] float m_OldDistances[4] float m_OldTextures[4] bool m_wastrapped default: int param v_mmf_trapmodesmoothwiththreshold caption = "Version (MMF_TrapModeSmoothWithThreshold)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_mmf_trapmodesmoothwiththreshold < 100 endparam } class MMF_TrapModeSmoothSum(MMF_TrapModeSmoothWithThreshold) { ; Sums the trapped values within the threshold.
public: import "common.ulb" func MMF_TrapModeSmoothSum(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) MMF_TrapModeSmoothWithThreshold.Init(pz) m_Solid = true endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) if (pdistance < m_Threshold) m_Distances[0] = m_Distances[0] + pdistance m_Textures[0] = m_Textures[0] + ptexture m_UntransformedPoints[0] = m_UntransformedPoints[0] + pz m_TransformedPoints[0] = m_TransformedPoints[0] + pzt m_IterationPoints[0] = m_IterationPoints[0] + m_Iterations m_Solid = false m_wastrapped = true endif endfunc default: title = "Smooth Sum" rating = recommended heading caption = "Information" text = "Note that when using Trap Color Mode Iteration this differs \ slightly from normal 'Sum' by giving the sum of the iteration \ counts when values were trapped rather than the trap count. \ To colour by the trap counts just use say 'Smooth Average' \ instead." endheading } class MMF_TrapModeSmoothAverage(MMF_TrapModeSmoothWithThreshold) { ; Sums the trapped values within the threshold and converts the ; results to averages.
public: import "common.ulb" func MMF_TrapModeSmoothAverage(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) MMF_TrapModeSmoothWithThreshold.Init(pz) m_Solid = true endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) if (pdistance < m_Threshold) m_Distances[0] = m_Distances[0] + pdistance m_Textures[0] = m_Textures[0] + ptexture m_UntransformedPoints[0] = m_UntransformedPoints[0] + pz m_TransformedPoints[0] = m_TransformedPoints[0] + pzt m_IterationPoints[0] = m_IterationPoints[0] + 1 m_Solid = false m_wastrapped = true endif endfunc func Result() float ii = 1.0 / m_IterationPoints[0] m_Distances[0] = m_Distances[0] * ii m_Textures[0] = m_Textures[0] * ii m_UntransformedPoints[0] = m_UntransformedPoints[0] * ii m_TransformedPoints[0] = m_TransformedPoints[0] * ii endfunc func OldResult() if m_OldIterationPoints[0]>0 float ii = 1.0 / m_OldIterationPoints[0] m_Distances[0] = m_OldDistances[0] * ii m_Textures[0] = m_OldTextures[0] * ii m_UntransformedPoints[0] = m_OldUntransformedPoints[0] * ii m_TransformedPoints[0] = m_OldTransformedPoints[0] * ii m_IterationPoints[0] = m_OldIterationPoints[0] m_Iterations = m_Iterations - 1 endif endfunc default: title = "Smooth Average" rating = recommended } class MMF_TrapModeSmoothLast(MMF_TrapModeSmoothWithThreshold) { ; Returns the values from the last trapped iteration within ; the threshold.
public: import "common.ulb" func MMF_TrapModeSmoothLast(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) MMF_TrapModeSmoothWithThreshold.Init(pz) m_Solid = true endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) if pdistance < m_Threshold m_Distances[0] = pdistance m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_Textures[0] = ptexture m_Solid = false m_wastrapped = true endif endfunc default: title = "Smooth Last" rating = recommended } class MMF_TrapModeSmoothClosest(MMF_TrapModeSmoothWithThreshold) { ; Returns trapped values from when the distance was a minimum.
public: import "common.ulb" func MMF_TrapModeSmoothClosest(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) m_Iterations = 0 m_Solid = true int j = 3 repeat m_UntransformedPoints[j] = m_OldUntransformedPoints[j] = (0,0) m_TransformedPoints[j] = m_OldTransformedPoints[j] = (0,0) m_IterationPoints[j] = m_OldIterationPoints[j] = 0 m_Distances[j] = m_OldDistances[j] = 1e20 m_Textures[j] = m_OldTextures[j] = 0.0 until (j=j-1)<0 m_wastrapped = false endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) if (pdistance < m_Threshold) m_Solid = false endif if (pdistance < m_Distances[0]) m_Distances[0] = pdistance m_Textures[0] = ptexture m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_wastrapped = true endif endfunc func OldResult() if m_OldIterationPoints[0]>0 m_Distances[0] = m_OldDistances[0] m_Textures[0] = m_OldTextures[0] m_UntransformedPoints[0] = m_OldUntransformedPoints[0] m_TransformedPoints[0] = m_OldTransformedPoints[0] m_IterationPoints[0] = m_OldIterationPoints[0] m_Iterations = m_Iterations - 1 endif endfunc default: title = "Smooth Closest" rating = recommended } class MMF_TrapModeSmoothSecondClosest(MMF_TrapModeSmoothWithThreshold) { ; Returns the differences between the closest and second closest trapped ; iterations.
public: import "common.ulb" func MMF_TrapModeSmoothSecondClosest(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) m_Iterations = 0 m_Solid = true int j = 3 repeat m_UntransformedPoints[j] = m_OldUntransformedPoints[j] = (0,0) m_TransformedPoints[j] = m_OldTransformedPoints[j] = (0,0) m_IterationPoints[j] = m_OldIterationPoints[j] = 0 m_Distances[j] = m_OldDistances[j] = 1e20 m_Textures[j] = m_OldTextures[j] = 0.0 until (j=j-1)<0 m_wastrapped = false endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) if m_wastrapped m_OldDistances[0] = m_Distances[0] m_OldTextures[0] = m_Textures[0] m_OldUntransformedPoints[0] = m_UntransformedPoints[0] m_OldTransformedPoints[0] = m_TransformedPoints[0] m_OldIterationPoints[0] = m_IterationPoints[0] m_OldDistances[1] = m_Distances[1] m_OldTextures[1] = m_Textures[1] m_OldUntransformedPoints[1] = m_UntransformedPoints[1] m_OldTransformedPoints[1] = m_TransformedPoints[1] m_OldIterationPoints[1] = m_IterationPoints[1] endif m_Iterations = m_Iterations + 1 if (pdistance < m_Threshold) m_Solid = false endif if pdistance < m_Distances[0] m_Distances[1] = m_Distances[0] m_Textures[1] = m_Textures[0] m_UntransformedPoints[1] = m_UntransformedPoints[0] m_TransformedPoints[1] = m_TransformedPoints[0] m_IterationPoints[1] = m_IterationPoints[0] m_Distances[0] = pdistance m_Textures[0] = ptexture m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_wastrapped = true elseif pdistance0 m_Distances[0] = abs(m_OldDistances[0] - m_OldDistances[1]) m_Textures[0] = m_OldTextures[0] - m_OldTextures[1] m_UntransformedPoints[0] = m_OldUntransformedPoints[0] \ - m_OldUntransformedPoints[1] m_TransformedPoints[0] = m_OldTransformedPoints[0] \ - m_OldTransformedPoints[1] m_IterationPoints[0] = abs(m_OldIterationPoints[0] \ - m_OldIterationPoints[1]) m_Iterations = m_Iterations - 1 endif endfunc default: title = "Smooth Second Closest" rating = recommended } class MMF_TrapModeSmoothTwoClosest(MMF_TrapModeSmoothSecondClosest) { ; Returns the averages of the closest and second closest trapped ; iterations. public: import "common.ulb" func MMF_TrapModeSmoothTwoClosest(Generic pparent) MMF_TrapModeSmoothSecondClosest.MMF_TrapModeSmoothSecondClosest(pparent) endfunc func Result() m_Distances[0] = 0.5*(m_Distances[0] + m_Distances[1]) m_Textures[0] = 0.5*(m_Textures[0] + m_Textures[1]) m_UntransformedPoints[0] = 0.5*(m_UntransformedPoints[0] \ + m_UntransformedPoints[1]) m_TransformedPoints[0] = 0.5*(m_TransformedPoints[0] \ + m_TransformedPoints[1]) m_IterationPoints[0] = round(0.5*(m_IterationPoints[0] \ + m_IterationPoints[1])) endfunc func OldResult() if m_OldIterationPoints[1]>0 m_Distances[0] = 0.5*(m_OldDistances[0] + m_OldDistances[1]) m_Textures[0] = 0.5*(m_OldTextures[0] + m_OldTextures[1]) m_UntransformedPoints[0] = 0.5*(m_OldUntransformedPoints[0] \ + m_OldUntransformedPoints[1]) m_TransformedPoints[0] = 0.5*(m_OldTransformedPoints[0] \ + m_OldTransformedPoints[1]) m_IterationPoints[0] = round(0.5*(m_OldIterationPoints[0] \ + m_OldIterationPoints[1])) endif endfunc default: title = "Smooth Two Closest" } class MMF_TrapModeSmoothFarthest(MMF_TrapModeSmoothWithThreshold) { ; Returns the values from the trapped iteration with the largest ; distance within the threshold.
public: import "common.ulb" func MMF_TrapModeSmoothFarthest(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) MMF_TrapModeSmoothWithThreshold.Init(pz) m_Solid = true endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) if (pdistance < m_Threshold && pdistance >= m_Distances[0]) m_Distances[0] = pdistance m_Textures[0] = ptexture m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_Solid = false m_wastrapped = true endif endfunc default: title = "Smooth Farthest" rating = recommended } class MMF_TrapModeSmoothSecondFarthest(MMF_TrapModeSmoothWithThreshold) { ; Returns the difference in the values from the farthest trapped ; iteration within the threshold and the second farthest.
public: import "common.ulb" func MMF_TrapModeSmoothSecondFarthest(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) MMF_TrapModeSmoothWithThreshold.Init(pz) m_Solid = true endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) if m_wastrapped m_OldDistances[0] = m_Distances[0] m_OldTextures[0] = m_Textures[0] m_OldUntransformedPoints[0] = m_UntransformedPoints[0] m_OldTransformedPoints[0] = m_TransformedPoints[0] m_OldIterationPoints[0] = m_IterationPoints[0] m_OldDistances[1] = m_Distances[1] m_OldTextures[1] = m_Textures[1] m_OldUntransformedPoints[1] = m_UntransformedPoints[1] m_OldTransformedPoints[1] = m_TransformedPoints[1] m_OldIterationPoints[1] = m_IterationPoints[1] endif m_Iterations = m_Iterations + 1 if pdistance >= m_Distances[0] && pdistance < m_Threshold m_Distances[1] = m_Distances[0] m_Textures[1] = m_Textures[0] m_UntransformedPoints[1] = m_UntransformedPoints[0] m_TransformedPoints[1] = m_TransformedPoints[0] m_IterationPoints[1] = m_IterationPoints[0] m_Distances[0] = pdistance m_Textures[0] = ptexture m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_wastrapped = true m_Solid = false elseif pdistance>=m_Distances[1] && pdistance < m_Threshold m_Distances[1] = pdistance m_Textures[1] = ptexture m_UntransformedPoints[1] = pz m_TransformedPoints[1] = pzt m_IterationPoints[1] = m_Iterations m_wastrapped = true m_Solid = false endif endfunc func IterateSilent() if m_wastrapped m_OldDistances[0] = m_Distances[0] m_OldTextures[0] = m_Textures[0] m_OldUntransformedPoints[0] = m_UntransformedPoints[0] m_OldTransformedPoints[0] = m_TransformedPoints[0] m_OldIterationPoints[0] = m_IterationPoints[0] m_OldDistances[1] = m_Distances[1] m_OldTextures[1] = m_Textures[1] m_OldUntransformedPoints[1] = m_UntransformedPoints[1] m_OldTransformedPoints[1] = m_TransformedPoints[1] m_OldIterationPoints[1] = m_IterationPoints[1] m_wastrapped = false endif m_Iterations = m_Iterations + 1 endfunc func Result() m_Distances[0] = abs(m_Distances[0] - m_Distances[1]) m_Textures[0] = m_Textures[0] - m_Textures[1] m_UntransformedPoints[0] = m_UntransformedPoints[0] \ - m_UntransformedPoints[1] m_TransformedPoints[0] = m_TransformedPoints[0] \ - m_TransformedPoints[1] m_IterationPoints[0] = abs(m_IterationPoints[0] \ - m_IterationPoints[1]) endfunc func OldResult() if m_OldIterationPoints[1]>0 m_Distances[0] = abs(m_OldDistances[0] - m_OldDistances[1]) m_Textures[0] = m_OldTextures[0] - m_OldTextures[1] m_UntransformedPoints[0] = m_OldUntransformedPoints[0] \ - m_OldUntransformedPoints[1] m_TransformedPoints[0] = m_OldTransformedPoints[0] \ - m_OldTransformedPoints[1] m_IterationPoints[0] = abs(m_OldIterationPoints[0] \ - m_OldIterationPoints[1]) m_Iterations = m_Iterations - 1 endif endfunc default: title = "Smooth Second Farthest" rating = recommended } class MMF_TrapModeSmoothTwoFarthest(MMF_TrapModeSmoothSecondFarthest) { ; Returns the averages of the values from the trapped iteration with the ; farthest distance within the threshold and the second farthest.
public: import "common.ulb" func MMF_TrapModeSmoothTwoFarthest(Generic pparent) MMF_TrapModeSmoothSecondFarthest.MMF_TrapModeSmoothSecondFarthest(pparent) endfunc func Result() m_Distances[0] = 0.5*(m_Distances[0] + m_Distances[1]) m_Textures[0] = 0.5*(m_Textures[0] + m_Textures[1]) m_UntransformedPoints[0] = 0.5*(m_UntransformedPoints[0] \ + m_UntransformedPoints[1]) m_TransformedPoints[0] = 0.5*(m_TransformedPoints[0] \ + m_TransformedPoints[1]) m_IterationPoints[0] = round(0.5*(m_IterationPoints[0] \ + m_IterationPoints[1])) endfunc func OldResult() if m_OldIterationPoints[1]>0 m_Distances[0] = 0.5*(m_OldDistances[0] + m_OldDistances[1]) m_Textures[0] = 0.5*(m_OldTextures[0] + m_OldTextures[1]) m_UntransformedPoints[0] = 0.5*(m_OldUntransformedPoints[0] \ + m_OldUntransformedPoints[1]) m_TransformedPoints[0] = 0.5*(m_OldTransformedPoints[0] \ + m_OldTransformedPoints[1]) m_IterationPoints[0] = round(0.5*(m_OldIterationPoints[0] \ + m_OldIterationPoints[1])) endif endfunc default: title = "Smooth Two Farthest" } class MMF_TrapModeSmoothChangeAverage(MMF_TrapModeSmooth) { ; Total differences in distance within threshold.
public: import "common.ulb" func MMF_TrapModeSmoothChangeAverage(Generic pparent) MMF_TrapModeSmooth.MMF_TrapModeSmooth(pparent) endfunc func Init(complex pz) MMF_TrapModeSmooth.Init(pz) m_Solid = true m_PreviousDistance = 0.0 m_PreviousTexture = 0.0 endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmooth.Iterate(pz, pzt, pdistance, ptexture) if (pdistance < m_PreviousDistance) m_Distances[0] = m_Distances[0] + m_PreviousDistance-pdistance m_Textures[0] = m_Textures[0] + m_PreviousTexture-ptexture m_UntransformedPoints[0] = m_UntransformedPoints[0] + pz m_TransformedPoints[0] = m_TransformedPoints[0] + pzt m_IterationPoints[0] = m_IterationPoints[0] + 1 m_Solid = false m_wastrapped = true endif m_PreviousDistance = pdistance m_PreviousTexture = ptexture endfunc protected: float m_PreviousDistance float m_PreviousTexture default: title = "Smooth Change Average" } class MMF_TrapModeSmoothNth(MMF_TrapModeSmoothWithThreshold) { ; This trap mode traps to the nth trapped point that is within the ; threshold.
public: import "common.ulb" func MMF_TrapModeSmoothNth(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) MMF_TrapModeSmoothWithThreshold.Init(pz) m_Solid = true m_count = @p_count endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) if (pdistance < m_Threshold && m_count>0) m_Distances[0] = pdistance m_Textures[0] = ptexture m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_Solid = false m_wastrapped = true m_count = m_count - 1 endif endfunc private: int m_count default: title = "Smooth First N" rating = recommended int param p_count caption = "Trap Count, N" default = 1 min = 1 hint = "The algorithm will stop trapping after trapping this many \ values. Colouring will be from the last values trapped \ even if less than this many traps occurred." endparam } class MMF_TrapModeSmoothTurningPoints(MMF_TrapModeSmoothWithThreshold) { ; Traps the values occurring when the distance found hits maxima ; and/or minima.

; Note that in this class the Results are taken care of in the child ; TrapMode "m_trapmode". public: import "common.ulb" func MMF_TrapModeSmoothTurningPoints(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) m_trapmode = new @p_trapmode(this) endfunc func Init(complex pz) m_Iterations = 0 m_trapmode.Init(pz) m_dir = 0 m_olddist = 0.0 m_oldv = 0.0 m_pzold = (0,0) m_pztold = (0,0) m_pdold = 0.0 m_ptold = 0.0 endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) float v = pdistance int dir = 0 if @p_mode=="Differences" v = pdistance - m_olddist endif if v - m_oldv < 0.0 dir = -1 ; decreasing elseif v - m_oldv > 0.0 dir = 1 ; increasing endif if (@p_trap=="All" && dir!=m_dir) || (@p_trap=="Maxima" && dirm_dir) if @p_version=="Original" || m_Iterations==0 m_trapmode.Iterate(pz, pzt, pdistance, ptexture) else m_trapmode.Iterate(m_pzold, m_pztold, m_pdold, m_ptold) endif else m_trapmode.IterateSilent() endif m_Iterations = m_Iterations + 1 m_dir = dir m_olddist = pdistance m_oldv = v m_pzold = pz m_pztold = pzt m_pdold = pdistance m_ptold = ptexture endfunc func IterateSilent() m_Iterations = m_Iterations + 1 m_trapmode.IterateSilent() endfunc func Result() m_trapmode.Result() endfunc func OldResult() if @p_trapmode==MMF_TrapModeSmooth MMF_TrapModeSmooth(m_trapmode).OldResult() elseif @p_trapmode==MMF_TrapModeSmoothWithThreshold MMF_TrapModeSmoothWithThreshold(m_trapmode).OldResult() endif endfunc ; call this to determine if the last sequence produced a solid point
bool func IsSolid() return m_trapmode.IsSolid() endfunc ; get a final untransformed point
complex func GetUntransformedPoint(int pindex) return m_trapmode.GetUntransformedPoint(pindex) endfunc ; get a final transformed point
complex func GetTransformedPoint(int pindex) return m_trapmode.GetTransformedPoint(pindex) endfunc ; get a final distance
float func GetDistance(int pindex) return m_trapmode.GetDistance(pindex) endfunc ; get a final texture
float func GetTexture(int pindex) return m_trapmode.GetTexture(pindex) endfunc ; get a final iteration
float func GetIteration(int pindex) return m_trapmode.GetIteration(pindex) endfunc ; get threshold value
float func GetThreshold() return m_trapmode.GetThreshold() endfunc ; set threshold value
func SetThreshold(float pthreshold) m_trapmode.SetThreshold(pthreshold) endfunc ; get whether threshold is even used
bool func UsesThreshold() return m_trapmode.UsesThreshold() endfunc private: TrapMode m_trapmode complex m_pzold complex m_pztold float m_pdold float m_ptold float m_olddist float m_oldv int m_dir default: title = "Smooth Turning Points" rating = recommended int param p_version caption = "Version" enum = "Original" "Fixed" default = 0 hint = "In the original version the values to be trapped are those \ from the iteration after the maxima or minima actually \ occurred. In the fixed version the algorithm is corrected \ so the values from when the maxima or minima occurred are \ trapped. Note that when iteration skipping is used the \ 'Fixed' option will only work properly if it is plugged \ into compatible formulas such as mmf.ulb Smooth Orbit Traps." endparam int param p_trap caption = "Turning Points to Trap" enum = "All" "Maxima" "Minima" default = 0 hint = "You can choose to trap all turning points, or just minima, or \ just maxima." endparam int param p_mode caption = "Values to use" enum = "Distances" "Differences" default = 0 hint = "When using distances the turning points in the distances \ are trapped. When using differences the turning points in \ the changes to the distances are trapped." endparam TrapMode param p_trapmode caption = "Trap Mode for the Turning Points" default = MMF_TrapModeSmoothAverage hint = "If using mmf.ulb Smooth Orbit Traps then it's best to choose \ a 'Smooth' trap mode for example from mmf.ulb, obviously don't \ choose 'Smooth Turning Points' here." endparam } class MMF_TrapModeSmoothProduct(MMF_TrapModeSmoothWithThreshold) { ; ; Note that this implimentation is slightly different to normal ; TrapModeProduct in that IterationPoints is kept as a trap counter ; and TransformedPoints and UntransformedPoints are initialised to ; 1 and multiplied by (1 + pz/cabs(pz)) and (1 + pzt/cabs(pzt)) ; respectively.
; public: import "common.ulb" func MMF_TrapModeSmoothProduct(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) m_Iterations = 0 m_Solid = true int j = 3 repeat m_UntransformedPoints[j] = m_OldUntransformedPoints[j] = (1,0) m_TransformedPoints[j] = m_OldTransformedPoints[j] = (1,0) m_IterationPoints[j] = m_OldIterationPoints[j] = 0 m_Distances[j] = m_OldDistances[j] = 1.0 m_Textures[j] = m_OldTextures[j] = 1.0 until (j=j-1)<0 m_wastrapped = false endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) if (pdistance < m_Threshold) float id = 1.0 / m_Threshold m_Distances[0] = m_Distances[0] * (pdistance + @adjust) * id m_Textures[0] = m_Textures[0] * ptexture * id m_UntransformedPoints[0] = m_UntransformedPoints[0] \ * (1.0 + pz / cabs(pz)) m_TransformedPoints[0] = m_TransformedPoints[0] \ * (1.0 + pzt / cabs(pzt)) m_IterationPoints[0] = m_IterationPoints[0] + 1 m_Solid = false m_wastrapped = true endif endfunc func Result() m_Distances[0] = abs(m_Distances[0]) ; Note that texture is not forced to positive here. endfunc func OldResult() if m_OldIterationPoints[0]>0 m_Distances[0] = abs(m_OldDistances[0]) m_Textures[0] = m_OldTextures[0] m_UntransformedPoints[0] = m_OldUntransformedPoints[0] m_TransformedPoints[0] = m_OldTransformedPoints[0] m_IterationPoints[0] = m_OldIterationPoints[0] m_Iterations = m_Iterations - 1 ; Note that texture is not forced to positive here. endif endfunc default: title = "Smooth Product" heading text = "Note that this implimentation is slightly different to \ normal Trap Mode Product in that the Iteration value is \ kept as a trap counter and TransformedPoints and \ UntransformedPoints will actually produce values when \ using an appropriate Trap Color Mode such as Magnitude, \ Real or Imaginary etc." endheading float param adjust caption = "Offset Distance" default = 0.0 hint = "Modifies the distances found by this value before \ multiplying. Try non-zero values if you get little \ or no colouring variation, note that often increases \ in the Trap Threshold will require increases in this \ value and vice-versa." endparam } class MMF_TrapModeSmoothProductDist(MMF_TrapModeSmoothWithThreshold) { ; ; Note that this implimentation is slightly different to normal ; TrapModeProduct in that IterationPoints is kept as a trap counter ; and TransformedPoints and UntransformedPoints are initialised to ; 1 and multiplied by (1 + pz/cabs(pz)) and (1 + pzt/cabs(pzt)) ; respectively.
; public: import "common.ulb" func MMF_TrapModeSmoothProductDist(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) m_Iterations = 0 m_Solid = true int j = 3 repeat m_UntransformedPoints[j] = m_OldUntransformedPoints[j] = (1,0) m_TransformedPoints[j] = m_OldTransformedPoints[j] = (1,0) m_IterationPoints[j] = m_OldIterationPoints[j] = 0 m_Distances[j] = m_OldDistances[j] = 1.0 m_Textures[j] = m_OldTextures[j] = 1.0 until (j=j-1)<0 m_wastrapped = false endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) pdistance = abs(pdistance - @p_testdist) if (pdistance < m_Threshold) float id = 1.0 / m_Threshold m_Distances[0] = m_Distances[0] * (pdistance + @adjust) * id m_Textures[0] = m_Textures[0] * ptexture * id m_UntransformedPoints[0] = m_UntransformedPoints[0] \ * (1.0 + pz / cabs(pz)) m_TransformedPoints[0] = m_TransformedPoints[0] \ * (1.0 + pzt / cabs(pzt)) m_IterationPoints[0] = m_IterationPoints[0] + 1 m_Solid = false m_wastrapped = true endif endfunc func OldResult() if m_OldIterationPoints[0]>0 m_Distances[0] = m_OldDistances[0] m_Textures[0] = m_OldTextures[0] m_UntransformedPoints[0] = m_OldUntransformedPoints[0] m_TransformedPoints[0] = m_OldTransformedPoints[0] m_IterationPoints[0] = m_OldIterationPoints[0] m_Iterations = m_Iterations - 1 endif endfunc default: title = "Smooth Product (from Test Distance)" heading text = "Note that this implimentation is slightly different to \ normal Trap Mode Product in that the Iteration value is \ kept as a trap counter and TransformedPoints and \ UntransformedPoints will actually produce values when \ using an appropriate Trap Color Mode such as Magnitude, \ Real or Imaginary etc." endheading float param adjust caption = "Offset Distance" default = 0.0 hint = "Modifies the distances found by this value before \ multiplying. Try non-zero values if you get little \ or no colouring variation, note that often increases \ in the Trap Threshold will require increases in this \ value and vice-versa." endparam float param p_testdist caption = "Trap Test Distance" default = 0.5 hint = "Multiplies the results of distances from this distance \ from the trap." endparam } class MMF_TrapModeSmoothProductAbove(MMF_TrapModeSmoothWithThreshold) { ; ; Note that this implimentation is slightly different to normal ; TrapModeProduct in that IterationPoints is kept as a trap counter ; and TransformedPoints and UntransformedPoints are initialised to ; 1 and multiplied by (1 + pz/cabs(pz)) and (1 + pzt/cabs(pzt)) ; respectively.
; public: import "common.ulb" func MMF_TrapModeSmoothProductAbove(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) m_Iterations = 0 m_Solid = true int j = 3 repeat m_UntransformedPoints[j] = m_OldUntransformedPoints[j] = (1,0) m_TransformedPoints[j] = m_OldTransformedPoints[j] = (1,0) m_IterationPoints[j] = m_OldIterationPoints[j] = 0 m_Distances[j] = m_OldDistances[j] = 1.0 m_Textures[j] = m_OldTextures[j] = 1.0 until (j=j-1)<0 m_wastrapped = false endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) pdistance = pdistance - @p_testdist if pdistance>=0 && pdistance < m_Threshold float id = 1.0 / m_Threshold m_Distances[0] = m_Distances[0] * (pdistance + @adjust) * id m_Textures[0] = m_Textures[0] * ptexture * id m_UntransformedPoints[0] = m_UntransformedPoints[0] \ * (1.0 + pz / cabs(pz)) m_TransformedPoints[0] = m_TransformedPoints[0] \ * (1.0 + pzt / cabs(pzt)) m_IterationPoints[0] = m_IterationPoints[0] + 1 m_Solid = false m_wastrapped = true endif endfunc func OldResult() if m_OldIterationPoints[0]>0 m_Distances[0] = m_OldDistances[0] m_Textures[0] = m_OldTextures[0] m_UntransformedPoints[0] = m_OldUntransformedPoints[0] m_TransformedPoints[0] = m_OldTransformedPoints[0] m_IterationPoints[0] = m_OldIterationPoints[0] m_Iterations = m_Iterations - 1 endif endfunc default: title = "Smooth Product Above" heading text = "Note that this implimentation is slightly different to \ normal Trap Mode Product in that the Iteration value is \ kept as a trap counter and TransformedPoints and \ UntransformedPoints will actually produce values when \ using an appropriate Trap Color Mode such as Magnitude, \ Real or Imaginary etc." endheading float param adjust caption = "Offset Distance" default = 0.0 hint = "Modifies the distances found by this value before \ multiplying. Try non-zero values if you get little \ or no colouring variation, note that often increases \ in the Trap Threshold will require increases in this \ value and vice-versa." endparam float param p_testdist caption = "Trap Test Distance" default = 0.5 hint = "Multiplies the results of distances from this distance \ from the trap." endparam } class MMF_TrapModeSmoothProductBelow(MMF_TrapModeSmoothWithThreshold) { ; ; Note that this implimentation is slightly different to normal ; TrapModeProduct in that IterationPoints is kept as a trap counter ; and TransformedPoints and UntransformedPoints are initialised to ; 1 and multiplied by (1 + pz/cabs(pz)) and (1 + pzt/cabs(pzt)) ; respectively.
; public: import "common.ulb" func MMF_TrapModeSmoothProductBelow(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) m_Iterations = 0 m_Solid = true int j = 3 repeat m_UntransformedPoints[j] = m_OldUntransformedPoints[j] = (1,0) m_TransformedPoints[j] = m_OldTransformedPoints[j] = (1,0) m_IterationPoints[j] = m_OldIterationPoints[j] = 0 m_Distances[j] = m_OldDistances[j] = 1.0 m_Textures[j] = m_OldTextures[j] = 1.0 until (j=j-1)<0 m_wastrapped = false endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) pdistance = @p_testdist - pdistance if pdistance>=0 && pdistance < m_Threshold float id = 1.0 / m_Threshold m_Distances[0] = m_Distances[0] * (pdistance + @adjust) * id m_Textures[0] = m_Textures[0] * ptexture * id m_UntransformedPoints[0] = m_UntransformedPoints[0] \ * (1.0 + pz / cabs(pz)) m_TransformedPoints[0] = m_TransformedPoints[0] \ * (1.0 + pzt / cabs(pzt)) m_IterationPoints[0] = m_IterationPoints[0] + 1 m_Solid = false m_wastrapped = true endif endfunc func OldResult() if m_OldIterationPoints[0]>0 m_Distances[0] = m_OldDistances[0] m_Textures[0] = m_OldTextures[0] m_UntransformedPoints[0] = m_OldUntransformedPoints[0] m_TransformedPoints[0] = m_OldTransformedPoints[0] m_IterationPoints[0] = m_OldIterationPoints[0] m_Iterations = m_Iterations - 1 endif endfunc default: title = "Smooth Product Below" heading text = "Note that this implimentation is slightly different to \ normal Trap Mode Product in that the Iteration value is \ kept as a trap counter and TransformedPoints and \ UntransformedPoints will actually produce values when \ using an appropriate Trap Color Mode such as Magnitude, \ Real or Imaginary etc." endheading float param adjust caption = "Offset Distance" default = 0.0 hint = "Modifies the distances found by this value before \ multiplying. Try non-zero values if you get little \ or no colouring variation, note that often increases \ in the Trap Threshold will require increases in this \ value and vice-versa." endparam float param p_testdist caption = "Trap Test Distance" default = 0.5 hint = "Multiplies the results of distances from this distance \ from the trap." endparam } class MMF_TrapModeSmoothNearest(MMF_TrapModeSmoothWithThreshold) { ; Returns values from the trapped iteration where the distance is nearest ; to the user value and within the threshold of it.
public: import "common.ulb" func MMF_TrapModeSmoothNearest(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) m_Iterations = 0 m_Solid = true int j = 3 repeat m_UntransformedPoints[j] = m_OldUntransformedPoints[j] = (0,0) m_TransformedPoints[j] = m_OldTransformedPoints[j] = (0,0) m_IterationPoints[j] = m_OldIterationPoints[j] = 0 m_Distances[j] = m_OldDistances[j] = 1e20 m_Textures[j] = m_OldTextures[j] = 0.0 until (j=j-1)<0 m_wastrapped = false endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) pdistance = abs(pdistance - @p_testdist) if (pdistance < m_Threshold) m_Solid = false endif if (pdistance < m_Distances[0]) m_Distances[0] = pdistance m_Textures[0] = ptexture m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_wastrapped = true endif endfunc func OldResult() if m_OldIterationPoints[0]>0 m_Distances[0] = m_OldDistances[0] m_Textures[0] = m_OldTextures[0] m_UntransformedPoints[0] = m_OldUntransformedPoints[0] m_TransformedPoints[0] = m_OldTransformedPoints[0] m_IterationPoints[0] = m_OldIterationPoints[0] m_Iterations = m_Iterations - 1 endif endfunc default: title = "Smooth Nearest" rating = recommended float param p_testdist caption = "Trap Test Distance" default = 0.5 hint = "Traps the result nearest this distance from the trap." endparam } class MMF_TrapModeSmoothFarthestDist(MMF_TrapModeSmoothWithThreshold) { ; Returns values from the trapped iteration where the distance is farthest ; from the user value and within the threshold of it.
public: import "common.ulb" func MMF_TrapModeSmoothFarthestDist(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) MMF_TrapModeSmoothWithThreshold.Init(pz) m_Solid = true endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) pdistance = abs(pdistance - @p_testdist) if (pdistance < m_Threshold && pdistance >= m_Distances[0]) m_Distances[0] = pdistance m_Textures[0] = ptexture m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_Solid = false m_wastrapped = true endif endfunc default: title = "Smooth Farthest (from Test Distance)" rating = recommended float param p_testdist caption = "Trap Test Distance" default = 0.5 hint = "Traps the result farthest from this distance from the trap \ provided the distance from this distance is within the \ threshold." endparam } class MMF_TrapModeSmoothNearestBelow(MMF_TrapModeSmoothWithThreshold) { ; Returns values from the trapped iteration with the nearest distance ; less than or equal to the user value and within the threshold of it.
public: import "common.ulb" func MMF_TrapModeSmoothNearestBelow(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) m_Iterations = 0 m_Solid = true int j = 3 repeat m_UntransformedPoints[j] = m_OldUntransformedPoints[j] = (0,0) m_TransformedPoints[j] = m_OldTransformedPoints[j] = (0,0) m_IterationPoints[j] = m_OldIterationPoints[j] = 0 m_Distances[j] = m_OldDistances[j] = 1e20 m_Textures[j] = m_OldTextures[j] = 0.0 until (j=j-1)<0 m_wastrapped = false endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) if (pdistance = @p_testdist - pdistance)>=0 if (pdistance < m_Threshold) m_Solid = false endif if (pdistance < m_Distances[0]) m_Distances[0] = pdistance m_Textures[0] = ptexture m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_wastrapped = true endif endif endfunc func OldResult() if m_OldIterationPoints[0]>0 m_Distances[0] = m_OldDistances[0] m_Textures[0] = m_OldTextures[0] m_UntransformedPoints[0] = m_OldUntransformedPoints[0] m_TransformedPoints[0] = m_OldTransformedPoints[0] m_IterationPoints[0] = m_OldIterationPoints[0] m_Iterations = m_Iterations - 1 endif endfunc default: title = "Smooth Nearest Below" rating = recommended float param p_testdist caption = "Trap Test Distance" default = 0.5 hint = "Traps the result nearest this distance from the trap but only \ if it's less than this distance from the trap." endparam } class MMF_TrapModeSmoothNearestAbove(MMF_TrapModeSmoothWithThreshold) { ; Returns values from the trapped iteration with the nearest distance ; greater than or equal to the user value and within the threshold of it.
public: import "common.ulb" func MMF_TrapModeSmoothNearestAbove(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) m_Iterations = 0 m_Solid = true int j = 3 repeat m_UntransformedPoints[j] = m_OldUntransformedPoints[j] = (0,0) m_TransformedPoints[j] = m_OldTransformedPoints[j] = (0,0) m_IterationPoints[j] = m_OldIterationPoints[j] = 0 m_Distances[j] = m_OldDistances[j] = 1e20 m_Textures[j] = m_OldTextures[j] = 0.0 until (j=j-1)<0 m_wastrapped = false endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) if (pdistance = pdistance - @p_testdist)>=0 if (pdistance < m_Threshold) m_Solid = false endif if (pdistance < m_Distances[0]) m_Distances[0] = pdistance m_Textures[0] = ptexture m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_wastrapped = true endif endif endfunc func OldResult() if m_OldIterationPoints[0]>0 m_Distances[0] = m_OldDistances[0] m_Textures[0] = m_OldTextures[0] m_UntransformedPoints[0] = m_OldUntransformedPoints[0] m_TransformedPoints[0] = m_OldTransformedPoints[0] m_IterationPoints[0] = m_OldIterationPoints[0] m_Iterations = m_Iterations - 1 endif endfunc default: title = "Smooth Nearest Above" rating = recommended float param p_testdist caption = "Trap Test Distance" default = 0.5 hint = "Traps the result nearest this distance from the trap but only \ if it's more than this distance from the trap." endparam } class MMF_TrapModeSmoothFarthestBelow(MMF_TrapModeSmoothWithThreshold) { ; Returns values from the trapped iteration with the farthest distance ; less than or equal to the user value and within the threshold of it.
public: import "common.ulb" func MMF_TrapModeSmoothFarthestBelow(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) MMF_TrapModeSmoothWithThreshold.Init(pz) m_Solid = true endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) pdistance = @p_testdist - pdistance if (pdistance < m_Threshold && pdistance >= m_Distances[0]) m_Distances[0] = pdistance m_Textures[0] = ptexture m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_Solid = false m_wastrapped = true endif endfunc default: title = "Smooth Farthest Below" rating = recommended float param p_testdist caption = "Trap Test Distance" default = 0.5 hint = "Traps the result farthest from this distance from the trap \ provided it's less than this distance from the trap and \ provided the distance from this distance is within the \ threshold." endparam } class MMF_TrapModeSmoothFarthestAbove(MMF_TrapModeSmoothWithThreshold) { ; Returns values from the trapped iteration with the farthest distance ; greater than or equal to the user value and within the threshold of it.
public: import "common.ulb" func MMF_TrapModeSmoothFarthestAbove(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) MMF_TrapModeSmoothWithThreshold.Init(pz) m_Solid = true endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) pdistance = pdistance - @p_testdist if (pdistance < m_Threshold && pdistance >= m_Distances[0]) m_Distances[0] = pdistance m_Textures[0] = ptexture m_UntransformedPoints[0] = pz m_TransformedPoints[0] = pzt m_IterationPoints[0] = m_Iterations m_Solid = false m_wastrapped = true endif endfunc default: title = "Smooth Farthest Above" rating = recommended float param p_testdist caption = "Trap Test Distance" default = 0.5 hint = "Traps the result farthest from this distance from the trap \ provided it's more than this distance from the trap and \ provided the distance from this distance is within the \ threshold." endparam } class MMF_TrapModeSmoothSumDist(MMF_TrapModeSmoothWithThreshold) { ; Sums the values with distamce within the threshold of the user distance.
public: import "common.ulb" func MMF_TrapModeSmoothSumDist(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) MMF_TrapModeSmoothWithThreshold.Init(pz) m_Solid = true endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) pdistance = abs(@p_testdist - pdistance) if pdistance < m_Threshold m_Distances[0] = m_Distances[0] + pdistance m_Textures[0] = m_Textures[0] + ptexture m_UntransformedPoints[0] = m_UntransformedPoints[0] + pz m_TransformedPoints[0] = m_TransformedPoints[0] + pzt m_IterationPoints[0] = m_IterationPoints[0] + m_Iterations m_Solid = false m_wastrapped = true endif endfunc default: title = "Smooth Sum (from Test Distance)" rating = recommended float param p_testdist caption = "Trap Test Distance" default = 0.5 hint = "Gets the sum of the distances from the test distance \ that are within the threshold." endparam } class MMF_TrapModeSmoothAverageDist(MMF_TrapModeSmoothSumDist) { ; Sums the values with distamce within the threshold of the user distance ; and converts the values to averages.
public: import "common.ulb" func MMF_TrapModeSmoothAverageDist(Generic pparent) MMF_TrapModeSmoothSumDist.MMF_TrapModeSmoothSumDist(pparent) endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) pdistance = abs(@p_testdist - pdistance) if pdistance < m_Threshold m_Distances[0] = m_Distances[0] + pdistance m_Textures[0] = m_Textures[0] + ptexture m_UntransformedPoints[0] = m_UntransformedPoints[0] + pz m_TransformedPoints[0] = m_TransformedPoints[0] + pzt m_IterationPoints[0] = m_IterationPoints[0] + 1 m_Solid = false m_wastrapped = true endif endfunc func Result() float ii = 1.0 / m_IterationPoints[0] m_Distances[0] = m_Distances[0] * ii m_Textures[0] = m_Textures[0] * ii m_UntransformedPoints[0] = m_UntransformedPoints[0] * ii m_TransformedPoints[0] = m_TransformedPoints[0] * ii endfunc func OldResult() if m_OldIterationPoints[0]>0 float ii = 1.0 / m_OldIterationPoints[0] m_Distances[0] = m_OldDistances[0] * ii m_Textures[0] = m_OldTextures[0] * ii m_UntransformedPoints[0] = m_OldUntransformedPoints[0] * ii m_TransformedPoints[0] = m_OldTransformedPoints[0] * ii m_IterationPoints[0] = m_OldIterationPoints[0] m_Iterations = m_Iterations - 1 endif endfunc default: title = "Smooth Average (from Test Distance)" rating = recommended float param p_testdist caption = "Trap Test Distance" default = 0.5 hint = "Gets the average of the distances from the test distance \ that are within the threshold." endparam } class MMF_TrapModeSmoothSumBelow(MMF_TrapModeSmoothWithThreshold) { ; Sums the values less than the user value and within the threshold of it.
public: import "common.ulb" func MMF_TrapModeSmoothSumBelow(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) MMF_TrapModeSmoothWithThreshold.Init(pz) m_Solid = true endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) pdistance = @p_testdist - pdistance if pdistance>=0 && pdistance < m_Threshold m_Distances[0] = m_Distances[0] + pdistance m_Textures[0] = m_Textures[0] + ptexture m_UntransformedPoints[0] = m_UntransformedPoints[0] + pz m_TransformedPoints[0] = m_TransformedPoints[0] + pzt m_IterationPoints[0] = m_IterationPoints[0] + m_Iterations m_Solid = false m_wastrapped = true endif endfunc default: title = "Smooth Sum Below" rating = recommended float param p_testdist caption = "Trap Test Distance" default = 0.5 hint = "Gets the sum of the distances from the test distance \ where the original distance was below the test distance \ and provided the distance from this distance is within \ the threshold." endparam } class MMF_TrapModeSmoothAverageBelow(MMF_TrapModeSmoothSumBelow) { ; Sums the values less than the user value and within the threshold of it ; and converts the values to averages.
public: import "common.ulb" func MMF_TrapModeSmoothAverageBelow(Generic pparent) MMF_TrapModeSmoothSumBelow.MMF_TrapModeSmoothSumBelow(pparent) endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) pdistance = @p_testdist - pdistance if pdistance>=0 && pdistance < m_Threshold m_Distances[0] = m_Distances[0] + pdistance m_Textures[0] = m_Textures[0] + ptexture m_UntransformedPoints[0] = m_UntransformedPoints[0] + pz m_TransformedPoints[0] = m_TransformedPoints[0] + pzt m_IterationPoints[0] = m_IterationPoints[0] + 1 m_Solid = false m_wastrapped = true endif endfunc func Result() float ii = 1.0 / m_IterationPoints[0] m_Distances[0] = m_Distances[0] * ii m_Textures[0] = m_Textures[0] * ii m_UntransformedPoints[0] = m_UntransformedPoints[0] * ii m_TransformedPoints[0] = m_TransformedPoints[0] * ii endfunc func OldResult() if m_OldIterationPoints[0]>0 float ii = 1.0 / m_OldIterationPoints[0] m_Distances[0] = m_OldDistances[0] * ii m_Textures[0] = m_OldTextures[0] * ii m_UntransformedPoints[0] = m_OldUntransformedPoints[0] * ii m_TransformedPoints[0] = m_OldTransformedPoints[0] * ii m_IterationPoints[0] = m_OldIterationPoints[0] m_Iterations = m_Iterations - 1 endif endfunc default: title = "Smooth Average Below" rating = recommended float param p_testdist caption = "Trap Test Distance" default = 0.5 hint = "Gets the average of the distances from the test distance \ where the original distance was below the test distance \ and provided the distance from this distance is within \ the threshold." endparam } class MMF_TrapModeSmoothSumAbove(MMF_TrapModeSmoothWithThreshold) { ; Sums the values above than the user value and within the threshold of it.
public: import "common.ulb" func MMF_TrapModeSmoothSumAbove(Generic pparent) MMF_TrapModeSmoothWithThreshold.MMF_TrapModeSmoothWithThreshold(pparent) endfunc func Init(complex pz) MMF_TrapModeSmoothWithThreshold.Init(pz) m_Solid = true endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) pdistance = pdistance - @p_testdist if pdistance>=0 && pdistance < m_Threshold m_Distances[0] = m_Distances[0] + pdistance m_Textures[0] = m_Textures[0] + ptexture m_UntransformedPoints[0] = m_UntransformedPoints[0] + pz m_TransformedPoints[0] = m_TransformedPoints[0] + pzt m_IterationPoints[0] = m_IterationPoints[0] + m_Iterations m_Solid = false m_wastrapped = true endif endfunc default: title = "Smooth Sum Above" rating = recommended float param p_testdist caption = "Trap Test Distance" default = 0.5 hint = "Gets the sum of the distances from the test distance \ where the original distance was above the test distance \ and provided the distance from this distance is within \ the threshold." endparam } class MMF_TrapModeSmoothAverageAbove(MMF_TrapModeSmoothSumAbove) { ; Sums the values above than the user value and within the threshold of it ; and converts the values to averages.
public: import "common.ulb" func MMF_TrapModeSmoothAverageAbove(Generic pparent) MMF_TrapModeSmoothSumAbove.MMF_TrapModeSmoothSumAbove(pparent) endfunc func Iterate(complex pz, complex pzt, float pdistance, float ptexture) MMF_TrapModeSmoothWithThreshold.Iterate(pz, pzt, pdistance, ptexture) pdistance = pdistance - @p_testdist if pdistance>=0 && pdistance < m_Threshold m_Distances[0] = m_Distances[0] + pdistance m_Textures[0] = m_Textures[0] + ptexture m_UntransformedPoints[0] = m_UntransformedPoints[0] + pz m_TransformedPoints[0] = m_TransformedPoints[0] + pzt m_IterationPoints[0] = m_IterationPoints[0] + 1 m_Solid = false m_wastrapped = true endif endfunc func Result() float ii = 1.0 / m_IterationPoints[0] m_Distances[0] = m_Distances[0] * ii m_Textures[0] = m_Textures[0] * ii m_UntransformedPoints[0] = m_UntransformedPoints[0] * ii m_TransformedPoints[0] = m_TransformedPoints[0] * ii endfunc func OldResult() if m_OldIterationPoints[0]>0 float ii = 1.0 / m_OldIterationPoints[0] m_Distances[0] = m_OldDistances[0] * ii m_Textures[0] = m_OldTextures[0] * ii m_UntransformedPoints[0] = m_OldUntransformedPoints[0] * ii m_TransformedPoints[0] = m_OldTransformedPoints[0] * ii m_IterationPoints[0] = m_OldIterationPoints[0] m_Iterations = m_Iterations - 1 endif endfunc default: title = "Smooth Average Above" rating = recommended float param p_testdist caption = "Trap Test Distance" default = 0.5 hint = "Gets the average of the distances from the test distance \ where the original distance was above the test distance \ and provided the distance from this distance is within \ the threshold." endparam } class MMF_TrapShapeZold(common.ulb:TrapShape) { ; This is a base class specifically for Trap Shapes that require ; old values of z.
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_TrapShapeZold(Generic pparent) TrapShape.TrapShape(pparent) endfunc ; call this before each sequence of values to be trapped
; @param pz the initial z value func Init(complex pz) m_Iterations = 0 m_LastZ = m_zold = m_zolder = pz m_zoldok = m_zolderok = false endfunc ; call this for each iteration being trapped

; It's up to the derived function to copy zold to zolder and ; pz to zold after using the values of zolder, zold and pz ; (without modifying them obviously).

; And to (finally) copy zoldok to zolderok and set zoldok to true.

; Note that if there's no result (due to no zold or zolder) then ; the function could return +infinity as the value to ensure the ; value is outside any threshold.
; @param pz the z value ; @return trap distance float func Iterate(complex pz) m_Iterations = m_Iterations + 1 m_LastZ = pz return real(pz) endfunc ; Update internal counters without transforming a value
; Flag for "got old z values" set to false
func IterateSilent() m_zoldok = m_zolderok = false m_Iterations = m_Iterations + 1 endfunc ; Update internal counters without transforming a value
; Keep updating old z values
; @param pz the z value func IterateSilentZold(complex pz) m_zolder = m_zold m_zold = pz m_zolderok = m_zoldok m_zoldok = true m_Iterations = m_Iterations + 1 endfunc protected: complex m_zold complex m_zolder bool m_zoldok bool m_zolderok default: int param v_mmftrapshapezold caption = "Version (MMF TrapShapeZold)" default = 100 hint = "This version parameter is used to detect when a change has \ been made to the formula that is incompatible with the \ previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_mmftrapshapezold < 100 endparam } class MMF_TrapShapeOldAngles(MMF_TrapShapeZold) { ; Trap various old angle values.
public: import "common.ulb" func MMF_TrapShapeOldAngles(Generic pparent) MMF_TrapShapeZold.MMF_TrapShapeZold(pparent) endfunc float func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this trapshape
m_LastZ = pz float r = recip(0.0) if (@mode=="Raw Old Angles" || @mode=="Absolute Old Angles" \ || @mode=="All Old Angles" || @mode=="Old Cosines" \ || @mode=="All Old Angles 2") && m_zoldok if @mode=="Raw Old Angles" r = atan2(pz + @offset - m_zold) elseif @mode=="Absolute Old Angles" r = abs(atan2(pz + @offset - m_zold)) elseif @mode=="All Old Angles" r = #pi + atan2(pz + @offset - m_zold) elseif @mode=="Old Cosines" r = cos(0.5*atan2(pz + @offset - m_zold)) elseif @mode=="All Old Angles 2" r = atan2(pz + @offset - m_zold) if r<0.0 r = r + 2.0*#pi endif endif elseif (@mode=="Raw Older Angles" || @mode=="Absolute Older Angles" \ || @mode=="All Older Angles" || @mode=="Older Cosines" \ || @mode=="All Older Angles 2") && m_zolderok if @mode=="Raw Older Angles" r = atan2(pz + @offset - m_zolder) elseif @mode=="Absolute Older Angles" r = abs(atan2(pz + @offset - m_zolder)) elseif @mode=="All Older Angles" r = #pi + atan2(pz + @offset - m_zolder) elseif @mode=="Older Cosines" r = cos(0.5*atan2(pz + @offset - m_zolder)) elseif @mode=="All Older Angles 2" r = atan2(pz + @offset - m_zolder) if r<0.0 r = r + 2.0*#pi endif endif endif m_zolder = m_zold m_zold = pz m_zolderok = m_zoldok m_zoldok = true return r endfunc default: title = "Angles (of z-zold or z-zolder)" heading text = "Intended for use with 'MMF Smooth Orbit Traps (Gradient)' or \ similar smoothing formulas since smoothing is usually required." endheading int param mode caption = "Method" enum = "Raw Old Angles" "Absolute Old Angles" "All Old Angles" \ "Old Cosines" "All Old Angles 2" "Raw Older Angles" \ "Absolute Older Angles" "All Older Angles" "Older Cosines" \ "All Older Angles 2" default = 3 hint = "Inspired by Cilia mode colouring." endparam complex param offset caption = "Z Offset" default = (0,0) hint = "Offsets z by this amount, useful for animation." endparam } class MMF_TrapShapeSimpleVergence(MMF_TrapShapeZold) { ; Trap the divergence or convergence in the orbit.
public: import "common.ulb" func MMF_TrapShapeSimpleVergence(Generic pparent) MMF_TrapShapeZold.MMF_TrapShapeZold(pparent) endfunc float func Iterate(complex pz) float r = recip(0) ; ensures that "no result" due to no zold or zolder ; returns a value outside the threshold ; m_Iterations = m_Iterations + 1 not used in this trapshape m_LastZ = pz if @type=="Divergence" && m_zoldok r = cabs(log(pz)/log(m_zold)) elseif @type=="Convergence" && m_zolderok r = cabs(log(pz-m_zold)/log(m_zold-m_zolder)) endif m_zolder = m_zold m_zold = pz m_zolderok = m_zoldok m_zoldok = true return r endfunc default: title = "Simple 'Vergence" int param type caption = "Type of 'Vergence" enum = "Divergence" "Convergence" default = 0 hint = "Divergence uses log(z)/log(zold), Convergence uses \ log(z-zold)/log(zold-zolder). Either type should \ work on any fractal whether convergent or divergent." endparam } class MMF_TrapShapeOrbitals(MMF_TrapShapeZold) { ; Traps the change in z or z-zold relative to z or z-zold.
public: import "common.ulb" func MMF_TrapShapeOrbitals(Generic pparent) MMF_TrapShapeZold.MMF_TrapShapeZold(pparent) endfunc ; The recip(0) ensures that "no result" due to no zold or zolder ; returns a value outside the threshold
float func Iterate(complex pz) float r = recip(0) ; m_Iterations = m_Iterations + 1 not used in this trapshape m_LastZ = pz if @type=="Divergent" && m_zoldok r = sqrt(|pz-m_zold|/|pz|) elseif m_zolderok if @type=="Convergent" r = sqrt(|pz-2.0*m_zold+m_zolder|/|pz-m_zold|) elseif @type=="Old Divergent" r = sqrt(|pz-m_zolder|/|pz|) endif endif m_zolder = m_zold m_zold = pz m_zolderok = m_zoldok m_zoldok = true return r endfunc default: title = "Orbitals" heading text = "Intended for use with 'MMF Smooth Orbit Traps (Gradient)' or \ similar smoothing formulas since smoothing is often required." endheading int param type caption = "Orbital Type" enum = "Divergent" "Convergent" "Old Divergent" default = 0 hint = "Divergent traps z to zold, Convergent traps z-zold to \ zold-zolder, Old Divergent traps z to zolder. \ All may work for any main formula whether it's \ convergent or divergent." endparam } class MMF_TrapShapeModulus(common.ulb:TrapShape) { public: import "common.ulb" import "Standard.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_TrapShapeModulus(Generic pparent) TrapShape.TrapShape(pparent) fTrapShape1 = new @p_TrapShape1(this) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this transform m_Solid = false fTrapShape1.Init(pz) endfunc float func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform pz = pz*@p_scale return fTrapShape1.Iterate(real(pz)%real(@p_modulus) \ +flip(imag(pz)%imag(@p_modulus))) endfunc private: TrapShape fTrapShape1 default: title = "Trap Shape Modulus" complex param p_modulus caption = "Modulus" default = (1.0,1.0) hint = "Both real and imaginay pats are used, being applied to the real \ and imaginay input values respectively." endparam complex param p_scale caption = "Scale" default = (1.0,0.0) hint = "Normally you'd stick to using a wholly real number." endparam TrapShape param p_TrapShape1 caption = "Following trap shape" default = Standard_TrapShapePoint hint = "The modified value is passsed on to this trap shape." endparam } class MMF_TrapShapeCurvature(MMF_TrapShapeZold) { ; ; Based on the original curvature formula by Damien Jones.
; public: import "common.ulb" func MMF_TrapShapeCurvature(Generic pparent) MMF_TrapShapeZold.MMF_TrapShapeZold(pparent) endfunc ; The recip(0) ensures that "no result" due to no zold or zolder ; returns a value outside the threshold
float func Iterate(complex pz) float r = recip(0) ; m_Iterations = m_Iterations + 1 not used in this trapshape m_LastZ = pz if @type=="Original" && m_zolderok r = atan2((pz - m_zold)/(m_zold - m_zolder)) elseif @type=="One Centre" && m_zoldok r = atan2((pz - @centre1)/(m_zold - @centre1)) elseif @type=="Two Centres" && m_zoldok r = atan2((pz - @centre1)/(m_zold - @centre2)) elseif @type=="Centre Offsets" && m_zolderok r = atan2((pz - m_zold - @centre1)/(m_zold - m_zolder - @centre2)) endif if r<1e100 if @method=="Absolute Angles" r = 2.0*abs(r) elseif @method=="All Angles #1" r = abs(#pi + r) elseif @method=="All Angles #2" if r<0 r = r + 2.0*#pi endif endif if @usesine r = 0.5*abs(1.0 + sin(r)) else r = r/(2.0*#pi) endif endif m_zolder = m_zold m_zold = pz m_zolderok = m_zoldok m_zoldok = true return r endfunc default: title = "Curvature" heading text = "Intended for use with 'MMF Smooth Orbit Traps (Gradient)' or \ similar smoothing formulas since smoothing is often required." endheading int param type caption = "Curvature Type" enum = "Original" "One Centre" "Two Centres" "Centre Offsets" default = 0 endparam complex param centre1 caption = "Centre 1" default = (0,0) visible = @type>0 endparam complex param centre2 caption = "Centre 2" default = (0,0) visible = @type>1 endparam int param method caption = "Angle method" enum = "Absolute Angles" "All Angles #1" "All Angles #2" "Raw Angles" default = 0 endparam bool param usesine caption = "Use Sine" default = false hint = "When enabled the sine of the angle is taken." endparam } class MMF_TrapShapeInterpolation(MMF_TrapShapeZold) { ; ; Based on the interpolation methods in mmf3.ucl Orbitals+.
; public: import "common.ulb" func MMF_TrapShapeInterpolation(Generic pparent) MMF_TrapShapeZold.MMF_TrapShapeZold(pparent) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this trapshape m_LastZ = m_zold = m_zolder = pz m_zoldok = m_zolderok = m_gotold = false endfunc ; The recip(0) ensures that "no result" due to no zold or zolder ; returns a value outside the threshold
float func Iterate(complex pz) complex zt = (0,0) complex a = (0,0) complex b = (0,0) float r = recip(0.0) float t = 0.0 bool gotz = false ; m_Iterations = m_Iterations + 1 not used in this trapshape m_LastZ = pz if (@usevar=="Predict1" || @usevar=="Predict2") \ && m_gotold && m_zoldok if @usevar=="Predict1" zt = m_oa*m_zold^@pwr1 + m_ob*m_zold^@pwr2 else zt = m_oa*m_zold^@pwr1 + @valb*m_zold^@pwr2 endif gotz = true endif m_gotold = false if @usevar=="Just a" || @usevar=="Just b" || @usevar=="Combined" \ || @usevar=="Predict1" if m_zolderok if @pwr1!=(0,0) if @pwr2!=(0,0) a = m_zold^@pwr1*m_zolder^@pwr2 - m_zolder^@pwr1*m_zold^@pwr2 else a = m_zold^@pwr1 - m_zolder^@pwr1 endif elseif @pwr2!=(0,0) a = m_zolder^@pwr2 - m_zold^@pwr2 endif m_gotold = true endif elseif m_zoldok if @pwr1!=(0,0) a = m_zold^@pwr1 else a = 1.0 endif m_gotold = true endif if m_gotold if @usevar=="Just a" || @usevar=="Just b" || @usevar=="Combined" \ || @usevar=="Predict1" a = 1.0/a if @pwr1!=(0,0) if @pwr2!=(0,0) if @usevar!="Just a" b = (m_zold^(@pwr1+1.0) - pz*m_zolder^@pwr1)*a endif if @usevar!="Just b" a = (pz*m_zolder^@pwr2 - m_zold^(@pwr2+1.0))*a endif else if @usevar!="Just a" b = (m_zold^(@pwr1+1.0) - pz*m_zolder^@pwr1)*a endif if @usevar!="Just b" a = (pz - m_zold)*a endif endif elseif @pwr2!=(0,0) if @usevar!="Just a" b = (m_zold - pz)*a endif if @usevar!="Just b" a = (pz*m_zolder^@pwr2 - m_zold^(@pwr2+1.0))*a endif endif elseif @pwr2!=(0,0) a = (pz - @valb*m_zold^@pwr2)/a else a = (pz - @valb)/a endif if @usevar=="Predict1" || @usevar=="Predict2" m_oa = a m_ob = b endif endif if ((@usevar=="Just a" || @usevar=="Just b" || @usevar=="Combined" \ || @usevar=="Fixed b") && m_gotold) || ((@usevar=="Predict1" \ || @usevar=="Predict2") && gotz) if @usevar=="Predict1" || @usevar=="Predict2" a = zt if @trapz a = pz - zt endif endif if @usevar!="Just b" if @fna==1 a = log(a) elseif @fna==2 a = sin(a) elseif @fna==3 a = cos(a) elseif @fna==4 a = tan(a) elseif @fna==5 a = sinh(a) elseif @fna==6 a = cosh(a) elseif @fna==7 a = tanh(a) elseif @fna==8 a = exp(a) elseif @fna==9 a = sqrt(a) elseif @fna==10 a = a^(1.0/3.0) elseif @fna==11 a = a*a elseif @fna==12 a = a^3.0 endif if @trap=="Magnitude" r = cabs(a) elseif @trap=="Real" r = abs(real(a)) elseif @trap=="Imaginary" r = abs(imag(a)) elseif @trap=="Angle" r = atan2(a) if @angle=="Absolute" r = 2.0*abs(r) elseif @angle=="All Angles 1" if r<0.0 r = 2.0*#pi + r endif elseif @angle=="All Angles 2" r = abs(#pi + r) endif if @usesin r = abs(1.0 + sin(r)) else r = r/(2.0*#pi) endif endif endif if @usevar=="Just b" || @usevar=="Combined" if @fnb==1 b = log(b) elseif @fnb==2 b = sin(b) elseif @fnb==3 b = cos(b) elseif @fnb==4 b = tan(b) elseif @fnb==5 b = sinh(b) elseif @fnb==6 b = cosh(b) elseif @fnb==7 b = tanh(b) elseif @fnb==8 b = exp(b) elseif @fnb==9 b = sqrt(b) elseif @fnb==10 b = b^(1.0/3.0) elseif @fnb==11 b = b*b elseif @fnb==12 b = b^3.0 endif if @trap=="Magnitude" t = cabs(b) elseif @trap=="Real" t = abs(real(b)) elseif @trap=="Imaginary" t = abs(imag(b)) elseif @trap=="Angle" t = atan2(b) if @angle=="Absolute" t = 2.0*abs(t) elseif @angle=="All Angles 1" if t<0.0 t = 2.0*#pi + t endif elseif @angle=="All Angles 2" t = abs(#pi + t) endif if @usesin t = abs(1.0 + sin(t)) else t = t/(2.0*#pi) endif endif if @usevar=="Just b" r = t elseif @mix=="Minimum" && tr r = t elseif @mix=="Mix %age" r = (0.01*@percent)*r + (1.0 - 0.01*@percent)*t endif endif endif m_zolder = m_zold m_zold = pz m_zolderok = m_zoldok m_zoldok = true return r endfunc func IterateSilent() m_zoldok = m_zolderok = m_gotold = false ; m_Iterations = m_Iterations + 1 not used in this trapshape endfunc func IterateSilentZold(complex pz) m_zolder = m_zold m_zold = pz m_gotold = false m_zolderok = m_zoldok m_zoldok = true ; m_Iterations = m_Iterations + 1 not used in this trapshape endfunc private: complex m_oa complex m_ob bool m_gotold default: title = "Interpolation Constants" heading text = "This method allows you to trap the interpolation \ constants a and/or b in a*z^n1 + b*z^n2. It is \ intended for use with 'MMF Smooth Orbit Traps (Gradient)' or \ similar smoothing formulas since smoothing is often required." endheading complex param pwr1 caption = "Power 1" default = (2,0) hint = "n1 in 'a*z^n1 + b*z^n2'. Note that if it is (0,0) then the \ interpolation formula becomes 'a + b*z^n2'." endparam complex param pwr2 caption = "Power 2" default = (1,0) hint = "n2 in 'a*z^n1 + b*z^n2'. Note that if it is (0,0) then the \ interpolation formula becomes 'a*z^n1 + b'." endparam int param usevar caption = "Variable/s to use" enum = "Just a" "Just b" "Combined" "Fixed b" "Predict1" "Predict2" default = 0 hint = " \ 'Combined' calculates values using a and b separately and then \ allows you to set the final value by combining the two \ separate values. 'Fixed b' allows you to specify a fixed value \ for b in a*z^n1 + b*z^n2 and colours based on a. \ Predict1 calculates both a and b and uses the values from \ the previous iteration to interpolate z and traps the \ interpolated value. Predict2 is the same \ as Predict1 but uses the 'Fixed b' interpolation method." endparam bool param trapz caption = "Trap z ?" default = false hint = "Normally just the interpolated value is used for \ 'Predict1' and 'Predict2' but you can choose to trap \ the actual z value to the predicted z value instead." visible = @usevar>3 endparam complex param valb caption = "Value of b" default = (0,0) visible = @usevar==3 || @usevar==5 endparam int param mix caption = "Colour mixing" enum = "Minimum" "Maximum" "Mix %age" default = 0 visible = @usevar==2 endparam float param percent caption = "Mix %age" default = 50.0 hint = "100% uses the value from a only, 0% uses the value from b only." visible = @usevar==2 && @mix==2 endparam int param fna caption = "Function for a (or interpolated z)" enum = "Ident" "Log" "Sin" "Cos" "Tan" "Sinh" "Cosh" "Tanh" "Exp" \ "Sqrt" "Cubert" "Square" "Cube" default = 0 hint = "Applied to the calculated value of a or the interpolated \ z value before use in any trapping or colouring." visible = @usevar!=1 endparam int param fnb caption = "Function for b" enum = "Ident" "Log" "Sin" "Cos" "Tan" "Sinh" "Cosh" "Tanh" "Exp" \ "Sqrt" "Cubert" "Square" "Cube" default = 0 hint = "Applied to the calculated value of b before use in any \ trapping or colouring." visible = @usevar>0 && @usevar<3 endparam int param trap caption = "Value to trap" enum = "Magnitude" "Real" "Imaginary" "Angle" default = 0 endparam int param angle caption = "Angle method" enum = "Absolute" "All Angles 1" "All Angles 2" default = 0 visible = @trap==3 endparam bool param usesin caption = "Take the sine of the angle" default = false visible = @trap==3 endparam } class MMF_TrapShapeCentreOfCurvature(MMF_TrapShapeZold) { ; Based on the original "curvature" by Luke Plant.
public: import "common.ulb" func MMF_TrapShapeCentreOfCurvature(Generic pparent) MMF_TrapShapeZold.MMF_TrapShapeZold(pparent) endfunc ; The recip(0) ensures that "no result" due to no zold or zolder ; returns a value outside the threshold
float func Iterate(complex pz) float r = recip(0) ; m_Iterations = m_Iterations + 1 not used in this trapshape m_LastZ = pz if m_zoldok float x2m1 = real(m_zold) - real(pz) float y2m1 = imag(m_zold) - imag(pz) float x3m1 = real(m_zolder) - real(pz) float y3m1 = imag(m_zolder) - imag(pz) float x2y2s = x2m1*(real(m_zold) + real(pz)) \ + y2m1*(imag(m_zold) + imag(pz)) float x3y3s = x3m1*(real(m_zolder) + real(pz)) \ + y3m1*(imag(m_zolder) + imag(pz)) float d = 2.0*(x2m1*y3m1-x3m1*y2m1) complex c = y3m1*x2y2s - y2m1*x3y3s + flip(x2m1*x3y3s - x3m1*x2y2s) if abs(d)<1e-5 if abs(d)*1e1003 endparam bool param p_scale caption = "Divide by magnitude" default = false hint = "May help if some areas get too busy." endparam bool param p_loglog caption = "Apply log(log(" default = true hint = "Avoids the coluring becoming too varied." endparam } class MMF_TrapShapeTriangleInequality(common.ulb:TrapShape) { ; Based on Triangle Inequality by Damien Jones.
public: import "common.ulb" func MMF_TrapShapeTriangleInequality(Generic pparent) TrapShape.TrapShape(pparent) tcentre = @p_tcentre fAC = cabs(@p_tcentre) endfunc ;

Here note the search loop to find a parent that is a Coloring object ; in order to get the ppixel value
; @param pz the z value func Init(complex pz) TrapShape.Init(pz) if @p_usepixel Generic obj = Generic(GetParent()) if obj repeat if Coloring(obj) tcentre = Coloring(obj).GetPixel() + @p_tcentre obj = 0 else obj = Generic(obj.GetParent()) if obj==0 tcentre = pz + @p_tcentre endif endif until obj==0 else tcentre = pz + @p_tcentre endif fAC = cabs(tcentre) endif endfunc float func Iterate(complex pz) TrapShape.Iterate(pz) float az2 = cabs(pz - tcentre) float lowbound = abs(az2 - fAC) if abs(az2 = az2 + fAC - lowbound)>1e-100 return (cabs(pz) - lowbound) / az2 else return (cabs(pz) - lowbound)*1e100 endif endfunc private: complex tcentre float fAC default: title = "Triangle Inequality" heading text = "Intended for use with 'MMF Smooth Orbit Traps (Gradient)' or \ similar smoothing formulas since smoothing is usually required." endheading bool param p_usepixel caption = "Use Location/Initial Z ?" default = true hint = "The original Triangle Inequality Average used #pixel as the \ base point, enabling this option normally replicates that. \ However in some cases the location value equivalent to #pixel \ may not be available and in such cases when this option is \ enabled then the start z value will be used instead i.e. if \ used with Julia formulas the location value will be used \ since start z is the location in a Julia formula but when \ used with Mandelbrot formulas the start z is not the location." endparam complex param p_tcentre caption = "Base Point or Offset" default = (1,0) hint = "If you choose to use initial z as the base point then this value \ is applied as an offset, otherwise it's used as the actual \ base point value. Note that to closely replicate standard \ Triangle Inequality Average colouring on a Julia Set then have \ 'Use Initial z ?' enabled, set 'Base Point or Offset' to (0,0) \ and use 'Smooth Average' from mmf.ulb as the Trap Mode." endparam } class MMF_TrapShapeFnz(common.ulb:TrapShape) { ; Simple functions of z converted to floats.
public: import "common.ulb" func MMF_TrapShapeFnz(Generic pparent) TrapShape.TrapShape(pparent) endfunc float func Iterate(complex pz) TrapShape.Iterate(pz) if @mode=="real(fn(z))" return real(@fn(pz)) elseif @mode=="abs(real(fn(z)))" return abs(real(@fn(pz))) elseif @mode=="imag(fn(z))" return imag(@fn(pz)) elseif @mode=="abs(imag(fn(z)))" return abs(imag(@fn(pz))) else;if @mode=="cabs(fn(z))" return cabs(@fn(pz)) endif endfunc default: title = "Functions" heading text = "Intended for use with 'MMF Smooth Orbit Traps (Gradient)' or \ similar smoothing formulas since smoothing is usually required." endheading func fn caption = "Function to use" default = sqrt() endfunc int param mode caption = "Method" enum = "real(fn(z))" "abs(real(fn(z)))" "imag(fn(z))" \ "abs(imag(fn(z)))" "cabs(fn(z))" default = 0 hint = "Original inspired by the idea of trapping the values of \ atan2(z)." endparam } class MMF_TrapShapeAngle(common.ulb:TrapShape) { ; Trapping values based on the angle of z.
public: import "common.ulb" func MMF_TrapShapeAngle(Generic pparent) TrapShape.TrapShape(pparent) endfunc float func Iterate(complex pz) TrapShape.Iterate(pz + @offset) if @mode=="Raw Angles" return atan2(pz + @offset) elseif @mode=="Absolute Angles" return abs(atan2(pz + @offset)) elseif @mode=="All Angles" return #pi + atan2(pz + @offset) elseif @mode=="Cosines" return cos(0.5*atan2(pz + @offset)) else;if @mode=="All Angles 2" float r = atan2(pz + @offset) if r<0.0 r = r + 2.0*#pi endif return r endif endfunc default: title = "Angles (of z)" heading text = "Intended for use with 'MMF Smooth Orbit Traps (Gradient)' or \ similar smoothing formulas since smoothing is usually required." endheading int param mode caption = "Method" enum = "Raw Angles" "Absolute Angles" "All Angles" "Cosines" \ "All Angles 2" default = 3 hint = "Inspired by Cilia mode colouring." endparam complex param offset caption = "Z Offset" default = (0,0) hint = "Offsets the z value by this amount - good for animation." endparam } class MMF_TrapModeIteration(Standard.ulb:Standard_TrapModeBase) { public: func Iterate(complex pz, complex pzt, float pdistance, float ptexture) Standard_TrapModeBase.Iterate(pz, pzt, pdistance, ptexture) if m_Iterations == @p_iter m_Solid = false SetTrapInfo(0, pz, pzt, pdistance) m_Textures[0] = ptexture endif endfunc default: title = "Given Iteration" int param p_iter caption = "Iteration to trap" default = 10 min = 1 hint = "Note that areas which did not reach this iteration count will \ be marked as 'solid'." endparam } class MMF_TrapColoring(common.ulb:TrapColoring) { ; Some extensions to the standard trap colouring.
public: import "common.ulb" ;

; @param pparent the parent, generally "this" for the parent, or zero
func MMF_TrapColoring(Generic pparent) TrapColoring.TrapColoring(pparent) m_ColorTransfer = new @f_colortransfer(this) m_TextureTransfer = new @f_texturetransfer(this) m_ColorTransfer.Init(0) m_TextureTransfer.Init(0) m_TextureFlag = true if @colourby>7 m_Image = new @f_image(this) endif if @colourby=="Image All" m_Merge = new @f_merge(this) if @adjustlayer m_Adjust = new @f_adjust(this) endif endif endfunc ;

; @return the colouring value for the trap
float func Result(TrapMode ptrapmode) complex v = (0,0) float f = 0.0 if @colourby=="Distance" f = ptrapmode.GetDistance(0) elseif @colourby=="Iteration" f = 0.05*ptrapmode.GetIteration(0) else if @usetrap=="Original Z value" v = ptrapmode.GetUntransformedPoint(0) elseif @usetrap=="Trapped Z value" v = ptrapmode.GetTransformedPoint(0) endif if @colourby=="Angle" || @colourby=="Sine" if (f = atan2(v))<0.0 f = 2.0*#pi + f endif if @colourby=="Angle" f = f/(2.0*#pi) else f = abs(1.0 + sin(f)) endif elseif @colourby=="Magnitude" f = cabs(v) elseif @colourby=="Real" f = real(v) elseif @colourby=="Imaginary" f = imag(v) elseif @colourby!="Texture Only" color clr = m_Image.GetColor(v) if @colourby=="Image All" f = 0.299*red(clr) + 0.587*green(clr) + 0.114*blue(clr) elseif @colourby=="Image Red" f = red(clr) elseif @colourby=="Image Green" f = green(clr) elseif @colourby=="Image Blue" f = blue(clr) elseif @colourby=="Image Alpha" f = alpha(clr) elseif @colourby=="Image Hue" f = hue(clr)/6.0 elseif @colourby=="Image Saturation" f = sat(clr) elseif @colourby=="Image Luminance" f = lum(clr) endif endif endif if @colourby!="Texture Only" && m_TextureFlag return m_ColorTransfer.Iterate(f) \ + m_TextureTransfer.Iterate(ptrapmode.GetTexture(0)) elseif m_TextureFlag return m_TextureTransfer.Iterate(ptrapmode.GetTexture(0)) else return m_ColorTransfer.Iterate(f) endif endfunc ;

; @return flag for using "image all"
bool func UseColor() if @colourby=="Image All" return true endif return false endfunc ;

; @param ptrapmode the trapmode
; @return texture value
float func ResultTexture(TrapMode ptrapmode) return m_TextureTransfer.Iterate(ptrapmode.GetTexture(0)) endfunc ;

; @param ptrapmode the trapmode
; @return the colour
color func ResultColor(TrapMode ptrapmode) complex v if @usetrap=="Original Z value" v = ptrapmode.GetUntransformedPoint(0) else;if @usetrap=="Trapped Z value" v = ptrapmode.GetTransformedPoint(0) endif return m_Image.GetColor(v) endfunc ;

; @param clr image colour
; @param tex texture index
; @return merged colour
color func MergeResult(color clr, float tex) if @adjustlayer if m_TextureFlag clr = m_Merge.GradientMerge(clr, tex) endif color c = @f_adjustcolour if @adjusttype==0 c = RGB(@adjred, @adjgreen, @adjblue) endif c = compose(clr, m_Adjust.Merge(clr, c), @f_opacity) return RGBA(red(c), green(c), blue(c), alpha(clr)) endif if m_TextureFlag return m_Merge.GradientMerge(clr, tex) endif return clr endfunc ; @param flag indicates whether texturing is used or not
func SetTextureFlag(bool flag) m_TextureFlag = flag endfunc protected: Transfer m_ColorTransfer Transfer m_TextureTransfer ImageWrapper m_Image GradientLayer m_Merge ColorMerge m_Adjust BOOL m_TextureFlag default: title = "MMF Colour Selector" int param v_mmf_trapcoloring caption = "Version (MMF_TrapColoring)" default = 100 hint = "This version parameter is used to detect when a change \ has been made to the formula that is incompatible with \ the previous version. When that happens, this field will \ reflect the old version number to alert you to the fact \ that an alternate rendering is being used." visible = @v_mmf_trapcoloring < 100 endparam int param colourby caption = "Colour By" enum = "Distance" "Iteration" "Angle" "Magnitude" "Real" "Imaginary" \ "Sine" "Texture Only" "Image All""Image Red" "Image Green" \ "Image Blue" "Image Alpha" "Image Hue" "Image Saturation" \ "Image Luminance" default = 0 hint = "Note that 'Texture Only' will only produce colouring if \ you're using a texture other than dmj5->Flat Texture. \ 'Image All' maps the image brightness (Yiq) to UF's gradient \ if the colouring is being used as a gradient colouring or uses \ the image colours if the colouring is being used as a direct \ colouring. 'Image Red' maps the image red to a gradient, \ 'Image Green' the green, 'Image Blue' the blue, 'Image Hue' \ the hue, 'Image Saturation' the saturation and 'Image Luminance' \ the luminance." endparam ImageWrapper param f_image caption = "Image Object" default = MMF_ImageImport hint = "This is the image object to use for your trap colouring." visible = @colourby>7 endparam int param usetrap caption = "Z value" enum = "Original Z value" "Trapped Z value" default = 0 hint = "When using 'Angle' as the value to colour by 'Original \ Z value' gives 'Angle' or 'Angle of Z' and 'Trapped \ Z value' gives 'Angle to Trap'." visible = @colourby>1 endparam Transfer param f_colortransfer caption = "Colour Transfer" default = NullTransfer hint = "Allows you to manipulate the colour value from the trap \ before combining with any texture. Does not apply to 'Image All' \ if the main colouring is in direct mode." visible = @colourby!=7 endparam Transfer param f_texturetransfer caption = "Texture Transfer" default = NullTransfer hint = "Allows you to manipulate any texture value before \ combining with the colour value from the trap." endparam GradientLayer param f_merge caption = "Texture/Iteration Merge" default = MMF_GradientLayer hint = "Only used if the main colouring is being used in direct colouring \ mode and texturing and/or adding the smooth iteration count \ is/are in use. Use to merge the texture/iteration value with the \ image. Note that the gradient you choose controls the colour of \ the texture/iteration layer which is normally treated as the top \ layer." visible = @colourby=="Image All" expanded = false endparam bool param adjustlayer caption = "Add Adjust layer" default = false hint = "Allows you to add an adjustment layer in a given colour to merge \ on top of the image/texture. Only active if the main colouring \ is in direct mode." visible = @colourby=="Image All" endparam int param adjusttype caption = "Colour or RGB" enum = "RGB values" "Colour Parameter" default = 1 hint = "This option is specifically added so that if you choose \ 'RGB values' you can 'explore' them and see changes to the image \ as you change the RGB. The option may become redundant in a \ future version of UF." visible = @colourby=="Image All" && @adjustlayer endparam float param adjred caption = "Red Value" default = 1.0 hint = "The red part of the adjust colour (0 to 1)." visible = @colourby=="Image All" && @adjustlayer && @adjusttype==0 endparam float param adjgreen caption = "Green Value" default = 1.0 hint = "The green part of the adjust colour (0 to 1)." visible = @colourby=="Image All" && @adjustlayer && @adjusttype==0 endparam float param adjblue caption = "Blue Value" default = 1.0 hint = "The blue part of the adjust colour (0 to 1)." visible = @colourby=="Image All" && @adjustlayer && @adjusttype==0 endparam color param f_adjustcolour caption = "Adjust Layer Colour" default = RGB(1,1,1) hint = "Allows you to apply overall adjustments to your colouring." visible = @colourby=="Image All" && @adjustlayer && @adjusttype==1 endparam ColorMerge param f_adjust caption = "Adjustment Layer Merge" default = MMF_ExtendedColorMerge visible = @colourby=="Image All" && @adjustlayer endparam float param f_opacity caption = "Adjustment Opacity" default = 1.0 hint = "Use to modify the adjustment opacity, the normal range is from \ 0 to 1." visible = @colourby=="Image All" && @adjustlayer endparam } class MMF_TrapTransfer(common.ulb:Transfer) { ; ; This transfer method is based on the original UF gradient transfer ; but with added options.
; David Makin, May 2008
public: ; @param pparent the parent, generally "this" for the parent, or zero func MMF_TrapTransfer(Generic pparent) Transfer.Transfer(pparent) endfunc ; @param pr the float value to manipulate ; @return the manipulated value float func Iterate(float pr) float x = @p_offset1 + (pr + @p_offset0) * @p_zscale0 if @p_forcepos && x<0.0 x = abs(x) endif if x<0.0 x = 0.0 else if (@p_xfer == "Sqr") x = 2.0*sqr(x) elseif (@p_xfer == "Sqrt") x = 0.5*sqrt(x) elseif (@p_xfer == "Cube") x = 3.0*x^3.0 elseif (@p_xfer == "CubeRoot") x = (x^(1.0/3.0))/3.0 elseif (@p_xfer == "Log") x = log(1.0 + x) elseif (@p_xfer == "Exp") if (x >= 100.0) x = exp(100.0) else x = exp(x) endif elseif (@p_xfer == "Sin") x = abs(sin(x)) elseif (@p_xfer == "ArcTan") x = abs(atan(x)) elseif (@p_xfer == "Cos") x = 1.0 + cos(x) elseif (@p_xfer == "LogTan") x = log(1.0 + abs(tan(x))) elseif (@p_xfer == "LogLog") x = log(1.0 + log(1.0 + x)) elseif (@p_xfer == "InvArcTan") x = 0.0005*((2.0*#pi/atan(x))^@p_iatpower - 1.0) elseif (@p_xfer == "Power") x = x^@p_power endif endif return @p_offset3 + (x + @p_offset2) * @p_zscale1 endfunc default: title = "Trap/Gradient Transfer" int param v_mmf_traptransfer caption = "Version (MMF_TrapTransfer)" default = 100 hint = "This version parameter is used to detect when a change has been made to the formula that is incompatible with the previous version. When that happens, this field will reflect the old version number to alert you to the fact that an alternate rendering is being used." visible = @v_mmf_traptransfer < 100 endparam float param p_offset0 caption = "Initial Pre-Offset" default = 0.0 hint = "Applied prior to the pre-scale." endparam float param p_zscale0 caption = "Pre-Scale" default = 1.0 exponential = true hint = "Applied prior to the 'Transfer Function'." endparam float param p_offset1 caption = "Final Pre-Offset" default = 0.0 hint = "Applied after the pre-scale but before the 'Transfer \ Function'." endparam bool param p_forcepos caption = "Force positive" default = false hint = "When enabled the value passed to the transfer function is made \ positive using abs(). If disabled then negative values are made \ zero and the transfer function is skipped." endparam int param p_xfer caption = "Transfer Function" default = 0 enum = "Linear" "Sqr" "Sqrt" "Cube" "CubeRoot" "Log" "Exp" "Sin" \ "ArcTan" "Cos" "LogTan" "LogLog" "InvArcTan" "Power" hint = "This function will be applied to the value. 'InvArcTan' is \ specifically designed to produce evenly spread smooth \ iteration colouring - use the power adjust to compensate \ for different bailout values." endparam float param p_iatpower caption = "Power adjust (for InvArcTan)" default = 2.0 hint = "For when adjusting smooth iteration colouring, this power \ adjust allows you to compensate for different bailout values, \ the larger the bailout, the larger you'll need to make the \ power value e.g. around 2 for a bailout of 128 or around 3.5 \ for a bailout of 65536." visible = @p_xfer==12 endparam float param p_power caption = "Power" default = 4.0 visible = @p_xfer==13 endparam float param p_offset2 caption = "Initial Post-Offset" default = 0.0 hint = "Applied prior to the post-scale." endparam float param p_zscale1 caption = "Post-Scale" default = 1.0 exponential = true hint = "Applied after the 'Transfer Function'." endparam float param p_offset3 caption = "Final Post-Offset" default = 0.0 hint = "The final offset." endparam } class MMF_TransferMerge(common.ulb:Transfer) { ; Allows the combination of multiple transfer options public: ; @param pparent the parent, generally "this" for the parent, or zero func MMF_TransferMerge(Generic pparent) Transfer.Transfer(pparent) m_transfer[0] = new @transfer0(pparent) m_transfer[1] = new @transfer1(pparent) if @numtrans>0 m_transfer[2] = new @transfer2(pparent) if @numtrans>1 m_transfer[3] = new @transfer3(pparent) if @numtrans>2 m_transfer[4] = new @transfer4(pparent) if @numtrans>3 m_transfer[5] = new @transfer5(pparent) if @numtrans>4 m_transfer[6] = new @transfer6(pparent) if @numtrans>5 m_transfer[7] = new @transfer7(pparent) if @numtrans>6 m_transfer[8] = new @transfer8(pparent) if @numtrans>7 m_transfer[9] = new @transfer9(pparent) endif endif endif endif endif endif endif endif endfunc ; @param pz complex to initialise func Init(complex pz) int i = 1 m_transfer[0].Init(pz) m_transfer[1].Init(pz) while (i=i+1)<@numtrans+2 m_transfer[i].Init(pz) endwhile endfunc ; @param pr the float value to manipulate ; @return the manipulated value float func Iterate(float pr) int i = 1 pr = m_transfer[1].Iterate(m_transfer[0].Iterate(pr)) while (i=i+1)<@numtrans+2 pr = m_transfer[i].Iterate(pr) endwhile return pr endfunc func IterateSilent() int i = 1 m_transfer[0].IterateSilent() m_transfer[1].IterateSilent() while (i=i+1)<@numtrans+2 m_transfer[i].IterateSilent() endwhile endfunc protected: Transfer m_transfer[10] default: title = "MMF Transfer Merge" int param v_mmftransfermerge caption = "Version (MMF Transfer Merge)" default = 100 hint = "This version parameter is used to detect when a change has been \ made to the formula that is incompatible with the previous \ version. When that happens, this field will reflect the old \ version number to alert you to the fact that an alternate \ rendering is being used." visible = @v_mmftransfermerge < 100 endparam int param numtrans caption = "Number of Transfers" enum = "2" "3" "4" "5" "6" "7" "8" "9" "10" default = 0 endparam Transfer param transfer0 caption = "1st Transfer" default = NullTransfer endparam Transfer param transfer1 caption = "2nd Transfer" default = NullTransfer endparam Transfer param transfer2 caption = "3rd Transfer" default = NullTransfer visible = @numtrans>0 endparam Transfer param transfer3 caption = "4th Transfer" default = NullTransfer visible = @numtrans>1 endparam Transfer param transfer4 caption = "5th Transfer" default = NullTransfer visible = @numtrans>2 endparam Transfer param transfer5 caption = "6th Transfer" default = NullTransfer visible = @numtrans>3 endparam Transfer param transfer6 caption = "7th Transfer" default = NullTransfer visible = @numtrans>4 endparam Transfer param transfer7 caption = "8th Transfer" default = NullTransfer visible = @numtrans>5 endparam Transfer param transfer8 caption = "9th Transfer" default = NullTransfer visible = @numtrans>6 endparam Transfer param transfer9 caption = "10th Transfer" default = NullTransfer visible = @numtrans>7 endparam } class MMF_AltfBm(common.ulb:Generic) { ; This is an fBm texture class. It simply has an an init for the ; internal texturing variable set-up and a function to return the ; texture value (float) for a given complex value.
public: ; @param pparent the parent, generally "this" for the parent, or zero func MMF_AltfBm(Generic pparent) Generic.Generic(pparent) endfunc ; Initialisation of the texture variables.

; This is designed to be called once per change of texture, so normally ; just once say in a global section or in a constructor but it could be ; recalled if initiators were included in the class that could be set up ; in the constructor and modified later - allowing reconfiguration of the fBm. ;

The initialisation is done here (in it's own function) instead of in the ; constructor mainly so that it's possible to avoid the init when texturing ; is disabled at run time e.g.
; if @fBm
; GlobalInit(value)
; endif

; Here pz is actually unused but is included in case derived functions ; want to initiate based on an external value.
; @param pz a complex value for initialisation of the fBm func GlobalInit(complex pz) float d=#pi/180.0 ; for conversion to radians float c=4096.0*@rs ; overall frequency ; fBm level 1 float ang=@ang0*d ; convert rotation to rads ; q[level,0] and q[level,1] are the scaling factors for the ; x+y and x-y arrays, the "correct" value should be the same ; for both (ie. 1/sqrt(2)) but to increase variation the ; values used are in the neighbourhood of 0.7071, being n/8192 ; where n is a prime number. q[0,0]=5471.0/8192.0 q[0,1]=6143.0/8192.0 ; The rotation values q[0,2]=cos(ang) q[0,3]=sin(ang) ; Combine the overall sharpness and frequency with the ; sharpness and frequency for this level. q[0,4]=@frac0*@frac q[0,5]=c*@rs0 ; Put the amplitude in the array so it can be indexed q[0,6]=@amp0 ; Put the enabled flag in an array so it can be indexed f[0]=@flag0 ; fBm level 2 (Note slightly different values q[1,0] and q[1,1]) ang=@ang1*d q[1,0]=6079.0/8192.0 q[1,1]=5521.0/8192.0 q[1,2]=cos(ang) q[1,3]=sin(ang) q[1,4]=@frac1*@frac q[1,5]=c*@rs1 q[1,6]=@amp1 f[1]=@flag1 ; fBm level 3 ang=@ang2*d q[2,0]=5501.0/8192.0 q[2,1]=6113.0/8192.0 q[2,2]=cos(ang) q[2,3]=sin(ang) q[2,4]=@frac2*@frac q[2,5]=c*@rs2 q[2,6]=@amp2 f[2]=@flag2 ; fBm level 4 ang=@ang3*d q[3,0]=6047.0/8192.0 q[3,1]=5563.0/8192.0 q[3,2]=cos(ang) q[3,3]=sin(ang) q[3,4]=@frac3*@frac q[3,5]=c*@rs3 q[3,6]=@amp3 f[3]=@flag3 ; fBm level 5 ang=@ang4*d q[4,0]=5507.0/8192.0 q[4,1]=6091.0/8192.0 q[4,2]=cos(ang) q[4,3]=sin(ang) q[4,4]=@frac4*@frac q[4,5]=c*@rs4 q[4,6]=@amp4 f[4]=@flag4 ; fBm level 6 ang=@ang5*d q[5,0]=6037.0/8192.0 q[5,1]=5573.0/8192.0 q[5,2]=cos(ang) q[5,3]=sin(ang) q[5,4]=@frac5*@frac q[5,5]=c*@rs5 q[5,6]=@amp5 f[5]=@flag5 ; fBm level 7 ang=@ang6*d q[6,0]=5531.0/8192.0 q[6,1]=6067.0/8192.0 q[6,2]=cos(ang) q[6,3]=sin(ang) q[6,4]=@frac6*@frac q[6,5]=c*@rs6 q[6,6]=@amp6 f[6]=@flag6 ; fBm level 8 ang=@ang7*d q[7,0]=6131.0/8192.0 q[7,1]=5479.0/8192.0 q[7,2]=cos(ang) q[7,3]=sin(ang) q[7,4]=@frac7*@frac q[7,5]=c*@rs7 q[7,6]=@amp7 f[7]=@flag7 ; fBm level 9 ang=@ang8*d q[8,0]=5503.0/8192.0 q[8,1]=6101.0/8192.0 q[8,2]=cos(ang) q[8,3]=sin(ang) q[8,4]=@frac8*@frac q[8,5]=c*@rs8 q[8,6]=@amp8 f[8]=@flag8 ; fBm level 10 ang=@ang9*d q[9,0]=6133.0/8192.0 q[9,1]=5477.0/8192.0 q[9,2]=cos(ang) q[9,3]=sin(ang) q[9,4]=@frac9*@frac q[9,5]=c*@rs9 q[9,6]=@amp9 f[9]=@flag9 ; fBm level 11 ang=@ang10*d q[10,0]=5557.0/8192.0 q[10,1]=6053.0/8192.0 q[10,2]=cos(ang) q[10,3]=sin(ang) q[10,4]=@frac10*@frac q[10,5]=c*@rs10 q[10,6]=@amp10 f[10]=@flag10 ; fBm level 12 ang=@ang11*d q[11,0]=6029.0/8192.0 q[11,1]=5581.0/8192.0 q[11,2]=cos(ang) q[11,3]=sin(ang) q[11,4]=@frac11*@frac q[11,5]=c*@rs11 q[11,6]=@amp11 f[11]=@flag11 ; fBm level 13 ang=@ang12*d q[12,0]=5527.0/8192.0 q[12,1]=6073.0/8192.0 q[12,2]=cos(ang) q[12,3]=sin(ang) q[12,4]=@frac12*@frac q[12,5]=c*@rs12 q[12,6]=@amp12 f[12]=@flag12 ; fBm level 14 ang=@ang13*d q[13,0]=6121.0/8192.0 q[13,1]=5483.0/8192.0 q[13,2]=cos(ang) q[13,3]=sin(ang) q[13,4]=@frac13*@frac q[13,5]=c*@rs13 q[13,6]=@amp13 f[13]=@flag13 ; fBm level 15 ang=@ang14*d q[14,0]=5569.0/8192.0 q[14,1]=6043.0/8192.0 q[14,2]=cos(ang) q[14,3]=sin(ang) q[14,4]=@frac14*@frac q[14,5]=c*@rs14 q[14,6]=@amp14 f[14]=@flag14 ; fBm level 16 ang=@ang15*d q[15,0]=6089.0/8192.0 q[15,1]=5519.0/8192.0 q[15,2]=cos(ang) q[15,3]=sin(ang) q[15,4]=@frac15*@frac q[15,5]=c*@rs15 q[15,6]=@amp15 f[15]=@flag15 ; Now initialise the height arrays ready for fBm creation. int r=@seed ; initialise the random variable float r1=r int l=0 ; level count int step=16384 ; initially assume all fBm while l<@levels int i=0 while i<4 h[l,i,0]=0 ; set entry 0 to 0 h[l,i,16384]=0 ; and entry 16384 ; If using Div 2, Div 4 or Div 8 initialise further array ; entries and adjust the binary step to be used later ; accordingly. if @mode>0 h[l,i,8192]=0 step=8192 if @mode>1 r=random(r) h[l,i,4096]=r/#randomrange r=random(r) h[l,i,12288]=r/#randomrange step=4096 if @mode>2 r=random(r) h[l,i,2048]=r/#randomrange r=random(r) h[l,i,6144]=r/#randomrange r=random(r) h[l,i,10240]=r/#randomrange r=random(r) h[l,i,14336]=r/#randomrange step=2048 if @mode>3 r=random(r) h[l,i,1024]=r/#randomrange r=random(r) h[l,i,3072]=r/#randomrange r=random(r) h[l,i,5120]=r/#randomrange r=random(r) h[l,i,7168]=r/#randomrange r=random(r) h[l,i,9216]=r/#randomrange r=random(r) h[l,i,11264]=r/#randomrange r=random(r) h[l,i,13312]=r/#randomrange r=random(r) h[l,i,15360]=r/#randomrange step=1024 endif endif endif endif i=i+1 endwhile l=l+1 endwhile ; Now calculate the number of extra (dummy) dice rolls to use ; (The dummy rolls mean the shape of the fBm will not change ; in great jumps as the number of dice used is changed - ; provided @dice is <= @dummy) int nd=0 if @dummy>0 nd=@dummy-ceil(@dice) if (nd<0 && (!@morph))||(nd<-1 && @morph) $define DEBUG print("Not enough dummy rolls") $undef DEBUG nd=0 endif endif ; Now proceed with the actual fBm creation l=0 float th=0 ; For the "Total height" while l<@levels i=0 while i<4 float rs=1.0 ; Initial fBm scale factor int s=step ; initial step float mx=0 ; for the maximum float mn=0 ; for the minimum while s>1 ; we've finished when s=1 int o=floor(s/2) ; offset is s/2 int p=o ; start index while p<16384 ; Now roll up the next random if @morph float nr=@dice if nr<=@dummy while nr>=1 r=random(r) nr=nr-1 endwhile r1=r if nr>0 r=random(r) r1=(1-nr)*r1+nr*r endif else r=random(r) r1=r nr=nr-1 while nr>=1 r=random(r) nr=nr-1 endwhile r1=nr*r1+(1-nr)*r endif else r1=0 float nr=@dice while nr>=1 r=random(r) r1=r1+r/#randomrange nr=nr-1 endwhile if nr>0 r=random(r) r1=r1+nr*r/#randomrange endif r1=r1/@dice endif ; Do any dummy rolls int n=nd while n>0 r=random(r) n=n-1 endwhile ; Height = (previous+next)/2 + random*scale factor ; or cubic interpolation + random*scale factor if @average==0 h[l,i,p]=(h[l,i,p-o]+h[l,i,p+o])/2+rs*r1 else int w=(p-o-s)%16384 if w<0 w=w+16384 endif float hh0=h[l,i,w] float hh1=h[l,i,p-o] float hh2=h[l,i,p+o] w=(p+o+s)%16384 float hh3=h[l,i,w] h[l,i,p]=(5*(hh1+hh2)-(hh0+hh3))/8+rs*r1 endif ; Check for max and min if h[l,i,p]>mx mx=h[l,i,p] endif if h[l,i,p]1) endheading bool param flag1 caption = "Level 2 status" default = true hint = "Use to enable/disable fBm level 2." visible = @showmaps && (@levels>1) endparam float param frac1 caption = "Sharpness #2" default = 0.7071 min = 1e-5 max = 1.0 hint = "Controls the sharpness of the fBm, lower values \ produce smoother results." visible = @showmaps && (@levels>1) && @flag1 endparam float param rs1 caption = "Frequency #2" default = 1.0 hint = "Controls the scale of the patterns." visible = @showmaps && (@levels>1) && @flag1 endparam float param amp1 caption = "Amplitude #2" default = 1.0 min = 0 hint = "Controls the relative effect of fBm level #2." visible = @showmaps && (@levels>1) && @flag1 endparam float param ang1 caption = "Rotation #2 (degrees)" default = 22.5 hint = "Rotates the pattern." visible = @showmaps && (@levels>1) && @flag1 endparam heading caption = "fBm level 3" visible = @showmaps && (@levels>2) endheading bool param flag2 caption = "Level 3 status" default = true hint = "Use to enable/disable fBm level 3." visible = @showmaps && (@levels>2) endparam float param frac2 caption = "Sharpness #3" default = 0.7071 min = 1e-5 max = 1.0 hint = "Controls the sharpness of the fBm, lower values \ produce smoother results." visible = @showmaps && (@levels>2) && @flag2 endparam float param rs2 caption = "Frequency #3" default = 1.0 hint = "Controls the scale of the patterns." visible = @showmaps && (@levels>2) && @flag2 endparam float param amp2 caption = "Amplitude #3" default = 1.0 min = 0 hint = "Controls the relative effect of fBm level #3." visible = @showmaps && (@levels>2) && @flag2 endparam float param ang2 caption = "Rotation #3 (degrees)" default = 11.25 hint = "Rotates the pattern." visible = @showmaps && (@levels>2) && @flag2 endparam heading caption = "fBm level 4" visible = @showmaps && (@levels>3) endheading bool param flag3 caption = "Level 4 status" default = true hint = "Use to enable/disable fBm level 4." visible = @showmaps && (@levels>3) endparam float param frac3 caption = "Sharpness #4" default = 0.7071 min = 1e-5 max = 1.0 hint = "Controls the sharpness of the fBm, lower values \ produce smoother results." visible = @showmaps && (@levels>3) && @flag3 endparam float param rs3 caption = "Frequency #4" default = 1.0 hint = "Controls the scale of the patterns." visible = @showmaps && (@levels>3) && @flag3 endparam float param amp3 caption = "Amplitude #4" default = 1.0 min = 0 hint = "Controls the relative effect of fBm level #4." visible = @showmaps && (@levels>3) && @flag3 endparam float param ang3 caption = "Rotation #4 (degrees)" default = 33.75 hint = "Rotates the pattern." visible = @showmaps && (@levels>3) && @flag3 endparam heading caption = "fBm level 5" visible = @showmaps && (@levels>4) endheading bool param flag4 caption = "Level 5 status" default = true hint = "Use to enable/disable fBm level 5." visible = @showmaps && (@levels>4) endparam float param frac4 caption = "Sharpness #5" default = 0.7071 min = 1e-5 max = 1.0 hint = "Controls the sharpness of the fBm, lower values \ produce smoother results." visible = @showmaps && (@levels>4) && @flag4 endparam float param rs4 caption = "Frequency #5" default = 1.0 hint = "Controls the scale of the patterns." visible = @showmaps && (@levels>4) && @flag4 endparam float param amp4 caption = "Amplitude #5" default = 1.0 min = 0 hint = "Controls the relative effect of fBm level #5." visible = @showmaps && (@levels>4) && @flag4 endparam float param ang4 caption = "Rotation #5 (degrees)" default = 16.875 hint = "Rotates the pattern." visible = @showmaps && (@levels>4) && @flag4 endparam heading caption = "fBm level 6" visible = @showmaps && (@levels>5) endheading bool param flag5 caption = "Level 6 status" default = true hint = "Use to enable/disable fBm level 6." visible = @showmaps && (@levels>5) endparam float param frac5 caption = "Sharpness #6" default = 0.7071 min = 1e-5 max = 1.0 hint = "Controls the sharpness of the fBm, lower values \ produce smoother results." visible = @showmaps && (@levels>5) && @flag5 endparam float param rs5 caption = "Frequency #6" default = 1.0 hint = "Controls the scale of the patterns." visible = @showmaps && (@levels>5) && @flag5 endparam float param amp5 caption = "Amplitude #6" default = 1.0 min = 0 hint = "Controls the relative effect of fBm level #6." visible = @showmaps && (@levels>5) && @flag5 endparam float param ang5 caption = "Rotation #6 (degrees)" default = 39.375 hint = "Rotates the pattern." visible = @showmaps && (@levels>5) && @flag5 endparam heading caption = "fBm level 7" visible = @showmaps && (@levels>6) endheading bool param flag6 caption = "Level 7 status" default = true hint = "Use to enable/disable fBm level 7." visible = @showmaps && (@levels>6) endparam float param frac6 caption = "Sharpness #7" default = 0.7071 min = 1e-5 max = 1.0 hint = "Controls the sharpness of the fBm, lower values \ produce smoother results." visible = @showmaps && (@levels>6) && @flag6 endparam float param rs6 caption = "Frequency #7" default = 1.0 hint = "Controls the scale of the patterns." visible = @showmaps && (@levels>6) && @flag6 endparam float param amp6 caption = "Amplitude #7" default = 1.0 min = 0 hint = "Controls the relative effect of fBm level #7." visible = @showmaps && (@levels>6) && @flag6 endparam float param ang6 caption = "Rotation #7 (degrees)" default = 28.125 hint = "Rotates the pattern." visible = @showmaps && (@levels>6) && @flag6 endparam heading caption = "fBm level 8" visible = @showmaps && (@levels>7) endheading bool param flag7 caption = "Level 8 status" default = true hint = "Use to enable/disable fBm level 8." visible = @showmaps && (@levels>7) endparam float param frac7 caption = "Sharpness #8" default = 0.7071 min = 1e-5 max = 1.0 hint = "Controls the sharpness of the fBm, lower values \ produce smoother results." visible = @showmaps && (@levels>7) && @flag7 endparam float param rs7 caption = "Frequency #8" default = 1.0 hint = "Controls the scale of the patterns." visible = @showmaps && (@levels>7) && @flag7 endparam float param amp7 caption = "Amplitude #8" default = 1.0 min = 0 hint = "Controls the relative effect of fBm level #8." visible = @showmaps && (@levels>7) && @flag7 endparam float param ang7 caption = "Rotation #8 (degrees)" default = 5.625 hint = "Rotates the pattern." visible = @showmaps && (@levels>7) && @flag7 endparam heading caption = "fBm level 9" visible = @showmaps && (@levels>8) endheading bool param flag8 caption = "Level 9 status" default = true hint = "Use to enable/disable fBm level 9." visible = @showmaps && (@levels>8) endparam float param frac8 caption = "Sharpness #9" default = 0.7071 min = 1e-5 max = 1.0 hint = "Controls the sharpness of the fBm, lower values \ produce smoother results." visible = @showmaps && (@levels>8) && @flag8 endparam float param rs8 caption = "Frequency #9" default = 2.0 hint = "Controls the scale of the patterns." visible = @showmaps && (@levels>8) && @flag8 endparam float param amp8 caption = "Amplitude #9" default = 0.5 min = 0 hint = "Controls the relative effect of fBm level #9." visible = @showmaps && (@levels>8) && @flag8 endparam float param ang8 caption = "Rotation #9 (degrees)" default = 19.6875 hint = "Rotates the pattern." visible = @showmaps && (@levels>8) && @flag8 endparam heading caption = "fBm level 10" visible = @showmaps && (@levels>9) endheading bool param flag9 caption = "Level 10 status" default = true hint = "Use to enable/disable fBm level 10." visible = @showmaps && (@levels>9) endparam float param frac9 caption = "Sharpness #10" default = 0.7071 min = 1e-5 max = 1.0 hint = "Controls the sharpness of the fBm, lower values \ produce smoother results." visible = @showmaps && (@levels>9) && @flag9 endparam float param rs9 caption = "Frequency #10" default = 2.0 hint = "Controls the scale of the patterns." visible = @showmaps && (@levels>9) && @flag9 endparam float param amp9 caption = "Amplitude #10" default = 0.5 min = 0 hint = "Controls the relative effect of level #10." visible = @showmaps && (@levels>9) && @flag9 endparam float param ang9 caption = "Rotation #10 (degrees)" default = 36.5625 hint = "Rotates the pattern." visible = @showmaps && (@levels>9) && @flag9 endparam heading caption = "fBm level 11" visible = @showmaps && (@levels>10) endheading bool param flag10 caption = "Level 11 status" default = true hint = "Use to enable/disable fBm level 11." visible = @showmaps && (@levels>10) endparam float param frac10 caption = "Sharpness #11" default = 0.7071 min = 1e-5 max = 1.0 hint = "Controls the sharpness of the fBm, lower values \ produce smoother results." visible = @showmaps && (@levels>10) && @flag10 endparam float param rs10 caption = "Frequency #11" default = 2.0 hint = "Controls the scale of the patterns." visible = @showmaps && (@levels>10) && @flag10 endparam float param amp10 caption = "Amplitude #11" default = 0.5 min = 0 hint = "Controls the relative effect of fBm level #11." visible = @showmaps && (@levels>10) && @flag10 endparam float param ang10 caption = "Rotation #11 (degrees)" default = 8.4375 hint = "Rotates the pattern." visible = @showmaps && (@levels>10) && @flag10 endparam heading caption = "fBm level 12" visible = @showmaps && (@levels>11) endheading bool param flag11 caption = "Level 12 status" default = true hint = "Use to enable/disable fBm level 12." visible = @showmaps && (@levels>11) endparam float param frac11 caption = "Sharpness #12" default = 0.7071 min = 1e-5 max = 1.0 hint = "Controls the sharpness of the fBm, lower values \ produce smoother results." visible = @showmaps && (@levels>11) && @flag11 endparam float param rs11 caption = "Frequency #12" default = 4.0 hint = "Controls the scale of the patterns." visible = @showmaps && (@levels>11) && @flag11 endparam float param amp11 caption = "Amplitude #12" default = 0.25 min = 0 hint = "Controls the relative effect of fBm level #12." visible = @showmaps && (@levels>11) && @flag11 endparam float param ang11 caption = "Rotation #12 (degrees)" default = 25.3125 hint = "Rotates the pattern." visible = @showmaps && (@levels>11) && @flag11 endparam heading caption = "fBm level 13" visible = @showmaps && (@levels>12) endheading bool param flag12 caption = "Level 13 status" default = true hint = "Use to enable/disable fBm level 13." visible = @showmaps && (@levels>12) endparam float param frac12 caption = "Sharpness #13" default = 0.7071 min = 1e-5 max = 1.0 hint = "Controls the sharpness of the fBm, lower values \ produce smoother results." visible = @showmaps && (@levels>12) && @flag12 endparam float param rs12 caption = "Frequency #13" default = 4.0 hint = "Controls the scale of the patterns." visible = @showmaps && (@levels>12) && @flag12 endparam float param amp12 caption = "Amplitude #13" default = 0.25 min = 0 hint = "Controls the relative effect of fBm level #13." visible = @showmaps && (@levels>12) && @flag12 endparam float param ang12 caption = "Rotation #13 (degrees)" default = 14.0625 hint = "Rotates the pattern." visible = @showmaps && (@levels>12) && @flag12 endparam heading caption = "fBm level 14" visible = @showmaps && (@levels>13) endheading bool param flag13 caption = "Level 14 status" default = true hint = "Use to enable/disable fBm level 14." visible = @showmaps && (@levels>13) endparam float param frac13 caption = "Sharpness #14" default = 0.7071 min = 1e-5 max = 1.0 hint = "Controls the sharpness of the fBm, lower values \ produce smoother results." visible = @showmaps && (@levels>13) && @flag13 endparam float param rs13 caption = "Frequency #14" default = 8.0 hint = "Controls the scale of the patterns." visible = @showmaps && (@levels>13) && @flag13 endparam float param amp13 caption = "Amplitude #14" default = 0.125 min = 0 hint = "Controls the relative effect of fBm level #14." visible = @showmaps && (@levels>13) && @flag13 endparam float param ang13 caption = "Rotation #14 (degrees)" default = 30.9375 hint = "Rotates the pattern." visible = @showmaps && (@levels>13) && @flag13 endparam heading caption = "fBm level 15" visible = @showmaps && (@levels>14) endheading bool param flag14 caption = "Level 15 status" default = true hint = "Use to enable/disable fBm level 15." visible = @showmaps && (@levels>14) endparam float param frac14 caption = "Sharpness #15" default = 0.7071 min = 1e-5 max = 1.0 hint = "Controls the sharpness of the fBm, lower values \ produce smoother results." visible = @showmaps && (@levels>14) && @flag14 endparam float param rs14 caption = "Frequency #15" default = 16.0 hint = "Controls the scale of the patterns." visible = @showmaps && (@levels>14) && @flag14 endparam float param amp14 caption = "Amplitude #15" default = 0.0625 min = 0 hint = "Controls the relative effect of fBm level #15." visible = @showmaps && (@levels>14) && @flag14 endparam float param ang14 caption = "Rotation #15 (degrees)" default = 2.8125 hint = "Rotates the pattern." visible = @showmaps && (@levels>14) && @flag14 endparam heading caption = "fBm level 16" visible = @showmaps && (@levels>15) endheading bool param flag15 caption = "Level 16 status" default = true hint = "Use to enable/disable fBm level 16." visible = @showmaps && (@levels>15) endparam float param frac15 caption = "Sharpness #16" default = 0.7071 min = 1e-5 max = 1.0 hint = "Controls the sharpness of the fBm, lower values \ produce smoother results." visible = @showmaps && (@levels>15) && @flag15 endparam float param rs15 caption = "Frequency #16" default = 32.0 hint = "Controls the scale of the patterns." visible = @showmaps && (@levels>15) && @flag15 endparam float param amp15 caption = "Amplitude #16" default = 0.03125 min = 0 hint = "Controls the relative effect of level #16." visible = @showmaps && (@levels>15) && @flag15 endparam float param ang15 caption = "Rotation #16 (degrees)" default = 42.1875 hint = "Rotates the pattern." visible = @showmaps && (@levels>15) && @flag15 endparam } class MMF_TrapShapefBm(common.ulb:TrapShape) { ; A TrapShape wrapper for Alternative fBm
public: func MMF_TrapShapefBm(Generic pparent) TrapShape.TrapShape(pparent) texture = new @texture(this) texture.GlobalInit(0) endfunc float func Iterate(complex pz) TrapShape.Iterate(pz) if @diviter=="Divide by Iterations" return texture.GetfBm(pz/m_Iterations) elseif @diviter=="Divide by Iterations^2" return texture.GetfBm(pz/sqr(m_Iterations)) else return texture.GetfBm(pz) endif endfunc private: MMF_AltfBm texture default: title = "MMF Alternative fBm Trap Shape" int param v_mmftrapshapefbm caption = "Trap Shape fBm (MMF)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam MMF_AltfBm param texture caption = "Trap Texture" default = MMF_AltfBm endparam int param diviter caption = "Texture Density Reduction" enum = "None" "Divide by Iterations" "Divide by Iterations^2" default = 0 hint = "Sometimes the change in density of the texturing can be \ a bit high with respect to changes in iteration value. \ Use the divide options to somewhat reduce this." endparam } class MMF_ExtendedColorMerge(common.ulb:DefaultColorMerge) { ; ; Extended colour merges.
; David Makin May 2008
; ; Anyone interested in merge modes may like to look here:
; http://www.pegtop.net/delphi/articles/blendmodes/
public: ; @param pparent the parent, generally "this" for the parent, or zero func MMF_ExtendedColorMerge(Generic pparent) DefaultColorMerge.DefaultColorMerge(pparent) endfunc ; @param pbottom the base color ; @param ptop the top color ; @return merged color color func Merge(color pbottom, color ptop) if @p_modeselect=="MMF Merge Modes" if @clamp float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<0.0 r = 0.0 elseif r>1.0 r = 1.0 endif if g<0.0 g = 0.0 elseif g>1.0 g = 1.0 endif if b<0.0 b = 0.0 elseif b>1.0 b = 1.0 endif ptop = rgba(r,g,b,alpha(ptop)) r = red(pbottom) g = green(pbottom) b = blue(pbottom) if r<0.0 r = 0.0 elseif r>1.0 r = 1.0 endif if g<0.0 g = 0.0 elseif g>1.0 g = 1.0 endif if b<0.0 b = 0.0 elseif b>1.0 b = 1.0 endif pbottom = rgba(r,g,b,alpha(pbottom)) endif if @p_mmfmergemode=="Exclusion" return rgba(red(pbottom) + red(ptop) - 2*red(pbottom)*red(ptop), \ green(pbottom) + green(ptop) - 2*green(pbottom)*green(ptop), \ blue(pbottom) + blue(ptop) - 2*blue(pbottom)*blue(ptop), \ alpha(ptop) ) elseif @p_mmfmergemode=="Fade Down" return rgba( red(ptop) * (1 - red(ptop) + red(pbottom)), \ green(ptop) * (1 - green(ptop) + green(pbottom)), \ blue(ptop) * (1 - blue(ptop) + blue(pbottom)), alpha(ptop) ) elseif @p_mmfmergemode=="Fade Up" return rgba(red(pbottom) + red(ptop)*(red(ptop) - red(pbottom)), \ green(pbottom) + green(ptop)*(green(ptop) - green(pbottom)), \ blue(pbottom) + blue(ptop)*(blue(ptop) - blue(pbottom)), \ alpha(ptop) ) elseif @p_mmfmergemode=="Contrast Down" return rgba( 0.5 + red(ptop)*(red(pbottom) - 0.5), \ 0.5 + green(ptop)*(green(pbottom) - 0.5), \ 0.5 + blue(ptop)*(blue(pbottom) - 0.5), alpha(ptop) ) elseif @p_mmfmergemode=="Contrast Up" float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<0.5 r = r - 2.0*red(ptop)*r*(0.5 - r) else r = r + 2.0*red(ptop)*(1.0 - r)*(r - 0.5) endif if g<0.5 g = g - 2.0*green(ptop)*g*(0.5 - g) else g = g + 2.0*green(ptop)*(1.0 - g)*(g - 0.5) endif if b<0.5 b = b - 2.0*blue(ptop)*b*(0.5 - b) else b = b + 2.0*blue(ptop)*(1.0 - b)*(b - 0.5) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Dodge" ; Here we clamp the maximum returned to 1.0 because of the special case ; when the color channel in ptop is one (or more). float r = 1.0 - red(ptop) float g = 1.0 - green(ptop) float b = 1.0 - blue(ptop) if red(pbottom)<=0 r = 0.0 elseif r<=0.0 r = 1.0 else r = red(pbottom)/r if r>1.0 r = 1.0 endif endif if green(pbottom)<=0 g = 0 elseif g<=0.0 g = 1.0 else g = green(pbottom)/g if g>1.0 g = 1.0 endif endif if blue(pbottom)<=0 b = 0 elseif b<=0.0 b = 1.0 else b = blue(pbottom)/b if b>1.0 b = 1.0 endif endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Burn" ; Here we clamp the minimum returned to 0 because of the special case ; when the color channel in ptop is zero (or less). float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<=0.0 r = 0.0 else r = 1.0 - (1.0 - red(pbottom))/r if r<0.0 r = 0.0 endif endif if g<=0.0 g = 0.0 else g = 1.0 - (1.0 - green(pbottom))/g if g<0.0 g = 0.0 endif endif if b<=0.0 b = 0.0 else b = 1.0 - (1.0 - blue(pbottom))/b if b<0.0 b = 0.0 endif endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Negation" return rgba( 1.0 - abs(1.0 - red(ptop) - red(pbottom)), \ 1.0 - abs(1.0 - green(ptop) - green(pbottom)), \ 1.0 - abs(1.0 - blue(ptop) - blue(pbottom)), alpha(ptop) ) elseif @p_mmfmergemode=="Reflect" ; Here we clamp the maximum returned to 1.0 because of the special case ; when the color channel in ptop is one (or more). float r = 1.0 - red(ptop) float g = 1.0 - green(ptop) float b = 1.0 - blue(ptop) if red(pbottom)<=0 r = 0.0 elseif r<=0.0 r = 1.0 else r = sqr(red(pbottom))/r if r>1.0 r = 1.0 endif endif if green(pbottom)<=0 g = 0.0 elseif g<=0.0 g = 1.0 else g = sqr(green(pbottom))/g if g>1.0 g = 1.0 endif endif if blue(pbottom)<=0 b = 0.0 elseif b<=0.0 b = 1.0 else b = sqr(blue(pbottom))/b if b>1.0 b = 1.0 endif endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Freeze" ; Here we clamp the minimum returned to 0 because of the special case ; when the color channel in ptop is zero (or less). float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<=0.0 r = 0.0 else r = 1.0 - sqr(1.0 - red(pbottom))/r if r<0.0 r = 0.0 endif endif if g<=0.0 g = 0.0 else g = 1.0 - sqr(1.0 - green(pbottom))/g if g<0.0 g = 0.0 endif endif if b<=0.0 b = 0.0 else b = 1.0 - sqr(1.0 - blue(pbottom))/b if b<0.0 b = 0.0 endif endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Rev. Contrast Down" return rgba( 0.5 + (1.0 - red(ptop))*(red(pbottom) - 0.5), \ 0.5 + (1.0 - green(ptop))*(green(pbottom) - 0.5), \ 0.5 + (1.0 - blue(ptop))*(blue(pbottom) - 0.5), alpha(ptop) ) elseif @p_mmfmergemode=="Rev. Contrast Up" float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<0.5 r = r - 2.0*(1.0 - red(ptop))*r*(0.5 - r) else r = r + 2.0*(1.0 - red(ptop))*(1.0 - r)*(r - 0.5) endif if g<0.5 g = g - 2.0*(1.0 - green(ptop))*g*(0.5 - g) else g = g + 2.0*(1.0 - green(ptop))*(1.0 - g)*(g - 0.5) endif if b<0.5 b = b - 2.0*(1.0 - blue(ptop))*b*(0.5 - b) else b = b + 2.0*(1.0 - blue(ptop))*(1.0 - b)*(b - 0.5) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Fade" float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<0.5 r = 2.0 * r * (0.5 - r + red(pbottom)) else r = red(pbottom) + 2.0 * (r - 0.5)*(r - red(pbottom)) endif if g<0.5 g = 2.0 * g * (0.5 - g + green(pbottom)) else g = green(pbottom) + 2.0 * (g - 0.5)*(g - green(pbottom)) endif if b<0.5 b = 2.0 * b * (0.5 - b + blue(pbottom)) else b = blue(pbottom) + 2.0 * (b - 0.5)*(b - blue(pbottom)) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Reverse Fade" float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<0.5 r = red(pbottom) + 2.0 * r * (r - red(pbottom)) else r = red(pbottom) + 2.0 * (1.0 - r)*(r - red(pbottom)) endif if g<0.5 g = green(pbottom) + 2.0 * g * (g - green(pbottom)) else g = green(pbottom) + 2.0 * (1.0 - g)*(g - green(pbottom)) endif if b<0.5 b = blue(pbottom) + 2.0 * b * (b - blue(pbottom)) else b = blue(pbottom) + 2.0 * (1.0 - b)*(b - blue(pbottom)) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Contrast" || @p_mmfmergemode=="Reverse Contrast" float r1 = red(ptop) float g1 = green(ptop) float b1 = blue(ptop) if @p_mmfmergemode=="Reverse Contrast" r1 = 1.0 - r1 g1 = 1.0 - g1 b1 = 1.0 - b1 endif if r1<0.5 r1 = 0.5 + 2.0 * r1 * (red(pbottom) - 0.5) else r1 = 2.0 * (r1 - 0.5) float r = red(pbottom) if r<0.5 r1 = r - 2.0*r1*r*(0.5 - r) else r1 = r + 2.0*r1*(1.0 - r)*(r - 0.5) endif endif if g1<0.5 g1 = 0.5 + 2.0 * g1 * (green(pbottom) - 0.5) else g1 = 2.0 * (g1 - 0.5) float g = green(pbottom) if g<0.5 g1 = g - 2.0*g1*g*(0.5 - g) else g1 = g + 2.0*g1*(1.0 - g)*(g - 0.5) endif endif if b1<0.5 b1 = 0.5 + 2.0 * b1 * (blue(pbottom) - 0.5) else b1 = 2.0 * (b1 - 0.5) float b = blue(pbottom) if b<0.5 b1 = b - 2.0*b1*b*(0.5 - b) else b1 = b + 2.0*b1*(1.0 - b)*(b - 0.5) endif endif return rgba(r1,g1,b1,alpha(ptop)) elseif @p_mmfmergemode=="Quantize" int nr = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + red(ptop)) - 1.0)) - 1 int ng = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + green(ptop)) - 1.0)) - 1 int nb = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + blue(ptop)) - 1.0)) - 1 return rgba(floor(red(pbottom)*(nr+0.999))/nr, \ floor(green(pbottom)*(ng+0.999))/ng, \ floor(blue(pbottom)*(nb+0.999))/nb,alpha(ptop)) elseif @p_mmfmergemode=="Reverse Quantize" int nr = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - red(ptop)) - 1.0)) - 1 int ng = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - green(ptop)) - 1.0)) - 1 int nb = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - blue(ptop)) - 1.0)) - 1 return rgba(floor(red(pbottom)*(nr+0.999))/nr, \ floor(green(pbottom)*(ng+0.999))/ng, \ floor(blue(pbottom)*(nb+0.999))/nb,alpha(ptop)) elseif @p_mmfmergemode=="Gamma" return rgba(red(pbottom)^(@mingamma+(@maxgamma-@mingamma)*red(ptop)), \ green(pbottom)^(@mingamma+(@maxgamma-@mingamma)*green(ptop)), \ blue(pbottom)^(@mingamma+(@maxgamma-@mingamma)*blue(ptop)), \ alpha(ptop)) elseif @p_mmfmergemode=="Inverse Gamma" return rgba(red(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*red(ptop))), \ green(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*green(ptop))), \ blue(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*blue(ptop))), \ alpha(ptop)) elseif @p_mmfmergemode=="Reverse Gamma" return rgba(red(pbottom)^(@mingamma+(@maxgamma-@mingamma)*(1.0-red(ptop))), \ green(pbottom)^(@mingamma+(@maxgamma-@mingamma)*(1.0-green(ptop))), \ blue(pbottom)^(@mingamma+(@maxgamma-@mingamma)*(1.0-blue(ptop))), \ alpha(ptop)) elseif @p_mmfmergemode=="Rev. Inv. Gamma" return rgba(red(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-red(ptop)))), \ green(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-green(ptop)))), \ blue(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-blue(ptop)))), \ alpha(ptop)) elseif @p_mmfmergemode=="Combined Gamma" float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<0.5 r = red(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-red(ptop))) else r = red(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(red(ptop)-0.5))) endif if g<0.5 g = green(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-green(ptop))) else g = green(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(green(ptop)-0.5))) endif if b<0.5 b = blue(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-blue(ptop))) else b = blue(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(blue(ptop)-0.5))) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Rev. Comb. Gamma" float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<0.5 r = red(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-red(ptop)))) else r = red(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(red(ptop)-0.5)) endif if g<0.5 g = green(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-green(ptop)))) else g = green(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(green(ptop)-0.5)) endif if b<0.5 b = blue(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-blue(ptop)))) else b = blue(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(blue(ptop)-0.5)) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Stamp" float r = red(pbottom) + 2.0*red(ptop) - 1.0 float g = green(pbottom) + 2.0*green(ptop) - 1.0 float b = blue(pbottom) + 2.0*blue(ptop) - 1.0 if r<0.0 r = 0.0 elseif r>1.0 r = 1.0 endif if g<0.0 g = 0.0 elseif g>1.0 g = 1.0 endif if b<0.0 b = 0.0 elseif b>1.0 b = 1.0 endif return RGBA(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Soft Dodge" float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<=0 r = 0 elseif r+red(ptop)<=1.0 if red(ptop)>=1.0 r = 1.0 elseif (r = 0.5*r/(1.0 - red(ptop)))>1.0 r = 1.0 endif elseif (r = 1.0 - 0.5*(1.0 - red(ptop))/r)<0.0 r = 0.0 endif if g<=0 g = 0 elseif g+green(ptop)<=1.0 if green(ptop)>=1.0 g = 1.0 elseif (g = 0.5*g/(1.0 - green(ptop)))>1.0 g = 1.0 endif elseif (g = 1.0 - 0.5*(1.0 - green(ptop))/g)<0.0 g = 0.0 endif if b<=0 b = 0 elseif b+blue(ptop)<=1.0 if blue(ptop)>=1.0 b = 1.0 elseif (b = 0.5*b/(1.0 - blue(ptop)))>1.0 b = 1.0 endif elseif (b = 1.0 - 0.5*(1.0 - blue(ptop))/b)<0.0 b = 0.0 endif return RGBA(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Soft Burn" float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<=0 r = 0 elseif r+red(pbottom)<=1.0 if red(pbottom)>=1.0 r = 1.0 elseif (r = 0.5*r/(1.0 - red(pbottom)))>1.0 r = 1.0 endif elseif (r = 1.0 - 0.5*(1.0 - red(pbottom))/r)<0.0 r = 0.0 endif if g<=0 g = 0 elseif g+green(pbottom)<=1.0 if green(pbottom)>=1.0 g = 1.0 elseif (g = 0.5*g/(1.0 - green(pbottom)))>1.0 g = 1.0 endif elseif (g = 1.0 - 0.5*(1.0 - green(pbottom))/g)<0.0 g = 0.0 endif if b<=0 b = 0 elseif b+blue(pbottom)<=1.0 if blue(pbottom)>=1.0 b = 1.0 elseif (b = 0.5*b/(1.0 - blue(pbottom)))>1.0 b = 1.0 endif elseif (b = 1.0 - 0.5*(1.0 - blue(pbottom))/b)<0.0 b = 0.0 endif return RGBA(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inverse Dodge" ; Here we clamp the maximum returned to 1.0 because of the special case ; when the color channel in ptop is one (or more). float r = 1.0 - red(pbottom) float g = 1.0 - green(pbottom) float b = 1.0 - blue(pbottom) if red(ptop)<=0 r = 0 elseif r<=0.0 r = 1.0 else r = red(ptop)/r if r>1.0 r = 1.0 endif endif if green(ptop)<=0 g = 0 elseif g<=0.0 g = 1.0 else g = green(ptop)/g if g>1.0 g = 1.0 endif endif if blue(ptop)<=0 b = 0 elseif b<=0.0 b = 1.0 else b = blue(ptop)/b if b>1.0 b = 1.0 endif endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inverse Burn" ; Here we clamp the minimum returned to 0 because of the special case ; when the color channel in ptop is zero (or less). float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<=0.0 r = 0.0 else r = 1.0 - (1.0 - red(ptop))/r if r<0.0 r = 0.0 endif endif if g<=0.0 g = 0.0 else g = 1.0 - (1.0 - green(ptop))/g if g<0.0 g = 0.0 endif endif if b<=0.0 b = 0.0 else b = 1.0 - (1.0 - blue(ptop))/b if b<0.0 b = 0.0 endif endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Glow" ; Here we clamp the maximum returned to 1.0 because of the special case ; when the color channel in ptop is one (or more). float r = 1.0 - red(pbottom) float g = 1.0 - green(pbottom) float b = 1.0 - blue(pbottom) if red(ptop)<=0 r = 0.0 elseif r<=0.0 r = 1.0 else r = sqr(red(ptop))/r if r>1.0 r = 1.0 endif endif if green(ptop)<=0 g = 0.0 elseif g<=0.0 g = 1.0 else g = sqr(green(ptop))/g if g>1.0 g = 1.0 endif endif if blue(ptop)<=0 b = 0.0 elseif b<=0.0 b = 1.0 else b = sqr(blue(ptop))/b if b>1.0 b = 1.0 endif endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Heat" ; Here we clamp the minimum returned to 0 because of the special case ; when the color channel in ptop is zero (or less). float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<=0.0 r = 0.0 else r = 1.0 - sqr(1.0 - red(ptop))/r if r<0.0 r = 0.0 endif endif if g<=0.0 g = 0.0 else g = 1.0 - sqr(1.0 - green(ptop))/g if g<0.0 g = 0.0 endif endif if b<=0.0 b = 0.0 else b = 1.0 - sqr(1.0 - blue(ptop))/b if b<0.0 b = 0.0 endif endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inv. Fade Down" return rgba( red(pbottom) * (1 - red(pbottom) + red(ptop)), \ green(pbottom) * (1 - green(pbottom) + green(ptop)), \ blue(pbottom) * (1 - blue(pbottom) + blue(ptop)), alpha(ptop) ) elseif @p_mmfmergemode=="Inv. Fade Up" return rgba(red(ptop) + red(pbottom)*(red(pbottom) - red(ptop)), \ green(ptop) + green(pbottom)*(green(pbottom) - green(ptop)), \ blue(ptop) + blue(pbottom)*(blue(pbottom) - blue(ptop)), \ alpha(ptop) ) elseif @p_mmfmergemode=="Inv. Contrast Down" return rgba( 0.5 + red(pbottom)*(red(ptop) - 0.5), \ 0.5 + green(pbottom)*(green(ptop) - 0.5), \ 0.5 + blue(pbottom)*(blue(ptop) - 0.5), alpha(ptop) ) elseif @p_mmfmergemode=="Inv. Contrast Up" float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<0.5 r = r - 2.0*red(pbottom)*r*(0.5 - r) else r = r + 2.0*red(pbottom)*(1.0 - r)*(r - 0.5) endif if g<0.5 g = g - 2.0*green(pbottom)*g*(0.5 - g) else g = g + 2.0*green(pbottom)*(1.0 - g)*(g - 0.5) endif if b<0.5 b = b - 2.0*blue(pbottom)*b*(0.5 - b) else b = b + 2.0*blue(pbottom)*(1.0 - b)*(b - 0.5) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inv. Rev. Con. Down" return rgba( 0.5 + (1.0 - red(pbottom))*(red(ptop) - 0.5), \ 0.5 + (1.0 - green(pbottom))*(green(ptop) - 0.5), \ 0.5 + (1.0 - blue(pbottom))*(blue(ptop) - 0.5), alpha(ptop) ) elseif @p_mmfmergemode=="Inv. Rev. Con. Up" float r = red(ptop) float g = green(ptop) float b = blue(ptop) if r<0.5 r = r - 2.0*(1.0 - red(pbottom))*r*(0.5 - r) else r = r + 2.0*(1.0 - red(pbottom))*(1.0 - r)*(r - 0.5) endif if g<0.5 g = g - 2.0*(1.0 - green(pbottom))*g*(0.5 - g) else g = g + 2.0*(1.0 - green(pbottom))*(1.0 - g)*(g - 0.5) endif if b<0.5 b = b - 2.0*(1.0 - blue(pbottom))*b*(0.5 - b) else b = b + 2.0*(1.0 - blue(pbottom))*(1.0 - b)*(b - 0.5) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inverse Fade" float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<0.5 r = 2.0 * r * (0.5 - r + red(ptop)) else r = red(ptop) + 2.0 * (r - 0.5)*(r - red(ptop)) endif if g<0.5 g = 2.0 * g * (0.5 - g + green(ptop)) else g = green(ptop) + 2.0 * (g - 0.5)*(g - green(ptop)) endif if b<0.5 b = 2.0 * b * (0.5 - b + blue(ptop)) else b = blue(ptop) + 2.0 * (b - 0.5)*(b - blue(ptop)) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inv. Rev. Fade" float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<0.5 r = red(ptop) + 2.0 * r * (r - red(ptop)) else r = red(ptop) + 2.0 * (1.0 - r)*(r - red(ptop)) endif if g<0.5 g = green(ptop) + 2.0 * g * (g - green(ptop)) else g = green(ptop) + 2.0 * (1.0 - g)*(g - green(ptop)) endif if b<0.5 b = blue(ptop) + 2.0 * b * (b - blue(ptop)) else b = blue(ptop) + 2.0 * (1.0 - b)*(b - blue(ptop)) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inverse Contrast" \ || @p_mmfmergemode=="Inv. Rev. Contrast" float r1 = red(pbottom) float g1 = green(pbottom) float b1 = blue(pbottom) if @p_mmfmergemode=="Inv. Rev. Contrast" r1 = 1.0 - r1 g1 = 1.0 - g1 b1 = 1.0 - b1 endif if r1<0.5 r1 = 0.5 + 2.0 * r1 * (red(ptop) - 0.5) else r1 = 2.0 * (r1 - 0.5) float r = red(ptop) if r<0.5 r1 = r - 2.0*r1*r*(0.5 - r) else r1 = r + 2.0*r1*(1.0 - r)*(r - 0.5) endif endif if g1<0.5 g1 = 0.5 + 2.0 * g1 * (green(ptop) - 0.5) else g1 = 2.0 * (g1 - 0.5) float g = green(ptop) if g<0.5 g1 = g - 2.0*g1*g*(0.5 - g) else g1 = g + 2.0*g1*(1.0 - g)*(g - 0.5) endif endif if b1<0.5 b1 = 0.5 + 2.0 * b1 * (blue(ptop) - 0.5) else b1 = 2.0 * (b1 - 0.5) float b = blue(ptop) if b<0.5 b1 = b - 2.0*b1*b*(0.5 - b) else b1 = b + 2.0*b1*(1.0 - b)*(b - 0.5) endif endif return rgba(r1,g1,b1,alpha(ptop)) elseif @p_mmfmergemode=="Inverse Quantize" int nr = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + red(pbottom)) - 1.0)) - 1 int ng = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + green(pbottom)) - 1.0)) - 1 int nb = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + blue(pbottom)) - 1.0)) - 1 return rgba(floor(red(ptop)*(nr+0.999))/nr, \ floor(green(ptop)*(ng+0.999))/ng, \ floor(blue(ptop)*(nb+0.999))/nb,alpha(ptop)) elseif @p_mmfmergemode=="Inv. Rev. Quantize" int nr = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - red(pbottom)) - 1.0)) - 1 int ng = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - green(pbottom)) - 1.0)) - 1 int nb = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - blue(pbottom)) - 1.0)) - 1 return rgba(floor(red(ptop)*(nr+0.999))/nr, \ floor(green(ptop)*(ng+0.999))/ng, \ floor(blue(ptop)*(nb+0.999))/nb,alpha(ptop)) elseif @p_mmfmergemode=="Inv. Gamma" return rgba(red(ptop)^(@mingamma+(@maxgamma-@mingamma)*red(pbottom)), \ green(ptop)^(@mingamma+(@maxgamma-@mingamma)*green(pbottom)), \ blue(ptop)^(@mingamma+(@maxgamma-@mingamma)*blue(pbottom)), \ alpha(ptop)) elseif @p_mmfmergemode=="Inv. Inverse Gamma" return rgba(red(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*red(pbottom))), \ green(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*green(pbottom))), \ blue(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*blue(pbottom))), \ alpha(ptop)) elseif @p_mmfmergemode=="Inv. Reverse Gamma" return rgba(red(ptop)^(@mingamma+(@maxgamma-@mingamma)*(1.0-red(pbottom))), \ green(ptop)^(@mingamma+(@maxgamma-@mingamma)*(1.0-green(pbottom))), \ blue(ptop)^(@mingamma+(@maxgamma-@mingamma)*(1.0-blue(pbottom))), \ alpha(ptop)) elseif @p_mmfmergemode=="Inv. Rev. Inv. Gamma" return rgba(red(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-red(pbottom)))), \ green(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-green(pbottom)))), \ blue(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-blue(pbottom)))), \ alpha(ptop)) elseif @p_mmfmergemode=="Inv. Combined Gamma" float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<0.5 r = red(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-r)) else r = red(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(r-0.5))) endif if g<0.5 g = green(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-g)) else g = green(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(g-0.5))) endif if b<0.5 b = blue(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-b)) else b = blue(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(b-0.5))) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inv. Rev. Comb. Gamma" float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if r<0.5 r = red(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-r))) else r = red(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(r-0.5)) endif if g<0.5 g = green(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-g))) else g = green(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(g-0.5)) endif if b<0.5 b = blue(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-b))) else b = blue(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(b-0.5)) endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Inverse Stamp" float r = red(ptop) + 2.0*red(pbottom) - 1.0 float g = green(ptop) + 2.0*green(pbottom) - 1.0 float b = blue(ptop) + 2.0*blue(pbottom) - 1.0 if r<0.0 r = 0.0 elseif r>1.0 r = 1.0 endif if g<0.0 g = 0.0 elseif g>1.0 g = 1.0 endif if b<0.0 b = 0.0 elseif b>1.0 b = 1.0 endif return RGBA(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Brightness (Yiq)" float btop = 0.299*red(ptop) + 0.587*green(ptop) + 0.114*blue(ptop) float bbtm = 0.299*red(pbottom) + 0.587*green(pbottom) \ + 0.114*blue(pbottom) if bbtm==0 return RGBA(btop,btop,btop,alpha(ptop)) else pbottom = pbottom*(btop/bbtm) return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop)) endif elseif @p_mmfmergemode=="Colour (Inverse Yiq)" float btop = 0.299*red(ptop) + 0.587*green(ptop) + 0.114*blue(ptop) float bbtm = 0.299*red(pbottom) + 0.587*green(pbottom) \ + 0.114*blue(pbottom) if btop==0 return RGBA(bbtm,bbtm,bbtm,alpha(ptop)) else pbottom = ptop*(bbtm/btop) return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop)) endif elseif @p_mmfmergemode=="Brightness (Custom)" float btop = (@redlvl*red(ptop) + @greenlvl*green(ptop) \ + @bluelvl*blue(ptop))/(@redlvl + @greenlvl +@bluelvl) float bbtm = (@redlvl*red(pbottom) + @greenlvl*green(pbottom) \ + @bluelvl*blue(pbottom))/(@redlvl + @greenlvl +@bluelvl) if bbtm==0 return RGBA(btop,btop,btop,alpha(ptop)) else pbottom = pbottom*(btop/bbtm) return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop)) endif elseif @p_mmfmergemode=="Colour (Custom)" float btop = (@redlvl*red(ptop) + @greenlvl*green(ptop) \ + @bluelvl*blue(ptop))/(@redlvl + @greenlvl +@bluelvl) float bbtm = (@redlvl*red(pbottom) + @greenlvl*green(pbottom) \ + @bluelvl*blue(pbottom))/(@redlvl + @greenlvl +@bluelvl) if btop==0 return RGBA(bbtm,bbtm,bbtm,alpha(ptop)) else pbottom = ptop*(bbtm/btop) return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop)) endif elseif @p_mmfmergemode=="Pin Light" float r = red(ptop) float g = green(ptop) float b = blue(ptop) if (r>=0.5 && rred(pbottom)) r = red(pbottom) endif if (g>=0.5 && ggreen(pbottom)) g = green(pbottom) endif if (b>=0.5 && bblue(pbottom)) b = blue(pbottom) endif return RGBA(r, g, b, alpha(ptop)) elseif @p_mmfmergemode=="Reverse Pin Light" float r = red(ptop) float g = green(ptop) float b = blue(ptop) if (r>=0.5 && r>red(pbottom)) || (r<0.5 && r=0.5 && g>green(pbottom)) || (g<0.5 && g=0.5 && b>blue(pbottom)) || (b<0.5 && b=0.5 && rred(ptop)) r = red(ptop) endif if (g>=0.5 && ggreen(ptop)) g = green(ptop) endif if (b>=0.5 && bblue(ptop)) b = blue(ptop) endif return RGBA(r, g, b, alpha(ptop)) elseif @p_mmfmergemode=="Inv. Rev. Pin Light" float r = red(pbottom) float g = green(pbottom) float b = blue(pbottom) if (r>=0.5 && r>red(ptop)) || (r<0.5 && r=0.5 && g>green(ptop)) || (g<0.5 && g=0.5 && b>blue(ptop)) || (b<0.5 && bbbtm if bbtm==0 return RGBA(btop,btop,btop,alpha(ptop)) else pbottom = pbottom*(btop/bbtm) endif endif return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop)) elseif @p_mmfmergemode=="Darken (Yiq)" float btop = 0.299*red(ptop) + 0.587*green(ptop) + 0.114*blue(ptop) float bbtm = 0.299*red(pbottom) + 0.587*green(pbottom) \ + 0.114*blue(pbottom) if btop=0.5 && btop>bbtm) || (btop<0.5 && btop=0.5 && btopbbtm) if bbtm==0 return RGBA(btop,btop,btop,alpha(ptop)) else pbottom = pbottom*(btop/bbtm) endif endif return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop)) elseif @p_mmfmergemode=="Inv. Pin (Yiq)" float btop = 0.299*red(ptop) + 0.587*green(ptop) + 0.114*blue(ptop) float bbtm = 0.299*red(pbottom) + 0.587*green(pbottom) \ + 0.114*blue(pbottom) if (bbtm>=0.5 && btop>bbtm) || (bbtm<0.5 && btop=0.5 && btopbbtm) if bbtm==0 return RGBA(btop,btop,btop,alpha(ptop)) else pbottom = pbottom*(btop/bbtm) endif endif return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop)) elseif @p_mmfmergemode=="Soft Quantize" int nr = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + red(ptop)) - 1.0)) int ng = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + green(ptop)) - 1.0)) int nb = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + blue(ptop)) - 1.0)) return rgba((1+2*floor(0.9999*nr*red(pbottom)))/(2*nr), \ (1+2*floor(0.9999*ng*green(pbottom)))/(2*nb), \ (1+2*floor(0.9999*nb*blue(pbottom)))/(2*ng),alpha(ptop)) elseif @p_mmfmergemode=="Rev. Soft Quantize" int nr = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - red(ptop)) - 1.0)) int ng = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - green(ptop)) - 1.0)) int nb = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - blue(ptop)) - 1.0)) return rgba((1+2*floor(0.9999*nr*red(pbottom)))/(2*nr), \ (1+2*floor(0.9999*ng*green(pbottom)))/(2*nb), \ (1+2*floor(0.9999*nb*blue(pbottom)))/(2*ng),alpha(ptop)) elseif @p_mmfmergemode=="Inv. Soft Quantize" int nr = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + red(pbottom)) - 1.0)) int ng = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + green(pbottom)) - 1.0)) int nb = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + blue(pbottom)) - 1.0)) return rgba((1+2*floor(0.9999*nr*red(ptop)))/(2*nr), \ (1+2*floor(0.9999*ng*green(ptop)))/(2*nb), \ (1+2*floor(0.9999*nb*blue(ptop)))/(2*ng),alpha(ptop)) elseif @p_mmfmergemode=="Inv. Rev. Soft Quantize" int nr = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - red(pbottom)) - 1.0)) int ng = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - green(pbottom)) - 1.0)) int nb = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - blue(pbottom)) - 1.0)) return rgba((1+2*floor(0.9999*nr*red(ptop)))/(2*nr), \ (1+2*floor(0.9999*ng*green(ptop)))/(2*nb), \ (1+2*floor(0.9999*nb*blue(ptop)))/(2*ng),alpha(ptop)) elseif @p_mmfmergemode=="Cyan (Inverse Red)" return rgba(red(pbottom),green(ptop),blue(ptop),alpha(ptop)) elseif @p_mmfmergemode=="Magenta (Inverse Green)" return rgba(red(ptop),green(pbottom),blue(ptop),alpha(ptop)) elseif @p_mmfmergemode=="Yellow (Inverse Blue)" return rgba(red(ptop),green(ptop),blue(pbottom),alpha(ptop)) elseif @p_mmfmergemode=="Inverse Hue" return hsla(hue(pbottom),sat(ptop),lum(ptop),alpha(ptop)) elseif @p_mmfmergemode=="Inverse Saturation" return hsla(hue(ptop),sat(pbottom),lum(ptop),alpha(ptop)) elseif @p_mmfmergemode=="Colourize (Inverse Luminance)" return hsla(hue(ptop),sat(ptop),lum(pbottom),alpha(ptop)) elseif @p_mmfmergemode=="Inverse Subtraction" float r = red(ptop) - red(pbottom) float g = green(ptop) - green(pbottom) float b = blue(ptop) - blue(pbottom) if r<0.0 r = 0.0 endif if g<0.0 g = 0.0 endif if b<0.0 b = 0.0 endif return rgba(r,g,b,alpha(ptop)) elseif @p_mmfmergemode=="Double" float r = (red(ptop)+1.0)*red(pbottom) float g = (green(ptop)+1.0)*green(pbottom) float b = (blue(ptop)+1.0)*blue(pbottom) if r>1.0 r = 1.0 endif if g>1.0 g = 1.0 endif if b>1.0 b = 1.0 endif return rgba(r,g,b,alpha(ptop)) else;if @p_mmfmergemode=="Inverse Double" float r = (red(pbottom)+1.0)*red(ptop) float g = (green(pbottom)+1.0)*green(ptop) float b = (blue(pbottom)+1.0)*blue(ptop) if r>1.0 r = 1.0 endif if g>1.0 g = 1.0 endif if b>1.0 b = 1.0 endif return rgba(r,g,b,alpha(ptop)) endif ; @p_mmfmergemode else;if @pmodeselect=="Original Merge Modes" return DefaultColorMerge.Merge(pbottom, ptop) endif ; @p_modeselect endfunc default: Title = "MMF Extended Colour Merge" int param v_mmfextendedcolormerge caption = "Version (MMF Extended Colour Merge)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam int param p_modeselect caption = "Merge Modes to choose from" enum = "Original Merge Modes" "MMF Merge Modes" default = 0 hint = "Choose from different collections of merge modes." endparam color func f_mergemode caption = "Merge Mode" default = mergemultiply() hint = "Sets the method used to merge input colors with." visible = @p_modeselect=="Original Merge Modes" endfunc bool param clamp caption = "Clamp Values" default = false hint = "When enabled the RGB values in both the top and bottom colours \ are clamped to the range 0<=v<=1. Should not be necessary most \ of the time." visible = @p_modeselect=="MMF Merge Modes" endparam int param p_mmfmergemode caption = "MMF Merge Mode" enum = "Exclusion" "Fade Down" "Fade Up" "Contrast Down" "Contrast Up" \ "Dodge" "Burn" "Negation" "Reflect" "Freeze" "Rev. Contrast Down" \ "Rev. Contrast Up" "Fade" "Reverse Fade" "Contrast" \ "Reverse Contrast" "Quantize" "Reverse Quantize" "Gamma" \ "Inverse Gamma" "Reverse Gamma" "Rev. Inv. Gamma" "Combined Gamma" \ "Rev. Comb. Gamma" "Stamp" "Soft Dodge" "Soft Burn" \ "Inverse Dodge" "Inverse Burn" "Glow" "Heat" "Inv. Fade Down" \ "Inv. Fade Up" "Inv. Contrast Down" "Inv. Contrast Up" \ "Inv. Rev. Con. Down" "Inv. Rev. Con. Up" "Inverse Fade" \ "Inv. Rev. Fade" "Inverse Contrast" "Inv. Rev. Contrast" \ "Inverse Quantize" "Inv. Rev. Quantize" "Inv. Gamma" \ "Inv. Inverse Gamma" "Inv. Reverse Gamma" "Inv. Rev. Inv. Gamma" \ "Inv. Combined Gamma" "Inv. Rev. Comb. Gamma" "Inverse Stamp" \ "Brightness (Yiq)" "Colour (Inverse Yiq)" "Brightness (Custom)" \ "Colour (Custom)" "Pin Light" "Reverse Pin Light" "Inv. Pin Light" \ "Inv. Rev. Pin Light" "Lighten (Yiq)" "Darken (Yiq)" "Pin (Yiq)" \ "Reverse Pin (Yiq)" "Inv. Pin (Yiq)" "Inv. Rev. Pin (Yiq)" \ "Soft Quantize" "Rev. Soft Quantize" "Inv. Soft Quantize" \ "Inv. Rev. Soft Quantize" "Cyan (Inverse Red)" \ "Magenta (Inverse Green)" "Yellow (Inverse Blue)" "Inverse Hue" \ "Inverse Saturation" "Colourize (Inverse Luminance)" \ "Inverse Subtraction" "Double" "Inverse Double" default = 0 hint = "Extra merge modes, just try them out !" visible = @p_modeselect=="MMF Merge Modes" endparam int param qmin caption = "Minimum Quantize" default = 2 min = 2 hint = "Sets the minimum number of colour levels used after merging." visible = @p_modeselect=="MMF Merge Modes" && \ (@p_mmfmergemode=="Quantize" \ || @p_mmfmergemode=="Reverse Quantize" \ || @p_mmfmergemode=="Inverse Quantize" \ || @p_mmfmergemode=="Inv. Rev. Quantize" \ || @p_mmfmergemode=="Soft Quantize" \ || @p_mmfmergemode=="Rev. Soft Quantize" \ || @p_mmfmergemode=="Inv. Soft Quantize" \ || @p_mmfmergemode=="Inv. Rev. Soft Quantize") endparam int param qmax caption = "Maximum Quantize" default = 32 min = 2 hint = "Sets the maximum number of colour levels used after merging. \ Should be set larger than 'Minimum Quantize' for correct use." visible = @p_modeselect=="MMF Merge Modes" && \ (@p_mmfmergemode=="Quantize" \ || @p_mmfmergemode=="Reverse Quantize" \ || @p_mmfmergemode=="Inverse Quantize" \ || @p_mmfmergemode=="Inv. Rev. Quantize" \ || @p_mmfmergemode=="Soft Quantize" \ || @p_mmfmergemode=="Rev. Soft Quantize" \ || @p_mmfmergemode=="Inv. Soft Quantize" \ || @p_mmfmergemode=="Inv. Rev. Soft Quantize") endparam float param mingamma caption = "Minimum Gamma" default = 1.0 min = 1.0 hint = "Sets the minimum gamma to be used, use 1.0 for 'no change'." visible = @p_modeselect=="MMF Merge Modes" && \ (@p_mmfmergemode=="Gamma" || @p_mmfmergemode=="Inverse Gamma" \ || @p_mmfmergemode=="Reverse Gamma" \ || @p_mmfmergemode=="Rev. Inv. Gamma" \ || @p_mmfmergemode=="Combined Gamma" \ || @p_mmfmergemode=="Rev. Comb. Gamma" \ || @p_mmfmergemode=="Inv. Gamma" \ || @p_mmfmergemode=="Inv. Inverse Gamma" \ || @p_mmfmergemode=="Inv. Reverse Gamma" \ || @p_mmfmergemode=="Inv. Rev. Inv. Gamma" \ || @p_mmfmergemode=="Inv. Combined Gamma" \ || @p_mmfmergemode=="Inv. Rev. Comb. Gamma") endparam float param maxgamma caption = "Maximum Gamma" default = 2.0 min = 1.0 hint = "Sets the maximum gamma to be used. Should be set larger than \ 'Minimum Gamma' for correct use." visible = @p_modeselect=="MMF Merge Modes" && \ (@p_mmfmergemode=="Gamma" || @p_mmfmergemode=="Inverse Gamma" \ || @p_mmfmergemode=="Reverse Gamma" \ || @p_mmfmergemode=="Rev. Inv. Gamma" \ || @p_mmfmergemode=="Combined Gamma" \ || @p_mmfmergemode=="Rev. Comb. Gamma" \ || @p_mmfmergemode=="Inv. Gamma" \ || @p_mmfmergemode=="Inv. Inverse Gamma" \ || @p_mmfmergemode=="Inv. Reverse Gamma" \ || @p_mmfmergemode=="Inv. Rev. Inv. Gamma" \ || @p_mmfmergemode=="Inv. Combined Gamma" \ || @p_mmfmergemode=="Inv. Rev. Comb. Gamma") endparam float param redlvl caption = "Red Factor" default = 0.299 min = 0.0 hint = "The default value is directly from the red Y value from the YIQ \ model. The value (relative to the green and blue values) should \ be based on the relative perception of the brightness of the red \ monitor colour as compared to the green and blue. The brighter \ you perceive a colour the larger the value you should use \ (relatively speaking) but experimenting with wildly different \ values can produce useful effects." visible = @p_modeselect=="MMF Merge Modes" && \ (@p_mmfmergemode=="Brightness (Custom)" \ || @p_mmfmergemode=="Colour (Custom)") endparam float param greenlvl caption = "Green Factor" default = 0.587 min = 0.0 hint = "The default value is directly from the green Y value from the YIQ \ model. The value (relative to the red and blue values) should \ be based on the relative perception of the brightness of the green \ monitor colour as compared to the red and blue. The brighter \ you perceive a colour the larger the value you should use \ (relatively speaking) but experimenting with wildly different \ values can produce useful effects." visible = @p_modeselect=="MMF Merge Modes" && \ (@p_mmfmergemode=="Brightness (Custom)" \ || @p_mmfmergemode=="Colour (Custom)") endparam float param bluelvl caption = "Blue Factor" default = 0.114 min = 0.0 hint = "The default value is directly from the blue Y value from the YIQ \ model. The value (relative to the red and green values) should \ be based on the relative perception of the brightness of the blue \ monitor colour as compared to the red and green. The brighter \ you perceive a colour the larger the value you should use \ (relatively speaking) but experimenting with wildly different \ values can produce useful effects." visible = @p_modeselect=="MMF Merge Modes" && \ (@p_mmfmergemode=="Brightness (Custom)" \ || @p_mmfmergemode=="Colour (Custom)") endparam } class MMF_RGBColorMerge(common.ulb:DefaultColorMerge) { ; ; Extended colour merges.
; David Makin May 2008
; ; Anyone interested in merge modes may like to look here:
; http://www.pegtop.net/delphi/articles/blendmodes/
public: ;

; @param pparent the parent, generally "this" for the parent, or zero func MMF_RGBColorMerge(Generic pparent) DefaultColorMerge.DefaultColorMerge(pparent) endfunc ;

; @param pbottom the base color ; @param ptop the top color ; @return merged color color func Merge(color pbottom, color ptop) float red float green float blue float bottom float top if @redtop=="Red" top = red(ptop) elseif @redtop=="Green" top = green(ptop) else top = blue(ptop) endif if @redbtm=="Red" bottom = red(pbottom) elseif @redbtm=="Green" bottom = green(pbottom) else bottom = blue(pbottom) endif if @p_modeselectred==1 red = MergeChannels(bottom, top, @p_mmfmergemodered, @qminred, @qmaxred, \ @mingammared, @maxgammared) else red = red(@f_mergemode(RGB(bottom,bottom,bottom), RGB(top,top,top))) endif if @greentop=="Red" top = red(ptop) elseif @greentop=="Green" top = green(ptop) else top = blue(ptop) endif if @greenbtm=="Red" bottom = red(pbottom) elseif @greenbtm=="Green" bottom = green(pbottom) else bottom = blue(pbottom) endif if @p_modeselectgreen==1 green = MergeChannels(bottom, top, @p_mmfmergemodegreen, @qmingreen, \ @qmaxgreen, @mingammagreen, @maxgammagreen) else green = green(@f_mergemodegreen(RGB(bottom,bottom,bottom), RGB(top,top,top))) endif if @bluetop=="Red" top = red(ptop) elseif @bluetop=="Green" top = green(ptop) else top = blue(ptop) endif if @bluebtm=="Red" bottom = red(pbottom) elseif @bluebtm=="Green" bottom = green(pbottom) else bottom = blue(pbottom) endif if @p_modeselectblue==1 blue = MergeChannels(bottom, top, @p_mmfmergemodeblue, @qminblue, \ @qmaxblue, @mingammablue, @maxgammablue) else blue = blue(@f_mergemodeblue(RGB(bottom,bottom,bottom), RGB(top,top,top))) endif return RGBA(red, green, blue, alpha(ptop)) endfunc float func MergeChannels(float bottom, float top, int mode, int qmin, \ int qmax, float mingamma, float maxgamma) if @clamp if top<0.0 top = 0.0 elseif top>1.0 top = 1.0 endif if bottom<0.0 bottom = 0.0 elseif bottom>1.0 bottom = 1.0 endif endif if mode==0;"Exclusion" return bottom + top - 2*bottom*top elseif mode==1;"Fade Down" return top * (1 - top + bottom) elseif mode==2;"Fade Up" return bottom + top*(top - bottom) elseif mode==3;"Contrast Down" return 0.5 + top*(bottom - 0.5) elseif mode==4;"Contrast Up" if bottom<0.5 return bottom - 2.0*top*bottom*(0.5 - bottom) else return bottom + 2.0*top*(1.0 - bottom)*(bottom - 0.5) endif elseif mode==5;"Dodge" ; Here we clamp the maximum returned to 1.0 because of the special case ; when the color channel in ptop is one (or more). top = 1.0 - top if bottom<=0 return 0.0 elseif top<=0.0 return 1.0 else top = bottom/top if top>1.0 top = 1.0 endif return top endif elseif mode==6;"Burn" ; Here we clamp the minimum returned to 0 because of the special case ; when the color channel in ptop is zero (or less). if top<=0.0 return 0.0 else top = 1.0 - (1.0 - bottom)/top if top<0.0 top = 0.0 endif return top endif elseif mode==7;"Negation" return 1.0 - abs(1.0 - top - bottom) elseif mode==8;"Reflect" ; Here we clamp the maximum returned to 1.0 because of the special case ; when the color channel in ptop is one (or more). top = 1.0 - top if bottom<=0 return 0.0 elseif top<=0.0 return 1.0 else top = sqr(bottom)/top if top>1.0 top = 1.0 endif return top endif elseif mode==9;"Freeze" ; Here we clamp the minimum returned to 0 because of the special case ; when the color channel in ptop is zero (or less). if top<=0.0 return 0.0 else top = 1.0 - sqr(1.0 - bottom)/top if top<0.0 top = 0.0 endif return top endif elseif mode==10;"Rev. Contrast Down" return 0.5 + (1.0 - top)*(bottom - 0.5) elseif mode==11;"Rev. Contrast Up" if bottom<0.5 return bottom - 2.0*(1.0 - top)*bottom*(0.5 - bottom) else return bottom + 2.0*(1.0 - top)*(1.0 - bottom)*(bottom - 0.5) endif elseif mode==12;"Fade" if top<0.5 return 2.0 * top * (0.5 - top + bottom) else return bottom + 2.0 * (top - 0.5)*(top - bottom) endif elseif mode==13;"Reverse Fade" if top<0.5 return bottom + 2.0 * top * (top - bottom) else return bottom + 2.0 * (1.0 - top)*(top - bottom) endif elseif mode==14 || mode==15;"Contrast" || "Reverse Contrast" if mode==15;"Reverse Contrast" top = 1.0 - top endif if top<0.5 return 0.5 + 2.0 * top * (bottom - 0.5) else top = 2.0 * (top - 0.5) if bottom<0.5 return bottom - 2.0*top*bottom*(0.5 - bottom) else return bottom + 2.0*top*(1.0 - bottom)*(bottom - 0.5) endif endif elseif mode==16;"Quantize" int nr = round(qmax - (qmax-qmin)*(2.0/(1.0 + top) - 1.0)) - 1 return floor(bottom*(nr+0.999))/nr elseif mode==17;"Reverse Quantize" int nr = round(qmax - (qmax-qmin)*(2.0/(2.0 - top) - 1.0)) - 1 return floor(bottom*(nr+0.999))/nr elseif mode==18;"Gamma" return bottom^(mingamma+(maxgamma-mingamma)*top) elseif mode==19;"Inverse Gamma" return bottom^(1.0/(mingamma+(maxgamma-mingamma)*top)) elseif mode==20;"Reverse Gamma" return bottom^(mingamma+(maxgamma-mingamma)*(1.0-top)) elseif mode==21;"Rev. Inv. Gamma" return bottom^(1.0/(mingamma+(maxgamma-mingamma)*(1.0-top))) elseif mode==22;"Combined Gamma" if top<0.5 return bottom^(mingamma+2.0*(maxgamma-mingamma)*(0.5-top)) else return bottom^(1.0/(mingamma+2.0*(maxgamma-mingamma)*(top-0.5))) endif elseif mode==23;"Rev. Comb. Gamma" if top<0.5 return bottom^(1.0/(mingamma+2.0*(maxgamma-mingamma)*(0.5-top))) else return bottom^(mingamma+2.0*(maxgamma-mingamma)*(top-0.5)) endif elseif mode==24;"Stamp" top = bottom + 2.0*top - 1.0 if top<0.0 return 0.0 elseif top>1.0 return 1.0 endif return top elseif mode==25;"Soft Dodge" if bottom<=0 return 0.0 elseif bottom+top<=1.0 if top>=1.0 return 1.0 elseif (top = 0.5*bottom/(1.0 - top))>1.0 return 1.0 endif elseif (top = 1.0 - 0.5*(1.0 - top)/bottom)<0.0 return 0.0 endif return top elseif mode==26;"Soft Burn" if top<=0 return 0.0 elseif top+bottom<=1.0 if bottom>=1.0 return 1.0 elseif (top = 0.5*top/(1.0 - bottom))>1.0 return 1.0 endif elseif (top = 1.0 - 0.5*(1.0 - bottom)/top)<0.0 return 0.0 endif return top elseif mode==27;"Inverse Dodge" ; Here we clamp the maximum returned to 1.0 because of the special case ; when the color channel in ptop is one (or more). bottom = 1.0 - bottom if top<=0 return 0 elseif bottom<=0.0 return 1.0 else top = top/bottom if top>1.0 return 1.0 endif return top endif elseif mode==28;"Inverse Burn" ; Here we clamp the minimum returned to 0 because of the special case ; when the color channel in ptop is zero (or less). if bottom<=0.0 return 0.0 else top = 1.0 - (1.0 - top)/bottom if top<0.0 return 0.0 endif return top endif elseif mode==29;"Glow" ; Here we clamp the maximum returned to 1.0 because of the special case ; when the color channel in ptop is one (or more). bottom = 1.0 - bottom if top<=0 return 0.0 elseif bottom<=0.0 return 1.0 else top = sqr(top)/bottom if top>1.0 return 1.0 endif return top endif elseif mode==30;"Heat" ; Here we clamp the minimum returned to 0 because of the special case ; when the color channel in ptop is zero (or less). if bottom<=0.0 return 0.0 else top = 1.0 - sqr(1.0 - top)/bottom if top<0.0 return 0.0 endif return top endif elseif mode==31;"Inv. Fade Down" return bottom * (1 - bottom + top) elseif mode==32;"Inv. Fade Up" return top + bottom*(bottom - top) elseif mode==33;"Inv. Contrast Down" return 0.5 + bottom*(top - 0.5) elseif mode==34;"Inv. Contrast Up" if top<0.5 return top - 2.0*bottom*top*(0.5 - top) else return top + 2.0*bottom*(1.0 - top)*(top - 0.5) endif elseif mode==35;"Inv. Rev. Con. Down" return 0.5 + (1.0 - bottom)*(top - 0.5) elseif mode==36;"Inv. Rev. Con. Up" if top<0.5 return top - 2.0*(1.0 - bottom)*top*(0.5 - top) else return top + 2.0*(1.0 - bottom)*(1.0 - top)*(top - 0.5) endif elseif mode==37;"Inverse Fade" if bottom<0.5 return 2.0 * bottom * (0.5 - bottom + top) else return top + 2.0 * (bottom - 0.5)*(bottom - top) endif elseif mode==38;"Inv. Rev. Fade" if bottom<0.5 return top + 2.0 * bottom * (bottom - top) else return top + 2.0 * (1.0 - bottom)*(bottom - top) endif elseif mode==39 \ || mode==40 ;"Inverse Contrast" || "Inv. Rev. Contrast" if mode==40 bottom = 1.0 - bottom endif if bottom<0.5 return 0.5 + 2.0 * bottom * (top - 0.5) else bottom = 2.0 * (bottom - 0.5) if top<0.5 return top - 2.0*bottom*top*(0.5 - top) else return top + 2.0*bottom*(1.0 - top)*(top - 0.5) endif endif elseif mode==41;"Inverse Quantize" int nr = round(qmax - (qmax-qmin)*(2.0/(1.0 + bottom) - 1.0)) - 1 return floor(top*(nr+0.999))/nr elseif mode==42;"Inv. Rev. Quantize" int nr = round(qmax - (qmax-qmin)*(2.0/(2.0 - bottom) - 1.0)) - 1 return floor(top*(nr+0.999))/nr elseif mode==43;"Inv. Gamma" return top^(mingamma+(maxgamma-mingamma)*bottom) elseif mode==44;"Inv. Inverse Gamma" return top^(1.0/(mingamma+(maxgamma-mingamma)*bottom)) elseif mode==45;"Inv. Reverse Gamma" return top^(mingamma+(maxgamma-mingamma)*(1.0-bottom)) elseif mode==46;"Inv. Rev. Inv. Gamma" return top^(1.0/(mingamma+(maxgamma-mingamma)*(1.0-bottom))) elseif mode==47;"Inv. Combined Gamma" if bottom<0.5 return top^(mingamma+2.0*(maxgamma-mingamma)*(0.5-bottom)) else return top^(1.0/(mingamma+2.0*(maxgamma-mingamma)*(bottom-0.5))) endif elseif mode==48;"Inv. Rev. Comb. Gamma" if bottom<0.5 return top^(1.0/(mingamma+2.0*(maxgamma-mingamma)*(0.5-bottom))) else return top^(mingamma+2.0*(maxgamma-mingamma)*(bottom-0.5)) endif elseif mode==49;"Inverse Stamp" top = top + 2.0*bottom - 1.0 if top<0.0 return 0.0 elseif top>1.0 return 1.0 endif return top elseif mode==50;"Pin Light" if (top>=0.5 && topbottom) return bottom endif return top elseif mode==51;"Reverse Pin Light" if (top>=0.5 && top>bottom) || (top<0.5 && top=0.5 && bottomtop) return top endif return bottom elseif mode==53;"Inv. Rev. Pin Light" if (bottom>=0.5 && bottom>top) || (bottom<0.5 && bottom1.0 r = 1.0 endif return r else;if mode==60;"Inverse Double" float r = (bottom+1.0)*top if r>1.0 r = 1.0 endif return r endif ; mode endfunc default: Title = "MMF RGB Colour Merge" int param v_mmfrgbcolormerge caption = "Version (MMF RGB Colour Merge)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam bool param clamp caption = "Clamp Values" default = false hint = "When enabled the RGB values in both the top and bottom colours \ are clamped to the range 0<=v<=1. Should not be necessary most \ of the time." visible = @p_modeselectred=="MMF Merge Modes" \ || @p_modeselectgreen=="MMF Merge Modes" \ || @p_modeselectblue=="MMF Merge Modes" endparam heading text = "Output Red" endheading int param redtop caption = "Red Top Colour" enum = "Red" "Green" "Blue" default = 0 hint = "Choose which colour from the top layer is used to produce \ the output red." endparam int param redbtm caption = "Red Bottom Colour" enum = "Red" "Green" "Blue" default = 0 hint = "Choose which colour from the bottom layer is used to produce \ the output red." endparam int param p_modeselectred caption = "Merge Modes for Red" enum = "Original Merge Modes" "MMF Merge Modes" default = 0 hint = "Choose from different collections of merge modes." endparam color func f_mergemode caption = "Merge Mode (Red)" default = mergemultiply() hint = "Sets the method used to merge input colors with." visible = @p_modeselectred=="Original Merge Modes" endfunc int param p_mmfmergemodered caption = "MMF Merge Mode (Red)" enum = "Exclusion" "Fade Down" "Fade Up" "Contrast Down" "Contrast Up" \ "Dodge" "Burn" "Negation" "Reflect" "Freeze" "Rev. Contrast Down" \ "Rev. Contrast Up" "Fade" "Reverse Fade" "Contrast" \ "Reverse Contrast" "Quantize" "Reverse Quantize" "Gamma" \ "Inverse Gamma" "Reverse Gamma" "Rev. Inv. Gamma" "Combined Gamma" \ "Rev. Comb. Gamma" "Stamp" "Soft Dodge" "Soft Burn" \ "Inverse Dodge" "Inverse Burn" "Glow" "Heat" "Inv. Fade Down" \ "Inv. Fade Up" "Inv. Contrast Down" "Inv. Contrast Up" \ "Inv. Rev. Con. Down" "Inv. Rev. Con. Up" "Inverse Fade" \ "Inv. Rev. Fade" "Inverse Contrast" "Inv. Rev. Contrast" \ "Inverse Quantize" "Inv. Rev. Quantize" "Inv. Gamma" \ "Inv. Inverse Gamma" "Inv. Reverse Gamma" "Inv. Rev. Inv. Gamma" \ "Inv. Combined Gamma" "Inv. Rev. Comb. Gamma" "Inverse Stamp" \ "Pin Light" "Reverse Pin Light" "Inv. Pin Light" \ "Inv. Rev. Pin Light" "Soft Quantize" "Rev. Soft Quantize" \ "Inv. Soft Quantize" "Inv. Rev. Soft Quantize" \ "Inverse Subtraction" "Double" "Inverse Double" default = 0 hint = "Extra merge modes, just try them out !" visible = @p_modeselectred=="MMF Merge Modes" endparam int param qminred caption = "Minimum Quantize" default = 2 min = 2 hint = "Sets the minimum number of colour levels used after merging." visible = @p_modeselectred=="MMF Merge Modes" && \ (@p_mmfmergemodered=="Quantize" \ || @p_mmfmergemodered=="Reverse Quantize" \ || @p_mmfmergemodered=="Inverse Quantize" \ || @p_mmfmergemodered=="Inv. Rev. Quantize" \ || @p_mmfmergemodered=="Soft Quantize" \ || @p_mmfmergemodered=="Rev. Soft Quantize" \ || @p_mmfmergemodered=="Inv. Soft Quantize" \ || @p_mmfmergemodered=="Inv. Rev. Soft Quantize") endparam int param qmaxred caption = "Maximum Quantize" default = 32 min = 2 hint = "Sets the maximum number of colour levels used after merging. \ Should be set larger than 'Minimum Quantize' for correct use." visible = @p_modeselectred=="MMF Merge Modes" && \ (@p_mmfmergemodered=="Quantize" \ || @p_mmfmergemodered=="Reverse Quantize" \ || @p_mmfmergemodered=="Inverse Quantize" \ || @p_mmfmergemodered=="Inv. Rev. Quantize" \ || @p_mmfmergemodered=="Soft Quantize" \ || @p_mmfmergemodered=="Rev. Soft Quantize" \ || @p_mmfmergemodered=="Inv. Soft Quantize" \ || @p_mmfmergemodered=="Inv. Rev. Soft Quantize") endparam float param mingammared caption = "Minimum Gamma" default = 1.0 min = 1.0 hint = "Sets the minimum gamma to be used, use 1.0 for 'no change'." visible = @p_modeselectred=="MMF Merge Modes" && \ (@p_mmfmergemodered=="Gamma" \ || @p_mmfmergemodered=="Inverse Gamma" \ || @p_mmfmergemodered=="Reverse Gamma" \ || @p_mmfmergemodered=="Rev. Inv. Gamma" \ || @p_mmfmergemodered=="Combined Gamma" \ || @p_mmfmergemodered=="Rev. Comb. Gamma" \ || @p_mmfmergemodered=="Inv. Gamma" \ || @p_mmfmergemodered=="Inv. Inverse Gamma" \ || @p_mmfmergemodered=="Inv. Reverse Gamma" \ || @p_mmfmergemodered=="Inv. Rev. Inv. Gamma" \ || @p_mmfmergemodered=="Inv. Combined Gamma" \ || @p_mmfmergemodered=="Inv. Rev. Comb. Gamma") endparam float param maxgammared caption = "Maximum Gamma" default = 2.0 min = 1.0 hint = "Sets the maximum gamma to be used. Should be set larger than \ 'Minimum Gamma' for correct use." visible = @p_modeselectred=="MMF Merge Modes" && \ (@p_mmfmergemodered=="Gamma" \ || @p_mmfmergemodered=="Inverse Gamma" \ || @p_mmfmergemodered=="Reverse Gamma" \ || @p_mmfmergemodered=="Rev. Inv. Gamma" \ || @p_mmfmergemodered=="Combined Gamma" \ || @p_mmfmergemodered=="Rev. Comb. Gamma" \ || @p_mmfmergemodered=="Inv. Gamma" \ || @p_mmfmergemodered=="Inv. Inverse Gamma" \ || @p_mmfmergemodered=="Inv. Reverse Gamma" \ || @p_mmfmergemodered=="Inv. Rev. Inv. Gamma" \ || @p_mmfmergemodered=="Inv. Combined Gamma" \ || @p_mmfmergemodered=="Inv. Rev. Comb. Gamma") endparam heading text = "Output Green" endheading int param greentop caption = "Green Top Colour" enum = "Red" "Green" "Blue" default = 1 hint = "Choose which colour from the top layer is used to produce \ the output green." endparam int param greenbtm caption = "Green Bottom Colour" enum = "Red" "Green" "Blue" default = 1 hint = "Choose which colour from the bottom layer is used to produce \ the output green." endparam int param p_modeselectgreen caption = "Merge Modes for Green" enum = "Original Merge Modes" "MMF Merge Modes" default = 0 hint = "Choose from different collections of merge modes." endparam color func f_mergemodegreen caption = "Merge Mode (Green)" default = mergemultiply() hint = "Sets the method used to merge input colors with." visible = @p_modeselectgreen=="Original Merge Modes" endfunc int param p_mmfmergemodegreen caption = "MMF Merge Mode (Green)" enum = "Exclusion" "Fade Down" "Fade Up" "Contrast Down" "Contrast Up" \ "Dodge" "Burn" "Negation" "Reflect" "Freeze" "Rev. Contrast Down" \ "Rev. Contrast Up" "Fade" "Reverse Fade" "Contrast" \ "Reverse Contrast" "Quantize" "Reverse Quantize" "Gamma" \ "Inverse Gamma" "Reverse Gamma" "Rev. Inv. Gamma" "Combined Gamma" \ "Rev. Comb. Gamma" "Stamp" "Soft Dodge" "Soft Burn" \ "Inverse Dodge" "Inverse Burn" "Glow" "Heat" "Inv. Fade Down" \ "Inv. Fade Up" "Inv. Contrast Down" "Inv. Contrast Up" \ "Inv. Rev. Con. Down" "Inv. Rev. Con. Up" "Inverse Fade" \ "Inv. Rev. Fade" "Inverse Contrast" "Inv. Rev. Contrast" \ "Inverse Quantize" "Inv. Rev. Quantize" "Inv. Gamma" \ "Inv. Inverse Gamma" "Inv. Reverse Gamma" "Inv. Rev. Inv. Gamma" \ "Inv. Combined Gamma" "Inv. Rev. Comb. Gamma" "Inverse Stamp" \ "Pin Light" "Reverse Pin Light" "Inv. Pin Light" \ "Inv. Rev. Pin Light" "Soft Quantize" "Rev. Soft Quantize" \ "Inv. Soft Quantize" "Inv. Rev. Soft Quantize" \ "Inverse Subtraction" "Double" "Inverse Double" default = 0 hint = "Extra merge modes, just try them out !" visible = @p_modeselectgreen=="MMF Merge Modes" endparam int param qmingreen caption = "Minimum Quantize" default = 2 min = 2 hint = "Sets the minimum number of colour levels used after merging." visible = @p_modeselectgreen=="MMF Merge Modes" && \ (@p_mmfmergemodegreen=="Quantize" \ || @p_mmfmergemodegreen=="Reverse Quantize" \ || @p_mmfmergemodegreen=="Inverse Quantize" \ || @p_mmfmergemodegreen=="Inv. Rev. Quantize" \ || @p_mmfmergemodegreen=="Soft Quantize" \ || @p_mmfmergemodegreen=="Rev. Soft Quantize" \ || @p_mmfmergemodegreen=="Inv. Soft Quantize" \ || @p_mmfmergemodegreen=="Inv. Rev. Soft Quantize") endparam int param qmaxgreen caption = "Maximum Quantize" default = 32 min = 2 hint = "Sets the maximum number of colour levels used after merging. \ Should be set larger than 'Minimum Quantize' for correct use." visible = @p_modeselectgreen=="MMF Merge Modes" && \ (@p_mmfmergemodegreen=="Quantize" \ || @p_mmfmergemodegreen=="Reverse Quantize" \ || @p_mmfmergemodegreen=="Inverse Quantize" \ || @p_mmfmergemodegreen=="Inv. Rev. Quantize" \ || @p_mmfmergemodegreen=="Soft Quantize" \ || @p_mmfmergemodegreen=="Rev. Soft Quantize" \ || @p_mmfmergemodegreen=="Inv. Soft Quantize" \ || @p_mmfmergemodegreen=="Inv. Rev. Soft Quantize") endparam float param mingammagreen caption = "Minimum Gamma" default = 1.0 min = 1.0 hint = "Sets the minimum gamma to be used, use 1.0 for 'no change'." visible = @p_modeselectgreen=="MMF Merge Modes" && \ (@p_mmfmergemodegreen=="Gamma" \ || @p_mmfmergemodegreen=="Inverse Gamma" \ || @p_mmfmergemodegreen=="Reverse Gamma" \ || @p_mmfmergemodegreen=="Rev. Inv. Gamma" \ || @p_mmfmergemodegreen=="Combined Gamma" \ || @p_mmfmergemodegreen=="Rev. Comb. Gamma" \ || @p_mmfmergemodegreen=="Inv. Gamma" \ || @p_mmfmergemodegreen=="Inv. Inverse Gamma" \ || @p_mmfmergemodegreen=="Inv. Reverse Gamma" \ || @p_mmfmergemodegreen=="Inv. Rev. Inv. Gamma" \ || @p_mmfmergemodegreen=="Inv. Combined Gamma" \ || @p_mmfmergemodegreen=="Inv. Rev. Comb. Gamma") endparam float param maxgammagreen caption = "Maximum Gamma" default = 2.0 min = 1.0 hint = "Sets the maximum gamma to be used. Should be set larger than \ 'Minimum Gamma' for correct use." visible = @p_modeselectgreen=="MMF Merge Modes" && \ (@p_mmfmergemodegreen=="Gamma" \ || @p_mmfmergemodegreen=="Inverse Gamma" \ || @p_mmfmergemodegreen=="Reverse Gamma" \ || @p_mmfmergemodegreen=="Rev. Inv. Gamma" \ || @p_mmfmergemodegreen=="Combined Gamma" \ || @p_mmfmergemodegreen=="Rev. Comb. Gamma" \ || @p_mmfmergemodegreen=="Inv. Gamma" \ || @p_mmfmergemodegreen=="Inv. Inverse Gamma" \ || @p_mmfmergemodegreen=="Inv. Reverse Gamma" \ || @p_mmfmergemodegreen=="Inv. Rev. Inv. Gamma" \ || @p_mmfmergemodegreen=="Inv. Combined Gamma" \ || @p_mmfmergemodegreen=="Inv. Rev. Comb. Gamma") endparam heading text = "Output Blue" endheading int param bluetop caption = "Blue Top Colour" enum = "Red" "Green" "Blue" default = 2 hint = "Choose which colour from the top layer is used to produce \ the output blue." endparam int param bluebtm caption = "Blue Bottom Colour" enum = "Red" "Green" "Blue" default = 2 hint = "Choose which colour from the bottom layer is used to produce \ the output blue." endparam int param p_modeselectblue caption = "Merge Modes for Blue" enum = "Original Merge Modes" "MMF Merge Modes" default = 0 hint = "Choose from different collections of merge modes." endparam color func f_mergemodeblue caption = "Merge Mode (Blue)" default = mergemultiply() hint = "Sets the method used to merge input colors with." visible = @p_modeselectblue=="Original Merge Modes" endfunc int param p_mmfmergemodeblue caption = "MMF Merge Mode (Blue)" enum = "Exclusion" "Fade Down" "Fade Up" "Contrast Down" "Contrast Up" \ "Dodge" "Burn" "Negation" "Reflect" "Freeze" "Rev. Contrast Down" \ "Rev. Contrast Up" "Fade" "Reverse Fade" "Contrast" \ "Reverse Contrast" "Quantize" "Reverse Quantize" "Gamma" \ "Inverse Gamma" "Reverse Gamma" "Rev. Inv. Gamma" "Combined Gamma" \ "Rev. Comb. Gamma" "Stamp" "Soft Dodge" "Soft Burn" \ "Inverse Dodge" "Inverse Burn" "Glow" "Heat" "Inv. Fade Down" \ "Inv. Fade Up" "Inv. Contrast Down" "Inv. Contrast Up" \ "Inv. Rev. Con. Down" "Inv. Rev. Con. Up" "Inverse Fade" \ "Inv. Rev. Fade" "Inverse Contrast" "Inv. Rev. Contrast" \ "Inverse Quantize" "Inv. Rev. Quantize" "Inv. Gamma" \ "Inv. Inverse Gamma" "Inv. Reverse Gamma" "Inv. Rev. Inv. Gamma" \ "Inv. Combined Gamma" "Inv. Rev. Comb. Gamma" "Inverse Stamp" \ "Pin Light" "Reverse Pin Light" "Inv. Pin Light" \ "Inv. Rev. Pin Light" "Soft Quantize" "Rev. Soft Quantize" \ "Inv. Soft Quantize" "Inv. Rev. Soft Quantize" \ "Inverse Subtraction" "Double" "Inverse Double" default = 0 hint = "Extra merge modes, just try them out !" visible = @p_modeselectblue=="MMF Merge Modes" endparam int param qminblue caption = "Minimum Quantize" default = 2 min = 2 hint = "Sets the minimum number of colour levels used after merging." visible = @p_modeselectblue=="MMF Merge Modes" && \ (@p_mmfmergemodeblue=="Quantize" \ || @p_mmfmergemodeblue=="Reverse Quantize" \ || @p_mmfmergemodeblue=="Inverse Quantize" \ || @p_mmfmergemodeblue=="Inv. Rev. Quantize" \ || @p_mmfmergemodeblue=="Soft Quantize" \ || @p_mmfmergemodeblue=="Rev. Soft Quantize" \ || @p_mmfmergemodeblue=="Inv. Soft Quantize" \ || @p_mmfmergemodeblue=="Inv. Rev. Soft Quantize") endparam int param qmaxblue caption = "Maximum Quantize" default = 32 min = 2 hint = "Sets the maximum number of colour levels used after merging. \ Should be set larger than 'Minimum Quantize' for correct use." visible = @p_modeselectblue=="MMF Merge Modes" && \ (@p_mmfmergemodeblue=="Quantize" \ || @p_mmfmergemodeblue=="Reverse Quantize" \ || @p_mmfmergemodeblue=="Inverse Quantize" \ || @p_mmfmergemodeblue=="Inv. Rev. Quantize" \ || @p_mmfmergemodeblue=="Soft Quantize" \ || @p_mmfmergemodeblue=="Rev. Soft Quantize" \ || @p_mmfmergemodeblue=="Inv. Soft Quantize" \ || @p_mmfmergemodeblue=="Inv. Rev. Soft Quantize") endparam float param mingammablue caption = "Minimum Gamma" default = 1.0 min = 1.0 hint = "Sets the minimum gamma to be used, use 1.0 for 'no change'." visible = @p_modeselectblue=="MMF Merge Modes" && \ (@p_mmfmergemodeblue=="Gamma" \ || @p_mmfmergemodeblue=="Inverse Gamma" \ || @p_mmfmergemodeblue=="Reverse Gamma" \ || @p_mmfmergemodeblue=="Rev. Inv. Gamma" \ || @p_mmfmergemodeblue=="Combined Gamma" \ || @p_mmfmergemodeblue=="Rev. Comb. Gamma" \ || @p_mmfmergemodeblue=="Inv. Gamma" \ || @p_mmfmergemodeblue=="Inv. Inverse Gamma" \ || @p_mmfmergemodeblue=="Inv. Reverse Gamma" \ || @p_mmfmergemodeblue=="Inv. Rev. Inv. Gamma" \ || @p_mmfmergemodeblue=="Inv. Combined Gamma" \ || @p_mmfmergemodeblue=="Inv. Rev. Comb. Gamma") endparam float param maxgammablue caption = "Maximum Gamma" default = 2.0 min = 1.0 hint = "Sets the maximum gamma to be used. Should be set larger than \ 'Minimum Gamma' for correct use." visible = @p_modeselectblue=="MMF Merge Modes" && \ (@p_mmfmergemodeblue=="Gamma" \ || @p_mmfmergemodeblue=="Inverse Gamma" \ || @p_mmfmergemodeblue=="Reverse Gamma" \ || @p_mmfmergemodeblue=="Rev. Inv. Gamma" \ || @p_mmfmergemodeblue=="Combined Gamma" \ || @p_mmfmergemodeblue=="Rev. Comb. Gamma" \ || @p_mmfmergemodeblue=="Inv. Gamma" \ || @p_mmfmergemodeblue=="Inv. Inverse Gamma" \ || @p_mmfmergemodeblue=="Inv. Reverse Gamma" \ || @p_mmfmergemodeblue=="Inv. Rev. Inv. Gamma" \ || @p_mmfmergemodeblue=="Inv. Combined Gamma" \ || @p_mmfmergemodeblue=="Inv. Rev. Comb. Gamma") endparam } class MMF_MixedLighting(common.ulb:DirectColoring) { ; ; Intended for use with the 'Gradient_Slope' class formula.
; David Makin May 2008
; public: ; @param pparent the parent,generally "this" for the parent, or zero func MMF_MixedLighting(Generic pparent) DirectColoring(pparent) fBm = new @fBm(this) transfbm = new @transfbm(this) trans = new @trans(this) ltrans = new @ltrans(this) merge = new @merge(this) trap = new @trap(this) if @perturb && @usefbm fBm.GlobalInit(0) endif endfunc ; @param pz the initial z value ; @param ppixel the location, usually #pixel func Init(complex pz,complex ppixel) if !@usefbm transfbm.Init(pz) endif trans.Init(pz) ltrans.Init(pz) trap.init(pz) if @InitfBm=="Pixel" fBmInit = 4.0*ppixel elseif @InitfBm=="Initial z" fBmInit = 4.0*pz endif endfunc ; @param pz the z value ; @return a colour color func Result(complex pz) float v = @ambient + (1.0 - @ambient)*imag(pz) if @mode!=1 if @perturb if @InitfBm!="Colour and Light" if @usefbm v = @str*transfbm.Iterate(fBm.GetfBm(fBmInit)) \ + (1.0-@str)*ltrans.Iterate(v) else v = @str*transfbm.Iterate(trap.Iterate(fBmInit)) \ + (1.0-@str)*ltrans.Iterate(v) endif else if @usefbm v = @str*transfbm.Iterate(fBm.GetfBm(100*pz)) \ + (1.0-@str)*ltrans.Iterate(v) else v = @str*transfbm.Iterate(trap.Iterate(100*pz)) \ + (1.0-@str)*ltrans.Iterate(v) endif endif elseif @v_MixedLighting>0 v = ltrans.Iterate(v) endif if @invert v = 1.0 - v endif if @lpos v = abs(v) endif endif if @mode<2 float b = trans.Iterate(real(pz)) if @pos0 b = abs(b) endif color c = gradient(b) if @mode==0 color l = @lightcol*v l = rgba(red(l), green(l), blue(l), @lightop) if @reverse return merge.FullMerge(l,c,@opacity) else return merge.FullMerge(c,l,@opacity) endif else return c endif elseif @mode==2 color l = @lightcol*v return rgba(red(l), green(l), blue(l), @lightop) elseif @mode==3 return gradient(0.9975*v) else float b = trans.iterate(real(pz)) ; if @v_MixedLighting=="1.0" ; b = trans.iterate(real(#z)) ; NB. using #z here was a mistake in v1.0 ; endif if @pos b = abs(b) endif ; if @v_MixedLighting!="1.0" if !@lrept if v<0.0 v = 0.0 elseif v>1.0 v = 1.0 endif endif v = v*0.99999 ; so the %1 won't wrap to 0 for 1 ; endif if !@rept if b<0.0 b = 0.0 elseif b>0.99999 b = 0.99999 endif endif ; if @v_MixedLighting=="1.0" ; v = 0.5 + 0.4975*v ; b = 0.4975*(b%1) ; else if (v = v%1)<0 v = 1.0 + v endif if (b = b%1)<0 b = 1.0 + b endif v = 0.5 + 0.4975*v b = 0.4975*b ; endif if @reverse return merge.FullMerge(gradient(v),gradient(b),@opacity) else return merge.FullMerge(gradient(b),gradient(v),@opacity) endif endif endfunc private: DefaultColorMerge merge Transfer transfbm Transfer trans Transfer ltrans MMF_AltfBm fBm TrapShape trap complex fBmInit default: title = "MMF Mixed Lighting (direct)" heading text = "Intended for use with the 'MMF Gradient Slope' class formula." endheading int param v_MixedLighting caption = "Version (MMF Mixed Lighting)" enum = "1.1" "1.2" default = 1 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number. Version 1.2 enables the 'Light \ transfer' when not using perturbation." visible = @v_MixedLighting<1 endparam int param mode caption = "Method" enum = "Mixed" "Just colouring" "Lighting (greyscale)" \ "Lighting (gradient)" "Split Palette" default =0 hint = "In 'Split Palette' mode colours 0 to 199 in the palette are used \ for the colouring and colours 200 to 399 are used for the \ lighting allowing coloured lighting combined with the base \ colouring. Note that this \ mode will only work properly with 'Color Density' set to 1, \ 'Transfer Function' set to Linear and 'Gradient Offset' set to 0. \ Also note that to avoid hard colour breaks colour 0 should be the \ same as colour 199 if the colouring wraps and colour 200 should \ be the same as colour 399 if the lighting wraps." endparam heading caption = "Combined parameters" visible = @mode==0 || @mode==4 endheading DefaultColorMerge param merge caption = "Merge method" default = MMF_ExtendedColorMerge visible = @mode==0 || @mode==4 endparam float param opacity caption = "Merge Opacity" default = 1.0 visible = @mode==0 || @mode==4 endparam bool param reverse caption = "Reverse colour and light" default = false hint = "Normally the lighting is applied as the top layer in the merge, \ enable this to reverse the order so the colouring is the top \ layer." visible = @mode==0 || @mode==4 endparam heading caption = "Colouring parameters" visible = @mode<2 || @mode==4 endheading Transfer param trans caption = "Colouring transfer" default = DefaultGradientTransfer hint = "Note that normally you should ensure that the returned value is \ positive." visible = @mode<2 || @mode==4 endparam bool param pos0 caption = "Force Positive Colour" default = false hint = "When enabled the absolute value of the colour is taken." visible = @mode<2 endparam bool param pos caption = "Force Positive Colour" default = true hint = "When enabled the absolute value of the colour is taken." visible = @mode==4 endparam bool param rept caption = "Repeat Colouring" default = true hint = "Allows you to specify whether the colouring value should be \ allowed to wrap around the gradient or not." visible = @mode==4 endparam heading caption = "Lighting parameters" visible = @mode!=1 endheading color param lightcol caption = "Light Colour" default = rgb(1.0, 1.0, 1.0) hint = "Sets the colour of the light." visible = @mode==0 || @mode==2 endparam float param lightop caption = "Light Opacity" default = 1.0 hint = "Sets the opacity of the light." visible = @mode==0 || @mode==2 endparam float param ambient caption = "Ambient Light" default = 0.0 min = -1.0 max = 1.0 hint = "Note that this will combine with any ambient light setting in the \ main formula." visible = @mode!=1 endparam bool param invert caption = "Invert lighting" default = false visible = @mode!=1 endparam bool param perturb caption = "Perturb the lighting" default = false hint = "When enabled you can perturb the light values using fBm." visible = @mode!=1 endparam int param InitfBm caption = "Perturbation initialisation" enum = "Pixel" "Initial z" "Colour and Light" default = 0 endparam float param str caption = "Perturbation strength" default = 0.5 min = 0.0 max = 1.0 hint = "Using 0.0 will produce no perturbation, using 1.0 will produce \ fBm only as the lighting." visible = @mode!=1 && @perturb endparam bool param usefbm caption = "Use Plain Alternative fBm ?" default = true hint = "If you disable this then you'll get a choice of plug-ins." visible = @mode!=1 && @perturb endparam MMF_AltfBm param fBm caption = "Perturbation" default = MMF_AltfBm visible = @mode!=1 && @perturb && @usefbm endparam Trapshape param trap caption = "Perturbation" default = MMF_TrapShapefBm visible = @mode!=1 && @perturb && !@usefbm endparam Transfer param transfbm caption = "Perturbation transfer" default = NullTransfer hint = "Normally transfers that take a number in the range 0..1 and \ return a number in the range 0..1 should be used." visible = @mode!=1 && @perturb endparam Transfer param ltrans caption = "Light transfer" default = NullTransfer hint = "Normally transfers that take a number in the range 0..1 and \ return a number in the range 0..1 should be used." visible = @mode!=1 endparam bool param lpos caption = "Force Positive Light" default = false hint = "When enabled the absolute value of the light is taken." visible = @mode!=1 endparam bool param lrept caption = "Repeat Lighting" default = false hint = "Allows you to specify whether the lighting value should be \ allowed to wrap around the gradient or not." visible = @mode==4 endparam } class MMF_ImageImport(common.ulb:ImageWrapper) { public: func MMF_ImageImport(Generic pparent) ImageWrapper.ImageWrapper(pparent) m_ImportedImage = new @p_importedimage if @p_seamless && @p_wrap && @p_twotile m_TileImage = new @p_tileimage endif m_Transform = new @p_transform(this) m_Transform.Init(0) m_Transform1 = new @p_transform1(this) m_Transform1.Init(0) m_fbm = new @p_fbm(this) m_fbm.GlobalInit(0) if @adjustlayer if @v_imageimport<101 m_Adjust = new @f_adjust(this) else m_Adjustment = new @f_adjustment(this) endif endif if !getEmpty() && @p_seamless m_Widthm1 = getWidth() m_Heightm1 = getHeight() m_InvWidth = 1.0/m_Widthm1 m_InvHeight = 1.0/m_Heightm1 m_Widthm1 = m_Widthm1 - 1.0 m_Heightm1 = m_Heightm1 - 1.0 if @p_wrap && @p_twotile m_tWidthm1 = m_TileImage.getWidth() m_tHeightm1 = m_TileImage.getHeight() m_tInvWidth = 1.0/m_tWidthm1 m_tInvHeight = 1.0/m_tHeightm1 m_tWidthm1 = m_tWidthm1 - 1.0 m_tHeightm1 = m_tHeightm1 - 1.0 endif m_i[0]=7 m_i[1]=11 m_i[2]=12 m_i[3]=13 m_i[4]=17 endif if @p_seedit srand(@p_seed) endif endfunc func fold(complex &pz, float &x, float &y, float &u, int &q, int &r, int &s) x = real(pz) u = -1.0 y = 1.0 s = random(@p_seed) q = 0 while xy q = q + 1 if x1.0 y = 1.0 endif else x = 2.0*y - x u = y - abs(s=random(s+@p_seed))/(0.6*#randomrange)-0.1 if u<-1.0 u = -1.0 endif endif endwhile if real(pz)<0.0 q = -q endif y = imag(pz) pz = ((x+1.0)%2.0)-1.0 x = y u = -1.0 y = 1.0 s = random(@p_seed) r = 0 while xy r = r + 1 if x1.0 y = 1.0 endif else x = 2.0*y - x u = y - abs(s=random(s+347))/(0.8*#randomrange)-0.1 if u<-1.0 u = -1.0 endif endif endwhile if imag(pz)>=0 r = -r endif pz = pz - flip(((1.0-x)%2.0)-1.0) endfunc color func getColor(complex pz) if getEmpty() return rgba(0,0,0,0) endif complex pz1 complex pz2 complex pz3 complex tpz float x float y float u float xg = @p_xgutter float yg = @p_ygutter float xo = @p_xoff float yo = @p_yoff int p[5] int t[5] int q int r int s if @p_tile && @p_seamless && @p_wrap && @p_usefbm pz = m_fbm.GetfBm(pz)+flip(m_fbm.GetfBm(flip(pz))) endif pz = m_Transform.Iterate(pz) if @p_maintainaspect pz = NormalizePixel(pz) endif color temp if @p_tile if @p_iterate pz1 = pz fold(pz,x,y,u,q,r,s) x = real(pz1) y = -imag(pz1) else x = real(pz) y = -imag(pz) endif if @p_seamless && @p_wrap && @p_twotile q = floor(((x+1.0)%10.0)/2.0) r = floor(((1.0+y)%10.0)/2.0) if q<0 q = 5+q endif if r<0 r = 5+r endif q = 1+2*r+q r = 0 repeat s=(q+2*floor(0.2*m_i[r]+0.01)+m_i[r])%5 if (s==0 && @p_patterny>=2) || (s==1 && @p_patternx>=4) \ || (s==2 && (@p_patternx%4)>=2) || (s==3 && (@p_patternx%2)) \ || (s==4 && (@p_patterny%2)) p[r] = 1 else p[r] = 0 endif until (r=r+1)>=5 endif if @p_iterate x = real(pz1) y = -imag(pz1) u = (x+1.0)%2.0 q = round(0.5*(x+1.4-u)) if u<0.0 q = q-1 endif u = (1.0+y)%2.0 s = round(0.5*(y + 1.4 - u)) if u<0.0 s = s-1 endif x = real(pz) y = -imag(pz) endif u = (x+1.0)%2.0 if !@p_iterate q = round(0.5*(x+1.4-u)) endif if u<0.0 if !@p_iterate q = q-1 endif x = u + 1.0 else x = u - 1.0 endif u = (1.0+y)%2.0 if !@p_iterate s = round(0.5*(y + 1.4 - u)) endif if u<0.0 if !@p_iterate s = s-1 endif y = u + 1.0 else y = u - 1.0 endif if @p_seamless && @p_wrap && @p_twotile && @p_advanced if @p_random r = 0 repeat t[r] = random((random(q+(m_i[r]%5)+12345678)%65536)+93427-@p_seed) if (t[r]%65536)>((u=random((random(s+floor(0.2*m_i[r]+0.01)+12345678)%65536)*@p_seed))%65536) p[r] = (p[r]+1)%2 endif t[r] = random(t[r]+random(round(u))) until (r=r+1)>=5 else r = 0 repeat t[r] = 0 until (r=r+1)>=5 endif endif pz = x - flip(y) endif pz = m_Transform1.Iterate(pz) if @p_retile && @p_tile x = (real(pz)+1.0)%2.0 if x<0.0 x = x + 1.0 else x = x - 1.0 endif y = (1.0-imag(pz))%2.0 if y<0.0 y = y + 1.0 else y = y - 1.0 endif pz = x - flip(y) endif if @p_mirror if @p_flip pz = -pz else pz = -conj(pz) endif elseif @p_flip pz = conj(pz) endif if @p_seamless && @p_wrap if @p_twotile if @p_iterate x = (real(pz1)+1.0)%2.0 if x<0.0 x = x + 1.0 else x = x - 1.0 endif y = (1.0-imag(pz1))%2.0 if y<0.0 y = y + 1.0 else y = y - 1.0 endif pz3 = x - flip(y) if p[2] tpz = (real(pz)*m_tWidthm1 - 1.0)*m_tInvWidth \ + flip((imag(pz)*m_tHeightm1 + 1.0)*m_tInvHeight) else tpz = (real(pz)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz)*m_Heightm1 + 1.0)*m_InvHeight) endif else pz3 = pz endif if p[2] pz = (real(pz3)*m_tWidthm1 - 1.0)*m_tInvWidth \ + flip((imag(pz3)*m_tHeightm1 + 1.0)*m_tInvHeight) else pz = (real(pz3)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz3)*m_Heightm1 + 1.0)*m_InvHeight) endif r = s = 0 if @p_advanced r = random(@p_seed) if real(pz)<0 if p[1]==0 r = random(r+t[1]) if p[2]==0 r = random(r+t[2]) xg = @p_xgutter00 xo = @p_xoff00 else xg = @p_xgutter01 xo = @p_xoff01 endif elseif p[2]==0 r = random(r+@p_seed+t[2]+657321) xg = @p_xgutter10 xo = @p_xoff10 else xg = @p_xgutter11 xo = @p_xoff11 endif elseif p[2]==0 r = random(r+t[2]) if p[3]==0 r = random(r+t[3]) xg = @p_xgutter00 xo = @p_xoff00 else xg = @p_xgutter01 xo = @p_xoff01 endif elseif p[3]==0 r = random(r+@p_seed+t[3]+657321) xg = @p_xgutter10 xo = @p_xoff10 else xg = @p_xgutter11 xo = @p_xoff11 endif if @p_rand xg = @p_gbasex + (@p_gmaxx-@p_gbasex)*abs(r=random(r))/#randomrange xo = abs((r=random(r))/#randomrange) endif s = random(@p_seed+564863) if imag(pz)>=0 if p[0]==0 s = random(s + t[0]) if p[2]==0 s = random(s+t[2]) yg = @p_ygutter00 yo = @p_yoff00 else yg = @p_ygutter01 yo = @p_yoff01 endif elseif p[2]==0 s = random(s+t[2]+6847334) yg = @p_ygutter10 yo = @p_yoff10 else yg = @p_ygutter11 yo = @p_yoff11 endif elseif p[2]==0 s = random(s+t[2]) if p[4]==0 s = random(s+t[4]) yg = @p_ygutter00 yo = @p_yoff00 else yg = @p_ygutter01 yo = @p_yoff01 endif elseif p[4]==0 s = random(s+t[4]+6847334) yg = @p_ygutter10 yo = @p_yoff10 else yg = @p_ygutter11 yo = @p_yoff11 endif if @p_rand yg = @p_gbasey + (@p_gmaxy-@p_gbasey)*abs(s=random(s))/#randomrange yo = abs((s=random(s))/#randomrange) r = random(r) s = random(s) else r = s = 0 endif endif if @p_iterate pz = tpz tpz = pz3 endif pz1 = pz3+flip(1.0-yo*(1.0-yg)) pz2 = pz3+1.0-xo*(1.0-xg) pz3 = pz3+1.0-xo*(1.0-xg)+flip(1.0-yo*(1.0-yg)) x = (real(pz1)+1.0)%2.0 if x<0.0 x = x + 1.0 else x = x - 1.0 endif y = (1.0-imag(pz1))%2.0 if y<0.0 y = y + 1.0 else y = y - 1.0 endif pz1 = x - flip(y) x = (real(pz2)+1.0)%2.0 if x<0.0 x = x + 1.0 else x = x - 1.0 endif y = (1.0-imag(pz2))%2.0 if y<0.0 y = y + 1.0 else y = y - 1.0 endif pz2 = x - flip(y) x = (real(pz3)+1.0)%2.0 if x<0.0 x = x + 1.0 else x = x - 1.0 endif y = (1.0-imag(pz3))%2.0 if y<0.0 y = y + 1.0 else y = y - 1.0 endif pz3 = x - flip(y) else pz1 = conj(pz) pz2 = -conj(pz) pz3 = -pz pz = (real(pz)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz)*m_Heightm1 + 1.0)*m_InvHeight) endif elseif @p_seamless pz = (real(pz)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz)*m_Heightm1 + 1.0)*m_InvHeight) endif color clr = m_ImportedImage.getColor(pz) color clr1 if @p_seamless && @p_wrap if @p_twotile if p[2] clr = m_TileImage.getColor((real(pz)*m_tWidthm1 - 1.0)*m_tInvWidth \ + flip((imag(pz)*m_tHeightm1 + 1.0)*m_tInvHeight)) endif endif if @p_twotile && @p_iterate pz = tpz endif x=abs(1.0-abs(real(pz))) y=abs(1.0-abs(imag(pz))) if x=yg clr = blend(clr1,clr,x) else y = sqr(y/yg) if y>x u = x if 1.0-x>y y = 1.0 - x - 0.25*x/y else y = y - 0.25*(1.0-y)/(1.0-x) endif else u = y if y<1.0-x y = 0.75*y/x - y else y = x - 1.0 + 0.75*(1.0-x)/(1.0-y) endif endif if isInf(y) || isNan(y) y = 0 endif if imag(pz)<0.0 q = (2*p[2]+p[4]+s)%4 if q==3 clr1 = blend(m_ImportedImage.getColor((real(pz1)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz1)*m_Heightm1 + 1.0)*m_InvHeight)),clr1,y) elseif q==2 clr1 = blend(m_TileImage.getColor((real(pz1)*m_tWidthm1 - 1.0)*m_tInvWidth \ + flip((imag(pz1)*m_tHeightm1 + 1.0)*m_tInvHeight)),clr1,y) else if @p_advanced && @p_rotate pz1 = flip(pz1) endif if q==1 clr1 = blend(m_ImportedImage.getColor((real(pz1)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz1)*m_Heightm1 + 1.0)*m_InvHeight)),clr1,y) else;ifq===0 clr1 = blend(m_TileImage.getColor((real(pz1)*m_tWidthm1 - 1.0)*m_tInvWidth \ + flip((imag(pz1)*m_tHeightm1 + 1.0)*m_tInvHeight)),clr1,y) endif endif else q = (2*p[0]+p[2]+s)%4 if q==3 clr1 = blend(m_ImportedImage.getColor((real(pz1)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz1)*m_Heightm1 + 1.0)*m_InvHeight)),clr1,y) elseif q==2 clr1 = blend(m_TileImage.getColor((real(pz1)*m_tWidthm1 - 1.0)*m_tInvWidth \ + flip((imag(pz1)*m_tHeightm1 + 1.0)*m_tInvHeight)),clr1,y) else if @p_advanced && @p_rotate pz1 = flip(pz1) endif if q==1 clr1 = blend(m_ImportedImage.getColor((real(pz1)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz1)*m_Heightm1 + 1.0)*m_InvHeight)),clr1,y) else;if q==0 clr1 = blend(m_TileImage.getColor((real(pz1)*m_tWidthm1 - 1.0)*m_tInvWidth \ + flip((imag(pz1)*m_tHeightm1 + 1.0)*m_tInvHeight)),clr1,y) endif endif endif clr = blend(clr1,clr,u) endif else q = (2*p[2]+p[3]+r)%4 if q==0 if @p_advanced && @p_rotate pz2 = flip(pz2) endif clr1 = m_TileImage.getColor((real(pz2)*m_tWidthm1 - 1.0)*m_tInvWidth \ + flip((imag(pz2)*m_tHeightm1 + 1.0)*m_tInvHeight)) elseif q==1 clr1 = m_TileImage.getColor((real(pz2)*m_tWidthm1 - 1.0)*m_tInvWidth \ + flip((imag(pz2)*m_tHeightm1 + 1.0)*m_tInvHeight)) elseif q==2 if @p_advanced && @p_rotate pz2 = flip(pz2) endif clr1 = m_ImportedImage.getColor((real(pz2)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz2)*m_Heightm1 + 1.0)*m_InvHeight)) else clr1 = m_ImportedImage.getColor((real(pz2)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz2)*m_Heightm1 + 1.0)*m_InvHeight)) endif if y>=yg clr = blend(clr1,clr,x) else y = sqr(y/yg) if y>x u = x if 1.0-x>y y = 1.0 - x - 0.25*x/y else y = y - 0.25*(1.0-y)/(1.0-x) endif else u = y if y<1.0-x y = 0.75*y/x - y else y = x - 1.0 + 0.75*(1.0-x)/(1.0-y) endif endif if imag(pz)<0.0 q = (2*p[2]+p[4]+s)%4 if q==3 clr1 = blend(m_ImportedImage.getColor((real(pz1)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz1)*m_Heightm1 + 1.0)*m_InvHeight)),clr1,y) elseif q==2 clr1 = blend(m_TileImage.getColor((real(pz1)*m_tWidthm1 - 1.0)*m_tInvWidth \ + flip((imag(pz1)*m_tHeightm1 + 1.0)*m_tInvHeight)),clr1,y) else if @p_advanced && @p_rotate pz1 = flip(pz1) endif if q==1 clr1 = blend(m_ImportedImage.getColor((real(pz1)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz1)*m_Heightm1 + 1.0)*m_InvHeight)),clr1,y) else;if q==0 clr1 = blend(m_TileImage.getColor((real(pz1)*m_tWidthm1 - 1.0)*m_tInvWidth \ + flip((imag(pz1)*m_tHeightm1 + 1.0)*m_tInvHeight)),clr1,y) endif endif else q = (2*p[0]+p[2]+s)%4 if q==3 clr1 = blend(m_ImportedImage.getColor((real(pz1)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz1)*m_Heightm1 + 1.0)*m_InvHeight)),clr1,y) elseif q==2 clr1 = blend(m_TileImage.getColor((real(pz1)*m_tWidthm1 - 1.0)*m_tInvWidth \ + flip((imag(pz1)*m_tHeightm1 + 1.0)*m_tInvHeight)),clr1,y) else if @p_advanced && @p_rotate pz1 = flip(pz1) endif if q==1 clr1 = blend(m_ImportedImage.getColor((real(pz1)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz1)*m_Heightm1 + 1.0)*m_InvHeight)),clr1,y) else;if q==0 clr1 = blend(m_TileImage.getColor((real(pz1)*m_tWidthm1 - 1.0)*m_tInvWidth \ + flip((imag(pz1)*m_tHeightm1 + 1.0)*m_tInvHeight)),clr1,y) endif endif endif clr = blend(clr1,clr,u) endif endif else x = 2.0*sqr(0.5*x/@p_xgutter) + 0.5 clr = blend(m_ImportedImage.getColor((real(pz2)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz2)*m_Heightm1 + 1.0)*m_InvHeight)),clr,x) if y<@p_ygutter clr1 = blend(m_ImportedImage.getColor((real(pz3)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz3)*m_Heightm1 + 1.0)*m_InvHeight)), \ m_ImportedImage.getColor((real(pz1)*m_Widthm1 - 1.0)*m_InvWidth \ + flip((imag(pz1)*m_Heightm1 + 1.0)*m_InvHeight)), \ x) y = 2.0*sqr(0.5*y/@p_ygutter) + 0.5 clr = blend(clr1,clr,y) endif endif elseif y100 endparam bool param p_wrap caption = "Wrapped tiles" default = false visible = @p_seamless endparam bool param p_usefbm caption = "Use fBm randomiser" default = false visible = @p_seamless && @p_wrap endparam MMF_AltfBm param p_fbm caption = "fBm settings" default = MMF_AltfBm visible = @p_seamless && @p_wrap && @p_usefbm endparam bool param p_twotile caption = "Use Secondary image" default = false visible = @p_seamless && @p_wrap endparam Image param p_tileimage caption = "Secondary image" hint = "This is the image to tile with the first, note that if necessary \ it will be stretched to match the dimensions of the main image. \ Currently the code is designed just to multi-tile horizontally but \ just to wrap the tiles to themselves vertically." visible = @p_seamless && @p_wrap && @p_twotile endparam int param p_patternx caption = "Pattern X" enum = "000" "001" "010" "011" "100" "101" "110" "111" default = 0 visible = @p_seamless && @p_wrap && @p_twotile endparam int param p_patterny caption = "Pattern Y" enum = "0x0" "0x1" "1x0" "1x1" default = 0 visible = @p_seamless && @p_wrap && @p_twotile endparam float param p_xgutter caption = "X Gutter" default = 0.5 visible = @p_seamless && @p_wrap && !@p_advanced endparam float param p_ygutter caption = "Y Gutter" default = 0.5 visible = @p_seamless && @p_wrap && !@p_advanced endparam float param p_xoff caption = "X Offset" default = 0.0 visible = @p_seamless && @p_wrap && @p_twotile && !@p_advanced endparam float param p_yoff caption = "Y Offset" default = 0.0 visible = @p_seamless && @p_wrap && @p_twotile && !@p_advanced endparam bool param p_advanced caption = "Advanced options" default = false visible = @p_seamless && @p_wrap && @p_twotile endparam bool param p_rotate caption = "Rotate edges" default = true visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced endparam bool param p_random caption = "Random tiling" default = true visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced endparam bool param p_rand caption = "Random edges" default = true visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced endparam bool param p_seedit caption = "Use random seed" default = true hint = "Disable to recover older images that change if it's enabled." visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced \ && (@p_rotate || @p_random || @p_rand) endparam int param p_seed caption = "Random edge seed" default = 10083 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced \ && @p_seedit && (@p_rotate || @p_random || @p_rand) endparam float param p_gbasex caption = "Min. edge width" default = 0.2 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && @p_rand endparam float param p_gmaxx caption = "Max. edge width" default = 0.8 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && @p_rand endparam float param p_gbasey caption = "Min. edge height" default = 0.2 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && @p_rand endparam float param p_gmaxy caption = "Max. edge height" default = 0.8 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && @p_rand endparam float param p_xgutter00 caption = "X gutter 00" default = 0.5 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && !@p_rand endparam float param p_xgutter01 caption = "X gutter 01" default = 0.5 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && !@p_rand endparam float param p_xgutter10 caption = "X gutter 10" default = 0.5 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && !@p_rand endparam float param p_xgutter11 caption = "X gutter 11" default = 0.5 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && !@p_rand endparam float param p_ygutter00 caption = "Y gutter 00" default = 0.5 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && !@p_rand endparam float param p_ygutter01 caption = "Y gutter 01" default = 0.5 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && !@p_rand endparam float param p_ygutter10 caption = "Y gutter 10" default = 0.5 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && !@p_rand endparam float param p_ygutter11 caption = "Y gutter 11" default = 0.5 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && !@p_rand endparam float param p_xoff00 caption = "X offset 00" default = 0.0 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && !@p_rand endparam float param p_xoff01 caption = "X offset 01" default = 0.0 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && !@p_rand endparam float param p_xoff10 caption = "X offset 10" default = 0.0 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && !@p_rand endparam float param p_xoff11 caption = "X offset 11" default = 0.0 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && !@p_rand endparam float param p_yoff00 caption = "Y offset 00" default = 0.0 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && !@p_rand endparam float param p_yoff01 caption = "Y offset 01" default = 0.0 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && !@p_rand endparam float param p_yoff10 caption = "Y offset 10" default = 0.0 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && !@p_rand endparam float param p_yoff11 caption = "Y offset 11" default = 0.0 visible = @p_seamless && @p_wrap && @p_twotile && @p_advanced && !@p_rand endparam } class MMF_FieldEstimator(common.ulb:GradientColoring) { ;

; This is a combination of Distance Estimator or Smooth Iteration or ; Exponential Smoothing and Distance Estimator Angles or Field Lines ; that allows the use of either the distance estimate or the smooth ; iteration value or the exponential smoothing value combined with ; either the distance estimator angles or the field line angles for ; mapping an image into a fractal.
; Updated May 2009

public: func MMF_FieldEstimator(Generic pparent) GradientColoring.GradientColoring(pparent) if @smooth!=1 if @v_mmffieldestimator>=2 && @useplugin \ && ((@mode!=3 && @angles==1) || (@mode!=2 && @distances==1)) distest = new @distest(this) endif if @mode!=3 if @angles==0 fltransfer = new @fltransfer(this) else;if @angles==1 datransfer = new @datransfer(this) endif endif if @mode!=2 if @distances==0 ittransfer = new @ittransfer(this) elseif @distances==1 detransfer = new @detransfer(this) else;if @distances==2 extransfer = new @extransfer(this) endif endif if @v_mmffieldestimator>0 && @mode<2 m_Transform = new @f_transformnew(this) endif if @mode==0 m_Image = new @f_image(this) if @v_mmffieldestimator==0 m_Transform = new @f_transform(this) endif if @usegradient usergradient = new @usergradient(this) endif if @adjustlayer m_Adjust = new @f_adjust(this) endif endif if @mode==4 || (@mode<2 && @usetexture) m_Transferx = new @f_transferx(this) m_Transfery = new @f_transfery(this) m_TexTransform = new @f_textransform(this) m_Texture = new @f_texture(this) m_TextureScale = new @f_texturescale(this) if @mode<2 m_Merge = new @f_Merge(this) endif endif endif if @smooth>0 if (@modec!=3 && @anglesc==1) || (@modec!=2 && @distancesc==1) distestc = new @distestc(this) endif if @modec!=3 if @anglesc==0 fltransferc = new @fltransferc(this) else;if @angles==1 datransferc = new @datransferc(this) endif endif if @modec!=2 if @distancesc==0 ittransferc = new @ittransferc(this) elseif @distancesc==1 detransferc = new @detransferc(this) else;if @distancesc==2 extransferc = new @extransferc(this) endif endif if @modec<2 m_Transformc = new @f_transformnewc(this) endif if @modec==0 m_Imagec = new @f_imagec(this) if @adjustlayerc m_Adjustc = new @f_adjustc(this) endif if @usegradientc usergradientc = new @usergradientc(this) endif endif if @modec==4 || (@modec<2 && @usetexturec) m_Transferxc = new @f_transferxc(this) m_Transferyc = new @f_transferyc(this) m_TexTransformc = new @f_textransformc(this) m_Texturec = new @f_texturec(this) m_TextureScalec = new @f_texturescalec(this) if @modec<2 m_Mergec = new @f_Mergec(this) endif endif endif endfunc func Init(complex pz, complex ppixel) m_Iterations = 0 m_Solid = false m_Pixel = ppixel zolder = (0,0) zold = pz sz = dz = 1.0 ex = exp(-cabs(pz)) exc = 0.0 if @julia zz[0] = pz zzc[0] = pz if @mode!=3 && @angles==1 && @smooth!=1 \ && (@v_mmffieldestimator<2 || !@useplugin) sz = @power*pz^(@power-1) endif m_Iterations = 1 endif if @smooth!=1 if @v_mmffieldestimator>=2 && @useplugin \ && ((@mode!=3 && @angles==1) || (@mode!=2 && @distances==1)) distest.Init(pz,ppixel) endif if @v_mmffieldestimator>0 if @mode!=3 if @angles==0 fltransfer.Init(0) else;if @angles==1 datransfer.Init(0) endif endif if @mode!=2 if @distances==0 ittransfer.Init(0) elseif @distances==1 detransfer.Init(0) else;if @distances==2 extransfer.Init(0) endif endif endif if @mode==0 || (@v_mmffieldestimator>0 && @mode==1) m_Transform.Init(pz) endif if @mode==4 || (@mode<2 && @usetexture) m_Transferx.Init(0) m_Transfery.Init(0) m_TexTransform.Init(pz) m_Texture.Init(pz) m_TextureScale.Init(0) endif endif if @smooth>0 if (@modec!=3 && @anglesc==1) || (@modec!=2 && @distancesc==1) distestc.Init(pz,ppixel) endif if @modec!=3 if @anglesc==0 fltransferc.Init(0) else;if @anglesc==1 datransferc.Init(0) endif endif if @modec!=2 if @distancesc==0 ittransferc.Init(0) elseif @distancesc==1 detransferc.Init(0) else;if @distancesc==2 extransferc.Init(0) endif endif if @modec==0 || @modec==1 m_Transformc.Init(pz) endif if @modec==4 || (@modec<2 && @usetexturec) m_Transferxc.Init(0) m_Transferyc.Init(0) m_TexTransformc.Init(pz) m_Texturec.Init(pz) m_TextureScalec.Init(0) endif endif endfunc func Iterate(complex pz) if @smooth!=1 if @mode!=3 && @angles==0 if m_Iterations>=@skip && m_Iterations<@skip+1000 zz[m_Iterations-@skip] = pz endif endif if @v_mmffieldestimator>=2 && @useplugin \ && ((@mode!=3 && @angles==1) || (@mode!=2 && @distances==1)) distest.Iterate(pz) elseif @mode!=3 && @angles==1 && (!@julia && m_Iterations==0) sz = @power*pz^(@power-1.0) elseif ((@mode!=2 && @distances==1) || (@mode!=3 && @angles==1)) \ && (@julia || m_Iterations>0) dz = @power*dz*pz^(@power-1.0) endif if @mode!=2 && @distances==2 ex = ex + exp(-cabs(pz)) endif endif if @smooth>0 if @modec!=3 && @anglesc==0 if m_Iterations>=@skipc && m_Iterations<@skipc+1000 zzc[m_Iterations-@skip] = pz endif endif if (@modec!=3 && @anglesc==1) || (@modec!=2 && @distancesc==1) distestc.Iterate(pz) endif if @modec!=2 && @distancesc==2 exc = exc + exp(-1.0/cabs(pz-zold)) endif zolder = zold endif zold = pz m_Iterations = m_Iterations + 1 endfunc float func ResultIndex(complex pz) float a = 0.0 float b = 0.0 float v = 0.0 complex tc = 0.0 s = 0.0 t = 0.0 u = 0.0 if @smooth!=1 && |pz|>@bailout && |pz-zold|>1.0 if @mode!=3 && @angles==0 bool f = false if (@julia && imag(pz - zold^@power)>=0.0) \ || (!@julia && imag(m_Pixel)>=0.0) f = true endif int i = m_Iterations - @skip if i<1000 s = atan2(pz)*(0.5/#pi) else s = atan2(zz[(i=i-1)])*(0.5/#pi) endif if s<0.0 s = s + 1.0 endif while (i=i-1)>=0 if (a = atan2(zz[i])*(0.5/#pi))<0.0 a = a + 1.0 endif if @original b = a = a*@power else b = b + (a = a*@power) endif b = b - (s = s + floor(a)) if f && b>=0.5 s = s + 1.0 b = b - @offset elseif !f && b<-0.5 s = s - 1.0 b = b + @offset endif if !@accident || @original b = @scale*b/@power endif s = s/@power endwhile if @accident2 s = b endif if (s = s%1)<0.0 s = s + 1.0 endif if @mode==4 || (@mode<2 && @usetexture) u = m_Transferx.Iterate(s) endif s = fltransfer.Iterate(s) if @mode==2 return s endif endif if @mode!=3 && @angles==1 if @useplugin s = distest.ResultAngle(pz) elseif (s = atan2(pz/(dz*sz))*(0.5/#pi))<0.0 s = s + 1.0 endif if @mode==4 || (@mode<2 && @usetexture) u = m_Transferx.Iterate(s) endif s = datransfer.Iterate(s) if @mode==2 return s endif endif if @mode!=2 && @distances==0 if !@julia m_Iterations = m_Iterations + 1 endif if @autopower && (b=|zold|)>0.0 a = log(|pz|) t = m_Iterations + (log(0.5*log(@bailout)) - log(0.5*a)) \ /log(a/log(b)) else t = m_Iterations + (log(0.5*log(@bailout)) - log(0.5*log(|pz|))) \ /log(@power) endif if @mode==4 || (@mode<2 && @usetexture) v = m_Transfery.Iterate(t) endif t = ittransfer.Iterate(t) if @mode==3 return t endif endif if @mode!=2 && @distances==1 if @useplugin t = distest.ResultDistance(pz) else t = cabs(pz) t = (@power*log(t)*t/cabs(dz))^(1.0/@power) if (@mode==4 || (@mode<2 && @usetexture)) && @v_mmffieldestimator<3 v = m_Transfery.Iterate(t) endif endif if (@mode==4 || (@mode<2 && @usetexture)) && @v_mmffieldestimator>=3 v = m_Transfery.Iterate(t) endif t = detransfer.Iterate(t) if @mode==3 return t endif endif if @mode!=2 && @distances==2 if @fixexp ex = ex + exp(-cabs(pz)) endif if @mode==4 || (@mode<2 && @usetexture) v = m_Transfery.Iterate(ex) endif t = extransfer.Iterate(ex) if @mode==3 return t endif endif if @f_transformnew!=NullTransform && @v_mmffieldestimator>0 tc = m_Transform.Iterate(s + flip(t)) s = real(tc) t = imag(tc) endif if @polar s = s*2.0*#pi if @v_mmffieldestimator>0 && @mode>0 tc = 0.5*t*(cos(s)+1.0 - flip(sin(s)-1.0)) else tc = t*(cos(s) - flip(sin(s))) endif s = real(tc) t = imag(tc) endif if @mode==4 || (@mode<2 && @usetexture) tc = m_TexTransform.Iterate(u+flip(v)) if @polartex u = real(tc)*2.0*#pi v = imag(tc) if @mode>0 tc = 0.5*v*(cos(u)+1.0 - flip(sin(u)-1.0)) else tc = v*(cos(u) - flip(sin(u))) endif endif u = m_TextureScale.Iterate(m_Texture.Iterate(tc)) endif if @mode==4 return u elseif @mode==1 if @usetexture if @mix=="Sum" return s + t + u elseif @mix=="Product" return s*t + u elseif @mix=="Absolute Difference" return abs(s - t) + u elseif @mix=="Quotient 1" return s/(t + 1) + u else;if @mix=="Quotient 2" return t/(s + 1) + u endif elseif @mix=="Sum" return s + t elseif @mix=="Product" return s*t elseif @mix=="Absolute Difference" return abs(s - t) elseif @mix=="Quotient 1" return s/(t + 1) else;if @mix=="Quotient 2" return t/(s + 1) endif else if !@polar s = 2*s - 1.0 t = 2*t - 1.0 endif if @v_mmffieldestimator==0 clr = m_Image.GetColor(m_Transform.Iterate(s+flip(t))) else clr = m_Image.GetColor(s+flip(t)) endif if @usetexture if @mapmethod=="Image All" || @mapmethod=="Image Brightness" return 0.299*red(clr) + 0.587*green(clr) + 0.114*blue(clr) + u elseif @mapmethod=="Image Red" return red(clr) + u elseif @mapmethod=="Image Green" return green(clr) + u elseif @mapmethod=="Image Blue" return blue(clr) + u elseif @mapmethod=="Image Alpha" return alpha(clr) + u elseif @mapmethod=="Image Hue" return hue(clr)/6.0 + u elseif @mapmethod=="Image Saturation" return sat(clr) + u else;if @mapmethod=="Image Luminance" return lum(clr) + u endif elseif @mapmethod=="Image All" || @mapmethod=="Image Brightness" return 0.299*red(clr) + 0.587*green(clr) + 0.114*blue(clr) elseif @mapmethod=="Image Red" return red(clr) elseif @mapmethod=="Image Green" return green(clr) elseif @mapmethod=="Image Blue" return blue(clr) elseif @mapmethod=="Image Alpha" return alpha(clr) elseif @mapmethod=="Image Hue" return hue(clr)/6.0 elseif @mapmethod=="Image Saturation" return sat(clr) else;if @mapmethod=="Image Luminance" return lum(clr) endif endif elseif @smooth>0 && (@v_mmffieldestimator>=4 || |pz-zold|<1.0) if @modec!=3 && @anglesc==0 int i = m_Iterations - @skipc float fix = #pi - atan2(pz) if i<1000 s = (atan2(pz-zzc[i-1]) + fix)*(0.5/#pi) else i = i - 1 s = (atan2(zzc[i]-zzc[i-1]) + fix)*(0.5/#pi) endif if s<0.0 s = s + 1.0 elseif s>=1.0 s = s - 1.0 endif if (s=s+@fixconv)>=1.0 s = s - 1.0 endif while (i=i-1)>=1 if (a = (atan2(zzc[i]-zzc[i-1]) + fix)*(0.5/#pi))<0.0 a = a + 1.0 elseif a>=1.0 a = a - 1.0 endif if (a=a+@fixconv)>=1.0 a = a - 1.0 endif if !@originalc b = b + (a = a*@powerc) else b = a = a*@powerc endif b = b - (s = s + floor(a)) if b>=0.5 s = s + 1.0 b = b - @offsetc elseif b<-0.5 s = s - 1.0 b = b + @offsetc endif if !@accidentc || @originalc b = @scalec*b/@powerc endif s = s/@powerc endwhile if @accident2c s = b endif if (s = s%1)<0.0 s = s + 1.0 endif if @modec==4 || (@modec<2 && @usetexturec) u = m_Transferxc.Iterate(s) endif s = fltransferc.Iterate(s) if @modec==2 return s endif endif if @modec!=3 && @anglesc==1 s = distestc.ResultAngle(pz) if @modec==4 || (@modec<2 && @usetexturec) u = m_Transferxc.Iterate(s) endif s = datransferc.Iterate(s) if @modec==2 return s endif endif if @modec!=2 && @distancesc==0 if !@julia m_Iterations = m_Iterations + 1 endif if @fixedconv if @autopowerc a = log(|pz-@convval|) t = m_Iterations + (log(-0.5*log(@smallbail)) - log(-0.5*a)) \ /log(a/log(|zold-@convval|)) else t = m_Iterations + (log(-0.5*log(@smallbail)) - log(-0.5*log(|pz-@convval|))) \ /log(@powerc) endif elseif @autopowerc && m_Iterations>1 a = log(|pz-zold|) t = m_Iterations + (log(-0.5*log(@smallbail)) - log(-0.5*a)) \ /log(a/log(|zold-zolder|)) else t = m_Iterations + (log(-0.5*log(@smallbail)) - log(-0.5*log(|pz-zold|))) \ /log(@powerc) endif if @modec==4 || (@modec<2 && @usetexturec) v = m_Transferyc.Iterate(t) endif t = ittransferc.Iterate(t) if @modec==3 return t endif endif if @modec!=2 && @distancesc==1 t = distestc.ResultDistance(pz) if @modec==4 || (@modec<2 && @usetexturec) v = m_Transferyc.Iterate(t) endif t = detransferc.Iterate(t) if @modec==3 return t endif endif if @modec!=2 && @distancesc==2 if @fixexpc exc = exc + exp(-1.0/cabs(pz-zold)) endif if @modec==4 || (@modec<2 && @usetexturec) v = m_Transferyc.Iterate(exc) endif t = extransferc.Iterate(exc) if @modec==3 return t endif endif if @f_transformnewc!=NullTransform tc = m_Transformc.Iterate(s + flip(t)) s = real(tc) t = imag(tc) endif if @polarc s = s*2.0*#pi if @modec>0 tc = 0.5*t*(cos(s)+1.0 - flip(sin(s)-1.0)) else tc = t*(cos(s) - flip(sin(s))) endif s = real(tc) t = imag(tc) endif if @modec==4 || (@modec<2 && @usetexturec) tc = m_TexTransformc.Iterate(u+flip(v)) if @polartexc u = real(tc)*2.0*#pi v = imag(tc) if @modec>0 tc = 0.5*v*(cos(u)+1.0 - flip(sin(u)-1.0)) else tc = v*(cos(u) - flip(sin(u))) endif endif u = m_TextureScalec.Iterate(m_Texturec.Iterate(tc)) endif if @modec==4 return u elseif @modec==1 if @usetexturec if @mixc=="Sum" return s + t + u elseif @mixc=="Product" return s*t + u elseif @mixc=="Absolute Difference" return abs(s - t) + u elseif @mixc=="Quotient 1" return s/(t + 1) + u else;if @mixc=="Quotient 2" return t/(s + 1) + u endif elseif @mixc=="Sum" return s + t elseif @mixc=="Product" return s*t elseif @mixc=="Absolute Difference" return abs(s - t) elseif @mixc=="Quotient 1" return s/(t + 1) else;if @mixc=="Quotient 2" return t/(s + 1) endif else if !@polarc s = 2*s - 1.0 t = 2*t - 1.0 endif clr = m_Imagec.GetColor(s+flip(t)) if @usetexturec if @mapmethodc=="Image All" || @mapmethodc=="Image Brightness" return 0.299*red(clr) + 0.587*green(clr) + 0.114*blue(clr) + u elseif @mapmethodc=="Image Red" return red(clr) + u elseif @mapmethodc=="Image Green" return green(clr) + u elseif @mapmethodc=="Image Blue" return blue(clr) + u elseif @mapmethodc=="Image Alpha" return alpha(clr) + u elseif @mapmethodc=="Image Hue" return hue(clr)/6.0 + u elseif @mapmethodc=="Image Saturation" return sat(clr) + u else;if @mapmethodc=="Image Luminance" return lum(clr) + u endif elseif @mapmethodc=="Image All" || @mapmethodc=="Image Brightness" return 0.299*red(clr) + 0.587*green(clr) + 0.114*blue(clr) elseif @mapmethodc=="Image Red" return red(clr) elseif @mapmethodc=="Image Green" return green(clr) elseif @mapmethodc=="Image Blue" return blue(clr) elseif @mapmethodc=="Image Alpha" return alpha(clr) elseif @mapmethodc=="Image Hue" return hue(clr)/6.0 elseif @mapmethodc=="Image Saturation" return sat(clr) else;if @mapmethodc=="Image Luminance" return lum(clr) endif endif else m_Solid = true return 0.0 endif endfunc color func Result(complex pz) float v = ResultIndex(pz) if @smooth!=1 && |pz|>@bailout && |pz-zold|>1.0 if @mode==0 && (@mapmethod=="Image All" || @v_mmffieldestimator>=5) if @v_mmffieldestimator>=5 && @mapmethod!="Image All" if @usegradient if @mapmethod=="Image Red" clr = usergradient.GetColour(red(clr)) elseif @mapmethod=="Image Green" clr = usergradient.GetColour(green(clr)) elseif @mapmethod=="Image Blue" clr = usergradient.GetColour(blue(clr)) elseif @mapmethod=="Image Alpha" clr = usergradient.GetColour(alpha(clr)) elseif @mapmethod=="Image Hue" clr = usergradient.GetColour(hue(clr)/6.0) elseif @mapmethod=="Image Saturation" clr = usergradient.GetColour(sat(clr)) elseif @mapmethod=="Image Luminance" clr = usergradient.GetColour(lum(clr)) elseif @mapmethod=="Image Brightness" clr = usergradient.GetColour(0.299*red(clr) + 0.587*green(clr) \ + 0.114*blue(clr)) endif elseif @mapmethod=="Image Red" clr = gradient(red(clr)) elseif @mapmethod=="Image Green" clr = gradient(green(clr)) elseif @mapmethod=="Image Blue" clr = gradient(blue(clr)) elseif @mapmethod=="Image Alpha" clr = gradient(alpha(clr)) elseif @mapmethod=="Image Hue" clr = gradient(hue(clr)/6.0) elseif @mapmethod=="Image Saturation" clr = gradient(sat(clr)) elseif @mapmethod=="Image Luminance" clr = gradient(lum(clr)) elseif @mapmethod=="Image Brightness" clr = gradient(0.299*red(clr) + 0.587*green(clr) + 0.114*blue(clr)) endif endif if @usetexture clr = m_Merge.GradientMerge(clr, u) endif if @adjustlayer color c = @f_adjustcolour if @adjusttype==0 c = RGB(@adjred, @adjgreen, @adjblue) endif c = compose(clr, m_Adjust.Merge(clr, c), @f_opacity) return RGBA(red(c), green(c), blue(c), alpha(clr)) endif return clr endif elseif @smooth>0 && |pz-zold|<1.0 if @modec==0 && (@mapmethodc=="Image All" || @v_mmffieldestimator>=5) if @v_mmffieldestimator>=5 && @mapmethodc!="Image All" if @usegradientc if @mapmethodc=="Image Red" clr = usergradientc.GetColour(red(clr)) elseif @mapmethodc=="Image Green" clr = usergradientc.GetColour(green(clr)) elseif @mapmethodc=="Image Blue" clr = usergradientc.GetColour(blue(clr)) elseif @mapmethodc=="Image Alpha" clr = usergradientc.GetColour(alpha(clr)) elseif @mapmethodc=="Image Hue" clr = usergradientc.GetColour(hue(clr)/6.0) elseif @mapmethodc=="Image Saturation" clr = usergradientc.GetColour(sat(clr)) elseif @mapmethodc=="Image Luminance" clr = usergradientc.GetColour(lum(clr)) elseif @mapmethodc=="Image Brightness" clr = usergradientc.GetColour(0.299*red(clr) + 0.587*green(clr) \ + 0.114*blue(clr)) endif elseif @mapmethodc=="Image Red" clr = gradient(red(clr)) elseif @mapmethodc=="Image Green" clr = gradient(green(clr)) elseif @mapmethodc=="Image Blue" clr = gradient(blue(clr)) elseif @mapmethodc=="Image Alpha" clr = gradient(alpha(clr)) elseif @mapmethodc=="Image Hue" clr = gradient(hue(clr)/6.0) elseif @mapmethodc=="Image Saturation" clr = gradient(sat(clr)) elseif @mapmethodc=="Image Luminance" clr = gradient(lum(clr)) elseif @mapmethodc=="Image Brightness" clr = gradient(0.299*red(clr) + 0.587*green(clr) + 0.114*blue(clr)) endif endif if @usetexturec clr = m_Mergec.GradientMerge(clr, u) endif if @adjustlayerc color c = @f_adjustcolourc if @adjusttypec==0 c = RGB(@adjredc, @adjgreenc, @adjbluec) endif c = compose(clr, m_Adjustc.Merge(clr, c), @f_opacityc) return RGBA(red(c), green(c), blue(c), alpha(clr)) endif return clr endif endif return gradient(v) endfunc private: ImageWrapper m_Image DistanceEstimatorBase distest Transform m_Transform Transform m_TexTransform ColorMerge m_Adjust Transfer fltransfer Transfer datransfer Transfer ittransfer Transfer detransfer Transfer extransfer Transfer m_Transferx Transfer m_Transfery Transfer m_TextureScale TrapShape m_Texture GradientLayer m_Merge MMF_UserGradient usergradient ImageWrapper m_Imagec DistanceEstimatorBase distestc Transform m_Transformc Transform m_TexTransformc ColorMerge m_Adjustc Transfer fltransferc Transfer datransferc Transfer ittransferc Transfer detransferc Transfer extransferc Transfer m_Transferxc Transfer m_Transferyc Transfer m_TextureScalec TrapShape m_Texturec GradientLayer m_Mergec MMF_UserGradient usergradientc complex zz[1000] complex zzc[1000] complex zold complex zolder complex sz complex dz float ex float s float t float u float exc color clr default: title = "MMF Field Estimator" rating = recommended int param v_mmffieldestimator caption = "Version (MMF Field Estimator)" enum = "1.0" "1.1" "1.2" "1.3" "1.4" "1.5" default = 5 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = @v_mmffieldestimator<5 endparam heading caption = "Main Control" endheading int param smooth caption = "Area to Colour" enum = "Divergent" "Convergent" "Both" default = 0 visible = @v_mmffieldestimator>=2 endparam bool param julia caption = "Julia Mode ?" default = false hint = "Enable for main formulas that are in Julia mode." visible = ((@mode!=3 || @distances==1) && @smooth!=1) \ || ((@modec!=3 || @distancesc==1) && @smooth>0) endparam heading caption = "Divergent Control" visible = @smooth!=1 endheading int param mode caption = "Colouring Mode" enum = "Image Mapping" "Mix" "Angles" "Distances" "Texture Only" default = 0 visible = @smooth!=1 endparam bool param usetexture caption = "Add Texture" default = false hint = "Adds texturing when enabled. Normally this will be mixed in as \ a gradient index but if the colouring is in direct mode and \ you're using 'Image Mapping' then the texturing is applied as \ a colour merge layer." visible = @mode<2 && @smooth!=1 endparam bool param polar caption = "Go Polar" default = false hint = "When enabled the angle values are used as angles and the \ distance values as a magnitude, when disabled the angle values \ and distance values are taken as being on perpendicular axes." visible = @mode<2 && @smooth!=1 endparam int param mix caption = "Mix Method" enum = "Sum" "Product" "Absolute Difference" "Quotient 1" "Quotient 2" default = 0 visible = @mode==1 && @smooth!=1 endparam int param angles caption = "Angle Method" enum = "Field Lines" "Dist.Est. Angles" default = 0 visible = @mode!=3 && @smooth!=1 endparam int param distances caption = "Distance/Potential" enum = "Smooth Iteration" "Distance Estimator" "Exponential Smoothing" default = 0 visible = @mode!=2 && @smooth!=1 endparam bool param useplugin caption = "Plug-in Distance Estimation ?" default = false hint = "The built-in divergent Distance Estimation is only accurate for \ standard fractals of the form z^p+c. Enabling the plug-in option \ allows you to plug-in distance estimation calculating algorithms \ for other fractal formulas." visible = @v_mmffieldestimator>=2 && @smooth!=1 \ && ((@mode!=3 && @angles==1) || (@mode!=2 && @distances==1)) endparam heading text = "Choose the correct distance estimator for your main fractal \ formula. Note that you can ignore the 'Mode' parameter in the \ distance estimator formula but you need to set the 'Julia ?', \ 'Power' and any other parameters correctly." visible = @v_mmffieldestimator>=2 && @smooth!=1 && @useplugin \ && ((@mode!=3 && @angles==1) || (@mode!=2 && @distances==1)) endheading DistanceEstimatorBase param distest caption = "Distance Estimator" default = MMF_StandardDistanceEstimator hint = "Choose the correct distance estimator for your main fractal \ formula. Note that you can ignore the 'Mode' parameter in the \ distance estimator formula but you need to set the 'Julia ?', \ 'Power' and any other parameters correctly." visible = @v_mmffieldestimator>=2 && @smooth!=1 && @useplugin \ && ((@mode!=3 && @angles==1) || (@mode!=2 && @distances==1)) endparam float param power caption = "Power/Degree/Exponent" default = 2.0 hint = "The power/degree/exponent of your main formula. The field lines \ algorithm will only work 'correctly' with fractal \ formulas that have positive integer values >=2." visible = ((@mode!=3 && (@angles==0 || !@useplugin)) \ || (@mode!=2 && (@distances==0 \ || (@distances==1 && !@useplugin)))) && @smooth!=1 endparam float param bailout caption = "Bailout Value" default = 128.0 hint = "The value you use should match the (divergent) bailout value \ from the main fractal formula." visible = (@mode!=2 && @distances==0) \ || (@v_mmffieldestimator>=2 && @smooth!=1) endparam Transform param f_transformnew caption = "Colouring Transform" default = NullTransform hint = "Use to position/flip/mirror/scale your image mapping." visible = @mode<2 && @v_mmffieldestimator>0 && @smooth!=1 endparam heading caption = "Field Lines Settings (divergent)" visible = @mode!=3 && @angles==0 && @smooth!=1 endheading int param skip caption = "Iteration Skip" default = 0 min = 0 hint = "Increasing the value extends the field line detail into areas \ of higher iteration count." visible = @mode!=3 && @angles==0 && @smooth!=1 endparam bool param original caption = "Use Old Algorithm" default = false hint = "Uses the original 'unfixed' version of the algorithm that wasn't \ previously released. May produce more pleasing results on some \ Julia Sets." visible = @mode!=3 && @angles==0 && @smooth!=1 endparam float param offset caption = "Error Reset" default = 1.0 min = 0.0 hint = "Use in combination with 'Error Scale' to correct errors in the \ Field Lines. Note that different areas of a Mandelbrot may \ require different values." visible = @mode!=3 && @angles==0 && !@original && @smooth!=1 endparam float param scale caption = "Error Scale" default = 1.0 min = 0.0 hint = "Use in combination with 'Error Reset' to correct errors in the \ Field Lines. Note that different areas of a Mandelbrot may \ require different values." visible = @mode!=3 && @angles==0 && !@original && @smooth!=1 endparam bool param accident caption = "Happy Accident" default = false hint = "When enabled the algorithm for the field lines uses a 'broken' \ version. The option is available because the broken version \ can produce interesting effects." visible = @mode!=3 && @angles==0 && !@original && @smooth!=1 endparam bool param accident2 caption = "Happy Accident 2" default = false hint = "When enabled the algorithm for the field lines uses a test \ version. The option is available because the test version \ can produce interesting effects." visible = @mode!=3 && @angles==0 && @smooth!=1 endparam Transfer param fltransfer caption = "Field Lines Transfer" default = NullTransfer hint = "Use to scale/adjust the field line density." visible = @mode<3 && @angles==0 && @smooth!=1 endparam heading caption = "Dist. Est. Angles Settings (divergent)" visible = @mode<3 && @angles==1 && @smooth!=1 endheading Transfer param datransfer caption = "Dist. Est. Angles Transfer" default = NullTransfer hint = "Use to scale/adjust the distance estimator angles density." visible = @mode<3 && @angles==1 && @smooth!=1 endparam heading caption = "Smooth Iteration Settings (divergent)" visible = @mode!=2 && @distances==0 && @smooth!=1 endheading bool param autopower caption = "Auto-Power" default = true hint = "When enabled the degree of divergence of the fractal is \ calculated rather than using the 'Power/Degree/Exponent' value." visible = @mode!=2 && @distances==0 && @smooth!=1 endparam Transfer param ittransfer caption = "Smooth Iteration Transfer" default = NullTransfer hint = "Use to scale/adjust the iteration density." visible = @mode!=2 && @mode!=4 && @distances==0 && @smooth!=1 endparam heading caption = "Distance Estimator Settings (divergent)" visible = @mode!=2 && @mode!=4 && @distances==1 && @smooth!=1 endheading Transfer param detransfer caption = "Distance Estimator Transfer" default = NullTransfer hint = "Use to scale/adjust the distance estimator density." visible = @mode!=2 && @mode!=4 && @distances==1 && @smooth!=1 endparam heading caption = "Exponential Smoothing Settings (divergent)" visible = @mode!=2 && @mode!=4 && @distances==2 && @smooth!=1 endheading bool param fixexp caption = "Improved Exponential" default = false hint = "When enabled the final z value is used in calculating the \ exponential smoothing. This will noticeably improve the results \ at less extreme bailout values." visible = @mode!=2 && @mode!=4 && @distances==2 && @smooth!=1 endparam Transfer param extransfer caption = "Exponential Smoothing Transfer" default = NullTransfer hint = "Use to scale/adjust the exponential smoothing density." visible = @mode!=2 && @mode!=4 && @distances==2 && @smooth!=1 endparam heading caption = "Image Settings (divergent)" visible = @mode==0 && @smooth!=1 endheading int param mapmethod caption = "Image Method" enum = "Image All" "Image Red" "Image Green" "Image Blue" "Image Alpha" \ "Image Hue" "Image Saturation" "Image Luminance" "Image Brightness" hint = "'Image All' maps the image brightness (Yiq) to UF's gradient \ if the colouring is being used as a gradient colouring or uses \ the image colours if the colouring is being used as a direct \ colouring. 'Image Red' maps the image red to a gradient, \ 'Image Green' the green, 'Image Blue' the blue, 'Image Hue' \ the hue, 'Image Saturation' the saturation and 'Image Luminance' \ the luminance. 'Image Brightness' works exactly the same as \ 'Image All' if in gradient mode or maps the image brightness to \ a gradient if in direct mode." visible = @mode==0 && @smooth!=1 endparam bool param usegradient caption = "Use Custom Gradient ?" default = false hint = "Only relevant if in direct colouring mode. If disabled then the \ value from the image is translated to a colour using UF's in-built \ gradient (as is always the case in gradient colouring mode), \ enable if you wish to use a gradient specified as user \ parameters instead." visible = @mode==0 && @smooth!=1 && @mapmethod!="Image All" \ && @v_mmffieldestimator>=5 endparam MMF_UserGradient param usergradient caption = "Custom Gradient" default = MMF_Gradient hint = "Create a custom gradient." visible = @mode==0 && @smooth!=1 && @mapmethod!="Image All" \ && @v_mmffieldestimator>=5 && @usegradient endparam bool param adjustlayer caption = "Add Adjust layer" default = false hint = "Allows you to add an adjustment layer in a given colour to merge \ on top of the image/texture. Only works if the main colouring \ is in direct mode." visible = @mode==0 && (@mapmethod=="Image All" || @v_mmffieldestimator>=5) \ && @smooth!=1 endparam int param adjusttype caption = "Colour or RGB" enum = "RGB values" "Colour Parameter" default = 1 hint = "This option is specifically added so that if you choose \ 'RGB values' you can 'explore' them and see changes to the image \ as you change the RGB. The option may become redundant in a \ future version of UF. Only works if the main colouring \ is in direct mode." visible = @mode==0 && (@mapmethod=="Image All" || @v_mmffieldestimator>=5) \ && @adjustlayer && @smooth!=1 endparam float param adjred caption = "Red Value" default = 1.0 hint = "The red part of the adjust colour (0 to 1). Only works if the \ main colouring is in direct mode." visible = @mode==0 && (@mapmethod=="Image All" || @v_mmffieldestimator>=5) \ && @adjustlayer && @adjusttype==0 && @smooth!=1 endparam float param adjgreen caption = "Green Value" default = 1.0 hint = "The green part of the adjust colour (0 to 1). Only works if the \ main colouring is in direct mode." visible = @mode==0 && (@mapmethod=="Image All" || @v_mmffieldestimator>=5) \ && @adjustlayer && @adjusttype==0 && @smooth!=1 endparam float param adjblue caption = "Blue Value" default = 1.0 hint = "The blue part of the adjust colour (0 to 1). Only works if the \ main colouring is in direct mode." visible = @mode==0 && (@mapmethod=="Image All" || @v_mmffieldestimator>=5) \ && @adjustlayer && @adjusttype==0 && @smooth!=1 endparam color param f_adjustcolour caption = "Adjust Layer Colour" default = RGB(1,1,1) hint = "Allows you to apply overall adjustments to your colouring. Only \ works if the main colouring is in direct mode." visible = @mode==0 && (@mapmethod=="Image All" || @v_mmffieldestimator>=5) \ && @adjustlayer && @adjusttype==1 && @smooth!=1 endparam ColorMerge param f_adjust caption = "Adjustment Layer Merge" default = MMF_ExtendedColorMerge hint = "Only works if the main colouring is in direct mode." visible = @mode==0 && (@mapmethod=="Image All" || @v_mmffieldestimator>=5) \ && @adjustlayer && @smooth!=1 endparam float param f_opacity caption = "Adjustment Opacity" default = 1.0 hint = "Use to modify the adjustment opacity, the normal range is from \ 0 to 1. Only works if the main colouring \ is in direct mode." visible = @mode==0 && (@mapmethod=="Image All" || @v_mmffieldestimator>=5) \ && @adjustlayer && @smooth!=1 endparam Transform param f_transform caption = "Image Transform" default = NullTransform hint = "Use to position/flip/mirror/scale your image mapping." visible = @mode==0 && @v_mmffieldestimator==0 && @smooth!=1 endparam ImageWrapper param f_image caption = "Image Object" default = MMF_ImageImport hint = "The image to use." visible = @mode==0 && @smooth!=1 endparam heading caption = "Texture Settings (divergent)" visible = (@mode==4 || (@mode<2 && @usetexture)) && @smooth!=1 endheading bool param polartex caption = "Go Polar" default = false visible = (@mode==4 || (@mode<2 && @usetexture)) && @smooth!=1 endparam Transfer param f_transferx caption = "Angle Transfer" default = NullTransfer visible = (@mode==4 || (@mode<2 && @usetexture)) && @smooth!=1 endparam Transfer param f_transfery caption = "Distance/Potential Transfer" default = NullTransfer visible = (@mode==4 || (@mode<2 && @usetexture)) && @smooth!=1 endparam Transform param f_textransform caption = "Texture Transform" default = NullTransform visible = (@mode==4 || (@mode<2 && @usetexture)) && @smooth!=1 endparam Transfer param f_texturescale caption = "Texture Amplitude" default = NullTransfer visible = (@mode==4 || (@mode<2 && @usetexture)) && @smooth!=1 endparam TrapShape param f_texture caption = "Texture" default = MMF_TrapShapefBm visible = (@mode==4 || (@mode<2 && @usetexture)) && @smooth!=1 endparam GradientLayer param f_merge caption = "Texture Merge" default = MMF_GradientLayer hint = "Only used if the main colouring is being used in direct colouring \ mode and using 'Image Mapping'. Use to merge the texture value \ with the image. Note that the gradient you choose controls the \ colour of the texture/iteration layer which is normally treated \ as the top layer." visible = @mode<2 && @usetexture && @smooth!=1 expanded = false endparam heading caption = "Convergent Control" visible = @smooth>0 endheading int param modec caption = "Colouring Mode" enum = "Image Mapping" "Mix" "Angles" "Distances" "Texture Only" default = 0 visible = @smooth>0 endparam bool param usetexturec caption = "Add Texture" default = false hint = "Adds texturing when enabled. Normally this will be mixed in as \ a gradient index but if the colouring is in direct mode and \ you're using 'Image Mapping' then the texturing is applied as \ a colour merge layer." visible = @modec<2 && @smooth>0 endparam bool param polarc caption = "Go Polar" default = false hint = "When enabled the angle values are used as angles and the \ distance values as a magnitude, when disabled the angle values \ and distance values are taken as being on perpendicular axes." visible = @modec<2 && @smooth>0 endparam int param mixc caption = "Mix Method" enum = "Sum" "Product" "Absolute Difference" "Quotient 1" "Quotient 2" default = 0 visible = @modec==1 && @smooth>0 endparam int param anglesc caption = "Angle Method" enum = "Field Lines" "Dist.Est. Angles" default = 0 visible = @modec!=3 && @smooth>0 endparam int param distancesc caption = "Distance/Potential" enum = "Smooth Iteration" "Distance Estimator" "Exponential Smoothing" default = 0 visible = @modec!=2 && @smooth>0 endparam DistanceEstimatorBase param distestc caption = "Distance Estimator" default = MMF_NewtonDistanceEstimator hint = "Choose the correct distance estimator for your main fractal \ formula. Note that you can ignore the 'Mode' parameter in the \ distance estimator formula but you need to set any 'Julia ?', \ 'Power' and other parameters correctly." visible = @smooth>0 \ && ((@modec!=3 && @anglesc==1) || (@modec!=2 && @distancesc==1)) endparam float param powerc caption = "Degree of Convergence" default = 2.0 hint = "The degree of convergence of your main formula. The field lines \ algorithm will only work 'correctly' with fractal \ formulas that have positive integer values >=2. For many \ convergent main formulas the value should be 2." visible = (@modec!=3 && @anglesc==0) || (@modec!=2 && @distancesc==0) \ && @smooth>0 endparam float param smallbail caption = "Small Bailout Value" default = 1e-5 hint = "The value you use should match he (convergent) bailout value \ from the main fractal formula." visible = @smooth>0 endparam Transform param f_transformnewc caption = "Colouring Transform" default = NullTransform hint = "Use to position/flip/mirror/scale your image mapping." visible = @modec<2 && @smooth>0 endparam heading caption = "Field Lines Settings (convergent)" visible = @modec!=3 && @anglesc==0 && @smooth>0 endheading int param skipc caption = "Iteration Skip" default = 0 min = 0 hint = "Increasing the value extends the field line detail into areas \ of higher iteration count." visible = @modec!=3 && @anglesc==0 && @smooth>0 endparam bool param originalc caption = "Use Old Algorithm" default = false hint = "Uses the original 'unfixed' version of the algorithm that wasn't \ previously released. May produce more pleasing results on some \ Julia Sets." visible = @modec!=3 && @anglesc==0 && @smooth>0 endparam float param fixconv caption = "Angle Fix" default = 0.0 visible = @modec!=3 && @anglesc==0 && @smooth>0 endparam float param offsetc caption = "Error Reset" default = 1.0 min = 0.0 hint = "Use in combination with 'Error Scale' to correct errors in the \ Field Lines. Note that different areas of a Mandelbrot may \ require different values." visible = @modec!=3 && @anglesc==0 && !@originalc && @smooth>0 endparam float param scalec caption = "Error Scale" default = 1.0 min = 0.0 hint = "Use in combination with 'Error Reset' to correct errors in the \ Field Lines. Note that different areas of a Mandelbrot may \ require different values." visible = @modec!=3 && @anglesc==0 && !@originalc && @smooth>0 endparam bool param accidentc caption = "Happy Accident" default = false hint = "When enabled the algorithm for the field lines uses a 'broken' \ version. The option is available because the broken version \ can produce interesting effects." visible = @modec!=3 && @anglesc==0 && !@originalc && @smooth>0 endparam bool param accident2c caption = "Happy Accident 2" default = false hint = "When enabled the algorithm for the field lines uses a test \ version. The option is available because the test version \ can produce interesting effects." visible = @modec!=3 && @anglesc==0 && @smooth>0 endparam Transfer param fltransferc caption = "Field Lines Transfer" default = NullTransfer hint = "Use to scale/adjust the field line density." visible = @modec<3 && @anglesc==0 && @smooth>0 endparam heading caption = "Dist. Est. Angles Settings (convergent)" visible = @modec<3 && @anglesc==1 && @smooth>0 endheading Transfer param datransferc caption = "Dist. Est. Angles Transfer" default = NullTransfer hint = "Use to scale/adjust the distance estimator angles density." visible = @modec<3 && @anglesc==1 && @smooth>0 endparam heading caption = "Smooth Iteration Settings (convergent)" visible = @modec!=2 && @distancesc==0 && @smooth>0 endheading bool param autopowerc caption = "Auto-Power" default = true hint = "When enabled the degree of divergence of the fractal is \ calculated rather than using the 'Power/Degree/Exponent' value." visible = @modec!=2 && @distancesc==0 && @smooth>0 endparam bool param fixedconv caption = "Fixed Convergence" default = false hint = "Enable when the main formula is testing for bailout using a \ fixed convergence value rather than the change in z i.e. when \ the main formula tests using |z-value| rather than |z-zold|." visible = @modec!=2 && @distancesc==0 && @smooth>0 endparam complex param convval caption = "Convergence Value" default = (1,0) hint = "Set this to the value that the main formula is using for testing \ for convergence i.e. value in |z-value|." visible = @modec!=2 && @distancesc==0 && @smooth>0 && @fixedconv endparam Transfer param ittransferc caption = "Smooth Iteration Transfer" default = NullTransfer hint = "Use to scale/adjust the iteration density." visible = @modec!=2 && @modec!=4 && @distancesc==0 && @smooth>0 endparam heading caption = "Distance Estimator Settings (convergent)" visible = @modec!=2 && @modec!=4 && @distancesc==1 && @smooth>0 endheading Transfer param detransferc caption = "Distance Estimator Transfer" default = NullTransfer hint = "Use to scale/adjust the distance estimator density." visible = @modec!=2 && @modec!=4 && @distancesc==1 && @smooth>0 endparam heading caption = "Exponential Smoothing Settings (convergent)" visible = @modec!=2 && @modec!=4 && @distancesc==2 && @smooth>0 endheading bool param fixexpc caption = "Improved Exponential" default = false hint = "When enabled the final z value is used in calculating the \ exponential smoothing. This will noticeably improve the results \ at less extreme bailout values." visible = @modec!=2 && @modec!=4 && @distancesc==2 && @smooth>0 endparam Transfer param extransferc caption = "Exponential Smoothing Transfer" default = NullTransfer hint = "Use to scale/adjust the exponential smoothing density." visible = @modec!=2 && @modec!=4 && @distancesc==2 && @smooth>0 endparam heading caption = "Image Settings (convergent)" visible = @modec==0 && @smooth>0 endheading int param mapmethodc caption = "Image Method" enum = "Image All" "Image Red" "Image Green" "Image Blue" "Image Alpha" \ "Image Hue" "Image Saturation" "Image Luminance" "Image Brightness" hint = "'Image All' maps the image brightness (Yiq) to UF's gradient \ if the colouring is being used as a gradient colouring or uses \ the image colours if the colouring is being used as a direct \ colouring. 'Image Red' maps the image red to a gradient, \ 'Image Green' the green, 'Image Blue' the blue, 'Image Hue' \ the hue, 'Image Saturation' the saturation and 'Image Luminance' \ the luminance. 'Image Brightness' works exactly the same as \ 'Image All' if in gradient mode or maps the image brightness to \ a gradient if in direct mode." visible = @modec==0 && @smooth>0 endparam bool param usegradientc caption = "Use Custom Gradient ?" default = false hint = "Only relevant if in direct colouring mode. If disabled then the \ value from the image is translated to a colour using UF's in-built \ gradient (as is always the case in gradient colouring mode), \ enable if you wish to use a gradient specified as user \ parameters instead." visible = @modec==0 && @smooth>0 && @mapmethodc!="Image All" \ && @v_mmffieldestimator>=5 endparam MMF_UserGradient param usergradientc caption = "Custom Gradient" default = MMF_Gradient hint = "Create a custom gradient." visible = @modec==0 && @smooth>0 && @mapmethodc!="Image All" \ && @v_mmffieldestimator>=5 && @usegradientc endparam bool param adjustlayerc caption = "Add Adjust layer" default = false hint = "Allows you to add an adjustment layer in a given colour to merge \ on top of the image/texture. Only works if the main colouring \ is in direct mode." visible = @modec==0 && (@mapmethodc=="Image All" || @v_mmffieldestimator>=5) \ && @smooth>0 endparam int param adjusttypec caption = "Colour or RGB" enum = "RGB values" "Colour Parameter" default = 1 hint = "This option is specifically added so that if you choose \ 'RGB values' you can 'explore' them and see changes to the image \ as you change the RGB. The option may become redundant in a \ future version of UF. Only works if the main colouring \ is in direct mode." visible = @modec==0 && (@mapmethodc=="Image All" || @v_mmffieldestimator>=5) \ && @adjustlayerc && @smooth>0 endparam float param adjredc caption = "Red Value" default = 1.0 hint = "The red part of the adjust colour (0 to 1). Only works if the \ main colouring is in direct mode." visible = @modec==0 && (@mapmethodc=="Image All" || @v_mmffieldestimator>=5) \ && @adjustlayerc && @adjusttypec==0 && @smooth>0 endparam float param adjgreenc caption = "Green Value" default = 1.0 hint = "The green part of the adjust colour (0 to 1). Only works if the \ main colouring is in direct mode." visible = @modec==0 && (@mapmethodc=="Image All" || @v_mmffieldestimator>=5) \ && @adjustlayerc && @adjusttypec==0 && @smooth>0 endparam float param adjbluec caption = "Blue Value" default = 1.0 hint = "The blue part of the adjust colour (0 to 1). Only works if the \ main colouring is in direct mode." visible = @modec==0 && (@mapmethodc=="Image All" || @v_mmffieldestimator>=5) \ && @adjustlayerc && @adjusttypec==0 && @smooth>0 endparam color param f_adjustcolourc caption = "Adjust Layer Colour" default = RGB(1,1,1) hint = "Allows you to apply overall adjustments to your colouring. Only \ works if the main colouring is in direct mode." visible = @modec==0 && (@mapmethodc=="Image All" || @v_mmffieldestimator>=5) \ && @adjustlayerc && @adjusttypec==1 && @smooth>0 endparam ColorMerge param f_adjustc caption = "Adjustment Layer Merge" default = MMF_ExtendedColorMerge hint = "Only works if the main colouring is in direct mode." visible = @modec==0 && (@mapmethodc=="Image All" || @v_mmffieldestimator>=5) \ && @adjustlayerc && @smooth>0 endparam float param f_opacityc caption = "Adjustment Opacity" default = 1.0 hint = "Use to modify the adjustment opacity, the normal range is from \ 0 to 1. Only works if the main colouring \ is in direct mode." visible = @modec==0 && (@mapmethodc=="Image All" || @v_mmffieldestimator>=5) \ && @adjustlayerc && @smooth>0 endparam ImageWrapper param f_imagec caption = "Image Object" default = MMF_ImageImport hint = "The image to use." visible = @modec==0 && @smooth>0 endparam heading caption = "Texture Settings (convergent)" visible = (@modec==4 || (@modec<2 && @usetexturec)) && @smooth>0 endheading bool param polartexc caption = "Go Polar" default = false visible = (@modec==4 || (@modec<2 && @usetexturec)) && @smooth>0 endparam Transfer param f_transferxc caption = "Angle Transfer" default = NullTransfer visible = (@modec==4 || (@modec<2 && @usetexturec)) && @smooth>0 endparam Transfer param f_transferyc caption = "Distance/Potential Transfer" default = NullTransfer visible = (@modec==4 || (@modec<2 && @usetexturec)) && @smooth>0 endparam Transform param f_textransformc caption = "Texture Transform" default = NullTransform visible = (@modec==4 || (@modec<2 && @usetexturec)) && @smooth>0 endparam Transfer param f_texturescalec caption = "Texture Amplitude" default = NullTransfer visible = (@modec==4 || (@modec<2 && @usetexturec)) && @smooth>0 endparam TrapShape param f_texturec caption = "Texture" default = MMF_TrapShapefBm visible = (@modec==4 || (@modec<2 && @usetexturec)) && @smooth>0 endparam GradientLayer param f_mergec caption = "Texture Merge" default = MMF_GradientLayer hint = "Only used if the main colouring is being used in direct colouring \ mode and using 'Image Mapping'. Use to merge the texture value \ with the image. Note that the gradient you choose controls the \ colour of the texture/iteration layer which is normally treated \ as the top layer." visible = @modec<2 && @usetexturec && @smooth>0 expanded = false endparam } class MMF_TwoColourings(common.ulb:GradientColoring) { public: import "Standard.ulb" func MMF_TwoColourings(Generic pparent) if @mode!=3 m_Colouring1 = new @f_colouring1(pparent) if @f_transfer1!=NullTransfer m_Transfer1 = new @f_transfer1(this) endif endif if @mode!=2 m_Colouring2 = new @f_colouring2(pparent) if @f_transfer2!=NullTransfer m_Transfer2 = new @f_transfer2(this) endif endif if @f_transform!=NullTransform && @mode<2 m_Transform = new @f_transform(this) endif if @mode=="Image Mapping" m_Image = new @f_image(this) if @mapmethod!="Image All" && @v_mmftwocolourings>=1 && @usegradient usergradient = new @usergradient(this) endif if @adjustlayer m_Adjust = new @f_adjust(this) endif endif if @mode==4 || (@mode<2 && @usetexture) if @f_transferx!=NullTransform m_Transferx = new @f_transferx(this) endif if @f_transfery!=NullTransform m_Transfery = new @f_transfery(this) endif if @f_textransform!=NullTransform m_TexTransform = new @f_textransform(this) endif if @f_texturescale!=NullTransfer m_TextureScale = new @f_texturescale(this) endif m_Texture = new @f_texture(this) m_Merge = new @f_merge(this) endif endfunc func Init(complex pz, complex ppixel) if @mode!=3 m_Colouring1.Init(pz,ppixel) if @f_transfer1!=NullTransfer m_Transfer1.Init(0) endif endif if @mode!=2 m_Colouring2.Init(pz,ppixel) if @f_transfer2!=NullTransfer m_Transfer2.Init(0) endif endif if @f_transform!=NullTransform && @mode<2 m_Transform.Init(pz) endif if @mode==4 || (@mode<2 && @usetexture) if @f_transferx!=NullTransform m_Transferx.Init(0) endif if @f_transfery!=NullTransform m_Transfery.Init(0) endif if @f_textransform!=NullTransform m_TexTransform.Init(pz) endif if @f_texturescale!=NullTransfer m_TextureScale.Init(0) endif m_Texture.Init(pz) endif endfunc func Iterate(complex pz) if @mode!=3 m_Colouring1.Iterate(pz) endif if @mode!=2 m_Colouring2.Iterate(pz) endif endfunc float func ResultIndex(complex pz) float s = 0.0 float t = 0.0 float r = 0.0 complex v = (0,0) u = 0.0 if @mode!=3 r = s = m_Colouring1.ResultIndex(pz) if (@mode==4 || (@mode<2 && @usetexture)) && @f_transferx!=NullTransfer r = m_Transferx.Iterate(r) endif if @f_transfer1!=NullTransfer s = m_Transfer1.Iterate(s) endif if @mode==2 return s endif endif if @mode!=2 u = t = m_Colouring2.ResultIndex(pz) if (@mode==4 || (@mode<2 && @usetexture)) && @f_transfery!=NullTransfer u = m_Transfery.Iterate(u) endif if @f_transfer2!=NullTransfer t = m_Transfer2.Iterate(t) endif if @mode==3 return t endif endif if @f_transform!=NullTransform && @mode<4 v = m_Transform.Iterate(s + flip(t)) s = real(v) t = imag(v) endif if (@mode==4 || (@mode<2 && @usetexture)) && @f_textransform!=NullTransform v = m_TexTransform.Iterate(r + flip(u)) r = real(v) u = imag(v) endif if @mode==4 || (@mode<2 && @usetexture) if @polartex r = r*2.0*#pi if @mode>0 v = 0.5*u*(cos(r)+1.0 - flip(sin(r)-1.0)) else v = u*(cos(r) - flip(sin(r))) endif r = real(v) u = imag(v) endif u = m_Texture.Iterate(r+flip(u)) if @f_texturescale!=NullTransfer u = m_TextureScale.Iterate(u) endif endif if @polar s = s*2.0*#pi if @mode>0 v = 0.5*t*(cos(s)+1.0 - flip(sin(s)-1.0)) else v = t*(cos(s) - flip(sin(s))) endif s = real(v) t = imag(v) endif if @mode==4 return u elseif @mode==1 if @usetexture if @mix=="Sum" return s + t + u elseif @mix=="Product" return s*t + u elseif @mix=="Absolute Difference" return abs(s - t) + u elseif @mix=="Quotient 1" return s/(t + 1) + u else;if @mix=="Quotient 2" return t/(s + 1) + u endif elseif @mix=="Sum" return s + t elseif @mix=="Product" return s*t elseif @mix=="Absolute Difference" return abs(s - t) elseif @mix=="Quotient 1" return s/(t + 1) else;if @mix=="Quotient 2" return t/(s + 1) endif else if !@polar s = 2*s - 1.0 t = 2*t - 1.0 endif clr = m_Image.GetColor(s+flip(t)) if @usetexture if @mapmethod=="Image All" || @mapmethod=="Image Brightness" return 0.299*red(clr) + 0.587*green(clr) + 0.114*blue(clr) + u elseif @mapmethod=="Image Red" return red(clr) + u elseif @mapmethod=="Image Green" return green(clr) + u elseif @mapmethod=="Image Blue" return blue(clr) + u elseif @mapmethod=="Image Alpha" return alpha(clr) + u elseif @mapmethod=="Image Hue" return hue(clr)/6.0 + u elseif @mapmethod=="Image Saturation" return sat(clr) + u else;if @mapmethod=="Image Luminance" return lum(clr) + u endif elseif @mapmethod=="Image All" || @mapmethod=="Image Brightness" return 0.299*red(clr) + 0.587*green(clr) + 0.114*blue(clr) elseif @mapmethod=="Image Red" return red(clr) elseif @mapmethod=="Image Green" return green(clr) elseif @mapmethod=="Image Blue" return blue(clr) elseif @mapmethod=="Image Alpha" return alpha(clr) elseif @mapmethod=="Image Hue" return hue(clr)/6.0 elseif @mapmethod=="Image Saturation" return sat(clr) else;if @mapmethod=="Image Luminance" return lum(clr) endif endif endfunc color func Result(complex pz) float v = ResultIndex(pz) if @mode==0 && (@mapmethod=="Image All" || @v_mmftwocolourings>=1) if @v_mmftwocolourings>=1 && @mapmethod!="Image All" if @usegradient if @mapmethod=="Image Red" clr = usergradient.GetColour(red(clr)) elseif @mapmethod=="Image Green" clr = usergradient.GetColour(green(clr)) elseif @mapmethod=="Image Blue" clr = usergradient.GetColour(blue(clr)) elseif @mapmethod=="Image Alpha" clr = usergradient.GetColour(alpha(clr)) elseif @mapmethod=="Image Hue" clr = usergradient.GetColour(hue(clr)/6.0) elseif @mapmethod=="Image Saturation" clr = usergradient.GetColour(sat(clr)) elseif @mapmethod=="Image Luminance" clr = usergradient.GetColour(lum(clr)) elseif @mapmethod=="Image Brightness" clr = usergradient.GetColour(0.299*red(clr) + 0.587*green(clr) \ + 0.114*blue(clr)) endif elseif @mapmethod=="Image Red" clr = gradient(red(clr)) elseif @mapmethod=="Image Green" clr = gradient(green(clr)) elseif @mapmethod=="Image Blue" clr = gradient(blue(clr)) elseif @mapmethod=="Image Alpha" clr = gradient(alpha(clr)) elseif @mapmethod=="Image Hue" clr = gradient(hue(clr)/6.0) elseif @mapmethod=="Image Saturation" clr = gradient(sat(clr)) elseif @mapmethod=="Image Luminance" clr = gradient(lum(clr)) elseif @mapmethod=="Image Brightness" clr = gradient(0.299*red(clr) + 0.587*green(clr) + 0.114*blue(clr)) endif endif if @usetexture clr = m_Merge.GradientMerge(clr, u) endif if @adjustlayer color c = @f_adjustcolour if @adjusttype==0 c = RGB(@adjred, @adjgreen, @adjblue) endif c = compose(clr, m_Adjust.Merge(clr, c), @f_opacity) return RGBA(red(c), green(c), blue(c), alpha(clr)) endif return clr endif return gradient(v) endfunc private: GradientColoring m_Colouring1 GradientColoring m_Colouring2 Transfer m_Transfer1 Transfer m_Transfer2 Transfer m_Transferx Transfer m_Transfery Transfer m_TextureScale Transform m_Transform Transform m_TexTransform ImageWrapper m_Image ColorMerge m_Adjust TrapShape m_Texture GradientLayer m_Merge MMF_UserGradient usergradient color clr float u default: title = "MMF Two Colourings" int param v_mmftwocolourings caption = "Version (MMF Two Colourings)" enum = "1.0" "1.1" default = 1 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = @v_mmftwocolourings<1 endparam heading caption = "Main Control" endheading int param mode caption = "Colouring Mode" enum = "Image Mapping" "Mix" "Colouring 1" "Colouring 2" "Texture Only" default = 0 endparam bool param usetexture caption = "Add Texture" default = false hint = "Adds texturing when enabled. Normally this will be mixed in as \ a gradient index but if the colouring is in direct mode and \ you're using 'Image Mapping' then the texturing is applied as \ a colour merge layer." visible = @mode<2 endparam bool param polar caption = "Go Polar" default = false hint = "When enabled the angle values are used as angles and the \ distance values as a magnitude, when disabled the angle values \ and distance values are taken as being on perpendicular axes." visible = @mode<2 endparam int param mix caption = "Mix Method" enum = "Sum" "Product" "Absolute Difference" "Quotient 1" "Quotient 2" default = 0 visible = @mode==1 endparam Transform param f_transform caption = "Colouring Transform" default = NullTransform hint = "Use for rotation/scaling/positioning." visible = @mode<2 endparam heading caption = "Colouring 1 Settings" visible = @mode!=3 endheading GradientColoring param f_colouring1 caption = "Colouring 1" default = MMF_SmoothOrbitTraps visible = @mode!=3 endparam Transfer param f_transfer1 caption = "Colour Transfer 1" default = NullTransfer visible = @mode<3 endparam heading caption = "Colouring 2 Settings" visible = @mode!=2 endheading GradientColoring param f_colouring2 caption = "Colouring 2" default = Standard_Smooth visible = @mode!=2 endparam Transfer param f_transfer2 caption = "Colour Transfer 2" default = NullTransfer visible = @mode!=2 && @mode!=4 endparam heading caption = "Image Mapping Settings" visible = @mode==0 endheading int param mapmethod caption = "Image Method" enum = "Image All" "Image Red" "Image Green" "Image Blue" "Image Alpha" \ "Image Hue" "Image Saturation" "Image Luminance" "Image Brightness" hint = "'Image All' maps the image brightness (Yiq) to UF's gradient \ if the colouring is being used as a gradient colouring or uses \ the image colours if the colouring is being used as a direct \ colouring. 'Image Red' maps the image red to a gradient, \ 'Image Green' the green, 'Image Blue' the blue, 'Image Hue' \ the hue, 'Image Saturation' the saturation and 'Image Luminance' \ the luminance. 'Image Brightness' works exactly the same way as \ 'Image All' when in gradient mode and maps the image brightness \ to a gradient when in direct mode." visible = @mode==0 endparam bool param usegradient caption = "Use Custom Gradient ?" default = false hint = "Only relevant if in direct colouring mode. If disabled then the \ value from the image is translated to a colour using UF's in-built \ gradient (as is always the case in gradient colouring mode), \ enable if you wish to use a gradient specified as user \ parameters instead." visible = @mode==0 && @mapmethod!="Image All" && @v_mmftwocolourings>=1 endparam MMF_UserGradient param usergradient caption = "Custom Gradient" default = MMF_Gradient hint = "Create a custom gradient." visible = @mode==0 && @mapmethod!="Image All" && @v_mmftwocolourings>=1 \ && @usegradient endparam bool param adjustlayer caption = "Add Adjust layer" default = false hint = "Allows you to add an adjustment layer in a given colour to merge \ on top of the image/texture. Only works if the main colouring \ is in direct mode." visible = @mode==0 && (@mapmethod=="Image All" || @v_mmftwocolourings>=1) endparam int param adjusttype caption = "Colour or RGB" enum = "RGB values" "Colour Parameter" default = 1 hint = "This option is specifically added so that if you choose \ 'RGB values' you can 'explore' them and see changes to the image \ as you change the RGB. The option may become redundant in a \ future version of UF. Only works if the main colouring is in \ direct mode." visible = @mode==0 && (@mapmethod=="Image All" || @v_mmftwocolourings>=1) \ && @adjustlayer endparam float param adjred caption = "Red Value" default = 1.0 hint = "The red part of the adjust colour (0 to 1). Only works if the \ main colouring is in direct mode." visible = @mode==0 && (@mapmethod=="Image All" || @v_mmftwocolourings>=1) \ && @adjustlayer && @adjusttype==0 endparam float param adjgreen caption = "Green Value" default = 1.0 hint = "The green part of the adjust colour (0 to 1). Only works if the \ main colouring is in direct mode." visible = @mode==0 && (@mapmethod=="Image All" || @v_mmftwocolourings>=1) \ && @adjustlayer && @adjusttype==0 endparam float param adjblue caption = "Blue Value" default = 1.0 hint = "The blue part of the adjust colour (0 to 1). Only works if the \ main colouring is in direct mode." visible = @mode==0 && (@mapmethod=="Image All" || @v_mmftwocolourings>=1) \ && @adjustlayer && @adjusttype==0 endparam color param f_adjustcolour caption = "Adjust Layer Colour" default = RGB(1,1,1) hint = "Allows you to apply overall adjustments to your colouring. Only \ works if the main colouring is in direct mode." visible = @mode==0 && (@mapmethod=="Image All" || @v_mmftwocolourings>=1) \ && @adjustlayer && @adjusttype==1 endparam ColorMerge param f_adjust caption = "Adjustment Layer Merge" default = MMF_ExtendedColorMerge hint = "Only works if the main colouring is in direct mode." visible = @mode==0 && (@mapmethod=="Image All" || @v_mmftwocolourings>=1) \ && @adjustlayer endparam float param f_opacity caption = "Adjustment Opacity" default = 1.0 hint = "Use to modify the adjustment opacity, the normal range is from \ 0 to 1. Only works if the main colouring is in direct mode." visible = @mode==0 && (@mapmethod=="Image All" || @v_mmftwocolourings>=1) \ && @adjustlayer endparam ImageWrapper param f_image caption = "Image Object" default = MMF_ImageImport hint = "The image to use." visible = @mode==0 endparam heading caption = "Texture Settings" visible = @mode==4 || (@mode<2 && @usetexture) endheading bool param polartex caption = "Polar Texture" default = false visible = @mode==4 || (@mode<2 && @usetexture) endparam Transfer param f_transferx caption = "Colouring 1 Transfer" default = NullTransfer visible = @mode==4 || (@mode<2 && @usetexture) endparam Transfer param f_transfery caption = "Colouring 2 Transfer" default = NullTransfer visible = @mode==4 || (@mode<2 && @usetexture) endparam Transform param f_textransform caption = "Texture Transform" default = NullTransform visible = @mode==4 || (@mode<2 && @usetexture) endparam TrapShape param f_texture caption = "Texture" default = MMF_TrapShapefBm visible = @mode==4 || (@mode<2 && @usetexture) endparam Transfer param f_texturescale caption = "Texture Amplitude" default = NullTransfer visible = @mode==4 || (@mode<2 && @usetexture) endparam GradientLayer param f_merge caption = "Texture Merge" default = MMF_GradientLayer hint = "Only used if the main colouring is being used in direct colouring \ mode and using 'Image Mapping'. Use to merge the texture value \ with the image. Note that the gradient you choose controls the \ colour of the texture/iteration layer which is normally treated \ as the top layer." visible = @mode<2 && @usetexture expanded = false endparam } class MMF_ExtendedCilia(common.ulb:GradientColoring) { ; ; Object version of ExtendedCilia in mmf3.ucl.
; This is an extension of Damien's Cilia colouring.

; It can use the "finalz" smoothing where a smoothing ; fraction is passed from the main formula based on ; a method suggested by Earl Hinrichs and it has a new ; extension to standard logarithmic smoothing in which ; the power/degree/exponent required for smoothing is ; calculated automagically by the formula - this works ; extremely well as long as the bailout/s are correct.

; It's also extended to allow Cilia for convergent areas ; and has new double-smoothed options that produce ; smooth results for those formulas with a smoothing ; power other than 2 (this is a cheat, there is a 'proper' ; way to do it but that only really works for whole ; integer powers (which you can now do using the "split" ; options with 'Interpolated', 'Sine Waves', 'Cells' or 'Bricks').

; This version includes options to "fix" the rotation and skew.

; NB. When using Hinrich's smoothing since the real part ; of the final z value is the smoothing fraction the ; formula doesn't know the actual final z value for ; the cilia hence only using older iterations will ; work unless you choose a main fractal formula using ; "+Atan" Hinrich's smoothing in which case 'No' for ; 'Old iterations' will work.

; ; Written by David Makin including ideas from many sources
; Original mmf3 formula November 2004
; Updated May 2009 ; public: ; @param pparent the parent, generally "this" for the parent, or zero func MMF_ExtendedCilia(Generic pparent) float rv = @rot*@split^-@rpwr float crv = @crot*@csplit^-@crpwr int gi = 0 il = real(1.0/log(@power)) ; for divergent smoothing lp = log(0.5*log(@bailout)) ilp = il*lp cil = real(1.0/log(@cpower)) ; for convergent smoothing clp = log(-0.5*log(@smallbail)) cilp = cil*clp iv = 0.0001*@iterval*@iterweight ivc = 0.0001*@citerval*@iterweightc iw = 1.0 - 0.01*@iterweight iwc = 1.0 - 0.01*@iterweightc co = 0.0025*@convoffset if @ciliamode!=6 && @ciliamode!=7 if @fixrot repeat rv = @split*rv rval[gi] = rv = rv - floor(rv) until (gi=gi+1)>#maxiter if @fixskew && @skew!=0.0 rv = 0.0 gi = 0 repeat rval[gi] = rval[gi] + rv rv = (rv + @skew)*@split rv = rv - floor(rv) until (gi=gi+1)>#maxiter endif endif if @cfixrot gi = 0 repeat crv = @csplit*crv crval[gi] = crv = crv - floor(crv) until (gi=gi+1)>#maxiter if @cfixskew && @cskew!=0.0 crv = 0.0 gi = 0 repeat crval[gi] = crval[gi] + crv crv = (crv + @cskew)*@csplit crv = crv - floor(crv) until (gi=gi+1)>#maxiter endif endif endif if @mapimage m_Image = new @f_image(this) m_Transform = new @f_transform(this) if @iterval>0 m_Merge = new @f_merge(this) endif if (@method==0 || @method==2 || @method==3 || @method>4) \ && @mapmethod!="Image All" && @v_mmfextendedcilia>=3 && @usegradient usergradient = new @usergradient(this) endif if @adjustlayer m_Adjust = new @f_adjust(this) endif endif if @mapimagec m_Imagec = new @f_imagec(this) m_Transformc = new @f_transformc(this) if @citerval>0 || @zbasin>0 m_Mergec = new @f_mergec(this) endif if (@method==1 || @method==2 || @method>3) \ && @mapmethodc!="Image All" && @v_mmfextendedcilia>=3 && @usegradientc usergradientc = new @usergradientc(this) endif if @adjustlayerc m_Adjustc = new @f_adjustc(this) endif endif endfunc ; @param pz the initial z value ; @param ppixel the location, normally #pixel func Init(complex pz, complex ppixel) GradientColoring.Init(pz, ppixel) if @mapimage m_Transform.Init(pz) endif if @mapimagec m_Transformc.Init(pz) endif z1 = z2 = z3 = z4 = z5 = z6 = pz endfunc ; @param pz the z value func Iterate(complex pz) GradientColoring.Iterate(pz) z6 = z5 z5 = z4 z4 = z3; save them z3 = z2 z2 = z1 z1 = pz endfunc ; @param pz the z value ; @return colour gradient index value float func ResultIndex(complex pz) float d1 = 0.0 float d2 = 0.0 float od = 0.0 float of = 0.0 float fz = 0.0 float fz1 = 0.0 float fz4 = 0.0 float fz5 = 0.0 float r = 0.0 float or = 0.0 float s = 0.0 int cm = 0 int oi = 0 float ivuse = 0.0 float iwuse = 0.0 int li = 0 bool usebasins = false bool isstandard = true int it = m_iterations + 1 float d = 0.0 float f = 0.0 float o = 0.0 iterbasin = 0.0 ; determine potential and decomposition ; this gives us a "coordinate" in d and f, ranging from 0 to 1 f = real(pz); fractional iteration if using Hinrich's smoothing fz = imag(pz) ; atan2(finalz) if using Hinrich's+Atan d1 = |pz| if @cfixed d2 = |pz-@cfixedval| else d2 = |pz-z1| endif if f<0 && d1<@bailout && (@method==4 || @method==5 || @method==6) usebasins = true isstandard = false o = co f = 1.0+@fudge1c*f IF (@colditer == 0) z6 = z3 z5 = z2 z4 = z1 ELSEIF (@colditer == 1) z6 = z4 z5 = z3 z4 = z2 ELSEIF (@colditer == 2) z6 = z5 z5 = z4 z4 = z3 ENDIF fz1 = atan2(z1 - z2) fz4 = atan2(z4 - z5) fz5 = atan2(z5 - z6) if @fixconv d1 = #pi - atan2(z1) fz = fz + d1 fz1 = fz1 + d1 fz4 = fz4 + d1 fz5 = fz5 + d1 endif if @cfixrot && @cciliamode!=6 && @cciliamode!=7 r = crval[it] or = crval[it-1] else r = @crot endif s = @cskew cm = @cciliamode oi = @colditer ivuse = ivc iwuse = iwc li = @logiterc wasdivergent = false elseif d1>=@bailout && (@method==0 || @method==2 || @method==6) IF (@olditer == 0) z6 = z3 z5 = z2 z4 = z1 ELSEIF (@olditer == 1) z6 = z4 z5 = z3 z4 = z2 ELSEIF (@olditer == 2) z6 = z5 z5 = z4 z4 = z3 ENDIF if @dauto && it>1 f = 1.0 + @fudge*real(lp - log(0.5*log(|pz|)))/log(log(|pz|)/log(|z1|)) else f = 1.0 + @fudge*real(ilp - il*log(0.5*log(|pz|))) endif fz = atan2(pz) fz1 = atan2(z1) fz4 = atan2(z4) fz5 = atan2(z5) if @fixrot && @ciliamode!=6 && @ciliamode!=7 r = rval[it] or = rval[it-1] else r = @rot endif s = @skew cm = @ciliamode oi = @olditer ivuse = iv iwuse = iw li = @logiter wasdivergent = true elseif f>=0 && d2>@smallbail && d1<@bailout \ && (@method==3 || @method==5 || @method==7) isstandard = false f = @fudge1*f IF (@olditer == 0) z6 = z3 z5 = z2 z4 = z1 ELSEIF (@olditer == 1) z6 = z4 z5 = z3 z4 = z2 ELSEIF (@olditer == 2) z6 = z5 z5 = z4 z4 = z3 ENDIF fz1 = atan2(z1) fz4 = atan2(z4) fz5 = atan2(z5) if @fixrot && @ciliamode!=6 && @ciliamode!=7 r = rval[it] or = rval[it-1] else r = @rot endif s = @skew cm = @ciliamode oi = @olditer ivuse = iv iwuse = iw li = @logiter wasdivergent = true elseif d2<=@smallbail && (@method==1 || @method==2 || @method==7) usebasins = true o = co IF (@colditer == 0) z6 = z3 z5 = z2 z4 = z1 ELSEIF (@colditer == 1) z6 = z4 z5 = z3 z4 = z2 ELSEIF (@colditer == 2) z6 = z5 z5 = z4 z4 = z3 ENDIF if @cfixed if @cauto && it>2 f = 1.0 + @fudgec*real(clp - log(-0.5*log(|pz-@cfixedval|))) \ /log(log(|pz-@cfixedval|)/log(|z1-@cfixedval|)) else f = 1.0 + @fudgec*real(cilp - cil*log(-0.5*log(|pz-@cfixedval|))) endif elseif @cauto && it>2 f = 1.0 + @fudgec*real(clp - log(-0.5*log(|pz-z1|))) \ /log(log(|pz-z1|)/log(|z1-z2|)) else f = 1.0 + @fudgec*real(cilp - cil*log(-0.5*log(|pz-z1|))) endif fz = atan2(pz - z1) fz1 = atan2(z1 - z2) fz4 = atan2(z4 - z5) fz5 = atan2(z5 - z6) if @fixconv d1 = #pi - atan2(pz) fz = fz + d1 fz1 = fz1 + d1 fz4 = fz4 + d1 fz5 = fz5 + d1 endif if @cfixrot && @cciliamode!=6 && @cciliamode!=7 r = crval[it] or = crval[it-1] else r = @crot endif s = @cskew cm = @cciliamode oi = @colditer ivuse = ivc iwuse = iwc li = @logiterc wasdivergent = false else m_solid = true wasdivergent = true if @v_mmfextendedcilia>0 return 0 endif endif if cm>7 && cm!=14 of = 1-f ; this is the cheating method !! if (oi<4) od = fz5; angle of z else od = fz1; angle of z endif if (od < 0); it's negative od = od + #pi * 2; make it positive endif od = od / (#pi * 2); scale so full angle range is 0..1 ; apply rotation and skew od = od + or + s*of od = od - floor(od) ; convert decomp and pot to tileable value d ; this is where the patterns are made IF cm==8; sawtooth IF (od < 0.5) od = od * (of+1.0) ELSE od = (od-0.5) * (of+1.0) - 0.5*of + 0.5 ENDIF od = abs(1.0-od*2.0) ELSEIF cm==9; interpolated d1 = abs(1.0-od*2.0) if @v_mmfextendedcilia<2 || wasdivergent d2 = abs(1.0-(od*@split-floor(od*@split))*2.0) else d2 = abs(1.0-(od*@csplit-floor(od*@csplit))*2.0) endif od = d1 + of*(d2-d1) ELSEIF cm==10; sine waves d1 = cos(od*#pi*2.0)*0.5 + 0.5 if @v_mmfextendedcilia<2 || wasdivergent d2 = cos(od*#pi*2.0*@split)*0.5 + 0.5 else d2 = cos(od*#pi*2.0*@csplit)*0.5 + 0.5 endif od = d1 + of*(d2-d1) ELSEIF cm==11; cells od = ((0.25-sqr(od-0.5)) * (0.25-sqr(of-0.5))) * 16.0 ELSEIF cm==12; bricks d1 = 1.0 - abs(od-0.5)*2.0 d2 = 1.0 - abs(of-0.5)*2.0 IF (d1 < d2) od = d1 ELSE od = d2 ENDIF ELSEIF cm==13; diamonds od = 0.5 - abs(od - 0.5) IF (of < 2.0/3.0) od = od + of*0.75 od = abs(1.0-od*2.0) ELSE IF (od < of*0.75-0.5) od = of*3.0-2.0-od*4.0 ELSE od = 1.0-(0.5-od)/(1.0-of*0.75) ENDIF ENDIF endif endif if (oi<4) d = fz4; angle of z else d = fz endif IF (d < 0); it's negative d = d + #pi * 2.0; make it positive ENDIF d = d / (#pi * 2.0); scale so full angle range is 0..1 ; apply rotation and skew d = d + r + s*f d = d - floor(d) ; convert decomp and pot to tileable value d ; this is where the patterns are made IF (cm == 0) || cm==8; sawtooth IF (d < 0.5) d = d * (f+1.0) ELSE d = (d-0.5) * (f+1.0) - 0.5*f + 0.5 ENDIF d = abs(1.0-d*2.0) ELSEIF (cm == 1) || cm==9; interpolated d1 = abs(1.0-d*2.0) if @v_mmfextendedcilia<2 || wasdivergent d2 = abs(1.0-(d*@split-floor(d*@split))*2.0) else d2 = abs(1.0-(d*@csplit-floor(d*@csplit))*2.0) endif d = d1 + f*(d2-d1) ELSEIF (cm == 2) || cm==10; sine waves d1 = cos(d*#pi*2.0)*0.5 + 0.5 if @v_mmfextendedcilia<2 || wasdivergent d2 = cos(d*#pi*2.0*@split)*0.5 + 0.5 else d2 = cos(d*#pi*2.0*@csplit)*0.5 + 0.5 endif d = d1 + f*(d2-d1) ELSEIF (cm == 3) || cm==11; cells d = ((0.25-sqr(d-0.5)) * (0.25-sqr(f-0.5))) * 16.0 ELSEIF (cm == 4) || cm==12; bricks d1 = 1.0 - abs(d-0.5)*2.0 d2 = 1.0 - abs(f-0.5)*2.0 IF (d1 < d2) d = d1 ELSE d = d2 ENDIF ELSEIF (cm == 5) || cm==13; diamonds d = 0.5 - abs(d - 0.5) IF (f < 2.0/3.0) d = d + f*0.75 d = abs(1.0-d*2.0) ELSE IF (d < f*0.75-0.5) d = f*3.0-2.0-d*4.0 ELSE d = 1.0-(0.5-d)/(1.0-f*0.75) ENDIF ENDIF elseif (cm == 6) ;Smoothed angles if oi<4 if fz4<-#pi fz4 = fz4 + 2*#pi elseif fz4>#pi fz4 = fz4 - 2*#pi endif if fz5<-#pi fz5 = fz5 + 2*#pi elseif fz5>#pi fz5 = fz5 - 2*#pi endif d = cos(0.5*fz4) d1 = cos(0.5*fz5); angle of older z else if fz<-#pi fz = fz + 2*#pi elseif fz>#pi fz = fz - 2*#pi endif if fz1<-#pi fz1 = fz1 + 2*#pi elseif fz1>#pi fz1 = fz1 - 2*#pi endif d = cos(0.5*fz) d1 = cos(0.5*fz1) endif d1 = d1 + s*f d = d + r*f d1 = d1 + r*(1-f) d = abs(d1 + (d-d1)*f) elseif (cm == 7) ;Just smooth iteration d = (-0.125 + 0.05*(it+f))^@ip ENDIF if cm>7 && cm!=14 d = od+(d-od)*f endif duse = d if cm != 7 && ivuse>0 d1 = it + f if li==1 d1 = log(1.0+d1) elseif li==2 d1 = log(1.0+log(1.0+d1)) endif if @v_mmfextendedcilia>=3 if wasdivergent iterbasin = @iterval*d1 else iterbasin = @citerval*d1 endif else iterbasin = d1 endif d = ivuse*d1 + iwuse*d endif if usebasins && @zbasin>0 if isstandard z2 = z1 z1 = pz endif if @zbasin==1 d1 = abs(real(2.0*#pi+atan2(z1))) od = abs(real(2.0*#pi+atan2(z2))) elseif @zbasin==2 d1 = abs(real(z1)) od = abs(real(z2)) elseif @zbasin==3 d1 = abs(imag(z1)) od = abs(imag(z2)) elseif @zbasin==4 d1 = abs(real(z1)+imag(z1)) od = abs(real(z2)+imag(z2)) elseif @zbasin==5 d1 = abs(2.0*real(z1)+imag(z1)) od = abs(2.0*real(z2)+imag(z2)) elseif @zbasin==6 d1 = abs(real(z1)+2.0*imag(z1)) od = abs(real(z2)+2.0*imag(z2)) elseif @zbasin==7 d1 = abs(real(z1)/(abs(imag(z1))+1.0)) od = abs(real(z2)/(abs(imag(z2))+1.0)) elseif @zbasin==8 d1 = abs(imag(z1)/(abs(real(z1))+1.0)) od = abs(imag(z2)/(abs(real(z2))+1.0)) elseif @zbasin==9 d1 = abs(2.0*real(sqrt(z1))+imag(sqrt(z1))) od = abs(2.0*real(sqrt(z2))+imag(sqrt(z2))) elseif @zbasin==10 d1 = abs(real(sqrt(z1))+2.0*imag(sqrt(z1))) od = abs(real(sqrt(z2))+2.0*imag(sqrt(z2))) endif d = d + (od=@zscale*(od+(d1-od)*f)) iterbasin = iterbasin + od endif if @mapimage && wasdivergent if f<0.0 f = f + 1.0 endif d = 2*((o+d)- floor(o+d)) - 1 duse = 2*((o+duse)- floor(o+duse)) - 1 fuse = f = 2*((it%@spread) + f)/@spread - 1 clr = m_Image.GetColor(m_Transform.Iterate(d+flip(f))) if @mapmethod=="Image All" || @mapmethod=="Image Brightness" return 0.299*red(clr) + 0.587*green(clr) + 0.114*blue(clr) elseif @mapmethod=="Image Red" return red(clr) elseif @mapmethod=="Image Green" return green(clr) elseif @mapmethod=="Image Blue" return blue(clr) elseif @mapmethod=="Image Alpha" return alpha(clr) elseif @mapmethod=="Image Hue" return hue(clr)/6.0 elseif @mapmethod=="Image Saturation" return sat(clr) elseif @mapmethod=="Image Luminance" return lum(clr) endif elseif @mapimagec && !wasdivergent d = 2*((o + d)- floor(o+d)) - 1 duse = 2*((o+duse)- floor(o+duse)) - 1 fuse = f = 2*((it%@spreadc) + f)/@spreadc - 1 clr = m_Imagec.GetColor(m_Transformc.Iterate(d+flip(f))) if @mapmethodc=="Image All" || @mapmethodc=="Image Brightness" return 0.299*red(clr) + 0.587*green(clr) + 0.114*blue(clr) elseif @mapmethodc=="Image Red" return red(clr) elseif @mapmethodc=="Image Green" return green(clr) elseif @mapmethodc=="Image Blue" return blue(clr) elseif @mapmethodc=="Image Alpha" return alpha(clr) elseif @mapmethodc=="Image Hue" return hue(clr)/6.0 elseif @mapmethodc=="Image Saturation" return sat(clr) elseif @mapmethodc=="Image Luminance" return lum(clr) endif endif return o + d * 0.9975 endfunc ; @param pz the z value ; @return colour value color func Result(complex pz) float v = ResultIndex(pz) if (@mapimage && (@mapmethod=="Image All" || @v_mmfextendedcilia>=3) \ && wasdivergent) \ || (@mapimagec && (@mapmethodc=="Image All" || @v_mmfextendedcilia>=3) \ && !wasdivergent) if wasdivergent clr = m_Image.GetColor(m_Transform.Iterate(duse+flip(fuse))) if @v_mmfextendedcilia>=3 && @mapmethod!="Image All" if @usegradient if @mapmethod=="Image Red" clr = usergradient.GetColour(red(clr)) elseif @mapmethod=="Image Green" clr = usergradient.GetColour(green(clr)) elseif @mapmethod=="Image Blue" clr = usergradient.GetColour(blue(clr)) elseif @mapmethod=="Image Alpha" clr = usergradient.GetColour(alpha(clr)) elseif @mapmethod=="Image Hue" clr = usergradient.GetColour(hue(clr)/6.0) elseif @mapmethod=="Image Saturation" clr = usergradient.GetColour(sat(clr)) elseif @mapmethod=="Image Luminance" clr = usergradient.GetColour(lum(clr)) elseif @mapmethod=="Image Brightness" clr = usergradient.GetColour(0.299*red(clr) + 0.587*green(clr) \ + 0.114*blue(clr)) endif elseif @mapmethod=="Image Red" clr = gradient(red(clr)) elseif @mapmethod=="Image Green" clr = gradient(green(clr)) elseif @mapmethod=="Image Blue" clr = gradient(blue(clr)) elseif @mapmethod=="Image Alpha" clr = gradient(alpha(clr)) elseif @mapmethod=="Image Hue" clr = gradient(hue(clr)/6.0) elseif @mapmethod=="Image Saturation" clr = gradient(sat(clr)) elseif @mapmethod=="Image Luminance" clr = gradient(lum(clr)) elseif @mapmethod=="Image Brightness" clr = gradient(0.299*red(clr) + 0.587*green(clr) + 0.114*blue(clr)) endif endif if @adjustlayer if @iterval>0 clr = m_Merge.GradientMerge(clr, iterbasin) endif color c = @f_adjustcolour if @adjusttype==0 c = RGB(@adjred, @adjgreen, @adjblue) endif c = compose(clr, m_Adjust.Merge(clr, c), @f_opacity) return RGBA(red(c), green(c), blue(c), alpha(clr)) endif if @iterval>0 return m_Merge.GradientMerge(clr, iterbasin) endif return clr else clr = m_Imagec.GetColor(m_Transformc.Iterate(duse+flip(fuse))) if @v_mmfextendedcilia>=3 && @mapmethodc!="Image All" if @usegradientc if @mapmethodc=="Image Red" clr = usergradientc.GetColour(red(clr)) elseif @mapmethodc=="Image Green" clr = usergradientc.GetColour(green(clr)) elseif @mapmethodc=="Image Blue" clr = usergradientc.GetColour(blue(clr)) elseif @mapmethodc=="Image Alpha" clr = usergradientc.GetColour(alpha(clr)) elseif @mapmethodc=="Image Hue" clr = usergradientc.GetColour(hue(clr)/6.0) elseif @mapmethodc=="Image Saturation" clr = usergradientc.GetColour(sat(clr)) elseif @mapmethodc=="Image Luminance" clr = usergradientc.GetColour(lum(clr)) elseif @mapmethodc=="Image Brightness" clr = usergradientc.GetColour(0.299*red(clr) + 0.587*green(clr) \ + 0.114*blue(clr)) endif elseif @mapmethodc=="Image Red" clr = gradient(red(clr)) elseif @mapmethodc=="Image Green" clr = gradient(green(clr)) elseif @mapmethodc=="Image Blue" clr = gradient(blue(clr)) elseif @mapmethodc=="Image Alpha" clr = gradient(alpha(clr)) elseif @mapmethodc=="Image Hue" clr = gradient(hue(clr)/6.0) elseif @mapmethodc=="Image Saturation" clr = gradient(sat(clr)) elseif @mapmethodc=="Image Luminance" clr = gradient(lum(clr)) elseif @mapmethodc=="Image Brightness" clr = gradient(0.299*red(clr) + 0.587*green(clr) + 0.114*blue(clr)) endif endif if @adjustlayerc if @citerval>0 clr = m_Mergec.GradientMerge(clr, iterbasin) endif color c = @f_adjustcolourc if @adjusttypec==0 c = RGB(@adjredc, @adjgreenc, @adjbluec) endif c = compose(clr, m_Adjustc.Merge(clr, c), @f_opacityc) return RGBA(red(c), green(c), blue(c), alpha(clr)) endif if @citerval>0 return m_Mergec.GradientMerge(clr, iterbasin) endif return clr endif endif return gradient(v) endfunc private: ImageWrapper m_Image Transform m_Transform GradientLayer m_Merge ColorMerge m_Adjust MMF_UserGradient usergradient ImageWrapper m_Imagec Transform m_Transformc GradientLayer m_Mergec ColorMerge m_Adjustc MMF_UserGradient usergradientc float rval[#maxiter+1] float crval[#maxiter+1] complex z1 complex z2 complex z3 complex z4 complex z5 complex z6 color clr float iterbasin float duse float fuse float il float lp float ilp float cil float clp float cilp float iv float ivc float iw float iwc float co bool wasdivergent default: title = "MMF Extended Cilia" rating = recommended int param v_mmfextendedcilia caption = "Version (MMF Extended Cilia)" enum = "1.0" "1.1" "1.2" "1.3" default = 3 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number. Version 1.1 has a minor change for \ when the 'solid' flag gets set. Version 1.2 fixes an issue with \ the convergent 'Split' value." visible = @v_mmfextendedcilia<3 endparam heading caption = "Main control" endheading int param method caption = "Smoothing" default = 0 enum = "Standard Div." "Standard Conv." "Standard both" \ "Hinrich's Div." "Hinrich's Conv." "Hinrich's both" \ "St.Div. H.Conv." "H.Div St.Conv." hint = "Specifies the type of smoothing to use and whether to \ colour divergent or convergent areas or both. \ Standard uses standard iteration smoothing and hence \ requires appropriate bailout (and power and fudge) values. \ Hinrich's uses what I've previously called 'finalz' \ smoothing where the final value of z from the main formula \ passes a smoothing fraction as real(z) and maybe atan(#z) \ as imag(z)." endparam heading caption = "Divergent smoothing" endheading float param bailout caption = "Bailout" default = 128.0 hint = "This should match the bailout in the fractal formula. \ Larger values work best, especially when using 'Old iterations'. \ When NOT using standard divergent smoothing \ you should still ensure this is a suitable value (eg. >=10)." endparam bool param dauto caption = "Auto-power" default = true hint = "When enabled should produce smoothing for any divergent \ areas without you needing to set a divergent power value \ for the colouring." visible = @method==0 || @method==2 || @method==6 endparam complex param power caption = "Power/exponent/degree" default = (2,0) hint = "This should match the power/degree/exponent in the \ fractal formula. If the value to use isn't immediately \ obvious from the main formula itself then it's best to \ choose the 'Just iteration' mode and modify this value \ (and maybe the Scaling fudge) until you get completely \ smooth colouring, or just enable auto-power." visible = @method==0 || @method==2 || @method==6 endparam float param fudge caption = "Scaling fudge" default = 1.0 hint = "This is a scaling fudge value, it's used to scale \ the calculated iteration fraction when the value \ doesn't reach 1, it's unlikely to be required for \ divergent smoothing but I added it just in case. If \ 'Auto-power' or the best value you can find for \ the power parameter don't produce smooth results then \ modifying this value may help." visible = @method==0 || @method==2 || @method==6 endparam float param fudge1 caption = "Scaling fudge 1" default = 1.0 hint = "This is a scaling fudge value, it's used to scale \ the calculated iteration fraction when the value \ doesn't reach 1, it's unlikely to be required for \ divergent smoothing but I added it just in case." visible = @method==3 || @method==5 || @method==7 endparam heading caption = "Divergent colouring" visible = @method==0 || @method==2 || @method==3 || @method>4 endheading bool param mapimage caption = "Image Mapping" default = false hint = "When enabled you can map an image into the Cilia. Note that the \ 'Image Only' Cilia Mode is specifically designed for the use of \ images but you may get interesting results for images in any of \ the Cilia Modes." visible = @method==0 || @method==2 || @method==3 || @method>4 endparam ImageWrapper param f_image caption = "Image Object" default = MMF_ImageImport hint = "The image to use." visible = @mapimage && (@method==0 || @method==2 || @method==3 || @method>4) endparam Transform param f_transform caption = "Image Transform" default = NullTransform hint = "Use to position/flip/mirror/scale your image mapping." visible = @mapimage && (@method==0 || @method==2 || @method==3 || @method>4) endparam int param mapmethod caption = "Image Method" enum = "Image All" "Image Red" "Image Green" "Image Blue" "Image Alpha" \ "Image Hue" "Image Saturation" "Image Luminance" "Image Brightness" hint = "'Image All' maps the image brightness (Yiq) to UF's gradient \ if the colouring is being used as a gradient colouring or uses \ the image colours if the colouring is being used as a direct \ colouring. 'Image Red' maps the image red to a gradient, \ 'Image Green' the green, 'Image Blue' the blue, 'Image Hue' \ the hue, 'Image Saturation' the saturation and 'Image Luminance' \ the luminance. 'Image Brightness' works the same as 'Image All' \ if in gradient mode or maps the brightness to a gradient if in \ direct mode." visible = @mapimage && (@method==0 || @method==2 || @method==3 || @method>4) endparam int param spread caption = "Image Spread" default = 1 min = 1 hint = "The number of iteration bands over which to spread your image." visible = @mapimage && (@method==0 || @method==2 || @method==3 || @method>4) endparam bool param usegradient caption = "Use Custom Gradient ?" default = false hint = "Only relevant if in direct colouring mode. If disabled then the \ value from the image is translated to a colour using UF's in-built \ gradient (as is always the case in gradient colouring mode), \ enable if you wish to use a gradient specified as user \ parameters instead." visible = @mapimage && (@method==0 || @method==2 || @method==3 || @method>4) \ && @mapmethod!="Image All" && @v_mmfextendedcilia>=3 endparam MMF_UserGradient param usergradient caption = "Custom Gradient" default = MMF_Gradient hint = "Create a custom gradient." visible = @mapimage && (@method==0 || @method==2 || @method==3 || @method>4) \ && @mapmethod!="Image All" && @v_mmfextendedcilia>=3 && @usegradient endparam GradientLayer param f_merge caption = "Iteration Merge" default = MMF_GradientLayer hint = "Only used if the main colouring is being used in direct colouring \ mode and add iteration is in use. Use to merge the iteration value \ and the image. Note that the gradient you choose controls the \ colour of the iteration layer which is normally treated as the top \ layer." visible = @mapimage && (@v_mmfextendedcilia>=3 || @mapmethod=="Image All") \ && @iterval>0 && (@method==0 || @method==2 || @method==3 || @method>4) expanded = false endparam bool param adjustlayer caption = "Add Adjust layer" default = false hint = "Allows you to add an adjustment layer in a given colour to merge \ on top of the image/texture. Only works if the main colouring \ is in direct mode." visible = @mapimage && (@v_mmfextendedcilia>=3 || @mapmethod=="Image All") \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam int param adjusttype caption = "Colour or RGB" enum = "RGB values" "Colour Parameter" default = 1 hint = "This option is specifically added so that if you choose \ 'RGB values' you can 'explore' them and see changes to the image \ as you change the RGB. The option may become redundant in a \ future version of UF. Only works if the main colouring \ is in direct mode." visible = @mapimage && (@v_mmfextendedcilia>=3 || @mapmethod=="Image All") \ && @adjustlayer \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam float param adjred caption = "Red Value" default = 1.0 hint = "The red part of the adjust colour (0 to 1). Only works if the \ main colouring is in direct mode." visible = @mapimage && (@v_mmfextendedcilia>=3 || @mapmethod=="Image All") \ && @adjustlayer && @adjusttype==0 \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam float param adjgreen caption = "Green Value" default = 1.0 hint = "The green part of the adjust colour (0 to 1). Only works if the \ main colouring is in direct mode." visible = @mapimage && (@v_mmfextendedcilia>=3 || @mapmethod=="Image All") \ && @adjustlayer && @adjusttype==0 \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam float param adjblue caption = "Blue Value" default = 1.0 hint = "The blue part of the adjust colour (0 to 1). Only works if the \ main colouring is in direct mode." visible = @mapimage && (@v_mmfextendedcilia>=3 || @mapmethod=="Image All") \ && @adjustlayer && @adjusttype==0 \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam color param f_adjustcolour caption = "Adjust Layer Colour" default = RGB(1,1,1) hint = "Allows you to apply overall adjustments to your colouring. Only \ works if the main colouring is in direct mode." visible = @mapimage && (@v_mmfextendedcilia>=3 || @mapmethod=="Image All") \ && @adjustlayer && @adjusttype==1 \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam ColorMerge param f_adjust caption = "Adjustment Layer Merge" default = MMF_ExtendedColorMerge hint = "Only works if the main colouring is in direct mode." visible = @mapimage && (@v_mmfextendedcilia>=3 || @mapmethod=="Image All") \ && @adjustlayer \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam float param f_opacity caption = "Adjustment Opacity" default = 1.0 hint = "Use to modify the adjustment opacity, the normal range is from \ 0 to 1. Only works if the main colouring is in direct mode." visible = @mapimage && (@v_mmfextendedcilia>=3 || @mapmethod=="Image All") \ && @adjustlayer \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam int param ciliamode caption = "Cilia Mode" default = 0 enum = "Sawtooth" "Interpolated" "Sine waves" "Cells" "Bricks" \ "Diamonds" "Smoothed angles" "Just iteration" "Smooth saw" \ "Smooth interpolated" "Smooth sine" "Smooth cells" "Smooth bricks" \ "Smooth diamonds" "Image Only" hint = "This is the periodic function used to generate the \ cilia pieces. Each has a different 'flavor'. \ The 'Smooth' versions produce smoothed results for \ Sawtooth, Interpolated, Sine waves and Diamonds when \ the degree of divergence or convergence is not 2, eg. z^3+c \ Note that 'Just iteration' is exactly that, the \ other parameters become irrelevant." visible = @method==0 || @method==2 || @method==3 || @method>4 endparam float param split caption = "Split" default = 2.0 hint = "Allows you to choose how the colouring 'splits' from one iteration \ to the next i.e. the increase in density of the colouring from one \ iteration to the next. Should 'correctly' be equal to the rate of \ divergence of the fractal e.g. 2 for z^2+c. Note that when using \ 'Sawtooth' or 'Diamonds' then only fractals where the correct \ value is 2 will work as intended." visible = @ciliamode!=6 && @ciliamode!=7 \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam int param olditer caption = "Old Iterations" default = 4 enum = "1 older" "2 older" "3 older" "4 older" "No" hint = "Uses older iterations for decomposition angle; this \ has the effect of spreading out the pattern. Best \ used to compensate for extreme bailouts. Note that \ 'No' requires the angle passed as the imaginary \ part of final z when using Hinrich's smoothing." visible = @ciliamode!=7 \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam float param iterval caption = "+Iter amount" default = 0.0 min = 0.0 hint = "Adds some iteration count to the colour value, \ thus producing colour change over the iterations. \ The larger the value the faster the colour change \ per iteration." visible = @ciliamode!=7 \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam float param iterweight caption = "Iter %age (div)" default = 50.0 hint = "Allows you to control the mixing of the smooth iteration value \ and the normal formula colouring value. Zero will use no iteration \ value and 100 will use all iteration value. Unused if using Image \ Mapping and in direct colouring mode." visible = @ciliamode!=7 && @iterval>0 \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam int param logiter caption = "+Iter function" enum = "Ident" "Log()" "Log(Log())" hint = "Allows you to apply log or double log to the iteration component." visible = @ciliamode!=7 && @iterval>0 && @iterweight!=0 \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam float param skew caption = "Skew" default = 0.0 hint = "This skews the pattern. Unless you enable 'Fix Rotation' and 'Fix \ Skew' then only certain values will maintain the pattern e.g. \ multiples of 0.5 for z^2+c whereas when the 'fixes' are enabled \ the pattern will be maintained whatever value you use. When using \ Smoothed angles it changes the pattern rather than skewing it." visible = @ciliamode!=7 \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam float param rot caption = "Rotation" default = 0.0 hint = "This rotates the pattern, only values from -1 to +1 \ make sense for rotation except when using 'Fix Rotation' in which \ case the entire pattern rotates together provided the 'Split' \ value is correct. When using Smoothed angles it \ changes the pattern rather than rotating it and any \ reasonable values make sense." visible = @ciliamode!=7 \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam bool param fixrot caption = "Fix Rotation" default = false hint = "When enabled the rotation is 'fixed'." visible = @ciliamode!=6 && @ciliamode!=7 \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam float param rpwr caption = "Rotation adjust" default = 5.0 min = 0.0 max = 20.0 hint = "Use to scale the effect of the 'Rotation' value, the larger the \ value you use the smaller the effect of changes to 'Rotation'. \ Typically increase the value in areas of higher iteration counts. \ Only needed when using a 'Split' greater than 1." visible = @fixrot && @ciliamode!=6 && @ciliamode!=7 \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam bool param fixskew caption = "Fix Skew" default = false hint = "When enabled the skew is 'fixed' for any skew values." visible = @fixrot && @ciliamode!=6 && @ciliamode!=7 \ && (@method==0 || @method==2 || @method==3 || @method>4) endparam heading caption = "Convergent smoothing" endheading float param smallbail caption = "Bailout" default = 1e-5 hint = "This should match the small bailout in your fractal formula. \ When NOT using standard convergent smoothing \ you should still ensure this is a suitable value (eg. <=1e-5)." endparam bool param cauto caption = "Auto-power" default = true hint = "When enabled should produce smoothing for any convergent \ areas without you needing to set a convergent power value \ for the colouring." visible = @method==1 || @method==2 || @method==7 endparam complex param cpower caption = "Power/exponent/degree" default = (2,0) hint = "This should match the power (exponent/degree) for the \ convergent areas of your main fractal formula. If the \ value to use isn't immediately obvious from the main \ formula itself then it's best to choose the 'Just \ iteration' mode and modify this value (and maybe the \ Scaling fudge) until you get completely smooth colouring, \ or just try auto-power." visible = @method==1 || @method==2 || @method==7 endparam float param fudgec caption = "Scaling Fudge" default = 1.0 hint = "This is a scaling fudge value, it's used to scale \ the calculated iteration fraction when the value \ doesn't reach 1. If 'Auto-power' or the best value you can \ find for the 'Convergent Power' parameter don't \ produce smooth results then modifying this value \ should help." visible = @method==1 || @method==2 || @method==7 endparam float param fudge1c caption = "Scaling Fudge 1" default = 1.0 hint = "This is a scaling fudge value, it's used to scale \ the calculated iteration fraction when the value \ doesn't reach 1." visible = @method==4 || @method==5 || @method==6 endparam bool param cfixed caption = "Absolute convergence" default = false hint = "For when using a main formula that tests for convergence by \ using (only) |#z-value| rather than |#z-zold|, a typical example \ would be a Magnet formula where |#z-1.0| is often used. When \ enabled set the value of 'Convergence root' appropriately." visible = @method==1 || @method==2 || @method==7 endparam complex param cfixedval caption = "Convergence root" default = (1,0) hint = "Use (1.0,0) for some Magnet formulas." visible = (@method==1 || @method==2 || @method==7) && @cfixed endparam heading caption = "Convergent colouring" visible = @method==1 || @method==2 || @method>3 endheading bool param mapimagec caption = "Image Mapping" default = false hint = "When enabled you can map an image into the Cilia. Note that the \ 'Image Only' Cilia Mode is specifically designed for the use of \ images but you may get interesting results for images in any of \ the Cilia Modes." visible = @method==1 || @method==2 || @method>3 endparam ImageWrapper param f_imagec caption = "Image Object" default = MMF_ImageImport hint = "The image to use." visible = @mapimagec && (@method==1 || @method==2 || @method>3) endparam Transform param f_transformc caption = "Image Transform" default = NullTransform hint = "Use to position/flip/mirror/scale your image mapping." visible = @mapimagec && (@method==1 || @method==2 || @method>3) endparam int param mapmethodc caption = "Image Method" enum = "Image All" "Image Red" "Image Green" "Image Blue" "Image Alpha" \ "Image Hue" "Image Saturation" "Image Luminance" "Image Brightness" hint = "'Image All' maps the image brightness (Yiq) to UF's gradient \ if the colouring is being used as a gradient colouring or uses \ the image colours if the colouring is being used as a direct \ colouring. 'Image Red' maps the image red to a gradient, \ 'Image Green' the green, 'Image Blue' the blue, 'Image Hue' \ the hue, 'Image Saturation' the saturation and 'Image Luminance' \ the luminance. 'Image Brightness' works the same as 'Image All' \ if in gradient mode or maps the brightness to a gradient if in \ direct mode." visible = @mapimagec && (@method==1 || @method==2 || @method>3) endparam int param spreadc caption = "Image Spread" default = 1 min = 1 hint = "The number of iteration bands over which to spread your image." visible = @mapimagec && (@method==1 || @method==2 || @method>3) endparam bool param usegradientc caption = "Use Custom Gradient ?" default = false hint = "Only relevant if in direct colouring mode. If disabled then the \ value from the image is translated to a colour using UF's in-built \ gradient (as is always the case in gradient colouring mode), \ enable if you wish to use a gradient specified as user \ parameters instead." visible = @mapimagec && (@method==1 || @method==2 || @method>3) \ && @mapmethodc!="Image All" && @v_mmfextendedcilia>=3 endparam MMF_UserGradient param usergradientc caption = "Custom Gradient" default = MMF_Gradient hint = "Create a custom gradient." visible = @mapimagec && (@method==1 || @method==2 || @method>3) \ && @mapmethodc!="Image All" && @v_mmfextendedcilia>=3 && @usegradientc endparam GradientLayer param f_mergec caption = "Iteration/Zbasin Merge" default = MMF_GradientLayer hint = "Only used if the main colouring is being used in direct colouring \ mode and add iteration or z basins is in use. Use to merge the \ iteration/z basin value with the image. Note that the gradient you \ choose controls the colour of the iteration/z basin layer which \ is normally treated as the top layer." visible = @mapimagec && (@v_mmfextendedcilia>=3 || @mapmethodc=="Image All") \ && (@citerval>0 || @zbasin>0) \ && (@method==1 || @method==2 || @method>3) expanded = false endparam bool param adjustlayerc caption = "Add Adjust layer" default = false hint = "Allows you to add an adjustment layer in a given colour to merge \ on top of the image/texture. Only works if the main colouring \ is in direct mode." visible = @mapimagec && (@v_mmfextendedcilia>=3 || @mapmethodc=="Image All") \ && (@method==1 || @method==2 || @method>3) endparam int param adjusttypec caption = "Colour or RGB" enum = "RGB values" "Colour Parameter" default = 1 hint = "This option is specifically added so that if you choose \ 'RGB values' you can 'explore' them and see changes to the image \ as you change the RGB. The option may become redundant in a \ future version of UF. Only works if the main colouring \ is in direct mode." visible = @mapimagec && (@v_mmfextendedcilia>=3 || @mapmethodc=="Image All") \ && @adjustlayerc \ && (@method==1 || @method==2 || @method>3) endparam float param adjredc caption = "Red Value" default = 1.0 hint = "The red part of the adjust colour (0 to 1). Only works if the \ main colouring is in direct mode." visible = @mapimagec && (@v_mmfextendedcilia>=3 || @mapmethodc=="Image All") \ && @adjustlayerc \ && @adjusttypec==0 && (@method==1 || @method==2 || @method>3) endparam float param adjgreenc caption = "Green Value" default = 1.0 hint = "The green part of the adjust colour (0 to 1). Only works if the \ main colouring is in direct mode." visible = @mapimagec && (@v_mmfextendedcilia>=3 || @mapmethodc=="Image All") \ && @adjustlayerc \ && @adjusttypec==0 && (@method==1 || @method==2 || @method>3) endparam float param adjbluec caption = "Blue Value" default = 1.0 hint = "The blue part of the adjust colour (0 to 1). Only works if the \ main colouring is in direct mode." visible = @mapimagec && (@v_mmfextendedcilia>=3 || @mapmethodc=="Image All") \ && @adjustlayerc \ && @adjusttypec==0 && (@method==1 || @method==2 || @method>3) endparam color param f_adjustcolourc caption = "Adjust Layer Colour" default = RGB(1,1,1) hint = "Allows you to apply overall adjustments to your colouring. Only \ works if the ain colouring is in direct mode." visible = @mapimagec && (@v_mmfextendedcilia>=3 || @mapmethodc=="Image All") \ && @adjustlayerc \ && @adjusttypec==1 && (@method==1 || @method==2 || @method>3) endparam ColorMerge param f_adjustc caption = "Adjustment Layer Merge" default = MMF_ExtendedColorMerge hint = "Only works if the main colouring is in direct mode." visible = @mapimagec && (@v_mmfextendedcilia>=3 || @mapmethodc=="Image All") \ && @adjustlayerc \ && (@method==1 || @method==2 || @method>3) endparam float param f_opacityc caption = "Adjustment Opacity" default = 1.0 hint = "Use to modify the adjustment opacity, the normal range is from \ 0 to 1. Only works if the main colouring is in direct mode." visible = @mapimagec && (@v_mmfextendedcilia>=3 || @mapmethodc=="Image All") \ && @adjustlayerc \ && (@method==1 || @method==2 || @method>3) endparam int param cciliamode caption = "Cilia Mode" default = 0 enum = "Sawtooth" "Interpolated" "Sine waves" "Cells" "Bricks" \ "Diamonds" "Smoothed angles" "Just iteration" "Smooth saw" \ "Smooth interpolated" "Smooth sine" "Smooth cells" "Smooth bricks" \ "Smooth diamonds" "Image Only" hint = "This is the periodic function used to generate the \ cilia pieces. Each has a different 'flavor'. \ The 'Smooth' versions produce smoothed results for \ Sawtooth, Interpolated, Sine waves and diamonds when \ the degree of divergence or convergence is not 2, eg. Nova formulas. \ Note that 'Just iteration' is exactly that, the \ other parameters become irrelevant." visible = @method==1 || @method==2 || @method>3 endparam float param csplit caption = "Split" default = 2.0 hint = "Allows you to choose how the colouring 'splits' from one iteration \ to the next i.e. the increase in density of the colouring from one \ iteration to the next. Should 'correctly' be 2 for the Newton or \ Magnet fractals. Note that when using 'Sawtooth' or 'Diamonds' \ then only fractals where the correct value is 2 will work as \ intended." visible = @cciliamode!=6 && @cciliamode!=7 \ && (@method==1 || @method==2 || @method>3) endparam bool param fixconv caption = "Convergent 'fix'" default = true hint = "Fixes the convergent areas of some fractals (eg. Newton) \ so areas in different z basins will have consistent colouring. \ Turn this off to get more variety in your fractal \ but then plain Sawtooth, Sine and Interpolated will \ have iteration bands in some areas - you could use the \ Smooth versions instead. You may find 'Smoothed angles' better \ with this switched off." visible = @cciliamode!=7 && (@method==1 || @method==2 || @method>3) endparam int param colditer caption = "Old Iterations" default = 0 enum = "1 older" "2 older" "3 older" "4 older" "No" hint = "Uses older iterations for decomposition angle; this \ has the effect of spreading out the pattern. Best \ used to compensate for extreme bailouts. Note that \ 'No' requires the angle passed as the imaginary \ part of final z when using Hinrich's smoothing." visible = @cciliamode!=7 && (@method==1 || @method==2 || @method>3) endparam float param citerval caption = "+Iter amount" default = 0.0 min = 0.0 hint = "Adds some iteration count to the colour value, \ thus producing colour change over the iterations. \ The larger the value the faster the colour change \ per iteration." visible = @cciliamode!=7 && (@method==1 || @method==2 || @method>3) endparam float param iterweightc caption = "Iter %age (conv)" default = 50.0 hint = "Allows you to control the mixing of the smooth iteration value \ and the normal formula colouring value. Zero will use no iteration \ value and 100 will use all iteration value." visible = @cciliamode!=7 && @citerval>0 \ && (@method==1 || @method==2 || @method>3) endparam int param logiterc caption = "+Iter function" enum = "Ident" "Log()" "Log(Log())" hint = "Allows you to apply log or double log to the iteration component." visible = @cciliamode!=7 && @citerval>0 && @iterweightc!=0 \ && (@method==1 || @method==2 || @method>3) endparam float param cskew caption = "Skew" default = 0.0 hint = "This skews the pattern. Unless you enable 'Fix Rotation' and 'Fix \ Skew' then only certain values will maintain the pattern e.g. \ multiples of 0.5 for Newton whereas when the 'fixes' are enabled \ the pattern will be maintained whatever value you use. When using \ Smoothed angles it changes the pattern rather than skewing it." visible = @cciliamode!=7 && (@method==1 || @method==2 || @method>3) endparam float param crot caption = "Rotation" default = 0.0 hint = "This rotates the pattern, only values from -1 to +1 \ make sense for rotation except when using 'Fix Rotation' in which \ case the entire pattern rotates together provided the 'Split' \ value is correct. When using Smoothed angles it \ changes the pattern rather than rotating it and any \ reasonable values make sense." visible = @cciliamode!=7 && (@method==1 || @method==2 || @method>3) endparam bool param cfixrot caption = "Fix Rotation" default = false hint = "When enabled the rotation is 'fixed'." visible = @cciliamode!=6 && @cciliamode!=7 \ && (@method==1 || @method==2 || @method>3) endparam float param crpwr caption = "Rotation adjust" default = 5.0 min = 0.0 max = 20.0 hint = "Use to scale the effect of the 'Rotation' value, the larger the \ value you use the smaller the effect of changes to 'Rotation'. \ Typically increase the value in areas of higher iteration counts. \ Only needed when using a 'Split' greater than 1." visible = @cfixrot && @cciliamode!=6 && @cciliamode!=7 \ && (@method==1 || @method==2 || @method>3) endparam bool param cfixskew caption = "Fix Skew" default = false hint = "When enabled the skew is 'fixed' for any skew value." visible = @cfixrot && @cciliamode!=6 && @cciliamode!=7 \ && (@method==1 || @method==2 || @method>3) endparam float param convoffset caption = "Colour offset" default = 0.0 hint = "Adds an offset to the final colour value in convergent areas, for \ when the main fractal has both convergent and divergent areas. \ The offset value corresponds to the number of gradient points when \ Color Density is 1 and Transfer Function is linear." visible = @method==1 || @method==2 || @method>3 endparam int param zbasin caption = "Add z basins" enum = "Off" "abs(atan2())" "abs(real())" "abs(imag())" "abs(real+imag)" \ "abs(2*real+imag)" "abs(2*imag+real)" "abs(real/(abs(imag)+1))" \ "abs(imag/(abs(real)+1))" "Roots 1" "Roots 2" default = 0 hint = "Allows you to add a value to the final colouring based on the \ penultimate value of z." visible = (@method==1 || @method==2 || @method>3) endparam float param zscale caption = "Basin scale" default = 0.1 hint = "Scales the effect of the z basin value." visible = (@method==1 || @method==2 || @method>3) && @zbasin>0 endparam float param ip caption = "Iteration Power" default = 1.0 visible = @ciliamode==7 endparam } class MMF_SwitchFormula(common.ulb:Formula) { ; Base class for formulas that allow switching to be used with ; mmf5.ufm-Generic Switch Formula
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SwitchFormula(Generic pparent) Formula.Formula(pparent) if (fType = @p_mandy) fValue = fConstant = @p_start else fValue = fConstant = @p_seed endif endfunc ; @param f flag for Mandelbrot or Julia mode, is true for Mandelbrots ; @param v the value to be used as the start value or constant func SetParams(bool f,complex v) if !@p_manual fType = f fValue = fConstant = v endif endfunc protected: complex fConstant complex fValue bool fType default: int param v_mmfswitchformula caption = "Version (MMF_SwitchFormula)" default = 100 hint = "This version parameter is used to detect when a change has \ been made to the formula that is incompatible with the \ previous version. When that happens, this field will reflect \ the old version number to alert you to the fact that an \ alternate rendering is being used." visible = @v_mmfswitchformula < 100 endparam heading caption = "Information" text = "This formula object is intended for use with the 'Generic \ Switch Formula' in mmf5.ufm and in formula objects that \ allow switching, however it will still function without \ switching in non-switching formulas and formula objects." endheading heading enabled = false endheading bool param p_manual caption = "Manual Over-ride" default = false hint = "When enabled you will have manual control of the \ Mandelbrot/Julia switching and the associated parameters \ i.e. you will be able to over-ride the settings from the \ parent object. Note that this will effectively disable \ UF's built-in switching but allow full use of this formula \ when not used with a compatible switching parent." endparam bool param p_mandy caption = "Mandelbrot ?" default = true hint = "Disable for Julia mode." visible = @p_manual endparam complex param p_start caption = "Mandelbrot Start Value" default = (0,0) visible = @p_manual && @p_mandy endparam complex param p_seed caption = "Julia Constant" default = (-1.25,0) visible = @p_manual && !@p_mandy endparam } class MMF_SwitchDivergentFormula(common.ulb:DivergentFormula) { ; Base class for Divergent formulas that allow switching to be used with ; mmf5.ufm-Generic Switch Formula
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SwitchDivergentFormula(Generic pparent) DivergentFormula.DivergentFormula(pparent) if (fType = @p_mandy) fValue = fConstant = @p_start else fValue = fConstant = @p_seed endif endfunc ; @param pz the initial location ; @return initial z for iteration complex func Init(complex pz) DivergentFormula.Init(pz) if fType fConstant = pz if @p_addpixel return fValue + fConstant else return fValue endif else return pz endif endfunc ; @param f flag for Mandelbrot or Julia mode, is true for Mandelbrots ; @param v the value to be used as the start value or constant func SetParams(bool f,complex v) if !@p_manual fType = f fValue = fConstant = v endif endfunc protected: complex fConstant complex fValue bool fType default: int param v_switchdivergentformula caption = "Version (MMF_DivergentFormula)" default = 100 hint = "This version parameter is used to detect when a change has \ been made to the formula that is incompatible with the \ previous version. When that happens, this field will reflect \ the old version number to alert you to the fact that an \ alternate rendering is being used." visible = @v_switchdivergentformula < 100 endparam heading caption = "Information" text = "This formula object is intended for use with the 'Generic \ Switch Formula' in mmf5.ufm and in formula objects that \ allow switching, however it will still function without \ switching in non-switching formulas and formula objects." endheading heading enabled = false endheading bool param p_manual caption = "Manual Over-ride" default = false hint = "When enabled you will have manual control of the \ Mandelbrot/Julia switching and the associated parameters \ i.e. you will be able to over-ride the settings from the \ parent object. Note that this will effectively disable \ UF's built-in switching but allow full use of this formula \ when not used with a compatible switching parent." endparam bool param p_mandy caption = "Mandelbrot ?" default = true hint = "Disable for Julia mode." visible = @p_manual endparam complex param p_start caption = "Mandelbrot Start Value" default = (0,0) visible = @p_manual && @p_mandy endparam complex param p_seed caption = "Julia Constant" default = (-1.25,0) visible = @p_manual && !@p_mandy endparam bool param p_addpixel caption = "Offset z start" default = false hint = "When enabled the z start value (in Mandelbrot mode) is offset \ by the constant for the current position - normally '#pixel'." visible = !@p_manual || @p_mandy endparam float param p_bailout caption = "Bailout" default = 128.0 hint = "Defines how soon an orbit bails out, i.e. doesn't belong \ to the fractal set anymore. Note: larger values result in \ more iterations being calculated." endparam } class MMF_SwitchConvergentFormula(common.ulb:ConvergentFormula) { ; Base class for Convergent formulas that allow switching to be used with
; mmf5.ufm-Generic Switch Formula
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SwitchConvergentFormula(Generic pparent) ConvergentFormula.ConvergentFormula(pparent) if (fType = @p_mandy) fValue = fConstant = @p_start else fValue = fConstant = @p_seed endif endfunc ; Note that here zold is initialised to initial z

; What it's initialised to is normally irrelevant unless the derived ; formula uses zold in its main calculations in which case the user ; should be given the choice of initialising zold to either the location, ; the initial z value or a fixed constant.
; @param pz the initial location ; @return initial z for iteration complex func Init(complex pz) ConvergentFormula.Init(pz) if fType fConstant = pz if @p_addpixel m_ZOld = fValue + fConstant return m_ZOld else m_ZOld = fValue return fValue endif else m_ZOld = pz return pz endif endfunc ; @param f flag for Mandelbrot or Julia mode, is true for Mandelbrots ; @param v the value to be used as the start value or constant func SetParams(bool f,complex v) if !@p_manual fType = f fValue = fConstant = v endif endfunc protected: complex fConstant complex fValue bool fType default: int param v_mmfswitchconvergentformula caption = "Version (MMF_ConvergentFormula)" default = 100 hint = "This version parameter is used to detect when a change has \ been made to the formula that is incompatible with the \ previous version. When that happens, this field will reflect \ the old version number to alert you to the fact that an \ alternate rendering is being used." visible = @v_mmfswitchconvergentformula < 100 endparam heading caption = "Information" text = "This formula object is intended for use with the 'Generic \ Switch Formula' in mmf5.ufm and in formula objects that \ allow switching, however it will still function without \ switching in non-switching formulas and formula objects." endheading heading enabled = false endheading bool param p_manual caption = "Manual Over-ride" default = false hint = "When enabled you will have manual control of the \ Mandelbrot/Julia switching and the associated parameters \ i.e. you will be able to over-ride the settings from the \ parent object. Note that this will effectively disable \ UF's built-in switching but allow full use of this formula \ when not used with a compatible switching parent." endparam bool param p_mandy caption = "Mandelbrot ?" default = true hint = "Disable for Julia mode." visible = @p_manual endparam complex param p_start caption = "Mandelbrot Start Value" default = (0,0) visible = @p_manual && @p_mandy endparam complex param p_seed caption = "Julia Constant" default = (-1.25,0) visible = @p_manual && !@p_mandy endparam bool param p_addpixel caption = "Offset z start" default = false hint = "When enabled the z start value (in Mandelbrot mode) is offset \ by the constant for the current position - normally '#pixel'." visible = !@p_manual || @p_mandy endparam float param p_bailout caption = "Bailout" default = 1.0e-5 hint = "Defines how soon an orbit bails out, i.e. doesn't belong \ to the fractal set anymore. Note: smaller values result in \ more iterations being calculated." endparam } class MMF_SwitchConvergentDivergentFormula(common.ulb:ConvergentDivergentFormula) { ; Switch Convergent/Divergent Formula base class.

; ; This class extends Formula to provide automatic, simple ; bailout tests. Formulas for which the outside points ; converge on points OR grow without bound should derive ; from this class so as to avoid having to write the ; bailout tests and the GetUpperBailout() and ; GetLowerBailout() function.
public: ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SwitchConvergentDivergentFormula(Generic pparent) ConvergentDivergentFormula.ConvergentDivergentFormula(pparent) if (fType = @p_mandy) fValue = fConstant = @p_start else fValue = fConstant = @p_seed endif endfunc ; Note that here zold is initialised to initial z

; What it's initialised to is normally irrelevant unless the derived ; formula uses zold in its main calculations in which case the user ; should be given the choice of initialising zold to either the location, ; the initial z value or a fixed constant.
; @param pz the location (normally #pixel) ; @return initial z for iteration complex func Init(complex pz) ConvergentDivergentFormula.Init(pz) if fType fConstant = pz if @p_addpixel m_ZOld = fValue + fConstant return m_ZOld else m_ZOld = fValue return fValue endif else m_ZOld = pz return pz endif endfunc ; @param f flag for Mandelbrot or Julia mode, is true for Mandelbrots ; @param v the value to be used as the start value or constant func SetParams(bool f,complex v) if !@p_manual fType = f fValue = fConstant = v endif endfunc protected: complex fConstant complex fValue bool fType default: int param v_mmfswitchconvergentdivergentformula caption = "Version (MMF_SwitchConvergentDivergentFormula)" default = 100 hint = "This version parameter is used to detect when a change has \ been made to the formula that is incompatible with the \ previous version. When that happens, this field will reflect \ the old version number to alert you to the fact that an \ alternate rendering is being used." visible = @v_mmfswitchconvergentdivergentformula < 100 endparam heading caption = "Information" text = "This formula object is intended for use with the 'Generic \ Switch Formula' in mmf5.ufm and in formula objects that \ allow switching, however it will still function without \ switching in non-switching formulas and formula objects." endheading heading enabled = false endheading bool param p_manual caption = "Manual Over-ride" default = false hint = "When enabled you will have manual control of the \ Mandelbrot/Julia switching and the associated parameters \ i.e. you will be able to over-ride the settings from the \ parent object. Note that this will effectively disable \ UF's built-in switching but allow full use of this formula \ when not used with a compatible switching parent." endparam bool param p_mandy caption = "Mandelbrot ?" default = true hint = "Disable for Julia mode." visible = @p_manual endparam complex param p_start caption = "Mandelbrot Start Value" default = (0,0) visible = @p_manual && @p_mandy endparam complex param p_seed caption = "Julia Constant" default = (-1.25,0) visible = @p_manual && !@p_mandy endparam bool param p_addpixel caption = "Offset z start" default = false hint = "When enabled the z start value (in Mandelbrot mode) is offset \ by the constant for the current position - normally '#pixel'." visible = !@p_manual || @p_mandy endparam } class MMF_SwitchStandard(MMF_SwitchDivergentFormula) { ; ; Generic Switchable Mandelbrot set.
; public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SwitchStandard(Generic pparent) MMF_SwitchDivergentFormula.MMF_SwitchDivergentFormula(pparent) endfunc complex func Iterate(complex pz) if @p_advanced && @p_switch=="Power" return pz^fConstant + @p_seed1 else return pz^@p_power + fConstant endif endfunc default: title = "Switch Standard" rating = recommended bool param p_advanced caption = "Enable Advanced Settings" default = false hint = "When enabled you can choose which variable is switchable." endparam int param p_switch caption = "Switch Value" enum = "Normal" "Power" default = 1 hint = "In 'Normal' mode the constant c in z^p+c is the switchable \ variable, in 'Power' mode the power p in z^p+c is used \ instead." visible = @p_advanced endparam complex param p_seed1 caption = "Seed" default = (0.25,0) hint = "The constant c in z^p+c." visible = @p_advanced && @p_switch>0 endparam complex param p_power caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the standard z^p+c \ formula. Increasing the real part to 3, 4, and so on, \ will add discs to the Mandelbrot figure. Non-integer \ real values and non-zero imaginary values will create \ distorted sets. Use (2, 0) for the standard Mandelbrot/Julia \ sets." visible = !@p_advanced || @p_switch!=1 endparam } class MMF_SwitchCardioid(MMF_SwitchDivergentFormula) { ; ; This formula is based on the generic form for a cardioid. ; public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SwitchCardioid(Generic pparent) MMF_SwitchDivergentFormula.MMF_SwitchDivergentFormula(pparent) endfunc complex func Iterate(complex pz) if @p_advanced && @p_switch=="Offset" return (sqr(pz+fConstant)+@p_diameter*real(pz+fConstant))^@p_power \ -(sqr(@p_diameter2)*sqr(pz+@p_offset2))^@p_power2+@p_seed1 elseif @p_advanced && @p_switch=="Offset 2" return (sqr(pz+@p_offset)+@p_diameter*real(pz+@p_offset))^@p_power \ -(sqr(@p_diameter2)*sqr(pz+fConstant))^@p_power2+@p_seed1 elseif @p_advanced && @p_switch=="Diameter" return (sqr(pz+@p_offset)+fConstant*real(pz+@p_offset))^@p_power \ -(sqr(@p_diameter2)*sqr(pz+@p_offset2))^@p_power2+@p_seed1 elseif @p_advanced && @p_switch=="Diameter 2" return (sqr(pz+@p_offset)+@p_diameter*real(pz+@p_offset))^@p_power \ -(sqr(fConstant)*sqr(pz+@p_offset2))^@p_power2+@p_seed1 elseif @p_advanced && @p_switch=="Power" return (sqr(pz+@p_offset)+@p_diameter*real(pz+@p_offset))^fConstant \ -(sqr(@p_diameter2)*sqr(pz+@p_offset2))^@p_power2+@p_seed1 elseif @p_advanced && @p_switch=="Power 2" return (sqr(pz+@p_offset)+@p_diameter*real(pz+@p_offset))^@p_power \ -(sqr(@p_diameter2)*sqr(pz+@p_offset2))^fConstant+@p_seed1 else return (sqr(pz+@p_offset)+@p_diameter*real(pz+@p_offset))^@p_power \ -(sqr(@p_diameter2)*sqr(pz+@p_offset2))^@p_power2+fConstant endif endfunc default: title = "Switch Cardioid" rating = recommended bool param p_advanced caption = "Enable Advanced Settings" default = false hint = "When enabled you can choose which variable is switchable." endparam int param p_switch caption = "Switch Value" enum = "Normal" "Power" "Power 2" "Diameter" "Diameter 2" "Offset" \ "Offset 2" default = 0 hint = "In 'Normal' mode the constant c in \ (sqr(z+offset)+diameter*real(z+offset))^power \ -(sqr(diameter2)*sqr(pz+offset2))^power2+c is the switchable \ variable (Seed), in the other modes the chosen parameter is used \ instead." visible = @p_advanced endparam complex param p_seed1 caption = "Seed" default = (0.25,0) hint = "The constant c" visible = @p_advanced && @p_switch>0 endparam complex param p_power caption = "Power" default = (2,0) hint = "This parameter sets the exponent for the first part pf the cardioid \ formula. Increasing the real part to 3, 4, and so on, \ will add discs to the Mandelbrot figure. Non-integer \ real values and non-zero imaginary values will create \ distorted sets. Use (2, 0) for the standard Cardioid" visible = !@p_advanced || @p_switch!=1 endparam complex param p_power2 caption = "Power 2" default = (1,0) hint = "This parameter sets the exponent for the secons part of the \ cardioid formula. Use (1, 0) for the standard Cardioid." visible = !@p_advanced || @p_switch!=2 endparam complex param p_diameter caption = "Diameter" default = (0.5,0) hint = "The diameter for the first part of the cardioid formula" visible = !@p_advanced || @p_switch!=3 endparam complex param p_diameter2 caption = "Diameter 2" default = (0.5,0) hint = "The diameter for the second part of the cardioid formula" visible = !@p_advanced || @p_switch!=4 endparam complex param p_offset caption = "Offset" default = (0,0) hint = "The offset for the first part of the cardioid formula" visible = !@p_advanced || @p_switch!=5 endparam complex param p_offset2 caption = "Offset 2" default = (0,0) hint = "The offset for the second part of the cardioid formula" visible = !@p_advanced || @p_switch!=6 endparam } class MMF_SwitchPhoenix(MMF_SwitchDivergentFormula) { ; ; Switchable object version of the Phoenix.
; The general equation is of the form
; ; z(n+1) = z(n)^a + c*z(n)^b + p*z(n-1)
; ; Originators: Damien M. Jones, Shigehiro Ushiki
; public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SwitchPhoenix(Generic pparent) MMF_SwitchDivergentFormula.MMF_SwitchDivergentFormula(pparent) endfunc complex func Init(complex pz) fOld = (0, 0) return MMF_SwitchDivergentFormula.Init(pz) endfunc complex func Iterate(complex pz) complex newz if !@p_advanced || @p_switch=="Normal" newz = pz^@p_power + pz^@power2 * fConstant + @induct * fOld elseif @p_switch=="Exponent 1" newz = pz^fConstant + pz^@power2 * @p_seed1 + @induct * fOld elseif @p_switch=="Exponent 2" newz = pz^@p_power + pz^fConstant * @p_seed1 + @induct * fOld else;if @p_switch=="Distortion" newz = pz^@p_power + pz^@power2 * @p_seed1 + fConstant * fOld endif fOld = pz return newz endfunc private: complex fOld default: title = "Switch Phoenix" rating = recommended bool param p_addpixel caption = "Offset z start" default = false hint = "When enabled the z start value (in Mandelbrot mode) is offset \ by the constant for the current position - normally '#pixel'. \ When your z start value is (0,0) then enable this for the \ original functionality of the Phoenix formula i.e. so that \ non-zero values of 'Exponent 2' will produce a Mandelbrot \ although it should be noted that leaving this disabled and \ using a Mandelbrot Start value of say 1e-5 may give a \ better Mandelbrot guide to the available Julia Sets." visible = !@p_manual || @p_mandy endparam bool param p_advanced caption = "Enable Advanced Settings" default = false hint = "When enabled you can choose which variable is switchable." endparam int param p_switch caption = "Switch Value" enum = "Normal" "Exponent 1" "Exponent 2" "Distortion" default = 3 hint = "In 'Normal' mode the additive constant is the switchable \ variable, in the other modes the relevant values are made \ switchable instead." visible = @p_advanced endparam complex param p_seed1 caption = "Seed" default = (-1,0) hint = "The constant c in z(n)^a + c*z(n)^b + p*z(n-1)." visible = @p_advanced && @p_switch>0 endparam complex param p_power ; Overrides p_power from Formula caption = "Exponent 1" default = (2,0) hint = "Defines the primary exponent for the fractal. The classic \ Phoenix curve uses exponent (2, 0)." visible = !@p_advanced || @p_switch!=1 endparam complex param power2 caption = "Exponent 2" default = (0,0) hint = "Defines the secondary exponent for the fractal. The classic \ Phoenix curve uses exponent (0, 0)." visible = !@p_advanced || @p_switch!=2 endparam complex param induct caption = "Distortion" default = (0.5,0) hint = "Sets how 'strong' the previous iteration's effect should be \ on the fractal." visible = !@p_advanced || @p_switch!=3 endparam float param p_bailout ; Overrides p_bailout from DivergentFormula caption = "Bailout" default = 1.0e20 exponential = true hint = "This parameter defines how soon an orbit bails out while \ iterating. Larger values will give smoother outlines." endparam } class MMF_SwitchNova(MMF_SwitchConvergentDivergentFormula) { ; ; Object version of NovaMandel for switching
; ; Nova fractal (Mandelbrot form), a modified Newtonian-style fractal.
; Object switch version by David Makin
; ; Originators Damien M. Jones, Paul Derbyshire

; ; Note that for historical reasons this formula uses its own ; bailout values instead of those defined in the base class ; doing so should not be taken as a model for other formulas.
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SwitchNova(Generic pparent) MMF_SwitchConvergentDivergentFormula.MMF_SwitchConvergentDivergentFormula(pparent) endfunc ; Note that here if the formula is in Mandelbrot mode then one is added ; to the start value by default. ; @param f flag, true for Mandelbrot mode, false for Julia mode ; @param v either the start value or the constant func SetParams(bool f,complex v) if !@p_manual if (fType = f) fValue = fConstant = v + 1.0 else fValue = fConstant = v endif endif endfunc complex func Init(complex pz) complex zz = MMF_SwitchConvergentDivergentFormula.Init(pz) if @p_advanced && @p_switch=="Exponent" pm1 = fConstant - 1.0 endif return zz endfunc complex func Iterate(complex pz) MMF_SwitchConvergentDivergentFormula.Iterate(pz) if !@p_advanced || @p_switch=="Normal" if @p_power == (3, 0) ; special optimized routine for power 3 complex zsquared = sqr(pz) return pz - @relax * (zsquared*pz-1.0) / (3.0*zsquared) + fConstant else return pz - @relax * (pz^@p_power-1.0) \ / (@p_power * pz^(@p_power-1.0)) + fConstant endif elseif @p_switch=="Exponent" return pz - @relax * (pz^fConstant-1.0) \ / (fConstant * pz^pm1) + @p_seed1 else;if @p_switch=="Relaxation" return pz - fConstant * (pz^@p_power-1.0) \ / (@p_power * pz^(@p_power-1.0)) + @p_seed1 endif endfunc bool func IsBailedOut(complex pz) if ((@p_BailType=="Divergent" || @p_BailType=="Both") \ && |pz|>@p_bailout1) \ || ((@p_BailType=="Convergent" || @p_BailType=="Both") \ && |pz-m_ZOld|<@p_bailout) m_BailedOut = true endif return m_BailedOut endfunc float func GetUpperBailout() return @p_bailout1 endfunc float func GetLowerBailout() return @p_bailout endfunc private: complex pm1 default: title = "Switch Nova" rating = recommended float param p_lowerbailout visible = false endparam float param p_upperbailout visible = false endparam complex param p_start caption = "Mandelbrot Start Value" default = (1,0) visible = @p_manual && @p_mandy endparam complex param p_seed caption = "Julia Seed" default = (0,0) visible = @p_manual && !@p_mandy endparam heading caption = "Information" text = "It should be noted that when using the Mandelbrot Start \ Value from a parent switching formula 1 is added to the \ value since generally the parental default will be (0,0) \ and the standard start value for Nova is (1,0)." endheading heading enabled = false endheading bool param p_advanced caption = "Enable Advanced Settings" default = false hint = "When enabled you can choose which variable is switchable." endparam int param p_switch caption = "Switch Value" enum = "Normal" "Exponent" "Relaxation" default = 2 hint = "In 'Normal' mode the additive constant is the switchable \ variable, in the other modes the relevant values are made \ switchable instead." visible = @p_advanced endparam complex param p_seed1 caption = "Seed" default = (-0.4,0.425) hint = "The additive constant." visible = @p_advanced && @p_switch>0 endparam complex param p_power caption = "Exponent" default = (3,0) hint = "Overall exponent for the equation. The value (3,0) gives \ the classic Nova fractals." visible = !@p_advanced || @p_switch!=1 endparam complex param relax caption = "Relaxation" default = (1,0) hint = "This can be used to slow down the convergence of \ the formula." visible = !@p_advanced || @p_switch!=2 endparam int param p_BailType caption = "Bailout Type" enum = "Divergent" "Convergent" "Both" default = 1 endparam float param p_bailout caption = "Convergent Bailout" default = 0.00001 exponential = true hint = "Convergent bailout value; smaller values will cause more \ iterations to be done for each point." visible = @p_BailType>0 endparam float param p_bailout1 caption = "Divergent Bailout" default = 1e20 exponential = true hint = "Divergent bailout value; it's best to use large values to \ avoid erroneous detection of divergent bailout in convergent \ areas." visible = @p_BailType!=1 endparam } class MMF_SwitchMagnet1(MMF_SwitchConvergentDivergentFormula) { ; ; Object version of Magnet 1 for switching
; ; Object switch version by David Makin
; public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SwitchMagnet1(Generic pparent) MMF_SwitchConvergentDivergentFormula.MMF_SwitchConvergentDivergentFormula(pparent) endfunc complex func Iterate(complex pz) MMF_SwitchConvergentDivergentFormula.Iterate(pz) return sqr( (pz^2 + fConstant - 1) / (2*pz + fConstant - 2) ) endfunc bool func IsBailedOut(complex pz) if ((@p_BailType=="Divergent" || @p_BailType=="Both") \ && |pz|>@p_upperbailout) \ || ((@p_BailType=="Convergent" || @p_BailType=="Both") \ && ((!fType && |pz-m_ZOld|<@p_lowerbailout) \ || (fType && |pz-1.0|<@p_lowerbailout))) m_BailedOut = true endif return m_BailedOut endfunc float func GetUpperBailout() return @p_upperbailout endfunc float func GetLowerBailout() return @p_lowerbailout endfunc default: title = "Switch Magnet 1" rating = recommended complex param p_power visible = false endparam complex param p_start caption = "Mandelbrot Start Value" default = (0,0) visible = @p_manual && @p_mandy endparam complex param p_seed caption = "Julia Seed" default = (0,0) visible = @p_manual && !@p_mandy endparam int param p_BailType caption = "Bailout Type" enum = "Divergent" "Convergent" "Both" default = 2 endparam float param p_lowerbailout caption = "Convergent Bailout" default = 1e-14 exponential = true hint = "Convergent bailout value; smaller values will cause more \ iterations to be done for each point." visible = @p_BailType>0 endparam float param p_upperbailout caption = "Divergent Bailout" default = 1e20 exponential = true hint = "Divergent bailout value; it's best to use large values to \ avoid erroneous detection of divergent bailout in convergent \ areas." visible = @p_BailType!=1 endparam } class MMF_SwitchMagnet2(MMF_SwitchConvergentDivergentFormula) { ; ; Object version of Magnet 2 for switching
; ; Object switch version by David Makin
; public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SwitchMagnet2(Generic pparent) MMF_SwitchConvergentDivergentFormula.MMF_SwitchConvergentDivergentFormula(pparent) endfunc complex func Iterate(complex pz) MMF_SwitchConvergentDivergentFormula.Iterate(pz) return sqr((pz^3.0 + 3.0*(fConstant-1.0)*pz \ + (fConstant-1.0)*(fConstant-2.0)) \ /(3.0*sqr(pz) + 3.0*(fConstant-2.0)*pz \ + (fConstant-1.0)*(fConstant-2.0) + 1.0)) endfunc bool func IsBailedOut(complex pz) if ((@p_BailType=="Divergent" || @p_BailType=="Both") \ && |pz|>@p_upperbailout) \ || ((@p_BailType=="Convergent" || @p_BailType=="Both") \ && ((!fType && |pz-m_ZOld|<@p_lowerbailout) \ || (fType && |pz-1.0|<@p_lowerbailout))) m_BailedOut = true endif return m_BailedOut endfunc float func GetUpperBailout() return @p_upperbailout endfunc float func GetLowerBailout() return @p_lowerbailout endfunc default: title = "Switch Magnet 2" rating = recommended complex param p_power visible = false endparam complex param p_start caption = "Mandelbrot Start Value" default = (0,0) visible = @p_manual && @p_mandy endparam complex param p_seed caption = "Julia Seed" default = (0,0) visible = @p_manual && !@p_mandy endparam int param p_BailType caption = "Bailout Type" enum = "Divergent" "Convergent" "Both" default = 2 endparam float param p_lowerbailout caption = "Convergent Bailout" default = 1e-9 exponential = true hint = "Convergent bailout value; smaller values will cause more \ iterations to be done for each point." visible = @p_BailType>0 endparam float param p_upperbailout caption = "Divergent Bailout" default = 1e20 exponential = true hint = "Divergent bailout value; it's best to use large values to \ avoid erroneous detection of divergent bailout in convergent \ areas." visible = @p_BailType!=1 endparam } class MMF_SwitchFormulaWars2(MMF_SwitchConvergentDivergentFormula) { ; Object version of the MMF Formula Wars 2 formula
; Extended to allow the combination of up to 6 formulae

; Note that for historical reasons this formula uses its own ; zold and bailout values instead of those defined in the base class ; doing so should not be taken as a model for other formulas.
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SwitchFormulaWars2(Generic pparent) MMF_SwitchConvergentDivergentFormula.MMF_SwitchConvergentDivergentFormula(pparent) fFormula1=new @classFormula1(this) fFormula2=new @classFormula2(this) fFormula3=new @classFormula3(this) fFormula4=new @classFormula4(this) fFormula5=new @classFormula5(this) fFormula6=new @classFormula6(this) SetParams(fType,fConstant) endfunc complex func Init(complex pz) m_Iterations = 0 m_BailedOut = false fz[0] = fFormula1.Init(pz) fz[1] = fFormula2.Init(pz) if @p_NumFormulas=="3" || @p_NumFormulas=="4" || @p_NumFormulas=="5" \ || @p_NumFormulas=="6" fz[2] = fFormula3.Init(pz) if @p_NumFormulas=="4" || @p_NumFormulas=="5" || @p_NumFormulas=="6" fz[3] = fFormula4.Init(pz) if @p_NumFormulas=="5" || @p_NumFormulas=="6" fz[4] = fFormula5.Init(pz) if @p_NumFormulas=="6" fz[5] = fFormula6.Init(pz) endif endif endif endif if fType fConstant = pz return fValue else return pz endif endfunc func SetParams(bool f,complex v) if !@p_manual fType = f fValue = fConstant = v endif if @classFormula1==MMF_SwitchFormula MMF_SwitchFormula(fFormula1).SetParams(fType,fConstant) elseif @classFormula1==MMF_SwitchDivergentFormula MMF_SwitchDivergentFormula(fFormula1).SetParams(fType,fConstant) elseif @classFormula1==MMF_SwitchConvergentFormula MMF_SwitchConvergentFormula(fFormula1).SetParams(fType,fConstant) elseif @classFormula1==MMF_SwitchConvergentDivergentFormula MMF_SwitchConvergentDivergentFormula(fFormula1).SetParams(fType,fConstant) endif if @classFormula2==MMF_SwitchFormula MMF_SwitchFormula(fFormula2).SetParams(fType,fConstant) elseif @classFormula2==MMF_SwitchDivergentFormula MMF_SwitchDivergentFormula(fFormula2).SetParams(fType,fConstant) elseif @classFormula2==MMF_SwitchConvergentFormula MMF_SwitchConvergentFormula(fFormula2).SetParams(fType,fConstant) elseif @classFormula2==MMF_SwitchConvergentDivergentFormula MMF_SwitchConvergentDivergentFormula(fFormula2).SetParams(fType,fConstant) endif if @p_NumFormulas=="3" || @p_NumFormulas=="4" || @p_NumFormulas=="5" \ || @p_NumFormulas=="6" if @classFormula3==MMF_SwitchFormula MMF_SwitchFormula(fFormula3).SetParams(fType,fConstant) elseif @classFormula3==MMF_SwitchDivergentFormula MMF_SwitchDivergentFormula(fFormula3).SetParams(fType,fConstant) elseif @classFormula3==MMF_SwitchConvergentFormula MMF_SwitchConvergentFormula(fFormula3).SetParams(fType,fConstant) elseif @classFormula3==MMF_SwitchConvergentDivergentFormula MMF_SwitchConvergentDivergentFormula(fFormula3).SetParams(fType,fConstant) endif if @p_NumFormulas=="4" || @p_NumFormulas=="5" || @p_NumFormulas=="6" if @classFormula4==MMF_SwitchFormula MMF_SwitchFormula(fFormula4).SetParams(fType,fConstant) elseif @classFormula4==MMF_SwitchDivergentFormula MMF_SwitchDivergentFormula(fFormula4).SetParams(fType,fConstant) elseif @classFormula4==MMF_SwitchConvergentFormula MMF_SwitchConvergentFormula(fFormula4).SetParams(fType,fConstant) elseif @classFormula4==MMF_SwitchConvergentDivergentFormula MMF_SwitchConvergentDivergentFormula(fFormula4).SetParams(fType,fConstant) endif if @p_NumFormulas=="5" || @p_NumFormulas=="6" if @classFormula5==MMF_SwitchFormula MMF_SwitchFormula(fFormula5).SetParams(fType,fConstant) elseif @classFormula5==MMF_SwitchDivergentFormula MMF_SwitchDivergentFormula(fFormula5).SetParams(fType,fConstant) elseif @classFormula5==MMF_SwitchConvergentFormula MMF_SwitchConvergentFormula(fFormula5).SetParams(fType,fConstant) elseif @classFormula5==MMF_SwitchConvergentDivergentFormula MMF_SwitchConvergentDivergentFormula(fFormula5).SetParams(fType,fConstant) endif if @p_NumFormulas=="6" if @classFormula6==MMF_SwitchFormula MMF_SwitchFormula(fFormula6).SetParams(fType,fConstant) elseif @classFormula6==MMF_SwitchDivergentFormula MMF_SwitchDivergentFormula(fFormula6).SetParams(fType,fConstant) elseif @classFormula6==MMF_SwitchConvergentFormula MMF_SwitchConvergentFormula(fFormula6).SetParams(fType,fConstant) elseif @classFormula6==MMF_SwitchConvergentDivergentFormula MMF_SwitchConvergentDivergentFormula(fFormula6).SetParams(fType,fConstant) endif endif endif endif endif endfunc complex func Iterate(complex pz) fzt = pz if m_Iterations==0 fZold = fzt = fz[0] else fZold = pz endif if @p_Method=="Alternate" int i = m_Iterations%(@p_NumFormulas+2) m_Iterations = m_Iterations + 1 if i==0 fzz = fFormula1.Iterate(fzt) elseif i==1 fzz = fFormula2.Iterate(fzt) elseif i==2 fzz = fFormula3.Iterate(fzt) elseif i==3 fzz = fFormula4.Iterate(fzt) elseif i==4 fzz = fFormula5.Iterate(fzt) elseif i==5 fzz = fFormula6.Iterate(fzt) endif else; @p_Method!="Alternate" m_Iterations = m_Iterations + 1 fzz = fzt = fFormula1.Iterate(fzt) if @p_Method!="Mix All" if m_Iterations==1 fzt = fz[1] else fzt = pz endif endif fzt = fFormula2.Iterate(fzt) CheckVals(1) if @p_NumFormulas=="3" || @p_NumFormulas=="4" || @p_NumFormulas=="5" \ || @p_NumFormulas=="6" if @p_Method!="Mix All" if m_Iterations==1 fzt = fz[2] else fzt = pz endif endif fzt = fFormula3.Iterate(fzt) CheckVals(2) if @p_NumFormulas=="4" || @p_NumFormulas=="5" || @p_NumFormulas=="6" if @p_Method!="Mix All" if m_Iterations==1 fzt = fz[3] else fzt = pz endif endif fzt = fFormula4.Iterate(fzt) CheckVals(3) if @p_NumFormulas=="5" || @p_NumFormulas=="6" if @p_Method!="Mix All" if m_Iterations==1 fzt = fz[4] else fzt = pz endif endif fzt = fFormula5.Iterate(fzt) CheckVals(4) if @p_NumFormulas=="6" if @p_Method!="Mix All" if m_Iterations==1 fzt = fz[5] else fzt = pz endif endif fzt = fFormula6.Iterate(fzt) CheckVals(5) endif endif endif endif if @p_Method=="Mix All" fzz = fzt endif endif; @p_Method=="Alternate" return fzz endfunc bool func IsBailedOut(complex pz) if ((@p_BailType=="Divergent" || @p_BailType=="Both" \ || @p_BailType=="Div.+Abs.Conv.") \ && |pz|>=@p_Bailout) \ || ((@p_BailType=="Convergent" || @p_BailType=="Both") \ && |pz-fZold|<=@p_SmallBail) \ || ((@p_BailType=="Absolute Convergence" \ || @p_BailType=="Div.+Abs.Conv.") \ && |pz-@p_root|<=@p_SmallBail ) m_BailedOut = true endif return m_BailedOut endfunc float func GetUpperBailout() return @p_Bailout endfunc float func GetLowerBailout() return @p_SmallBail endfunc private: ; Updates the z value to use according to the selected condition
; @param i the formula number func CheckVals(int i) if @p_Method=="Minimum Magnitude" if |fzt-@p_Coord|<|fzz-@p_Coord| fzz = fzt if m_Iterations==1 fZold = fz[i] endif endif elseif @p_Method=="Maximum Magnitude" if |fzt-@p_Coord|>|fzz-@p_Coord| fzz = fzt if m_Iterations==1 fZold = fz[i] endif endif elseif @p_Method=="Minimum Abs. Real" if abs(real(fzt)-real(@p_coord))<=abs(real(fzz)-real(@p_coord)) fzz = fzt if m_Iterations==1 fZold = fz[i] endif endif elseif @p_Method=="Maximum Abs. Real" if abs(real(fzt)-real(@p_coord))>abs(real(fzz)-real(@p_coord)) fzz = fzt if m_Iterations==1 fZold = fz[i] endif endif elseif @p_Method=="Minimum Abs. Imaginary" if abs(imag(fzt)-imag(@p_coord))<=abs(imag(fzz)-imag(@p_coord)) fzz = fzt if m_Iterations==1 fZold = fz[i] endif endif elseif @p_Method=="Maximum Abs. Imaginary" if abs(imag(fzt)-imag(@p_coord))>abs(imag(fzz)-imag(@p_coord)) fzz = fzt if m_Iterations==1 fZold = fz[i] endif endif elseif @p_Method=="Minimum Real" if real(fzt)-real(@p_coord)<=real(fzz)-real(@p_coord) fzz = fzt if m_Iterations==1 fZold = fz[i] endif endif elseif @p_Method=="Maximum Real" if real(fzt)-real(@p_coord)>real(fzz)-real(@p_coord) fzz = fzt if m_Iterations==1 fZold = fz[i] endif endif elseif @p_Method=="Minimum Imaginary" if imag(fzt)-imag(@p_coord)<=imag(fzz)-imag(@p_coord) fzz = fzt if m_Iterations==1 fZold = fz[i] endif endif elseif @p_Method=="Maximum Imaginary" if imag(fzt)-imag(@p_coord)>imag(fzz)-imag(@p_coord) fzz = fzt if m_Iterations==1 fZold = fz[i] endif endif elseif @p_Method=="Abs. Minima" if abs(real(fzt)-real(@p_coord))<=abs(real(fzz)-real(@p_coord)) fzz = real(fzt) + flip(imag(fzz)) if m_Iterations==1 fZold = real(fz[i]) + flip(imag(fZold)) endif endif if abs(imag(fzt)-imag(@p_coord))<=abs(imag(fzz)-imag(@p_coord)) fzz = real(fzz) + flip(imag(fzt)) if m_Iterations==1 fZold = real(fZold) + flip(imag(fz[i])) endif endif elseif @p_Method=="Abs. Maxima" if abs(real(fzt)-real(@p_coord))>abs(real(fzz)-real(@p_coord)) fzz = real(fzt) + flip(imag(fzz)) if m_Iterations==1 fZold = real(fz[i]) + flip(imag(fZold)) endif endif if abs(imag(fzt)-imag(@p_coord))>abs(imag(fzz)-imag(@p_coord)) fzz = real(fzz) + flip(imag(fzt)) if m_Iterations==1 fZold = real(fZold) + flip(imag(fz[i])) endif endif elseif @p_Method=="Minima" if real(fzt)-real(@p_coord)<=real(fzz)-real(@p_coord) fzz = real(fzt) + flip(imag(fzz)) if m_Iterations==1 fZold = real(fz[i]) + flip(imag(fZold)) endif endif if imag(fzt)-imag(@p_coord)<=imag(fzz)-imag(@p_coord) fzz = real(fzz) + flip(imag(fzt)) if m_Iterations==1 fZold = real(fZold) + flip(imag(fz[i])) endif endif elseif @p_Method=="Maxima" if real(fzt)-real(@p_coord)>real(fzz)-real(@p_coord) fzz = real(fzt) + flip(imag(fzz)) if m_Iterations==1 fZold = real(fz[i]) + flip(imag(fZold)) endif endif if imag(fzt)-imag(@p_coord)>imag(fzz)-imag(@p_coord) fzz = real(fzz) + flip(imag(fzt)) if m_Iterations==1 fZold = real(fZold) + flip(imag(fz[i])) endif endif endif endfunc Formula fFormula1 Formula fFormula2 Formula fFormula3 Formula fFormula4 Formula fFormula5 Formula fFormula6 complex fz[6] complex fZold complex fzt complex fzz default: title = "Switch Formula Wars #2" rating = recommended int param v_mmfswitchformulawars2 caption = "Version (Switch Formula Wars #2)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam complex param p_power visible = false endparam float param p_upperbailout visible = false endparam float param p_lowerbailout visible = false endparam bool param p_addpixel visible = false endparam heading caption = "Bailout Options" text = "You should note that the bailout options and values you set \ here will override the bailout settings in the various formula \ parameters. This is because your chosen warring combination \ could produce either convergent or divergent results whereas \ some of your warring formulas may be convergent and others \ divergent." endheading int param p_BailType caption = "Bailout Type" enum = "Divergent" "Convergent" "Both" "Absolute Convergence" \ "Div.+Abs.Conv." default = 0 hint = "If you get an empty or nearly empty fractal try switching \ from 'Divergent' to 'Convergent' or vice-versa or choosing \ 'Both'. Note that in some cases if your fractal is a \ Mandelbrot you may need to ensure that the zstart value \ is non-zero." endparam complex param p_root caption = "Convergence Value" default = (1,0) hint = "This is the value for testing for convergence to. For the \ 'Magnet' formulas the value should be (1,0), if you don't \ know the value to use it's best to stick to the plain \ 'Convergent' 'Bailout Type'. It's always worth trying (0,0)." visible = @p_BailType>2 endparam float param p_Bailout caption = "Divergent Bailout" default = 128.0 hint = "In general larger values will require higher iterations." visible = @p_BailType==0 || @p_BailType==2 || @p_BailType==4 endparam float param p_SmallBail caption = "Convergent Bailout" default = 1e-5 hint = "In general smaller values will require higher iterations." visible = @p_BailType>0 endparam heading caption = "War Settings" endheading int param p_Method caption = "Method of choice" enum = "Minimum Magnitude" "Maximum Magnitude" "Minimum Abs. Real" \ "Maximum Abs. Real" "Minimum Abs. Imaginary" \ "Maximum Abs. Imaginary" "Minimum Real" "Maximum Real" \ "Minimum Imaginary" "Maximum Imaginary" "Abs. Minima" \ "Abs. Maxima" "Minima" "Maxima" "Mix All" "Alternate" default = 0 endparam complex param p_Coord caption = "Centre" default = (0,0) hint = "Used as the centre for the testing to decide which \ formula to use on each iteration." visible = @p_Method<6 endparam int param p_NumFormulas caption = "Number of Formulas" enum = "2" "3" "4" "5" "6" default = 0 endparam heading caption = "The Warring Formulas" endheading heading caption = "Warring Formula #1" endheading heading text = "'Fractal Formula #1' is not a switch formula and so will \ not switch using UFs built-in switch method." visible = @classFormula1!=MMF_SwitchFormula \ && @classFormula1!=MMF_SwitchDivergentFormula \ && @classFormula1!=MMF_SwitchConvergentFormula \ && @classFormula1!=MMF_SwitchConvergentDivergentFormula endheading Formula param classFormula1 caption = "Fractal Formula #1" default = MMF_SwitchStandard endparam heading caption = "Warring Formula #2" endheading heading text = "'Fractal Formula #2' is not a switch formula and so will \ not switch using UFs built-in switch method." visible = @classFormula2!=MMF_SwitchFormula \ && @classFormula2!=MMF_SwitchDivergentFormula \ && @classFormula2!=MMF_SwitchConvergentFormula \ && @classFormula2!=MMF_SwitchConvergentDivergentFormula endheading Formula param classFormula2 caption = "Fractal Formula #2" default = MMF_SwitchStandard endparam heading caption = "Warring Formula #3" visible = @p_NumFormulas>0 endheading heading text = "'Fractal Formula #3' is not a switch formula and so will \ not switch using UFs built-in switch method." visible = @p_NumFormulas>0 && @classFormula3!=MMF_SwitchFormula \ && @classFormula3!=MMF_SwitchDivergentFormula \ && @classFormula3!=MMF_SwitchConvergentFormula \ && @classFormula3!=MMF_SwitchConvergentDivergentFormula endheading Formula param classFormula3 caption = "Fractal Formula #3" default = MMF_SwitchStandard visible = @p_NumFormulas>0 endparam heading caption = "Warring Formula #4" visible = @p_NumFormulas>1 endheading heading text = "'Fractal Formula #4' is not a switch formula and so will \ not switch using UFs built-in switch method." visible = @p_NumFormulas>1 && @classFormula4!=MMF_SwitchFormula \ && @classFormula4!=MMF_SwitchDivergentFormula \ && @classFormula4!=MMF_SwitchConvergentFormula \ && @classFormula4!=MMF_SwitchConvergentDivergentFormula endheading Formula param classFormula4 caption = "Fractal Formula #4" default = MMF_SwitchStandard visible = @p_NumFormulas>1 endparam heading caption = "Warring Formula #5" visible = @p_NumFormulas>2 endheading heading text = "'Fractal Formula #5' is not a switch formula and so will \ not switch using UFs built-in switch method." visible = @p_NumFormulas>2 && @classFormula5!=MMF_SwitchFormula \ && @classFormula5!=MMF_SwitchDivergentFormula \ && @classFormula5!=MMF_SwitchConvergentFormula \ && @classFormula5!=MMF_SwitchConvergentDivergentFormula endheading Formula param classFormula5 caption = "Fractal Formula #5" default = MMF_SwitchStandard visible = @p_NumFormulas>2 endparam heading caption = "Warring Formula #6" visible = @p_NumFormulas>3 endheading heading text = "'Fractal Formula #6' is not a switch formula and so will \ not switch using UFs built-in switch method." visible = @p_NumFormulas>3 && @classFormula6!=MMF_SwitchFormula \ && @classFormula6!=MMF_SwitchDivergentFormula \ && @classFormula6!=MMF_SwitchConvergentFormula \ && @classFormula6!=MMF_SwitchConvergentDivergentFormula endheading Formula param classFormula6 caption = "Fractal Formula #6" default = MMF_SwitchStandard visible = @p_NumFormulas>3 endparam } class MMF_TransformMod(common.ulb:UserTransform) { ; Applies a modulus
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_TransformMod(Generic pparent) UserTransform.UserTransform(pparent) fTransform1 = new @p_Transform1(this) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this transform m_Solid = false fTransform1.Init(pz) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform pz = pz*@p_scale return fTransform1.Iterate(real(pz)%real(@p_modulus) \ +flip(imag(pz)%imag(@p_modulus))) endfunc private: Transform fTransform1 default: title = "Transform Modulus" complex param p_modulus caption = "Modulus" default = (1.0,1.0) hint = "Both real and imaginay pats are used, being applied to the real \ and imaginay input values respectively." endparam complex param p_scale caption = "Scale" default = (1.0,0.0) hint = "Normally you'd stick to using a wholly real number." endparam Transform param p_Transform1 caption = "Following transfom" default = MMF_GeneralTransform hint = "The modified value is passsed on to this transform." endparam } class MMF_GeneralTransform(common.ulb:UserTransform) { ; offset,scale,offset,function,offset,scale,offset
public: complex func Iterate(complex pz) return ( @p_func((pz + @p_offset)*@p_scale + @p_offset1) \ + @p_offset2) * @p_scale1 + @p_offset3 endfunc default: title = "General Transform" complex param p_offset caption = "Initial Pre-Offset" default = (0,0) endparam complex param p_scale caption = "Pre-Scale" default = (1,0) endparam complex param p_offset1 caption = "Final Pre-Offset" default = (0,0) endparam func p_func caption = "Function" default = ident() endfunc complex param p_offset2 caption = "Initial Post-Offset" default = (0,0) endparam complex param p_scale1 caption = "Post-Scale" default = (1,0) endparam complex param p_offset3 caption = "Final Post-Offset" default = (0,0) endparam } class MMF_SwitchRecursion(MMF_SwitchConvergentDivergentFormula) { ; This formula is an adaption of 'Switch Recursion' from mmfs.ufm ; which itself was based on the Lucas recursion formula found on Mathworld.

; Note that for historical reasons this formula uses its own ; zold and bailout values instead of those defined in the base class ; doing so should not be taken as a model for other formulas.
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SwitchRecursion(Generic pparent) MMF_SwitchConvergentDivergentFormula.MMF_SwitchConvergentDivergentFormula(pparent) fTransform0 = new @p_Transform0(this) fTransform1 = new @p_Transform1(this) fTransformPZ = new @p_TransformPZ(this) fTransformP = new @p_TransformP(this) fTransformQZ = new @p_TransformQZ(this) fTransformQ = new @p_TransformQ(this) fTransformX = new @p_TransformX(this) fTransformD = new @p_TransformD(this) endfunc complex func Init(complex pz) ; m_Iterations = 0 not used in this formula m_BailedOut = false fTransform0.Init(pz) fTransform1.Init(pz) fTransformPZ.Init(pz) fTransformP.Init(pz) fTransformQZ.Init(pz) fTransformQ.Init(pz) fTransformX.Init(pz) fTransformD.Init(pz) if fType fConstant = pz if @p_addpixel fZold = pz = fValue + fConstant else fZold = pz = fValue endif else fZold = pz endif if @p_type=="Iterative" m_p = m_p0 = fTransform0.Iterate(pz) m_p1 = fTransform1.Iterate(pz) m_recursecount = 2 endif return pz endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this formula if @p_type=="Normal" complex p complex p0 = fTransform0.Iterate(pz) complex p1 = fTransform1.Iterate(pz) int i = 2 repeat p = ((fTransformPZ.Iterate(i)*pz + fTransformP.Iterate(i))*p1 \ + (fTransformQZ.Iterate(i)*pz + fTransformQ.Iterate(i))*p0) \ / fTransformD.Iterate(i) p0 = p1 p1 = p until (i=i+1)>@p_recurse m_p = p1 else;if @p_type=="Iterative" m_p = ((fTransformPZ.Iterate(m_recursecount)*pz \ + fTransformP.Iterate(m_recursecount))*m_p1 \ + (fTransformQZ.Iterate(m_recursecount)*pz \ + fTransformQ.Iterate(m_recursecount))*m_p0) \ / fTransformD.Iterate(m_recursecount) m_p0 = m_p1 m_p1 = m_p m_recursecount = m_recursecount + 1 endif if @p_fractal=="Pn(z)+c" m_p = fTransformX.Iterate(m_p) + fConstant elseif @p_fractal=="c*Pn(z)" m_p = fConstant*fTransformX.Iterate(m_p) elseif @p_fractal=="Pn(z)+zold+c" m_p = fTransformX.Iterate(m_p) + fZold + fConstant elseif @p_fractal=="c*Pn(z)+zold" m_p = fConstant*fTransformX.Iterate(m_p) + fZold elseif @p_fractal=="zold*Pn(z)+c" m_p = fZold*fTransformX.Iterate(m_p) + fConstant else;if @p_fractal=="c*zold*Pn(z)" m_p = fConstant*fZold*fTransformX.Iterate(m_p) endif fZold = pz return m_p endfunc bool func IsBailedOut(complex pz) if ((@p_BailType=="Divergent" || @p_BailType=="Both" \ || @p_BailType=="Div.+Abs.Conv.") \ && |pz|>=@p_Bailout) \ || ((@p_BailType=="Convergent" || @p_BailType=="Both") \ && |pz-fZold|<=@p_SmallBail) \ || ((@p_BailType=="Absolute Convergence" \ || @p_BailType=="Div.+Abs.Conv.") \ && |pz-@p_root|<=@p_SmallBail ) m_BailedOut = true endif return m_BailedOut endfunc float func GetUpperBailout() return @p_Bailout endfunc float func GetLowerBailout() return @p_SmallBail endfunc complex func GetPrimaryExponent() return @p_recurse endfunc private: Transform fTransform0 Transform fTransform1 Transform fTransformPZ Transform fTransformP Transform fTransformQZ Transform fTransformQ Transform fTransformX Transform fTransformD complex fZold complex m_p complex m_p0 complex m_p1 int m_recursecount default: title = "Switch Recursion" int param v_mmfswitchrecursion caption = "Version (MMF Switch Recursion)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam float param p_upperbailout visible = false endparam float param p_lowerbailout visible = false endparam bool param p_addpixel caption = "Offset z start" default = false hint = "When enabled the z start value (in Mandelbrot mode) is offset \ by the constant for the current position - normally '#pixel'." visible = !@p_manual || @p_mandy endparam complex param p_power visible = false endparam heading caption = "Information" text = "This formula is an adaptation of 'Switch Recursion' from \ mmfs.ufm which itself was based on the Lucas recursion \ formula found on Mathworld. Tip: You'll often find that \ the best Mandelbrot start value (critical value) is \ non-zero when you change the recursion parameters. You \ can use the switch back from the Julia to the Mandelbrot \ to help find the critical value - it's usually when the \ Mandelbrot 'lake' is at its largest, if you stick to real \ values for the recursion parameters then the critical \ value should also be real. Note that it's often worth trying \ values such as -1, -0.5, 0.5 or 1 as the Mandelbrot start \ value. For those more mathematically inclined see the details \ of the 'Transpoly' formula in mmf.html for details of several \ classic polynomial functions that you can create using this \ formula by setting the recursion transforms and values \ appropriately." endheading heading caption = "Bailout Options" text = "Depending on the transforms you choose your fractal could \ be either divergent or convergent. You need to choose the \ correct type to produce a result, a symptom of choosing the \ wrong type is an image in a single solid colour e.g. black. \ Sometimes fractals produce both types of 'vergence and for \ these you can choose 'Both'." endheading int param p_BailType caption = "Bailout Type" enum = "Divergent" "Convergent" "Both" "Absolute Convergence" \ "Div.+Abs.Conv." default = 0 hint = "If you get an empty or nearly empty fractal try switching \ from 'Divergent' to 'Convergent' or vice-versa or choosing \ 'Both'. Note that in some cases if your fractal is a \ Mandelbrot you may need to ensure that the zstart value \ is non-zero." endparam complex param p_root caption = "Convergence Value" default = (1,0) hint = "This is the value for testing for convergence to. For the \ 'Magnet' formulas the value should be (1,0), if you don't \ know the value to use it's best to stick to the plain \ 'Convergent' 'Bailout Type'. It's always worth trying (0,0)." visible = @p_BailType>2 endparam float param p_Bailout caption = "Divergent Bailout" default = 128.0 hint = "In general larger values will require higher iterations." visible = @p_BailType==0 || @p_BailType==2 || @p_BailType==4 endparam float param p_SmallBail caption = "Convergent Bailout" default = 1e-5 hint = "In general smaller values will require higher iterations." visible = @p_BailType>0 endparam heading caption = "Fractal Method" endheading int param p_type caption = "Recursion Type" enum = "Normal" "Iterative" default = 0 hint = "When you specify 'Normal' a set number of recursions are \ performed on each iteration, the number of recursions will \ control the degree (exponent) of the fractal (at least for \ divergent fractals). When you choose 'Iterative' the \ recurrence relation is performed as the iterations i.e. for \ divergent fractals the degree increases with the number of \ iterations." endparam int param p_recurse caption = "Number of Recursions" default = 6 min = 2 hint = "The number of recursions to perform on each iteration. The \ minimum is 2. Using the defaults a count of 2 will produce \ a degree 2 fractal, 3 will produce a degree 3 fractal and so \ on." visible = @p_type==0 endparam Transform param p_TransformX caption = "Transform of Pn(z)" default = NullTransform hint = "Here you may specify a transform of the recurrence \ function Pn(z) before it is plugged into the 'Fractal \ Formula'." endparam int param p_fractal caption = "Fractal Formula" enum = "Pn(z)+c" "c*Pn(z)" "Pn(z)+zold+c" "c*Pn(z)+zold" \ "zold*Pn(z)+c" "c*zold*Pn(z)" default = 0 hint = "Normally the recurrence relation you set using the \ transforms will produce a polynomial in z, Pn(z). \ Here you can choose how Pn(z) is used to produce a \ fractal." endparam heading caption = "Recursion Equations" text = "Here you can set the equations used for the recurrence \ relation by choosing appropriate transforms. \ The recurrence relation works as follows: Two base \ equations are used, P0(z) and P1(z) and on each recursion \ Pn(z) is created as Pn(z) = ((Q(n)*z + R(n))*Pn-1(z) + \ (S(n)*z + T(n))*Pn-2(z))/D(n) where Q(n), R(n), S(n), T(n) \ and D(n) are functions of the recurrence level n. You \ specify P0 as 'Transform 0', P1 as 'Transform 1', Q as \ 'Transform Q', R as 'Transform R', S as 'Transform S', T \ as 'Transform T' and D as 'Transform D'. The formula is \ really designed so you should use either the 'Constant Value', \ 'Simple Scale' or 'Linear' transforms from mmf.ulb but \ interesting results may arise from almost any transform :)" endheading Transform param p_Transform0 caption = "Transform 0" default = MMF_Scale hint = "P0(z)" endparam Transform param p_Transform1 caption = "Transform 1" default = MMF_Scale hint = "P1(z)" endparam Transform param p_TransformPZ caption = "Transform Q" default = MMF_Constant hint = "Q(n) in (Q(n)*z + R(n))*Pn-1(z) + (S(n)*z + T(n))*Pn-2(z)" endparam Transform param p_TransformP caption = "Transform R" default = MMF_Constant hint = "R(n) in (Q(n)*z + R(n))*Pn-1(z) + (S(n)*z + T(n))*Pn-2(z)" endparam Transform param p_TransformQZ caption = "Transform S" default = MMF_Constant hint = "S(n) in (Q(n)*z + R(n))*Pn-1(z) + (S(n)*z + T(n))*Pn-2(z)" endparam Transform param p_TransformQ caption = "Transform T" default = MMF_Constant hint = "T(n) in (Q(n)*z + R(n))*Pn-1(z) + (S(n)*z + T(n))*Pn-2(z)" endparam Transform param p_TransformD caption = "Transform D" default = MMF_Constant hint = "The polynomial is divided by this transform of the \ recurrence level at each stage." endparam } class MMF_SwitchGradientSlopeHelper { ; ; Helper class for SwitchGradientSlope.
; By David Makin
; First version May 2008
; public: import "common.ulb" import "Standard.ulb" func MMF_SwitchGradientSlopeHelper(MMF_SwitchGradientSlope owner) fFormula = new @formulaClass(owner) fColouring = new @coloringClass(owner) endfunc complex func Init(const complex pz) fZ = fFormula.Init(pz) fColouring.Init(fZ,pz) return fZ endfunc func SetParams(bool f,complex v) if @formulaClass==MMF_SwitchFormula MMF_SwitchFormula(fFormula).SetParams(f,v) elseif @formulaClass==MMF_SwitchDivergentFormula MMF_SwitchDivergentFormula(fFormula).SetParams(f,v) elseif @formulaClass==MMF_SwitchConvergentFormula MMF_SwitchConvergentFormula(fFormula).SetParams(f,v) elseif @formulaClass==MMF_SwitchConvergentDivergentFormula MMF_SwitchConvergentDivergentFormula(fFormula).SetParams(f,v) endif endfunc complex func Iterate() return (fZ = fFormula.Iterate(fZ)) endfunc func IterateCol() fColouring.Iterate(fZ) return endfunc bool func IsBailedOut() return fFormula.IsBailedOut(fZ) endfunc float func GetHeight() return fColouring.ResultIndex(fZ) endfunc complex func GetPrimaryExponent() return fFormula.GetPrimaryExponent() endfunc float func GetUpperBailout() return fFormula.GetUpperBailout() endfunc float func GetLowerBailout() return fFormula.GetLowerBailout() endfunc private: Formula fFormula GradientColoring fColouring complex fZ default: title = "Switch Gradient Slope Helper" int param v_mmfgradientslopehelper caption = "Version (MMF Gradient Slope Helper)" default = 100 hint = "This version parameter is used to detect when a change has been \ made to the formula that is incompatible with the previous \ version. When that happens, this field will reflect the old \ version number to alert you to the fact that an alternate \ rendering is being used." visible = @v_mmfgradientslopehelper<100 endparam heading text = "'Fractal Formula' is not a switch formula and so will \ not switch using UFs built-in switch method." visible = @formulaClass!=MMF_SwitchFormula \ && @formulaClass!=MMF_SwitchDivergentFormula \ && @formulaClass!=MMF_SwitchConvergentFormula \ && @formulaClass!=MMF_SwitchConvergentDivergentFormula endheading Formula param formulaClass caption = "Fractal Formula" default = MMF_SwitchStandard hint = "Sets the actual fractal formula to use for the lighting effect." endparam GradientColoring param coloringClass caption = "Colouring Algorithm" default = Standard_Smooth hint = "Selects the colouring algorithm to be used. Note that where \ necessary you should ensure duplicate parameters in the 'Fractal \ Formula' and the 'Colouring Algorithm' match each other - \ typically bailout values and degree/exponent/power values." endparam } class MMF_SwitchGradientSlope(MMF_SwitchFormula) { ; ; Creates 3D lighting effects when combined with the ; Lighting or Mixed Lighting (direct) colouring algorithms.
; Allows "slope" colouring from any formula, any colouring.
; ; Written by David Makin based on Standard_Slope by Damien Jones
; Original May 2008
; public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SwitchGradientSlope(Generic pparent) MMF_SwitchFormula(pparent) fHelper[0] = new @helperClass(this) fHelper[1] = new @helperClass(this) fHelper[2] = new @helperClass(this) fTransfer[0] = new @transferClass(this) fTransfer[1] = new @transferClass(this) fTransfer[2] = new @transferClass(this) if @mode>0 ; If using 'Colouring+Lighting" pre-compute some constants float rot = (270.0-@angle)*(#pi/180.0) ; degrees to radians conversion float ele = @elevation*(#pi/180.0) ; The lighting Normal lx = cos(rot) * cos(ele) ly = sin(rot) * cos(ele) lz = sin(ele) ; Scale for adjusting light value accounting for ambient level amb = 0.5*(1.0 - @ambient) endif endfunc func SetParams(bool f,complex v) if !@p_manual fType = f fValue = fConstant = v endif fHelper[0].SetParams(f,v) ; This was a bug in the first release but fHelper[1].SetParams(f,v) ; as it happens the problem was simply fixed fHelper[2].SetParams(f,v) ; by removing the "manual override" params ; from future use since they aren't needed ; because the manual override in the child ; switch formula is sufficient. ; f,v here should have been fType,fConstant endfunc complex func Init(complex pz) complex z1 = fHelper[0].Init(pz) ; primary iterated point fHelper[1].Init(pz + @offset) ; horizontally offset point fHelper[2].Init(pz + flip(@offset)) ; vertically offset point fTransfer[0].Init(pz) fTransfer[1].Init(pz + @offset) fTransfer[2].Init(pz + flip(@offset)) fIteration = 0 return z1 endfunc complex func Iterate(complex pz) ; We can't use the pz value because we need to keep track of three z values. fIteration = fIteration + 1 complex z1 = fHelper[0].Iterate() m_BailedOut = fHelper[0].IsBailedOut() fHelper[1].Iterate() if @earlyout m_BailedOut = m_BailedOut || fHelper[1].IsBailedOut() endif fHelper[2].Iterate() if @earlyout m_BailedOut = m_BailedOut || fHelper[2].IsBailedOut() endif if !m_BailedOut ; for normal UF behaviour don't call iterate for ; the colouring formula if we've bailed out fHelper[0].IterateCol() fHelper[1].IterateCol() fHelper[2].IterateCol() endif if m_BailedOut || fIteration == #maxiter ; done or last ; Get "height" offsets - note that "vz" would be -@offset float e1 = fHelper[0].GetHeight() float vy = fTransfer[0].Iterate(e1) float vx = fTransfer[1].Iterate(fHelper[1].GetHeight()) - vy float vy = fTransfer[2].Iterate(fHelper[2].GetHeight()) - vy ; normalising scale float vd = 1.0/sqrt(sqr(vx)+sqr(vy)+sqr(@offset)) if @mode==0 return vd*(vx + flip(vy)); fudge z from vector (vz is implied) else ; return the colouring value as real and the light value as imaginary ; note that + lz*offset is a double negative i.e. + -lz*-@offset return e1 + flip(@ambient + amb*(1.0+vd*(lx*vx + ly*vy + lz*@offset))) endif else ; didn't compute z this time ; use primary iteration value to keep periodicity working return z1 endif endfunc complex func GetPrimaryExponent() return fHelper[0].GetPrimaryExponent() endfunc float func GetUpperBailout() return fHelper[0].GetUpperBailout() endfunc float func GetLowerBailout() return fHelper[0].GetLowerBailout() endfunc private: MMF_SwitchGradientSlopeHelper fHelper[3] Transfer fTransfer[3] float lx float ly float lz float amb int fIteration default: title = "Switch Gradient Slope" rating = recommended heading text = "Tip: Use with the Standard Lighting coloring algorithms \ or reb5.ucl-Lighting with Textures or the Mixed \ Lighting (direct) colouring algorithm from mmf.ulb." endheading int param v_mmfswitchgradientslope caption = "Version (Switch Gradient Slope)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam bool param p_manual visible = false endparam bool param p_mandy visible = false endparam complex param p_start visible = false endparam complex param p_seed visible = false endparam float param offset caption = "Orbit Separation" default = 0.00000001 exponential = true hint = "Defines how far apart the simultaneous orbits are. Smaller \ distances will produce more accurate results, the deeper you zoom \ the smaller the value needs to be to keep detail." endparam bool param earlyout caption = "Early Out" default = false hint = "This formula iterates 3 points to get the normal for the slope \ colouring, normally all 3 points are iterated until the primary \ point bails out. Unfortunately with some colourings this can lead \ to a NAN (not a number) problem, typically at higher zooms \ producing areas of solid flat lighting. If you think you have \ this problem try enabling 'Early Out' which terminates iteration \ as soon as any one of the three points bails out." endparam int param mode caption = "Method" enum = "Lighting" "Colouring+Lighting" default = 0 hint = "'Lighting' is for colouring using the standard 'Lighting' method \ 'Colouring+Lighting' is for use with the \ 'Mixed Lighting (direct)' colouring." endparam float param angle caption = "Light Rotation" default = 90.0 hint = "Gives the rotation of the light source, in degrees. With 0 \ degrees, the light comes from above. Positive values give \ clockwise rotation." visible = @mode==1 endparam float param elevation caption = "Light Elevation" default = 30.0 hint = "Gives the elevation of the light source, in degrees." visible = @mode==1 endparam float param ambient caption = "Ambient Light" default = 0.0 min = -1.0 max = 1.0 hint = "Specifies the level of ambient light." visible = @mode==1 endparam Transfer param transferClass caption = "Height Transfer" default = TrapTransfer hint = "Selects a class to transform the calculated height value." expanded = false endparam MMF_SwitchGradientSlopeHelper param helperClass selectable = false endparam complex param p_power ; Hide p_power from Formula visible = false endparam } class MMF_FormulaTransformWrapper(common.ulb:ConvergentDivergentFormula) { ; A formula that wraps two transforms around any formula iteration.

; Note that for historical reasons this formula uses its own ; zold and bailout values instead of those defined in the base class ; doing so should not be taken as a model for other formulas.
public: import "common.ulb" import "Standard.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_FormulaTransformWrapper(Generic pparent) ConvergentDivergentFormula.ConvergentDivergentFormula(pparent) fFormula = new @classFormula(this) fPreTransform = new @classPreTransform(this) fPostTransform = new @classPostTransform(this) endfunc complex func Init(complex pz) ; m_Iterations = 0 not used in this formula m_BailedOut = false fPreTransform.Init(pz) fPostTransform.Init(pz) return fFormula.Init(pz) endfunc complex func Iterate(complex pz) fZold = pz ; m_Iterations = m_Iterations + 1 not used in this formula return fPostTransform.Iterate(fFormula.Iterate(fPreTransform.Iterate(pz))) endfunc complex func GetPrimaryExponent() return fFormula.GetPrimaryExponent() endfunc bool func IsBailedOut(complex pz) if ((@p_BailType=="Divergent" || @p_BailType=="Both" \ || @p_BailType=="Div.+Abs.Conv.") \ && |pz|>=@p_Bailout) \ || ((@p_BailType=="Convergent" || @p_BailType=="Both") \ && |pz-fZold|<=@p_SmallBail) \ || ((@p_BailType=="Absolute Convergence" \ || @p_BailType=="Div.+Abs.Conv.") \ && |pz-@p_root|<=@p_SmallBail ) m_BailedOut = true endif return m_BailedOut endfunc float func GetUpperBailout() return @p_Bailout endfunc float func GetLowerBailout() return @p_SmallBail endfunc protected: Formula fFormula UserTransform fPreTransform UserTransform fPostTransform complex fZold default: title = "Formula Transformations" int param v_mmfformulatransformwrapper caption = "Version (MMF_FormulaTransformWrapper)" default = 100 hint = "This version parameter is used to detect when a change has \ been made to the formula that is incompatible with the \ previous version. When that happens, this field will reflect \ the old version number to alert you to the fact that an \ alternate rendering is being used." visible = @v_mmfformulatransformwrapper < 100 endparam complex param p_power visible = false endparam float param p_upperbailout visible = false endparam float param p_lowerbailout visible = false endparam heading caption = "Bailout Options" text = "You should note that the bailout options and values you set \ here will override the bailout settings in the 'Formula' \ parameters. This is because your chosen transforms may cause \ a divergent formula to become convergent or vice-versa." endheading int param p_BailType caption = "Bailout Type" enum = "Divergent" "Convergent" "Both" "Absolute Convergence" \ "Div.+Abs.Conv." default = 0 hint = "If you get an empty or nearly empty fractal try switching \ from 'Divergent' to 'Convergent' or vice-versa or choosing \ 'Both'. Note that in some cases if your fractal is a \ Mandelbrot you may need to ensure that the zstart value \ is non-zero." endparam complex param p_root caption = "Convergence Value" default = (1,0) hint = "This is the value for testing for convergence to. For the \ 'Magnet' formulas the value should be (1,0), if you don't \ know the value to use it's best to stick to the plain \ 'Convergent' 'Bailout Type'. It's always worth trying (0,0)." visible = @p_BailType>2 endparam float param p_Bailout caption = "Divergent Bailout" default = 128.0 hint = "In general larger values will require higher iterations." visible = @p_BailType==0 || @p_BailType==2 || @p_BailType==4 endparam float param p_SmallBail caption = "Convergent Bailout" default = 1e-5 hint = "In general smaller values will require higher iterations." visible = @p_BailType>0 endparam heading caption = "The Pre-Transform" text = "Transforms z on each iteration prior to the main formula \ calculation." endheading UserTransform param classPreTransform caption = "Pre-Transform" default = NullTransform hint = "Transforms z on each iteration prior to the main formula \ calculation." endparam heading caption = "The Main Formula" endheading Formula param classFormula caption = "Formula" default = Standard_Mandelbrot hint = "The main formula." endparam heading caption = "The Post-Transform" text = "Transforms z on each iteration after the main formula \ calculation." endheading UserTransform param classPostTransform caption = "Post-Transform" default = NullTransform hint = "Transforms z on each iteration after the main formula \ calculation." endparam } class MMF_SwitchFormulaTransformWrapper(MMF_SwitchConvergentDivergentFormula) { ; A formula that wraps two transforms around any formula iteration.
; With switching when used with mmf5.ufm-Generic Switch Formula

; Note that for historical reasons this formula uses its own ; zold and bailout values instead of those defined in the base class ; doing so should not be taken as a model for other formulas.
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SwitchFormulaTransformWrapper(Generic pparent) MMF_SwitchConvergentDivergentFormula.MMF_SwitchConvergentDivergentFormula(pparent) fFormula = new @classFormula(this) fPreTransform = new @classPreTransform(this) fPostTransform = new @classPostTransform(this) endfunc func SetParams(bool f,complex v) if @classFormula==MMF_SwitchFormula MMF_SwitchFormula(fFormula).SetParams(f,v) elseif @classFormula==MMF_SwitchDivergentFormula MMF_SwitchDivergentFormula(fFormula).SetParams(f,v) elseif @classFormula==MMF_SwitchConvergentFormula MMF_SwitchConvergentFormula(fFormula).SetParams(f,v) elseif @classFormula==MMF_SwitchConvergentDivergentFormula MMF_SwitchConvergentDivergentFormula(fFormula).SetParams(f,v) endif endfunc complex func Init(complex pz) ; m_Iterations = 0 not used in this formula m_BailedOut = false fPreTransform.Init(pz) fPostTransform.Init(pz) return fFormula.Init(pz) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this formula fZold = pz return fPostTransform.Iterate(fFormula.Iterate(fPreTransform.Iterate(pz))) endfunc complex func GetPrimaryExponent() return fFormula.GetPrimaryExponent() endfunc bool func IsBailedOut(complex pz) if ((@p_BailType=="Divergent" || @p_BailType=="Both" \ || @p_BailType=="Div.+Abs.Conv.") \ && |pz|>=@p_Bailout) \ || ((@p_BailType=="Convergent" || @p_BailType=="Both") \ && |pz-fZold|<=@p_SmallBail) \ || ((@p_BailType=="Absolute Convergence" \ || @p_BailType=="Div.+Abs.Conv.") \ && |pz-@p_root|<=@p_SmallBail ) m_BailedOut = true endif return m_BailedOut endfunc float func GetUpperBailout() return @p_Bailout endfunc float func GetLowerBailout() return @p_SmallBail endfunc protected: Formula fFormula UserTransform fPreTransform UserTransform fPostTransform complex fZold default: title = "Switch Formula Transformations" rating = recommended int param v_mmfswitchformulatransformwrapper caption = "Version (MMF_SwitchFormulaTransformWrapper)" default = 100 hint = "This version parameter is used to detect when a change has \ been made to the formula that is incompatible with the \ previous version. When that happens, this field will reflect \ the old version number to alert you to the fact that an \ alternate rendering is being used." visible = @v_mmfswitchformulatransformwrapper < 100 endparam bool param p_manual visible = false endparam complex param p_power visible = false endparam float param p_upperbailout visible = false endparam float param p_lowerbailout visible = false endparam bool param p_addpixel visible = false endparam heading caption = "Bailout Options" text = "You should note that the bailout options and values you set \ here will override the bailout settings in the 'Formula' \ parameters. This is because your chosen transforms may cause \ a divergent formula to become convergent or vice-versa." endheading int param p_BailType caption = "Bailout Type" enum = "Divergent" "Convergent" "Both" "Absolute Convergence" \ "Div.+Abs.Conv." default = 0 hint = "If you get an empty or nearly empty fractal try switching \ from 'Divergent' to 'Convergent' or vice-versa or choosing \ 'Both'. Note that in some cases if your fractal is a \ Mandelbrot you may need to ensure that the zstart value \ is non-zero." endparam complex param p_root caption = "Convergence Value" default = (1,0) hint = "This is the value for testing for convergence to. For the \ 'Magnet' formulas the value should be (1,0), if you don't \ know the value to use it's best to stick to the plain \ 'Convergent' 'Bailout Type'. It's always worth trying (0,0)." visible = @p_BailType>2 endparam float param p_Bailout caption = "Divergent Bailout" default = 128.0 hint = "In general larger values will require higher iterations." visible = @p_BailType==0 || @p_BailType==2 || @p_BailType==4 endparam float param p_SmallBail caption = "Convergent Bailout" default = 1e-5 hint = "In general smaller values will require higher iterations." visible = @p_BailType>0 endparam heading caption = "The Pre-Transform" text = "Transforms z on each iteration prior to the main formula \ calculation." endheading UserTransform param classPreTransform caption = "Pre-Transform" default = NullTransform hint = "Transforms z on each iteration prior to the main formula \ calculation. To use multiple transforms select 'Transform \ Merge' from common.ulb." endparam heading caption = "The Main Formula" endheading heading text = "Note that the current 'Formula' is not a switch formula \ and so will not switch using UFs built-in switch method." visible = @classFormula!=MMF_SwitchFormula \ && @classFormula!=MMF_SwitchDivergentFormula \ && @classFormula!=MMF_SwitchConvergentFormula \ && @classFormula!=MMF_SwitchConvergentDivergentFormula endheading Formula param classFormula caption = "Formula" default = MMF_SwitchStandard hint = "The main formula." endparam heading caption = "The Post-Transform" text = "Transforms z on each iteration after the main formula \ calculation." endheading UserTransform param classPostTransform caption = "Post-Transform" default = NullTransform hint = "Transforms z on each iteration after the main formula \ calculation. To use multiple transforms select 'Transform \ Merge' from common.ulb." endparam } class MMF_SelfRotation(common.ulb:UserTransform) { ; Rotates the complex value by multiples of its own angle.
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SelfRotation(Generic pparent) UserTransform.UserTransform(pparent) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform if pz!=(0,0) float m = cabs(pz) if @degree==(1,0) pz = sqr(pz)/m else pz = pz^(@degree+1.0)/m^@degree endif endif return pz endfunc default: title = "Self Rotation" complex param degree caption = "Degree of rotation" default = (1,0) hint = "The larger the value, the more rotation involved. Using 1.0 \ means that the z value is rotated by its own angle, using \ 2.0 means that it's rotated by twice its own angle, 3.0 by \ three times and so on. Values less than 1, non-integer values, \ negative values, imaginary values etc. will produce strange \ results, not that results aren't strange anyway - in \ particular when self-rotation is applied the chance of \ Strangely Attractive orbits is increased :)" endparam } class MMF_RunningSum(common.ulb:UserTransform) { ; Returns the sum of pz and all previous values of pz
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_RunningSum(Generic pparent) UserTransform.UserTransform(pparent) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this transform m_Solid = false m_Sum = (0,0) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform return m_Sum = m_Sum + pz endfunc func IterateSilent() ; m_Iterations = m_Iterations + 1 not used in this transform if @p_restart m_Sum = (0,0) endif endfunc protected: complex m_Sum default: title = "Running Sum" bool param p_restart caption = "Reset the Sum" default = false hint = "This is only for when the transform is used in a situation \ where there may be iteration skipping, for example in a \ colouring formula. If you enable this option then the sum \ is reset to zero each time iteration skipping occurs." endparam } class MMF_RunningProduct(common.ulb:UserTransform) { ; Returns the product of pz and all previous values of pz.
; Fudges used when pz is zero.
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_RunningProduct(Generic pparent) UserTransform.UserTransform(pparent) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this transform m_Solid = false m_Product = (1,0) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform if pz!=(0,0) return m_Product = m_Product*pz elseif @p_method=="Alternative" return m_Product else;if @p_method=="Original" return pz endif endfunc func IterateSilent() ; m_Iterations = m_Iterations + 1 not used in this transform if @p_restart m_Product = (1,0) endif endfunc protected: complex m_Product default: title = "Running Product" int param p_method caption = "Method" enum = "Original" "Alternative" default = 0 hint = "The original method matches 'Iterate the Product' as used in \ various older mmf formulas." endparam bool param p_restart caption = "Reset the Product" default = false hint = "This is only for when the transform is used in a situation \ where there may be iteration skipping, for example in a \ colouring formula. If you enable this option then the product \ is reset to one each time iteration skipping occurs." endparam } class MMF_PowerFunctions(common.ulb:UserTransform) { ; fn(z)^power
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_PowerFunctions(Generic pparent) UserTransform.UserTransform(pparent) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform return @p_fn(pz)^@p_power endfunc default: title = "Power Functions" heading text = "Simply function(z)^power." endheading func p_fn caption = "Function to use" default = ident() hint = "For most applications it's best not to use 'cabs'." endfunc complex param p_power caption = "Power" default = (2,0) endparam } class MMF_SimpleMatrixTransform(common.ulb:UserTransform) { ; Transforms pz by a general 2*2 matrix.
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SimpleMatrixTransform(Generic pparent) UserTransform.UserTransform(pparent) endfunc ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SimpleMatrix(Generic pparent) UserTransform.UserTransform(pparent) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform return real(pz)*real(@p_r0) + imag(pz)*real(@p_r1) \ + flip(real(pz)*imag(@p_r0) + imag(pz)*imag(@p_r1)) endfunc default: title = "Simple Matrix Transform" heading text = "This matrix transform takes the form: \ z = x*Re(Row 0) + y*Re(Row 1) + flip(x*Im(Row 0) \ + y*Im(Row 1))." endheading complex param p_r0 caption = "Row 0" default = (1,0) hint = "Use (1,0) for the identity matrix." endparam complex param p_r1 caption = "Row 1" default = (0,1) hint = "Use (0,1) for the identity matrix." endparam } class MMF_OffsetMatrixTransform(common.ulb:UserTransform) { ; Transforms pz by an offset and a general 2*2 matrix.
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_OffsetMatrixTransform(Generic pparent) UserTransform.UserTransform(pparent) offset = @p_offset r0 = @p_r0 r1 = @p_r1 endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform pz = pz + offset return real(pz)*real(r0) + imag(pz)*real(r1) \ + flip(real(pz)*imag(r0) + imag(pz)*imag(r1)) endfunc complex offset complex r0 complex r1 default: title = "Offset Matrix Transform" heading text = "This matrix transform takes the form: \ z = x*Re(Row 0) + y*Re(Row 1) + flip(x*Im(Row 0) \ + y*Im(Row 1))." endheading complex param p_offset caption = "Offset" default = (0,0) endparam complex param p_r0 caption = "Row 0" default = (1,0) hint = "Use (1,0) for the identity matrix." endparam complex param p_r1 caption = "Row 1" default = (0,1) hint = "Use (0,1) for the identity matrix." endparam } class MMF_CrossProduct(MMF_TrapTransformZold) { ; Cross products involving z, zold and zolder
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_CrossProduct(Generic pparent) MMF_TrapTransformZold.MMF_TrapTransformZold(pparent) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this transform m_Solid = false m_zold = m_zolder = pz m_zoldok = m_zolderok = false endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform complex z1 = pz if @p_mode=="Z and Zold" && m_zoldok z1 = real(pz)*imag(m_zold) - flip(real(m_zold)*imag(pz)) elseif @p_mode=="Z and Zolder" && m_zolderok z1 = real(pz)*imag(m_zolder) - flip(real(m_zolder)*imag(pz)) elseif @p_mode=="Z-Zold and Z-Zolder" && m_zoldok && m_zolderok complex z2 = pz - m_zolder z1 = pz - m_zold z1 = real(z1)*imag(z2) - flip(real(z2)*imag(z1)) elseif @p_mode=="Z-Zold and Zold-Zolder" && m_zoldok && m_zolderok complex z2 = m_zold - m_zolder z1 = pz - m_zold z1 = real(z1)*imag(z2) - flip(real(z2)*imag(z1)) endif m_zolder = m_zold m_zold = pz m_zolderok = m_zoldok m_zoldok = true return z1 endfunc default: title = "Cross Product" heading text = "It may also be used in main formulas that allow iterative \ transforms such as Switch Formula Transformations in mmf.ulb." endheading int param p_mode caption = "Vectors to Cross" enum = "Z and Zold" "Z and Zolder" "Z-Zold and Z-Zolder" \ "Z-Zold and Zold-Zolder" default = 0 endparam } class MMF_UserFormulaTransform(common.ulb:UserTransform) { ; A roll-your-own formula
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_UserFormulaTransform(Generic pparent) UserTransform.UserTransform(pparent) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform complex z1 = @p_coeff1*@p_func1(pz)^@p_power1 if @p_numterms>0 z1 = z1 + @p_coeff2*@p_func2(pz)^@p_power2 endif if @p_numterms>1 z1 = z1 + @p_coeff3*@p_func3(pz)^@p_power3 endif if @p_numterms>2 z1 = z1 + @p_coeff4*@p_func4(pz)^@p_power4 endif if @p_numterms>3 z1 = z1 + @p_coeff5*@p_func5(pz)^@p_power5 endif if @p_numterms>4 z1 = z1 + @p_coeff6*@p_func6(pz)^@p_power6 endif if @p_numterms>5 z1 = z1 + @p_coeff7*@p_func7(pz)^@p_power7 endif if @p_numterms>6 z1 = z1 + @p_coeff8*@p_func8(pz)^@p_power8 endif if @p_numterms>7 z1 = z1 + @p_coeff9*@p_func9(pz)^@p_power9 endif if @p_numterms>8 z1 = z1 + @p_coeff10*@p_func10(pz)^@p_power10 endif return z1 endfunc default: title = "User Formula Transform" int param p_numterms caption = "Number of Terms" enum = "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" default = 0 endparam heading text = "The first term." endheading complex param p_coeff1 caption = "Coefficient 1" default = (1,0) hint = "The coefficient, c, in c*f(z)^p." endparam func p_func1 caption = "Function 1" default = ident() hint = "The function, f, in c*f(z)^p." endfunc complex param p_power1 caption = "Power 1" default = (1,0) hint = "The power, p, in c*f(z)^p." endparam heading text = "The second term." visible = @p_numterms>0 endheading complex param p_coeff2 caption = "Coefficient 2" default = (1,0) hint = "The coefficient, c, in c*f(z)^p." visible = @p_numterms>0 endparam func p_func2 caption = "Function 2" default = ident() hint = "The function, f, in c*f(z)^p." visible = @p_numterms>0 endfunc complex param p_power2 caption = "Power 2" default = (1,0) hint = "The power, p, in c*f(z)^p." visible = @p_numterms>0 endparam heading text = "The third term." visible = @p_numterms>1 endheading complex param p_coeff3 caption = "Coefficient 3" default = (1,0) hint = "The coefficient, c, in c*f(z)^p." visible = @p_numterms>1 endparam func p_func3 caption = "Function 3" default = ident() hint = "The function, f, in c*f(z)^p." visible = @p_numterms>1 endfunc complex param p_power3 caption = "Power 3" default = (1,0) hint = "The power, p, in c*f(z)^p." visible = @p_numterms>1 endparam heading text = "The fourth term." visible = @p_numterms>2 endheading complex param p_coeff4 caption = "Coefficient 4" default = (1,0) hint = "The coefficient, c, in c*f(z)^p." visible = @p_numterms>2 endparam func p_func4 caption = "Function 4" default = ident() hint = "The function, f, in c*f(z)^p." visible = @p_numterms>2 endfunc complex param p_power4 caption = "Power 4" default = (1,0) hint = "The power, p, in c*f(z)^p." visible = @p_numterms>2 endparam heading text = "The fifth term." visible = @p_numterms>3 endheading complex param p_coeff5 caption = "Coefficient 5" default = (1,0) hint = "The coefficient, c, in c*f(z)^p." visible = @p_numterms>3 endparam func p_func5 caption = "Function 5" default = ident() hint = "The function, f, in c*f(z)^p." visible = @p_numterms>3 endfunc complex param p_power5 caption = "Power 5" default = (1,0) hint = "The power, p, in c*f(z)^p." visible = @p_numterms>3 endparam heading text = "The sixth term." visible = @p_numterms>4 endheading complex param p_coeff6 caption = "Coefficient 6" default = (1,0) hint = "The coefficient, c, in c*f(z)^p." visible = @p_numterms>4 endparam func p_func6 caption = "Function 6" default = ident() hint = "The function, f, in c*f(z)^p." visible = @p_numterms>4 endfunc complex param p_power6 caption = "Power 6" default = (1,0) hint = "The power, p, in c*f(z)^p." visible = @p_numterms>4 endparam heading text = "The seventh term." visible = @p_numterms>5 endheading complex param p_coeff7 caption = "Coefficient 7" default = (1,0) hint = "The coefficient, c, in c*f(z)^p." visible = @p_numterms>5 endparam func p_func7 caption = "Function 7" default = ident() hint = "The function, f, in c*f(z)^p." visible = @p_numterms>5 endfunc complex param p_power7 caption = "Power 7" default = (1,0) hint = "The power, p, in c*f(z)^p." visible = @p_numterms>5 endparam heading text = "The eighth term." visible = @p_numterms>6 endheading complex param p_coeff8 caption = "Coefficient 8" default = (1,0) hint = "The coefficient, c, in c*f(z)^p." visible = @p_numterms>6 endparam func p_func8 caption = "Function 8" default = ident() hint = "The function, f, in c*f(z)^p." visible = @p_numterms>6 endfunc complex param p_power8 caption = "Power 8" default = (1,0) hint = "The power, p, in c*f(z)^p." visible = @p_numterms>6 endparam heading text = "The ninth term." visible = @p_numterms>7 endheading complex param p_coeff9 caption = "Coefficient 9" default = (1,0) hint = "The coefficient, c, in c*f(z)^p." visible = @p_numterms>7 endparam func p_func9 caption = "Function 9" default = ident() hint = "The function, f, in c*f(z)^p." visible = @p_numterms>7 endfunc complex param p_power9 caption = "Power 9" default = (1,0) hint = "The power, p, in c*f(z)^p." visible = @p_numterms>7 endparam heading text = "The tenth term." visible = @p_numterms>8 endheading complex param p_coeff10 caption = "Coefficient 10" default = (1,0) hint = "The coefficient, c, in c*f(z)^p." visible = @p_numterms>8 endparam func p_func10 caption = "Function 10" default = ident() hint = "The function, f, in c*f(z)^p." visible = @p_numterms>8 endfunc complex param p_power10 caption = "Power 10" default = (1,0) hint = "The power, p, in c*f(z)^p." visible = @p_numterms>8 endparam } class MMF_TransformAdd(common.ulb:UserTransform) { ; Adds the results of two transforms together
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_TransformAdd(Generic pparent) UserTransform.UserTransform(pparent) fTransform1 = new @p_Transform1(this) fTransform2 = new @p_Transform2(this) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this transform m_Solid = false fTransform1.Init(pz) fTransform2.Init(pz) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform return fTransform1.Iterate(pz) + fTransform2.Iterate(pz) endfunc private: Transform fTransform1 Transform fTransform2 default: title = "Transform Add" Transform param p_Transform1 caption = "First Transform" default = MMF_GeneralTransform hint = "The result of this is added to the result of 'Second Transform'." endparam Transform param p_Transform2 caption = "Second Transform" default = MMF_GeneralTransform hint = "The result of this is added to the result of 'First Transform'." endparam } class MMF_TransformSubtract(common.ulb:UserTransform) { ; Subtracts the result of one transform from another
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_TransformSubtract(Generic pparent) UserTransform.UserTransform(pparent) fTransform1 = new @p_Transform1(this) fTransform2 = new @p_Transform2(this) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this transform m_Solid = false fTransform1.Init(pz) fTransform2.Init(pz) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform return fTransform1.Iterate(pz) - fTransform2.Iterate(pz) endfunc private: Transform fTransform1 Transform fTransform2 default: title = "Transform Subtract" heading text = "Subtracts 'Second Transform' from 'First Transform'." endheading Transform param p_Transform1 caption = "First Transform" default = MMF_GeneralTransform hint = "The result of 'Second Transform' is subtracted from the \ result of this." endparam Transform param p_Transform2 caption = "Second Transform" default = MMF_GeneralTransform hint = "The result of this is subtracted from the result of \ 'First Transform'." endparam } class MMF_TransformMultiply(common.ulb:UserTransform) { ; Multiplies two transforms together
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_TransformMultiply(Generic pparent) UserTransform.UserTransform(pparent) fTransform1 = new @p_Transform1(this) fTransform2 = new @p_Transform2(this) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this transform m_Solid = false fTransform1.Init(pz) fTransform2.Init(pz) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform return fTransform1.Iterate(pz)*fTransform2.Iterate(pz) endfunc private: Transform fTransform1 Transform fTransform2 default: title = "Transform Multiply" Transform param p_Transform1 caption = "First Transform" default = MMF_GeneralTransform hint = "The result of this is multiplied by the result of \ 'Second Transform'." endparam Transform param p_Transform2 caption = "Second Transform" default = MMF_GeneralTransform hint = "The result of this is multiplied by the result of \ 'First Transform'." endparam } class MMF_TransformDivide(common.ulb:UserTransform) { ; Divides one transform by another
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_TransformDivide(Generic pparent) UserTransform.UserTransform(pparent) fTransform1 = new @p_Transform1(this) fTransform2 = new @p_Transform2(this) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this transform m_Solid = false fTransform1.Init(pz) fTransform2.Init(pz) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform return fTransform1.Iterate(pz)/fTransform2.Iterate(pz) endfunc private: Transform fTransform1 Transform fTransform2 default: title = "Transform Divide" heading text = "Divides 'First Transform' by 'Second Transform'." endheading Transform param p_Transform1 caption = "First Transform" default = MMF_GeneralTransform hint = "The result of this is divided by the result of \ 'Second Transform'. Note that when the result of \ the second transform is zero there may be unwanted \ consequences." endparam Transform param p_Transform2 caption = "Second Transform" default = MMF_GeneralTransform hint = "The result of 'First Transform' is divided by the \ result of this. Note that when the result of \ this transform is zero there may be unwanted \ consequences." endparam } class MMF_TransformSum(common.ulb:UserTransform) { ; Sums up to 10 transforms together (with coefficients)
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_TransformSum(Generic pparent) UserTransform.UserTransform(pparent) fTransform1 = new @p_Transform1(this) fTransform2 = new @p_Transform2(this) fTransform3 = new @p_Transform3(this) fTransform4 = new @p_Transform4(this) fTransform5 = new @p_Transform5(this) fTransform6 = new @p_Transform6(this) fTransform7 = new @p_Transform7(this) fTransform8 = new @p_Transform8(this) fTransform9 = new @p_Transform9(this) fTransform10 = new @p_Transform10(this) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this transform m_Solid = false fTransform1.Init(pz) fTransform2.Init(pz) fTransform3.Init(pz) fTransform4.Init(pz) fTransform5.Init(pz) fTransform6.Init(pz) fTransform7.Init(pz) fTransform8.Init(pz) fTransform9.Init(pz) fTransform10.Init(pz) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform complex zz = @p_coeff1*fTransform1.Iterate(pz) \ + @p_coeff2*fTransform2.Iterate(pz) if @p_numtrans=="3" || @p_numtrans=="4" || @p_numtrans=="5" \ || @p_numtrans=="6" || @p_numtrans=="7" || @p_numtrans=="8" \ || @p_numtrans=="9" || @p_numtrans=="10" zz = zz + @p_coeff3*fTransform3.Iterate(pz) endif if @p_numtrans=="4" || @p_numtrans=="5" \ || @p_numtrans=="6" || @p_numtrans=="7" || @p_numtrans=="8" \ || @p_numtrans=="9" || @p_numtrans=="10" zz = zz + @p_coeff4*fTransform4.Iterate(pz) endif if @p_numtrans=="5" \ || @p_numtrans=="6" || @p_numtrans=="7" || @p_numtrans=="8" \ || @p_numtrans=="9" || @p_numtrans=="10" zz = zz + @p_coeff5*fTransform5.Iterate(pz) endif if @p_numtrans=="6" || @p_numtrans=="7" || @p_numtrans=="8" \ || @p_numtrans=="9" || @p_numtrans=="10" zz = zz + @p_coeff6*fTransform6.Iterate(pz) endif if @p_numtrans=="7" || @p_numtrans=="8" \ || @p_numtrans=="9" || @p_numtrans=="10" zz = zz + @p_coeff7*fTransform7.Iterate(pz) endif if @p_numtrans=="8" || @p_numtrans=="9" || @p_numtrans=="10" zz = zz + @p_coeff8*fTransform8.Iterate(pz) endif if @p_numtrans=="9" || @p_numtrans=="10" zz = zz + @p_coeff9*fTransform8.Iterate(pz) endif if @p_numtrans=="10" zz = zz + @p_coeff10*fTransform8.Iterate(pz) endif return zz endfunc private: Transform fTransform1 Transform fTransform2 Transform fTransform3 Transform fTransform4 Transform fTransform5 Transform fTransform6 Transform fTransform7 Transform fTransform8 Transform fTransform9 Transform fTransform10 default: title = "Transform Sum" int param p_numtrans caption = "Number of terms" enum = "2" "3" "4" "5" "6" "7" "8" "9" "10" default = 0 hint = "Each transform term is multiplied by its coefficient \ and the results are summed together." endparam heading text = "The first term in the sum." endheading complex param p_coeff1 caption = "Coefficient 1" default = (1,0) hint = "The coefficient of the first term." endparam Transform param p_Transform1 caption = "First Transform" default = MMF_GeneralTransform endparam heading text = "The second term in the sum." endheading complex param p_coeff2 caption = "Coefficient 2" default = (1,0) hint = "The coefficient of the second term." endparam Transform param p_Transform2 caption = "Second Transform" default = MMF_GeneralTransform endparam heading text = "The third term in the sum." visible = @p_numtrans>0 endheading complex param p_coeff3 caption = "Coefficient 3" default = (1,0) hint = "The coefficient of the third term." visible = @p_numtrans>0 endparam Transform param p_Transform3 caption = "Third Transform" default = MMF_GeneralTransform visible = @p_numtrans>0 endparam heading text = "The fourth term in the sum." visible = @p_numtrans>1 endheading complex param p_coeff4 caption = "Coefficient 4" default = (1,0) hint = "The coefficient of the fourth term." visible = @p_numtrans>1 endparam Transform param p_Transform4 caption = "Fourth Transform" default = MMF_GeneralTransform visible = @p_numtrans>1 endparam heading text = "The fifth term in the sum." visible = @p_numtrans>2 endheading complex param p_coeff5 caption = "Coefficient 5" default = (1,0) hint = "The coefficient of the fifth term." visible = @p_numtrans>2 endparam Transform param p_Transform5 caption = "Fifth Transform" default = MMF_GeneralTransform visible = @p_numtrans>2 endparam heading text = "The sixth term in the sum." visible = @p_numtrans>3 endheading complex param p_coeff6 caption = "Coefficient 6" default = (1,0) hint = "The coefficient of the sixth term." visible = @p_numtrans>3 endparam Transform param p_Transform6 caption = "Sixth Transform" default = MMF_GeneralTransform visible = @p_numtrans>3 endparam heading text = "The seventh term in the sum." visible = @p_numtrans>4 endheading complex param p_coeff7 caption = "Coefficient 7" default = (1,0) hint = "The coefficient of the seventh term." visible = @p_numtrans>4 endparam Transform param p_Transform7 caption = "Seventh Transform" default = MMF_GeneralTransform visible = @p_numtrans>4 endparam heading text = "The eighth term in the sum." visible = @p_numtrans>5 endheading complex param p_coeff8 caption = "Coefficient 8" default = (1,0) hint = "The coefficient of the eighth term." visible = @p_numtrans>5 endparam Transform param p_Transform8 caption = "Eighth Transform" default = MMF_GeneralTransform visible = @p_numtrans>5 endparam heading text = "The ninth term in the sum." visible = @p_numtrans>6 endheading complex param p_coeff9 caption = "Coefficient 9" default = (1,0) hint = "The coefficient of the ninth term." visible = @p_numtrans>6 endparam Transform param p_Transform9 caption = "Ninth Transform" default = MMF_GeneralTransform visible = @p_numtrans>6 endparam heading text = "The tenth term in the sum." visible = @p_numtrans>7 endheading complex param p_coeff10 caption = "Coefficient 10" default = (1,0) hint = "The coefficient of the tenth term." visible = @p_numtrans>7 endparam Transform param p_Transform10 caption = "Tenth Transform" default = MMF_GeneralTransform visible = @p_numtrans>7 endparam } class MMF_TransformProduct(common.ulb:UserTransform) { ; Multiplies up to 10 transforms together (with powers)
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_TransformProduct(Generic pparent) UserTransform.UserTransform(pparent) fTransform1 = new @p_Transform1(this) fTransform2 = new @p_Transform2(this) fTransform3 = new @p_Transform3(this) fTransform4 = new @p_Transform4(this) fTransform5 = new @p_Transform5(this) fTransform6 = new @p_Transform6(this) fTransform7 = new @p_Transform7(this) fTransform8 = new @p_Transform8(this) fTransform9 = new @p_Transform9(this) fTransform10 = new @p_Transform10(this) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this transform m_Solid = false fTransform1.Init(pz) fTransform2.Init(pz) fTransform3.Init(pz) fTransform4.Init(pz) fTransform5.Init(pz) fTransform6.Init(pz) fTransform7.Init(pz) fTransform8.Init(pz) fTransform9.Init(pz) fTransform10.Init(pz) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform complex zz = fTransform1.Iterate(pz)^@p_power1 \ * fTransform2.Iterate(pz)^@p_power2 if @p_numtrans=="3" || @p_numtrans=="4" || @p_numtrans=="5" \ || @p_numtrans=="6" || @p_numtrans=="7" || @p_numtrans=="8" \ || @p_numtrans=="9" || @p_numtrans=="10" zz = zz * fTransform3.Iterate(pz)^@p_power3 endif if @p_numtrans=="4" || @p_numtrans=="5" \ || @p_numtrans=="6" || @p_numtrans=="7" || @p_numtrans=="8" \ || @p_numtrans=="9" || @p_numtrans=="10" zz = zz * fTransform4.Iterate(pz)^@p_power4 endif if @p_numtrans=="5" \ || @p_numtrans=="6" || @p_numtrans=="7" || @p_numtrans=="8" \ || @p_numtrans=="9" || @p_numtrans=="10" zz = zz * fTransform5.Iterate(pz)^@p_power5 endif if @p_numtrans=="6" || @p_numtrans=="7" || @p_numtrans=="8" \ || @p_numtrans=="9" || @p_numtrans=="10" zz = zz * fTransform6.Iterate(pz)^@p_power6 endif if @p_numtrans=="7" || @p_numtrans=="8" \ || @p_numtrans=="9" || @p_numtrans=="10" zz = zz * fTransform7.Iterate(pz)^@p_power7 endif if @p_numtrans=="8" || @p_numtrans=="9" || @p_numtrans=="10" zz = zz * fTransform8.Iterate(pz)^@p_power8 endif if @p_numtrans=="9" || @p_numtrans=="10" zz = zz * fTransform9.Iterate(pz)^@p_power9 endif if @p_numtrans=="10" zz = zz * fTransform10.Iterate(pz)^@p_power10 endif return zz endfunc private: Transform fTransform1 Transform fTransform2 Transform fTransform3 Transform fTransform4 Transform fTransform5 Transform fTransform6 Transform fTransform7 Transform fTransform8 Transform fTransform9 Transform fTransform10 default: title = "Transform Product" int param p_numtrans caption = "Number of terms" enum = "2" "3" "4" "5" "6" "7" "8" "9" "10" default = 0 hint = "Each transform term is raised to its power \ and the results are multiplied together." endparam heading text = "The first term in the product." endheading complex param p_power1 caption = "Power 1" default = (1,0) hint = "The power of the first term." endparam Transform param p_Transform1 caption = "First Transform" default = MMF_GeneralTransform endparam heading text = "The second term in the product." endheading complex param p_power2 caption = "Power 2" default = (1,0) hint = "The power of the second term." endparam Transform param p_Transform2 caption = "Second Transform" default = MMF_GeneralTransform endparam heading text = "The third term in the product." visible = @p_numtrans>0 endheading complex param p_power3 caption = "Power 3" default = (1,0) hint = "The power of the third term." visible = @p_numtrans>0 endparam Transform param p_Transform3 caption = "Third Transform" default = MMF_GeneralTransform visible = @p_numtrans>0 endparam heading text = "The fourth term in the product." visible = @p_numtrans>1 endheading complex param p_power4 caption = "Power 4" default = (1,0) hint = "The power of the fourth term." visible = @p_numtrans>1 endparam Transform param p_Transform4 caption = "Fourth Transform" default = MMF_GeneralTransform visible = @p_numtrans>1 endparam heading text = "The fifth term in the product." visible = @p_numtrans>2 endheading complex param p_power5 caption = "Power 5" default = (1,0) hint = "The power of the fifth term." visible = @p_numtrans>2 endparam Transform param p_Transform5 caption = "Fifth Transform" default = MMF_GeneralTransform visible = @p_numtrans>2 endparam heading text = "The sixth term in the product." visible = @p_numtrans>3 endheading complex param p_power6 caption = "Power 6" default = (1,0) hint = "The power of the sixth term." visible = @p_numtrans>3 endparam Transform param p_Transform6 caption = "Sixth Transform" default = MMF_GeneralTransform visible = @p_numtrans>3 endparam heading text = "The seventh term in the product." visible = @p_numtrans>4 endheading complex param p_power7 caption = "Power 7" default = (1,0) hint = "The power of the seventh term." visible = @p_numtrans>4 endparam Transform param p_Transform7 caption = "Seventh Transform" default = MMF_GeneralTransform visible = @p_numtrans>4 endparam heading text = "The eighth term in the product." visible = @p_numtrans>5 endheading complex param p_power8 caption = "Power 8" default = (1,0) hint = "The power of the eighth term." visible = @p_numtrans>5 endparam Transform param p_Transform8 caption = "Eighth Transform" default = MMF_GeneralTransform visible = @p_numtrans>5 endparam heading text = "The ninth term in the product." visible = @p_numtrans>6 endheading complex param p_power9 caption = "Power 9" default = (1,0) hint = "The power of the ninth term." visible = @p_numtrans>6 endparam Transform param p_Transform9 caption = "Ninth Transform" default = MMF_GeneralTransform visible = @p_numtrans>6 endparam heading text = "The tenth term in the product." visible = @p_numtrans>7 endheading complex param p_power10 caption = "Power 10" default = (1,0) hint = "The power of the tenth term." visible = @p_numtrans>7 endparam Transform param p_Transform10 caption = "Tenth Transform" default = MMF_GeneralTransform visible = @p_numtrans>7 endparam } class MMF_TransformPowerFunctions(common.ulb:UserTransform) { ; fn(transform)^power
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_TransformPowerFunctions(Generic pparent) UserTransform.UserTransform(pparent) fTransform = new @p_Transform(this) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this transform m_Solid = false fTransform.Init(pz) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform return @p_fn(fTransform.Iterate(pz))^@p_power endfunc private: Transform fTransform default: title = "Transform Power Functions" func p_fn caption = "Function to use" default = ident() hint = "For most applications it's best not to use 'cabs'." endfunc complex param p_power caption = "Power" default = (2,0) endparam Transform param p_Transform caption = "Transform" default = MMF_GeneralTransform endparam } class MMF_FormulaTransform(common.ulb:UserTransform) { ; Allows the use of any object main formula as a transform
public: import "common.ulb" import "Standard.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_FormulaTransform(Generic pparent) UserTransform.UserTransform(pparent) fFormula = new @p_Formula(this) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this transform m_Solid = false fFormula.Init(pz) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform return fFormula.Iterate(pz) endfunc private: Formula fFormula default: title = "Any Formula" heading text = "Choose any main formula to be used as the transform, not \ all formulas will produce good results. Note that some of \ the main formula parameters will be superfluos, such as any \ bailout value/s." endheading Formula param p_Formula caption = "Formula" default = Standard_Mandelbrot hint = "The normal iterative function of the chosen formula is used as \ the transform." endparam } class MMF_SwitchTransformFormula(MMF_SwitchFormula) { ; Any Transform applied as a formula.
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SwitchTransformFormula(Generic pparent) MMF_SwitchFormula.MMF_SwitchFormula(pparent) fTransform = new @classTransform(this) endfunc complex func Init(complex pz) ; m_Iterations = 0 not used in this formula m_BailedOut = false if @p_initold=="Fixed Value" fZold = @p_zold elseif @p_initold=="Position" fZold = pz elseif @p_initold=="Start Value" if fType if @p_addpixel fZold = fValue + pz else fZold = fValue endif else fZold = pz endif else;if @p_initold=="Constant" if fType fZold = pz else fZold = fConstant endif endif fTransform.Init(pz) if fType fConstant = pz if @p_addpixel return fValue + fConstant else return fValue endif else return pz endif endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this formula complex zz = fTransform.Iterate(pz) if @p_type=="tx(z)+c" zz = zz + fConstant elseif @p_type=="c*tx(z)" return fConstant*zz elseif @p_type=="tx(z)+zold+c" zz = zz + fZold + fConstant elseif @p_type=="c*tx(z)+zold" zz = fConstant*zz + fZold elseif @p_type=="zold*tx(z)+c" zz = fZold*zz + fConstant else;if @p_type=="c*zold*tx(z)" zz = fConstant*fZold*zz endif fZold = pz return zz endfunc bool func IsBailedOut(complex pz) if ((@p_BailType=="Divergent" || @p_BailType=="Both" \ || @p_BailType=="Div.+Abs.Conv.") \ && |pz|>=@p_Bailout) \ || ((@p_BailType=="Convergent" || @p_BailType=="Both") \ && |pz-fZold|<=@p_SmallBail) \ || ((@p_BailType=="Absolute Convergence" \ || @p_BailType=="Div.+Abs.Conv.") \ && |pz-@p_root|<=@p_SmallBail ) m_BailedOut = true endif return m_BailedOut endfunc float func GetUpperBailout() return @p_Bailout endfunc float func GetLowerBailout() return @p_SmallBail endfunc protected: UserTransform fTransform complex fZold default: title = "Switch Transform Formula" rating = recommended int param v_mmfswitchtransformformula caption = "Version (MMF_SwitchTransformFormula)" default = 100 hint = "This version parameter is used to detect when a change has \ been made to the formula that is incompatible with the \ previous version. When that happens, this field will reflect \ the old version number to alert you to the fact that an \ alternate rendering is being used." visible = @v_mmfswitchtransformformula < 100 endparam complex param p_power visible = false endparam bool param p_addpixel caption = "Offset z start" default = false hint = "When enabled the z start value (in Mandelbrot mode) is offset \ by the constant for the current position - normally '#pixel'." visible = !@p_manual || @p_mandy endparam heading caption = "Bailout Options" endheading int param p_BailType caption = "Bailout Type" enum = "Divergent" "Convergent" "Both" "Absolute Convergence" \ "Div.+Abs.Conv." default = 0 hint = "If you get an empty or nearly empty fractal try switching \ from 'Divergent' to 'Convergent' or vice-versa or choosing \ 'Both'. Note that in some cases if your fractal is a \ Mandelbrot you may need to ensure that the zstart value \ is non-zero." endparam complex param p_root caption = "Convergence Value" default = (1,0) hint = "This is the value for testing for convergence to. For the \ 'Magnet' formulas the value should be (1,0), if you don't \ know the value to use it's best to stick to the plain \ 'Convergent' 'Bailout Type'. It's always worth trying (0,0)." visible = @p_BailType>2 endparam float param p_Bailout caption = "Divergent Bailout" default = 128.0 hint = "In general larger values will require higher iterations." visible = @p_BailType==0 || @p_BailType==2 || @p_BailType==4 endparam float param p_SmallBail caption = "Convergent Bailout" default = 1e-5 hint = "In general smaller values will require higher iterations." visible = @p_BailType>0 endparam heading caption = "The Formula method" endheading int param p_type caption = "Fractal Type" enum = "tx(z)+c" "c*tx(z)" "tx(z)+zold+c" "c*tx(z)+zold" \ "zold*tx(z)+c" "c*zold*tx(z)" default = 0 endparam int param p_initold caption = "Initial Zold" enum = "Fixed Value" "Position" "Start Value" "Constant" default = 0 endparam complex param p_zold caption = "Initial Zold Value" default = (0,0) visible = @p_initold==0 endparam heading caption = "The Formula Transform" text = "Transforms z on each iteration." endheading UserTransform param classTransform caption = "The Transform" default = MMF_PowerFunctions hint = "Transforms z on each iteration. To use multiple \ transforms select 'Transform Merge' from common.ulb." endparam } class MMF_Constant(common.ulb:UserTransform) { ; returns a user constant, whatever the value of pz
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_Constant(Generic pparent) UserTransform.UserTransform(pparent) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this transform m_Solid = false endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform return @p_constant endfunc default: title = "Constant Value" complex param p_constant caption = "The Constant" default = (1,0) endparam } class MMF_Scale(common.ulb:UserTransform) { ; Simply scales pz by the user scale value.
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_Scale(Generic pparent) UserTransform.UserTransform(pparent) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this transform m_Solid = false endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform return @p_scale*pz endfunc default: title = "Simple Scale" complex param p_scale caption = "The Scale" default = (1,0) endparam } class MMF_Linear(common.ulb:UserTransform) { ; Simple linear transform
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_Linear(Generic pparent) UserTransform.UserTransform(pparent) endfunc func Init(complex pz) ; m_Iterations = 0 not used in this transform m_Solid = false endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform return @p_scale*pz + @p_constant endfunc default: title = "Linear" complex param p_scale caption = "The Scale" default = (1,0) hint = "The scale, s, in s*z + c." endparam complex param p_constant caption = "The Constant" default = (0,0) hint = "The constant, c, in s*z + c." endparam } class MMF_GammaTransform(common.ulb:UserTransform) { ; Complex Gamma(z)
public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_GammaTransform(Generic pparent) UserTransform.UserTransform(pparent) endfunc complex func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 not used in this transform return Math.ComplexGamma(pz) endfunc default: title = "Gamma Transform" } class MMF_SwitchBeta(MMF_SwitchDivergentFormula) { ; ; Switchable Beta(z,c).
; public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_SwitchBeta(Generic pparent) MMF_SwitchDivergentFormula.MMF_SwitchDivergentFormula(pparent) endfunc complex func Iterate(complex pz) return Math.ComplexBeta(pz,fConstant) endfunc default: title = "Switch Beta" bool param p_addpixel caption = "Offset z start" default = true hint = "When enabled the z start value (in Mandelbrot mode) is offset \ by the constant for the current position - normally '#pixel'." visible = !@p_manual || @p_mandy endparam complex param p_power visible = false endparam } class Contraction(common.ulb:Generic) { ; Contraction base class. public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func Contraction(Generic pparent) Generic.Generic(pparent) endfunc ; @param pz ; @param pc func Init(complex pz, complex pc) endfunc ; @param pz ; @param pc ; @return the contracted value complex func Iterate(complex pz, complex pc) return pz endfunc default: int param v_contraction caption = "Version (Contraction)" default = 100 hint = "This version parameter is used to detect when a change has \ been made to the formula that is incompatible with the \ previous version. When that happens, this field will reflect \ the old version number to alert you to the fact that an \ alternate rendering is being used." visible = @v_contraction < 100 endparam } class DistanceEstimatorBase(common.ulb:GradientColoring) { ; Distance Estimator base class. public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func DistanceEstimatorBase(Generic pparent) GradientColoring.GradientColoring(pparent) endfunc ; @param pz ; @return the distance float func ResultDistance(complex pz) return real(pz) endfunc ; @param pz ; @return the angle (from 0 to 1) float func ResultAngle(complex pz) return real(pz) endfunc protected: complex dz default: int param v_distanceestimatorbase caption = "Version (Distance Estimator Base)" default = 100 hint = "This version parameter is used to detect when a change has \ been made to the formula that is incompatible with the \ previous version. When that happens, this field will reflect \ the old version number to alert you to the fact that an \ alternate rendering is being used." visible = @v_distanceestimatorbase < 100 endparam } class MMF_NewtonDistanceEstimator(DistanceEstimatorBase) { ; Distance Estimator for Newton formulas solving z^p-c. public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_NewtonDistanceEstimator(Generic pparent) DistanceEstimatorBase.DistanceEstimatorBase(pparent) endfunc ; @param pz ; @param ppixel func Init(complex pz, complex ppixel) DistanceEstimatorBase.Init(pz, ppixel) zold = pz odz = 1.0 dz = (@power - 1.0)/@power - @root*(@power - 1.0)*pz^(@power - 2.0) \ /(@power*pz^(2.0*(@power - 1.0))) endfunc ; @param pz func Iterate(complex pz) m_Iterations = m_Iterations + 1 zold = pz odz = dz dz = dz *((@power - 1.0)/@power - @root*(@power - 1.0)*pz^(@power - 2.0) \ /(@power*pz^(2.0*(@power - 1.0)))) endfunc ; @param pz ; @return the gradient index float func ResultIndex(complex pz) float a = 0.0 float d = 0.0 complex zv = pz - zold complex dzv = 1.0/(dz - odz) if @mode=="Angle" || @mode=="Combined" if (a = atan2(zv*dzv)*(0.5/#pi))<0.0 a = a + 1.0 endif if @mode=="Angle" return a endif endif if @mode=="Distance" || @mode=="Combined" d = 0.5*cabs((@power - 1.0)*zv) d = -d*log(d)*cabs(dzv) if @mode=="Distance" return d endif endif return a+d endfunc ; @param pz ; @return the distance float func ResultDistance(complex pz) float v = 0.5*cabs((@power - 1.0)*(pz - zold)) return -v*log(v)/cabs(dz-odz) endfunc ; @param pz ; @return the angle (from 0 to 1) float func ResultAngle(complex pz) float r if (r=atan2((pz-zold)/(dz-odz))*(0.5/#pi))<0.0 r = r + 1.0 endif return r endfunc protected: complex zold complex odz default: title = "MMF Newton Distance Estimator" int param v_mmf_newtondistanceestimator caption = "Version (MMF Newton Distance Estimator)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam int param mode caption = "Mode" enum = "Distance" "Angle" "Combined" default = 0 endparam complex param power caption = "Power (p in z^p-r)" default = (3,0) endparam complex param root caption = "Root (r in z^p-r)" default = (1,0) endparam } class MMF_Magnet1DistanceEstimator(DistanceEstimatorBase) { ; Distance Estimator for the Magnet 1 formula. public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_Magnet1DistanceEstimator(Generic pparent) DistanceEstimatorBase.DistanceEstimatorBase(pparent) endfunc ; @param pz ; @param ppixel func Init(complex pz, complex ppixel) DistanceEstimatorBase.Init(pz, ppixel) zold = pz odz = 1.0 if @fixit complex fz = 0.0 complex gz = 0.0 if @julia fz = sqr(pz) + (@seed - 1.0) gz = 2.0*pz + (@seed - 2.0) else fz = sqr(pz) + (m_Pixel - 1.0) gz = 2.0*pz + (m_Pixel - 2.0) endif complex dfz = 2.0*pz complex dgz = 2.0 dz = 2.0*fz*(dfz*gz - fz*dgz)/gz^3.0 elseif @julia dz = (2.0*sqr(pz) + (2.0*@seed - 4.0)*pz - 2.0*@seed + 2.0) \ /sqr(2.0*pz + @seed - 2.0) else dz = (2.0*sqr(pz) + (2.0*m_Pixel - 4.0)*pz - 2.0*m_Pixel + 2.0) \ /sqr(2.0*pz + m_Pixel - 2.0) endif endfunc ; @param pz func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 zold = pz odz = dz if @fixit complex fz = 0.0 complex gz = 0.0 if @julia fz = sqr(pz) + (@seed - 1.0) gz = 2.0*pz + (@seed - 2.0) else fz = sqr(pz) + (m_Pixel - 1.0) gz = 2.0*pz + (m_Pixel - 2.0) endif complex dfz = 2.0*pz complex dgz = 2.0 dz = dz*2.0*fz*(dfz*gz - fz*dgz)/gz^3.0 elseif @julia dz = dz*((2.0*sqr(pz) + (2.0*@seed - 4.0)*pz - 2.0*@seed + 2.0) \ /sqr(2.0*pz + @seed - 2.0)) else dz = dz*((2.0*sqr(pz) + (2.0*m_Pixel - 4.0)*pz - 2.0*m_Pixel + 2.0) \ /sqr(2.0*pz + m_Pixel - 2.0)) endif endfunc ; @param pz ; @return the gradient index float func ResultIndex(complex pz) float a = 0.0 float d = 0.0 complex zv = pz - zold if |zv|<1.0 && @method!=1 if @modec=="Angle" || @modec=="Combined" if (a = atan2(zv/(dz-odz))*(0.5/#pi))<0.0 a = a + 1.0 endif if @modec=="Angle" return a endif endif if @modec=="Distance" || @modec=="Combined" if @fixit d = cabs(zv) d = -d*log(d)/cabs(dz-odz) else d = |(dz-odz)/zv|^0.0625 ; Note that this is from trial and error endif if @modec=="Distance" return d endif endif elseif @method>0 && |zv|>=1.0 if @mode=="Angle" || @mode=="Combined" if @fixit if (a = atan2(pz/dz)*(0.5/#pi))<0.0 a = a + 1.0 endif elseif (a = atan2(dz)*(0.5/#pi))<0.0 a = a + 1.0 endif if @mode=="Angle" return a endif endif if @mode=="Distance" || @mode=="Combined" if @fixit d = cabs(pz) d = d*log(d)/cabs(dz) else ; again from trial and error: d = ((1.0-log(0.5*log(|@bailout|))+log(0.5*log(|pz|)))*|dz|)^0.0625 endif if @mode=="Distance" return d endif endif else m_Solid = true endif return a+d endfunc ; @param pz ; @return the distance float func ResultDistance(complex pz) if |pz-zold|<1.0 if @fixit float d = cabs(pz-zold) return -d*log(d)/cabs(dz-odz) endif return |(dz-odz)/(pz-zold)|^0.0625 ; Note that this is from trial and error else if @fixit float d = cabs(pz) return d*log(d)/cabs(dz) endif return ((1.0-log(0.5*log(|@bailout|))+log(0.5*log(|pz|)))*|dz|)^0.0625 endif endfunc ; @param pz ; @return the angle (from 0 to 1) float func ResultAngle(complex pz) float r = 0.0 if |pz-zold|<1.0 if (r=atan2((pz-zold)/(dz-odz))*(0.5/#pi))<0.0 r = r + 1.0 endif else if @fixit r = atan2(pz/dz)*(0.5/#pi) else r = atan2(dz)*(0.5/#pi) endif if r<0.0 r = r + 1.0 endif endif return r endfunc protected: complex zold complex odz default: title = "MMF Magnet 1 Distance Estimator" int param v_mmf_magnet1distanceestimator caption = "Version (MMF Magnet 1 Distance Estimator)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam heading text = "Note that this colouring is only based on distance estimation, \ it's not accurate at true distance estimation." endheading bool param fixit caption = "Fix the DE" default = false hint = "When enabled the colouring is closer to true distance estimation \ but less useful for image mapping." endparam bool param julia caption = "Julia ?" default = false hint = "Enable when the main formula is a Julia." endparam complex param seed caption = "Julia Seed" default = (0,0) hint = "Set to the value of the Julia seed in the main formula." visible = @julia endparam int param method caption = "Method" enum = "Convergent" "Divergent" "Both" default = 2 hint = "When plugged into 'MMF Field Estimator' you should use 'Both'." endparam int param modec caption = "Convergent Mode" enum = "Distance" "Angle" "Combined" default = 0 visible = @method!=1 endparam int param mode caption = "Divergent Mode" enum = "Distance" "Angle" "Combined" default = 0 visible = @method>0 endparam float param bailout caption = "Divergent Bailout" default = 1e20 visible = @method>0 endparam } class MMF_Magnet2DistanceEstimator(DistanceEstimatorBase) { ; Distance Estimator for the Magnet 2 formula. public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_Magnet2DistanceEstimator(Generic pparent) DistanceEstimatorBase.DistanceEstimatorBase(pparent) endfunc ; @param pz ; @param ppixel func Init(complex pz, complex ppixel) DistanceEstimatorBase.Init(pz, ppixel) complex fz = (0,0) complex gz = (0,0) complex dfz = (0,0) complex dgz = (0,0) zold = pz odz = 1.0 ; Note that the running derivative calculation could be optimised if @julia fz = pz^3.0 + (3.0*(@seed - 1.0))*pz + ((@seed - 1.0)*(@seed - 2.0)) gz = 3.0*sqr(pz) + (3.0*(@seed - 2.0))*pz \ + ((@seed - 1.0)*(@seed - 2.0)) + 1.0 dfz = 3.0*sqr(pz) + (3.0*(@seed - 1.0)) dgz = 6.0*pz + (3.0*(@seed - 2.0)) else fz = pz^3.0 + (3.0*(m_Pixel - 1.0))*pz + ((m_Pixel - 1.0)*(m_Pixel - 2.0)) gz = 3.0*sqr(pz) + (3.0*(m_Pixel - 2.0))*pz \ + ((m_Pixel - 1.0)*(m_Pixel - 2.0)) + 1.0 dfz = 3.0*sqr(pz) + (3.0*(m_Pixel - 1.0)) dgz = 6.0*pz + (3.0*(m_Pixel - 2.0)) endif dz = fz*(dfz*gz - fz*dgz)/gz^3.0 if @fixit dz = 2.0*dz endif endfunc ; @param pz func Iterate(complex pz) if @fixit m_Iterations = m_Iterations + 1 endif complex fz = (0,0) complex gz = (0,0) complex dfz = (0,0) complex dgz = (0,0) zold = pz odz = dz if @julia fz = pz^3.0 + (3.0*(@seed - 1.0))*pz + ((@seed - 1.0)*(@seed - 2.0)) gz = 3.0*sqr(pz) + (3.0*(@seed - 2.0))*pz \ + ((@seed - 1.0)*(@seed - 2.0)) + 1.0 dfz = 3.0*sqr(pz) + (3.0*(@seed - 1.0)) dgz = 6.0*pz + (3.0*(@seed - 2.0)) else fz = pz^3.0 + (3.0*(m_Pixel - 1.0))*pz + ((m_Pixel - 1.0)*(m_Pixel - 2.0)) gz = 3.0*sqr(pz) + (3.0*(m_Pixel - 2.0))*pz \ + ((m_Pixel - 1.0)*(m_Pixel - 2.0)) + 1.0 dfz = 3.0*sqr(pz) + (3.0*(m_Pixel - 1.0)) dgz = 6.0*pz + (3.0*(m_Pixel - 2.0)) endif dz = dz*fz*(dfz*gz - fz*dgz)/gz^3.0 if @fixit dz = 2.0*dz endif endfunc ; @param pz ; @return the gradient index float func ResultIndex(complex pz) float a = 0.0 float d = 0.0 complex zv = pz - zold if |zv|<1.0 && @method!=1 if @modec=="Angle" || @modec=="Combined" if (a = atan2(zv/(dz-odz))*(0.5/#pi))<0.0 a = a + 1.0 endif if @modec=="Angle" return a endif endif if @modec=="Distance" || @modec=="Combined" if @fixit d = cabs(zv) d = -d*log(d)/cabs(dz-odz) else d = 3.0*|(dz-odz)/zv^@cfudge|^0.03125 ; Note that this is from trial and error endif if @modec=="Distance" return d endif endif elseif @method>0 && |zv|>=1.0 if @mode=="Angle" || @mode=="Combined" if (a = atan2(pz/dz)*(0.5/#pi))<0.0 a = a + 1.0 endif if @mode=="Angle" return a endif endif if @mode=="Distance" || @mode=="Combined" if @fixit d = cabs(pz*log(pz)/dz) if m_Iterations>0 a = cabs(zold*log(zold)/odz) d = d + (d - a)*(log(0.5*log(@bailout))-log(0.5*log(|pz|))) \ /log(log(|pz|)/log(|zold|)) endif else ; again from trial and error: d = |dz/pz|^0.0625 endif if @mode=="Distance" return d endif endif else m_Solid = true endif return a+d endfunc ; @param pz ; @return the distance float func ResultDistance(complex pz) if |pz-zold|<1.0 if @fixit float d = cabs(pz-zold) return -d*log(d)/cabs(dz-odz) else return 3.0*|(dz-odz)/(pz-zold)^@cfudge|^0.03125 ; Note that this is from trial and error endif else if @fixit float d = cabs(pz*log(pz)/dz) if m_Iterations>0 float a = cabs(zold*log(zold)/odz) d = d + (d - a)*(log(0.5*log(@bailout))-log(0.5*log(|pz|))) \ /log(log(|pz|)/log(|zold|)) endif return d else return |dz/pz|^0.0625 endif endif endfunc ; @param pz ; @return the angle (from 0 to 1) float func ResultAngle(complex pz) float r = 0.0 if |pz-zold|<1.0 if (r=atan2((pz-zold)/(dz-odz))*(0.5/#pi))<0.0 r = r + 1.0 endif elseif (r = atan2(pz/dz)*(0.5/#pi))<0.0 r = r + 1.0 endif return r endfunc protected: complex zold complex odz default: title = "MMF Magnet 2 Distance Estimator" int param v_mmf_magnet2distanceestimator caption = "Version (MMF Magnet 2 Distance Estimator)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam heading text = "Note that this colouring is only based on distance estimation, \ it's not accurate at true distance estimation." endheading bool param julia caption = "Julia ?" default = false hint = "Enable when the main formula is a Julia." endparam complex param seed caption = "Julia Seed" default = (0,0) hint = "Set to the value of the Julia seed in the main formula." visible = @julia endparam bool param fixit caption = "True DE" default = false hint = "When enabled the distance modes are much closer to true \ distance estimation however this is probably not as useful \ a colouring method for image mapping as the default." endparam int param method caption = "Method" enum = "Convergent" "Divergent" "Both" default = 2 hint = "When plugged into 'MMF Field Estimator' you should use 'Both'." endparam int param modec caption = "Convergent Mode" enum = "Distance" "Angle" "Combined" default = 0 visible = @method!=1 endparam float param cfudge caption = "Convergent Adjust" default = 0.962 hint = "Use to remove iteration breaks." visible = @method!=1 && @modec!=1 && !@fixit endparam int param mode caption = "Divergent Mode" enum = "Distance" "Angle" "Combined" default = 0 visible = @method>0 endparam float param bailout caption = "Divergent Bailout" default = 65536.0 visible = @method>0 endparam } class MMF_NovaDistanceEstimator(DistanceEstimatorBase) { ; Distance Estimator for the Nova formula. public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_NovaDistanceEstimator(Generic pparent) DistanceEstimatorBase.DistanceEstimatorBase(pparent) endfunc ; @param pz ; @param ppixel func Init(complex pz, complex ppixel) DistanceEstimatorBase.Init(pz, ppixel) zold = pz odz = 1.0 ; Note that the running derivative calculation could be optimised if @julia complex fz = (@power - @relax)*pz^@power + @relax complex gz = @power*pz^(@power - 1.0) complex dfz = @power*(@power - @relax)*pz^(@power - 1.0) complex dgz = @power*(@power - 1.0)*pz^(@power - 2.0) dz = (dfz*gz - fz*dgz)/sqr(gz) else dz = 1.0 endif endfunc ; @param pz func Iterate(complex pz) ; m_Iterations = m_Iterations + 1 complex fz = (@power - @relax)*pz^@power + @relax complex gz = @power*pz^(@power - 1.0) complex dfz = @power*(@power - @relax)*pz^(@power - 1.0) complex dgz = @power*(@power - 1.0)*pz^(@power - 2.0) zold = pz odz = dz dz = dz*(dfz*gz - fz*dgz)/sqr(gz) endfunc ; @param pz ; @return the gradient index float func ResultIndex(complex pz) float a = 0.0 float d = 0.0 pz = pz - zold dz = dz - odz if @modec=="Angle" || @modec=="Combined" if (a = atan2(pz/dz)*(0.5/#pi))<0.0 a = a + 1.0 endif if @modec=="Angle" return a endif endif if @modec=="Distance" || @modec=="Combined" if @fixit && @julia d = 0.5*cabs((@power - 1.0)*pz) d = -d*log(d)/cabs(dz) else d = cabs(pz/dz) endif if @modec=="Distance" return d endif endif return a+d endfunc ; @param pz ; @return the distance float func ResultDistance(complex pz) if @fixit && @julia float v = 0.5*cabs((@power - 1.0)*(pz - zold)) return -v*log(v)/cabs(dz-odz) endif return cabs((pz-zold)/(dz-odz)) endfunc ; @param pz ; @return the angle (from 0 to 1) float func ResultAngle(complex pz) float r = 0.0 if (r=atan2((pz-zold)/(dz-odz))*(0.5/#pi))<0.0 r = r + 1.0 endif return r endfunc protected: complex zold complex odz default: title = "MMF Nova Distance Estimator" int param v_mmf_novadistanceestimator caption = "Version (MMF Nova Distance Estimator)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam heading text = "Note that this colouring is only based on distance estimation, \ it's not really accurate at true distance estimation." endheading bool param julia caption = "Julia ?" default = false hint = "Enable when the main formula is a Julia." endparam bool param fixit caption = "Fix Julias ?" default = false hint = "When enabled the DE is better for some Julia Sets." visible = @julia endparam int param modec caption = "Mode" enum = "Distance" "Angle" "Combined" default = 0 endparam complex param power caption = "Nova Power" default = (3,0) hint = "This should match the power in the main formula." endparam complex param relax caption = "Relaxation" default = (1,0) hint = "This should match the relaxation in the main formula." endparam } class MMF_StandardDistanceEstimator(DistanceEstimatorBase) { ; Distance Estimator for formulas of the form z^p+c. ; ; Derivative using the chain rule (f,g,h are functions) ; ; f = g(h) ; f' = g'(h).h' ; ; leads to ; dz = f'(z).dz ; ; Second derivative using the product rule ; ; f'' = g''(h)h'^2 + g'(h).h'' ; ; leads to ; d2z = f''(z).dz^2 + f'(z).d2z ; Public: import "common.ulb" ; @param pparent the parent, generally "this" for the parent, or zero func MMF_StandardDistanceEstimator(Generic pparent) DistanceEstimatorBase.DistanceEstimatorBase(pparent) if @doper \ && (@addperiod || (@passedtype && @passedposition && @addposition)) pertrans = new @pertrans(this) if @addperiod periodtrans = new @periodtrans(this) endif if @passedtype && @passedposition && @addposition postrans = new @postrans(this) endif endif endfunc ; @param pz ; @param ppixel func Init(complex pz, complex ppixel) DistanceEstimatorBase.Init(pz, ppixel) sz = dz = 1.0 if @v_mmf_standarddistanceestimator=="1.0" if @julia && @mode=="Angle" sz = @power*pz^(@power - 1) m_Iterations = 1 endif else type = -1 if @passedtype float m = abs(real(pz)) float n = 2.0^ceil(log(m)/log(2.0)-9.0) type = floor(m/n) m = 512.0*(m - n*type) type = type - 256 if real(pz)<0.0 m = -m endif pz = m + flip(imag(#z)) if (@passedpoint && type==1) || (@passedposition && type>1) ;; recover the point or position and original imaginary value of #z m = abs(imag(pz)) n = 2.0^ceil(log(m)/log(2.0)-9.0) p = floor(m/n) m = 512.0*(m - n*p) p = p - 257 if imag(pz)<0.0 m = -m endif pz = real(pz) + flip(m) endif endif if @doper && (@addperiod \ || (@passedtype && @passedposition && @addposition && type>1)) pertrans.Init(pz) if @addperiod periodtrans.Init(pz) endif if @passedtype && @passedposition && @addposition && type>1 postrans.Init(pz) endif endif zold = pz odz = 1.0;= d2z = od2z = s2z = 1.0 if @julia sz = @power*pz^(@power - 1.0) m_Iterations = 1 endif if @doper zvals[0] = pz dzvals[0] = dz count = 1 endif endif endfunc ; @param pz func Iterate(complex pz) if @v_mmf_standarddistanceestimator!="1.0" odz = dz zold = pz endif if !@julia && m_Iterations==0 sz = @power*pz^(@power - 1) elseif @julia || m_Iterations>0 dz = @power*dz*pz^(@power - 1) ; if @v_mmf_standarddistanceestimator!="1.0" ; d2z = @power*(@power-1)*pz^(@power-2)*dz^2 + @power*d2z*pz^(@power-1) ; endif if @doper zvals[count] = pz dzvals[count] = dz if (count=count+1)>=201 count = 0 endif endif endif m_Iterations = m_Iterations + 1 endfunc ; @param pz ; @return the gradient index float func ResultIndex(complex pz) float a = 0.0 float d = 0.0 if @v_mmf_standarddistanceestimator=="1.0" if @mode=="Angle" || @mode=="Combined" if (a = atan2(pz/(dz*sz))*(0.5/#pi))<0.0 a = a + 1.0 endif if @mode=="Angle" return a endif endif if @mode=="Distance" || @mode=="Combined" d = cabs(pz) d = cabs((@power*log(d)*d/cabs(dz))^(1.0/@power)) if @mode=="Distance" return d endif endif else if type==0 || |pz|>=@bailout if @dodiv if @mode=="Angle" || @mode=="Combined" if (a = atan2(pz/(sz*dz))*(0.5/#pi))<0.0 a = a + 1.0 endif if @mode=="Angle" return a endif endif if @mode=="Distance" || @mode=="Combined" d = cabs(pz) d = (cabs(@power)*log(d)*d/cabs(dz))^(1.0/cabs(@power)) if @mode=="Distance" return d endif endif else if @divsolid m_Solid = true endif return @divfill endif elseif type==1 || |pz-zold|<=@smallbail if @doconv odz = dz dz = @power*dz*pz^(@power-1.0) if @cmode=="Angle" || @cmode=="Combined" if (a = atan2(-(pz-zold)/(sz*(dz-odz)))*(0.5/#pi))<0.0 a = a + 1.0 endif if @cmode=="Angle" return a endif endif if @cmode=="Distance" || @cmode=="Combined" d = cabs(pz-zold) d = 2.0*(cabs(@power)*d/cabs(dz-odz))^(1.0/cabs(@power)) if @cmode=="Distance" return d endif endif else if @convsolid m_Solid = true endif return @convfill endif elseif @doper int i = 0 if type>1 if (i=count-type)<0 i = i + 201 endif else i = count - 2 if i<0 i = i + 201 endif while i!=count && |zvals[i]-pz|>@perbail if (i=i-1)<0 i = 200 endif endwhile if (type=count-i)<0 type = type + 201 endif endif if i!=count dz = @power*dz*pz^(@power-1.0) if @pmode=="Angle" || @pmode=="Combined" if (a = atan2(-(pz-zvals[i])/(sz*(dz-dzvals[i])))*(0.5/#pi))<0.0 a = a + 1.0 endif if @pmode=="Angle" if @addperiod && @passedtype && @passedposition && @addposition a = pertrans.Iterate(a) + periodtrans.Iterate(type) \ + postrans.Iterate(p/type) elseif @addperiod a = pertrans.Iterate(a) + periodtrans.Iterate(type) elseif @passedtype && @passedposition && @addposition a = pertrans.Iterate(a) + postrans.Iterate(p/type) endif return a endif endif if @pmode=="Distance" || @pmode=="Combined" d = cabs(pz-zvals[i]) d = 2.0*(cabs(@power)*d/cabs(dz-dzvals[i]))^(1.0/cabs(@power)) if @pmode=="Distance" if @addperiod && @passedtype && @passedposition && @addposition d = pertrans.Iterate(d) + periodtrans.Iterate(type) \ + postrans.Iterate(p/type) elseif @addperiod d = pertrans.Iterate(d) + periodtrans.Iterate(type) elseif @passedtype && @passedposition && @addposition d = pertrans.Iterate(d) + postrans.Iterate(p/type) endif return d endif endif d = a + d a = 0 if @addperiod && @passedtype && @passedposition && @addposition d = pertrans.Iterate(d) + periodtrans.Iterate(type) \ + postrans.Iterate(p/type) elseif @addperiod d = pertrans.Iterate(d) + periodtrans.Iterate(type) elseif @passedtype && @passedposition && @addposition d = pertrans.Iterate(d) + postrans.Iterate(p/type) endif else if @persolid m_Solid = true endif return @perfill endif else if @persolid m_Solid = true endif return @perfill endif endif return a+d endfunc ; @param pz ; @return the distance float func ResultDistance(complex pz) float d = 0.0 if @v_mmf_standarddistanceestimator=="1.0" || type==0 || |pz|>=@bailout d = cabs(pz) return (cabs(@power)*log(d)*d/cabs(dz))^(1.0/cabs(@power)) elseif type==1 || |pz-zold|<=@smallbail complex ndz = @power*dz*pz^(@power-1.0) d = cabs(pz-zold) return 2.0*(cabs(@power)*d/cabs(ndz-dz))^(1.0/cabs(@power)) else int i = 0 if type>1 if (i=count-type)<0 i = i + 201 endif else i = count - 2 if i<0 i = i + 201 endif while i!=count && |zvals[i]-pz|>@perbail if (i=i-1)<0 i = 200 endif endwhile endif if i!=count complex ndz = @power*dz*pz^(@power-1.0) d = cabs(pz-zvals[i]) d = 2.0*(cabs(@power)*d/cabs(ndz-dzvals[i]))^(1.0/cabs(@power)) if @addperiod && @passedtype && @passedposition && @addposition return pertrans.Iterate(d) + periodtrans.Iterate(type) \ + postrans.Iterate(p/type) elseif @addperiod return pertrans.Iterate(d) + periodtrans.Iterate(type) elseif @passedtype && @passedposition && @addposition return pertrans.Iterate(d) + postrans.Iterate(p/type) else return d endif else return 0.0 endif endif endfunc ; @param pz ; @return the angle (from 0 to 1) float func ResultAngle(complex pz) float r = 0.0 if @v_mmf_standarddistanceestimator=="1.0" || |pz|>=@bailout if (r=atan2(pz/(dz*sz))*(0.5/#pi))<0.0 r = r + 1.0 endif elseif |pz-zold|<=@smallbail complex ndz = @power*dz*pz^(@power-1.0) if (r = atan2(-(pz-zold)/(sz*(ndz-dz)))*(0.5/#pi))<0.0 r = r + 1.0 endif else int i = 0 if type>1 if (i=count-type)<0 i = i + 201 endif else i = count - 2 if i<0 i = i + 201 endif while i!=count && |zvals[i]-pz|>@perbail if (i=i-1)<0 i = 200 endif endwhile endif while i!=count && |zvals[i]-pz|>@perbail if (i=i-1)<0 i = 200 endif endwhile if i!=count complex ndz = @power*dz*pz^(@power-1.0) if (r = atan2(-(pz-zvals[i])/(sz*(ndz-dzvals[i])))*(0.5/#pi))<0.0 r = r + 1.0 endif if @addperiod && @passedtype && @passedposition && @addposition r = pertrans.Iterate(r) + periodtrans.Iterate(type) \ + postrans.Iterate(p/type) elseif @addperiod r = pertrans.Iterate(r) + periodtrans.Iterate(type) elseif @passedtype && @passedposition && @addposition r = pertrans.Iterate(r) + postrans.Iterate(p/type) endif endif endif return r endfunc protected: Transfer pertrans Transfer periodtrans Transfer postrans complex zvals[201] complex dzvals[201] complex sz complex zold complex odz int type int count int p ; complex d2z ; complex od2z ; complex s2z default: title = "MMF Standard Distance Estimator" heading caption = "Information" text = "This colouring formula understands the mmf5.ufm:Multi Bailout \ Formula (and possibly other compatible formulas) that include \ periodic bailout testing and that can be set to pass the bailout \ type and other information to the colouring. Note that in this \ colouring the 'Periodic settings' will only work correctly when \ such a fractal formula is used with the fractal formula set to \ test for periodic bailout and either 'Colour using entire orbit' \ or 'Pass Bailout Type' is enabled - if neither of these is \ enabled then this colouring will treat periodic bailout as being \ standard convergence and the colouring in such areas will not be \ 'correct'. Note that in this colouring 'Bailout type passed' \ should be enabled when 'Pass bailout type' is enabled in the \ fractal formula, 'Convergent point passed' should be enabled when \ 'Pass which point' is in use and enabled in the fractal formula \ and 'Period position passed' should be enabled when 'Pass period \ position' is in use and enabled in the fractal formula." endheading heading caption = "Main control" endheading int param v_mmf_standarddistanceestimator caption = "Version (MMF Standard Distance Estimator)" enum = "1.0" "1.1" default = 1 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = true endparam complex param power caption = "Power (p in z^p+c)" default = (2,0) endparam bool param julia caption = "Julia ?" default = false hint = "Enable if your main formula is a Julia." endparam bool param passedtype caption = "Bailout type passed ?" default = false hint = "Enable if the main fractal formula has a parameter enabled to \ pass the bailout type to the colouring. At the moment the only \ formula with this parameter option is mmf5.ufm:Multi Bailout \ Formula." visible = @v_mmf_standarddistanceestimator!="1.0" endparam bool param passedpoint caption = "Convergent point passed ?" default = false hint = "Enable if the main fractal formula has a parameter enabled to \ pass the attraction point to the colouring. At the moment the only \ formula with this parameter option is mmf5.ufm:Multi Bailout \ Formula." visible = @v_mmf_standarddistanceestimator!="1.0" && @passedtype endparam bool param passedposition caption = "Period position passed ?" default = false hint = "Enable if the main fractal formula has a parameter enabled to \ pass the period position to the colouring. At the moment the only \ formula with this parameter option is mmf5.ufm:Multi Bailout \ Formula." visible = @v_mmf_standarddistanceestimator!="1.0" && @passedtype endparam heading caption = "Divergent settings" visible = @v_mmf_standarddistanceestimator!="1.0" endheading float param bailout caption = "Bailout (divergent)" default = 128.0 hint = "You should set this to the divergent bailout value in the \ fractal formula." visible = @v_mmf_standarddistanceestimator!="1.0" endparam bool param dodiv caption = "Colour divergent ?" default = true hint = "When enabled divergent areas will be coloured using distance \ estimator values or angles, when disabled you can have them \ filled either in the solid colour or by specifying a value to \ use to look up a gradient colour." visible = @v_mmf_standarddistanceestimator!="1.0" endparam int param mode caption = "Mode (divergent)" enum = "Distance" "Angle" "Combined" default = 0 visible = @v_mmf_standarddistanceestimator=="1.0" || @dodiv endparam bool param divsolid caption = "Solid ? (divergent)" default = true hint = "When enabled divergent areas are filled using the solid colour." visible = @v_mmf_standarddistanceestimator!="1.0" && !@dodiv endparam float param divfill caption = "Fill value (divergent)" default = 0.0 hint = "The value to use to look up a fill colour from UF's gradient for \ divergent areas. When the standard colour parameters are at the \ default settings this value corresponds to the gradient positions \ i.e. from 0.0 to 399.999." visible = @v_mmf_standarddistanceestimator!="1.0" && !@dodiv && !@divsolid endparam heading caption = "Convergent settings" text = "This is *not* a true distance estimate in convergent areas, \ it is merely based on the normal distance estimator formula as \ adapted to work on the Newton fractal and other convergent \ fractals. It is used here as it does provide a valuable \ colouring alternative." visible = @v_mmf_standarddistanceestimator!="1.0" endheading float param smallbail caption = "Bailout (convergent)" default = 1e-8 hint = "You should set this to the convergent bailout value in the \ fractal formula." visible = @v_mmf_standarddistanceestimator!="1.0" endparam bool param doconv caption = "Colour convergent ?" default = true hint = "When enabled convergent areas will be coloured using distance \ estimator values or angles, when disabled you can have them \ filled either in the solid colour or by specifying a value to \ use to look up a gradient colour." visible = @v_mmf_standarddistanceestimator!="1.0" endparam int param cmode caption = "Mode (convergent)" enum = "Distance" "Angle" "Combined" default = 0 visible = @v_mmf_standarddistanceestimator!="1.0" && @doconv endparam bool param convsolid caption = "Solid ? (convergent)" default = true hint = "When enabled convergent areas are filled using the solid colour." visible = @v_mmf_standarddistanceestimator!="1.0" && !@doconv endparam float param convfill caption = "Fill value (convergent)" default = 0.0 hint = "The value to use to look up a fill colour from UF's gradient for \ convergent areas. When the standard colour parameters are at the \ default settings this value corresponds to the gradient positions \ i.e. from 0.0 to 399.999." visible = @v_mmf_standarddistanceestimator!="1.0" && !@doconv && !@convsolid endparam heading caption = "Periodic settings" text = "This is *not* a true distance estimate in periodic areas, \ it is merely based on the normal distance estimator formula as \ adapted to work on the Newton fractal and other convergent \ fractals. It is used here as it does provide a valuable \ colouring alternative." visible = @v_mmf_standarddistanceestimator!="1.0" endheading float param perbail caption = "Bailout (periodic)" default = 1e-8 hint = "You should set this to the periodic bailout value in the \ fractal formula (if any)." visible = @v_mmf_standarddistanceestimator!="1.0" endparam bool param doper caption = "Colour periodic ?" default = true hint = "When enabled periodic areas will be coloured using distance \ estimator values or angles, when disabled you can have them \ filled either in the solid colour or by specifying a value to \ use to look up a gradient colour." visible = @v_mmf_standarddistanceestimator!="1.0" endparam int param pmode caption = "Mode (periodic)" enum = "Distance" "Angle" "Combined" default = 0 visible = @v_mmf_standarddistanceestimator!="1.0" && @doper endparam bool param addperiod caption = "Add period ?" default = false hint = "When enabled the period found will be mixed with your chosen \ periodic colouring." visible = @v_mmf_standarddistanceestimator!="1.0" && @doper endparam bool param addposition caption = "Add position ?" default = false hint = "When enabled the position of the attractor found within the \ period will be mixed in the final colouring value." visible = @v_mmf_standarddistanceestimator!="1.0" && @doper \ && @passedtype && @passedposition endparam Transfer param pertrans caption = "Periodic colour transfer" default = NullTransfer hint = "Use to scale either your periodic distance or angle value \ before it is mixed with the period and/or position values." visible = @v_mmf_standarddistanceestimator!="1.0" && @doper && (@addperiod \ || (@passedtype && @passedposition && @addposition)) endparam Transfer param periodtrans caption = "Period transfer" default = NullTransfer hint = "Use to scale the period found before it is mixed with the final \ colour." visible = @v_mmf_standarddistanceestimator!="1.0" && @doper && @addperiod endparam Transfer param postrans caption = "Position transfer" default = NullTransfer hint = "Use to scale the position found before it is mixed with the final \ colour." visible = @v_mmf_standarddistanceestimator!="1.0" && @doper \ && @passedtype && @passedposition && @addposition endparam bool param persolid caption = "Solid ? (periodic)" default = true hint = "When enabled periodic areas are filled using the solid colour." visible = @v_mmf_standarddistanceestimator!="1.0" && !@doper endparam float param perfill caption = "Fill value (periodic)" default = 0.0 hint = "The value to use to look up a fill colour from UF's gradient for \ periodic areas. When the standard colour parameters are at the \ default settings this value corresponds to the gradient positions \ i.e. from 0.0 to 399.999." visible = @v_mmf_standarddistanceestimator!="1.0" && !@doper && !@persolid endparam } class MMF_SeedDLA(common.ulb:Generic) { public: import "common.ulb" ; @param pparent the parent, generally "this" from "DLA Inspired" func MMF_SeedDLA(Generic pparent) m_Parent = pparent endfunc default: int param mmf_seeddla caption = "Version (MMF_SeedDLA)" default = 100 hint = "This version parameter is used to detect when a change has \ been made to the formula that is incompatible with the \ previous version. When that happens, this field will reflect \ the old version number to alert you to the fact that an \ alternate rendering is being used." visible = @mmf_seeddla < 100 endparam } class MMF_DeadDLA(common.ulb:Generic) { public: import "common.ulb" ; @param pparent the parent, generally "this" from "DLA Inspired" func MMF_DeadDLA(Generic pparent) m_Parent = pparent endfunc ; @param x the x pixel position of a stimulus ; @param y the y pixel position of a stimulus ; @return the square of the pixel distance float func DeadDistance(float x,float y) return 1e200 endfunc default: int param mmf_deaddla caption = "Version (MMF_DeadDLA)" default = 100 hint = "This version parameter is used to detect when a change has \ been made to the formula that is incompatible with the \ previous version. When that happens, this field will reflect \ the old version number to alert you to the fact that an \ alternate rendering is being used." visible = @mmf_deaddla < 100 endparam color param colour caption = "Dead Point Colour" default = RGB(0,0,0) hint = "Note that if not using a direct colouring mode then this \ parameter is ignored and 'dead' points are set to the palette \ colour from 'Dead Point Index'." endparam float param index caption = "Dead Point Index" default = 399.0 min = 0.0 max = 399.0 hint = "Note that if not using a gradient colouring mode then this \ parameter is ignored and 'dead' points are set to the colour \ from 'Dead Point Colour'." endparam } class MMF_NoDeadDLA(MMF_DeadDLA) { public: import "common.ulb" ; @param pparent the parent, generally "this" from "DLA Inspired" func MMF_NoDeadDLA(Generic pparent) m_Parent = pparent endfunc ; @param x the x pixel position of a stimulus ; @param y the y pixel position of a stimulus ; @return the square of the pixel distance float func DeadDistance(float x,float y) return 1e200 endfunc default: title = "No Dead Point DLA Seeding" color param colour default = RGB(0,0,0) visible = false endparam float param index default = 399.0 visible = false endparam } class MMF_OnePointDeadDLA(MMF_DeadDLA) { import "common.ulb" ; @param pparent the parent, generally "this" from "DLA Inspired" func MMF_OnePointDeadDLA(Generic pparent) m_Parent = pparent MMF_DLA(pparent).SetDeadPoint(floor(@xco*#width)+2,floor(@yco*#height)+2, \ @colour,@index) MMF_DLA(pparent).SetDeadPoint(floor(@xco*#width)+3,floor(@yco*#height)+2, \ @colour,@index) MMF_DLA(pparent).SetDeadPoint(floor(@xco*#width)+2,floor(@yco*#height)+3, \ @colour,@index) MMF_DLA(pparent).SetDeadPoint(floor(@xco*#width)+3,floor(@yco*#height)+3, \ @colour,@index) endfunc ; @param x the x pixel position of a stimulus ; @param y the y pixel position of a stimulus ; @return the square of the pixel distance float func DeadDistance(float x,float y) return sqr(x-floor(@xco*#width)-2) + sqr(y-floor(@yco*#height)-2) endfunc default: title = "Single Dead Point" float param xco caption = "Fraction Across Screen" default = 0.25 min = 0.0 max = 1.0 hint = "Use 0.0 for the far left, use 1.0 for the far right." endparam float param yco caption = "Fraction Down Screen" default = 0.25 min = 0.0 max = 1.0 hint = "Use 0.0 for the top, use 1.0 for the bottom." endparam } class MMF_LineDeadDLA(MMF_DeadDLA) { public: import "common.ulb" ; @param pparent the parent, generally "this" from "DLA Inspired" func MMF_LineDeadDLA(Generic pparent) m_Parent = pparent d2 = sqr(dx=(real(@le)-real(@ls))*#width) \ + sqr(dy=(imag(@le)-imag(@ls))*#height) id2 = 1.0/d2 float x = real(@ls)*#width + 2 float y = imag(@ls)*#height + 2 if abs(dx)>=abs(dy) if dx==0 MMF_DLA(pparent).SetDeadPoint(floor(x),floor(y),@colour,@index) MMF_DLA(pparent).SetDeadPoint(floor(x)+1,floor(y),@colour,@index) MMF_DLA(pparent).SetDeadPoint(floor(x),floor(y)+1,@colour,@index) MMF_DLA(pparent).SetDeadPoint(floor(x)+1,floor(y)+1,@colour,@index) elseif dx>0 float d = dy/dx repeat MMF_DLA(pparent).SetDeadPoint(floor(x),floor(y),@colour,@index) MMF_DLA(pparent).SetDeadPoint(floor(x),floor(y)+1,@colour,@index) y = y + d until (x=x+1)>real(@le)*#width + 2 else float d = -dy/dx repeat MMF_DLA(pparent).SetDeadPoint(floor(x),floor(y),@colour,@index) MMF_DLA(pparent).SetDeadPoint(floor(x),floor(y)+1,@colour,@index) y = y + d until (x=x-1)0 float d = dx/dy repeat MMF_DLA(pparent).SetDeadPoint(floor(x),floor(y),@colour,@index) MMF_DLA(pparent).SetDeadPoint(floor(x)+1,floor(y),@colour,@index) x = x + d until (y=y+1)>imag(@le)*#height + 2 else float d = -dx/dy repeat MMF_DLA(pparent).SetDeadPoint(floor(x),floor(y),@colour,@index) MMF_DLA(pparent).SetDeadPoint(floor(x)+1,floor(y),@colour,@index) x = x + d until (y=y-1)d2 return sqr(x - dx) + sqr(y - dy) else return sqr(y*dx - x*dy)*id2 endif endfunc private: float d2 float id2 float dx float dy default: title = "Dead Line" complex param ls caption = "Line Start" default = (0.25,0.25) hint = "The start point of the dead line. The real part is the fraction \ across the screen and the imaginary part is the fraction down \ the screen. Both real and imaginary parts should be \ >=0 and <=1." endparam complex param le caption = "Line End" default = (0.25,0.75) hint = "The end point of the dead line. The real part is the fraction \ across the screen and the imaginary part is the fraction down \ the screen. Both real and imaginary parts should be \ >=0 and <=1." endparam } class MMF_FractalDeadDLA(MMF_DeadDLA) { import "common.ulb" import "Standard.ulb" ; @param pparent the parent, generally "this" from "DLA Inspired" func MMF_FractalDeadDLA(Generic pparent) m_Parent = pparent Formula f = new @formulaClass(this) GradientColoring ci = new @insidecoloringClass(this) GradientColoring co = new @outsidecoloringClass(this) complex zz complex p float py float v int y = -2 repeat py = (imag(#center) + 2*#height/(#width*#magn)) - y/(0.25*#magn*#width) int x = -2 repeat p = x/(0.25*#magn*#width) + (real(#center) - 2/#magn) + flip(py) if @rotate p = #center + (real(p)-real(#center))*cos(#angle) \ - (imag(p)-imag(#center))*sin(#angle) \ + flip((imag(p)-imag(#center))*cos(#angle) \ + (real(p)-real(#center))*sin(#angle)) endif int i = 0 zz = f.Init(p) if @inside ci.Init(zz,p) endif if @outside co.Init(zz,p) endif repeat zz = f.Iterate(zz) if @inside ci.Iterate(zz) endif if @outside && !f.IsBailedOut(zz) co.Iterate(zz) endif until (i=i+1)>=#maxiter || f.IsBailedOut(zz) if @inside && i>=#maxiter v = ci.ResultIndex(zz) if v>=@imin && v<=@imax if @grid>1 MMF_DLA(pparent).SetDeadPoint(x+2-(x%@grid), \ y+2-(y%@grid),@icolour,@iindex) else MMF_DLA(pparent).SetDeadPoint(x+2,y+2,@icolour,@iindex) endif endif elseif @outside && i<#maxiter v = co.ResultIndex(zz) if v>=@omin && v<=@omax if @grid>1 MMF_DLA(pparent).SetDeadPoint(x+2-(x%@grid), \ y+2-(y%@grid),@ocolour,@oindex) else MMF_DLA(pparent).SetDeadPoint(x+2,y+2,@ocolour,@oindex) endif endif elseif i>=@min && i<=@max if @grid>1 MMF_DLA(pparent).SetDeadPoint(x+2-(x%@grid), \ y+2-(y%@grid),@colour,@index) else MMF_DLA(pparent).SetDeadPoint(x+2,y+2,@colour,@index) endif endif until (x=x+1)>=#width+3 until (y=y+1)>=#height+3 endfunc ; @param x the x pixel position of a stimulus ; @param y the y pixel position of a stimulus ; @return the square of the pixel distance float func DeadDistance(float x,float y) return MMF_DLA(m_parent).DeadDist() endfunc default: title = "Dead Fractal" bool param rotate caption = "Use UF Rotation" default = false hint = "If you wish to rotate the fractal used (using UF's default \ angle) then you need to enable this parameter." endparam int param grid caption = "Limit to Grid" default = 1 min = 1 hint = "When using values >1 only the top-left pixel in a every grid \ of the given size is set as a dead pixel. For example if you \ use 2 for a 2*2 grid then at most one pixel in every 4 will be \ set as 'dead'." endparam Formula param formulaClass caption = "Fractal Formula" default = Standard_Mandelbrot endparam bool param inside caption = "Use 'Inside' Colouring" default = false hint = "When enabled you can choose a colouring method for 'inside' areas." endparam GradientColoring param insidecoloringClass caption = "Coloring Algorithm" default = Standard_OrbitTraps hint = "Selects the inside colouring algorithm to be used." visible = @inside endparam float param imin caption = "Minimum Inside Index" default = 0.0 min = 0.0 hint = "The minimum index from the inside colouring to set as 'dead'." visible = @inside endparam float param imax caption = "Maximum Inside Index" default = 0.1 min = 0.0 hint = "The maximum index from the inside colouring to set as 'dead'." visible = @inside endparam color param icolour caption = "Inside Colour" default = RGB(0,0,0) hint = "Note that if not using a direct colouring mode then this \ parameter is ignored and 'dead' points are set to the palette \ colour from 'Inside Index'." visible = @inside endparam float param iindex caption = "Inside Index" default = 399.0 min = 0.0 max = 399.0 hint = "Note that if not using a gradient colouring mode then this \ parameter is ignored and 'dead' points are set to the colour \ from 'Inside Colour'." visible = @inside endparam bool param outside caption = "Use 'Outside' Colouring" default = false hint = "When enabled you can choose a colouring method for 'outside' areas." endparam GradientColoring param outsidecoloringClass caption = "Coloring Algorithm" default = Standard_DistanceEstimator hint = "Selects the coloring algorithm to be used." visible = @outside endparam float param omin caption = "Minimum Outside Index" default = 0.0 min = 0.0 hint = "The minimum index from the outside colouring to set as 'dead'." visible = @outside endparam float param omax caption = "Maximum Outside Index" default = 0.2 min = 0.0 hint = "The maximum index from the outside colouring to set as 'dead'." visible = @outside endparam color param ocolour caption = "Outside Colour" default = RGB(0,0,0) hint = "Note that if not using a direct colouring mode then this \ parameter is ignored and 'dead' points are set to the palette \ colour from 'Outside Index'." visible = @outside endparam float param oindex caption = "Outside Index" default = 399.0 min = 0.0 max = 399.0 hint = "Note that if not using a gradient colouring mode then this \ parameter is ignored and 'dead' points are set to the colour \ from 'Outside Colour'." visible = @outside endparam int param min caption = "Minimum Iteration" default = 10 min = 0 hint = "The minimum iteration to set as 'dead'. Note that to disable \ dead points based on iteration then just set this to a larger \ value than 'Maximum Iteration'." visible = !@outside || !@inside endparam int param max caption = "Maximum Iteration" default = 99 min = 0 hint = "The maximum iteration to set as 'dead'. Note that to disable \ dead points based on iteration then just set this to a smaller \ value than 'Minimum Iteration'." visible = !@outside || !@inside endparam color param colour caption = "Iteration Colour" default = RGB(0,0,0) hint = "Note that if not using a direct colouring mode then this \ parameter is ignored and 'dead' points are set to the palette \ colour from 'Iteration Index'." visible = !@outside || !@inside endparam float param index caption = "Iteration Index" default = 399.0 min = 0.0 max = 399.0 hint = "Note that if not using a gradient colouring mode then this \ parameter is ignored and 'dead' points are set to the colour \ from 'Iteration Colour'." visible = !@outside || !@inside endparam } class MMF_MultiDeadDLA(MMF_DeadDLA) { import "common.ulb" ; @param pparent the parent, generally "this" from "DLA Inspired" func MMF_MultiDeadDLA(Generic pparent) m_Parent = pparent seed1 = new @seed1(pparent) seed2 = new @seed2(pparent) if @numseeds>0 seed3 = new @seed3(pparent) if @numseeds>1 seed4 = new @seed4(pparent) if @numseeds>2 seed5 = new @seed5(pparent) if @numseeds>3 seed6 = new @seed6(pparent) endif endif endif endif endfunc ; @param x the x pixel position of a stimulus ; @param y the y pixel position of a stimulus ; @return the square of the pixel distance float func DeadDistance(float x,float y) float w float v v = seed1.DeadDistance(x,y) if (w=seed2.DeadDistance(x,y))0 if (w=seed3.DeadDistance(x,y))1 if (w=seed4.DeadDistance(x,y))2 if (w=seed5.DeadDistance(x,y))3 if (w=seed6.DeadDistance(x,y))0 endparam MMF_DeadDLA param seed4 caption = "Dead Point Type 4" default = MMF_OnePointDeadDLA visible = @numseeds>1 endparam MMF_DeadDLA param seed5 caption = "Dead Point Type 5" default = MMF_OnePointDeadDLA visible = @numseeds>2 endparam MMF_DeadDLA param seed6 caption = "Dead Point Type 6" default = MMF_OnePointDeadDLA visible = @numseeds>3 endparam color param colour default = RGB(0,0,0) visible = false endparam float param index default = 399.0 visible = false endparam } class MMF_OnePointSeedDLA(MMF_SeedDLA) { import "common.ulb" ; @param pparent the parent, generally "this" from "DLA Inspired" func MMF_OnePointSeedDLA(Generic pparent) m_Parent = pparent MMF_DLA(pparent).SetStartPoint(floor(@xco*#width)+2,floor(@yco*#height)+2) endfunc default: title = "Single Point Seed" float param xco caption = "Fraction Across Screen" default = 0.5 min = 0.0 max = 1.0 hint = "Use 0.0 for the far left, use 1.0 for the far right." endparam float param yco caption = "Fraction Down Screen" default = 0.5 min = 0.0 max = 1.0 hint = "Use 0.0 for the top, use 1.0 for the bottom." endparam } class MMF_FractalSeedDLA(MMF_SeedDLA) { import "common.ulb" import "Standard.ulb" ; @param pparent the parent, generally "this" from "DLA Inspired" func MMF_FractalSeedDLA(Generic pparent) m_Parent = pparent Formula f = new @formulaClass(this) GradientColoring ci = new @insidecoloringClass(this) GradientColoring co = new @outsidecoloringClass(this) complex zz complex p float py float v int y = -2 repeat py = (imag(#center) + 2*#height/(#width*#magn)) - y/(0.25*#magn*#width) int x = -2 repeat p = x/(0.25*#magn*#width) + (real(#center) - 2/#magn) + flip(py) if @rotate p = #center + (real(p)-real(#center))*cos(#angle) \ - (imag(p)-imag(#center))*sin(#angle) \ + flip((imag(p)-imag(#center))*cos(#angle) \ + (real(p)-real(#center))*sin(#angle)) endif int i = 0 zz = f.Init(p) if @inside ci.Init(zz,p) endif if @outside co.Init(zz,p) endif repeat zz = f.Iterate(zz) if @inside ci.Iterate(zz) endif if @outside && !f.IsBailedOut(zz) co.Iterate(zz) endif until (i=i+1)>=#maxiter || f.IsBailedOut(zz) if @inside && i>=#maxiter v = ci.ResultIndex(zz) if v>=@imin && v<=@imax MMF_DLA(pparent).SetStartPoint(x+2,y+2) endif elseif @outside && i<#maxiter v = co.ResultIndex(zz) if v>=@omin && v<=@omax MMF_DLA(pparent).SetStartPoint(x+2,y+2) endif elseif i>=@min && i<=@max MMF_DLA(pparent).SetStartPoint(x+2,y+2) endif until (x=x+1)>=#width+3 until (y=y+1)>=#height+3 endfunc default: title = "Fractal Seeding" bool param rotate caption = "Use UF Rotation" default = false hint = "If you wish to rotate the fractal used (using UF's default \ angle) then you need to enable this parameter." endparam Formula param formulaClass caption = "Fractal Formula" default = Standard_Mandelbrot endparam bool param inside caption = "Use 'Inside' Colouring" default = false hint = "When enabled you can choose a colouring method for 'inside' areas." endparam GradientColoring param insidecoloringClass caption = "Coloring Algorithm" default = Standard_OrbitTraps hint = "Selects the inside colouring algorithm to be used." visible = @inside endparam float param imin caption = "Minimum Inside Index" default = 0.0 min = 0.0 hint = "The minimum index from the inside colouring to seed." visible = @inside endparam float param imax caption = "Maximum Inside Index" default = 0.05 min = 0.0 hint = "The maximum index from the inside colouring to seed." visible = @inside endparam bool param outside caption = "Use 'Outside' Colouring" default = false hint = "When enabled you can choose a colouring method for 'outside' areas." endparam GradientColoring param outsidecoloringClass caption = "Coloring Algorithm" default = Standard_DistanceEstimator hint = "Selects the coloring algorithm to be used." visible = @outside endparam float param omin caption = "Minimum Outside Index" default = 0.0 min = 0.0 hint = "The minimum index from the outside colouring to seed." visible = @outside endparam float param omax caption = "Maximum Outside Index" default = 0.05 min = 0.0 hint = "The maximum index from the outside colouring to seed." visible = @outside endparam int param min caption = "Minimum Iteration" default = 60 min = 0 hint = "The minimum iteration to seed." visible = !@outside || !@inside endparam int param max caption = "Maximum Iteration" default = 99 min = 0 hint = "The maximum iteration to seed." visible = !@outside || !@inside endparam } class MMF_MultiSeedDLA(MMF_SeedDLA) { import "common.ulb" ; @param pparent the parent, generally "this" from "DLA Inspired" func MMF_MultiSeedDLA(Generic pparent) m_Parent = pparent seed1 = new @seed1(pparent) seed2 = new @seed2(pparent) if @numseeds>0 seed3 = new @seed3(pparent) if @numseeds>1 seed4 = new @seed4(pparent) if @numseeds>2 seed5 = new @seed5(pparent) if @numseeds>3 seed6 = new @seed6(pparent) endif endif endif endif endfunc protected: MMF_SeedDLA seed1 MMF_SeedDLA seed2 MMF_SeedDLA seed3 MMF_SeedDLA seed4 MMF_SeedDLA seed5 MMF_SeedDLA seed6 default: title = "Multiple DLA Seed Types" int param numseeds caption = "Number of types" enum = "2" "3" "4" "5" "6" default = 0 endparam MMF_SeedDLA param seed1 caption = "Seed Type 1" default = MMF_OnePointSeedDLA endparam MMF_SeedDLA param seed2 caption = "Seed Type 2" default = MMF_OnePointSeedDLA endparam MMF_SeedDLA param seed3 caption = "Seed Type 3" default = MMF_OnePointSeedDLA visible = @numseeds>0 endparam MMF_SeedDLA param seed4 caption = "Seed Type 4" default = MMF_OnePointSeedDLA visible = @numseeds>1 endparam MMF_SeedDLA param seed5 caption = "Seed Type 5" default = MMF_OnePointSeedDLA visible = @numseeds>2 endparam MMF_SeedDLA param seed6 caption = "Seed Type 6" default = MMF_OnePointSeedDLA visible = @numseeds>3 endparam } class MMF_StimulusDLA(common.ulb:Generic) { import "common.ulb" ; @param pparent the parent, generally "this" from "DLA Inspired" func MMF_StimulusDLA(Generic pparent) m_Parent = pparent endfunc ; @param left The leftmost pixel of the organisms for this stimulus ; @param right The rightmost pixel of the organisms for this stimulus ; @param top The top pixel of the organisms for this stimulus ; @param bottom The bottom pixel of the organisms for this stimulus ; @return pixel x + flip(pixel y) complex func GetPoint(float left,float right,float top,float bottom) return 0.5*#width + 2 + flip(0.5*#height + 2) endfunc ; @return the square of the detection radius for this stimulus float func GetRange() return sqr(@detect) endfunc ; @param x adjusted stimulus x pixel coordinate ; @param y adjusted stimulus y pixel coordinate ; @return cos+flip(sin) of the directional angle complex func Direction(float x,float y) if @isdirectional==0 return 0.0 ; No direction, will result in no change to distance based ; on direction elseif @isdirectional==1 return cos(#pi*(@angle-90)/180) + flip(sin(#pi*(@angle-90)/180)) elseif @isdirectional>1 && @isdirectional<6 float d = 1.0/sqrt(sqr(x = real(@point)*#width - x) \ + sqr(y = imag(@point)*#height - y)) if @isdirectional==2 return -d*(x + flip(y)) elseif @isdirectional==3 return d*(x + flip(y)) elseif @isdirectional==4 return d*(flip(x) - y) else return d*(y - flip(x)) endif else float a = (@min - 90 + abs(r=random(r))*(@max-@min)/#randomrange)*#pi/180 return cos(a) + flip(sin(a)) endif endfunc protected: int r default: int param mmf_stimulusdla caption = "Version (MMF_StimulusDLA)" default = 100 hint = "This version parameter is used to detect when a change has \ been made to the formula that is incompatible with the \ previous version. When that happens, this field will reflect \ the old version number to alert you to the fact that an \ alternate rendering is being used." visible = @mmf_stimulusdla < 100 endparam int param seed caption = "Random Seed 1" default = 12345678 hint = "Changing the value will change the pattern of stimuli." endparam int param isdirectional caption = "Moving stimuli ?" enum = "No" "Fixed Direction" "To a Point" "Away from a Point" \ "Point Clockwise" "Point AntiClockwise" "Random Direction" default = 0 hint = "When enabled you can define a direction of movement for the \ stimuli generated by this object. Note that this parameter is \ ignored in 'MMF DLA Inspired' unless you enabled 'Added \ Stimulus Movement' in the Advanced Options." endparam float param angle caption = "Direction of Movement" default = 0.0 hint = "The angle at which the stimuli are moving (in degrees). Zero \ means the stimuli are moving from the top (i.e. down). Positive \ values are clockwise so 90 means they're moving from the right \ (i.e. left). Note that this parameter is ignored in 'MMF DLA \ Inspired' unless you enabled 'Added Stimulus Movement' in the \ Advanced Options." visible = @isdirectional==1 endparam complex param point caption = "Active Point" default = (0.5,0.5) hint = "This is the point to which the stimuli are heading. It specifies \ a point location as a fraction of the screen width and height. \ The real part specifies the horizontal location, 0.0 is left \ and 1.0 is right. The imaginary part specifies the vertical \ location, 0.0 is top and 1.0 is bottom. Note that this parameter \ is ignored in 'MMF DLA Inspired' unless you enabled 'Added \ Stimulus Movement' in the Advanced Options." visible = @isdirectional>1 && @isdirectional<6 endparam float param min caption = "Minimum Angle" default = -90.0 hint = "The minimum angle at which the stimuli are moving (in degrees). \ Zero means the stimuli are moving from the top (i.e. down). \ Positive values are clockwise so 90 means they're moving from the \ right (i.e. left). Note that this parameter is ignored in 'MMF \ DLA Inspired' unless you enabled 'Added Stimulus Movement' in the \ Advanced Options." visible = @isdirectional==6 endparam float param max caption = "Maximum Angle" default = 90.0 hint = "The maximum angle at which the stimuli are moving (in degrees). \ Zero means the stimuli are moving from the top (i.e. down). \ Positive values are clockwise so 90 means they're moving from the \ right (i.e. left). Note that this parameter is ignored in 'MMF \ DLA Inspired' unless you enabled 'Added Stimulus Movement' in the \ Advanced Options." visible = @isdirectional==6 endparam float param detect caption = "Maximum Detection %age" default = 100.0 min = 0.5 hint = "This percentage specifies the maximum distance at which the \ organisms can detect this stimulus. The distance affects the \ fractal nature of the organisms." endparam } class MMF_CircleStimulusDLA(MMF_StimulusDLA) { import "common.ulb" ; @param pparent the parent, generally "this" from "DLA Inspired" func MMF_CircleStimulusDLA(Generic pparent) m_Parent = pparent r = @seed endfunc ; @param left The leftmost pixel of the organisms for this stimulus ; @param right The rightmost pixel of the organisms for this stimulus ; @param top The top pixel of the organisms for this stimulus ; @param bottom The bottom pixel of the organisms for this stimulus ; @return pixel x + flip(pixel y) complex func GetPoint(float left,float right,float top,float bottom) float a = abs(r=random(r))*(2.0*#pi/#randomrange) float x = sqrt(abs(r=random(r))/#randomrange) if @bias>=0.0 x = x^@bias else x = 0.5*(x^(-@bias)) if abs(r=random(r))>1073741824 x = 1.0 - x endif endif x = x*(@radius*sqrt(sqr(0.5*#width)+sqr(0.5*#height))) return x*cos(a) + (real(@centre)*#width + 2) \ + flip(x*sin(a) + (imag(@centre)*#height + 2)) endfunc default: title = "Circle DLA Stimulus" float param detect caption = "Maximum Detection %age" default = 100.0 min = 0.5 hint = "This percentage specifies the maximum distance at which the \ organisms can detect this stimulus. The distance affects the \ fractal nature of the organisms. Results will differ from \ 'Smart Circle DLA Stimulus' espacially when biasing." endparam complex param centre caption = "Centre Coords" default = (0.5,0.5) hint = "(0,0) is screen top-left, (1,1) is screen bottom-right. The \ real part gives the horizontal location and the imaginary \ part gives the vertical location." endparam float param radius caption = "Radius" default = 0.6 hint = "Scales the circle according to the height and width of the \ screen. Using 1.0 selects a radius such that a circle centred \ at the centre of the screen would just pass through the screen \ corners." endparam float param bias caption = "Bias" default = 1.0 hint = "Positive values bias to the centre or edge of the circle. \ Use values >0 and <1 to bias to the edge, values >1 to bias \ to the centre. Negative values bias towards half radius or to \ the centre and the edge. Use values <0 and >-1 to bias to the \ half radius, values <-1 to bias to the centre and edge." endparam } class MMF_SmartCircleStimulusDLA(MMF_StimulusDLA) { import "common.ulb" ; @param pparent the parent, generally "this" from "DLA Inspired" func MMF_SmartCircleStimulusDLA(Generic pparent) m_Parent = pparent r = @seed endfunc ; @param left The leftmost pixel of the organisms for this stimulus ; @param right The rightmost pixel of the organisms for this stimulus ; @param top The top pixel of the organisms for this stimulus ; @param bottom The bottom pixel of the organisms for this stimulus ; @return pixel x + flip(pixel y) complex func GetPoint(float left,float right,float top,float bottom) float a = abs(r=random(r))*(2.0*#pi/#randomrange) float x = sqrt(abs(r=random(r))/#randomrange) if @bias>=0.0 x = x^@bias else x = 0.5*(x^(-@bias)) if abs(r=random(r))>1073741824 x = 1.0 - x endif endif if @method==0 x = x*((0.01*@detect*sqrt(sqr(#width+5)+sqr(#height+5))) \ + 0.5*sqrt(sqr(right-left)+sqr(bottom-top))) else if (x=x*(0.5 + 0.005*@detect)*sqrt(sqr(right-left)+sqr(bottom-top)))<2 x = 2 endif endif return x*cos(a) + 0.5*(left + right) \ + flip(x*sin(a) + 0.5*(top + bottom)) endfunc default: title = "Smart Circle DLA Stimulus" int param method caption = "Detection %age Method" enum = "Original" "Scaled" default = 0 hint = "When using 'Original' the 'Maximum Detection %age' sets the \ maximum detection distance to a %age of the screen size, when \ using 'Scaled' a %age of the range of the organisms affected \ by the stimulus is used instead." endparam float param detect caption = "Maximum Detection %age" default = 4.0 min = 0.5 hint = "This percentage specifies the maximum distance at which the \ organisms can detect this stimulus. The distance affects the \ fractal nature of the organisms. Results will differ from \ 'Circle DLA Stimulus' espacially when biasing." endparam float param bias caption = "Bias" default = 1.0 hint = "Positive values bias to the centre or edge of the circle. \ Use values >0 and <1 to bias to the edge, values >1 to bias \ to the centre. Negative values bias towards half radius or to \ the centre and the edge. Use values <0 and >-1 to bias to the \ half radius, values <-1 to bias to the centre and edge." endparam } class MMF_RectStimulusDLA(MMF_StimulusDLA) { import "common.ulb" ; @param pparent the parent, generally "this" from "DLA Inspired" func MMF_RectStimulusDLA(Generic pparent) m_Parent = pparent r = @seed endfunc ; @param left The leftmost pixel of the organisms for this stimulus ; @param right The rightmost pixel of the organisms for this stimulus ; @param top The top pixel of the organisms for this stimulus ; @param bottom The bottom pixel of the organisms for this stimulus ; @return pixel x + flip(pixel y) complex func GetPoint(float left,float right,float top,float bottom) float x = abs(r=random(r))/#randomrange float y = abs(r=random(r))/#randomrange if @biasx>=0.0 x = x^@biasx else x = 0.5*(x^(-@biasx)) if abs(r=random(r))>1073741824 x = 1.0 - x endif endif if @biasy>=0.0 y = y^@biasy else y = 0.5*(y^(-@biasy)) if abs(r=random(r))>1073741824 y = 1.0 - y endif endif return (x-0.5)*(real(@scale)*#width) + real(@centre)*#width + 2 \ + flip((y-0.5)*(imag(@scale)*#height) + imag(@centre)*#height + 2) endfunc default: title = "Rectangular DLA Stimulus" float param detect caption = "Maximum Detection %age" default = 100.0 min = 0.5 hint = "This percentage specifies the maximum distance at which the \ organisms can detect this stimulus. The distance affects the \ fractal nature of the organisms, when using biasing the results \ will be noticeably different from 'Smart Rectangluar DLA \ Stimulus'." endparam complex param centre caption = "Centre Coords" default = (0.5,0.5) hint = "(0,0) is screen top-left, (1,1) is screen bottom-right. The \ real part gives the horizontal location and the imaginary \ part gives the vertical location." endparam complex param scale caption = "Rectangle Scale" default = (1.0,1.0) hint = "Scales the rectangle according to the height and width of the \ screen. The real part scales the width of the rectangle with \ respect to the screen width and the imaginary part scales the \ height of the rectangle with respect to the screen height. \ Both values should be kept positive." endparam float param biasx caption = "Horizontal Bias" default = 1.0 hint = "Positive values bias to the left/right. Use values >0 and <1 \ to bias to the right, values >1 to bias to the left. Negative \ values bias towards the centre or the edges. Use values <0 and \ >-1 to bias to the centre, values <-1 to bias to the sides." endparam float param biasy caption = "Vertical Bias" default = 1.0 hint = "Positive values bias to the top/bottom. Use values >0 and <1 \ to bias to the bottom, values >1 to bias to the top. Negative \ values bias towards the centre or the edges. Use values <0 and \ >-1 to bias to the centre, values <-1 to bias to the sides." endparam } class MMF_SmartRectStimulusDLA(MMF_StimulusDLA) { import "common.ulb" ; @param pparent the parent, generally "this" from "DLA Inspired" func MMF_SmartRectStimulusDLA(Generic pparent) m_Parent = pparent r = @seed endfunc ; @param left The leftmost pixel of the organisms for this stimulus ; @param right The rightmost pixel of the organisms for this stimulus ; @param top The top pixel of the organisms for this stimulus ; @param bottom The bottom pixel of the organisms for this stimulus ; @return pixel x + flip(pixel y) complex func GetPoint(float left,float right,float top,float bottom) float x = abs(r=random(r))/#randomrange float y = abs(r=random(r))/#randomrange if @biasx>=0.0 x = x^@biasx else x = 0.5*(x^(-@biasx)) if abs(r=random(r))>1073741824 x = 1.0 - x endif endif if @biasy>=0.0 y = y^@biasy else y = 0.5*(y^(-@biasy)) if abs(r=random(r))>1073741824 y = 1.0 - y endif endif if @method==0 left = left - (0.01*@detect*sqrt(sqr(#width+5)+sqr(#height+5))) right = right + (0.01*@detect*sqrt(sqr(#width+5)+sqr(#height+5))) top = top - (0.01*@detect*sqrt(sqr(#width+5)+sqr(#height+5))) bottom = bottom + (0.01*@detect*sqrt(sqr(#width+5)+sqr(#height+5))) else float v = 0.01*@detect*(right - left) if v<4 v = 4 endif left = left - v right = right + v if (v=0.01*@detect*(bottom - top))<4 v = 4 endif top = top - v bottom = bottom + v endif return left + x*(right - left) + flip(top + y*(bottom - top)) endfunc default: title = "Smart Rectangular DLA Stimulus" int param method caption = "Detection %age Method" enum = "Original" "Scaled" default = 0 hint = "When using 'Original' the 'Maximum Detection %age' sets the \ maximum detection distance to a %age of the screen size, when \ using 'Scaled' a %age of the range of the organisms affected \ by the stimulus is used instead." endparam float param detect caption = "Maximum Detection %age" default = 2.0 min = 0.5 hint = "This percentage specifies the maximum distance at which the \ organisms can detect this stimulus. The distance affects the \ fractal nature of the organisms, when using biasing the results \ will be noticeably different from 'Rectangluar DLA Stimulus'." endparam float param biasx caption = "Horizontal Bias" default = 1.0 hint = "Positive values bias to the left/right. Use values >0 and <1 \ to bias to the right, values >1 to bias to the left. Negative \ values bias towards the centre or the edges. Use values <0 and \ >-1 to bias to the centre, values <-1 to bias to the sides." endparam float param biasy caption = "Vertical Bias" default = 1.0 hint = "Positive values bias to the top/bottom. Use values >0 and <1 \ to bias to the bottom, values >1 to bias to the top. Negative \ values bias towards the centre or the edges. Use values <0 and \ >-1 to bias to the centre, values <-1 to bias to the sides." endparam } class MMF_DLA(common.ulb:GradientColoring) { public: import "common.ulb" ; @param pparent the parent, generally "this" from the parent, or zero func MMF_DLA(Generic pparent) GradientColoring.GradientColoring(pparent) float nd[16] bool ss[16,16] complex p = (0,0) float d = 0.0 float rot = (270.0+@angle)*(#pi/180.0) ; degrees to radians conversion float ele = @elevation*(#pi/180.0) int i = 0 int j = 0 int k = 0 int l = 0 int z = 0 int a = 0 int b = 0 int c = @numgenerations int sr = 0 bool f = true ; The lighting Normal lx = cos(rot) * cos(ele) ly = sin(rot) * cos(ele) lz = sin(ele) i = #height + 3 + @offset repeat j = #width + 3 + @offset repeat s[j,i] = 0 until (j=j-1)<0 until (i=i-1)<0 i = ceil((#height+4+@offset)/64) - 1 repeat j = ceil((#width+4+@offset)/64) - 1 repeat k = 16 repeat t[j,i,k] = 0 until (k=k-1)<0 until (j=j-1)<0 until (i=i-1)<0 i = 15 repeat g[i] = 0 tn[i] = 0 top[i] = 100000000 btm[i] = -1 lft[i] = 100000000 rgt[i] = -1 until (i=i-1)<0 mxl = 100000000 mxr = -1 mxu = 100000000 mxd = -1 r = @seed n = 0 q = (#width+@offset)*(#height+@offset) if @use=="Pixel Count" q = @pixels elseif @use=="Percentage" q = round(0.01*@percent*q) endif a = q pn[0] = @palmin1 pn[1] = @palmin2 pn[2] = @palmin3 pn[3] = @palmin4 pn[4] = @palmin5 pn[5] = @palmin6 pn[6] = @palmin7 pn[7] = @palmin8 pn[8] = @palmin9 pn[9] = @palmin10 pn[10] = @palmin11 pn[11] = @palmin12 pn[12] = @palmin13 pn[13] = @palmin14 pn[14] = @palmin15 pn[15] = @palmin16 px[0] = @palmax1 - @palmin1 px[1] = @palmax2 - @palmin2 px[2] = @palmax3 - @palmin3 px[3] = @palmax4 - @palmin4 px[4] = @palmax5 - @palmin5 px[5] = @palmax6 - @palmin6 px[6] = @palmax7 - @palmin7 px[7] = @palmax8 - @palmin8 px[8] = @palmax9 - @palmin9 px[9] = @palmax10 - @palmin10 px[10] = @palmax11 - @palmin11 px[11] = @palmax12 - @palmin12 px[12] = @palmax13 - @palmin13 px[13] = @palmax14 - @palmin14 px[14] = @palmax15 - @palmin15 px[15] = @palmax16 - @palmin16 lc[0] = @lightcol1 lc[1] = @lightcol2 lc[2] = @lightcol3 lc[3] = @lightcol4 lc[4] = @lightcol5 lc[5] = @lightcol6 lc[6] = @lightcol7 lc[7] = @lightcol8 lc[8] = @lightcol9 lc[9] = @lightcol10 lc[10] = @lightcol11 lc[11] = @lightcol12 lc[12] = @lightcol13 lc[13] = @lightcol14 lc[14] = @lightcol15 lc[15] = @lightcol16 m[0] = @method1 m[1] = @method2 m[2] = @method3 m[3] = @method4 m[4] = @method5 m[5] = @method6 m[6] = @method7 m[7] = @method8 m[8] = @method9 m[9] = @method10 m[10] = @method11 m[11] = @method12 m[12] = @method13 m[13] = @method14 m[14] = @method15 m[15] = @method16 nd[0] = @nodirection1*sqrt(#width*#height/(640*480)) nd[1] = @nodirection2*sqrt(#width*#height/(640*480)) nd[2] = @nodirection3*sqrt(#width*#height/(640*480)) nd[3] = @nodirection4*sqrt(#width*#height/(640*480)) nd[4] = @nodirection5*sqrt(#width*#height/(640*480)) nd[5] = @nodirection6*sqrt(#width*#height/(640*480)) nd[6] = @nodirection7*sqrt(#width*#height/(640*480)) nd[7] = @nodirection8*sqrt(#width*#height/(640*480)) nd[8] = @nodirection9*sqrt(#width*#height/(640*480)) nd[9] = @nodirection10*sqrt(#width*#height/(640*480)) nd[10] = @nodirection11*sqrt(#width*#height/(640*480)) nd[11] = @nodirection12*sqrt(#width*#height/(640*480)) nd[12] = @nodirection13*sqrt(#width*#height/(640*480)) nd[13] = @nodirection14*sqrt(#width*#height/(640*480)) nd[14] = @nodirection15*sqrt(#width*#height/(640*480)) nd[15] = @nodirection16*sqrt(#width*#height/(640*480)) sz[0] = ceil(0.01*@size1*(#width+4+@offset)*(#height+4+@offset)) sz[1] = ceil(0.01*@size2*(#width+4+@offset)*(#height+4+@offset)) sz[2] = ceil(0.01*@size3*(#width+4+@offset)*(#height+4+@offset)) sz[3] = ceil(0.01*@size4*(#width+4+@offset)*(#height+4+@offset)) sz[4] = ceil(0.01*@size5*(#width+4+@offset)*(#height+4+@offset)) sz[5] = ceil(0.01*@size6*(#width+4+@offset)*(#height+4+@offset)) sz[6] = ceil(0.01*@size7*(#width+4+@offset)*(#height+4+@offset)) sz[7] = ceil(0.01*@size8*(#width+4+@offset)*(#height+4+@offset)) sz[8] = ceil(0.01*@size9*(#width+4+@offset)*(#height+4+@offset)) sz[9] = ceil(0.01*@size10*(#width+4+@offset)*(#height+4+@offset)) sz[10] = ceil(0.01*@size11*(#width+4+@offset)*(#height+4+@offset)) sz[11] = ceil(0.01*@size12*(#width+4+@offset)*(#height+4+@offset)) sz[12] = ceil(0.01*@size13*(#width+4+@offset)*(#height+4+@offset)) sz[13] = ceil(0.01*@size14*(#width+4+@offset)*(#height+4+@offset)) sz[14] = ceil(0.01*@size15*(#width+4+@offset)*(#height+4+@offset)) sz[15] = ceil(0.01*@size16*(#width+4+@offset)*(#height+4+@offset)) dtct[0] = (@detect1 - 1.0)/#randomrange dtct[1] = (@detect2 - 1.0)/#randomrange dtct[2] = (@detect3 - 1.0)/#randomrange dtct[3] = (@detect4 - 1.0)/#randomrange dtct[4] = (@detect5 - 1.0)/#randomrange dtct[5] = (@detect6 - 1.0)/#randomrange dtct[6] = (@detect7 - 1.0)/#randomrange dtct[7] = (@detect8 - 1.0)/#randomrange dtct[8] = (@detect9 - 1.0)/#randomrange dtct[9] = (@detect10 - 1.0)/#randomrange dtct[10] = (@detect11 - 1.0)/#randomrange dtct[11] = (@detect12 - 1.0)/#randomrange dtct[12] = (@detect13 - 1.0)/#randomrange dtct[13] = (@detect14 - 1.0)/#randomrange dtct[14] = (@detect15 - 1.0)/#randomrange dtct[15] = (@detect16 - 1.0)/#randomrange mov[0] = @move1 mov[1] = @move2 mov[2] = @move3 mov[3] = @move4 mov[4] = @move5 mov[5] = @move6 mov[6] = @move7 mov[7] = @move8 mov[8] = @move9 mov[9] = @move10 mov[10] = @move11 mov[11] = @move12 mov[12] = @move13 mov[13] = @move14 mov[14] = @move15 mov[15] = @move16 ss[0,0] = @seed1stimulus1 ss[0,1] = @seed1stimulus2 ss[0,2] = @seed1stimulus3 ss[0,3] = @seed1stimulus4 ss[0,4] = @seed1stimulus5 ss[0,5] = @seed1stimulus6 ss[0,6] = @seed1stimulus7 ss[0,7] = @seed1stimulus8 ss[0,8] = @seed1stimulus9 ss[0,9] = @seed1stimulus10 ss[0,10] = @seed1stimulus11 ss[0,11] = @seed1stimulus12 ss[0,12] = @seed1stimulus13 ss[0,13] = @seed1stimulus14 ss[0,14] = @seed1stimulus15 ss[0,15] = @seed1stimulus16 ss[1,0] = @seed2stimulus1 ss[1,1] = @seed2stimulus2 ss[1,2] = @seed2stimulus3 ss[1,3] = @seed2stimulus4 ss[1,4] = @seed2stimulus5 ss[1,5] = @seed2stimulus6 ss[1,6] = @seed2stimulus7 ss[1,7] = @seed2stimulus8 ss[1,8] = @seed2stimulus9 ss[1,9] = @seed2stimulus10 ss[1,10] = @seed2stimulus11 ss[1,11] = @seed2stimulus12 ss[1,12] = @seed2stimulus13 ss[1,13] = @seed2stimulus14 ss[1,14] = @seed2stimulus15 ss[1,15] = @seed2stimulus16 ss[2,0] = @seed3stimulus1 ss[2,1] = @seed3stimulus2 ss[2,2] = @seed3stimulus3 ss[2,3] = @seed3stimulus4 ss[2,4] = @seed3stimulus5 ss[2,5] = @seed3stimulus6 ss[2,6] = @seed3stimulus7 ss[2,7] = @seed3stimulus8 ss[2,8] = @seed3stimulus9 ss[2,9] = @seed3stimulus10 ss[2,10] = @seed3stimulus11 ss[2,11] = @seed3stimulus12 ss[2,12] = @seed3stimulus13 ss[2,13] = @seed3stimulus14 ss[2,14] = @seed3stimulus15 ss[2,15] = @seed3stimulus16 ss[3,0] = @seed4stimulus1 ss[3,1] = @seed4stimulus2 ss[3,2] = @seed4stimulus3 ss[3,3] = @seed4stimulus4 ss[3,4] = @seed4stimulus5 ss[3,5] = @seed4stimulus6 ss[3,6] = @seed4stimulus7 ss[3,7] = @seed4stimulus8 ss[3,8] = @seed4stimulus9 ss[3,9] = @seed4stimulus10 ss[3,10] = @seed4stimulus11 ss[3,11] = @seed4stimulus12 ss[3,12] = @seed4stimulus13 ss[3,13] = @seed4stimulus14 ss[3,14] = @seed4stimulus15 ss[3,15] = @seed4stimulus16 ss[4,0] = @seed5stimulus1 ss[4,1] = @seed5stimulus2 ss[4,2] = @seed5stimulus3 ss[4,3] = @seed5stimulus4 ss[4,4] = @seed5stimulus5 ss[4,5] = @seed5stimulus6 ss[4,6] = @seed5stimulus7 ss[4,7] = @seed5stimulus8 ss[4,8] = @seed5stimulus9 ss[4,9] = @seed5stimulus10 ss[4,10] = @seed5stimulus11 ss[4,11] = @seed5stimulus12 ss[4,12] = @seed5stimulus13 ss[4,13] = @seed5stimulus14 ss[4,14] = @seed5stimulus15 ss[4,15] = @seed5stimulus16 ss[5,0] = @seed6stimulus1 ss[5,1] = @seed6stimulus2 ss[5,2] = @seed6stimulus3 ss[5,3] = @seed6stimulus4 ss[5,4] = @seed6stimulus5 ss[5,5] = @seed6stimulus6 ss[5,6] = @seed6stimulus7 ss[5,7] = @seed6stimulus8 ss[5,8] = @seed6stimulus9 ss[5,9] = @seed6stimulus10 ss[5,10] = @seed6stimulus11 ss[5,11] = @seed6stimulus12 ss[5,12] = @seed6stimulus13 ss[5,13] = @seed6stimulus14 ss[5,14] = @seed6stimulus15 ss[5,15] = @seed6stimulus16 ss[6,0] = @seed7stimulus1 ss[6,1] = @seed7stimulus2 ss[6,2] = @seed7stimulus3 ss[6,3] = @seed7stimulus4 ss[6,4] = @seed7stimulus5 ss[6,5] = @seed7stimulus6 ss[6,6] = @seed7stimulus7 ss[6,7] = @seed7stimulus8 ss[6,8] = @seed7stimulus9 ss[6,9] = @seed7stimulus10 ss[6,10] = @seed7stimulus11 ss[6,11] = @seed7stimulus12 ss[6,12] = @seed7stimulus13 ss[6,13] = @seed7stimulus14 ss[6,14] = @seed7stimulus15 ss[6,15] = @seed7stimulus16 ss[7,0] = @seed8stimulus1 ss[7,1] = @seed8stimulus2 ss[7,2] = @seed8stimulus3 ss[7,3] = @seed8stimulus4 ss[7,4] = @seed8stimulus5 ss[7,5] = @seed8stimulus6 ss[7,6] = @seed8stimulus7 ss[7,7] = @seed8stimulus8 ss[7,8] = @seed8stimulus9 ss[7,9] = @seed8stimulus10 ss[7,10] = @seed8stimulus11 ss[7,11] = @seed8stimulus12 ss[7,12] = @seed8stimulus13 ss[7,13] = @seed8stimulus14 ss[7,14] = @seed8stimulus15 ss[7,15] = @seed8stimulus16 ss[8,0] = @seed9stimulus1 ss[8,1] = @seed9stimulus2 ss[8,2] = @seed9stimulus3 ss[8,3] = @seed9stimulus4 ss[8,4] = @seed9stimulus5 ss[8,5] = @seed9stimulus6 ss[8,6] = @seed9stimulus7 ss[8,7] = @seed9stimulus8 ss[8,8] = @seed9stimulus9 ss[8,9] = @seed9stimulus10 ss[8,10] = @seed9stimulus11 ss[8,11] = @seed9stimulus12 ss[8,12] = @seed9stimulus13 ss[8,13] = @seed9stimulus14 ss[8,14] = @seed9stimulus15 ss[8,15] = @seed9stimulus16 ss[9,0] = @seed10stimulus1 ss[9,1] = @seed10stimulus2 ss[9,2] = @seed10stimulus3 ss[9,3] = @seed10stimulus4 ss[9,4] = @seed10stimulus5 ss[9,5] = @seed10stimulus6 ss[9,6] = @seed10stimulus7 ss[9,7] = @seed10stimulus8 ss[9,8] = @seed10stimulus9 ss[9,9] = @seed10stimulus10 ss[9,10] = @seed10stimulus11 ss[9,11] = @seed10stimulus12 ss[9,12] = @seed10stimulus13 ss[9,13] = @seed10stimulus14 ss[9,14] = @seed10stimulus15 ss[9,15] = @seed10stimulus16 ss[10,0] = @seed11stimulus1 ss[10,1] = @seed11stimulus2 ss[10,2] = @seed11stimulus3 ss[10,3] = @seed11stimulus4 ss[10,4] = @seed11stimulus5 ss[10,5] = @seed11stimulus6 ss[10,6] = @seed11stimulus7 ss[10,7] = @seed11stimulus8 ss[10,8] = @seed11stimulus9 ss[10,9] = @seed11stimulus10 ss[10,10] = @seed11stimulus11 ss[10,11] = @seed11stimulus12 ss[10,12] = @seed11stimulus13 ss[10,13] = @seed11stimulus14 ss[10,14] = @seed11stimulus15 ss[10,15] = @seed11stimulus16 ss[11,0] = @seed12stimulus1 ss[11,1] = @seed12stimulus2 ss[11,2] = @seed12stimulus3 ss[11,3] = @seed12stimulus4 ss[11,4] = @seed12stimulus5 ss[11,5] = @seed12stimulus6 ss[11,6] = @seed12stimulus7 ss[11,7] = @seed12stimulus8 ss[11,8] = @seed12stimulus9 ss[11,9] = @seed12stimulus10 ss[11,10] = @seed12stimulus11 ss[11,11] = @seed12stimulus12 ss[11,12] = @seed12stimulus13 ss[11,13] = @seed12stimulus14 ss[11,14] = @seed12stimulus15 ss[11,15] = @seed12stimulus16 ss[12,0] = @seed13stimulus1 ss[12,1] = @seed13stimulus2 ss[12,2] = @seed13stimulus3 ss[12,3] = @seed13stimulus4 ss[12,4] = @seed13stimulus5 ss[12,5] = @seed13stimulus6 ss[12,6] = @seed13stimulus7 ss[12,7] = @seed13stimulus8 ss[12,8] = @seed13stimulus9 ss[12,9] = @seed13stimulus10 ss[12,10] = @seed13stimulus11 ss[12,11] = @seed13stimulus12 ss[12,12] = @seed13stimulus13 ss[12,13] = @seed13stimulus14 ss[12,14] = @seed13stimulus15 ss[12,15] = @seed13stimulus16 ss[13,0] = @seed14stimulus1 ss[13,1] = @seed14stimulus2 ss[13,2] = @seed14stimulus3 ss[13,3] = @seed14stimulus4 ss[13,4] = @seed14stimulus5 ss[13,5] = @seed14stimulus6 ss[13,6] = @seed14stimulus7 ss[13,7] = @seed14stimulus8 ss[13,8] = @seed14stimulus9 ss[13,9] = @seed14stimulus10 ss[13,10] = @seed14stimulus11 ss[13,11] = @seed14stimulus12 ss[13,12] = @seed14stimulus13 ss[13,13] = @seed14stimulus14 ss[13,14] = @seed14stimulus15 ss[13,15] = @seed14stimulus16 ss[14,0] = @seed15stimulus1 ss[14,1] = @seed15stimulus2 ss[14,2] = @seed15stimulus3 ss[14,3] = @seed15stimulus4 ss[14,4] = @seed15stimulus5 ss[14,5] = @seed15stimulus6 ss[14,6] = @seed15stimulus7 ss[14,7] = @seed15stimulus8 ss[14,8] = @seed15stimulus9 ss[14,9] = @seed15stimulus10 ss[14,10] = @seed15stimulus11 ss[14,11] = @seed15stimulus12 ss[14,12] = @seed15stimulus13 ss[14,13] = @seed15stimulus14 ss[14,14] = @seed15stimulus15 ss[14,15] = @seed15stimulus16 ss[15,0] = @seed16stimulus1 ss[15,1] = @seed16stimulus2 ss[15,2] = @seed16stimulus3 ss[15,3] = @seed16stimulus4 ss[15,4] = @seed16stimulus5 ss[15,5] = @seed16stimulus6 ss[15,6] = @seed16stimulus7 ss[15,7] = @seed16stimulus8 ss[15,8] = @seed16stimulus9 ss[15,9] = @seed16stimulus10 ss[15,10] = @seed16stimulus11 ss[15,11] = @seed16stimulus12 ss[15,12] = @seed16stimulus13 ss[15,13] = @seed16stimulus14 ss[15,14] = @seed16stimulus15 ss[15,15] = @seed16stimulus16 merge = new @merge(this) DLAStimulus[0] = new @DLAStimulus1(this) if @numstimuli>0 DLAStimulus[1] = new @DLAStimulus2(this) if @numstimuli>1 DLAStimulus[2] = new @DLAStimulus3(this) if @numstimuli>2 DLAStimulus[3] = new @DLAStimulus4(this) if @numstimuli>3 DLAStimulus[4] = new @DLAStimulus5(this) if @numstimuli>4 DLAStimulus[5] = new @DLAStimulus6(this) if @numstimuli>5 DLAStimulus[6] = new @DLAStimulus7(this) if @numstimuli>6 DLAStimulus[7] = new @DLAStimulus8(this) if @numstimuli>7 DLAStimulus[8] = new @DLAStimulus9(this) if @numstimuli>8 DLAStimulus[9] = new @DLAStimulus10(this) if @numstimuli>9 DLAStimulus[10] = new @DLAStimulus11(this) if @numstimuli>10 DLAStimulus[11] = new @DLAStimulus12(this) if @numstimuli>11 DLAStimulus[12] = new @DLAStimulus13(this) if @numstimuli>12 DLAStimulus[13] = new @DLAStimulus14(this) if @numstimuli>13 DLAStimulus[14] = new @DLAStimulus15(this) if @numstimuli>14 DLAStimulus[15] = new @DLAStimulus16(this) endif endif endif endif endif endif endif endif endif endif endif endif endif endif endif DLADead = new @DLADead(this) ; "dead" point seeding o = 0 DLASeed[0] = new @DLASeed1(this) if @numplants>0 o = 1 DLASeed[1] = new @DLASeed2(this) if @numplants>1 o = 2 DLASeed[2] = new @DLASeed3(this) if @numplants>2 o = 3 DLASeed[3] = new @DLASeed4(this) if @numplants>3 o = 4 DLASeed[4] = new @DLASeed5(this) if @numplants>4 o = 5 DLASeed[5] = new @DLASeed6(this) if @numplants>5 o = 6 DLASeed[6] = new @DLASeed7(this) if @numplants>6 o = 7 DLASeed[7] = new @DLASeed8(this) if @numplants>7 o = 8 DLASeed[8] = new @DLASeed9(this) if @numplants>8 o = 9 DLASeed[9] = new @DLASeed10(this) if @numplants>9 o = 10 DLASeed[10] = new @DLASeed11(this) if @numplants>10 o = 11 DLASeed[11] = new @DLASeed12(this) if @numplants>11 o = 12 DLASeed[12] = new @DLASeed13(this) if @numplants>12 o = 13 DLASeed[13] = new @DLASeed14(this) if @numplants>13 o = 14 DLASeed[14] = new @DLASeed15(this) if @numplants>14 o = 15 DLASeed[15] = new @DLASeed16(this) endif endif endif endif endif endif endif endif endif endif endif endif endif endif endif if n==0 $define DEBUG print("Major Problem !") print("No organism seeds planted.") print("You need to rethink your seeding.") $undef DEBUG else i = @numplants repeat if tn[i]==0 $define DEBUG print("Warning: No seeds planted for organism ",i+1) print("You may want to rethink your seeding.") $undef DEBUG endif until (i=i-1)<0 z = 100000 b = q repeat o = 0 repeat if (d=nd[o])>0.0 && tn[o]>0 && sz[o]>0 if tn[o]=1.0 RandomGrowth(abs(r=random(r))%tn[o]) d = d - 1.0 endwhile if abs(r=random(r))/#randomrange@numplants i = @numstimuli l = @pixelgrowth - 1 sr = @symmetry - 1 repeat maxleft = 100000000 maxright = -1 maxup = 100000000 maxdown = -1 o = @numplants repeat if ss[o,i] && tn[o]>0 && sz[o]>0 if lft[o]maxright maxright = rgt[o] endif if top[o]maxdown maxdown = btm[o] endif endif until (o=o-1)<0 if maxright>=0 if l<@pixelgrowth - 1 || sr<@symmetry - 1 if @notinside f = true endif pgx = real(p) pgy = imag(p) if pgx<0.0 pgx = 0.0 elseif pgx>#width+3+@offset pgx = #width+3+@offset endif if pgy<0.0 pgy = 0.0 elseif pgy>#height+3+@offset pgy = #height+3+@offset endif bx = floor(pgx/64) by = floor(pgy/64) elseif @notinside f = true j = @numtries repeat p = DLAStimulus[i].GetPoint(maxleft,maxright,maxup,maxdown) pgx = real(p) pgy = imag(p) if pgx<0.0 pgx = 0.0 elseif pgx>#width+3+@offset pgx = #width+3+@offset endif if pgy<0.0 pgy = 0.0 elseif pgy>#height+3+@offset pgy = #height+3+@offset endif bx = floor(pgx/64) by = floor(pgy/64) if s[floor(pgx),floor(pgy)]>0 f = false endif until f || (j=j-1)<=0 else p = DLAStimulus[i].GetPoint(maxleft,maxright,maxup,maxdown) pgx = real(p) pgy = imag(p) if pgx<0.0 pgx = 0.0 elseif pgx>#width+3+@offset pgx = #width+3+@offset endif if pgy<0.0 pgy = 0.0 elseif pgy>#height+3+@offset pgy = #height+3+@offset endif bx = floor(pgx/64) by = floor(pgy/64) endif fo = -1 if !@notinside || f maxleft = floor(maxleft/64) maxright = floor(maxright/64) maxup = floor(maxup/64) maxdown = floor(maxdown/64) v = DLAStimulus[i].GetRange() \ *(0.0001*(sqr(#width+5)+sqr(#height+5))) if (d = DLADead.DeadDistance(pgx,pgy))maxleft maxleft = j endif if (j=ceil((pgx+d)/64) - 1)maxup maxup = j endif if (j=ceil((pgy+d)/64) - 1)0 && sz[o]>0 PointGrowth() endif until (o=o-1)<0 if fk>=0 o = fo NewGrowth(fk,sx[fx,fy,fk],sy[fx,fy,fk],fx,fy) if @seeds=="Diamond" MoreGrowth(sx[fx,fy,fk],sy[fx,fy,fk]-1) MoreGrowth(sx[fx,fy,fk]-1,sy[fx,fy,fk]) MoreGrowth(sx[fx,fy,fk]+1,sy[fx,fy,fk]) MoreGrowth(sx[fx,fy,fk],sy[fx,fy,fk]+1) endif endif endif o = 0 repeat if o!=fo && (d=-nd[o])>0.0 && tn[o]>0 && sz[o]>0 if tn[o]=1.0 RandomGrowth(abs(r=random(r))%tn[o]) d = d - 1.0 endwhile if abs(r=random(r))/#randomrange@numplants else l = 0 sr = 0 endif if (l = l - 1)<0 if @fixpixels || @symmetry>1 l = @pixelgrowth - 1 else l = 1 endif if @symmetry>1 if (sr = sr - 1)<0 sr = @symmetry - 1 i = i - 1 else pqy = 2.0*(sr + 1)*#pi/@symmetry pqx = sin(pqy) pqy = cos(pqy) p = p - 0.5*(#width + flip(#height)) p = real(p)*pqy + imag(p)*pqx + flip(imag(p)*pqy - real(p)*pqx) p = p + 0.5*(#width + flip(#height)) endif else i = i - 1 endif endif until i<0 c = c - 1 if (z=z-1)<=0 z = 100000 if b-q<=@fail*100000 n = -n endif b = q if @showprogress $define DEBUG if @use=="Pixel Count" print(" ",@pixels-q," pixels remaining.") elseif @use=="Percentage" print(" ",floor(10000*((a-q)/a))/100,"% completed") else print(" ",c," generations to go.") endif $undef DEBUG endif endif until n<=0 || q<=0 || (@use=="Generations" && c<=0) endif if @showprogress $define DEBUG print("Completed.") print("Number of Generations ",@numgenerations-c) print("Sceeen Pixels Remaining ",(#width+@offset)*(#height+@offset) \ - a + q) print("Screen %age converted ",round(10000*((a-q) \ /((#width+@offset)*(#height+@offset)))) \ /100 ) print("Seed points remaining ",abs(n)) $undef DEBUG endif endfunc ; @param k the number of the seed to grow func RandomGrowth(int k) int i = ceil((#height+4+@offset)/64) - 1 repeat int j = ceil((#width+4+@offset)/64) - 1 repeat if t[j,i,o+1]-t[j,i,o]>k k = k + t[j,i,o] int x = sx[j,i,k] int y = sy[j,i,k] NewGrowth(k,x,y,j,i) return else k = k + t[j,i,o] - t[j,i,o+1] endif until (j=j-1)<0 until (i=i-1)<0 endfunc func PointGrowth() float w float d float dx float dy float det = dtct[o] float mv = mov[o] int xs int ys int xe int ye int ix int iy int e int off = 10000 if bxmaxright off = bx - maxright endif if bymaxdown if by-maxdownmaxright e = e + 1 xe = maxright endif if (ye=by+off)>maxdown e = e + 1 ye = maxdown endif if e<4 iy = ys ix = xs repeat if t[ix,iy,o+1]>t[ix,iy,o] int i = t[ix,iy,o+1] - 1 repeat w = sqr(dx=pgx-sx[ix,iy,i]) + sqr(dy=pgy-sy[ix,iy,i]) if @addrandom && det>0.0 w = w*sqr(1.0 + abs(r=random(r))*det) endif if @addmovement && dir!=0.0 && mv>0.0 d = sqrt(w) w = sqr(d + mv*(d - dx*real(dir) - dy*imag(dir))) endif if wmaxleft maxleft = fx endif if (fx=ceil((pgx+w)/64) - 1)maxup maxup = fy endif if (fy=ceil((pgy+w)/64) - 1)xe if ye>ys iy = ye ix = xs repeat if t[ix,iy,o+1]>t[ix,iy,o] int i = t[ix,iy,o+1] - 1 repeat w = sqr(dx=pgx-sx[ix,iy,i]) + sqr(dy=pgy-sy[ix,iy,i]) if @addrandom && det>0.0 w = w*sqr(1.0 + abs(r=random(r))*det) endif if @addmovement && dir!=0.0 && mv>0.0 d = sqrt(w) w = sqr(d + mv*(d - dx*real(dir) - dy*imag(dir))) endif if wmaxleft maxleft = fx endif if (fx=ceil((pgx+w)/64) - 1)maxup maxup = fy endif if (fy=ceil((pgy+w)/64) - 1)xe if (iy=ys+1)t[ix,iy,o] int i = t[ix,iy,o+1] - 1 repeat w = sqr(dx=pgx-sx[ix,iy,i]) + sqr(dy=pgy-sy[ix,iy,i]) if @addrandom && det>0.0 w = w*sqr(1.0 + abs(r=random(r))*det) endif if @addmovement && dir!=0.0 && mv>0.0 d = sqrt(w) w = sqr(d + mv*(d - dx*real(dir) - dy*imag(dir))) endif if wmaxleft maxleft = fx endif if (fx=ceil((pgx+w)/64) - 1)maxup maxup = fy endif if (fy=ceil((pgy+w)/64) - 1)=ye if xe>xs ix = xe iy = ys + 1 repeat if t[ix,iy,o+1]>t[ix,iy,o] int i = t[ix,iy,o+1] - 1 repeat w = sqr(dx=pgx-sx[ix,iy,i]) + sqr(dy=pgy-sy[ix,iy,i]) if @addrandom && det>0.0 w = w*sqr(1.0 + abs(r=random(r))*det) endif if @addmovement && dir!=0.0 && mv>0.0 d = sqrt(w) w = sqr(d + mv*(d - dx*real(dir) - dy*imag(dir))) endif if wmaxleft maxleft = fx endif if (fx=ceil((pgx+w)/64) - 1)maxup maxup = fy endif if (fy=ceil((pgy+w)/64) - 1)=ye endif endif endif off = off + 1 endif until e>=4 endfunc float func DeadDist() float w int xs int ys int xe int ye int ix int iy int e int maxleft = mxl int maxright = mxr int maxup = mxu int maxdown = mxd int off = 10000 if bxmxr off = bx - mxr endif if bymxd if by-mxdmaxright e = e + 1 xe = maxright endif if (ye=by+off)>maxdown e = e + 1 ye = maxdown endif if e<4 iy = ys ix = xs repeat if t[ix,iy,0]>0 int i = t[ix,iy,0] - 1 repeat if (w=sqr(pgx-sx[ix,iy,i])+sqr(pgy-sy[ix,iy,i]))maxleft maxleft = fx endif if (fx=ceil((pgx+w)/64) - 1)maxup maxup = fy endif if (fy=ceil((pgy+w)/64) - 1)xe if ye>ys iy = ye ix = xs repeat if t[ix,iy,0]>0 int i = t[ix,iy,0] - 1 repeat if (w=sqr(pgx-sx[ix,iy,i])+sqr(pgy-sy[ix,iy,i]))maxleft maxleft = fx endif if (fx=ceil((pgx+w)/64) - 1)maxup maxup = fy endif if (fy=ceil((pgy+w)/64) - 1)xe if (iy=ys+1)0 int i = t[ix,iy,0] - 1 repeat if (w=sqr(pgx-sx[ix,iy,i])+sqr(pgy-sy[ix,iy,i]))maxleft maxleft = fx endif if (fx=ceil((pgx+w)/64) - 1)maxup maxup = fy endif if (fy=ceil((pgy+w)/64) - 1)=ye if xe>xs ix = xe iy = ys + 1 repeat if t[ix,iy,0]>0 int i = t[ix,iy,0] - 1 repeat if (w=sqr(pgx-sx[ix,iy,i])+sqr(pgy-sy[ix,iy,i]))maxleft maxleft = fx endif if (fx=ceil((pgx+w)/64) - 1)maxup maxup = fy endif if (fy=ceil((pgy+w)/64) - 1)=ye endif endif endif off = off + 1 endif until e>=4 return v endfunc ; @param k the index for the point number ; @param x pixel x coordinate ; @param y pixel y coordinate ; @param ix 64*64 box x index ; @param iy 64*64 box y index func NewGrowth(int k, int x, int y, int ix, int iy) int i = o + 1 int j if s[x,y]==-1 s[x,y] = (g[o]=g[o]+1)*16 + o if x>=2 && x<=#width+1+@offset && y>=2 && y<=#height+1+@offset q = q - 1 endif n = n - 1 tn[o] = tn[o] - 1 sz[o] = sz[o] - 1 repeat t[ix,iy,i] = t[ix,iy,i] - 1 sx[ix,iy,k] = sx[ix,iy,t[ix,iy,i]] sy[ix,iy,k] = sy[ix,iy,t[ix,iy,i]] k = t[ix,iy,i] until (i=i+1)>@numplants+1 x = x - 1 y = y - 1 if (i=y+2)<=#height+3+@offset if @seeds=="Square" j = x + 2 repeat if j>=0 && j<=#width+3+@offset && s[j,i]==0 NewSeed(j,i) endif until (j=j-1)=0 if s[x,i]==0 NewSeed(x,i) endif endif if y>=0 if @seeds=="Square" j = x + 2 repeat if j>=0 && j<=#width+3+@offset && s[j,y]==0 NewSeed(j,y) endif until (j=j-1)=0 && x<=#width+3+@offset && y>=0 && y<=#height+3+@offset int ix = floor(x/64) int iy = floor(y/64) int i = t[ix,iy,o+1] while (i=i-1)>=t[ix,iy,o] if sx[ix,iy,i]==x && sy[ix,iy,i]==y NewGrowth(i,x,y,ix,iy) i = -1 endif endwhile endif endfunc ; @param x the x pixel coordinate ; @param y the y pixel coordinate func NewSeed(int x,int y) int i = @numplants + 1 int ix = floor(x/64) int iy = floor(y/64) repeat sx[ix,iy,t[ix,iy,i]] = sx[ix,iy,t[ix,iy,i-1]] sy[ix,iy,t[ix,iy,i]] = sy[ix,iy,t[ix,iy,i-1]] t[ix,iy,i] = t[ix,iy,i] + 1 until (i=i-1)<=o sx[ix,iy,t[ix,iy,o]] = x sy[ix,iy,t[ix,iy,o]] = y if xrgt[o] rgt[o] = x endif if ybtm[o] btm[o] = y endif tn[o] = tn[o] + 1 if x>0 && x<#width+3+@offset && y>0 && y<#height+3+@offset n = n + 1 s[x,y] = -1 else s[x,y] = -2 endif endfunc ; @param x the x pixel coordinate ; @param y the y pixel coordinate ; @param c the dead point colour ; @param i the dead point palette index func SetDeadPoint(int x,int y,color c,float i) if s[x,y]==0 s[x,y] = -3 - (round(red(c)*127)*128 + round(green(c)*127))*128 \ - round(blue(c)*127) - floor(i)*128*128*128 int ix = floor(x/64) int iy = floor(y/64) sx[ix,iy,t[ix,iy,0]] = x sy[ix,iy,t[ix,iy,0]] = y if ixmxr mxr = ix endif if iymxd mxd = iy endif t[ix,iy,0] = t[ix,iy,0] + 1 int j = 0 while (j=j+1)<=@numplants+1 t[ix,iy,j] = t[ix,iy,0] endwhile q = q - 1 endif endfunc ; @param x the x pixel coordinate ; @param y the y pixel coordinate func SetStartPoint(int x,int y) if s[x,y]==0 s[x,y] = -1 int ix = floor(x/64) int iy = floor(y/64) sx[ix,iy,t[ix,iy,o+1]] = x sy[ix,iy,t[ix,iy,o+1]] = y if xrgt[o] rgt[o] = x endif if ybtm[o] btm[o] = y endif t[ix,iy,o+1] = t[ix,iy,o+1] + 1 int i = o+1 while (i=i+1)<=@numplants+1 t[ix,iy,i] = t[ix,iy,o+1] endwhile tn[o] = tn[o] + 1 n = n + 1 endif endfunc func Iterate(complex pz) endfunc color func Result(complex pz) float c = 0.0025*@backcol color clr = gradient(c) int v = s[2+floor(real(#screenpixel)),2+floor(imag(#screenpixel))] if v<-2 v = (-(v + 3))%(128*128*128) return RGBA(floor(v/(128*128))/128,floor((v%(128*128))/128)/128, \ floor(v%128)/128,1) elseif v<=0 if @backmethod==0 m_Solid = true endif else o = v%16 c = 0.0025*(pn[o] + px[o]*v/(16*g[o])) clr = gradient(c) if m[o]>0 float c1 = 0.5*(1.0 + @ambient) if @sample && @offset>1 float c2 int v1 int n1 = 0 int n2 = 0 int n3 = 0 float t1 = 0.0 float t2 = 0.0 float t3 = 0.0 int i = 0 if @altsample && @offset%2==0 repeat int j = 0 repeat v1 = s[j + 2 + floor(real(#screenpixel)), \ i + 2 + floor(imag(#screenpixel))] if v1>0 if o==v1%16 n1 = n1 + 1 t1 = t1 + 0.0025*(pn[o] + px[o]*v1/(16*g[o])) endif endif until (j=j+1)>=@offset/2 until (i=i+1)>=@offset/2 i = 0 repeat int j = floor(@offset/2) repeat v1 = s[j + 2 + floor(real(#screenpixel)), \ i + 2 + floor(imag(#screenpixel))] if v1>0 if o==v1%16 n2 = n2 + 1 t2 = t2 + 0.0025*(pn[o] + px[o]*v1/(16*g[o])) endif endif until (j=j+1)>=@offset until (i=i+1)>=@offset/2 i = floor(@offset/2) repeat int j = 0 repeat v1 = s[j + 2 + floor(real(#screenpixel)), \ i + 2 + floor(imag(#screenpixel))] if v1>0 if o==v1%16 n3 = n3 + 1 t3 = t3 + 0.0025*(pn[o] + px[o]*v1/(16*g[o])) endif endif until (j=j+1)>=@offset/2 until (i=i+1)>=@offset else repeat int j = 0 repeat v1 = s[j + 2 + floor(real(#screenpixel)), \ i + 2 + floor(imag(#screenpixel))] if v1>0 if o==v1%16 if i<@offset && j<@offset n1 = n1 + 1 t1 = t1 + 0.0025*(pn[o] + px[o]*v1/(16*g[o])) endif if j>0 && i<@offset n2 = n2 + 1 t2 = t2 + 0.0025*(pn[o] + px[o]*v1/(16*g[o])) endif if i>0 && j<@offset n3 = n3 + 1 t3 = t3 + 0.0025*(pn[o] + px[o]*v1/(16*g[o])) endif endif endif until (j=j+1)>@offset until (i=i+1)>@offset endif if n1>0 && n2>0 && n3>0 t1 = t1/n1 t2 = t2/n2 - t1 t3 = t3/n3 - t1 c1 = @ambient + 0.5*(1.0 - @ambient) \ *(1.0 + (lx*t2 + ly*t3 + lz*(@offset*@lscale)) \ /sqrt(sqr(t2)+sqr(t3)+sqr(@offset*@lscale))) endif elseif @offset+2+floor(real(#screenpixel))<#width+4+@offset \ && @offset+2+floor(imag(#screenpixel))<#height+4+@offset int v1 = s[@offset + 2 + floor(real(#screenpixel)), \ 2 + floor(imag(#screenpixel))] int v2 = s[2 + floor(real(#screenpixel)), \ @offset + 2 + floor(imag(#screenpixel))] if v1>0 && v2>0 if o==v1%16 && o==v2%16 c1 = 0.0025*(pn[o] + px[o]*v1/(16*g[o])) - c float c2 = 0.0025*(pn[o] + px[o]*v2/(16*g[o])) - c c1 = @ambient + 0.5*(1.0 - @ambient) \ *(1.0 + (lx*c1 + ly*c2 + lz*(0.1*@offset*@lscale)) \ /sqrt(sqr(c1)+sqr(c2)+sqr(0.1*@offset*@lscale))) endif endif endif if m[0]==1 clr = gradient(c1) else color lt = lc[o]*c1 lt = rgba(red(lt), green(lt), blue(lt), 1.0) if @reverse clr = merge.FullMerge(lt,clr,@opacity) else clr = merge.FullMerge(clr,lt,@opacity) endif endif endif endif return clr endfunc float func ResultIndex(complex pz) float c = 0.0025*@backcol int v = s[2+floor(real(#screenpixel)),2+floor(imag(#screenpixel))] if v<-2 c = 0.0025*floor(-(v + 3)/(128*128*128)) elseif v<=0 if @backmethod==0 m_Solid = true endif else o = v%16 c = 0.0025*(pn[o] + px[o]*v/(16*g[o])) if m[o]==1 float c1 = 0.5*(1.0 + @ambient) if @sample && @offset>1 float c2 int v1 int n1 = 0 int n2 = 0 int n3 = 0 float t1 = 0.0 float t2 = 0.0 float t3 = 0.0 int i = 0 if @altsample && @offset%2==0 repeat int j = 0 repeat v1 = s[j + 2 + floor(real(#screenpixel)), \ i + 2 + floor(imag(#screenpixel))] if v1>0 if o==v1%16 n1 = n1 + 1 t1 = t1 + 0.0025*(pn[o] + px[o]*v1/(16*g[o])) endif endif until (j=j+1)>=@offset/2 until (i=i+1)>=@offset/2 i = 0 repeat int j = floor(@offset/2) repeat v1 = s[j + 2 + floor(real(#screenpixel)), \ i + 2 + floor(imag(#screenpixel))] if v1>0 if o==v1%16 n2 = n2 + 1 t2 = t2 + 0.0025*(pn[o] + px[o]*v1/(16*g[o])) endif endif until (j=j+1)>=@offset until (i=i+1)>=@offset/2 i = floor(@offset/2) repeat int j = 0 repeat v1 = s[j + 2 + floor(real(#screenpixel)), \ i + 2 + floor(imag(#screenpixel))] if v1>0 if o==v1%16 n3 = n3 + 1 t3 = t3 + 0.0025*(pn[o] + px[o]*v1/(16*g[o])) endif endif until (j=j+1)>=@offset/2 until (i=i+1)>=@offset else repeat int j = 0 repeat v1 = s[j + 2 + floor(real(#screenpixel)), \ i + 2 + floor(imag(#screenpixel))] if v1>0 if o==v1%16 if i<@offset && j<@offset n1 = n1 + 1 t1 = t1 + 0.0025*(pn[o] + px[o]*v1/(16*g[o])) endif if j>0 && i<@offset n2 = n2 + 1 t2 = t2 + 0.0025*(pn[o] + px[o]*v1/(16*g[o])) endif if i>0 && j<@offset n3 = n3 + 1 t3 = t3 + 0.0025*(pn[o] + px[o]*v1/(16*g[o])) endif endif endif until (j=j+1)>@offset until (i=i+1)>@offset endif if n1>0 && n2>0 && n3>0 t1 = t1/n1 t2 = t2/n2 - t1 t3 = t3/n3 - t1 c1 = @ambient + 0.5*(1.0 - @ambient) \ *(1.0 + (lx*t2 + ly*t3 + lz*(@offset*@lscale)) \ /sqrt(sqr(t2)+sqr(t3)+sqr(@offset*@lscale))) endif elseif @offset+2+floor(real(#screenpixel))<#width+4+@offset \ && @offset+2+floor(imag(#screenpixel))<#height+4+@offset int v1 = s[@offset + 2 + floor(real(#screenpixel)), \ 2 + floor(imag(#screenpixel))] int v2 = s[2 + floor(real(#screenpixel)), \ @offset + 2 + floor(imag(#screenpixel))] if v1>0 && v2>0 if o==v1%16 && o==v2%16 c1 = 0.0025*(pn[o] + px[o]*v1/(16*g[o])) - c float c2 = 0.0025*(pn[o] + px[o]*v2/(16*g[o])) - c c1 = @ambient + 0.5*(1.0 - @ambient) \ *(1.0 + (lx*c1 + ly*c2 + lz*(0.1*@offset*@lscale)) \ /sqrt(sqr(c1)+sqr(c2)+sqr(0.1*@offset*@lscale))) endif endif endif c = c1 endif endif return c endfunc bool func IsSolid() return m_Solid endfunc protected: int s[#width+4+@offset,#height+4+@offset] int sx[ceil((#width+4+@offset)/64),ceil((#height+4+@offset)/64),4096] int sy[ceil((#width+4+@offset)/64),ceil((#height+4+@offset)/64),4096] int t[ceil((#width+4+@offset)/64),ceil((#height+4+@offset)/64),17] MMF_StimulusDLA DLAStimulus[16] MMF_SeedDLA DLASeed[16] MMF_DeadDLA DLADead DefaultColorMerge merge float pn[16] float px[16] float dtct[16] float mov[16] color lc[16] int m[16] int g[16] int tn[16] int top[16] int btm[16] int lft[16] int rgt[16] int sz[16] complex dir float lx float ly float lz float v float pgx float pgy int r int n int o int q int bx int by int fk int fx int fy int fo int maxleft int maxright int maxup int maxdown int mxl int mxr int mxu int mxd default: title = "MMF DLA Inspired" heading text = "IMPORTANT: This colouring is intended for use with a 'Pixel' \ formula such as mt.ufm-Pixel. \ Note that you should plug this object into either \ 'Generic Coloring (Gradient) Render=false' or 'Generic Coloring \ (Direct) Render=false' from mmf5.ucl. \ The formula is inspired by Diffusion Limited Aggregation. \ Unlike DLA it does not use random particle motion to generate \ the fractal, rather random stimuli locations are generated and \ the fractal grows from the closest seed point to the stimulus \ adding to the available seed points at the same time. \ You can create up to 16 different organisms \ each of which may have multiple initial seed points. \ You choose the number of organisms and how each is seeded in the \ screen area and individuals are then grown from the seeds. \ In each generation the organisms grow by one or more \ points, the points of growth either being simply random or \ based on a location where a stimulus is generated. \ You should note that the combined lighting and colouring \ options only work if you plug this formula into the '(Direct)' \ colouring. The formula is designed to be used with the main UF \ gradient parameters set at the default values i.e. 'Color \ Density' set to 1, 'Transfer Function' Linear and 'Gradient \ Offset' zero. The DLA algorithm itself is pixel-based so you \ can't zoom in or out or change location, however the fractal \ plug-ins for seeding and for dead points will respond to \ changes in magnification and location enabling you to use any \ part of another fractal as the seeds and/or the dead points." endheading bool param showprogress caption = "Show Progress" default = false hint = "When enabled progress is shown by means of compiler messages. \ If enabled and no compiler messages are produced then try hitting \ the 'Reload Formula' button for the colouring." endparam int param seed caption = "Random Seed" default = 12345678 hint = "This is the overall random control seed. Changing this will \ modify all directionless growth patterns." endparam int param use caption = "Completion target" enum = "Pixel Count" "Percentage" "Generations" default = 1 hint = "Growth is continued until your completion target is met or \ until the maximum possible area is covered. 'Pixel Count' stops \ growth when the specified number of pixels have been converted, \ 'Percentage' when the specified percentage of the screen area is \ converted and 'Generations' when the specified number of \ generations of growth is completed." endparam int param pixels caption = "Number of Pixels" default = 20000 min = 1 hint = "Growth is stopped when this many pixels have 'grown' or when \ growth has ceased." visible = @use==0 endparam float param percent caption = "Percentage of Screen" default = 100.0 min = 0.1 max = 100.0 hint = "Growth is stopped when this %age of the screen has 'grown' or \ when growth has ceased." visible = @use==1 endparam int param numgenerations caption = "No. of Generations" default = 10000 min = 1 hint = "The more generations the greater the area of growth but the \ longer the render time. Growth will always stop when all \ possible growth points are converted even if the target number \ of generations is not reached." visible = @use==2 endparam float param fail caption = "Failure Rate" default = 0.01 min = 0.0 max = 1.0 hint = "Assumes growth has stopped when this many or fewer pixels are \ produced per generation. Set to zero if you wish maximum \ possible growth." endparam int param seeds caption = "Seeding Method" enum = "Star" "Square" "Diamond" default = 0 hint = "Using 'Star' seeds are only planted on horizontally and/or \ vertically adjacent pixels to growth points. Using 'Square' \ seeds are planted on the diagonally adjacent pixels as well. \ Using 'Diamond' points are grown in the star shape and the \ surrounding diamond is seeded." endparam int param symmetry caption = "Symmetry" default = 1 hint = "Use values>1 to add rotational symmetry to the seeding." endparam int param pixelgrowth caption = "Points per Stimulus" default = 1 min = 1 hint = "The number of points to grow per organism per stimulus location." endparam bool param fixpixels caption = "Fix Points per Stimulus" default = false hint = "Fixes an error in the original where the points per stimulus \ was only used on the first stimulus. When this is enabled if \ 'Points per Stimulus' is >1 then it is applied to all stimuli \ instead of just the first." visible = @symmetry<2 endparam bool param notinside caption = "Restrict Stimulus Locations" default = false hint = "When enabled the locations of the stimuli are restricted to \ points not already part of the fractal. You should note that \ when enabled and not using any 'Directionless Growth' then you \ should not expect all pixels to 'grow', in other words if using \ 'Pixel Count' or 'Percentage' as the 'Completeion Target' then \ if your values are too high completion may be slow." endparam int param numtries caption = "Number of Tries" default = 10 min = 1 hint = "This is the maximum number of times to try growth of the \ organisms per generation i.e. generate a stimulus either until \ growth is allowed or until this many stimulus locations have \ been tried." visible = @notinside endparam int param backmethod caption = "'Background' Method" enum = "Solid Colour" "Palette colour" default = 0 hint = "Here you can choose to have pixels that are neither 'dead' \ points nor growth points coloured either using the 'Solid Color' \ or by specifying the palette index of the colour to use." endparam float param backcol caption = "Background Colour" default = 399.0 min = 0.0 hint = "Here you can specify the palette index of the background colour." visible = @backmethod==1 endparam int param offset caption = "Lighting Pixel Offset" default = 1 min = 1 max = 50 hint = "Specifies the pixel spread for calculating the lighting normals. \ You may want to increase the value for larger renders, e.g. 1 for \ 640*480, say 2 for 1280*960 etc. The maximum is 50." endparam bool param sample caption = "Multi-Sample" default = false hint = "When disabled the lighting is simply calculated from the main \ point and two points offset horizontally and vertically by the \ 'Lighting Pixel Offset'. When enabled all pixels in a square of \ side 'Lighting Pixel Offset' with the main pixel as the top-left \ are used in the lighting calculation (for each pixel in the \ square that pixel and the pixel to the right and below are used \ to calculate the light value for that point and the result from \ all the points in the square is averaged)." visible = @offset>1 endparam bool param altsample caption = "Alternative Sampling" default = false hint = "When enabled the 'Multi-Sample' method is changed slightly, \ instead of averaging over the whole area, the area is split \ into 2*2 squares (each of side 'Lighting Pixel Offset/2) and \ the top-left, top-right and bottom-left of these are sampled \ for the lighting." visible = @offset%2==0 && @sample endparam float param lscale caption = "Light Pre-scale" default = 1.0 min = 1e-200 hint = "The pre-scale for the lighting. Values closer to zero will \ accentuate the lighting (i.e. >0 and <1). Values >1 will reduce \ the lighting effect." endparam float param angle caption = "Light Rotation" default = 90.0 hint = "Gives the rotation of any light source, in degrees. With 0 \ degrees, the light comes from above. Positive values give \ clockwise rotation." endparam float param elevation caption = "Light Elevation" default = 30.0 hint = "Gives the elevation of any light source, in degrees." endparam float param ambient caption = "Ambient Light" default = 0.0 hint = "Specifies the level of ambient light, usual range is from \ -1 to +1. Use -1 for no ambient." endparam DefaultColorMerge param merge caption = "Lighting Merge method" default = MMF_ExtendedColorMerge hint = "This plug-in is ignored if 'MMF DLA Inspired' is plugged \ into a gradient colouring rather than a direct colouring." endparam bool param reverse caption = "Reverse the Merging" default = false hint = "When enabled the order of merging the colouring and lighting \ is reversed from the norm. \ This parameter is ignored if 'MMF DLA Inspired' is plugged \ into a gradient colouring rather than a direct colouring." endparam float param opacity caption = "Merge Opacity" default = 1.0 hint = "The merge opacity for combined colouring organisms. \ This parameter is ignored if 'MMF DLA Inspired' is plugged \ into a gradient colouring rather than a direct colouring." endparam heading caption = "Advanced Options" endheading bool param addrandom caption = "Added Detection Accuracy" default = false hint = "When enabled you will have extra parameters on your organisms \ to set a detection accuracy. Changing the detection accuracy \ will change their fractal nature." endparam bool param addmovement caption = "Added Stimulus Movement" default = false hint = "When enabled the stimuli 'Direction of Movement' parameters \ come into play as do the organism parameters to control how \ well the organisms detect stimulus movement." endparam heading caption = "The Stimuli" text = "You can select up to 16 different types of stimuli each of \ which may be produced in multiple ways. In the organism \ parameters you can control whether each organism is affected by \ any/all of the stimuli." endheading int param numstimuli caption = "Number of Stimuli" enum = "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" \ "15" "16" default = 0 endparam MMF_StimulusDLA param DLAStimulus1 caption = "Stimulus 1" default = MMF_RectStimulusDLA hint = "Choose your stimulus !" endparam MMF_StimulusDLA param DLAStimulus2 caption = "Stimulus 2" default = MMF_RectStimulusDLA visible = @numstimuli>0 hint = "Choose your stimulus !" endparam MMF_StimulusDLA param DLAStimulus3 caption = "Stimulus 3" default = MMF_RectStimulusDLA visible = @numstimuli>1 hint = "Choose your stimulus !" endparam MMF_StimulusDLA param DLAStimulus4 caption = "Stimulus 4" default = MMF_RectStimulusDLA visible = @numstimuli>2 hint = "Choose your stimulus !" endparam MMF_StimulusDLA param DLAStimulus5 caption = "Stimulus 5" default = MMF_RectStimulusDLA visible = @numstimuli>3 hint = "Choose your stimulus !" endparam MMF_StimulusDLA param DLAStimulus6 caption = "Stimulus 6" default = MMF_RectStimulusDLA visible = @numstimuli>4 hint = "Choose your stimulus !" endparam MMF_StimulusDLA param DLAStimulus7 caption = "Stimulus 7" default = MMF_RectStimulusDLA visible = @numstimuli>5 hint = "Choose your stimulus !" endparam MMF_StimulusDLA param DLAStimulus8 caption = "Stimulus 8" default = MMF_RectStimulusDLA visible = @numstimuli>6 hint = "Choose your stimulus !" endparam MMF_StimulusDLA param DLAStimulus9 caption = "Stimulus 9" default = MMF_RectStimulusDLA visible = @numstimuli>7 hint = "Choose your stimulus !" endparam MMF_StimulusDLA param DLAStimulus10 caption = "Stimulus 10" default = MMF_RectStimulusDLA visible = @numstimuli>8 hint = "Choose your stimulus !" endparam MMF_StimulusDLA param DLAStimulus11 caption = "Stimulus 11" default = MMF_RectStimulusDLA visible = @numstimuli>9 hint = "Choose your stimulus !" endparam MMF_StimulusDLA param DLAStimulus12 caption = "Stimulus 12" default = MMF_RectStimulusDLA visible = @numstimuli>10 hint = "Choose your stimulus !" endparam MMF_StimulusDLA param DLAStimulus13 caption = "Stimulus 13" default = MMF_RectStimulusDLA visible = @numstimuli>11 hint = "Choose your stimulus !" endparam MMF_StimulusDLA param DLAStimulus14 caption = "Stimulus 14" default = MMF_RectStimulusDLA visible = @numstimuli>12 hint = "Choose your stimulus !" endparam MMF_StimulusDLA param DLAStimulus15 caption = "Stimulus 15" default = MMF_RectStimulusDLA visible = @numstimuli>13 hint = "Choose your stimulus !" endparam MMF_StimulusDLA param DLAStimulus16 caption = "Stimulus 16" default = MMF_RectStimulusDLA visible = @numstimuli>14 hint = "Choose your stimulus !" endparam heading caption = "Dead Points" text = "These are points on the screen that do not normally support \ growth and also block detection of stimuli by the organisms." endheading MMF_DeadDLA param DLADead caption = "Dead Point Seeding" default = MMF_NoDeadDLA hint = "Points selected by this object are 'dead' points, they will not \ normally turn into part of an organism and if positioned in \ between an organism and a stimulus then the organism will be \ unaffected by the stimulus." endparam heading caption = "The Organisms" endheading heading enabled = false endheading heading text = "You can select up to 16 different organisms each of which may \ have multiple seed points resulting in as many individuals \ as you like. Each organism may be coloured differently as well \ as having different growth characteristics." endheading int param numplants caption = "Number of Organisms" enum = "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" \ "15" "16" default = 0 endparam heading caption = "First Organism" endheading float param size1 caption = "Maximum Size" default = 100.0 min = 0.0 max = 100.0 hint = "The maximum size of this organism is this %age of the screen \ pixels. When the number of growth pixels based on this %age \ has occurred then growth of this organism stops." endparam int param method1 caption = "Colouring Method" enum = "Colour" "Slope" "Combined" default = 0 hint = "You can choose to colour the fractal with just the default \ colouring or using a 'slope' colouring or a combination of \ the two if and only if 'DLA Inspired' is plugged in a direct \ colouring. If plugged into a gradient colouring then the \ 'Combined' option is ignored and 'Colour' used instead." endparam float param palmin1 caption = "Min. Palette Index" default = 0.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the lower end of the palette \ portion for the organism." endparam float param palmax1 caption = "Max. Palette Index" default = 399.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the upper end of the palette \ portion for the organism." endparam color param lightcol1 caption = "Lighting Colour" default = RGB(1.0,1.0,1.0) hint = "The colour for the lighting in 'Combined' mode, ignored if using \ gradient colouring." visible = @method1==2 endparam float param nodirection1 caption = "Directionless Growth" default = 0.0 hint = "Here you can specify the number of points of directionless \ growth of the organism per generation. Directionless growth \ occurs randomly from any edge point on the organism and is \ not affected by any stimulus. Note that you can use fractional \ values, 0.5 means a 50% chance of one pixel of directionless \ growth per generation, 1.25 means one pixel of directionless \ growth and a 25% chance of a second. Normally you should use \ zero or a positive number but if you use a negative value then \ there will be so many pixels of directionless growth \ of the organism only when there is no directed growth due to \ an active stimulus." endparam MMF_SeedDLA param DLASeed1 caption = "Organism 1 Seeding" default = MMF_OnePointSeedDLA hint = "Sets the seeding method for the organism." endparam bool param Seed1Stimulus1 caption = "Reacts to Stimulus 1" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 1' i.e. it treats them as food or light." endparam bool param Seed1Stimulus2 caption = "Reacts to Stimulus 2" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 2' i.e. it treats them as food or light." visible = @numstimuli>0 endparam bool param Seed1Stimulus3 caption = "Reacts to Stimulus 3" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 3' i.e. it treats them as food or light." visible = @numstimuli>1 endparam bool param Seed1Stimulus4 caption = "Reacts to Stimulus 4" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 4' i.e. it treats them as food or light." visible = @numstimuli>2 endparam bool param Seed1Stimulus5 caption = "Reacts to Stimulus 5" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 5' i.e. it treats them as food or light." visible = @numstimuli>3 endparam bool param Seed1Stimulus6 caption = "Reacts to Stimulus 6" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 6' i.e. it treats them as food or light." visible = @numstimuli>4 endparam bool param Seed1Stimulus7 caption = "Reacts to Stimulus 7" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 7' i.e. it treats them as food or light." visible = @numstimuli>5 endparam bool param Seed1Stimulus8 caption = "Reacts to Stimulus 8" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 8' i.e. it treats them as food or light." visible = @numstimuli>6 endparam bool param Seed1Stimulus9 caption = "Reacts to Stimulus 9" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 9' i.e. it treats them as food or light." visible = @numstimuli>7 endparam bool param Seed1Stimulus10 caption = "Reacts to Stimulus 10" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 10' i.e. it treats them as food or light." visible = @numstimuli>8 endparam bool param Seed1Stimulus11 caption = "Reacts to Stimulus 11" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 11' i.e. it treats them as food or light." visible = @numstimuli>9 endparam bool param Seed1Stimulus12 caption = "Reacts to Stimulus 12" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 12' i.e. it treats them as food or light." visible = @numstimuli>10 endparam bool param Seed1Stimulus13 caption = "Reacts to Stimulus 13" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 13' i.e. it treats them as food or light." visible = @numstimuli>11 endparam bool param Seed1Stimulus14 caption = "Reacts to Stimulus 14" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 14' i.e. it treats them as food or light." visible = @numstimuli>12 endparam bool param Seed1Stimulus15 caption = "Reacts to Stimulus 15" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 15' i.e. it treats them as food or light." visible = @numstimuli>13 endparam bool param Seed1Stimulus16 caption = "Reacts to Stimulus 16" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 16' i.e. it treats them as food or light." visible = @numstimuli>14 endparam float param detect1 caption = "Detection accuracy" default = 1.0 min = 1.0 hint = "This is the accuracy with which the organism detects stimuli. \ An accuracy of 1 means it always detects the stimulus accurately, \ if you use 2 then it estimates the distance to the stimulus at \ somewhere between the correct value and twice the correct value. \ A setting of 10 means the organism could estimate the distance at \ being up to 10* further than it is." visible = @addrandom endparam float param move1 caption = "Movement Detection" default = 1.0 min = 0.0 hint = "Use zero for no movement detection, otherwise the larger the \ value specified the greater the effect of a moving stimulus. \ Typically use values from say 1 to 10." visible = @addmovement endparam heading caption = "Second Organism" visible = @numplants>0 endheading float param size2 caption = "Maximum Size" default = 100.0 min = 0.0 max = 100.0 hint = "The maximum size of this organism is this %age of the screen \ pixels. When the number of growth pixels based on this %age \ has occurred then growth of this organism stops." visible = @numplants>0 endparam int param method2 caption = "Colouring Method" enum = "Colour" "Slope" "Combined" default = 0 hint = "You can choose to colour the fractal with just the default \ colouring or using a 'slope' colouring or a combination of \ the two if and only if 'DLA Inspired' is plugged in a direct \ colouring. If plugged into a gradient colouring then the \ 'Combined' option is ignored and 'Colour' used instead." visible = @numplants>0 endparam float param palmin2 caption = "Min. Palette Index" default = 0.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the lower end of the palette \ portion for the organism." visible = @numplants>0 endparam float param palmax2 caption = "Max. Palette Index" default = 399.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the upper end of the palette \ portion for the organism." visible = @numplants>0 endparam color param lightcol2 caption = "Lighting Colour" default = RGB(1.0,1.0,1.0) hint = "The colour for the lighting in 'Combined' mode, ignored if using \ gradient colouring." visible = @method2==2 && @numplants>0 endparam float param nodirection2 caption = "Directionless Growth" default = 0.0 hint = "Here you can specify the number of points of directionless \ growth of the organism per generation. Directionless growth \ occurs randomly from any edge point on the organism and is \ not affected by any stimulus. Note that you can use fractional \ values, 0.5 means a 50% chance of one pixel of directionless \ growth per generation, 1.25 means one pixel of directionless \ growth and a 25% chance of a second. Normally you should use \ zero or a positive number but if you use a negative value then \ there will be so many pixels of directionless growth \ of the organism only when there is no directed growth due to \ an active stimulus." visible = @numplants>0 endparam MMF_SeedDLA param DLASeed2 caption = "Organism 2 Seeding" default = MMF_OnePointSeedDLA hint = "Sets the seeding method for the organism." visible = @numplants>0 endparam bool param Seed2Stimulus1 caption = "Reacts to Stimulus 1" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 1' i.e. it treats them as food or light." visible = @numplants>0 endparam bool param Seed2Stimulus2 caption = "Reacts to Stimulus 2" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 2' i.e. it treats them as food or light." visible = @numplants>0 && @numstimuli>0 endparam bool param Seed2Stimulus3 caption = "Reacts to Stimulus 3" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 3' i.e. it treats them as food or light." visible = @numplants>0 && @numstimuli>1 endparam bool param Seed2Stimulus4 caption = "Reacts to Stimulus 4" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 4' i.e. it treats them as food or light." visible = @numplants>0 && @numstimuli>2 endparam bool param Seed2Stimulus5 caption = "Reacts to Stimulus 5" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 5' i.e. it treats them as food or light." visible = @numplants>0 && @numstimuli>3 endparam bool param Seed2Stimulus6 caption = "Reacts to Stimulus 6" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 6' i.e. it treats them as food or light." visible = @numplants>0 && @numstimuli>4 endparam bool param Seed2Stimulus7 caption = "Reacts to Stimulus 7" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 7' i.e. it treats them as food or light." visible = @numplants>0 && @numstimuli>5 endparam bool param Seed2Stimulus8 caption = "Reacts to Stimulus 8" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 8' i.e. it treats them as food or light." visible = @numplants>0 && @numstimuli>6 endparam bool param Seed2Stimulus9 caption = "Reacts to Stimulus 9" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 9' i.e. it treats them as food or light." visible = @numplants>0 && @numstimuli>7 endparam bool param Seed2Stimulus10 caption = "Reacts to Stimulus 10" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 10' i.e. it treats them as food or light." visible = @numplants>0 && @numstimuli>8 endparam bool param Seed2Stimulus11 caption = "Reacts to Stimulus 11" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 11' i.e. it treats them as food or light." visible = @numplants>0 && @numstimuli>9 endparam bool param Seed2Stimulus12 caption = "Reacts to Stimulus 12" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 12' i.e. it treats them as food or light." visible = @numplants>0 && @numstimuli>10 endparam bool param Seed2Stimulus13 caption = "Reacts to Stimulus 13" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 13' i.e. it treats them as food or light." visible = @numplants>0 && @numstimuli>11 endparam bool param Seed2Stimulus14 caption = "Reacts to Stimulus 14" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 14' i.e. it treats them as food or light." visible = @numplants>0 && @numstimuli>12 endparam bool param Seed2Stimulus15 caption = "Reacts to Stimulus 15" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 15' i.e. it treats them as food or light." visible = @numplants>0 && @numstimuli>13 endparam bool param Seed2Stimulus16 caption = "Reacts to Stimulus 16" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 16' i.e. it treats them as food or light." visible = @numplants>0 && @numstimuli>14 endparam float param detect2 caption = "Detection accuracy" default = 1.0 min = 1.0 hint = "This is the accuracy with which the organism detects stimuli. \ An accuracy of 1 means it always detects the stimulus accurately, \ if you use 2 then it estimates the distance to the stimulus at \ somewhere between the correct value and twice the correct value. \ A setting of 10 means the organism could estimate the distance at \ being up to 10* further than it is." visible = @numplants>0 && @addrandom endparam float param move2 caption = "Movement Detection" default = 1.0 min = 0.0 hint = "Use zero for no movement detection, otherwise the larger the \ value specified the greater the effect of a moving stimulus. \ Typically use values from say 1 to 10." visible = @numplants>0 && @addmovement endparam heading caption = "Third Organism" visible = @numplants>1 endheading float param size3 caption = "Maximum Size" default = 100.0 min = 0.0 max = 100.0 hint = "The maximum size of this organism is this %age of the screen \ pixels. When the number of growth pixels based on this %age \ has occurred then growth of this organism stops." visible = @numplants>1 endparam int param method3 caption = "Colouring Method" enum = "Colour" "Slope" "Combined" default = 0 hint = "You can choose to colour the fractal with just the default \ colouring or using a 'slope' colouring or a combination of \ the two if and only if 'DLA Inspired' is plugged in a direct \ colouring. If plugged into a gradient colouring then the \ 'Combined' option is ignored and 'Colour' used instead." visible = @numplants>1 endparam float param palmin3 caption = "Min. Palette Index" default = 0.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the lower end of the palette \ portion for the organism." visible = @numplants>1 endparam float param palmax3 caption = "Max. Palette Index" default = 399.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the upper end of the palette \ portion for the organism." visible = @numplants>1 endparam color param lightcol3 caption = "Lighting Colour" default = RGB(1.0,1.0,1.0) hint = "The colour for the lighting in 'Combined' mode, ignored if using \ gradient colouring." visible = @method3==2 && @numplants>1 endparam float param nodirection3 caption = "Directionless Growth" default = 0.0 hint = "Here you can specify the number of points of directionless \ growth of the organism per generation. Directionless growth \ occurs randomly from any edge point on the organism and is \ not affected by any stimulus. Note that you can use fractional \ values, 0.5 means a 50% chance of one pixel of directionless \ growth per generation, 1.25 means one pixel of directionless \ growth and a 25% chance of a second. Normally you should use \ zero or a positive number but if you use a negative value then \ there will be so many pixels of directionless growth \ of the organism only when there is no directed growth due to \ an active stimulus." visible = @numplants>1 endparam MMF_SeedDLA param DLASeed3 caption = "Organism 3 Seeding" default = MMF_OnePointSeedDLA hint = "Sets the seeding method for the organism." visible = @numplants>1 endparam bool param Seed3Stimulus1 caption = "Reacts to Stimulus 1" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 1' i.e. it treats them as food or light." visible = @numplants>1 endparam bool param Seed3Stimulus2 caption = "Reacts to Stimulus 2" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 2' i.e. it treats them as food or light." visible = @numplants>1 && @numstimuli>0 endparam bool param Seed3Stimulus3 caption = "Reacts to Stimulus 3" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 3' i.e. it treats them as food or light." visible = @numplants>1 && @numstimuli>1 endparam bool param Seed3Stimulus4 caption = "Reacts to Stimulus 4" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 4' i.e. it treats them as food or light." visible = @numplants>1 && @numstimuli>2 endparam bool param Seed3Stimulus5 caption = "Reacts to Stimulus 5" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 5' i.e. it treats them as food or light." visible = @numplants>1 && @numstimuli>3 endparam bool param Seed3Stimulus6 caption = "Reacts to Stimulus 6" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 6' i.e. it treats them as food or light." visible = @numplants>1 && @numstimuli>4 endparam bool param Seed3Stimulus7 caption = "Reacts to Stimulus 7" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 7' i.e. it treats them as food or light." visible = @numplants>1 && @numstimuli>5 endparam bool param Seed3Stimulus8 caption = "Reacts to Stimulus 8" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 8' i.e. it treats them as food or light." visible = @numplants>1 && @numstimuli>6 endparam bool param Seed3Stimulus9 caption = "Reacts to Stimulus 9" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 9' i.e. it treats them as food or light." visible = @numplants>1 && @numstimuli>7 endparam bool param Seed3Stimulus10 caption = "Reacts to Stimulus 10" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 10' i.e. it treats them as food or light." visible = @numplants>1 && @numstimuli>8 endparam bool param Seed3Stimulus11 caption = "Reacts to Stimulus 11" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 11' i.e. it treats them as food or light." visible = @numplants>1 && @numstimuli>9 endparam bool param Seed3Stimulus12 caption = "Reacts to Stimulus 12" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 12' i.e. it treats them as food or light." visible = @numplants>1 && @numstimuli>10 endparam bool param Seed3Stimulus13 caption = "Reacts to Stimulus 13" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 13' i.e. it treats them as food or light." visible = @numplants>1 && @numstimuli>11 endparam bool param Seed3Stimulus14 caption = "Reacts to Stimulus 14" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 14' i.e. it treats them as food or light." visible = @numplants>1 && @numstimuli>12 endparam bool param Seed3Stimulus15 caption = "Reacts to Stimulus 15" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 15' i.e. it treats them as food or light." visible = @numplants>1 && @numstimuli>13 endparam bool param Seed3Stimulus16 caption = "Reacts to Stimulus 16" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 16' i.e. it treats them as food or light." visible = @numplants>1 && @numstimuli>14 endparam float param detect3 caption = "Detection accuracy" default = 1.0 min = 1.0 hint = "This is the accuracy with which the organism detects stimuli. \ An accuracy of 1 means it always detects the stimulus accurately, \ if you use 2 then it estimates the distance to the stimulus at \ somewhere between the correct value and twice the correct value. \ A setting of 10 means the organism could estimate the distance at \ being up to 10* further than it is." visible = @numplants>1 && @addrandom endparam float param move3 caption = "Movement Detection" default = 1.0 min = 0.0 hint = "Use zero for no movement detection, otherwise the larger the \ value specified the greater the effect of a moving stimulus. \ Typically use values from say 1 to 10." visible = @numplants>1 && @addmovement endparam heading caption = "Fourth Organism" visible = @numplants>2 endheading float param size4 caption = "Maximum Size" default = 100.0 min = 0.0 max = 100.0 hint = "The maximum size of this organism is this %age of the screen \ pixels. When the number of growth pixels based on this %age \ has occurred then growth of this organism stops." visible = @numplants>2 endparam int param method4 caption = "Colouring Method" enum = "Colour" "Slope" "Combined" default = 0 hint = "You can choose to colour the fractal with just the default \ colouring or using a 'slope' colouring or a combination of \ the two if and only if 'DLA Inspired' is plugged in a direct \ colouring. If plugged into a gradient colouring then the \ 'Combined' option is ignored and 'Colour' used instead." visible = @numplants>2 endparam float param palmin4 caption = "Min. Palette Index" default = 0.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the lower end of the palette \ portion for the organism." visible = @numplants>2 endparam float param palmax4 caption = "Max. Palette Index" default = 399.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the upper end of the palette \ portion for the organism." visible = @numplants>2 endparam color param lightcol4 caption = "Lighting Colour" default = RGB(1.0,1.0,1.0) hint = "The colour for the lighting in 'Combined' mode, ignored if using \ gradient colouring." visible = @method4==2 && @numplants>2 endparam float param nodirection4 caption = "Directionless Growth" default = 0.0 hint = "Here you can specify the number of points of directionless \ growth of the organism per generation. Directionless growth \ occurs randomly from any edge point on the organism and is \ not affected by any stimulus. Note that you can use fractional \ values, 0.5 means a 50% chance of one pixel of directionless \ growth per generation, 1.25 means one pixel of directionless \ growth and a 25% chance of a second. Normally you should use \ zero or a positive number but if you use a negative value then \ there will be so many pixels of directionless growth \ of the organism only when there is no directed growth due to \ an active stimulus." visible = @numplants>2 endparam MMF_SeedDLA param DLASeed4 caption = "Organism 4 Seeding" default = MMF_OnePointSeedDLA hint = "Sets the seeding method for the organism." visible = @numplants>2 endparam bool param Seed4Stimulus1 caption = "Reacts to Stimulus 1" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 1' i.e. it treats them as food or light." visible = @numplants>2 endparam bool param Seed4Stimulus2 caption = "Reacts to Stimulus 2" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 2' i.e. it treats them as food or light." visible = @numplants>2 && @numstimuli>0 endparam bool param Seed4Stimulus3 caption = "Reacts to Stimulus 3" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 3' i.e. it treats them as food or light." visible = @numplants>2 && @numstimuli>1 endparam bool param Seed4Stimulus4 caption = "Reacts to Stimulus 4" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 4' i.e. it treats them as food or light." visible = @numplants>2 && @numstimuli>2 endparam bool param Seed4Stimulus5 caption = "Reacts to Stimulus 5" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 5' i.e. it treats them as food or light." visible = @numplants>2 && @numstimuli>3 endparam bool param Seed4Stimulus6 caption = "Reacts to Stimulus 6" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 6' i.e. it treats them as food or light." visible = @numplants>2 && @numstimuli>4 endparam bool param Seed4Stimulus7 caption = "Reacts to Stimulus 7" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 7' i.e. it treats them as food or light." visible = @numplants>2 && @numstimuli>5 endparam bool param Seed4Stimulus8 caption = "Reacts to Stimulus 8" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 8' i.e. it treats them as food or light." visible = @numplants>2 && @numstimuli>6 endparam bool param Seed4Stimulus9 caption = "Reacts to Stimulus 9" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 9' i.e. it treats them as food or light." visible = @numplants>2 && @numstimuli>7 endparam bool param Seed4Stimulus10 caption = "Reacts to Stimulus 10" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 10' i.e. it treats them as food or light." visible = @numplants>2 && @numstimuli>8 endparam bool param Seed4Stimulus11 caption = "Reacts to Stimulus 11" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 11' i.e. it treats them as food or light." visible = @numplants>2 && @numstimuli>9 endparam bool param Seed4Stimulus12 caption = "Reacts to Stimulus 12" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 12' i.e. it treats them as food or light." visible = @numplants>2 && @numstimuli>10 endparam bool param Seed4Stimulus13 caption = "Reacts to Stimulus 13" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 13' i.e. it treats them as food or light." visible = @numplants>2 && @numstimuli>11 endparam bool param Seed4Stimulus14 caption = "Reacts to Stimulus 14" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 14' i.e. it treats them as food or light." visible = @numplants>2 && @numstimuli>12 endparam bool param Seed4Stimulus15 caption = "Reacts to Stimulus 15" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 15' i.e. it treats them as food or light." visible = @numplants>2 && @numstimuli>13 endparam bool param Seed4Stimulus16 caption = "Reacts to Stimulus 16" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 16' i.e. it treats them as food or light." visible = @numplants>2 && @numstimuli>14 endparam float param detect4 caption = "Detection accuracy" default = 1.0 min = 1.0 hint = "This is the accuracy with which the organism detects stimuli. \ An accuracy of 1 means it always detects the stimulus accurately, \ if you use 2 then it estimates the distance to the stimulus at \ somewhere between the correct value and twice the correct value. \ A setting of 10 means the organism could estimate the distance at \ being up to 10* further than it is." visible = @numplants>2 && @addrandom endparam float param move4 caption = "Movement Detection" default = 1.0 min = 0.0 hint = "Use zero for no movement detection, otherwise the larger the \ value specified the greater the effect of a moving stimulus. \ Typically use values from say 1 to 10." visible = @numplants>2 && @addmovement endparam heading caption = "Fifth Organism" visible = @numplants>3 endheading float param size5 caption = "Maximum Size" default = 100.0 min = 0.0 max = 100.0 hint = "The maximum size of this organism is this %age of the screen \ pixels. When the number of growth pixels based on this %age \ has occurred then growth of this organism stops." visible = @numplants>3 endparam int param method5 caption = "Colouring Method" enum = "Colour" "Slope" "Combined" default = 0 hint = "You can choose to colour the fractal with just the default \ colouring or using a 'slope' colouring or a combination of \ the two if and only if 'DLA Inspired' is plugged in a direct \ colouring. If plugged into a gradient colouring then the \ 'Combined' option is ignored and 'Colour' used instead." visible = @numplants>3 endparam float param palmin5 caption = "Min. Palette Index" default = 0.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the lower end of the palette \ portion for the organism." visible = @numplants>3 endparam float param palmax5 caption = "Max. Palette Index" default = 399.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the upper end of the palette \ portion for the organism." visible = @numplants>3 endparam color param lightcol5 caption = "Lighting Colour" default = RGB(1.0,1.0,1.0) hint = "The colour for the lighting in 'Combined' mode, ignored if using \ gradient colouring." visible = @method5==2 && @numplants>3 endparam float param nodirection5 caption = "Directionless Growth" default = 0.0 hint = "Here you can specify the number of points of directionless \ growth of the organism per generation. Directionless growth \ occurs randomly from any edge point on the organism and is \ not affected by any stimulus. Note that you can use fractional \ values, 0.5 means a 50% chance of one pixel of directionless \ growth per generation, 1.25 means one pixel of directionless \ growth and a 25% chance of a second. Normally you should use \ zero or a positive number but if you use a negative value then \ there will be so many pixels of directionless growth \ of the organism only when there is no directed growth due to \ an active stimulus." visible = @numplants>3 endparam MMF_SeedDLA param DLASeed5 caption = "Organism 5 Seeding" default = MMF_OnePointSeedDLA hint = "Sets the seeding method for the organism." visible = @numplants>3 endparam bool param Seed5Stimulus1 caption = "Reacts to Stimulus 1" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 1' i.e. it treats them as food or light." visible = @numplants>3 endparam bool param Seed5Stimulus2 caption = "Reacts to Stimulus 2" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 2' i.e. it treats them as food or light." visible = @numplants>3 && @numstimuli>0 endparam bool param Seed5Stimulus3 caption = "Reacts to Stimulus 3" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 3' i.e. it treats them as food or light." visible = @numplants>3 && @numstimuli>1 endparam bool param Seed5Stimulus4 caption = "Reacts to Stimulus 4" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 4' i.e. it treats them as food or light." visible = @numplants>3 && @numstimuli>2 endparam bool param Seed5Stimulus5 caption = "Reacts to Stimulus 5" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 5' i.e. it treats them as food or light." visible = @numplants>3 && @numstimuli>3 endparam bool param Seed5Stimulus6 caption = "Reacts to Stimulus 6" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 6' i.e. it treats them as food or light." visible = @numplants>3 && @numstimuli>4 endparam bool param Seed5Stimulus7 caption = "Reacts to Stimulus 7" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 7' i.e. it treats them as food or light." visible = @numplants>3 && @numstimuli>5 endparam bool param Seed5Stimulus8 caption = "Reacts to Stimulus 8" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 8' i.e. it treats them as food or light." visible = @numplants>3 && @numstimuli>6 endparam bool param Seed5Stimulus9 caption = "Reacts to Stimulus 9" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 9' i.e. it treats them as food or light." visible = @numplants>3 && @numstimuli>7 endparam bool param Seed5Stimulus10 caption = "Reacts to Stimulus 10" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 10' i.e. it treats them as food or light." visible = @numplants>3 && @numstimuli>8 endparam bool param Seed5Stimulus11 caption = "Reacts to Stimulus 11" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 11' i.e. it treats them as food or light." visible = @numplants>3 && @numstimuli>9 endparam bool param Seed5Stimulus12 caption = "Reacts to Stimulus 12" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 12' i.e. it treats them as food or light." visible = @numplants>3 && @numstimuli>10 endparam bool param Seed5Stimulus13 caption = "Reacts to Stimulus 13" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 13' i.e. it treats them as food or light." visible = @numplants>3 && @numstimuli>11 endparam bool param Seed5Stimulus14 caption = "Reacts to Stimulus 14" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 14' i.e. it treats them as food or light." visible = @numplants>3 && @numstimuli>12 endparam bool param Seed5Stimulus15 caption = "Reacts to Stimulus 15" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 15' i.e. it treats them as food or light." visible = @numplants>3 && @numstimuli>13 endparam bool param Seed5Stimulus16 caption = "Reacts to Stimulus 16" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 16' i.e. it treats them as food or light." visible = @numplants>3 && @numstimuli>14 endparam float param detect5 caption = "Detection accuracy" default = 1.0 min = 1.0 hint = "This is the accuracy with which the organism detects stimuli. \ An accuracy of 1 means it always detects the stimulus accurately, \ if you use 2 then it estimates the distance to the stimulus at \ somewhere between the correct value and twice the correct value. \ A setting of 10 means the organism could estimate the distance at \ being up to 10* further than it is." visible = @numplants>3 && @addrandom endparam float param move5 caption = "Movement Detection" default = 1.0 min = 0.0 hint = "Use zero for no movement detection, otherwise the larger the \ value specified the greater the effect of a moving stimulus. \ Typically use values from say 1 to 10." visible = @numplants>3 && @addmovement endparam heading caption = "Sixth Organism" visible = @numplants>4 endheading float param size6 caption = "Maximum Size" default = 100.0 min = 0.0 max = 100.0 hint = "The maximum size of this organism is this %age of the screen \ pixels. When the number of growth pixels based on this %age \ has occurred then growth of this organism stops." visible = @numplants>4 endparam int param method6 caption = "Colouring Method" enum = "Colour" "Slope" "Combined" default = 0 hint = "You can choose to colour the fractal with just the default \ colouring or using a 'slope' colouring or a combination of \ the two if and only if 'DLA Inspired' is plugged in a direct \ colouring. If plugged into a gradient colouring then the \ 'Combined' option is ignored and 'Colour' used instead." visible = @numplants>4 endparam float param palmin6 caption = "Min. Palette Index" default = 0.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the lower end of the palette \ portion for the organism." visible = @numplants>4 endparam float param palmax6 caption = "Max. Palette Index" default = 399.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the upper end of the palette \ portion for the organism." visible = @numplants>4 endparam color param lightcol6 caption = "Lighting Colour" default = RGB(1.0,1.0,1.0) hint = "The colour for the lighting in 'Combined' mode, ignored if using \ gradient colouring." visible = @method6==2 && @numplants>4 endparam float param nodirection6 caption = "Directionless Growth" default = 0.0 hint = "Here you can specify the number of points of directionless \ growth of the organism per generation. Directionless growth \ occurs randomly from any edge point on the organism and is \ not affected by any stimulus. Note that you can use fractional \ values, 0.5 means a 50% chance of one pixel of directionless \ growth per generation, 1.25 means one pixel of directionless \ growth and a 25% chance of a second. Normally you should use \ zero or a positive number but if you use a negative value then \ there will be so many pixels of directionless growth \ of the organism only when there is no directed growth due to \ an active stimulus." visible = @numplants>4 endparam MMF_SeedDLA param DLASeed6 caption = "Organism 6 Seeding" default = MMF_OnePointSeedDLA hint = "Sets the seeding method for the organism." visible = @numplants>4 endparam bool param Seed6Stimulus1 caption = "Reacts to Stimulus 1" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 1' i.e. it treats them as food or light." visible = @numplants>4 endparam bool param Seed6Stimulus2 caption = "Reacts to Stimulus 2" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 2' i.e. it treats them as food or light." visible = @numplants>4 && @numstimuli>0 endparam bool param Seed6Stimulus3 caption = "Reacts to Stimulus 3" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 3' i.e. it treats them as food or light." visible = @numplants>4 && @numstimuli>1 endparam bool param Seed6Stimulus4 caption = "Reacts to Stimulus 4" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 4' i.e. it treats them as food or light." visible = @numplants>4 && @numstimuli>2 endparam bool param Seed6Stimulus5 caption = "Reacts to Stimulus 5" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 5' i.e. it treats them as food or light." visible = @numplants>4 && @numstimuli>3 endparam bool param Seed6Stimulus6 caption = "Reacts to Stimulus 6" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 6' i.e. it treats them as food or light." visible = @numplants>4 && @numstimuli>4 endparam bool param Seed6Stimulus7 caption = "Reacts to Stimulus 7" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 7' i.e. it treats them as food or light." visible = @numplants>4 && @numstimuli>5 endparam bool param Seed6Stimulus8 caption = "Reacts to Stimulus 8" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 8' i.e. it treats them as food or light." visible = @numplants>4 && @numstimuli>6 endparam bool param Seed6Stimulus9 caption = "Reacts to Stimulus 9" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 9' i.e. it treats them as food or light." visible = @numplants>4 && @numstimuli>7 endparam bool param Seed6Stimulus10 caption = "Reacts to Stimulus 10" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 10' i.e. it treats them as food or light." visible = @numplants>4 && @numstimuli>8 endparam bool param Seed6Stimulus11 caption = "Reacts to Stimulus 11" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 11' i.e. it treats them as food or light." visible = @numplants>4 && @numstimuli>9 endparam bool param Seed6Stimulus12 caption = "Reacts to Stimulus 12" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 12' i.e. it treats them as food or light." visible = @numplants>4 && @numstimuli>10 endparam bool param Seed6Stimulus13 caption = "Reacts to Stimulus 13" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 13' i.e. it treats them as food or light." visible = @numplants>4 && @numstimuli>11 endparam bool param Seed6Stimulus14 caption = "Reacts to Stimulus 14" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 14' i.e. it treats them as food or light." visible = @numplants>4 && @numstimuli>12 endparam bool param Seed6Stimulus15 caption = "Reacts to Stimulus 15" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 15' i.e. it treats them as food or light." visible = @numplants>4 && @numstimuli>13 endparam bool param Seed6Stimulus16 caption = "Reacts to Stimulus 16" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 16' i.e. it treats them as food or light." visible = @numplants>4 && @numstimuli>14 endparam float param detect6 caption = "Detection accuracy" default = 1.0 min = 1.0 hint = "This is the accuracy with which the organism detects stimuli. \ An accuracy of 1 means it always detects the stimulus accurately, \ if you use 2 then it estimates the distance to the stimulus at \ somewhere between the correct value and twice the correct value. \ A setting of 10 means the organism could estimate the distance at \ being up to 10* further than it is." visible = @numplants>4 && @addrandom endparam float param move6 caption = "Movement Detection" default = 1.0 min = 0.0 hint = "Use zero for no movement detection, otherwise the larger the \ value specified the greater the effect of a moving stimulus. \ Typically use values from say 1 to 10." visible = @numplants>4 && @addmovement endparam heading caption = "Seventh Organism" visible = @numplants>5 endheading float param size7 caption = "Maximum Size" default = 100.0 min = 0.0 max = 100.0 hint = "The maximum size of this organism is this %age of the screen \ pixels. When the number of growth pixels based on this %age \ has occurred then growth of this organism stops." visible = @numplants>5 endparam int param method7 caption = "Colouring Method" enum = "Colour" "Slope" "Combined" default = 0 hint = "You can choose to colour the fractal with just the default \ colouring or using a 'slope' colouring or a combination of \ the two if and only if 'DLA Inspired' is plugged in a direct \ colouring. If plugged into a gradient colouring then the \ 'Combined' option is ignored and 'Colour' used instead." visible = @numplants>5 endparam float param palmin7 caption = "Min. Palette Index" default = 0.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the lower end of the palette \ portion for the organism." visible = @numplants>5 endparam float param palmax7 caption = "Max. Palette Index" default = 399.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the upper end of the palette \ portion for the organism." visible = @numplants>5 endparam color param lightcol7 caption = "Lighting Colour" default = RGB(1.0,1.0,1.0) hint = "The colour for the lighting in 'Combined' mode, ignored if using \ gradient colouring." visible = @method7==2 && @numplants>5 endparam float param nodirection7 caption = "Directionless Growth" default = 0.0 hint = "Here you can specify the number of points of directionless \ growth of the organism per generation. Directionless growth \ occurs randomly from any edge point on the organism and is \ not affected by any stimulus. Note that you can use fractional \ values, 0.5 means a 50% chance of one pixel of directionless \ growth per generation, 1.25 means one pixel of directionless \ growth and a 25% chance of a second. Normally you should use \ zero or a positive number but if you use a negative value then \ there will be so many pixels of directionless growth \ of the organism only when there is no directed growth due to \ an active stimulus." visible = @numplants>5 endparam MMF_SeedDLA param DLASeed7 caption = "Organism 7 Seeding" default = MMF_OnePointSeedDLA hint = "Sets the seeding method for the organism." visible = @numplants>5 endparam bool param Seed7Stimulus1 caption = "Reacts to Stimulus 1" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 1' i.e. it treats them as food or light." visible = @numplants>5 endparam bool param Seed7Stimulus2 caption = "Reacts to Stimulus 2" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 2' i.e. it treats them as food or light." visible = @numplants>5 && @numstimuli>0 endparam bool param Seed7Stimulus3 caption = "Reacts to Stimulus 3" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 3' i.e. it treats them as food or light." visible = @numplants>5 && @numstimuli>1 endparam bool param Seed7Stimulus4 caption = "Reacts to Stimulus 4" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 4' i.e. it treats them as food or light." visible = @numplants>5 && @numstimuli>2 endparam bool param Seed7Stimulus5 caption = "Reacts to Stimulus 5" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 5' i.e. it treats them as food or light." visible = @numplants>5 && @numstimuli>3 endparam bool param Seed7Stimulus6 caption = "Reacts to Stimulus 6" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 6' i.e. it treats them as food or light." visible = @numplants>5 && @numstimuli>4 endparam bool param Seed7Stimulus7 caption = "Reacts to Stimulus 7" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 7' i.e. it treats them as food or light." visible = @numplants>5 && @numstimuli>5 endparam bool param Seed7Stimulus8 caption = "Reacts to Stimulus 8" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 8' i.e. it treats them as food or light." visible = @numplants>5 && @numstimuli>6 endparam bool param Seed7Stimulus9 caption = "Reacts to Stimulus 9" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 9' i.e. it treats them as food or light." visible = @numplants>5 && @numstimuli>7 endparam bool param Seed7Stimulus10 caption = "Reacts to Stimulus 10" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 10' i.e. it treats them as food or light." visible = @numplants>5 && @numstimuli>8 endparam bool param Seed7Stimulus11 caption = "Reacts to Stimulus 11" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 11' i.e. it treats them as food or light." visible = @numplants>5 && @numstimuli>9 endparam bool param Seed7Stimulus12 caption = "Reacts to Stimulus 12" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 12' i.e. it treats them as food or light." visible = @numplants>5 && @numstimuli>10 endparam bool param Seed7Stimulus13 caption = "Reacts to Stimulus 13" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 13' i.e. it treats them as food or light." visible = @numplants>5 && @numstimuli>11 endparam bool param Seed7Stimulus14 caption = "Reacts to Stimulus 14" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 14' i.e. it treats them as food or light." visible = @numplants>5 && @numstimuli>12 endparam bool param Seed7Stimulus15 caption = "Reacts to Stimulus 15" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 15' i.e. it treats them as food or light." visible = @numplants>5 && @numstimuli>13 endparam bool param Seed7Stimulus16 caption = "Reacts to Stimulus 16" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 16' i.e. it treats them as food or light." visible = @numplants>5 && @numstimuli>14 endparam float param detect7 caption = "Detection accuracy" default = 1.0 min = 1.0 hint = "This is the accuracy with which the organism detects stimuli. \ An accuracy of 1 means it always detects the stimulus accurately, \ if you use 2 then it estimates the distance to the stimulus at \ somewhere between the correct value and twice the correct value. \ A setting of 10 means the organism could estimate the distance at \ being up to 10* further than it is." visible = @numplants>5 && @addrandom endparam float param move7 caption = "Movement Detection" default = 1.0 min = 0.0 hint = "Use zero for no movement detection, otherwise the larger the \ value specified the greater the effect of a moving stimulus. \ Typically use values from say 1 to 10." visible = @numplants>5 && @addmovement endparam heading caption = "Eighth Organism" visible = @numplants>6 endheading float param size8 caption = "Maximum Size" default = 100.0 min = 0.0 max = 100.0 hint = "The maximum size of this organism is this %age of the screen \ pixels. When the number of growth pixels based on this %age \ has occurred then growth of this organism stops." visible = @numplants>6 endparam int param method8 caption = "Colouring Method" enum = "Colour" "Slope" "Combined" default = 0 hint = "You can choose to colour the fractal with just the default \ colouring or using a 'slope' colouring or a combination of \ the two if and only if 'DLA Inspired' is plugged in a direct \ colouring. If plugged into a gradient colouring then the \ 'Combined' option is ignored and 'Colour' used instead." visible = @numplants>6 endparam float param palmin8 caption = "Min. Palette Index" default = 0.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the lower end of the palette \ portion for the organism." visible = @numplants>6 endparam float param palmax8 caption = "Max. Palette Index" default = 399.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the upper end of the palette \ portion for the organism." visible = @numplants>6 endparam color param lightcol8 caption = "Lighting Colour" default = RGB(1.0,1.0,1.0) hint = "The colour for the lighting in 'Combined' mode, ignored if using \ gradient colouring." visible = @method8==2 && @numplants>6 endparam float param nodirection8 caption = "Directionless Growth" default = 0.0 hint = "Here you can specify the number of points of directionless \ growth of the organism per generation. Directionless growth \ occurs randomly from any edge point on the organism and is \ not affected by any stimulus. Note that you can use fractional \ values, 0.5 means a 50% chance of one pixel of directionless \ growth per generation, 1.25 means one pixel of directionless \ growth and a 25% chance of a second. Normally you should use \ zero or a positive number but if you use a negative value then \ there will be so many pixels of directionless growth \ of the organism only when there is no directed growth due to \ an active stimulus." visible = @numplants>6 endparam MMF_SeedDLA param DLASeed8 caption = "Organism 8 Seeding" default = MMF_OnePointSeedDLA hint = "Sets the seeding method for the organism." visible = @numplants>6 endparam bool param Seed8Stimulus1 caption = "Reacts to Stimulus 1" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 1' i.e. it treats them as food or light." visible = @numplants>6 endparam bool param Seed8Stimulus2 caption = "Reacts to Stimulus 2" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 2' i.e. it treats them as food or light." visible = @numplants>6 && @numstimuli>0 endparam bool param Seed8Stimulus3 caption = "Reacts to Stimulus 3" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 3' i.e. it treats them as food or light." visible = @numplants>6 && @numstimuli>1 endparam bool param Seed8Stimulus4 caption = "Reacts to Stimulus 4" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 4' i.e. it treats them as food or light." visible = @numplants>6 && @numstimuli>2 endparam bool param Seed8Stimulus5 caption = "Reacts to Stimulus 5" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 5' i.e. it treats them as food or light." visible = @numplants>6 && @numstimuli>3 endparam bool param Seed8Stimulus6 caption = "Reacts to Stimulus 6" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 6' i.e. it treats them as food or light." visible = @numplants>6 && @numstimuli>4 endparam bool param Seed8Stimulus7 caption = "Reacts to Stimulus 7" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 7' i.e. it treats them as food or light." visible = @numplants>6 && @numstimuli>5 endparam bool param Seed8Stimulus8 caption = "Reacts to Stimulus 8" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 8' i.e. it treats them as food or light." visible = @numplants>6 && @numstimuli>6 endparam bool param Seed8Stimulus9 caption = "Reacts to Stimulus 9" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 9' i.e. it treats them as food or light." visible = @numplants>6 && @numstimuli>7 endparam bool param Seed8Stimulus10 caption = "Reacts to Stimulus 10" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 10' i.e. it treats them as food or light." visible = @numplants>6 && @numstimuli>8 endparam bool param Seed8Stimulus11 caption = "Reacts to Stimulus 11" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 11' i.e. it treats them as food or light." visible = @numplants>6 && @numstimuli>9 endparam bool param Seed8Stimulus12 caption = "Reacts to Stimulus 12" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 12' i.e. it treats them as food or light." visible = @numplants>6 && @numstimuli>10 endparam bool param Seed8Stimulus13 caption = "Reacts to Stimulus 13" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 13' i.e. it treats them as food or light." visible = @numplants>6 && @numstimuli>11 endparam bool param Seed8Stimulus14 caption = "Reacts to Stimulus 14" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 14' i.e. it treats them as food or light." visible = @numplants>6 && @numstimuli>12 endparam bool param Seed8Stimulus15 caption = "Reacts to Stimulus 15" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 15' i.e. it treats them as food or light." visible = @numplants>6 && @numstimuli>13 endparam bool param Seed8Stimulus16 caption = "Reacts to Stimulus 16" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 16' i.e. it treats them as food or light." visible = @numplants>6 && @numstimuli>14 endparam float param detect8 caption = "Detection accuracy" default = 1.0 min = 1.0 hint = "This is the accuracy with which the organism detects stimuli. \ An accuracy of 1 means it always detects the stimulus accurately, \ if you use 2 then it estimates the distance to the stimulus at \ somewhere between the correct value and twice the correct value. \ A setting of 10 means the organism could estimate the distance at \ being up to 10* further than it is." visible = @numplants>6 && @addrandom endparam float param move8 caption = "Movement Detection" default = 1.0 min = 0.0 hint = "Use zero for no movement detection, otherwise the larger the \ value specified the greater the effect of a moving stimulus. \ Typically use values from say 1 to 10." visible = @numplants>6 && @addmovement endparam heading caption = "Ninth Organism" visible = @numplants>7 endheading float param size9 caption = "Maximum Size" default = 100.0 min = 0.0 max = 100.0 hint = "The maximum size of this organism is this %age of the screen \ pixels. When the number of growth pixels based on this %age \ has occurred then growth of this organism stops." visible = @numplants>7 endparam int param method9 caption = "Colouring Method" enum = "Colour" "Slope" "Combined" default = 0 hint = "You can choose to colour the fractal with just the default \ colouring or using a 'slope' colouring or a combination of \ the two if and only if 'DLA Inspired' is plugged in a direct \ colouring. If plugged into a gradient colouring then the \ 'Combined' option is ignored and 'Colour' used instead." visible = @numplants>7 endparam float param palmin9 caption = "Min. Palette Index" default = 0.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the lower end of the palette \ portion for the organism." visible = @numplants>7 endparam float param palmax9 caption = "Max. Palette Index" default = 399.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the upper end of the palette \ portion for the organism." visible = @numplants>7 endparam color param lightcol9 caption = "Lighting Colour" default = RGB(1.0,1.0,1.0) hint = "The colour for the lighting in 'Combined' mode, ignored if using \ gradient colouring." visible = @method9==2 && @numplants>7 endparam float param nodirection9 caption = "Directionless Growth" default = 0.0 hint = "Here you can specify the number of points of directionless \ growth of the organism per generation. Directionless growth \ occurs randomly from any edge point on the organism and is \ not affected by any stimulus. Note that you can use fractional \ values, 0.5 means a 50% chance of one pixel of directionless \ growth per generation, 1.25 means one pixel of directionless \ growth and a 25% chance of a second. Normally you should use \ zero or a positive number but if you use a negative value then \ there will be so many pixels of directionless growth \ of the organism only when there is no directed growth due to \ an active stimulus." visible = @numplants>7 endparam MMF_SeedDLA param DLASeed9 caption = "Organism 9 Seeding" default = MMF_OnePointSeedDLA hint = "Sets the seeding method for the organism." visible = @numplants>7 endparam bool param Seed9Stimulus1 caption = "Reacts to Stimulus 1" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 1' i.e. it treats them as food or light." visible = @numplants>7 endparam bool param Seed9Stimulus2 caption = "Reacts to Stimulus 2" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 2' i.e. it treats them as food or light." visible = @numplants>7 && @numstimuli>0 endparam bool param Seed9Stimulus3 caption = "Reacts to Stimulus 3" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 3' i.e. it treats them as food or light." visible = @numplants>7 && @numstimuli>1 endparam bool param Seed9Stimulus4 caption = "Reacts to Stimulus 4" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 4' i.e. it treats them as food or light." visible = @numplants>7 && @numstimuli>2 endparam bool param Seed9Stimulus5 caption = "Reacts to Stimulus 5" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 5' i.e. it treats them as food or light." visible = @numplants>7 && @numstimuli>3 endparam bool param Seed9Stimulus6 caption = "Reacts to Stimulus 6" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 6' i.e. it treats them as food or light." visible = @numplants>7 && @numstimuli>4 endparam bool param Seed9Stimulus7 caption = "Reacts to Stimulus 7" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 7' i.e. it treats them as food or light." visible = @numplants>7 && @numstimuli>5 endparam bool param Seed9Stimulus8 caption = "Reacts to Stimulus 8" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 8' i.e. it treats them as food or light." visible = @numplants>7 && @numstimuli>6 endparam bool param Seed9Stimulus9 caption = "Reacts to Stimulus 9" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 9' i.e. it treats them as food or light." visible = @numplants>7 && @numstimuli>7 endparam bool param Seed9Stimulus10 caption = "Reacts to Stimulus 10" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 10' i.e. it treats them as food or light." visible = @numplants>7 && @numstimuli>8 endparam bool param Seed9Stimulus11 caption = "Reacts to Stimulus 11" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 11' i.e. it treats them as food or light." visible = @numplants>7 && @numstimuli>9 endparam bool param Seed9Stimulus12 caption = "Reacts to Stimulus 12" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 12' i.e. it treats them as food or light." visible = @numplants>7 && @numstimuli>10 endparam bool param Seed9Stimulus13 caption = "Reacts to Stimulus 13" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 13' i.e. it treats them as food or light." visible = @numplants>7 && @numstimuli>11 endparam bool param Seed9Stimulus14 caption = "Reacts to Stimulus 14" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 14' i.e. it treats them as food or light." visible = @numplants>7 && @numstimuli>12 endparam bool param Seed9Stimulus15 caption = "Reacts to Stimulus 15" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 15' i.e. it treats them as food or light." visible = @numplants>7 && @numstimuli>13 endparam bool param Seed9Stimulus16 caption = "Reacts to Stimulus 16" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 16' i.e. it treats them as food or light." visible = @numplants>7 && @numstimuli>14 endparam float param detect9 caption = "Detection accuracy" default = 1.0 min = 1.0 hint = "This is the accuracy with which the organism detects stimuli. \ An accuracy of 1 means it always detects the stimulus accurately, \ if you use 2 then it estimates the distance to the stimulus at \ somewhere between the correct value and twice the correct value. \ A setting of 10 means the organism could estimate the distance at \ being up to 10* further than it is." visible = @numplants>7 && @addrandom endparam float param move9 caption = "Movement Detection" default = 1.0 min = 0.0 hint = "Use zero for no movement detection, otherwise the larger the \ value specified the greater the effect of a moving stimulus. \ Typically use values from say 1 to 10." visible = @numplants>7 && @addmovement endparam heading caption = "Tenth Organism" visible = @numplants>8 endheading float param size10 caption = "Maximum Size" default = 100.0 min = 0.0 max = 100.0 hint = "The maximum size of this organism is this %age of the screen \ pixels. When the number of growth pixels based on this %age \ has occurred then growth of this organism stops." visible = @numplants>8 endparam int param method10 caption = "Colouring Method" enum = "Colour" "Slope" "Combined" default = 0 hint = "You can choose to colour the fractal with just the default \ colouring or using a 'slope' colouring or a combination of \ the two if and only if 'DLA Inspired' is plugged in a direct \ colouring. If plugged into a gradient colouring then the \ 'Combined' option is ignored and 'Colour' used instead." visible = @numplants>8 endparam float param palmin10 caption = "Min. Palette Index" default = 0.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the lower end of the palette \ portion for the organism." visible = @numplants>8 endparam float param palmax10 caption = "Max. Palette Index" default = 399.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the upper end of the palette \ portion for the organism." visible = @numplants>8 endparam color param lightcol10 caption = "Lighting Colour" default = RGB(1.0,1.0,1.0) hint = "The colour for the lighting in 'Combined' mode, ignored if using \ gradient colouring." visible = @method10==2 && @numplants>8 endparam float param nodirection10 caption = "Directionless Growth" default = 0.0 hint = "Here you can specify the number of points of directionless \ growth of the organism per generation. Directionless growth \ occurs randomly from any edge point on the organism and is \ not affected by any stimulus. Note that you can use fractional \ values, 0.5 means a 50% chance of one pixel of directionless \ growth per generation, 1.25 means one pixel of directionless \ growth and a 25% chance of a second. Normally you should use \ zero or a positive number but if you use a negative value then \ there will be so many pixels of directionless growth \ of the organism only when there is no directed growth due to \ an active stimulus." visible = @numplants>8 endparam MMF_SeedDLA param DLASeed10 caption = "Organism 10 Seeding" default = MMF_OnePointSeedDLA hint = "Sets the seeding method for the organism." visible = @numplants>8 endparam bool param Seed10Stimulus1 caption = "Reacts to Stimulus 1" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 1' i.e. it treats them as food or light." visible = @numplants>8 endparam bool param Seed10Stimulus2 caption = "Reacts to Stimulus 2" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 2' i.e. it treats them as food or light." visible = @numplants>8 && @numstimuli>0 endparam bool param Seed10Stimulus3 caption = "Reacts to Stimulus 3" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 3' i.e. it treats them as food or light." visible = @numplants>8 && @numstimuli>1 endparam bool param Seed10Stimulus4 caption = "Reacts to Stimulus 4" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 4' i.e. it treats them as food or light." visible = @numplants>8 && @numstimuli>2 endparam bool param Seed10Stimulus5 caption = "Reacts to Stimulus 5" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 5' i.e. it treats them as food or light." visible = @numplants>8 && @numstimuli>3 endparam bool param Seed10Stimulus6 caption = "Reacts to Stimulus 6" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 6' i.e. it treats them as food or light." visible = @numplants>8 && @numstimuli>4 endparam bool param Seed10Stimulus7 caption = "Reacts to Stimulus 7" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 7' i.e. it treats them as food or light." visible = @numplants>8 && @numstimuli>5 endparam bool param Seed10Stimulus8 caption = "Reacts to Stimulus 8" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 8' i.e. it treats them as food or light." visible = @numplants>8 && @numstimuli>6 endparam bool param Seed10Stimulus9 caption = "Reacts to Stimulus 9" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 9' i.e. it treats them as food or light." visible = @numplants>8 && @numstimuli>7 endparam bool param Seed10Stimulus10 caption = "Reacts to Stimulus 10" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 10' i.e. it treats them as food or light." visible = @numplants>8 && @numstimuli>8 endparam bool param Seed10Stimulus11 caption = "Reacts to Stimulus 11" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 11' i.e. it treats them as food or light." visible = @numplants>8 && @numstimuli>9 endparam bool param Seed10Stimulus12 caption = "Reacts to Stimulus 12" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 12' i.e. it treats them as food or light." visible = @numplants>8 && @numstimuli>10 endparam bool param Seed10Stimulus13 caption = "Reacts to Stimulus 13" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 13' i.e. it treats them as food or light." visible = @numplants>8 && @numstimuli>11 endparam bool param Seed10Stimulus14 caption = "Reacts to Stimulus 14" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 14' i.e. it treats them as food or light." visible = @numplants>8 && @numstimuli>12 endparam bool param Seed10Stimulus15 caption = "Reacts to Stimulus 15" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 15' i.e. it treats them as food or light." visible = @numplants>8 && @numstimuli>13 endparam bool param Seed10Stimulus16 caption = "Reacts to Stimulus 16" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 16' i.e. it treats them as food or light." visible = @numplants>8 && @numstimuli>14 endparam float param detect10 caption = "Detection accuracy" default = 1.0 min = 1.0 hint = "This is the accuracy with which the organism detects stimuli. \ An accuracy of 1 means it always detects the stimulus accurately, \ if you use 2 then it estimates the distance to the stimulus at \ somewhere between the correct value and twice the correct value. \ A setting of 10 means the organism could estimate the distance at \ being up to 10* further than it is." visible = @numplants>8 && @addrandom endparam float param move10 caption = "Movement Detection" default = 1.0 min = 0.0 hint = "Use zero for no movement detection, otherwise the larger the \ value specified the greater the effect of a moving stimulus. \ Typically use values from say 1 to 10." visible = @numplants>8 && @addmovement endparam heading caption = "Eleventh Organism" visible = @numplants>9 endheading float param size11 caption = "Maximum Size" default = 100.0 min = 0.0 max = 100.0 hint = "The maximum size of this organism is this %age of the screen \ pixels. When the number of growth pixels based on this %age \ has occurred then growth of this organism stops." visible = @numplants>9 endparam int param method11 caption = "Colouring Method" enum = "Colour" "Slope" "Combined" default = 0 hint = "You can choose to colour the fractal with just the default \ colouring or using a 'slope' colouring or a combination of \ the two if and only if 'DLA Inspired' is plugged in a direct \ colouring. If plugged into a gradient colouring then the \ 'Combined' option is ignored and 'Colour' used instead." visible = @numplants>9 endparam float param palmin11 caption = "Min. Palette Index" default = 0.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the lower end of the palette \ portion for the organism." visible = @numplants>9 endparam float param palmax11 caption = "Max. Palette Index" default = 399.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the upper end of the palette \ portion for the organism." visible = @numplants>9 endparam color param lightcol11 caption = "Lighting Colour" default = RGB(1.0,1.0,1.0) hint = "The colour for the lighting in 'Combined' mode, ignored if using \ gradient colouring." visible = @method11==2 && @numplants>9 endparam float param nodirection11 caption = "Directionless Growth" default = 0.0 hint = "Here you can specify the number of points of directionless \ growth of the organism per generation. Directionless growth \ occurs randomly from any edge point on the organism and is \ not affected by any stimulus. Note that you can use fractional \ values, 0.5 means a 50% chance of one pixel of directionless \ growth per generation, 1.25 means one pixel of directionless \ growth and a 25% chance of a second. Normally you should use \ zero or a positive number but if you use a negative value then \ there will be so many pixels of directionless growth \ of the organism only when there is no directed growth due to \ an active stimulus." visible = @numplants>9 endparam MMF_SeedDLA param DLASeed11 caption = "Organism 11 Seeding" default = MMF_OnePointSeedDLA hint = "Sets the seeding method for the organism." visible = @numplants>9 endparam bool param Seed11Stimulus1 caption = "Reacts to Stimulus 1" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 1' i.e. it treats them as food or light." visible = @numplants>9 endparam bool param Seed11Stimulus2 caption = "Reacts to Stimulus 2" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 2' i.e. it treats them as food or light." visible = @numplants>9 && @numstimuli>0 endparam bool param Seed11Stimulus3 caption = "Reacts to Stimulus 3" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 3' i.e. it treats them as food or light." visible = @numplants>9 && @numstimuli>1 endparam bool param Seed11Stimulus4 caption = "Reacts to Stimulus 4" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 4' i.e. it treats them as food or light." visible = @numplants>9 && @numstimuli>2 endparam bool param Seed11Stimulus5 caption = "Reacts to Stimulus 5" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 5' i.e. it treats them as food or light." visible = @numplants>9 && @numstimuli>3 endparam bool param Seed11Stimulus6 caption = "Reacts to Stimulus 6" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 6' i.e. it treats them as food or light." visible = @numplants>9 && @numstimuli>4 endparam bool param Seed11Stimulus7 caption = "Reacts to Stimulus 7" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 7' i.e. it treats them as food or light." visible = @numplants>9 && @numstimuli>5 endparam bool param Seed11Stimulus8 caption = "Reacts to Stimulus 8" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 8' i.e. it treats them as food or light." visible = @numplants>9 && @numstimuli>6 endparam bool param Seed11Stimulus9 caption = "Reacts to Stimulus 9" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 9' i.e. it treats them as food or light." visible = @numplants>9 && @numstimuli>7 endparam bool param Seed11Stimulus10 caption = "Reacts to Stimulus 10" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 10' i.e. it treats them as food or light." visible = @numplants>9 && @numstimuli>8 endparam bool param Seed11Stimulus11 caption = "Reacts to Stimulus 11" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 11' i.e. it treats them as food or light." visible = @numplants>9 && @numstimuli>9 endparam bool param Seed11Stimulus12 caption = "Reacts to Stimulus 12" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 12' i.e. it treats them as food or light." visible = @numplants>9 && @numstimuli>10 endparam bool param Seed11Stimulus13 caption = "Reacts to Stimulus 13" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 13' i.e. it treats them as food or light." visible = @numplants>9 && @numstimuli>11 endparam bool param Seed11Stimulus14 caption = "Reacts to Stimulus 14" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 14' i.e. it treats them as food or light." visible = @numplants>9 && @numstimuli>12 endparam bool param Seed11Stimulus15 caption = "Reacts to Stimulus 15" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 15' i.e. it treats them as food or light." visible = @numplants>9 && @numstimuli>13 endparam bool param Seed11Stimulus16 caption = "Reacts to Stimulus 16" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 16' i.e. it treats them as food or light." visible = @numplants>9 && @numstimuli>14 endparam float param detect11 caption = "Detection accuracy" default = 1.0 min = 1.0 hint = "This is the accuracy with which the organism detects stimuli. \ An accuracy of 1 means it always detects the stimulus accurately, \ if you use 2 then it estimates the distance to the stimulus at \ somewhere between the correct value and twice the correct value. \ A setting of 10 means the organism could estimate the distance at \ being up to 10* further than it is." visible = @numplants>9 && @addrandom endparam float param move11 caption = "Movement Detection" default = 1.0 min = 0.0 hint = "Use zero for no movement detection, otherwise the larger the \ value specified the greater the effect of a moving stimulus. \ Typically use values from say 1 to 10." visible = @numplants>9 && @addmovement endparam heading caption = "Twelfth Organism" visible = @numplants>10 endheading float param size12 caption = "Maximum Size" default = 100.0 min = 0.0 max = 100.0 hint = "The maximum size of this organism is this %age of the screen \ pixels. When the number of growth pixels based on this %age \ has occurred then growth of this organism stops." visible = @numplants>10 endparam int param method12 caption = "Colouring Method" enum = "Colour" "Slope" "Combined" default = 0 hint = "You can choose to colour the fractal with just the default \ colouring or using a 'slope' colouring or a combination of \ the two if and only if 'DLA Inspired' is plugged in a direct \ colouring. If plugged into a gradient colouring then the \ 'Combined' option is ignored and 'Colour' used instead." visible = @numplants>10 endparam float param palmin12 caption = "Min. Palette Index" default = 0.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the lower end of the palette \ portion for the organism." visible = @numplants>10 endparam float param palmax12 caption = "Max. Palette Index" default = 399.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the upper end of the palette \ portion for the organism." visible = @numplants>10 endparam color param lightcol12 caption = "Lighting Colour" default = RGB(1.0,1.0,1.0) hint = "The colour for the lighting in 'Combined' mode, ignored if using \ gradient colouring." visible = @method12==2 && @numplants>10 endparam float param nodirection12 caption = "Directionless Growth" default = 0.0 hint = "Here you can specify the number of points of directionless \ growth of the organism per generation. Directionless growth \ occurs randomly from any edge point on the organism and is \ not affected by any stimulus. Note that you can use fractional \ values, 0.5 means a 50% chance of one pixel of directionless \ growth per generation, 1.25 means one pixel of directionless \ growth and a 25% chance of a second. Normally you should use \ zero or a positive number but if you use a negative value then \ there will be so many pixels of directionless growth \ of the organism only when there is no directed growth due to \ an active stimulus." visible = @numplants>10 endparam MMF_SeedDLA param DLASeed12 caption = "Organism 12 Seeding" default = MMF_OnePointSeedDLA hint = "Sets the seeding method for the organism." visible = @numplants>10 endparam bool param Seed12Stimulus1 caption = "Reacts to Stimulus 1" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 1' i.e. it treats them as food or light." visible = @numplants>10 endparam bool param Seed12Stimulus2 caption = "Reacts to Stimulus 2" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 2' i.e. it treats them as food or light." visible = @numplants>10 && @numstimuli>0 endparam bool param Seed12Stimulus3 caption = "Reacts to Stimulus 3" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 3' i.e. it treats them as food or light." visible = @numplants>10 && @numstimuli>1 endparam bool param Seed12Stimulus4 caption = "Reacts to Stimulus 4" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 4' i.e. it treats them as food or light." visible = @numplants>10 && @numstimuli>2 endparam bool param Seed12Stimulus5 caption = "Reacts to Stimulus 5" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 5' i.e. it treats them as food or light." visible = @numplants>10 && @numstimuli>3 endparam bool param Seed12Stimulus6 caption = "Reacts to Stimulus 6" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 6' i.e. it treats them as food or light." visible = @numplants>10 && @numstimuli>4 endparam bool param Seed12Stimulus7 caption = "Reacts to Stimulus 7" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 7' i.e. it treats them as food or light." visible = @numplants>10 && @numstimuli>5 endparam bool param Seed12Stimulus8 caption = "Reacts to Stimulus 8" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 8' i.e. it treats them as food or light." visible = @numplants>10 && @numstimuli>6 endparam bool param Seed12Stimulus9 caption = "Reacts to Stimulus 9" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 9' i.e. it treats them as food or light." visible = @numplants>10 && @numstimuli>7 endparam bool param Seed12Stimulus10 caption = "Reacts to Stimulus 10" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 10' i.e. it treats them as food or light." visible = @numplants>10 && @numstimuli>8 endparam bool param Seed12Stimulus11 caption = "Reacts to Stimulus 11" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 11' i.e. it treats them as food or light." visible = @numplants>10 && @numstimuli>9 endparam bool param Seed12Stimulus12 caption = "Reacts to Stimulus 12" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 12' i.e. it treats them as food or light." visible = @numplants>10 && @numstimuli>10 endparam bool param Seed12Stimulus13 caption = "Reacts to Stimulus 13" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 13' i.e. it treats them as food or light." visible = @numplants>10 && @numstimuli>11 endparam bool param Seed12Stimulus14 caption = "Reacts to Stimulus 14" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 14' i.e. it treats them as food or light." visible = @numplants>10 && @numstimuli>12 endparam bool param Seed12Stimulus15 caption = "Reacts to Stimulus 15" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 15' i.e. it treats them as food or light." visible = @numplants>10 && @numstimuli>13 endparam bool param Seed12Stimulus16 caption = "Reacts to Stimulus 16" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 16' i.e. it treats them as food or light." visible = @numplants>10 && @numstimuli>14 endparam float param detect12 caption = "Detection accuracy" default = 1.0 min = 1.0 hint = "This is the accuracy with which the organism detects stimuli. \ An accuracy of 1 means it always detects the stimulus accurately, \ if you use 2 then it estimates the distance to the stimulus at \ somewhere between the correct value and twice the correct value. \ A setting of 10 means the organism could estimate the distance at \ being up to 10* further than it is." visible = @numplants>10 && @addrandom endparam float param move12 caption = "Movement Detection" default = 1.0 min = 0.0 hint = "Use zero for no movement detection, otherwise the larger the \ value specified the greater the effect of a moving stimulus. \ Typically use values from say 1 to 10." visible = @numplants>10 && @addmovement endparam heading caption = "Thirteenth Organism" visible = @numplants>11 endheading float param size13 caption = "Maximum Size" default = 100.0 min = 0.0 max = 100.0 hint = "The maximum size of this organism is this %age of the screen \ pixels. When the number of growth pixels based on this %age \ has occurred then growth of this organism stops." visible = @numplants>11 endparam int param method13 caption = "Colouring Method" enum = "Colour" "Slope" "Combined" default = 0 hint = "You can choose to colour the fractal with just the default \ colouring or using a 'slope' colouring or a combination of \ the two if and only if 'DLA Inspired' is plugged in a direct \ colouring. If plugged into a gradient colouring then the \ 'Combined' option is ignored and 'Colour' used instead." visible = @numplants>11 endparam float param palmin13 caption = "Min. Palette Index" default = 0.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the lower end of the palette \ portion for the organism." visible = @numplants>11 endparam float param palmax13 caption = "Max. Palette Index" default = 399.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the upper end of the palette \ portion for the organism." visible = @numplants>11 endparam color param lightcol13 caption = "Lighting Colour" default = RGB(1.0,1.0,1.0) hint = "The colour for the lighting in 'Combined' mode, ignored if using \ gradient colouring." visible = @method13==2 && @numplants>11 endparam float param nodirection13 caption = "Directionless Growth" default = 0.0 hint = "Here you can specify the number of points of directionless \ growth of the organism per generation. Directionless growth \ occurs randomly from any edge point on the organism and is \ not affected by any stimulus. Note that you can use fractional \ values, 0.5 means a 50% chance of one pixel of directionless \ growth per generation, 1.25 means one pixel of directionless \ growth and a 25% chance of a second. Normally you should use \ zero or a positive number but if you use a negative value then \ there will be so many pixels of directionless growth \ of the organism only when there is no directed growth due to \ an active stimulus." visible = @numplants>11 endparam MMF_SeedDLA param DLASeed13 caption = "Organism 13 Seeding" default = MMF_OnePointSeedDLA hint = "Sets the seeding method for the organism." visible = @numplants>11 endparam bool param Seed13Stimulus1 caption = "Reacts to Stimulus 1" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 1' i.e. it treats them as food or light." visible = @numplants>11 endparam bool param Seed13Stimulus2 caption = "Reacts to Stimulus 2" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 2' i.e. it treats them as food or light." visible = @numplants>11 && @numstimuli>0 endparam bool param Seed13Stimulus3 caption = "Reacts to Stimulus 3" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 3' i.e. it treats them as food or light." visible = @numplants>11 && @numstimuli>1 endparam bool param Seed13Stimulus4 caption = "Reacts to Stimulus 4" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 4' i.e. it treats them as food or light." visible = @numplants>11 && @numstimuli>2 endparam bool param Seed13Stimulus5 caption = "Reacts to Stimulus 5" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 5' i.e. it treats them as food or light." visible = @numplants>11 && @numstimuli>3 endparam bool param Seed13Stimulus6 caption = "Reacts to Stimulus 6" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 6' i.e. it treats them as food or light." visible = @numplants>11 && @numstimuli>4 endparam bool param Seed13Stimulus7 caption = "Reacts to Stimulus 7" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 7' i.e. it treats them as food or light." visible = @numplants>11 && @numstimuli>5 endparam bool param Seed13Stimulus8 caption = "Reacts to Stimulus 8" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 8' i.e. it treats them as food or light." visible = @numplants>11 && @numstimuli>6 endparam bool param Seed13Stimulus9 caption = "Reacts to Stimulus 9" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 9' i.e. it treats them as food or light." visible = @numplants>11 && @numstimuli>7 endparam bool param Seed13Stimulus10 caption = "Reacts to Stimulus 10" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 10' i.e. it treats them as food or light." visible = @numplants>11 && @numstimuli>8 endparam bool param Seed13Stimulus11 caption = "Reacts to Stimulus 11" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 11' i.e. it treats them as food or light." visible = @numplants>11 && @numstimuli>9 endparam bool param Seed13Stimulus12 caption = "Reacts to Stimulus 12" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 12' i.e. it treats them as food or light." visible = @numplants>11 && @numstimuli>10 endparam bool param Seed13Stimulus13 caption = "Reacts to Stimulus 13" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 13' i.e. it treats them as food or light." visible = @numplants>11 && @numstimuli>11 endparam bool param Seed13Stimulus14 caption = "Reacts to Stimulus 14" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 14' i.e. it treats them as food or light." visible = @numplants>11 && @numstimuli>12 endparam bool param Seed13Stimulus15 caption = "Reacts to Stimulus 15" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 15' i.e. it treats them as food or light." visible = @numplants>11 && @numstimuli>13 endparam bool param Seed13Stimulus16 caption = "Reacts to Stimulus 16" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 16' i.e. it treats them as food or light." visible = @numplants>11 && @numstimuli>14 endparam float param detect13 caption = "Detection accuracy" default = 1.0 min = 1.0 hint = "This is the accuracy with which the organism detects stimuli. \ An accuracy of 1 means it always detects the stimulus accurately, \ if you use 2 then it estimates the distance to the stimulus at \ somewhere between the correct value and twice the correct value. \ A setting of 10 means the organism could estimate the distance at \ being up to 10* further than it is." visible = @numplants>11 && @addrandom endparam float param move13 caption = "Movement Detection" default = 1.0 min = 0.0 hint = "Use zero for no movement detection, otherwise the larger the \ value specified the greater the effect of a moving stimulus. \ Typically use values from say 1 to 10." visible = @numplants>11 && @addmovement endparam heading caption = "Fourteenth Organism" visible = @numplants>12 endheading float param size14 caption = "Maximum Size" default = 100.0 min = 0.0 max = 100.0 hint = "The maximum size of this organism is this %age of the screen \ pixels. When the number of growth pixels based on this %age \ has occurred then growth of this organism stops." visible = @numplants>12 endparam int param method14 caption = "Colouring Method" enum = "Colour" "Slope" "Combined" default = 0 hint = "You can choose to colour the fractal with just the default \ colouring or using a 'slope' colouring or a combination of \ the two if and only if 'DLA Inspired' is plugged in a direct \ colouring. If plugged into a gradient colouring then the \ 'Combined' option is ignored and 'Colour' used instead." visible = @numplants>12 endparam float param palmin14 caption = "Min. Palette Index" default = 0.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the lower end of the palette \ portion for the organism." visible = @numplants>12 endparam float param palmax14 caption = "Max. Palette Index" default = 399.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the upper end of the palette \ portion for the organism." visible = @numplants>12 endparam color param lightcol14 caption = "Lighting Colour" default = RGB(1.0,1.0,1.0) hint = "The colour for the lighting in 'Combined' mode, ignored if using \ gradient colouring." visible = @method14==2 && @numplants>12 endparam float param nodirection14 caption = "Directionless Growth" default = 0.0 hint = "Here you can specify the number of points of directionless \ growth of the organism per generation. Directionless growth \ occurs randomly from any edge point on the organism and is \ not affected by any stimulus. Note that you can use fractional \ values, 0.5 means a 50% chance of one pixel of directionless \ growth per generation, 1.25 means one pixel of directionless \ growth and a 25% chance of a second. Normally you should use \ zero or a positive number but if you use a negative value then \ there will be so many pixels of directionless growth \ of the organism only when there is no directed growth due to \ an active stimulus." visible = @numplants>12 endparam MMF_SeedDLA param DLASeed14 caption = "Organism 14 Seeding" default = MMF_OnePointSeedDLA hint = "Sets the seeding method for the organism." visible = @numplants>12 endparam bool param Seed14Stimulus1 caption = "Reacts to Stimulus 1" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 1' i.e. it treats them as food or light." visible = @numplants>12 endparam bool param Seed14Stimulus2 caption = "Reacts to Stimulus 2" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 2' i.e. it treats them as food or light." visible = @numplants>12 && @numstimuli>0 endparam bool param Seed14Stimulus3 caption = "Reacts to Stimulus 3" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 3' i.e. it treats them as food or light." visible = @numplants>12 && @numstimuli>1 endparam bool param Seed14Stimulus4 caption = "Reacts to Stimulus 4" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 4' i.e. it treats them as food or light." visible = @numplants>12 && @numstimuli>2 endparam bool param Seed14Stimulus5 caption = "Reacts to Stimulus 5" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 5' i.e. it treats them as food or light." visible = @numplants>12 && @numstimuli>3 endparam bool param Seed14Stimulus6 caption = "Reacts to Stimulus 6" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 6' i.e. it treats them as food or light." visible = @numplants>12 && @numstimuli>4 endparam bool param Seed14Stimulus7 caption = "Reacts to Stimulus 7" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 7' i.e. it treats them as food or light." visible = @numplants>12 && @numstimuli>5 endparam bool param Seed14Stimulus8 caption = "Reacts to Stimulus 8" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 8' i.e. it treats them as food or light." visible = @numplants>12 && @numstimuli>6 endparam bool param Seed14Stimulus9 caption = "Reacts to Stimulus 9" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 9' i.e. it treats them as food or light." visible = @numplants>12 && @numstimuli>7 endparam bool param Seed14Stimulus10 caption = "Reacts to Stimulus 10" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 10' i.e. it treats them as food or light." visible = @numplants>12 && @numstimuli>8 endparam bool param Seed14Stimulus11 caption = "Reacts to Stimulus 11" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 11' i.e. it treats them as food or light." visible = @numplants>12 && @numstimuli>9 endparam bool param Seed14Stimulus12 caption = "Reacts to Stimulus 12" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 12' i.e. it treats them as food or light." visible = @numplants>12 && @numstimuli>10 endparam bool param Seed14Stimulus13 caption = "Reacts to Stimulus 13" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 13' i.e. it treats them as food or light." visible = @numplants>12 && @numstimuli>11 endparam bool param Seed14Stimulus14 caption = "Reacts to Stimulus 14" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 14' i.e. it treats them as food or light." visible = @numplants>12 && @numstimuli>12 endparam bool param Seed14Stimulus15 caption = "Reacts to Stimulus 15" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 15' i.e. it treats them as food or light." visible = @numplants>12 && @numstimuli>13 endparam bool param Seed14Stimulus16 caption = "Reacts to Stimulus 16" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 16' i.e. it treats them as food or light." visible = @numplants>12 && @numstimuli>14 endparam float param detect14 caption = "Detection accuracy" default = 1.0 min = 1.0 hint = "This is the accuracy with which the organism detects stimuli. \ An accuracy of 1 means it always detects the stimulus accurately, \ if you use 2 then it estimates the distance to the stimulus at \ somewhere between the correct value and twice the correct value. \ A setting of 10 means the organism could estimate the distance at \ being up to 10* further than it is." visible = @numplants>12 && @addrandom endparam float param move14 caption = "Movement Detection" default = 1.0 min = 0.0 hint = "Use zero for no movement detection, otherwise the larger the \ value specified the greater the effect of a moving stimulus. \ Typically use values from say 1 to 10." visible = @numplants>12 && @addmovement endparam heading caption = "Fifteenth Organism" visible = @numplants>13 endheading float param size15 caption = "Maximum Size" default = 100.0 min = 0.0 max = 100.0 hint = "The maximum size of this organism is this %age of the screen \ pixels. When the number of growth pixels based on this %age \ has occurred then growth of this organism stops." visible = @numplants>13 endparam int param method15 caption = "Colouring Method" enum = "Colour" "Slope" "Combined" default = 0 hint = "You can choose to colour the fractal with just the default \ colouring or using a 'slope' colouring or a combination of \ the two if and only if 'DLA Inspired' is plugged in a direct \ colouring. If plugged into a gradient colouring then the \ 'Combined' option is ignored and 'Colour' used instead." visible = @numplants>13 endparam float param palmin15 caption = "Min. Palette Index" default = 0.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the lower end of the palette \ portion for the organism." visible = @numplants>13 endparam float param palmax15 caption = "Max. Palette Index" default = 399.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the upper end of the palette \ portion for the organism." visible = @numplants>13 endparam color param lightcol15 caption = "Lighting Colour" default = RGB(1.0,1.0,1.0) hint = "The colour for the lighting in 'Combined' mode, ignored if using \ gradient colouring." visible = @method15==2 && @numplants>13 endparam float param nodirection15 caption = "Directionless Growth" default = 0.0 hint = "Here you can specify the number of points of directionless \ growth of the organism per generation. Directionless growth \ occurs randomly from any edge point on the organism and is \ not affected by any stimulus. Note that you can use fractional \ values, 0.5 means a 50% chance of one pixel of directionless \ growth per generation, 1.25 means one pixel of directionless \ growth and a 25% chance of a second. Normally you should use \ zero or a positive number but if you use a negative value then \ there will be so many pixels of directionless growth \ of the organism only when there is no directed growth due to \ an active stimulus." visible = @numplants>13 endparam MMF_SeedDLA param DLASeed15 caption = "Organism 15 Seeding" default = MMF_OnePointSeedDLA hint = "Sets the seeding method for the organism." visible = @numplants>13 endparam bool param Seed15Stimulus1 caption = "Reacts to Stimulus 1" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 1' i.e. it treats them as food or light." visible = @numplants>13 endparam bool param Seed15Stimulus2 caption = "Reacts to Stimulus 2" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 2' i.e. it treats them as food or light." visible = @numplants>13 && @numstimuli>0 endparam bool param Seed15Stimulus3 caption = "Reacts to Stimulus 3" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 3' i.e. it treats them as food or light." visible = @numplants>13 && @numstimuli>1 endparam bool param Seed15Stimulus4 caption = "Reacts to Stimulus 4" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 4' i.e. it treats them as food or light." visible = @numplants>13 && @numstimuli>2 endparam bool param Seed15Stimulus5 caption = "Reacts to Stimulus 5" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 5' i.e. it treats them as food or light." visible = @numplants>13 && @numstimuli>3 endparam bool param Seed15Stimulus6 caption = "Reacts to Stimulus 6" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 6' i.e. it treats them as food or light." visible = @numplants>13 && @numstimuli>4 endparam bool param Seed15Stimulus7 caption = "Reacts to Stimulus 7" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 7' i.e. it treats them as food or light." visible = @numplants>13 && @numstimuli>5 endparam bool param Seed15Stimulus8 caption = "Reacts to Stimulus 8" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 8' i.e. it treats them as food or light." visible = @numplants>13 && @numstimuli>6 endparam bool param Seed15Stimulus9 caption = "Reacts to Stimulus 9" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 9' i.e. it treats them as food or light." visible = @numplants>13 && @numstimuli>7 endparam bool param Seed15Stimulus10 caption = "Reacts to Stimulus 10" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 10' i.e. it treats them as food or light." visible = @numplants>13 && @numstimuli>8 endparam bool param Seed15Stimulus11 caption = "Reacts to Stimulus 11" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 11' i.e. it treats them as food or light." visible = @numplants>13 && @numstimuli>9 endparam bool param Seed15Stimulus12 caption = "Reacts to Stimulus 12" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 12' i.e. it treats them as food or light." visible = @numplants>13 && @numstimuli>10 endparam bool param Seed15Stimulus13 caption = "Reacts to Stimulus 13" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 13' i.e. it treats them as food or light." visible = @numplants>13 && @numstimuli>11 endparam bool param Seed15Stimulus14 caption = "Reacts to Stimulus 14" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 14' i.e. it treats them as food or light." visible = @numplants>13 && @numstimuli>12 endparam bool param Seed15Stimulus15 caption = "Reacts to Stimulus 15" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 15' i.e. it treats them as food or light." visible = @numplants>13 && @numstimuli>13 endparam bool param Seed15Stimulus16 caption = "Reacts to Stimulus 16" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 16' i.e. it treats them as food or light." visible = @numplants>13 && @numstimuli>14 endparam float param detect15 caption = "Detection accuracy" default = 1.0 min = 1.0 hint = "This is the accuracy with which the organism detects stimuli. \ An accuracy of 1 means it always detects the stimulus accurately, \ if you use 2 then it estimates the distance to the stimulus at \ somewhere between the correct value and twice the correct value. \ A setting of 10 means the organism could estimate the distance at \ being up to 10* further than it is." visible = @numplants>13 && @addrandom endparam float param move15 caption = "Movement Detection" default = 1.0 min = 0.0 hint = "Use zero for no movement detection, otherwise the larger the \ value specified the greater the effect of a moving stimulus. \ Typically use values from say 1 to 10." visible = @numplants>13 && @addmovement endparam heading caption = "Sixteenth Organism" visible = @numplants>14 endheading float param size16 caption = "Maximum Size" default = 100.0 min = 0.0 max = 100.0 hint = "The maximum size of this organism is this %age of the screen \ pixels. When the number of growth pixels based on this %age \ has occurred then growth of this organism stops." visible = @numplants>14 endparam int param method16 caption = "Colouring Method" enum = "Colour" "Slope" "Combined" default = 0 hint = "You can choose to colour the fractal with just the default \ colouring or using a 'slope' colouring or a combination of \ the two if and only if 'DLA Inspired' is plugged in a direct \ colouring. If plugged into a gradient colouring then the \ 'Combined' option is ignored and 'Colour' used instead." visible = @numplants>14 endparam float param palmin16 caption = "Min. Palette Index" default = 0.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the lower end of the palette \ portion for the organism." visible = @numplants>14 endparam float param palmax16 caption = "Max. Palette Index" default = 399.0 min = 0.0 max = 399.0 hint = "Specifies the gradient index of the upper end of the palette \ portion for the organism." visible = @numplants>14 endparam color param lightcol16 caption = "Lighting Colour" default = RGB(1.0,1.0,1.0) hint = "The colour for the lighting in 'Combined' mode, ignored if using \ gradient colouring." visible = @method16==2 && @numplants>14 endparam float param nodirection16 caption = "Directionless Growth" default = 0.0 hint = "Here you can specify the number of points of directionless \ growth of the organism per generation. Directionless growth \ occurs randomly from any edge point on the organism and is \ not affected by any stimulus. Note that you can use fractional \ values, 0.5 means a 50% chance of one pixel of directionless \ growth per generation, 1.25 means one pixel of directionless \ growth and a 25% chance of a second. Normally you should use \ zero or a positive number but if you use a negative value then \ there will be so many pixels of directionless growth \ of the organism only when there is no directed growth due to \ an active stimulus." visible = @numplants>14 endparam MMF_SeedDLA param DLASeed16 caption = "Organism 16 Seeding" default = MMF_OnePointSeedDLA hint = "Sets the seeding method for the organism." visible = @numplants>14 endparam bool param Seed16Stimulus1 caption = "Reacts to Stimulus 1" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 1' i.e. it treats them as food or light." visible = @numplants>14 endparam bool param Seed16Stimulus2 caption = "Reacts to Stimulus 2" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 2' i.e. it treats them as food or light." visible = @numplants>14 && @numstimuli>0 endparam bool param Seed16Stimulus3 caption = "Reacts to Stimulus 3" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 3' i.e. it treats them as food or light." visible = @numplants>14 && @numstimuli>1 endparam bool param Seed16Stimulus4 caption = "Reacts to Stimulus 4" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 4' i.e. it treats them as food or light." visible = @numplants>14 && @numstimuli>2 endparam bool param Seed16Stimulus5 caption = "Reacts to Stimulus 5" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 5' i.e. it treats them as food or light." visible = @numplants>14 && @numstimuli>3 endparam bool param Seed16Stimulus6 caption = "Reacts to Stimulus 6" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 6' i.e. it treats them as food or light." visible = @numplants>14 && @numstimuli>4 endparam bool param Seed16Stimulus7 caption = "Reacts to Stimulus 7" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 7' i.e. it treats them as food or light." visible = @numplants>14 && @numstimuli>5 endparam bool param Seed16Stimulus8 caption = "Reacts to Stimulus 8" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 8' i.e. it treats them as food or light." visible = @numplants>14 && @numstimuli>6 endparam bool param Seed16Stimulus9 caption = "Reacts to Stimulus 9" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 9' i.e. it treats them as food or light." visible = @numplants>14 && @numstimuli>7 endparam bool param Seed16Stimulus10 caption = "Reacts to Stimulus 10" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 10' i.e. it treats them as food or light." visible = @numplants>14 && @numstimuli>8 endparam bool param Seed16Stimulus11 caption = "Reacts to Stimulus 11" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 11' i.e. it treats them as food or light." visible = @numplants>14 && @numstimuli>9 endparam bool param Seed16Stimulus12 caption = "Reacts to Stimulus 12" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 12' i.e. it treats them as food or light." visible = @numplants>14 && @numstimuli>10 endparam bool param Seed16Stimulus13 caption = "Reacts to Stimulus 13" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 13' i.e. it treats them as food or light." visible = @numplants>14 && @numstimuli>11 endparam bool param Seed16Stimulus14 caption = "Reacts to Stimulus 14" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 14' i.e. it treats them as food or light." visible = @numplants>14 && @numstimuli>12 endparam bool param Seed16Stimulus15 caption = "Reacts to Stimulus 15" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 15' i.e. it treats them as food or light." visible = @numplants>14 && @numstimuli>13 endparam bool param Seed16Stimulus16 caption = "Reacts to Stimulus 16" default = true hint = "When enabled the organism is attracted to points generated by \ 'Stimulus 16' i.e. it treats them as food or light." visible = @numplants>14 && @numstimuli>14 endparam float param detect16 caption = "Detection accuracy" default = 1.0 min = 1.0 hint = "This is the accuracy with which the organism detects stimuli. \ An accuracy of 1 means it always detects the stimulus accurately, \ if you use 2 then it estimates the distance to the stimulus at \ somewhere between the correct value and twice the correct value. \ A setting of 10 means the organism could estimate the distance at \ being up to 10* further than it is." visible = @numplants>14 && @addrandom endparam float param move16 caption = "Movement Detection" default = 1.0 min = 0.0 hint = "Use zero for no movement detection, otherwise the larger the \ value specified the greater the effect of a moving stimulus. \ Typically use values from say 1 to 10." visible = @numplants>14 && @addmovement endparam } class MMF_QuickImage(common.ulb:DirectColoring) { public: import "common.ulb" ; Image just displays an image from disk. It's best used on the Outside tab, ; together with the Pixel formula from Standard.ufm. import "Standard.ulb" func MMF_QuickImage(Generic pparent) Generic.Generic(pparent) m_img = new @f_image(this) if @showsize $define DEBUG if !m_img.getEmpty() print("Width: ",m_img.getWidth()) print("Height: ",m_img.getHeight()) else print("No image") endif endif endfunc color func Result(complex pz) ; Use #pixel as the complex coordinate inside the image, but scale such that ; the default corner coordinates (-2,1.5)..(2,-1.5) correspond to the entire ; image width. complex c = 0.5 * pz if !m_img.getEmpty() if m_img.getHeight() ; @param pparent typically 'this' from the parent or zero func MMF_AdjustmentLayers(Generic pparent) Generic.Generic(pparent) m_Adjust = new @f_adjust(this) m_Adjust1 = new @f_adjust1(this) m_Adjustmore = new @f_adjustmore(this) m_Adjustmore1 = new @f_adjustmore1(this) endfunc float func stretch(float col) if col>=@min && col<=@max if @skew if col<=@centre return 0.5*(col-@min)/(@centre-@min) else return 0.5 + 0.5*(col-@centre)/(@max-@centre) endif else return (col - @min)/(@max - @min) endif endif return col endfunc float func contract(float col,float old) if old>=@min && old<=@max if @skew if old<=@centre return @min + 2.0*col*(@centre-@min) else return @centre + 2.0*(col-0.5)*(@max-@centre) endif else return @min + col*(@max-@min) endif endif return old endfunc ;

; @param pbottom the base color ; @return adjusted color color func Adjust(color pbottom) color ptop color pbase = pbottom if @stretch pbottom = rgb( stretch(red(pbottom)), stretch(green(pbottom)), \ stretch(blue(pbottom)) ) endif if @adjusttype==0 ptop = RGB(@adjred, @adjgreen, @adjblue) else ptop = @f_adjustcolour endif ptop = compose(pbottom, m_Adjust.Merge(pbottom, ptop), @f_opacity) if @stretch ptop = rgb( contract(red(ptop),red(pbase)), \ contract(green(ptop),green(pbase)), \ contract(blue(ptop),blue(pbase)) ) endif if @rept ptop = m_Adjustmore.Adjust(ptop) endif if @domore ptop = compose(ptop, \ m_Adjust1.Merge(ptop, m_Adjustmore1.Adjust(pbase)), @f_opacity1) endif return RGBA(red(ptop), green(ptop), blue(ptop), alpha(pbottom)) endfunc private: ColorMerge m_Adjust ColorMerge m_Adjust1 Adjustmentlayer m_Adjustmore Adjustmentlayer m_Adjustmore1 default: title = "MMF Adjustment Layers" param v_mmfadjustmentlayer caption = "Version (MMF Adjustment Layers)" enum = "1.0" default = 0 hint = "This field is to absolutely ensure backward compatibility, \ the default will always be set to the latest version, but \ there may be some cases where an older effect that you like \ is lost in an update and you could still use it by selecting \ the older version number." visible = false endparam int param adjusttype caption = "Colour or RGB" enum = "RGB values" "Colour Parameter" default = 1 hint = "This option is specifically added so that if you choose \ 'RGB values' you can 'explore' them and see changes to the image \ as you change the RGB. The option may become redundant in a \ future version of UF." endparam float param adjred caption = "Red Value" default = 1.0 hint = "The red part of the adjust colour (0 to 1)." visible = @adjusttype==0 endparam float param adjgreen caption = "Green Value" default = 1.0 hint = "The green part of the adjust colour (0 to 1)." visible = @adjusttype==0 endparam float param adjblue caption = "Blue Value" default = 1.0 hint = "The blue part of the adjust colour (0 to 1)." visible = @adjusttype==0 endparam color param f_adjustcolour caption = "Adjust Layer Colour" default = RGB(1,1,1) hint = "Allows you to apply overall adjustments to your colouring." visible = @adjusttype==1 endparam bool param stretch caption = "Restrict range" default = false hint = "When enabled you can set a range between 0 and 1 using a specified \ minimum and maximum such that the adjustment is restricted to that \ range." endparam float param min caption = "Range Minimum" default = 0.2 hint = "Value should be less than Range Maximum" visible = @stretch endparam float param max caption = "Range Maximum" default = 0.8 hint = "Value should be more than Range Minimum" visible = @stretch endparam bool param skew caption = "Skew centre" default = false hint = "When enabled the chosen range is skewed by using the specified \ value as the centre of the range" endparam float param centre caption = "Range Centre" default = 0.5 hint = "Value should be between Range Minimum and Range Maximum" visible = @stretch && @skew endparam ColorMerge param f_adjust caption = "Adjustment Layer Merge" default = MMF_ExtendedColorMerge hint = "How the adjust colour is applied to the layer." endparam float param f_opacity caption = "Adjustment Opacity" default = 1.0 hint = "Use to modify the adjustment opacity, the normal range is from \ 0 to 1." endparam heading text = "Additional adjustments" endheading bool param rept caption = "Add another adjustment" default = false endparam Adjustmentlayer param f_adjustmore caption = "Extra adjustment" default = MMF_AdjustmentLayer visible = @rept endparam bool param domore caption = "Add another layer" default = true endparam ColorMerge param f_adjust1 caption = "Adjustment Layers Merge" default = MMF_ExtendedColorMerge hint = "How the two adjusted layers are merged." visible = @domore endparam float param f_opacity1 caption = "Merge Opacity" default = 1.0 hint = "Use to modify the merge opacity, the normal range is from \ 0 to 1." visible = @domore endparam Adjustmentlayer param f_adjustmore1 caption = "Extra adjustment layer" default = MMF_AdjustmentLayer visible = @domore endparam }