Orbital view - 3D label or not 3D label, that is the question

The user clicks on a button, a global 3D view of the planet Mars appears and there you can have a quick glance at all your bases around the planet. Also, as you're curious and want to learn more about the planet, sometimes you go there in order to check where that particular crater is, or how many "Planitia" Mars has.

What do you think, would you like it in a mobile game? I do. And that's what I'm working on lately.

As I'm using Godot Engine, I'd like to explain the way it's done here and why.

First thing I had the 3d mars model generated (not in Bleder, but directly in Godot using elevation data, previous posts should give you an idea of how I did it). It has quite a number of polygons, I might need to reduce them (maybe in half), or use some other trick.

Then I placed a scene with the globe, a spatial node as rotation axis for the camera, and finally a camera with a raycast child node attached to it.

3d planetary view nodes setup

Like this

As you can see it also have an area there, with it's collision shape, it is used in order to detect raycast collisions (if you're trying to do something similar, remember to enable collision with areas, by default is disabled).

Converting vectors into Latitude / Longitude

The camera rotation axis is the one rotating and not the planet in order to make it easier to convert a direction (or a position in 3D space) into a latitude/longitude position and vice versa. Found the pseudo code somewhere on the internet, and in GDScript the lat/lon to position is something like this:

latlon to vector and back

latlon to vector and back

In order to make use of what you have above, you'll need to know where are you clicking, tapping, or dragging. Godot has tons of useful functions that help the task, first is to detect the input event, it's 2D position, then to project that into a 3d ray, and the raycast node is there for this purpose. You just need to rotate its direction based on where you click, so that once you raypick you'll get the 3d direction vector (where on the planet you have clicked/tapped). The function above converts the vector into a latitude longitude Vector2.

Adding locations (aka POIs)

So, after creating the scene and code necessary in order to get the coordinates from your input, I've added the locations, the data comes from github, but the original source I think is this one, from the IAU (International Astronomical Union). Data soulr be free to use for any kind of projects, if I'm wrong let me know.

I downloaded a CSV fomat, that I've converted into JSON, then loaded into godot as an array of dictionaries. I had then available the followind data fields:

  • latitude
  • longitude
  • size
  • name
  • type
  • id
  • a couple more I haven't used

With that, and the functions above, it was easy to do the opposite, convert lat/lon into a direction vector and project that onto the sphere, but there, unexpectedly, came the biggest problem I encountered for this feature, the use of 3D labels, that was the first thing it came into my mind. I knew Godot does not yet implement that as a node, so I had to implement that, luckily there are tons of examples on how to do it, and I'm resuming it like this:

  • MeshInstance (with a viewport texture that uses the viewport below)
  • Viewport
  • label (label is a child node of viewport, so that it's rendered there)

I then instanced it as much as I needed, problem here is performance, it looks like it's quite heavy this way, it works, but I had several crashes after I implemented that, and even if I wasn't able to prove it 100%, I'm quite sure, this setup causes the usage of too much RAM thus crashes the game. That's such a shame, because 3D labels where pretty cool, I could have wrapped them around the sphere, in order to simulate something similar to a decal.

So, to cite Shakespeare, the problem is about 3D label or not 3D label.

As a side note, Godot have the implementation of 3d text and labels into their roadmap, you can see this post as a confirmation:

It would be a very desirable feature as many would make use of it, and using the viewport thing is not the ideal solution, especially given the performance issues I'm sure I'm not the only one reporting.

Mars locations take 2

Second attempt was using a feature I have discovered only recently: unproject a 3D vector into 2d screen coordinates.

So what I did was to create a scene that I would then use as a label, instance as many as I want, bind it to a 3d marker (this time just a point mesh), and do the unproject trick:

unproject from 3d to 2d

unproject: from 3d to 2d

This time performance seemed to be good, I mean, I had no crashes (but it locked when I selected like a thousand locations), also I did not needed to use a lot of raycasting in order to detect clicks on the labels, that's a good thing. So I now only need to group very close locations into one label, add a symbol per feature type, use a different UI element (something like a callout) for when I'll be able to track units and bases along the planet's surface.

Download video

A better version of this map will be showcased as soon as I have it.

Btw, if you got this far reading, maybe it is worth mentioning that I do post daily updates on twitter:



Log in with itch.io to leave a comment.

Good job! :)