dead ends

This commit is contained in:
Bob Omb 2015-12-04 20:21:34 -08:00
parent 2470966032
commit 2a592e57a0
2 changed files with 112 additions and 85 deletions

189
init.lua
View File

@ -2,7 +2,7 @@ PROCESSOR = "magick" -- options are: "py", "gm", "magick", "imlib2", "pngLua"
--gm does not work and requires graphicksmagick, py is buggy and requires lunatic-python to be built, and the PIL,
--imlib2 treats 16-bit as 8-bit and requires imlib2, magick requires magick wand
--convert uses commandline imagemagick "convert" or graphicsmagick "gm convert" ("convert.exe" or "gm.exe convert")
--png loads the entire image into memory so has size limitations based on your resources, but needs no libs
--png locks up and does not work...
MODPATH = minetest.get_modpath("realterrain")
WORLDPATH = minetest.get_worldpath()
RASTERS = MODPATH .. "/rasters/"
@ -38,7 +38,7 @@ elseif PROCESSOR == "gm" then
elseif PROCESSOR == "convert" then
convert = "convert" -- could also be convert.exe, "gm convert" or "gm.exe convert"
elseif PROCESSOR == "png" then
package.path = (MODPATH.."/lib/pngLua/?.lua;"..MOPATH.."/lib/pngLua/?/init.lua;"..package.path)
package.path = (MODPATH.."/lib/pngLua/?.lua;"..MODPATH.."/lib/pngLua/?/init.lua;"..package.path)
ie.require "png"
end
local realterrain = {}
@ -572,7 +572,31 @@ function realterrain.init()
for k,rastername in next, rasternames do
if realterrain.settings["file"..rastername] ~= "" then
if py then
if PROCESSOR == "png" then
local function get_png(filename)
local ok, r = pcall(pngImage, filename)
if not ok then return nil, r end -- NOTE: r == error message
return r
end
local img, e = get_png(RASTERS..realterrain.settings["file"..rastername]) --@todo locks up, no error!
if not img then
print(e)
return nil, e
end
--check if the image is a png and if so load it
realterrain[rastername].image = img
img = nil
if realterrain[rastername].image then
realterrain[rastername].width = realterrain[rastername].image.width
realterrain[rastername].length = realterrain[rastername].image.height
else
print("your "..rastername.." file is missing or is not a PNG (should be: "..realterrain.settings["file"..rastername].."), maybe delete or edit world/realterrain_settings")
realterrain[rastername] = {}
end
elseif py then
py.execute(rastername.." = Image.open('"..RASTERS..realterrain.settings["file"..rastername] .."')")
py.execute(rastername.."_w, "..rastername.."_l = "..rastername..".size")
realterrain[rastername].width = tonumber(tostring(py.eval(rastername.."_w")))
@ -586,6 +610,7 @@ function realterrain.init()
py.execute(rastername.." = "..rastername..".convert('L')")
realterrain[rastername].mode = "L"
end
py.execute(rastername.."_pixels = "..rastername..".load()")
else
realterrain[rastername].image = imageload(RASTERS..realterrain.settings["file"..rastername])
if realterrain[rastername].image then
@ -710,7 +735,7 @@ function realterrain.generate(minp, maxp)
local heightmap = {}
local entries = 0
local input_present = false
if gm then
if gm then --@todo this isn't working but would be the only way to use gm (magick will also work once gm does)
heightmap = realterrain.build_heightmap(xstart,xend,zstart,zend, get_cover, get_input) --experiment
else
for z=zstart,zend do
@ -1095,36 +1120,24 @@ function realterrain.get_raw_pixel(x,z, rastername) -- "rastername" is a string
if ( x >= 0 and x < realterrain[rastername].width )
and ( z >= 0 and z < realterrain[rastername].length ) then
--print(rastername..": x "..x..", z "..z)
if py then
if png then
local pixel = img.scanLines[y].pixels[x]
r=pixel.R
g=pixel.G
b=pixel.B
elseif py then
if realterrain[rastername].mode == "RGB" then
py.execute(rastername.."_r, "..rastername.."_g,"..rastername.."_b = "..rastername..".getpixel(("..x..", "..z.."))")
py.execute(rastername.."_r, "..rastername.."_g,"..rastername.."_b = "..rastername.."_pixels["..x..", "..z.."]")
r = tonumber(tostring(py.eval(rastername.."_r")))
g = tonumber(tostring(py.eval(rastername.."_g")))
b = tonumber(tostring(py.eval(rastername.."_b")))
else
r = tonumber(tostring(py.eval(rastername..".getpixel(("..x..","..z.."))"))) --no bit depth conversion required
r = tonumber(tostring(py.eval(rastername.."_pixels["..x..","..z.."]"))) --no bit depth conversion required
end
--print(r)
else
if realterrain[rastername].image then
if gm then --this method is unusably slow until direct pixel access is exposed in gm!
--[[
line = realterrain[rastername].image:clone():crop(1,1,x,z):format("txt"):toString()
--print(line)
--parse the output pixels
--local firstcomma = string.find(line, ",")
--local right = tonumber(string.sub(line, 1 , firstcomma - 1)) + 1
--print("right: "..right)
local firstcolon = string.find(line, ":")
--local down = (tonumber(string.sub(line, firstcomma + 1 , firstcolon - 1)) + 1 ) * (-1)
--print("down: "..down)
local secondcomma = string.find(line, ",", firstcolon)
r = string.sub(line, firstcolon + 3, secondcomma -1)
--print(r)
r = tonumber(r)
--print(r)
--]]
elseif magick then
if magick then
r,g,b = realterrain[rastername].image:get_pixel(x, z) --@todo change when magick autodetects bit depth
r = math.floor(r * (2^realterrain[rastername].bits))
g = math.floor(g * (2^realterrain[rastername].bits))
@ -1203,25 +1216,18 @@ function realterrain.parse_enumeration(line)
end
function realterrain.get_enumeration(rastername, xstart, width, zstart, length) --raster is a string so py can use it
local enumeration
if py then
enumeration = py.eval(rastername..".getpixels(("..x..","..z.."))")
print(enumeration)
--v = tonumber(tostring(v))
else
if gm then
enumeration = realterrain[rastername].image:clone():crop(width,length,xstart,zstart):format("txt"):toString()
elseif magick then
local tmpimg
tmpimg = realterrain[rastername].image:clone()
tmpimg:crop(width,length,xstart,zstart)
tmpimg:set_format("txt")
enumeration = tmpimg:get_blob()
tmpimg:destroy()
elseif imlib2 then
--no method for this in imlib2
end
if gm then
enumeration = realterrain[rastername].image:clone():crop(width,length,xstart,zstart):format("txt"):toString()
elseif magick then
local tmpimg
tmpimg = realterrain[rastername].image:clone()
tmpimg:crop(width,length,xstart,zstart)
tmpimg:set_format("txt")
enumeration = tmpimg:get_blob()
tmpimg:destroy()
end
--local cmd = convert..' "'..RASTERS..realterrain.settings.fileelev..'"'..' -crop 80x80+'..col..'+'..row..' txt:-'
return enumeration
end
@ -1245,51 +1251,72 @@ function realterrain.build_heightmap(xstart, xend, zstart, zend, get_cover, get_
if mode.get_input3 then table.insert(rasternames, "input3") end
for k,rastername in next, rasternames do
local enumeration = realterrain.get_enumeration(rastername, xstart, width, zstart, length)
--print("entire enumeration: "..enumeration)
local entries = 0
local mincol, maxcol, minrow, maxrow
local firstline = true
for k,line in next, string.split(enumeration, "\n") do
if magick and firstline then
firstline = false --first line is a head in IM but not GM
else
entries = entries + 1
--print(entries .." :: " .. v)
local value, right, down = realterrain.parse_enumeration(line)
--print("elev: "..e)
value = math.floor((value / tonumber(realterrain.settings.yscale)) + tonumber(realterrain.settings.yoffset))
local x = xstart + right -1
local z = 0- zstart + down
if not mincol then
mincol = x
maxcol = x
minrow = z
maxrow = z
else
if x < mincol then mincol = x end
if x > maxcol then maxcol = x end
if z < minrow then minrow = z end
if z > maxrow then maxrow = z end
end--]]
--print ("x: "..x..", z: "..z..", elev: "..value)
if py then
--py.execute(rastername.."_pixels = "..rastername..".load()")
for z = zstart, zend, 1 do
if not pixels[z] then pixels[z] = {} end
pixels[z][x] = {rastername=value}
if z >= 0 and z <= realterrain[rastername].length then
for x = xstart, xend, 1 do
if x >= 0 and x <= realterrain[rastername].width then
print("x: "..x..", z: "..z)
py.execute("pixel = "..rastername.."_pixels["..x..","..z.."]")
local pixel = tonumber(tostring(py.eval("pixel"))) --@todo pixel is not defined!
print(pixel)
if not pixels[z][x] then pixels[z][x] = {} end
pixels[z][x][rastername] = pixel
end
end
end
end
end
local enumeration
if gm or magick then
enumeration = realterrain.get_enumeration(rastername, xstart, width, zstart, length)
--print("entire enumeration: "..enumeration)
local entries = 0
local mincol, maxcol, minrow, maxrow
local firstline = true
for k,line in next, string.split(enumeration, "\n") do
if magick and firstline then
firstline = false --first line is a head in IM but not GM
else
entries = entries + 1
--print(entries .." :: " .. v)
local value, right, down = realterrain.parse_enumeration(line)
--print("elev: "..e)
value = math.floor((value / tonumber(realterrain.settings.yscale)) + tonumber(realterrain.settings.yoffset))
local x = xstart + right -1
local z = 0- zstart + down
if not mincol then
mincol = x
maxcol = x
minrow = z
maxrow = z
else
if x < mincol then mincol = x end
if x > maxcol then maxcol = x end
if z < minrow then minrow = z end
if z > maxrow then maxrow = z end
end--]]
--print ("x: "..x..", z: "..z..", elev: "..value)
if not pixels[z] then pixels[z] = {} end
pixels[z][x] = {rastername=value}
end
end
print("result range: x:"..mincol..","..maxcol.."; z:"..minrow..","..maxrow)
print("result entries: "..entries)
end
print("result range: x:"..mincol..","..maxcol.."; z:"..minrow..","..maxrow)
print("result entries: "..entries)
end
return pixels
end--]]
end
--this funcion gets the hieght needed to fill below a node for surface-only modes
function realterrain.fill_below(x,z,heightmap)

View File

@ -133,8 +133,8 @@ ScanLine.pixels = {}
ScanLine.filterType = 0
function ScanLine:__init(stream, depth, colorType, palette, length)
bpp = math.floor(depth/8) * self:bitFromColorType(colorType)
bpl = bpp*length
local bpp = math.floor(depth/8) * self:bitFromColorType(colorType)
local bpl = bpp*length
self.filterType = stream:readByte()
stream:seek(-1)
stream:writeByte(0)
@ -248,7 +248,7 @@ function pngImage:__init(path, progCallback)
local idat = {}
local num = 1
while true do
ch = Chunk(str)
local ch = Chunk(str)
if ch.name == "IHDR" then ihdr = IHDR(ch) end
if ch.name == "PLTE" then plte = PLTE(ch) end
if ch.name == "IDAT" then idat[num] = IDAT(ch) num = num+1 end
@ -263,7 +263,7 @@ function pngImage:__init(path, progCallback)
for k,v in pairs(idat) do dataStr = dataStr .. v.data end
local output = {}
deflate.inflate_zlib {input = dataStr, output = function(byte) output[#output+1] = string.char(byte) end, disable_crc = true}
imStr = Stream({input = table.concat(output)})
local imStr = Stream({input = table.concat(output)})
for i = 1, self.height do
self.scanLines[i] = ScanLine(imStr, self.depth, self.colorType, plte, self.width)