TheDuckCow / godot-road-generator

A godot plugin for creating 3D highways and streets.
MIT License
313 stars 16 forks source link

Proposal for Road Containers #122

Closed TheDuckCow closed 9 months ago

TheDuckCow commented 10 months ago

This post is a proposal that helps enable intersections, hand-crafted scenes (puzzle piece road segments), as well as improve the usability of larger road networks.


Current problems

A proposed solution:

Open questions

Pro’s of the proposal

Con’s of the proposal:

Misc feature ideas

TheDuckCow commented 10 months ago

Hey @bdog2112 FYI that I migrated and extended upon the private proposal doc over to this space. Still keen to hear your thoughts, but figured having a public place for discussion would also be useful

bdog2112 commented 10 months ago

PRIMARY THOUGHTS: My sense is that we already have just about everything we need:

bdog2112 commented 10 months ago

SECONDARY THOUGHTS: Many of the discussed bullet points require a specific context. There are two main contexts for most of the issues:

  1. Creating roads via code in the Wheel Steel Project.
  2. Creating roads manually in the IDE.

It's important to know the context being discussed. At any rate, here are some additional thoughts and comments.

RoadContainer Coordinates:

Curves:

Pre-Fabs:

bdog2112 commented 10 months ago

On the subject of RoadSegments, RoadPoints, and pre-fabs: It would be nice if we could drop a pre-fab road into a scene and have it magically link up.

What if we didn't have to explicitly assign Prev/Next RoadPoints? There's a fairly straight-forward way to implement this. Define Prev/Next RoadPoints by their order in the SceneTree.

Here is an example with two scenes: "Scene1" and "Scene2".

Scene1:

Based on the node order, we can assume:

Now, let's create "Scene2" and incorporate Scene1 into it.

Scene2:

The beauty of our newfound way for determining RoadPoint order is that Scene1 doesn't explicitly have to know anything about Scene2.

We can infer that the first 3 RoadPoints are the ones from Scene1 and RoadPoint3 connects to RoadPoint4 and so on... The implication, again, is that RoadPoint (and scene) placement determines the order in which RoadPoints are drawn. The RoadNetwork figures out the sequence when it refreshes.

So, to wrap up this post: The goal is to enable the use of RoadNetworks as child scenes and easily connect them to a parent scene. This approach could facilitate that use case.

bdog2112 commented 10 months ago

Oh, I would add the following recommendation:

Leave RoadNetworks named as they are, at least for the time being, in order to avoid unnecessary confusion.

Other objects have been renamed and, for various reasons, the name change was only partially implemented. Hence, we're dealing with two different names for the same object. It would be nice to avoid that if possible.

RoadIntersections could likely be an extension of RoadNetwork. This makes sense based on the fact that RoadNetworks take care of the drawing of Segments. RoadIntersections could take care of drawing Intersections.

It would be good to dedicate some resources to the development of RoadIntersections at some point.

bdog2112 commented 10 months ago

Perhaps, one final thought. If introducing a "RoadContainer" object, consider using IT as the top-level road object. Thus, the RoadContainer would contain the RoadNetworks and RoadNetworks would contain the RoadPoints.

It follows that the RoadIntersections would probably inherit from, or simply be patterned after RoadNetworks and sit at the same level in the hierarchy.

TheDuckCow commented 10 months ago

Thanks for sharing your comments! Responding to a few of the points here ahead of our discussion tomorrow:

What's missing is the ability to connect two streets (RoadNetworks) together.

Actually it happens to be that it does already work to connect to roads together, but it's a bit ambiguous about which one owns that segment. In any event, we essentially need to assert that the endpoints of two different RoadContainers need to exactly line up (so it's either an intersection, or one road continuously turning into another road).

Where should RoadContainers be placed in terms of coordinates? This simply requires an executive decision. First RoadPoint sounds good.

I think starting with the first RoadPoint is a good approach, and then if it gets moved, up to the user if they want to recenter or anything like that.

In the Wheel Steal game, will the roads always remain stationary or will the camera remain stationary at world origin while the roads move?

Assume roads will remain stationary, and the camera is moving.

When working in the IDE, it would be nice to be able to grab a single Spatial in order to move an entire road. But, it's not necessarily a requirement.

Agreed - user can always select multiple points. Users will mostly interact at the level of control points (ie RoadPoints) anyways, since moving entire roads as separate pieces won't really make sense since they might have starting connections which would either need to remain connected, or be disconnected after manual movement.

What was the context for the curves in the discussion?

Sorry I jumped between two thoughts. I'm referring to what I mentioned earlier in the post: "We have another feature intent whereby we create curves that follow along the outside edge of the road, as well as the exact middle belonging to the median line (both would account for lane changes)."

Think: one road will have one continuous curve object that follows the entire outside forward direction. Then someone can use the proedural geometry tools to place railings and lamp points along the entire length of the road. In Wheel Steal that gets tricky since we keep adding new segments (and removing old ones), so it could cause flicker. But, I think enabling an option to generate curves for only single segments at a time as well solves our use case problem there.

Pre-Fabs:...The developer needs to be able to save RoadPoints into a scene and then, later, assign them to a RoadNetwork as well as stitch other aspects of the scenes together.

.. addressing below

On the subject of RoadSegments, RoadPoints, and pre-fabs: It would be nice if we could drop a pre-fab road into a scene and have it magically link up.

Agreed. Essentially, I'm thinking that the ends of "RoadContainers" must always point to other RoadContainers. These ends are defined by unconnected RoadPoints within them, but essentially define the "shape" of the RoadContainer itself, and should work with composed scenes all the same. The more I think of it, the more I feel this is an intuitive and strong structure that fits all our needs.

I'll make a second post that is more addressing the structure I have in mind, will make this clearer.

TheDuckCow commented 10 months ago

So, to clarify my idea of the hierarchy with the new structure:

Scene which is a saved prefab RoadContainer

Let's presume we also have RoadContainerB, with a similar setup

Scene where you want to use the prefab

The thing I really like about this structure, is that RoadPoints of intersections and normal roadcontainers are not treated differently, and they're always at the same hierarchy level, vs having RoadPoints sometimes at one level or another. In this scenario, the connected containers do need to "know" about the contained RoadPoints on the edge, but the container/intersection object can essentially manage the arrays for what those are, so it's still a clean interface.

TheDuckCow commented 9 months ago

@bdog2112 and I synced yesterday to think through this some more, and we even created a crude mockup in godot with a simple script including export array vars which would imply how the interfaces of the RoadContainer would look like.

We also mentioned trying to avoid the ambiguity of renaming RoadNetwork. It could be that something like RoadRoot (or RoadRoute, or RoadSystem). That's more of a detail in the end. With this approach, RoadContainers create a nice boundary between their own siblings in a higher level scene, and the contents of its own subscene. The interface is an export array of nodepaths to point to other roads/intersections that this road container should connect to, as well as an index variable which indicates which roadpoint within that container should be used to connect to.

structure new proposal
TheDuckCow commented 9 months ago

With recent merges, I'm going to go ahead and close this task as done, since it is technically a "proposal" and we've started implementation.

For the interested parties, here's some additional diagramming planning I did to help illustrate how RoadPoints of one container will relate to road points in other containers.

Page 6