Open delebash opened 1 year ago
It looks like vmapSize
refers to the size of the 9x9 grid in the coordinate reference frame of the map (or WGS84, if that is what Turf.js is using), so 18.144km. I think they are using this value as part of a scaling operation (the 1.05 you refer to in the video) to conform to the cities skyline map size of 17.28km, but it's hard to say. It seems that since the website defaults to a grid that matches gameply in Cities Skylines (and why 1080/1081 is used), this adjustment is a convenience that avoids some issue with just creating a grid based on 17.28km. Perhaps the pixel dimensions using vmapSize
are more convenient to work with.
The bitwise operations seem to be storing the 16bit height value into two 8bit channels, allowing the Cities Skyline engine to represent a greater range of height values within the limitations of the engine. I don't think this applies to Unreal Engine, or Unreal Engine handles that conversion itself on import. Again, I don't know for sure. You should try and remove that step at some point.
It seems what you'd like to do is select multiple tiles (or use a drawn rectangle) and download encompassed tiles from a certain zoom level (i.e. resolution) that gives the detail you want for your area. An easy example for what I mean would be selecting the single tile at zoom 0, choosing zoom 1 as your resolution, and getting back the four tiles that exist for the world at zoom 1.
Working on this easy example, here is a function that returns all tile URLs from Mapbox at a specified zoom level that are encompassed by a lower-zoom-level tile (not tested):
function getEncompassedTiles(tileInfo, delta) {
const encompassedTiles = [];
const zoomLevel = tileInfo.z + delta;
for (let x = tileInfo.x * Math.pow(2, delta); x < (tileInfo.x + 1) * Math.pow(2, delta); x++) {
for (let y = tileInfo.y * Math.pow(2, delta); y < (tileInfo.y + 1) * Math.pow(2, delta); y++) {
const tileURL = `https://api.mapbox.com/v4/mapbox.terrain-rgb/${zoomLevel}/${x}/${y}@2x.pngraw?access_token=${mapboxgl.accessToken}`;
encompassedTiles.push(tileURL);
}
}
return encompassedTiles;
}
You could replace the "click tile and download that tile" logic in your project with "click tile and download all encompassed tiles for your desired zoom level". You would want to limit the allowed delta between the encompassing tile's zoom level and the desired resolution zoom tile of course, I would stick to 2 in difference between the encompassing tile's zoom level and the desired zoom level. That would return 16 URLs for a total heightmap size of 8192 x 8192.
You then need to stitch these tiles together into a single heightmap. In my easy example above, the stiched 4-tile heightmap would be of size 1024x1024 (terrain-rgb tiles from my library are downloaded at 512x512). They seem to have the logic for that in the Cities-Skylines-heightmap-generator project, but the scaling and other Cities Skyline-specific stuff needs to be removed.
Also, the bilinear interpolation they are doing is probably to smooth out the height maps. The terrain-rgb tiles have integer height map values instead of floats, so they create a step-like pattern. The interpolation helps alleviate this. They also do some sea level stuff it seems, that appears to be specific to that game.
I would keep things simple for now: try to get the "select a tile and download higher zoom level tiles" functionality working, then the logic for stiching those tiles into a single heightmap working. From there, it's just a matter of how to set things up to scale properly in Unreal. This is a hard problem...I can see why terrain-party went with using SRTM data.
I could be wrong about a lot of these details, but I think overall, your questions pertain to stuff in that project that is specific to Cities Skylines. As for working together, my time is pretty slammed with work and family. If you have specific problems and you want me to take a stab at a pull request, I can try...but no promises.
Yep removing the Cities stuff is what I am working on. The main reason for using this was the tile stitching method. Do you have a method for stitching the tiles together. Thank you for the download method. So if I can get an array of data the same that we currently get except that it is an array of stitched tiles then would be awesome. TY.
Oops, looks like the bilinear interpolation is due to them setting a custom resolution. I've forked your repo and can take a stab at a few things when I can.
Thank you so much!
Hope you are doing well, just saw some of you new updates, very cool. I am actually working on re-writing my site. I found some cool code that does some neat tile stitching. I currently have tile stitching implemented in my site but this guy does it in a better way. You seem to be very good at the math which I am not. I was wondering if you have time could I ask you some questions. Here is my current code https://github.com/delebash/unreal_map_bridge. He has some calculations with hard coded values such as 1080 and 1081. If you look at the app.js and find the function toHieghtmap see comment // in heightmap, each pixel is treated as vertex data, and 1081px represents 1080 faces.
// therefore, "1px = 16m" when the map size is 17.28km
The 17.28km is specific to Citiy Skylines as noted here https://skylines.paradoxwikis.com/Maps. I don't really understand how 1080 and vmapSize, work in creating the heightmap. For Unreal we need to be able to set a heightmap size to different sizes such as 2017x2017. Another thing I do not understand is the Bitwise operator at the end of function convertHeightmap how it converts 65535 to 255. If you have the time I would appreciate the help. Maybe we should just work on one map app that we both can add features to. Let me know what you think. TY and Cheers!
Little video explaining my problems. https://youtu.be/4Ln9UyFGIbM TY