1
0
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:
Tomáš Brada 2015-02-08 16:58:57 +01:00
parent e912d0c5e5
commit 51d5d0b83a
4 changed files with 75 additions and 109 deletions

View File

@ -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

View File

@ -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.")

View File

@ -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)

View File

@ -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)