First game with OpenStreetMap scene

Hi there. I am new to JME3 and so far just downloaded the SDK and went through parts of the basic tutorials. On my mind is a network game where multiple players can run through ‘their city’. Tasks/Adventures will have to come later.

Has someone already managed to convert OpenStreetMap data into an scene? Would an attempt do to so be feasible at all?

I found

but it seems there is no further feedback of the outcome, let alone the result would be open source so I can use it as well.

Yes it can be done. @pspeed posted a demo few years ago:

1 Like

That looks great and is definitely good enough for my purpose.
What would I have to do so I can use that code or feature? Is it part of JME? Is it an addon? Is there some documentation about it?

Or should I fire all these questions to @pspeed directly?

1 Like

It’s a bunch of hastily written prototype code but I’ll see if I can remember where I put it.

I used to do a lot of GIS work a long time ago so most of the data-related issues were already familiar to me… which is why I was able to hack some code together over a weekend or so.

2 Likes

OpenStreetMap is a great data source, but getting it into a realtime rendering isn’t trivial (it’s not impossibly difficult either, but plan to spend some good time on the project if you want more than basic data display).

Maybe I start with some custom level drawn by hand based on openstreetmap.
After all for the first scenario there is much more to do than just the world…

Here is the source code to my racing prototype stuff I was working on:
https://drive.google.com/file/d/11GkqGFLGJfIL3uJz5ZkArq2cW-4dwQ5Q/view?usp=sharing

It’s really raw and message but hopefully you can see how I load and convert the OSM files into something useful.

It probably won’t run without the right OSM files and may require some locally built dependencies, I don’t remember. I think it also wants some geotiffs for elevation and tree cover and stuff.

But maybe the code is useful.

In the end it produced stuff that looks like:

Which was pretty cool to drive a car around in.

4 Likes

Downloaded, and I will have a look at it.
Seems I need to focus on OSMConverter. But as there is no main() method:

Is it possible that you started the game with some osm file and it would on-the-fly convert into something for JME? Ah, Main.java lines 480 to 488 should demo the magic…

While going through the code it seems there is an external dependency from TerrainState.java to a package called com.simsilica.fx. I found https://github.com/Simsilica/SimFX but there seems no release so far. Also in the Maven repositories I cannot find that one.

Not complaining about donated code I will try to compile it myself now.

Yes, for the time being, SimFX users need to build from source. Download/check it out and then run “gradle install” or whatever.

Though note that the SimFX dependency is (I believe) for the atmospheric materials. You may end up not needing it for your own game (though atmospherics are nice in the end).

Thank you for the hint. Somehow I have no luck with gradle so far.
Knowing Ant and Maven however I can make my way.

Meanwhile I created my own SAX parser to get the building data and looked at your buildingsToMesh method. Ultimately I now attached them as geometry with material Unshaded/Blue to the rootNode. For me every building is a mesh of it’s own - I think you placed all buildings into one mesh.

When I start my BasicGame I now get a black screen. My assumption is that the buildings are far off from where the camera is, and now I am trying figure out how/where to place the camera so I can actually see something. How can I find a suitable place for the camera or the player?

If you have a spatial, get its world bounds… put the camera in the center.

Always works for anything even if not the best placement.

Somehow I am trying to achieve that, however the problem is that I am yet a bit unfamiliar with the API.
My code snippet looks like this:

        List<Spatial> buildings = new OSMap().getBuildings(assetManager);
        for (Spatial sp: buildings) {
            rootNode.attachChild(sp);
        }
        log.debug("added {} spatials", buildings.size());
        
        // set camera to first building
        cam.setLocation(buildings.get(0).getWorldTranslation());

My idea was to place the cam at any one of the vertexes of the mesh that is underlying the spatial. Even if the one building that is too close to the camera might get clipped, there should be other buildings around. But then I am querying the world translation - it may be something totally different than what I think it is.

How exactly do I retrieve the spatial’s world bounds?

Edit: I now used this code:

cam.setLocation(buildings.get(0).getWorldBound().getCenter());

and now I can see blue blocks again. Many of them! This is exciting. But I do not yet recognize the pattern. I may need a compass and coordinates as a HUD. Moving on… :slight_smile:

If you are using the unshaded material still, then that could by why you aren’t noticing any pattern to your blocks.

I would instead recommend using Lighting.j3md or PBRLighting.j3md, and add a DirectionalLight (and LightProbe if you use PBR) to your scene, then you’ll notice shading and depth to the blocks.

Yupp. I did not go by patterns on the blocks themselves. I used ‘Q’ to fly upwards until I could see the positions and directions of the blocks, and I compared them to OSM that was open in my browser. Some buildings had very specific shape and ultimately I could make them out.

Next steps are to add some masonry material (I have not yet any clue how to do that) and building height. Plus I need to distinguish residential buildings from garages. After all the OSM data provides the purpose, number of levels and whether it is a flat rooftop - all encapsulated in the tags. Having some roads and water surfaces would also ease recognition by far.

Screenshot from 2022-02-23 23-24-11

2 Likes

Glad you got it working.

Are all of those buildings really flat or did the height code get nerfed in my OSM stuff that you are using?

I only used part of your code. Which means right now all buildings have equal height=1.
Am still experimenting.