What's a good way to have every tri on a sphere's surface know which hexagon/pentagon cell it's in?

There are lots of games out there that use a planet built from hexagons and pentagons. Before We Leave, for example:

I want to work with a similar thing in Unreal, but I also want to be able to manipulate the shape of the planet at a finer resolution than simply those large cells. So here’s a geodesic icosahedron in Blender, then the same thing with 2 levels of subdivision, and then again with 4 levels of subdivision and some manipulation made possible by the higher vertex count. I’ve added the colours just for visualisation.

Now taking that shape, returning it to its spherical-ish form and ditching the materials, this is what Unreal sees when it is imported:

](filedata/fetch?id=1867474&d=1614683309)

I want to be able to do things like:

  • each cell has its own state/data
  • know which cell any point on the surface is in
  • per-cell material changes
  • operations based on things like counting cells with some state across the whole surface, etc.

The main caveats are:

  • a high vertex count is required
  • 500-1000 cells are desired, so separating cells by assigning materials in Blender isn’t an option
  • the mesh can be divided into regions with clean edges, ie., regions borders are visually smooth, unlike the red region in the image below. I’ve been going with the icosahedron for this reason, but hexagons aren’t strictly required, only smooth regions are.

](filedata/fetch?id=1867475&d=1614684521)

So the question is:
How would you go about getting every triangle to know which hexagonal/pentagonal cell it is in?

There might be another path entirely to suggest that ticks the above boxes. I’m interested if so.

Cheers :slight_smile:

*Quick addition to mention the approach I’m currently taking:

  1. Create a 2nd “shell” mesh the same as the first but without the subdivisions
  2. Make it slightly larger, make its faces face inwards, and position it in the same place as the main mesh
  3. Line trace outwards from every tri on the main mesh, to hit the cells on the shell mesh
  4. Get the normal from the line trace hit. If it’s a normal that hasn’t been discovered yet, register that tri to a new cell. If it’s a normal that has already been discovered, register that tri to the cell that previously-discovered normal goes with.

It’s more maths than it is Unreal, so I’m hoping there’s a smarter/more elegant way that better uses Unreal’s features to achieve a similar result.*

Vertex paint?
You can store 3 channels of 8bit - if you normalize the value by taking the total sum of the cells on the sphere you can easily multiply to find the coordinates based on whatever distribution system you want to implement on it.
standard X Y Z since it is a sphere should work quite well…

instead of starting with an hex, start with a sphere so you can section it off like we do with earth. LON, LAT.

After you have the sphere in quads vertex paint it.
if you then simplify it you are left wirh mixed results on a cell, which describes where the cells sits a bit more accurately.

If starting with a hex, you need to parse much the same way but base it on each face location in world space instead.

Fairly simple to script in pyton/blender in either case…

If you need it avaliable in code you are probably better off splitting the quads into separate entities and composing the final sphere with them

Thanks for the reply and I don’t mean for this to sound rude, but there’s a lot there that is really unclear. (In your first paragraph alone there are 5 places where you refer to a thing that you haven’t actually written or named.)

Rather than try to understand it, for now I’ll stick with the approach described at the end of my post and see if a more Unreal-esque suggestion pops up. I added that in an edit so no worries that you hadn’t seen it; it appears I must have missed your reply when I did so. But since your suggestion appears to be about number & vertex crunching just as much as mine is, I don’t think it’s going to be much of an improvement for me to switch from blueprinting in Unreal to coding in Blender plus blueprinting in Unreal.

Again thanks for the thoughts however, just looks a bit rushed there.

“In your first paragraph alone there are 5 places where you refer to a thing that you haven’t actually written or named”

Very first line of my post: vertex paint.

How is it I haven’t named the thing when its literally the first line? :shrug:

your question should be “is this avaliable to access over BP”.
in which case, it wasn’t by default a while back / you have to write your own CPP function to sample FColorVertexBuffer.

However, put that aside. The concept is the exact same.
if you color the original sphere manually in a DCC, then subdivide it, you retain the original colors on the vertex paint in each square.

you can leverage this to parse all the faces and output an ID and a Color in text file.

you can then use thebfile inside unreal to manage whatever / however.

Mind you, it’s actually not clear at all what you wish to manage and how, which is mostly the issue.
you can get the data a lot easier in a 3d program then you can in engine simply because you’d have to script a cpp function to read vertex color values when really, all you need in the end is a flat text file to fill an array with / do other data stuff (we readers would assume)

To reply to what you asked about naming the thing, I’m sure you weren’t actually saying things like “coordinates of the vertex paint”, “multiply the vertex paint”, “implement on the vertex paint”, etc. So while vertex painting was the general area you had in mind, there isn’t a way for someone who would need the explanation you were writing to also be able to interpret how all those bits actually connect to it. At best it could only be understood by people who didn’t need it. The intent to help is appreciated, so please just see my comment as something to take into consideration.

I don’t think there is an issue here that what I want to achieve is unclear (or any issue here at all). I think the question’s title is quite clear itself, and I walked through the problem with images, and bullet pointed the desired outcomes and caveats.

To clarify for anyone else reading, I am definitely not asking if this is available over BP. I’m interested if there is any good way to do what it says.
(Coincidentally I can use a BP just fine to achieve the approach written at the end of my post, but I’m not asking about that.)

The text file approach is good thinking (what is DCC by the way?), but one downside is the manual colouring to separate cells. For large cell counts it’s impractical. There is probably a way to script that manual work away, but again it comes down to vertex crunching in one tool then parsing in Unreal when I can already address the problem by vertex crunching in Unreal.

From what we’ve talked about so far and from your experience and the approaches your mind is taking, it looks like vertex crunching would still be required either way. I guess I was just wondering if Unreal, which has many tricks I don’t know about, has some trick for doing something like blap, geodesic regions!!. :smiley: I was actually concerned that crunching numbers would be the inelegant approach, but it’s looking like that was the wrong concern to have.

Dcc = digital content creation / any 3d app in this case.

I would dare say that pre-crunching is always more perfromant.
a game already has a ton of stuff going on. The more you can remove from the computing side the better.

Let me rephrase that first paragraph in a non technical way…

Take the vertex position at the lowest spot in the sphere. Read its z. Take a vertex at the highest spot of the sphere, read its z.
Assume the lowest value is equal to 0. The highest to 1.
each vertex within the sphere located between the 2 z values can now be assigned a z vertex paint value that represent its position in world space.
following so far? repeat for x, repeat for y.

any 3d app worth anything will allow you to pack those values in, in a matter of seconds by making a script / or provoding one thay already exists.

Now, normally when I do stuff like that I do it on a per vertex basis. In your case you need to do it on a per face basis. The concept should be the same.
furthermore, it may also not be needed.

If you start off with a limited number of faces you may be better of managing by hand and going in set increments.

Like I said, you have 4 data sets of values from 1 to 255 that you can use to “label” each face before you subdivide it.
once you are done with that range you can combine the other values just like colors.
further, blender doesn’t crush down float point values to 8bit in vertex colors anymore. So, provided unreal doesn’t alter what is imported it probably does just because it would be too cool if it didn’t you could get a lot more than 255 entries per channel.

All that explained, you still need to convert from the paint values to a text file in order to use it at runtime imho.
Its just faster to read from an array… and sampling a color from a texture is also expensive.