if not modules then modules = { } end modules ['mlib-eff'] = { version = 1.001, optimize = true, comment = "companion to mlib-ctx.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files", } -- musical timestamp: Snarky Puppy & Metropole Orkest - Waves Upon Waves (cond. -- Jules Buckley) [Official Video] : begin september 2025 (we still have -- fantastic human made music!) local type, tonumber, load = type, tonumber, load local report = logs.reporter("metapost","effect") local registerdirect = metapost.registerdirect local scannumber = mp.scan.number local injectnumber = mp.inject.number local setbytemap = mp.setbytemap local getbytemap = mp.getbytemap local newbytemap = mp.newbytemap local getbytemapdata = mp.getbytemapdata local loadbytemapfile = mp.loadbytemapfile local setbytemapoctave = mp.setbytemapoctave local perlinnoise = effects.perlinnoise local perlinoctave = effects.perlinoctave local simplexnoise = effects.simplexnoise local simplexoctave = effects.simplexoctave local angleoctave = effects.angleoctave local detailoctave = effects.detailoctave local directoctave = effects.octave local octavebytemap = effects.octavebytemap local newoctave = effects.newoctave local stepoctave = effects.stepoctave local octavemethods = effects.getoctavemethods() local octaveloops = effects.getoctaveloops() local octavevariants = effects.getoctavevariants() local function noise(method) injectnumber(method( scannumber(), -- x scannumber(), -- y scannumber() -- z )) end local function octave(method) injectnumber(method( scannumber(), -- iterations scannumber(), -- amplitude scannumber(), -- frequency scannumber(), -- persistence scannumber(), -- lacunarity scannumber(), -- angle scannumber(), -- minimum scannumber(), -- maximum scannumber(), -- x scannumber() -- y )) end registerdirect("perlinnoise", function() noise(perlinnoise) end) registerdirect("simplexnoise", function() noise(simplexnoise) end) registerdirect("perlinoctave", function() noise(perlinoctave) end) registerdirect("simplexoctave", function() noise(simplexoctave) end) local getparameterset = metapost.getparameterset local f_function = [[ local math = math local round = math.round %s -- todo: only dx dy when detail return function(v,x,y,dx,dy) return %s end ]] function mp.lmt_noise_do() local p = getparameterset() -- local bytemap = tonumber(p.bytemap) or 1 local nx = tonumber(p.nx) or 10 local ny = tonumber(p.ny) or 10 local nz = tonumber(p.nz) or 1 local iterations = tonumber(p.iterations) or 1 local amplitude = tonumber(p.amplitude) or 1.0 local frequency = tonumber(p.frequency) or tonumber(p.scale) or 1.0 local persistence = tonumber(p.persistence) or 0.5 local lacunarity = tonumber(p.lacunarity) or 2.0 local minimum = tonumber(p.minimum) or 0 local maximum = tonumber(p.maximum) or 255 local colorcode = p.colorcode or "" local colorfunction = p.colorfunction or "" local method = p.method or "perlin" local preamble = p.preamble or "" local angle = tonumber(p.angle) or 0 local initialize = p.initialize local filename = p.filename or "" local action = false local trace = p.trace -- todo: check color depth if colorfunction ~= "" then action = MP[colorfunction] end if type(action) ~= "function" and colorcode ~= "" then colorcode = string.formatters[f_function](preamble,colorcode) action = load(colorcode) if type(action) == "function" then action = action() end end if type(action) ~= "function" then -- action = function(v) return v, v, v end action = false -- function(v) return v, v, v end end -- local slowloop = true local slowloop = false -- local data local keep = false if filename ~= "" then nx, ny, nz = loadbytemapfile(bytemap,filename) if not slowloop then nx, ny, nz, data = getbytemapdata(bytemap,true) end keep = true elseif initialize == false then -- redefinition needs checking -- nx, ny, nz, data = getbytemapdata(bytemap,false) if not slowloop then nx, ny, nz, data = getbytemapdata(bytemap,true) end keep = true else newbytemap(bytemap,nx,ny,nz) end -- -- print(data) -- local z = p.z local t = { } if trace then statistics.starttiming(t) report("method : %s",method) report("horizontal : %i",nx) report("vertical : %i",ny) report("depth : %i",nz) report("iterations : %i",iterations) report("amplitude : %N",amplitude) report("frequency : %N",frequency) report("persistence : %N",persistence) report("lacunarity : %N",lacunarity) report("minimum : %N",minimum) report("maximum : %N",maximum) report("angle : %N",angle) if z then report("z value : %N",z) end end -- local octave if method == "test1" then if not action then -- ignore elseif z then for x=0,nx-1 do for y=0,ny-1 do local v = directoctave(2,iterations,amplitude,frequency,persistence,lacunarity,angle,minimum,maximum,x,y,z) setbytemap(bytemap,x,y,action(v,x,y)) -- r, g, b end end else for x=0,nx-1 do for y=0,ny-1 do local v = directoctave(2,iterations,amplitude,frequency,persistence,lacunarity,angle,minimum,maximum,x,y) setbytemap(bytemap,x,y,action(v,x,y)) -- r, g, b end end end elseif method == "test2" then octave = newoctave(2,iterations,amplitude,frequency,persistence,lacunarity,angle,minimum,maximum,z or false) local result, size = octavebytemap(octave,nx,ny,nz,action,data) newbytemap(bytemap,nx,ny,nz,result) elseif method == "simplex" then if slowloop and action then octave = newoctave(2,iterations,amplitude,frequency,persistence,lacunarity,angle,minimum,maximum) if z then for x=0,nx-1 do for y=0,ny-1 do local v = stepoctave(octave,x,y,z) setbytemap(bytemap,x,y,action(v,x,y)) -- r, g, b end end else for x=0,nx-1 do for y=0,ny-1 do local v = stepoctave(octave,x,y) setbytemap(bytemap,x,y,action(v,x,y)) -- r, g, b end end end else octave = newoctave(2,iterations,amplitude,frequency,persistence,lacunarity,angle,minimum,maximum,z or false) newbytemap(bytemap,nx,ny,nz) setbytemapoctave(bytemap,octave,action) end elseif method == "detail" then if slowloop and action then octave = newoctave(4,iterations,amplitude,frequency,persistence,lacunarity,angle,minimum,maximum) if z then if keep then for x=0,nx-1 do for y=0,ny-1 do local v, dx, dy = stepoctave(octave,x,y,z) setbytemap(bytemap,x,y,action(v,x,y,dx,dy,getbytemap(bytemap,x,y))) -- r, g, b end end else for x=0,nx-1 do for y=0,ny-1 do local v, dx, dy = stepoctave(octave,x,y,z) setbytemap(bytemap,x,y,action(v,x,y,dx,dy)) -- r, g, b end end end else if keep then for x=0,nx-1 do for y=0,ny-1 do local v, dx, dy = stepoctave(octave,x,y) setbytemap(bytemap,x,y,action(v,x,y,dx,dy,getbytemap(bytemap,x,y))) -- r, g, b end end else for x=0,nx-1 do for y=0,ny-1 do local v, dx, dy = stepoctave(octave,x,y) setbytemap(bytemap,x,y,action(v,x,y,dx,dy)) -- r, g, b end end end end else octave = newoctave(4,iterations,amplitude,frequency,persistence,lacunarity,angle,minimum,maximum,z or false) newbytemap(bytemap,nx,ny,nz) setbytemapoctave(bytemap,octave,action) end elseif method == "angle" then if slowloop and action then octave = newoctave(3,iterations,amplitude,frequency,persistence,lacunarity,angle,minimum,maximum) if z then for x=0,nx-1 do for y=0,ny-1 do local v = stepoctave(octave,x,y,z) setbytemap(bytemap,x,y,action(v,x,y)) -- r, g, b end end else for x=0,nx-1 do for y=0,ny-1 do local v = stepoctave(octave,x,y) setbytemap(bytemap,x,y,action(v,x,y)) -- r, g, b end end end else octave = newoctave(3,iterations,amplitude,frequency,persistence,lacunarity,angle,minimum,maximum,z or false) newbytemap(bytemap,nx,ny,nz) setbytemapoctave(bytemap,octave,action) end else if slowloop and action then octave = newoctave(1,iterations,amplitude,frequency,persistence,lacunarity,angle,minimum,maximum) if z then for x=0,nx-1 do for y=0,ny-1 do local v = stepoctave(octave,x,y,z) setbytemap(bytemap,x,y,action(v,x,y)) -- r, g, b end end else for x=0,nx-1 do for y=0,ny-1 do local v = stepoctave(octave,x,y) setbytemap(bytemap,x,y,action(v,x,y)) -- r, g, b end end end else octave = newoctave(1,iterations,amplitude,frequency,persistence,lacunarity,angle,minimum,maximum,z or false) newbytemap(bytemap,nx,ny,nz) setbytemapoctave(bytemap,octave,action) end end if trace then if octave then local s = effects.getoctavestatus(octave) report("used method : %s", octavemethods[s.method]) report("used variant : %s", octavevariants[s.variant]) if s.zset then report("used z value : %N", s.z) end if s.wset then report("used w value : %N", s.w) end end statistics.stoptiming(t) report("seconds used : %s",statistics.elapsedseconds(t)) end end