Page 1 of 1

Heightmap Exporter Widget (currently buggy)

Posted: 09 Aug 2007, 22:44
by TheFatController
I'm developing a widget to export heightmaps from maps with a lua command for science and fun, however currently it has a strange bug that I can only attribute to Spring's GetGroundHeight command.

http://pw3n.net/export_heightmap.lua

Here's some sample output (converted to jpeg for bandwidth):

Image
Duck

Altored Divide (linked for size)

Image
Metalheck

Tropical (linked for size)

Some maps work fine like closecombat and stratos, others go totally wrong like Tropical and some get half way like altored...

I am at a loss to what else the problem could be if not GetGroundHeight, I've tested the bitmap writing code with horizontal lines, vertical lines and chessboard pixels and none of them are distorted.

Anyone got any ideas on how to fix it? :)

Posted: 10 Aug 2007, 00:53
by Kloot
Fixed it up for you (you had swapped the bitmap dimensions in the header):

Code: Select all

...

local function writeBmp(data, filename)
	local file = assert(io.open(filename,'w'), "Unable to save to "..filename)
	-- bitmap file header
	file:write("BM") -- 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(1)) -- 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(0)) -- horizontal pixels per meter
	file:write(le.uint32(0)) -- vertical pixels per meter
	file:write(le.uint32(0)) -- number of colours used
	file:write(le.uint32(0)) -- important colours

	-- bmps are upside down
	for row = heightMapY, 0, -1 do
		for col = 0, heightMapX, 1 do
			file:write(le.uint8(data[row][col] or 0):rep(4))
		end
	end

	file:close()
	Spring.Echo("Exported to " .. filename)
end


function widget:TextCommand(command)
	if (string.find(command, 'exportheightmap') == 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 = ("screenshots\\" .. string.lower(string.gsub(Game.mapName, ".smf", "_")) .. "heightmap.bmp")

		writeBmp(imageData, filename)
		Spring.Echo("Map Height - Min: " .. floor(minHeight) .. ", Max: " .. floor(maxHeight))

	end
end
This saves each individual row in left to right order and the rows themselves from top to bottom, then inverts them vertically on write-out.

Posted: 10 Aug 2007, 02:33
by Neddie
I hope that isn't the way those heightmaps really look, because that's damn sloppy work...

Posted: 15 Aug 2007, 09:34
by Argh
So, like... I can install this as a widget in my mod, and then use it to, oh, I dunno... maybe take some of the maps that I like for gameplay, but hate the painting... and fix 'em? Hmm...

Posted: 15 Aug 2007, 10:59
by imbaczek
Better ask revenge how he did SSB dry.

Posted: 15 Aug 2007, 16:01
by Forboding Angel
SMFED is how he did SSB dry. It takes all of 3 seconds to change the height. No recompiling or anything. I also find it funny that he claims to have used a hex editor. For what? Changing the map name? Everyone knows that if you leave the smt with the same filename, then just change the smf and smd to whatever you want, the name of the map gets changed...


However, I digress.

Posted: 15 Aug 2007, 20:33
by imbaczek

Posted: 15 Aug 2007, 20:40
by Neddie
Argh wrote:So, like... I can install this as a widget in my mod, and then use it to, oh, I dunno... maybe take some of the maps that I like for gameplay, but hate the painting... and fix 'em? Hmm...
You mean, be a pretentious and presumptuous sleaze-ball and steal part of the work of another while simultaneously insulting the whole of the piece?

Yes. Yes you could. I would suggest just asking for permission and the source files.

Posted: 15 Aug 2007, 20:54
by Dragon45
On an unrelated note, remember that widget made a while back to dynamically change waterheight ingame?

Couldnt you just use that and link it to the lobby (not so simple, but w/e) to make "Dry" maps?

Posted: 15 Aug 2007, 21:15
by Argh
You mean, be a pretentious and presumptuous sleaze-ball and steal part of the work of another while simultaneously insulting the whole of the piece?


I have permission to fix the map I had in mind, actually. The original author doesn't have the heightmap or anything, which is why this came up in the first place- I don't want to mess with the heightmap, I just want to reskin it.

I should say, though, that the idea of re-doing, say, SpeedMetal, so that it doesn't look like crap, has occurred to me, yes ;)

Posted: 16 Aug 2007, 03:50
by hunterw
Dragon45 wrote:On an unrelated note, remember that widget made a while back to dynamically change waterheight ingame?

Couldnt you just use that and link it to the lobby (not so simple, but w/e) to make "Dry" maps?
its called smfed, just look at the negative number for the low value and add double that to each.

Posted: 16 Aug 2007, 07:05
by REVENGE
Err yeah, all we really need to do is fix up this piece of win, which currently doesn't do the feature map and minimap / other stuff. The thing is, it correctly locates the headers for each different section within the SMF file, but doesn't dump each section as muzzybear hasn't included that in the script. I could probably figure out how to add it easily enough by looking at mapconv's source. This is part of how I replaced the minimap in SSB v2 with the one from SSB v1.

So we don't need some lua mess that reads height values and creates a new map. The original heightmap is in raw format stored in the smf without compression or encryption. The last thing needed is something to convert the raws to something workable. Muzzy started a script for that too, and he uses a free image library that, unfortunately, doesn't handle raw data beyond 16bits. So I'm working on that right now. :P

Posted: 16 Aug 2007, 07:10
by REVENGE
Forboding Angel wrote:SMFED is how he did SSB dry. It takes all of 3 seconds to change the height. No recompiling or anything. I also find it funny that he claims to have used a hex editor. For what? Changing the map name? Everyone knows that if you leave the smt with the same filename, then just change the smf and smd to whatever you want, the name of the map gets changed...


However, I digress.
You're quite correct regarding smfed. However, as I wanted to rename the smt as well [don't ask why], I was forced to hex edit and discovered some more intracacies about the smf format itself. For instance, instead of just a text string referring to the filename of the smt texture, a few hex codes coming from the smt file are also stored in the smf file, presumably as an identifier or a pointer of some sort.

In addition, changing the length of the text string also changed the size of the smf file itself. This caused the rest of the file to fail when read by the Spring engine, and I discovered that there are additional hex codes at the beginning of the file that refer to the location of the rest of the map data [feature data specifically im guessing] later on in the file. Those have to be updated accordingly to make sure the file is read correctly.

Finally, because the minimap in SSB v2 has water on it, and I wanted a minimap reflecting dry terrain, I decided to use NOiZE's SSB v1 minimap, where he did not include the water in the picture. Since minimap size is fixed, all I had to do was to find the chunk of raw data that was the minimap, then swap it out using the hex editor.

Posted: 16 Aug 2007, 07:16
by REVENGE
Argh wrote:
You mean, be a pretentious and presumptuous sleaze-ball and steal part of the work of another while simultaneously insulting the whole of the piece?


I have permission to fix the map I had in mind, actually. The original author doesn't have the heightmap or anything, which is why this came up in the first place- I don't want to mess with the heightmap, I just want to reskin it.

I should say, though, that the idea of re-doing, say, SpeedMetal, so that it doesn't look like crap, has occurred to me, yes ;)
As for redoing SpeedMetal, I'm gonna have a go at it as well. :P I like the heightmap of the Speed Water map, with the ramps going down to either side of the center bridge. That plus some features and some textures, would make a nice Speed Metal Advanced. :D

Posted: 16 Aug 2007, 09:19
by Tobi
This may be useful instead of messing with the hex :-)
http://www.osrts.info/~buildbot/spring/ ... le_8h.html

Posted: 16 Aug 2007, 11:05
by REVENGE
Tobi wrote:This may be useful instead of messing with the hex :-)
http://www.osrts.info/~buildbot/spring/ ... le_8h.html
ZOMG

Tobi = God.

Re: Heightmap Exporter Widget (currently buggy)

Posted: 21 Feb 2009, 19:57
by kb18951452
I'm trying to get the heightmap as a greyscale bmp/jpg/anything raster to feed into my CNC machine and make a coffee table.

Re: Heightmap Exporter Widget (currently buggy)

Posted: 22 Feb 2009, 16:32
by Hoi
Maybe this can help you:

http://www.planet-wars.eu/heightmaps/

there are some hightmaps in there, I hope the one you need is in there too.

Re: Heightmap Exporter Widget (currently buggy)

Posted: 22 Feb 2009, 17:54
by TheFatController
Or just request the one you want and maybe someone will post a png for you