DynamicTerrain returns incorrect map height

When using the getHeightFromMap() function on a dynamic terrain, it’s returning inaccurate heights. I’m not sure if this is a bug or something I’m doing wrong, but I had originally used a similar function on a basic height map, and it worked fine.

You can see what I mean when you move around on the following example. The camera should stay at +2 height above the terrain at all times:

https://playground.babylonjs.com/#3DT04E#7

I have played a bit with your PG, here are my findings => I think those comments are more directed to @jerome who wrote the dynamic terrain class.

PG: https://playground.babylonjs.com/#3DT04E#11

In this PG, you will see that the box does follow correctly the terrain (use only the cursor keys, don’t rotate with the mouse, else you may “unstick” the box from the terrain).

Now, uncomment line 101 and comment 102: it does not work anymore.

The difference is that in this latter case I don’t pass the mapSizeX/mapSizeZ values, so they are computed by getHeightFromMap => the computation gives 2625. However, the CreateMapFromHeightMapToRef method is called with 2640 for both values (120 * 22 = 2640), that’s why I tried to override the call by passing 2640, which seems to work.

However, even in this case, I can see some problems:

  • if you uncomment line 36 to set the starting position of the camera outside the initial 2640x2640 area, the y value is off => it follows the terrain but with a little lag (probably by 2640-2625=15 units)
  • (comment again line 36) if you comment line 43 and uncomment line 44, you will see the box is off => it seems that if the starting position of the camera is not (0,0,0) when calling the terrain constructor, the elevation computation is not ok
  • reload the PG (to have a working config). If line 35 you replace the starting position by new BABYLON.Vector3(7, 15, 32); you will see the box is too high:
    image
3 Likes

Awesome work! This definitely shows the problem much better than I was trying to. I think you’re on to something with it actually following the correct terrain, but just off by some offset it looks like.
In my game development I had noticed the map was 2625 instead of 2640, which I think is applied because the given datamap needs to seam smoothly with the repeated edge, so I think it just cuts out the last division and uses that division to seam one side of the datamap to the next. It’s 15 short because 8 (zone divisions) * 22 (zones) = 176, and 2640 (total map width) / 176 (total divisions) = 15 (division width).

So the code is maybe reading in the data correctly from the image, and creating a correct datamap, but then when that datamap is being created as a visual terrain, it’s modifying the edge to seam the edges (maybe it’s not updating the underlying datamap?), and so the entire map is skewed by some small offset visually, so when you get the height it’s probably returning the correct height given the datamap, but the terrain is showing something slightly offset.

I’m going to mess with your playground and see if I find anything else worth noting. I’ll probably also look over the differences in the code between the dynamic terrain getHeightFromMap function and the getHeightAtCoordinates function that’s used in the default Babylon heightmap ground: BABYLON.Mesh.CreateGroundFromHeightMap.The default one works perfectly.

2 Likes

I’ll check this. Thank you for the investigation :slight_smile:

3 Likes

Awesome! Thank you, my game will render with almost 600k less faces once this is working! Let me know if you make any progress and if there’s anything I can do to help!

I think I have an idea where the issue comes from (the terrain folding on some edges to make seamless textures on junctions).
I’ll have a look in the next weeks. I don’t have my computer for developping for now.

2 Likes

A simple minded solution so ignore if it will not work. A Boolean option, “isRepeating” in the CreateMapFromHeightMapToRef method that is true when using a repeating tile, in which case no need to fold just butt the data?

2 Likes

Hey Jerome, just wondering if you’ve gotten a chance to look at this yet?

Unfortunately no. I wish I have a way to spend time on my development machine, but I don’t know if this will really happen before weeks. :frowning:

1 Like

Wondering if this has been looked into?

Unfortunately no. I don’t have any time for now to code for BJS :frowning:
I hope these good times will come back soon !

1 Like

No rush @jerome, hope you are all good :slight_smile:

1 Like

I know this is years old at this point, but it seems like this is still an issue?

@thomas, it probably still is indeed. Dynamic Terrain is part of the Babylon Extensions and fully community maintained and available as sources here Extensions/DynamicTerrain/src/babylon.dynamicTerrain.ts at master · BabylonJS/Extensions · GitHub

We will happily take a PR if you can figure what the issue is ?

1 Like

Haha ok I’ll take a look once I’m done with my day job :laughing:

The problem was actually largely resolved for me by just increasing the maxSubZ substantially.

I also modified the interpolation a bit which seemed to catch a couple edge cases, but am not confident enough to PR it yet. Might later when I have more time to test.

1 Like

Awesome! Interested in seeing the full solution. I was never able to find the cause of the problem, and ended up working out a different solution. If fixed, this terrain would be a great addition!