TheDuckCow / godot-road-generator

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

Add 3D gizmo controls for lane counts #40

Closed TheDuckCow closed 1 year ago

TheDuckCow commented 1 year ago

As the next step extension to https://github.com/TheDuckCow/godot-road-generator/issues/34, we should update the 3D view such that we can easily change the number of lanes visually by dragging the control points inwards or outwards.

Some requirements:

bdog2112 commented 1 year ago

The following should adhere to the above constraints. At present, I'm thinking it'll work like this:

One detail that isn't exlicitly mentioned is widget Lane Markers. Although, they are often pictured in mockups.

At present, the intent is to leave the lane markers as an option on the table. But, initially, the focus will be on Handles, Arrows, and Road. If Lane Markers are needed, then we need some additional requirements.

TheDuckCow commented 1 year ago

Good callout that the lane markers requirements aren't present yet. Let's leave that out of scope for now, easily added in later once we see the system we like and working well.

For now, let's not display the handles for not-currently-selected RoadPoints. This way we only ever have one set in the scene at a time. In fact, you might even get away with actually having only one set in the scene, and just keep moving and/or hiding them based on current selection.. this could be most optimal and avoid constant creation/queue_free'ing. Endpoint is, I don't want to end in a state where every single road point has 3-some additional children meshes that are present but hidden until selected.

User moves and fully controls Handles (no snapping while moving) Arrows snap, interactively, to nearest lane edge (plus 0.25lw).

Yup I think this works well. Though we'll probably want to "snap" the lane count to the integer multiplier position once the user has let go (similar to how roads switch from low poly to full rendering after you have stopped moving them).

Road does not update while user is moving Handles because that is processor intensive and it also causes the RoadPoint to re-center.

I think this is ok for now. In the future, we could update to insert additional lane markings to sort of "preview" when new lanes will be updated before release. It may also be that we just want to move to having the roadpoint's lanes generate out from the center (that align center setting we spoke of long ago.. but out of scope for now).

Let me know if that's all clear or if it raises any other questions!

bdog2112 commented 1 year ago

old widget is/is not shown (TBD)

Should we continue to display the old (red/yellow) widget along with the new one?

In fact, you might even get away with actually having only one set in the scene, and just keep moving and/or hiding them based on current selection.. this could be most optimal and avoid constant creation/queue_free'ing.

Right now, the widget geo is created/freed by each individual instance of the RoadPoint class. We could create a single copy directly in the GizmoPlugin class and use its logic to position and show/hide it.

As for how the widget geo is created, the current process of using Immediate Geometry works well. Meaning that we don't need to import any models. We could just continue employing the old methodology. But, do it directly in the GizmoPlugin.

In the future, we could update to insert additional lane markings to sort of "preview" when new lanes will be updated before release.

Yeah, this is the perfect use case for overlaying those blue lane dividers and add/removing them interactively. Is that what you're suggesting?

TheDuckCow commented 1 year ago

Should we continue to display the old (red/yellow) widget along with the new one?

This new visual should replace the old red/yellow placeholder visual. We can disable it, instead of fully deleting, in the short term, but later we can entirely remove.

...Meaning that we don't need to import any models. We could just continue employing the old methodology. But, do it directly in the GizmoPlugin.

Though I do like the idea of using immediate geometry, which feels more "fit for purpose", it's just a bit more work to actually create the models that way. Having a lot of immediate geometry also quickly slows things down, a problem faced by the Lane Segment visualization. So I'm also interested to see how this goes using meshes as part of interactive selection.

Yeah, this is the perfect use case for overlaying those blue lane dividers and add/removing them interactively. Is that what you're suggesting?

Yeah exactly (plus, much further down the line, maybe some very temporary immediate geometry sort of preview "shadow" of the area being expanded). For now we'd start with just the lane marker, but we can do this as a second step once we get the initial handle placement working.

We could create a single copy directly in the GizmoPlugin class and use its logic to position and show/hide it.

Yeah I like this idea 👍 let's see if we can pull that off

bdog2112 commented 1 year ago

Hey @TheDuckCow, the RoadPoint lane gizmo has been updated!

GIZMO FEATURES

GIZMO ISSUES

The implication is that it's impossible to reliably determine which object is the primary selection. Hence, it is difficult to consistently display a gizmo on the correct object in all situations.

Godot may redraw any gizmo at any time, whether its parent is selected or not and we don't want users altering deselected objects unintentionally. So, we have to make sure the Gizmo's redraw routine knows if it should draw handles each and every time it runs.

I've done my best to address these problems by hiding gizmos when nothing is selected. But, there is still an issue with multiple selections.

Since it's not possible to determine Godot's primary selection when multiple items are selected, it might be best to simply hide gizmos in that situation.

TTD

TheDuckCow commented 1 year ago

Great to see this progress! Would love it if you can go ahead and create a PR for the branch, even though it's in draft (just helpful to keep track). Happy to talk through what of this we can live on the call today.

Side note, I did get an error the first time opening the project on this current branch, and errors persisted after restarting.

Initial error (which caused a global godot popup saying the addon was disabled due to errors):

 Unable to open file: res://.import/gizmo_blue_handle.png-5b1155ef9bf6c3ffd6b3ab6d395f34ae.s3tc.stex.
 Failed loading resource: res://.import/gizmo_blue_handle.png-5b1155ef9bf6c3ffd6b3ab6d395f34ae.s3tc.stex. Make sure resources have been imported by opening the project in the editor at least once.
 Failed loading resource: res://addons/road-generator/gizmo_blue_handle.png. Make sure resources have been imported by opening the project in the editor at least once.
 res://addons/road-generator/road_point_gizmo.gd:13 - Parse Error: Can't preload resource at path: res://addons/road-generator/gizmo_blue_handle.png
 res://addons/road-generator/plugin.gd:5 - Parse Error: Couldn't fully preload the script, possible cyclic reference or compilation error. Use "load()" instead if a cyclic reference is intended.
Switch Scene Tab
 servers/visual_server.cpp:346 - Octahedral compression cannot be used to compress a zero-length vector, please use normalized normal values or disable octahedral compression
Road segs rebuilt: 6
Switch Scene Tab
 Cannot get path of node as it is not in a scene tree.
 (Node not found: "segments" (relative to "").)
 modules/gdscript/gdscript_functions.cpp:775 - Segments node path not found

After restarting (and re-enabling the plugin):

Road segs rebuilt: 6
Switch Scene Tab
 Cannot get path of node as it is not in a scene tree.
 (Node not found: "segments" (relative to "").)
 modules/gdscript/gdscript_functions.cpp:775 - Segments node path not found
TheDuckCow commented 1 year ago

Mild edit - it did start working fine actually for the most part, I just had to manually toggle the refresh roads on startup tick box (separate bug that this is even ever needed). So far, this is actually working quite well!