mapbox / mapbox-unity-sdk

Mapbox Unity SDK - https://www.mapbox.com/unity/
Other
721 stars 214 forks source link

Am I understanding ModifierStack and Modifiers correctly? #370

Closed colin-young closed 6 years ago

colin-young commented 6 years ago

I think I'm starting to grok some of the API:

So far so good? If so, I'm guessing I could create my own custom modifiers:

Am I on the right track?

The one thing that seems to be missing is the ability to annotate existing tilesets with ground truths (i.e. adding a road-type attribute to the existing road layer to indicate if it is asphalt or brick, or whether or not is has sidewalks), but I think that's a Mapbox Studio limitation.

brnkhy commented 6 years ago

Hey @colin-young, nice analysis and you're right on most part;

Modifier Stack and Merged Modifier Stack does almost everything same except one difference;

MeshData represents the data you need to create the game object and the main goal of the mesh modifiers is to fill that up. I don't think MeshData is final at this stage though, I like the idea but can improve this (it's also missing some basic stuff like Tangents at the moment).

Original point to world space conversion is kinda hidden at the moment I guess, but it's inside VectorFeatureUnity class constructor. We create VectorFeatureUnity from VectorTileFeatures to get them ready for the processing.

about custom modifiers;

I don't know how it works but my suggestion would be; do not try to embed that into our mesh generation. Use mesh generation to create all data you need, then have another external script or something to use that data and library to create roads. It would probably be much simpler and managable if you keep them separate like that.

And you're right, I believe it's not possible to annotate existing tilesets like that at this point. @BergWerkGIS might know better though.

Oh and one final thing, we're planing a rework on mod stacks and modifier soon. A small one to make it all much easier to use and understand. Also I'll probably be writing documentation on those stuff this week.

colin-young commented 6 years ago

I should have mentioned I did get the difference between the Merged- and the Modifier stacks. The initial code docs comment was what really helped me understand how it all works, so please keep that in there when you rewrite :)

I don't understand SnapLabeledToTerrain. So you only want to snap objects with a particular property value ? Or let's me ask, what kind of behaviour you need SnapTerrainModifier doesn't do?

On further reflection, I figured the 2nd approach (points in Studio and then use those to place assets) is probably a better route, and accomplishes the same thing. Imagine you've got a bunch of assets, say building models imported from SketchUp, and you want to place those in the correct location and have them sitting on the terrain. I currently have a hacked-together solution that uses a world-to-unity conversion to move my models which it identifies by the tag I've assigned to them. There are a number of issues with this approach and managing the location through Studio tilesets seems like a more manageable proposition.

You are probably right about keeping the generation of the road network outside of the Mapbox stack, and just generate some data structure via the stack to pass to those routines. I was just concerned that other post-modifier stack steps relied on the terrain being un-modified, and this approach would eliminate that concern, even if the API is changed to where that is the case. I've probably got enough work trying to make Road Architect do something it isn't really designed to do (generate the roads at runtime). If only there was a way for Mapbox to generate and persist terrain inside the Unity editor... (I do understand there are licensing issues involving multiple third parties that would need to be resolved).

Looking forward to seeing the rework on the stacks. For me the biggest barrier was just understanding what happens internally. I could follow the tutorial and get it all working, but when you want to go off and extend things it's helpful to understand what those steps are doing. It probably doesn't help that I'm a business app developer, not games or GIS, so I'm trying to learn 2 completely new paradigms here :)

brnkhy commented 6 years ago

@colin-young if you're planning to place prefabs on points, I think it might be better to use lines actually. I had this idea for a long time but couldn't test it; you can create lines instead of points. Then place the prefab at the first point, use second point to calculate its rotation, maybe third point for scale and some other stuff as well. Just remember "line" isn't really line, just a list of vertices. (actually I think points are lists of vertices as well but I'm not sure now)

I'm really interested in the Road Architect experiment, let us know if you have any problems, would love to see that work. Saving terrain to editor wouldn't help much I guess, we're always planning stuff applicable for everywhere, not limited area solutions like that.

I'll ticket the modifier stacks ideas soon 👍

colin-young commented 6 years ago

Thanks. I'll look at the line idea, but in my case I was planning to create my models already rotated, but it could be useful for populating with generic models.

I'm really interested in the Road Architect experiment, let us know if you have any problems, would love to see that work. Saving terrain to editor wouldn't help much I guess, we're always planning stuff applicable for everywhere, not limited area solutions like that.

What I'm trying to do with RA (and about to start coding as soon as I'm done here) is generate the roads at runtime, which is explicitly not how RA is intended to be used... basically I'm trying to duct-tape together one library intended to generate terrain at runtime with another intended to modify terrain at edit time. I'm sure there will be no problems at all... :)

I know other people have asked about edit-time terrain, so I'm sure this isn't the only use-case, but I also understand you've got licensing and tons of other work to do that will probably provide more value to more people.

colin-young commented 6 years ago

@brnkhy A quick question, admittedly it might be more Unity-related than Mapbox: where or how do I trigger a script to run after the modifier stack is finished? I've written some code that's probably not going to work exactly correctly yet but should at least throw an exception or breakpoint, but so far I can't figure out how to trigger it. It looks like Start() is the right place, but I'm not getting triggered and I'm not totally confident that's really the right place. I may also be attached to the wrong object. IIRC I'm attached to the Road Architect object at the moment. I'm using https://github.com/UnityCommunity/UnitySingleton to hold my collection of nodes created by the modifier stack. Not sure if there is a way to orchestrate things from there somehow.

brnkhy commented 6 years ago

@colin-young oh I just saw this, I'm really sorry about it :( It depends on what you mean by "finished". If you mean finished for a single feature, you can call your stuff at the end of the Execute method. That's the point processing a feature is fully finished. If you mean finished all work though, that's harder and depends on your usecase & app logic. Because in most applications (especially with moving camera and loading new tiles), modifier stack is never really finished. And since it doesn't know about the incoming work load and just recieves features one by one, hard to determine when it's "finished". MapVisualizer has a state property and fires an event when all work is finished though, might that help?

colin-young commented 6 years ago

It's not for a single feature. I want to know when everything has finished loading. I kind of figured out via logging that I was getting triggered on multiple occasions from the modifier stack. Per feature seems about right.

MapVisualizer will probably do the trick. For my current work, the plan is to pre-load the entire area so there really will be a "finished" for the modifier stack. I'm not trying to support the players leaving the pre-defined area and will put up obstacles to prevent that so I won't need to deal with dynamically loading new tiles.

I'm not using UnitySingleton any more. I found Zenject which makes way more sense to me (my day job is building enterprisey web applications and APIs), and I'm pretty sure I'm triggering things from my custom modifier. Should be easy enough to move that code out of there and inject a MapVisualizer into my road manager. Incidentally, I've given up on RoadArchitect (for now) and am looking at EasyRoads3d (not free or OSS unfortunately, but does have an officially supported runtime scripting API, and directly supports importing OSM although I'm not sure how I'd make that work with MapBox).

Thanks!