-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- function widget:GetInfo() return { name = "Export Heightmap", desc = "Usage: /luaui exportheightmap", author = "user finished it, again", date = "Feb ??, 2008", license = "GNU GPL, v2 or later", layer = -5, enabled = true -- loaded by default? } end -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- local heightMapX = (Game.mapX * 64) local heightMapY = (Game.mapY * 64) local GetGroundHeight = Spring.GetGroundHeight local le = {} local mod = math.mod local max = math.max local floor = math.floor -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- do function le.uint32(n) return string.char( mod(n,256), mod(n,65536)/256, mod(n, 16777216)/65536,n/16777216 ) end function le.uint16(n) return string.char( mod(n,256), mod(n,65536)/256 ) end function le.uint8(n) return string.char( mod(n,256) ) end end local function bmptxt(data, filename) local file = assert(io.open(filename,'w'), "Unable to save to "..filename) for row = heightMapX, 0, -1 do for col = 0, heightMapY, 1 do file:write(tostring(data[row][col] or 0)) file:write('\n') end end file:close() Spring.Echo("Created temporary file " .. filename) end local function writeTGA(data, filename) local file = assert(io.open(filename,'w'), "Unable to save to "..filename) --------------tga file header------------------------------ file:write(le.uint8(1)) -- id length file:write(le.uint8(0)) -- c map type file:write(le.uint8(3)) -- image type --/-color map specification------------------------------- file:write(le.uint16(0)) -- first entry index file:write(le.uint16(16777216)) -- color map length file:write(le.uint8(8)) --/-image specification----------------------------------- file:write(le.uint16(0)) --x-start file:write(le.uint16(0)) --y-start file:write(le.uint16(heightMapX + 1)) --image x file:write(le.uint16(heightMapY + 1)) --image y file:write(le.uint8(32)) --bits per pixel file:write(le.uint8(0)) --image descriptor -------------end tga file header--------------------------- -------------image/color map data-------------------------- file:write(le.uint8(0)) -- image id --var --/-------color map data---------------------------------- file:write(le.uint8(24)) -- c map data --/-------image data(pixels)------------------------------ for row = heightMapX, 0, -1 do for col = 0, heightMapY, 1 do file:write(le.uint16(data[row][col] or 0):rep(4)) end end ------------end image/color map data----------------------- ------------developer area--------------------------------- file:write(le.uint8(0)) -- dev fields file:write(le.uint8(0)) -- dev dir ------------end developer area----------------------------- --extension area file:write(le.uint16(0)) -- ext size 2*8 file:write("here be the author name") -- author --ascII 41 file:write("tga file format") -- coment --ascII 324 -- date/time stamp file:write(le.uint16(1)) file:write(le.uint16(0)) file:write(le.uint16(2008)) file:write(le.uint16(0)) file:write("") -- job name -- ascII file:write(le.uint16(0)) -- job time --3*16 file:write("spring engine") -- soft id -- ascII file:write(le.uint8(0.76)) -- version --3*8 file:write(le.uint32(0)) -- keycolor file:write(le.uint16(0)) -- pixel aspect ratio 2*16 file:write(le.uint16(0)) -- gamma 2*16 file:write(le.uint32(0)) -- c correction offset file:write(le.uint32(0)) -- postage stamp offset file:write(le.uint32(0)) -- scan line offset file:write(le.uint8(0)) -- attrib type file:write(le.uint8(0)) -- scan line table file:write(le.uint8(0)) -- postage stamp image file:write(le.uint8(0)) -- color correction table --1k shorts 8*1000 file:write(le.uint32(0)) -- extension area offset file:write(le.uint32(0)) -- dev dir offset file:write("TRUEVISION-XFILE") -- signature --file:write(le.uint8(8)) -- size of image data (only necessary if compressed) --file:write(le.uint8(0)) -- horizontal pixels per meter file:close() end local function writeBmp(data, filename) local file = assert(io.open(filename,'w'), "Unable to save to "..filename) --bmptxt(data,"tmp.txt") file:write("B") -- windows bitmap header file:write("M") -- windows bitmap header file:write(le.uint32(0)) -- filesize, only useful for compressed bitmaps file:write(le.uint16(0)) -- reserved1, always 0 file:write(le.uint16(0)) -- reserved2, always 0 file:write(le.uint32(54)) -- offset into file of data -- bitmap info header file:write(le.uint32(40)) -- size of bitmap info header file:write(le.uint32(heightMapX+1)) -- width (colums) file:write(le.uint32(heightMapY+1)) -- height (rows) file:write(le.uint16(0)) -- number of planes file:write(le.uint16(32)) -- bits per pixel file:write(le.uint32(0)) -- compression type file:write(le.uint32(0)) -- size of image data (only necessary if compressed) file:write(le.uint32(3100)) -- horizontal pixels per meter file:write(le.uint32(3100)) -- vertical pixels per meter file:write(le.uint32(0)) -- number of colours used file:write(le.uint32(0)) -- important colours --local temp = io.open("tmp.txt",'r') --for line in temp:lines() do -- file:write(le.uint8(line):rep(4)) --end -- bmps are upside down for row = heightMapX, 0, -1 do for col = 0, heightMapY, 1 do file:write(le.uint8(data[row][col] or 0):rep(4)) end end file:close() Spring.Echo("Exported to " .. filename) end local function writeppm(data, filename) local file = assert(io.open(filename,'w'), "Unable to save to "..filename) file:write("P2") file:write("\n") file:write("# CREATOR: heightmap_exporter.lua") file:write("\n") file:write("# i know this format is bad.") file:write("\n") file:write(heightMapX+1) file:write(" ") file:write(heightMapY+1) file:write("\n") file:write("255") file:write("\n") for row = heightMapX, 0, -1 do for col = 0, heightMapY, 1 do file:write(tostring(data[row][col] or 0).."\n") end end file:close() Spring.Echo("Exported to " .. filename) end local function writetxt(data, filename) local file = assert(io.open(filename,'w'), "Unable to save to "..filename) for row = heightMapX, 0, -1 do for col = 0, heightMapY, 1 do if (tonumber(data[row][col]) < 100)and(tonumber(data[row][col]) > 9)then data[row][col] = "0"..tostring(data[row][col]) end if (tonumber(data[row][col]) < 10)then data[row][col] = "00"..tostring(data[row][col]) end file:write(tostring(data[row][col] or 0).."-") end file:write('\n') end file:close() Spring.Echo("Exported to " .. filename) end function widget:TextCommand(command) if (string.find(command, 'exportheightmapbmp') == 1) then local minHeight, maxHeight = Spring.GetGroundExtremes() local heightDif = (maxHeight - minHeight) local imageData = {} print("min height: " .. tostring(minHeight) .. ", max height: " .. tostring(maxHeight)) -- save the image data for row = 0, heightMapY, 1 do imageData[row] = {} for col = 0, heightMapX, 1 do local pixelHeight = GetGroundHeight(col * 8, row * 8) local pixelColor = floor(((pixelHeight - minHeight) / heightDif) * 255) imageData[row][col] = pixelColor end end local filename = ("LuaUI\\Widgets\\output".. string.lower(string.gsub(Game.mapName, ".smf", "_")) .. "heightmap.bmp") writeBmp(imageData, filename) Spring.Echo("Map Height - Min: " .. floor(minHeight) .. ", Max: " .. floor(maxHeight)) elseif (string.find(command, 'exportheightmaptga') == 1) then local minHeight, maxHeight = Spring.GetGroundExtremes() local heightDif = (maxHeight - minHeight) local imageData = {} print("min height: " .. tostring(minHeight) .. ", max height: " .. tostring(maxHeight)) for row = 0, heightMapY, 1 do imageData[row] = {} for col = 0, heightMapX, 1 do local pixelHeight = GetGroundHeight(col * 8, row * 8) local pixelColor = floor(((pixelHeight - minHeight) / heightDif) * 255) imageData[row][col] = pixelColor end end local filename = ("LuaUI\\Widgets\\output".. string.lower(string.gsub(Game.mapName, ".smf", "_")) .. "heightmap.tga") writeTGA(imageData, filename) Spring.Echo("Map Height - Min: " .. floor(minHeight) .. ", Max: " .. floor(maxHeight)) end if (string.find(command, 'exportheightmaptxt') == 1) then local minHeight, maxHeight = Spring.GetGroundExtremes() local heightDif = (maxHeight - minHeight) local imageData = {} print("min height: " .. tostring(minHeight) .. ", max height: " .. tostring(maxHeight)) -- save the image data for row = 0, heightMapY, 1 do imageData[row] = {} for col = 0, heightMapX, 1 do local pixelHeight = GetGroundHeight(col * 8, row * 8) local pixelColor = floor(((pixelHeight - minHeight) / heightDif) * 255) imageData[row][col] = pixelColor end end local filename = ("LuaUI\\Widgets\\output".. string.lower(string.gsub(Game.mapName, ".smf", "_")) .. "heightmap.txt") writetxt(imageData, filename) Spring.Echo("Map Height - Min: " .. floor(minHeight) .. ", Max: " .. floor(maxHeight)) end if (string.find(command, 'exportslopemaptxt') == 1) then local imageData = {} for row = 0, heightMapY, 1 do imageData[row] = {} for col = 0, heightMapX, 1 do local sx,sy,sz = Spring.GetGroundNormal(col * 8, row * 8) local slopelevel = sx + sz slopelevel = slopelevel * 1000 slopelevel = math.floor(slopelevel) imageData[row][col] = slopelevel end end local filename = ("LuaUI\\Widgets\\output".. string.lower(string.gsub(Game.mapName, ".smf", "_")) .. "slopemap.txt") writetxt(imageData, filename) elseif (string.find(command, 'exportheightmapppm') == 1) then local minHeight, maxHeight = Spring.GetGroundExtremes() local heightDif = (maxHeight - minHeight) local imageData = {} print("min height: " .. tostring(minHeight) .. ", max height: " .. tostring(maxHeight)) -- save the image data for row = 0, heightMapY, 1 do imageData[row] = {} for col = 0, heightMapX, 1 do local pixelHeight = GetGroundHeight(col * 8, row * 8) local pixelColor = floor(((pixelHeight - minHeight) / heightDif) * 255) imageData[row][col] = pixelColor end end local filename = ("LuaUI\\Widgets\\output\\" .. string.lower(string.gsub(Game.mapName, ".smf", "_")) .. "heightmap.pgm") writeppm(imageData, filename) Spring.Echo("Map Height - Min: " .. floor(minHeight) .. ", Max: " .. floor(maxHeight)) end end -------------------------------------------------------------------------------- --------------------------------------------------------------------------------