What I want to achieve
I want to generate sphere planet world, seamless of course, for RTS game like Planetary Annihilation: TITANS, which means I want:
- place walking agents on sphere, move them on a sphere surface, be able to do A* pathfinding
- generate polygonal regions on sphere like Voronoi
- have world divided by chunks (possibly reduced to 1D array) to effectively perform calculations like local avoidance.
- generate seamless surface heightmap based on noise functions AND not to store this height map as a texture but just store height overrides in chunks. This way I can have just
uint
seed and overrides instead of keeping huge heightmap texture.
How would I do it in seamless 2D world
In 2D space things are really simple even if your world one axis seamless: 2D map can be imagined as cylinder, or both axis are seamless: 2D map can be imagined as torus.
Coordinates
They are just float
x
, y
. Moving is just adjusting coordinates. Distance between 2 points is just distance between 2D vectors. Seamlessness of moving is achieved by %
operation with coordinates, like x = x % x_max
.
World as 2D grid
2D world can be represented as 2D grid where each cell is a chunk with which I can effectively store and access data, because 2D grid is reduced to 1D array. 2D position can be easily converted to chunk index and back.
Heightmap noise generation
Seamless noise can be tricky, but here we have golden treasure of map noise generation from red blob games.
Presenting world and LOD
I would use simple plane mesh with rectangular connection of triangles to represent terrain of 2D world. LOD then could be implemented by recursively add vertices into mesh cells like tree. Again with 2D world it is simple because mesh / data / LOD are all grid based.
Problems of doing same with sphere world
Because claimed / x-seamless / xy-seamless 2D worlds are all not really the sphere (they are plane / cylinder / torus in terms of wrapping) there can't be 1:1 transformation between 2D and spherical 2D world.
When trying to wrap rectangular around sphere something should be disturbed. It could be that we actually run all logic in 2D but project coordinates on sphere, but we will get disturbed positions near poles.
Or we can run logic on sphere and project positions back to 2D then we will get disturbed 2D representation like what happens with earth map when it represented in 2D, which is what called Equirectangular projection.
One way or another I need some "grid" representation of chunks, because in the end I need to test what chunks of sphere camera see and effectively cull objects which are not in visible chunk.
Cubemap solution
Representing sphere as cubemap kills all problems working with sphere, because sphere now represented as 6 2D grids.
- Constructing mesh is just get cube (or six plane faces) with vertices adjusted in a way they lay on unit sphere. LOD is now also possible because we can work with faces separately.
- Store and access needed chunk now isn't a problem also because now we are back on 2D grids.
Problem with cubemap coordinate system
Many thanks again to red blob games and this article in particular. Here we can find a way to implement coordinate system for cubemap world. But moving across faces is a huge mess, not only because it require to map direction for each face but also because when both x
and y
have to be wrapped to another face it becomes ambiguous which face to choose. So moving on cube map becomes problematic for corner cases.
Use cubemap only for data
I think it is possible to use spherical coordinate system latitude
and longitude
and reimplement common operations like moving, getting distance, etc. but on sphere instead of 2D surface and use cubemap representation only for storing data in and read from chunks.
Where to live finally?
- Living on sphere means to deal with spherical calculations which are more complex to understand and expensive because require trigonometrical functions. But then coordinate system becomes natural because we actually live on sphere and just map it on cubemap when need to work with rectangular chunks.
- Living on cubemap means to deal with cubemap coordinate system which is complex core of all this approach also producing prohibited moving cases. But in return we get nice and simple 2D calculations for everything with natural storing data in rectangular chunks and only use sphere to represent our world in 3D as a planet.
What I want as an answer
Maybe I already answered my question and there is no place to answer anymore and I just need to chose one way or another comparing pros and cons. But maybe I miss something, maybe there is another smart way to do what I need without overcomplicating everything. I will appreciate any advice.