mirror of
git://repo.or.cz/rocks.git
synced 2025-01-01 14:00:30 +01:00
Optimalized layer generator. Breaks veins and ores.
This commit is contained in:
parent
e912d0c5e5
commit
51d5d0b83a
@ -15,7 +15,8 @@ rocks.register_vein("clay",{
|
||||
hmin=-8, hmax=nil,
|
||||
layers={ "mudstone" },
|
||||
})
|
||||
rocks.register_ore( "clay", "default:clay", {treshold=0, chance=0.8 } )
|
||||
rocks.register_ore( "clay", "default:clay", {treshold=0, chance=1 } )
|
||||
rocks.register_ore( "clay", "default:torch", {treshold=0, chance=0.3 } )
|
||||
|
||||
-- Breccia Mixture soft in mudstone
|
||||
-- Conglomerate Sed soft in mudstone
|
||||
@ -23,6 +24,13 @@ rocks.register_ore( "clay", "default:clay", {treshold=0, chance=0.8 } )
|
||||
-- Hornfels MM/contact vhard in mudstone in mountains
|
||||
-- Marble MM/contact hard in mudstone in mountains
|
||||
-- Limestone Sed med in Rhyolite, Andesite in mountains
|
||||
rocks.register_vein("limestone",{
|
||||
spread = {x=10, y=10, z=10},
|
||||
treshold=0.75,
|
||||
seed = 10,
|
||||
hmin=nil, hmax=nil,
|
||||
layers={ "mudstone" },
|
||||
})
|
||||
-- Dolomite Sed med in Rhyolite, Andesite in mountains
|
||||
-- Quartzite MM/contact vhard sandstone
|
||||
|
||||
|
15
init.lua
15
init.lua
@ -20,8 +20,19 @@ rocks.noiseparams_layers = {
|
||||
}
|
||||
|
||||
dofile(modpath.."/mapgen.lua")
|
||||
dofile(modpath.."/geologica.lua")
|
||||
dofile(modpath.."/geologica_nv.lua")
|
||||
dofile(modpath.."/testing.lua")
|
||||
--dofile(modpath.."/geologica.lua")
|
||||
--dofile(modpath.."/geologica_nv.lua")
|
||||
|
||||
print("[rocks] sorting layers")
|
||||
|
||||
for i,d in pairs(rocks.layers_name) do table.insert(rocks.layers,d) end
|
||||
table.sort(rocks.layers,function(a,b)
|
||||
return a.height<b.height
|
||||
end)
|
||||
|
||||
for i,d in pairs(rocks.layers) do
|
||||
print(" init,layer "..i.." "..minetest.serialize(d))
|
||||
end
|
||||
|
||||
print("[rocks] loaded.")
|
||||
|
143
mapgen.lua
143
mapgen.lua
@ -2,128 +2,75 @@
|
||||
-- layer generator
|
||||
--
|
||||
|
||||
local function mknoises(layers,minp,maxp,seed)
|
||||
local nm={}
|
||||
for ln,ld in pairs(rocks.layers) do
|
||||
if (ld.height-ld.gain<maxp.y)and((not ld.maxheight)or(ld.maxheight+ld.gain>minp.y)) then
|
||||
local np=rocks.noiseparams_layers
|
||||
np.seed=ld.seed
|
||||
local side_length = (maxp.x - minp.x) + 1
|
||||
local map_lengths_xyz = {x=side_length, y=side_length, z=side_length}
|
||||
ld.nmap=minetest.get_perlin_map(np,map_lengths_xyz):get2dMap({x=minp.x, y=minp.z})
|
||||
local vidx=1
|
||||
for vn,vd in pairs(ld.veins) do
|
||||
-- todo check if hmax,hmin is in current block
|
||||
vd.onmap=minetest.get_perlin_map(vd.np,map_lengths_xyz):get3dMap_flat(minp)
|
||||
vidx=vidx+1
|
||||
end
|
||||
table.insert(nm,ld)
|
||||
end
|
||||
end
|
||||
return nm
|
||||
end
|
||||
|
||||
local function mkheightmap(layers,x,z,minp,maxp)
|
||||
local hm={}
|
||||
for ln,ld in pairs(layers) do
|
||||
local noise=ld.nmap[z-minp.z+1][x-minp.x+1]
|
||||
if noise<ld.limit then
|
||||
ld.nh = (noise*ld.gain)+ld.height
|
||||
-- if (ld.nh<maxy)and(ld.nh>miny)
|
||||
table.insert(hm,ld)
|
||||
end
|
||||
end
|
||||
return hm
|
||||
end
|
||||
|
||||
local stonectx=nil
|
||||
local airctx=nil
|
||||
|
||||
minetest.register_on_generated(function(minp, maxp, seed)
|
||||
if not stone_ctx then stone_ctx= minetest.get_content_id("default:stone") end
|
||||
if not air_ctx then air_ctx= minetest.get_content_id("air") end
|
||||
-- noise values range (-1;+1) (1 octave)
|
||||
-- 3 octaves it is like 1.7 max
|
||||
-- 4 octaves with 0.8 presist = 2.125 max !!
|
||||
stone_ctx= minetest.get_content_id("default:stone")
|
||||
air_ctx= minetest.get_content_id("air")
|
||||
local timebefore=os.clock();
|
||||
local manipulator, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local nodes = manipulator:get_data()
|
||||
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
|
||||
-- initialize noises and sort out unused layers
|
||||
local availlayers=mknoises(rocks.layers,minp,maxp,seed)
|
||||
local perlin_index = 1
|
||||
local side_length = (maxp.x - minp.x) + 1
|
||||
local map_lengths_xyz = {x=side_length, y=side_length, z=side_length}
|
||||
|
||||
-- sort out unused layers
|
||||
-- generate noises
|
||||
avl={}
|
||||
for i,d in ipairs(rocks.layers) do
|
||||
-- h je normaalna vyyska horného konca vrstvy
|
||||
if (d.height+d.gain)>=minp.y then -- ak je to mimo zdola tak ju vyhodime
|
||||
-- urobime sum pre vrstvu
|
||||
local np=rocks.noiseparams_layers
|
||||
np.seed=d.seed
|
||||
np.scale=d.gain
|
||||
np.offset=d.height
|
||||
d.nmap=minetest.get_perlin_map(np,map_lengths_xyz):get2dMap_flat({x=minp.x, y=minp.z})
|
||||
-- contene_id kamenov
|
||||
d.rock.ctx=d.rock.ctx or minetest.get_content_id(d.rock.node)
|
||||
table.insert(avl,d) -- pridame ju
|
||||
if (d.height-d.gain)>maxp.y then break end -- ak je mimo zhora tak uz dalsie nehladaj
|
||||
else
|
||||
print(" no higher "..d.height.." than "..minp.y)
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
print("[rocks] afterinit "..os.clock()-timebefore)
|
||||
print("[rocks] afterinit "..os.clock()-timebefore.." #layers="..#avl)
|
||||
for lh,ld in ipairs(avl) do
|
||||
print(" "..lh.."->"..ld.name)
|
||||
end
|
||||
|
||||
local noise2d_ix = 1
|
||||
local noise3d_ix = 1
|
||||
|
||||
for x=minp.x,maxp.x,1 do
|
||||
for z=minp.z,maxp.z,1 do
|
||||
--* initialize layers hmap
|
||||
local layers=mkheightmap(availlayers,x,z,minp,maxp)
|
||||
if layers then for y=minp.y,maxp.y,1 do
|
||||
|
||||
for y=minp.y,maxp.y,1 do
|
||||
local p_pos = area:index(x, y, z)
|
||||
local layer,rock
|
||||
|
||||
--* select layer
|
||||
local layer
|
||||
for ln,ld in pairs(layers) do
|
||||
if (ld)and
|
||||
(ld.nh<y)and
|
||||
((not layer)or(ld.height>layer.height))
|
||||
then
|
||||
for lh,ld in ipairs(avl) do
|
||||
if y<ld.nmap[noise2d_ix] then
|
||||
layer=ld
|
||||
rock=layer.rock
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
--* select vein
|
||||
local vein=nil
|
||||
if layer then
|
||||
for vn,vd in pairs(layer.veins) do
|
||||
if ((not vd.hmin) or y>vd.hmin)
|
||||
and((not vd.hmax) or y<vd.hmax)
|
||||
and(vd.onmap[perlin_index]>vd.treshold)
|
||||
then
|
||||
vein=vd
|
||||
end
|
||||
end
|
||||
--if vein then print("[rocks] generate vein") end
|
||||
end
|
||||
|
||||
--* select rock
|
||||
local rock=nil
|
||||
if vein then
|
||||
for von,vod in pairs(vein.ores) do
|
||||
if not vod.pr then vod.pr=PseudoRandom(seed+von) end
|
||||
if (vein.onmap[perlin_index]>vod.treshold)
|
||||
and(vod.pr:next(0,1)<=vod.chance) --< todo add pseudorandom chance
|
||||
and( (not rock) or
|
||||
(vod.treshold>=rock.treshold
|
||||
-- or vod.chance<=rock.chance works better with this disabled
|
||||
)
|
||||
)
|
||||
then
|
||||
rock=vod
|
||||
end
|
||||
end
|
||||
end
|
||||
if (not rock) and layer then
|
||||
rock=layer.rock -- not in vein? > select base rock
|
||||
end
|
||||
|
||||
--* place rocks
|
||||
if (rock) and(nodes[p_pos]==stone_ctx) then
|
||||
if not rock.ctx then
|
||||
rock.ctx=minetest.get_content_id(rock.node)
|
||||
end
|
||||
nodes[p_pos] = rock.ctx
|
||||
-- if minp.x>0 then nodes[p_pos]=air_ctx end -- debug
|
||||
end
|
||||
|
||||
perlin_index =perlin_index+1
|
||||
end end
|
||||
noise3d_ix =noise3d_ix+1
|
||||
end
|
||||
noise2d_ix = noise2d_ix+1
|
||||
end
|
||||
end
|
||||
manipulator:set_data(nodes)
|
||||
-- manipulator:calc_lighting()
|
||||
-- manipulator:update_liquids()
|
||||
manipulator:calc_lighting()
|
||||
manipulator:update_liquids()
|
||||
manipulator:write_to_map()
|
||||
print("[rocks] gen "..os.clock()-timebefore)
|
||||
end)
|
||||
|
16
register.lua
16
register.lua
@ -3,6 +3,7 @@
|
||||
rocks = {}
|
||||
|
||||
rocks.layers = {}
|
||||
rocks.layers_name = {}
|
||||
rocks.veins = {}
|
||||
rocks.ores = {}
|
||||
|
||||
@ -12,20 +13,19 @@ rocks.register_layer=function(name,params,rock)
|
||||
assert(params.gain)
|
||||
assert(params.height)
|
||||
local maxheight
|
||||
for ln,ld in pairs(rocks.layers) do
|
||||
if (ld.height<params.height)and ((not ld.maxheight) or (ld.maxheight>params.height)) then ld.maxheight=params.height end
|
||||
if (ld.height>params.height)and((not maxheight) or (maxheight>ld.height)) then maxheight=ld.height end
|
||||
end
|
||||
rocks.layers[name]= {
|
||||
|
||||
local ld= {
|
||||
gain=params.gain,
|
||||
height=params.height,
|
||||
maxheight=maxheight,
|
||||
limit=params.limit,
|
||||
seed=params.seed,
|
||||
rock={ node=rock },
|
||||
veins={}
|
||||
veins={},
|
||||
name=name
|
||||
}
|
||||
print("[rocks] layer "..name)
|
||||
rocks.layers_name[name]= ld
|
||||
print("[rocks] layer "..ld.name)
|
||||
end
|
||||
|
||||
rocks.register_vein=function(name,params)
|
||||
@ -44,7 +44,7 @@ rocks.register_vein=function(name,params)
|
||||
layers=params.layers,
|
||||
ores={}
|
||||
}
|
||||
for ln,ld in pairs(rocks.layers) do
|
||||
for ln,ld in pairs(rocks.layers_name) do
|
||||
ld.veins[name]=rocks.veins[name]
|
||||
end
|
||||
print("[rocks] vein "..name)
|
||||
|
Loading…
Reference in New Issue
Block a user