Gizmo
Taking sone time off starting Thursday, here is what I could cook this short week before leaving.
Junctions, What Left and Why?
So, as I mentioned last week, one of the key missing parts in my game is the ability to generate junctions. It may sound stupid but without them road is just "straight" which would be lame for most players (although I still have a lot of fun driving on it personally), and I definitely don't want to generate junction models manually.

Once junctions are implemented, I will be able to fully generate a complex road system that hopefully will be interesting to navigate (surely not as interesting as handcrafted race tracks, but I have hopes). The missing parts for a MVP will then "just" be audio and UI. Full player-facing scripting, more game modes, hand-crafted maps, multiplayer (why not?), etc. can all be handled later.

I already have some of the right-side junctions working (rendering model only) and now I need to extend this to left-side junctions and collision models. Finally will come intersections. That's still a lot of work and debugging ahead.
Gizmo Handles
So far I have been debugging road generation with those ImGui sliders. Kinda funny for a minute but it gets old trying to adjust the various road waypoints to test a specific configuration. So, I decided to implement Gizmo handles, those colorful geometric shapes used in game editors to translate and rotate (and sometimes scale) entities in a map.

Of course I spent the extra time thinking about how I would later reuse the same ECS elements for a potential in-game map editor, or maybe even an actual game editor if I ever make more than one game with my engine. All while attempting to support different kinds of Gizmo Handles, because my junction problem already had interesting needs: 4 transforms and 1 angle.
So far, the generic code is as follows:
struct AHandle
{
virtual float getDistance(Ray const& mouseRay) const;
virtual void beginDrag(Ray const& mouseRay);
virtual void drag(Ray const& mouseRay);
virtual void endDrag();
};
struct GizmoContext
{
std::weak_ptr<AHandle> hoveredHandle;
std::weak_ptr<AHandle> activeHandle;
};
struct GizmoComponent
{
std::vector<std::shared_ptr<AHandle>> handles;
};
struct GizmoSystem
{
// Responsible for updating active handle if any,
// else looping through handles in GizmoComponents and
// setting the closest to mouse's ray as hovered or active.
};While more specific modules will implement custom gizmo handle behaviors:
struct AxisTranslateHandle : public AHandle;
struct AxisRotateHandle : public AHandle;
struct TransformGizmoComponent
{
std::shared_ptr<AxisTranslateHandle> translateX;
std::shared_ptr<AxisTranslateHandle> translateY;
std::shared_ptr<AxisTranslateHandle> translateZ;
std::shared_ptr<AxisRotateHandle> rotateX;
std::shared_ptr<AxisRotateHandle> rotateY;
std::shared_ptr<AxisRotateHandle> rotateZ;
}
struct TransformGizmoSystem
{
// If active handle comes from TransformGizmoComponent,
// process requested change (e.g. move related entity).
// In any case update and display TransformGizmoComponent's handles.
};
I am not super satisfied yet with how a handle is stored in both a GizmoComponent (for GizmoSystem to process) and a specific component (to be processed when manipulated by user) of the same entity, but this will do for now.
Debugging Junctions With Gizmo Handles
Enough blah blah, here is what you have been waiting for (right?), junction generation debugging with control Gizmos:
Just this quick test already makes a lot of bugs pop in my very early implementation of road junctions, and you may notice that Gizmo Handles are a bit finicky and hard to "grab", but this will be it for this week as I have a plane to catch soon.
----
There is an alternate timeline where bogosort works every time and nobody knows why. ~ Some Guy On The Internet
