I am creating a heightmap analysis tool as a hobby programming project and I have hit a problem I can't immediately work out. I was hoping that someone in this forum could help me.
I have used the helicopters in PR to figure out the altitude of certain points on a couple of PR maps, but I can't figure out how those heights translate to those in the heightmap files (or rather from heightmap to in-game altitude).
I know how heightmaps are stored and know the idea of "white = highest, black = lowest on the map".
In the corresponding Heightdata.con file for the level there is a line:
0.0025 is the height scale yes, though i dont belive anyone has get behind the doors of the secret how its calculated, only thing you can do is have a look into the editor where you type in a special height value and that gets calculated to the scale
I remember that a german PR player made a mortar calc tool which used the heightmap to get the height values of the map. You may want to look how he has done it.
WeeD-KilleR wrote:I remember that a german PR player made a mortar calc tool which used the heightmap to get the height values of the map. You may want to look how he has done it.
That's how he calculates the height. the heightscale is set for each map like this:
if (gettitle == "2km_2albasrah") { heightscale = 0.0025; }
if (gettitle == "1km_1asad_khal") { heightscale = 0.0025; }
if (gettitle == "4km_burning_sands") { heightscale = 0.000915527; }
[...]
He uses the heightmap all the time to calulate the rounds for the mortar. If I understood it right he uses the build-in function getPixel() to get the value of the postition and multiplies it with the heightscale.
I hope it helped you.
EDIT2:
Another edit, getPixel(x1,y1) returns a 4-5 ditgit number, multiplied by the scale it returns reasonable values.
Last edited by WeeD-KilleR on 2012-07-07 19:18, edited 3 times in total.
WeeD-KilleR wrote:Well, let me take a look into the files. I guess it should be possible to find the code he used.
Found it, here we go:
That's how he calculates the height. the heightscale is set for each map like this:
He uses the heightmap all the time to calulate the rounds for the mortar. If I understood it right he uses the build-in function getPixel() to get the value of the postition and multiplies it with the heightscale.
I hope it helped you.
EDIT2:
Another edit, getPixel(x1,y1) returns a 4-5 ditgit number, multiplied by the scale it returns reasonable values.
It did but in an indirect way, I did have a look at his code and I went back to my own code. I think my troubles stem from the conversion I do between the .raw format and the displayable image I create. The code snippet I am using at the moment seems (if I understand it correctly) to only take every odd 8 bits and use those, which is why I get so very small numbers when I multiply with the height scale, which is a very small number.
I will update the thread if I make progress tomorrow. As for now, thank you for your help! It made me go back and check my code.
Feel free to contribute further (everyone). Information is still appreciated!
Its really pretty simple when you break the system down to its basics.
How a heightmap works is that 100% black, aka, 0% white = 0m height on every single map in BF2. However ingame the altitude is done off the "sea" water level (aka, terrain water level), which might actually be set to something like 15m high above the heightmaps bottom point, as otherwise you wouldn't have any sea bed. This also note is the reason why on the Falklands why when you jump in a jet, it says your altitude is 10,000m when your actually at sea level, which is because the Falklands can't use the normal terrain water most maps have, so instead its terrain water is 10km underground, with a waterplane being the water you see and also why it doesn't look like water for low gfx users.
100% white on the heightmap = the maps coded max terrain height. I can't remember what the default value in meters is, that most maps uses but to find out that you need to open a map up with the BF2 editor and then look in the map's level settings to what it is then you can translate that to the y scale in what you have quoted above.
One thing to keep in mind however is that many maps do not actually use the heightmap to its full potential. While most maps do go down to 100% black, other than really deserts without any water, most maps do not go up to 100% white, with there highest peak being something around 95% white, or some not going anything much above 60% white (which isn't very good mapping btw in that case as your not using the heightmap to its full potential of accuracy and decreasing terrain warping by as much as possible).
So the only thing you really need to find is what the altitude is on each map, with the default being iirc something around 164.something meters high but to find out the real value, the only way is the editor.
Once you've found it, its a simple process of working out the height by simply finding out what % of white that part of the heightmap is, then applying that % to the max height value. So for example if a map has a 250m max height setting, and the point on the heightmap you want to know the height to is 72% white, then its simply 72% of 250m which is 180m. Another point on the heightmap of the same example map might be 19% white, which in that case its height would be 47.5m high.
Hope that clears it up.
EDIT: quickly loaded up a map with the default height value in the editor since I had it running and the default value is 163.84m
And yes its heightmap scale is "heightmap.setScale 2/0.0025/2", so 0.0025 = 163.84m
Last edited by Rhino on 2012-07-08 19:31, edited 4 times in total.
you have to get the int value of each pixel and multiple it with the heightscale, that gives you the ingame height. the data is stored in 16bit grayscale afaik, so it ranges from 0 (black) to 65536 (white).
how you read that data depends on you, but if you read it directly from the .raw you have to consider that 1. the heightmap is flipped, 2. the heightmap is 1pixel bigger than the minimap (e.g. heightmap 1025x1025 and minimap 1024x1024), 3. the heightmaps are not always same size they are either 513x513 or 1025x1025, you can take those numbers from heightdata.con.
thats all i know about it, hope it helps.
[R-DEV]Rhino wrote:Its really pretty simple when you break the system down to its basics.
I want to thank you very much for taking your time to write this post. I can guess and prod at the files available to me, but having someone with experience helping, well that's just a whole other (much better) experience! I could read your posts about the BF2 engine for days
It's late, so I won't have time to try the new information out but I think I might have understood it now. I can read the value from the Heightdata.con file, multiply the scale value with 65536 and get the actual ingame value (if I understand it correctly in my tired state).
Mats391 wrote:you have to get the int value of each pixel and multiple it with the heightscale, that gives you the ingame height. the data is stored in 16bit grayscale afaik, so it ranges from 0 (black) to 65536 (white).
how you read that data depends on you, but if you read it directly from the .raw you have to consider that 1. the heightmap is flipped, 2. the heightmap is 1pixel bigger than the minimap (e.g. heightmap 1025x1025 and minimap 1024x1024), 3. the heightmaps are not always same size they are either 513x513 or 1025x1025, you can take those numbers from heightdata.con.
thats all i know about it, hope it helps.
Thank you for taking the time to write in the thread.
I had already figured out that the heightmap is flipped since I successfully opened the raw file in photoshop and couldn't overlay a map of the level at first. It being 1025 (or 513 etc.) I read somewhere else before getting too far ahead of myself.
I had not considered that the heightmaps might not be the same size but I already have a simple solution in the works for that.
I really like that more people are chipping in with information, I felt at rock bottom when I started out, but things are beginning to make sense.
Programming is what is hindering me a bit, since getting the 16-bit value out without it turning into characters is seemingly a task I have not yet become completely dominant over.