Heightmap problems
by Bloodknight · in Torque Game Engine Advanced · 04/10/2010 (4:22 pm) · 9 replies
Is there some special tricks i need to learn to get these working correctly, every time i load a heightmap or even use L3DT to export a terrain i end up with a vertical cliff or a droppoff that shouldnt be there as if the heightmap has moved its origin point, most often its only 1 pixel out it seems, but sometimes i get lucky and the origin is the dead center of the terrain.
heres an example

another example using the specific heightmap

heres the heightmap

any idea how to fix this or if its something i'm doing wrong, or if theres specific steps to avoid it
heres an example

another example using the specific heightmap

heres the heightmap

any idea how to fix this or if its something i'm doing wrong, or if theres specific steps to avoid it
About the author
#2
04/10/2010 (9:01 pm)
Doesn't this happen because terrain object is designed to tile ... so there's some "carry over" to the other side naturally when you import a heightmap?
#3
Seems to me that theres a small bunch of possible causes.
This is all beginning to look like
1) the start coords are 1, 1 instead of 0,0 or
2) the start coords are not initialised
04/11/2010 (6:15 am)
Which would be fine, only i dont need to be limited to making small islands or seamless terrains for this particular project.Seems to me that theres a small bunch of possible causes.
This is all beginning to look like
1) the start coords are 1, 1 instead of 0,0 or
2) the start coords are not initialised
#4
I think this bug in TGEA has been discussed in the forum previously, and is not specific to L3DT terrain:
www.torquepowered.com/community/forums/viewthread/73273
This edge skirt was added, I understand, to fill the seam between adjacent tiles with tiling terrain blocks. However, even when tiling is disabled for the terrain blocks, the renderer still adds the extra column & row skirt.
I do not think this is a problem with the TER file(s). It's clear from your bitmap that the height values are OK, and there is no incorrect carry-over of pixels from edge to edge in the bitmap.
However, if you can find an example of a TER file that doesn't show this erroneous behaviour, I'd love to pull it apart and see what's different.
Best regards,
Aaron.
04/15/2010 (2:57 am)
Hi Bloodknight,I think this bug in TGEA has been discussed in the forum previously, and is not specific to L3DT terrain:
www.torquepowered.com/community/forums/viewthread/73273
This edge skirt was added, I understand, to fill the seam between adjacent tiles with tiling terrain blocks. However, even when tiling is disabled for the terrain blocks, the renderer still adds the extra column & row skirt.
I do not think this is a problem with the TER file(s). It's clear from your bitmap that the height values are OK, and there is no incorrect carry-over of pixels from edge to edge in the bitmap.
However, if you can find an example of a TER file that doesn't show this erroneous behaviour, I'd love to pull it apart and see what's different.
Best regards,
Aaron.
#5
I dont think a terrain file exists without that problem unless the heightmap is a seamless texture. I tried looking into the code for answers but it all seesm to lead me into uncommented bits of code that involve structs full of structs of vectors and matrices, made my head hurt.
If i could get at the raw data i'm sure that would be at least useful. I'm betting its a prime example of where an array is being used from a (1, 1) index rather than a (0, 0) index and just wrapping around, probably at the point the terrain written from the bitmap but equally it could be at the point of rendering the terrain.
If L3DT uses its own bitmap --> .ter functions rather than using the torque functions, then chances are its when the .ter is loaded.
Another thing that would be interesting to know is if this is a carry over from TGE, i cant run TGE at the moment since it hard locks my win 7 machine. If TGE doesnt have this problem then its possible we could track the bug down
04/15/2010 (7:11 am)
I'm sure i did see a thread a while back but searches turned up nothing useful, and i wasnt in any way blaming L3DT i was just pointing out that l3dt export and manual heightmap loading have the same results.I dont think a terrain file exists without that problem unless the heightmap is a seamless texture. I tried looking into the code for answers but it all seesm to lead me into uncommented bits of code that involve structs full of structs of vectors and matrices, made my head hurt.
If i could get at the raw data i'm sure that would be at least useful. I'm betting its a prime example of where an array is being used from a (1, 1) index rather than a (0, 0) index and just wrapping around, probably at the point the terrain written from the bitmap but equally it could be at the point of rendering the terrain.
If L3DT uses its own bitmap --> .ter functions rather than using the torque functions, then chances are its when the .ter is loaded.
Another thing that would be interesting to know is if this is a carry over from TGE, i cant run TGE at the moment since it hard locks my win 7 machine. If TGE doesnt have this problem then its possible we could track the bug down
#6
The code for loading the TER file in TGEA is in the terrData.cpp file, on or around line 1997:
That looks just fine to me; there's certainty no array indexing problem.
As stated in the other thread, the 'geometry wrap' is a deliberate feature, not some sort of array indexing bug. It appears to be added in the 'getHeight' function in the 'terrData.h' file, starting on line 432:
Note the checks where the pixels with x or y values of exactly BlockSize (that is, one pixel off the edge of the map) are set to the values at x or y of 0. There's your problem.
To remove the skirt, you could change this to:
(so as to change the minimum amount of code, this keeps the skirt, but uses the height values of the immediate neighbour pixels, so it won't be noticeable.)
> Another thing that would be interesting to know is if this is a carry
> over from TGE
Yes indeed. I can confirm that, this very morning, TGE 1.5.2 showed the same behaviour. In fairness to TGE, I think it was designed to only work with tiled terrain. Consequently, under that constraint, the 1px wide skirt would always be smooth and unnoticeable. By loading non-tiled terrain in TGE, one breaks that constraint, and hence the skirt looks very out of place because the edges don't match up.
> If L3DT uses its own bitmap --> .ter functions rather than using the
> torque functions...
L3DT shares no common code with Torque, as far as I know.
Cheerio,
Aaron.
04/15/2010 (3:39 pm)
Hi Bloodknight,The code for loading the TER file in TGEA is in the terrData.cpp file, on or around line 1997:
// read the HeightField
for (S32 i=0; i < (TerrainBlock::BlockSize * TerrainBlock::BlockSize); i++)
stream.read(&ret->mHeightMap[i]);That looks just fine to me; there's certainty no array indexing problem.
As stated in the other thread, the 'geometry wrap' is a deliberate feature, not some sort of array indexing bug. It appears to be added in the 'getHeight' function in the 'terrData.h' file, starting on line 432:
inline U16 getHeight(U32 x, U32 y) const {
if ((x == TerrainBlock::BlockSize) && mEdgeTerrainFiles[0] != NULL)
return mEdgeTerrainFiles[0]->getHeight(0,y);
if ((y == TerrainBlock::BlockSize) && mEdgeTerrainFiles[1] != NULL)
return mEdgeTerrainFiles[1]->getHeight(x,0);
return mHeightMap[(x & TerrainBlock::BlockMask) + ((y & TerrainBlock::BlockMask) << TerrainBlock::BlockShift)];
}Note the checks where the pixels with x or y values of exactly BlockSize (that is, one pixel off the edge of the map) are set to the values at x or y of 0. There's your problem.
To remove the skirt, you could change this to:
inline U16 getHeight(U32 x, U32 y) const {
if ((x == TerrainBlock::BlockSize) && mEdgeTerrainFiles[0] != NULL)
return mEdgeTerrainFiles[0]->getHeight(TerrainBlock::BlockSize-1,y);
if ((y == TerrainBlock::BlockSize) && mEdgeTerrainFiles[1] != NULL)
return mEdgeTerrainFiles[1]->getHeight(x,TerrainBlock::BlockSize-1);
return mHeightMap[(x & TerrainBlock::BlockMask) + ((y & TerrainBlock::BlockMask) << TerrainBlock::BlockShift)];
}(so as to change the minimum amount of code, this keeps the skirt, but uses the height values of the immediate neighbour pixels, so it won't be noticeable.)
> Another thing that would be interesting to know is if this is a carry
> over from TGE
Yes indeed. I can confirm that, this very morning, TGE 1.5.2 showed the same behaviour. In fairness to TGE, I think it was designed to only work with tiled terrain. Consequently, under that constraint, the 1px wide skirt would always be smooth and unnoticeable. By loading non-tiled terrain in TGE, one breaks that constraint, and hence the skirt looks very out of place because the edges don't match up.
> If L3DT uses its own bitmap --> .ter functions rather than using the
> torque functions...
L3DT shares no common code with Torque, as far as I know.
Cheerio,
Aaron.
#7
seems the only real solution is to hand craft all terrain heightmaps to be seemless or spend hours hand editing the screwups
04/16/2010 (12:29 pm)
I'm pretty much giving up on this, your code changes are seemingly unreachable, i cant find any solutions and unless its an iphone problems or an xbox problem then the new management dont seem to care.seems the only real solution is to hand craft all terrain heightmaps to be seemless or spend hours hand editing the screwups
#8
Okay, if re-compiling TGEA with the above changes is not an option for you, I'd recommend you use the 'Edge wrapping' option in L3DT to ensure that the east/west and north/south borders of your map join seamlessly. This option is in the 'heightfield size' wizard, when you first generate your terrain map (see userguide). This should save you hours of manually editing edges.
Cheerio,
Aaron.
04/16/2010 (6:36 pm)
Hi Bloodknight,Okay, if re-compiling TGEA with the above changes is not an option for you, I'd recommend you use the 'Edge wrapping' option in L3DT to ensure that the east/west and north/south borders of your map join seamlessly. This option is in the 'heightfield size' wizard, when you first generate your terrain map (see userguide). This should save you hours of manually editing edges.
Cheerio,
Aaron.
#9
While its a relatively easy fix for most maps, this particular map calls for the mountains in one set of corners and open water in the other corners, which sadly just exacerbates the problem on this map in particular, other maps arent an issue, but the sheer massiveness of the difference between the two edges make it so.
I'll come back to this problem later on, not like i dont have a dozen or so other sub projects to work on at this point, so i can easy take a break without taking a break :)
04/16/2010 (8:12 pm)
no recompiling is fine, and not only that ive stuck watches and breakpoints all through that function, the problem is that those 2 if conditions are never triggered, not when i load a mission, nor when i load a bitmap to create a terrain block, and ive no idea why, ive litterally spent hours looking at, recompiling and stepping through the code.While its a relatively easy fix for most maps, this particular map calls for the mountains in one set of corners and open water in the other corners, which sadly just exacerbates the problem on this map in particular, other maps arent an issue, but the sheer massiveness of the difference between the two edges make it so.
I'll come back to this problem later on, not like i dont have a dozen or so other sub projects to work on at this point, so i can easy take a break without taking a break :)
Torque 3D Owner Bloodknight
Bloodknight Studios
Ive been hunting in the scripts and code but i'm clearly lost in here