Help with globe extrusion

I am trying to do something similar to the Kaspersky globe in Babylon. I have a sphere and read a geojson file and draw borders of countries.

I am stuck with trying to extrude the countries, and color them in as solid colors rather than outlines.

Any suggestions? I’ve been working on my 3d plane learning, but I feel like there is something in Babylon or an extension that can help.

Here’s a link to the Kaspersky.

Thanks!

Hi @Keeger and welcome to the forum. This is just off the top of my head so may be a silly idea. This will draw and extrude a country drawn on a plane Create Parametric Shapes - Babylon.js Documentation. You would then need to map the top and bottom vertices of the mesh onto spheres

1 Like

I can get the extrusion drawing, but i am not sure what you mean by map the top and bottom vertices on to spheres?

thanks

Irregular extruded shape -> country
blue sphere -> planet
grey sphere -> shell: depth for displayed country on planet

Vertices of lower plane of country map to planet.
Vertices of upper plane of country map to shell.

Take the vertices of the country mesh (which needs to be updatable) and map appropriately the lower and upper vertices to the inner and outer spheres, respectively and the country will be attached to the planet.

Question. Do the country points from the geojson file form a flat plane or do they lie on a sphere?

they are lat/long only. i use this code to convert to sphere:

x_values.push(Math.cos(lat * Math.PI / 180) * Math.cos(lon * Math.PI / 180) * sphere_radius);
y_values.push(Math.cos(lat * Math.PI / 180) * Math.sin(lon * Math.PI / 180) * sphere_radius);
z_values.push(Math.sin(lat * Math.PI / 180) * sphere_radius);

seems to work.

but i don’t have a mesh. i looked into that, and it seems i probably need to create a custom mesh? but all i have is a series of vertices representing the border. not sure how to take that and make a mesh.

Sorry i’m raw when it comes to babylon and 3d in general. I appreciate your help!

Using the latitude and longitude values as the x and y components for the shape create an extruded polygon Create Parametric Shapes - Babylon.js Documentation making sure it is updatable. Then you can update the vertices https://doc.babylonjs.com/How_To/Updating_Vertices with the mapping you give above replacing lat with the x value of the vertex position and lon with the z value of the vertex position. If I get chance I will do an example this weekend.

As usual things are never as simple as I think. However hopefully here is a solution you can work with https://www.babylonjs-playground.com/#DHCRQH#1

AS you said it is easy enough to create an outline of a country Babylon.js Playground. The first issue is that to fill in the outline. To do this requires the polygon outline of the country to be filled in with triangles. Not a straight forward task with an irregular not convex polygon. In terms of a custom mesh then the triangulation of the polygon has to be done and the top and bottom country polygons need to be joined around the sides with triangles.

Now the MeshBuilder method already does this for a list of polygon points. However this only works when the polygon is lying on the XZ plane.

There may be more efficient ways to do it.

The steps are

  1. Position the geojson coordinate points on the surface of a sphere.
  2. Find the center of the polygon and the normal of the center of the polygon (average all normals for all points)
  3. Construct a plane perpendicular to this average normal at a set distance from the sphere. The average normal becomes the normal to the plane and passes through a point on the plane C.
  4. Map all points on the polygon onto the plane.
  5. Using the plane normal, a vector in the plane (point 0 - C) for a set of axes for the plane.
  6. Using a rotation matrix, rotate all points on the plane so that the plane normal is vertical (ie plane now in XZ plane)
  7. Calculate an average distance H for y of tthe plane (atkes into account floating point errors)
  8. Use the mapped points now on the horizontal plane to form an extruded polygon with a given depth;
  9. Replace the 0 y values for the positions in the vertexData of the extruded polygon with H
  10. Use the inverse matrix to rotate the extrudedPolygon positions of the vertexData back to lie on the original plane.
  11. Reverse map the positions so that the lower polygon wraps around the sphere and the top polygon is above it.

Good luck playing around.

3 Likes

JohnK, I missed your response from a week ago. I wish I had seen it sooner, I have spent quite some time messing with this. lol. I actually got a custom mesh made with triangles, but if the lines are too long, the mesh digs into the sphere surface, and it’s been…challenging.

Your playground and steps looks like it works. I’m going to play with that and see how it looks with multiple countries touching etc. I am hopeful tho! if it works, I will see about exporting the work so i dont have to re-calculate it every time, since this is for a fixed look.

Thanks!!!

John, maths…man this is tricky.

so i took your example, and set it against my coords, and it works like a champ!

except!

if I lower depth to 0.05, i get holes.

I looked into it more, and I think the issue is my code to translate from lat long to sphere vectors. if I use the formula i started with, no holes, but the country is mirrored. I found a formula to fix this, but holes show up, unless I bump the radius.

bumping the radius though lets you see the countries are floating. boo.

i created a playground, any chance you might have insight into the clipping issue with holes? right now its “working but mirrored” and if you swap the code calculation comments, it’ll have a big hole in the center of the US.

https://www.babylonjs-playground.com/#5I9JSA#2

maybe I can just tell babylon to not clip on the extrude, so it draws? i mean, it’ll be fine visually if the material is there.

Thanks,
Matt

@Keeger seems like lat and long come from a right handed system, line 127 solves this.

https://www.babylonjs-playground.com/#5I9JSA#3

1 Like

weird. so that fixes the US. but other countries still have holes. Here’s canada as an example:

https://www.babylonjs-playground.com/#5I9JSA#4

Any thoughts as to why increasing depth fixes this?

The only thing I can think of is that parts of the top of the extrusion are such that they fall below the sphere surface. Possibly just floating point errors. You may just have to increase the depth just enough to stop it.

I’ve been looking at this all day.

it’s not floating point errors. what it is, is large countries, and the extrusion formula creates a triangle that crosses it in a large distance. such that it is below the sphere surface far enough, that after extrusion, it is still below the sphere.

and yea, kicking up depth fixes it, but i really dislike the depth I end up, because it is way too tall.

i have been wracking my brain on how to solve this, but i’ve been unsuccessful.

i dont know the best way to describe this, but what if I defined a set of points inside the polygon, so that instead of an outline, i have more of a “backing” if I can draw curves through the non-border points, i could make like a ribbon type shape or something, and extrude that?

while I can generate points, I don’t know how to order them in the plane. I’ve also had issues making ribbons, a 1 path ribbon doesn’t seem to work here. but maybe if I make a “filled in” curved plane, I can extrude that with math, and that gives me my 2nd ribbon path?

no idea if this makes sense.

You might split the larger countries so no single triangle lays across the whole distance?
Looks very cool what you got going.

thx.

I thought about that, but once I have this extruded, the next step will be a highlight on mouseover / click of a country. If i split them, i think that will ruin the highlight on the larger parts. but maybe it won’t. haven’t done highlighting yet :slight_smile:

Yeah I think if you texture it and normal it right it will be seamless. Maybe even just break the whole dataset down into lat/long sized meshes…
Like you could recombine the country into a single mesh after it’s been processed into tris.

Note that you will need to recalculate the normals on the last version of the polygon for the texture idea to work as I have not done this.

Had time to have a further look and this

is indeed the issue. Yopu can see this by looking at the wireframe version, https://www.babylonjs-playground.com/#5I9JSA#5.

The triangulation of the polygon planes is set to minimise the number of triangles used.

Increasing the number of triangles using increaseVertices shows an improvement https://www.babylonjs-playground.com/#5I9JSA#7. However this creates another problem as the increaseVertices method splits all triangles into multiple smaller triangles including all the triangles forming the depth. Since there are very many edge vertices this can increase the vertices beyond the webgl limits. So that a way of splitting only the larger triangles into smaller ones is necessary.

right. i was trying to find long lines and manually split. but i saw the large number of vertices, i kinda went oof.

I tried another idea.

I made a ribbon with the surface points and manually extruded points. this gives me a nice extruded border, with an open top.

i then tried to use your extrusion code to make a thinner extrusion depth, like 0.02, as a cap. i thought since i was already above the earth, it might work.

no change, those lines are still so long they go into the earth.

i then tried to make triangles inside, using turf.js, but the triangles ended up drawing lines outside of the borders, making the mesh ugly. (cuz its a triangle grid).

but right now, the ribbon works for raising borders. any ideas on how to create a cap mesh? it doesn’t need to be truly 3d, just curve with the sphere. (heh)

I have a thought.

so my triangle mesh goes just a little bit outside the borders. and I have my ribbon mesh of the borders. is there a way to use the merge mesh capability to basically crop the triangle mesh parts that go outside the boundary?