big nasty function to find flat areas
parent
a507933974
commit
9db4f7af6a
|
@ -0,0 +1,190 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local type_lookup = {}
|
||||||
|
|
||||||
|
for name,def in pairs(minetest.registered_nodes) do
|
||||||
|
if def.groups.soil then
|
||||||
|
type_lookup[minetest.get_content_id(name)] = 1 -- 1 is "ground"
|
||||||
|
elseif def.groups.cracky then
|
||||||
|
type_lookup[minetest.get_content_id(name)] = 1 -- cracky things are part of the ground
|
||||||
|
elseif def.groups.sand then
|
||||||
|
type_lookup[minetest.get_content_id(name)] = 1
|
||||||
|
elseif def.groups.crumbly then
|
||||||
|
type_lookup[minetest.get_content_id(name)] = 1 -- gravel, clay, snow, etc
|
||||||
|
|
||||||
|
elseif def.groups.choppy then
|
||||||
|
type_lookup[minetest.get_content_id(name)] = 0 -- trees, wood, etc
|
||||||
|
elseif def.groups.snappy then
|
||||||
|
type_lookup[minetest.get_content_id(name)] = 0 -- grass, leaves, etc
|
||||||
|
elseif def.groups.fleshy then
|
||||||
|
type_lookup[minetest.get_content_id(name)] = 0 -- apples
|
||||||
|
elseif def.groups.liquid then
|
||||||
|
type_lookup[minetest.get_content_id(name)] = 0 -- water, lava
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
type_lookup[minetest.get_content_id("air")] = 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bt.register_action("AreaIsFlat", {
|
||||||
|
tick = function(node, data)
|
||||||
|
if not data.targetPos then
|
||||||
|
return "failed"
|
||||||
|
end
|
||||||
|
data.targetPos = vector.floor(data.targetPos)
|
||||||
|
|
||||||
|
local mmin = vector.add(node.min, data.targetPos)
|
||||||
|
local mmax = vector.add(node.max, data.targetPos)
|
||||||
|
|
||||||
|
-- local x1 = node.max.x + data.targetPos.x
|
||||||
|
-- local y1 = node.max.y + data.targetPos.y
|
||||||
|
-- local z1 = node.max.z + data.targetPos.z
|
||||||
|
-- local x0 = node.min.x + data.targetPos.x
|
||||||
|
-- local y0 = node.min.y + data.targetPos.y
|
||||||
|
-- local z0 = node.min.z + data.targetPos.z
|
||||||
|
|
||||||
|
local vm = minetest.get_voxel_manip()
|
||||||
|
local emin, emax = vm:read_from_map(
|
||||||
|
mmin,
|
||||||
|
mmax
|
||||||
|
)
|
||||||
|
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
|
||||||
|
local data = vm:get_data()
|
||||||
|
print(dump(emin))
|
||||||
|
print(dump(emax))
|
||||||
|
|
||||||
|
local x1 = mmax.x -- node.min.x
|
||||||
|
local y1 = mmax.y -- node.min.y
|
||||||
|
local z1 = mmax.z -- node.min.z
|
||||||
|
local x0 = mmin.x
|
||||||
|
local y0 = mmin.y
|
||||||
|
local z0 = mmin.z
|
||||||
|
|
||||||
|
function ind(x, y, z)
|
||||||
|
local i = (z * area.zstride) + (y * area.ystride) + x + 1
|
||||||
|
return math.floor(i)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local deltas = {}
|
||||||
|
local last_y = (y1 + y0) / 2
|
||||||
|
local total_found = 0
|
||||||
|
local mean = 0
|
||||||
|
local total_missing = 0
|
||||||
|
-- print(x1 .. " " .. y1 .. " " ..z1 )
|
||||||
|
for z = z0, z1 do -- for each xy plane progressing northwards
|
||||||
|
for x = x0, x1 do -- for each node do
|
||||||
|
|
||||||
|
local y = math.floor(y1 / 2)
|
||||||
|
local vi = area:index(x, y, z)
|
||||||
|
|
||||||
|
|
||||||
|
local t = type_lookup[data[vi]] or 0
|
||||||
|
-- print(t .. " d:" .. data[vi].. " - x: " .. x .. ", y: " .. y .. ", z: " ..z)
|
||||||
|
|
||||||
|
local found = false
|
||||||
|
if t == 0 then -- in the air, go down
|
||||||
|
while y > y0 do
|
||||||
|
y = y - 1
|
||||||
|
vi = area:index(x, y, z)
|
||||||
|
t = type_lookup[data[vi]] or 0
|
||||||
|
-- print("too high "..y)
|
||||||
|
-- print(t .. " d:" .. data[vi].. " - x: " .. x .. ", y: " .. y .. ", z: " ..z)
|
||||||
|
|
||||||
|
|
||||||
|
if t == 1 then
|
||||||
|
-- found the ground
|
||||||
|
-- print(minetest.get_name_from_content_id(data[vi]))
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
else
|
||||||
|
-- print(minetest.get_name_from_content_id(data[vi]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
else -- underground, go up
|
||||||
|
|
||||||
|
while y < y1 do
|
||||||
|
y = y + 1
|
||||||
|
vi = area:index(x, y, z)
|
||||||
|
-- print("too low " .. y)
|
||||||
|
t = type_lookup[data[vi] ] or 0
|
||||||
|
-- print(t .. " d:" .. data[vi].. " - x: " .. x .. ", y: " .. y .. ", z: " ..z)
|
||||||
|
-- print(
|
||||||
|
if t == 0 then
|
||||||
|
-- found the sky, go back down one
|
||||||
|
y = y - 1
|
||||||
|
vi = area:index(x, y, z)
|
||||||
|
-- print(minetest.get_name_from_content_id(data[vi]))
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
else
|
||||||
|
-- print(minetest.get_name_from_content_id(data[vi]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
if found then
|
||||||
|
vi = area:index(x, y, z)
|
||||||
|
-- print("----- found " .. data[vi] .. " " ..minetest.get_name_from_content_id(data[vi]))
|
||||||
|
last_y = y
|
||||||
|
local dy = y - y0
|
||||||
|
deltas[dy] = (deltas[dy] or 0) + 1
|
||||||
|
total_found = total_found + 1
|
||||||
|
mean = mean + dy
|
||||||
|
else
|
||||||
|
total_missing = total_missing + 1
|
||||||
|
-- print("--------- missing")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print("total_found ".. total_found)
|
||||||
|
print("total_missing ".. total_missing)
|
||||||
|
print(dump(deltas))
|
||||||
|
mean = mean / total_found
|
||||||
|
|
||||||
|
local variance = 0
|
||||||
|
for k,v in pairs(deltas) do
|
||||||
|
local d = mean - k
|
||||||
|
variance = variance + (d * d)
|
||||||
|
end
|
||||||
|
|
||||||
|
variance = variance / total_found
|
||||||
|
|
||||||
|
print("variance: ".. variance)
|
||||||
|
if variance > node.max_variance then
|
||||||
|
return "failed"
|
||||||
|
end
|
||||||
|
|
||||||
|
return "success"
|
||||||
|
end,
|
||||||
|
|
||||||
|
ctor = function(min, max, max_variance)
|
||||||
|
return {
|
||||||
|
min = min,
|
||||||
|
max = max,
|
||||||
|
max_variance = max_variance,
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue