Voxelmanip/perlinmap version

This commit is contained in:
paramat 2014-10-11 05:55:20 +01:00
parent 56dd643d38
commit dd5fafdc22
2 changed files with 164 additions and 116 deletions

View File

@ -1,14 +1,4 @@
Release thread http://forum.minetest.net/viewtopic.php?id=5159 meru 0.3.0 by paramat
For latest stable Minetest and compatible back to 0.4.3. For latest stable Minetest and compatible back to 0.4.8
Depends default. Depends default
License WTFPL. License WTFPL
* Meru mod is a vertical 1 dimensional realm, 1D referring to large scale structure, and can act as a vertical connector between horizontal realms, such as the ground and the floatlands.
* A single spike shaped mountain is created in newly generated chunks, at a random location within a chosen area; by default this area is +/-1024 for use in a new world, to add a mountain to an existing world you need to edit these area parameters to a completely ungenerated part of your world.
* For testing this mod or for cheating edit parameter COORD = true, the co-ordinates of the mountain will be printed to terminal while within the generation area.
* No new nodes, the mountain is a hollow cone made of stone and desert stone, with a smooth transition across biome boundaries creating the red stripes. By default the height is 1km, but since i have increased the maximum width to 3x3 chunks the mountain can still look well proportioned when 2km. There are a few cave entrances on the surface, these 'fissure system' caves expand under the surface helping the creation of a path upwards. If the mountain generates over water you can use the central conical void to jump down the last few hundred metres.
* There are many parameters for fine tuning the structure, some parameters change smoothly with height or distance from the center. Reducing noise to zero at the center creates a perfect spike as a summit. Constant noise throughout often creates floating islands at the summit. Choosing zero noise throughout creates a smooth geometric conical shape. There is a parameter CONVEX to control whether the basic conical structure bulges outwards or is pinched inwards in the middle.

224
init.lua
View File

@ -1,128 +1,186 @@
-- meru 0.2.0 by paramat. -- meru 0.3.0 by paramat
-- License WTFPL. -- For latest stable Minetest and compatible back to 0.4.8
-- Depends default
-- License WTFPL
-- Parameters. -- Voxelmanip version
local ONGEN = true -- (true / false) Enable / disable generation. -- Parameters
local PROG = true -- Print processing progess to terminal.
local COORD = false -- Print tower co-ordinates to terminal.
local XMIN = -1024 -- Area for random spawn. local COORD = false -- Print tower co-ordinates to terminal (cheat)
local XMIN = -1024 -- Area for random spawn
local XMAX = 1024 local XMAX = 1024
local ZMIN = -1024 local ZMIN = -1024
local ZMAX = 1024 local ZMAX = 1024
local BASRAD = 64 -- -- Average radius y = -32. local BASRAD = 64 -- Average radius at y = -32
local HEIGHT = 1024 -- -- Approximate height measured from y = -32. local HEIGHT = 2048 -- Approximate height measured from y = -32
local CONVEX = 0.6 -- -- Convexity. 0.5 = concave, 1 = perfect cone, 2 = convex. local CONVEX = 0.6 -- Convexity. <1 = concave, 1 = conical, >1 = convex
local VOID = 0.4 -- -- Void threshold. Controls size of central voids. local VOID = 0.4 -- Void threshold. Controls size of central void
local NOISYRAD = 0.2 -- -- Noisyness of structure at base radius. 0 = smooth geometric form, 0.3 = noisy. local NOISYRAD = 0.2 -- Noisyness of structure at base radius. 0 = smooth geometric form, 0.3 = noisy
local NOISYCEN = 0 -- -- Noisyness of structure at centre. local NOISYCEN = 0 -- Noisyness of structure at centre
local FISOFFBAS = 0.02 -- -- Fissure noise offset at base. controls amount / size of fissure entrances on outer surface. local FISOFFBAS = 0.02 -- Fissure noise offset at base. controls size of fissure entrances on outer surface
local FISOFFTOP = 0.04 -- -- Fissure noise offset at top. local FISOFFTOP = 0.04 -- Fissure noise offset at top
local FISEXPBAS = 0.6 -- -- Fissure expansion rate under surface at base. local FISEXPBAS = 0.6 -- Fissure expansion rate under surface at base
local FISEXPTOP = 1.2 -- -- Fissure expansion rate under surface at top. local FISEXPTOP = 1.2 -- Fissure expansion rate under surface at top
local SEEDDIFF1 = 46893 -- 3D noise for primary structure. -- 3D noise for primary structure
local OCTAVES1 = 5 --
local PERSISTENCE1 = 0.5 --
local SCALE1 = 64 --
local SEEDDIFF2 = 92940980987 -- 3D noise for fissures. local np_structure = {
local OCTAVES2 = 4 -- offset = 0,
local PERSISTENCE2 = 0.5 -- scale = 1,
local SCALE2 = 24 -- spread = {x=64, y=64, z=64},
seed = 46893,
octaves = 5,
persist = 0.5
}
-- End of parameters. -- 3D noise for fissures
meru = {} local np_fissure = {
offset = 0,
scale = 1,
spread = {x=24, y=24, z=24},
seed = 92940980987,
octaves = 4,
persist = 0.5
}
local SEEDDIFF3 = 9130 -- 9130 -- Values should match minetest mapgen desert perlin. -- End of parameters
local OCTAVES3 = 3 -- 3
local PERSISTENCE3 = 0.5 -- 0.5
local SCALE3 = 250 -- 250
local SEEDDIFF4 = 5839090 -- 2D noise for biome. Parameters must match mgv6 biome noise
local OCTAVES4 = 2 -- 2
local PERSISTENCE4 = 0.5 -- 0.5
local SCALE4 = 3 -- 3
local cxmin = math.floor((XMIN + 32) / 80) -- chunk co ordinates local np_biome = {
offset = 0,
scale = 1,
spread = {x=250, y=250, z=250},
seed = 9130,
octaves = 3,
persist = 0.5
}
local cxmin = math.floor((XMIN + 32) / 80) -- limits in chunk co-ordinates
local czmin = math.floor((ZMIN + 32) / 80) local czmin = math.floor((ZMIN + 32) / 80)
local cxmax = math.floor((XMAX + 32) / 80) local cxmax = math.floor((XMAX + 32) / 80)
local czmax = math.floor((ZMAX + 32) / 80) local czmax = math.floor((ZMAX + 32) / 80)
local cxav = (cxmin + cxmax) / 2 local cxav = (cxmin + cxmax) / 2 -- spawn area midpoint in chunk co-ordinates
local czav = (czmin + czmax) / 2 local czav = (czmin + czmax) / 2
local xnom = (cxmax - cxmin) / 4 local xnom = (cxmax - cxmin) / 4 -- noise multipliers
local znom = (czmax - czmin) / 4 local znom = (czmax - czmin) / 4
-- On generated function. -- Nodes
if ONGEN then minetest.register_node("meru:stone", {
minetest.register_on_generated(function(minp, maxp, seed) description = "Stone",
if maxp.x >= XMIN and minp.x <= XMAX tiles = {"default_stone.png"},
and maxp.z >= ZMIN and minp.z <= ZMAX then is_ground_content = false,
local env = minetest.env groups = {cracky=3, stone=1},
local perlin4 = env:get_perlin(SEEDDIFF4, OCTAVES4, PERSISTENCE4, SCALE4) drop = "default:cobble",
local noisex = perlin4:get2d({x=31,y=23}) sounds = default.node_sound_stone_defaults(),
local noisez = perlin4:get2d({x=17,y=11}) })
minetest.register_node("meru:destone", {
description = "Desert Stone",
tiles = {"default_desert_stone.png"},
is_ground_content = false,
groups = {cracky=3, stone=1},
drop = "default:desert_stone",
sounds = default.node_sound_stone_defaults(),
})
-- On generated function
minetest.register_on_generated(function(minp, maxp, seed)
if maxp.x < XMIN or minp.x > XMAX
or maxp.z < ZMIN or minp.z > ZMAX then
return
end
local locnoise = minetest.get_perlin(5839090, 2, 0.5, 3)
local noisex = locnoise:get2d({x=31,y=23})
local noisez = locnoise:get2d({x=17,y=11})
local cx = cxav + math.floor(noisex * xnom) -- chunk co ordinates local cx = cxav + math.floor(noisex * xnom) -- chunk co ordinates
local cz = czav + math.floor(noisez * znom) local cz = czav + math.floor(noisez * znom)
local merux = 80 * cx + 8 local merux = 80 * cx + 8
local meruz = 80 * cz + 8 local meruz = 80 * cz + 8
if COORD then if COORD then
print ("[meru] x "..merux.." z "..meruz) print ("[meru] at x "..merux.." z "..meruz)
end end
if minp.x >= merux - 120 and minp.x <= merux + 40 if minp.x < merux - 120 or minp.x > merux + 40
and minp.z >= meruz - 120 and minp.z <= meruz + 40 or minp.z < meruz - 120 or minp.z > meruz + 40
and minp.y >= -32 and minp.y <= HEIGHT * 1.2 then or minp.y < -32 or minp.y > HEIGHT * 1.2 then
local perlin1 = env:get_perlin(SEEDDIFF1, OCTAVES1, PERSISTENCE1, SCALE1) return
local perlin2 = env:get_perlin(SEEDDIFF2, OCTAVES2, PERSISTENCE2, SCALE2) end
local perlin3 = env:get_perlin(SEEDDIFF3, OCTAVES3, PERSISTENCE3, SCALE3)
local x1 = maxp.x local t0 = os.clock()
local y1 = maxp.y
local z1 = maxp.z
local x0 = minp.x local x0 = minp.x
local y0 = minp.y local y0 = minp.y
local z0 = minp.z local z0 = minp.z
-- Loop through nodes in chunk. local x1 = maxp.x
for x = x0, x1 do local y1 = maxp.y
-- For each plane do. local z1 = maxp.z
if PROG then print ("[meru] chunk minp ("..x0.." "..y0.." "..z0..")")
print ("[meru] Plane "..x - x0.." Chunk ("..minp.x.." "..minp.y.." "..minp.z..")")
end local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
local data = vm:get_data()
local c_stone = minetest.get_content_id("meru:stone")
local c_destone = minetest.get_content_id("meru:destone")
local sidelen = x1 - x0 + 1
local chulens = {x=sidelen, y=sidelen, z=sidelen}
local minposxyz = {x=x0, y=y0, z=z0}
local nvals_structure = minetest.get_perlin_map(np_structure, chulens):get3dMap_flat(minposxyz)
local nvals_fissure = minetest.get_perlin_map(np_fissure, chulens):get3dMap_flat(minposxyz)
local nvals_biome = minetest.get_perlin_map(np_biome, chulens):get2dMap_flat({x=x0+150, y=z0+50})
local nixyz = 1 -- 3D noise index
local nixz = 1 -- 2D noise index
for z = z0, z1 do for z = z0, z1 do
-- For each column do.
local noise3 = perlin3:get2d({x=x+150,y=z+50}) -- Offsets must match minetest mapgen desert perlin.
local desert = false
if noise3 > 0.45 or math.random(0,10) > (0.45 - noise3) * 100 then -- Smooth transition 0.35 to 0.45.
desert = true
end
for y = y0, y1 do for y = y0, y1 do
-- For each node do. local vi = area:index(x0, y, z)
local noise1 = perlin1:get3d({x=x,y=y,z=z}) for x = x0, x1 do
local n_structure = nvals_structure[nixyz]
local radius = ((x - merux) ^ 2 + (z - meruz) ^ 2) ^ 0.5 local radius = ((x - merux) ^ 2 + (z - meruz) ^ 2) ^ 0.5
local deprop = (BASRAD - radius) / BASRAD local deprop = (BASRAD - radius) / BASRAD -- radial depth proportion
local noisy = NOISYRAD + deprop * (NOISYCEN - NOISYRAD) local noisy = NOISYRAD + deprop * (NOISYCEN - NOISYRAD)
local heprop = ((y + 32) / HEIGHT) local heprop = ((y + 32) / HEIGHT) -- height proportion
local offset = deprop - heprop ^ CONVEX local offset = deprop - heprop ^ CONVEX
local noise1off = noise1 * noisy + offset local n_offstructure = n_structure * noisy + offset
if noise1off > 0 and noise1off < VOID then if n_offstructure > 0 and n_offstructure < VOID then
local noise2 = perlin2:get3d({x=x,y=y,z=z}) local n_absfissure = math.abs(nvals_fissure[nixyz])
local fisoff = FISOFFBAS + heprop * (FISOFFTOP - FISOFFBAS) local fisoff = FISOFFBAS + heprop * (FISOFFTOP - FISOFFBAS)
local fisexp = FISEXPBAS + heprop * (FISEXPTOP - FISEXPBAS) local fisexp = FISEXPBAS + heprop * (FISEXPTOP - FISEXPBAS)
if math.abs(noise2) - noise1off * fisexp - fisoff > 0 then if n_absfissure - n_offstructure * fisexp - fisoff > 0 then
local n_biome = nvals_biome[nixz]
local desert = n_biome > 0.45
or math.random(0,10) > (0.45 - n_biome) * 100
if desert then if desert then
env:add_node({x=x,y=y,z=z},{name="default:desert_stone"}) data[vi] = c_destone
else else
env:add_node({x=x,y=y,z=z},{name="default:stone"}) data[vi] = c_stone
end end
end end
end end
nixyz = nixyz + 1
nixz = nixz + 1
vi = vi + 1
end end
nixz = nixz - sidelen
end end
nixz = nixz + sidelen
end end
end
end vm:set_data(data)
end) vm:set_lighting({day=0, night=0})
end vm:calc_lighting()
vm:write_to_map(data)
local chugent = math.ceil((os.clock() - t0) * 1000)
print ("[meru] "..chugent.." ms")
end)