RID and CSGBox3D when RayCast isn't being accurate on a NavMesh

Godot Version

4.5

Question

I’m working on a prototype builder game. Think any SIM or Tycoon style game where you place paths. I then have visitors walking on these paths. Since the field is one large navmesh but I only want visitors on the paths (and I’m using a grid placement format), I put Navigation Obstacles (with a hidden CSGBox3D) on each grid point where there is not a path,

When I move the cursor to an “empty” square and click to place a path it is instantiated and the NavObstacle in that location is queue freed thus deleting it. I rebake the nav mesh and the visitors can now walk on this space. All of this is working good except one problem.

I use a raycast from the camera to the mouse position to determine the coordinates, then divide/multiply to get them to an integer for that location (thus forcing grid placement). In closer areas this seems to work well but further away on the map the placement of the path and the mouse position can be substantially off. I determined that it is the (hidden) CSGBox3D that is actually catching the raycast and thus returning coordinates that don’t always match the mouse position… could be literally half a grid position off of where I am expecting.

To fix this I’ve tried a variety of things with groups, collision layers and PhysicsRayQueryParameters3D exclude of the RIDs I don’t want to catch the ray. The layers don’t seem to want to play as I need them to interact with everything else (especially visitors) and I’ve yet to find a combination that plays nice. The groups seem to be ignored although this could be because the top level NavObstacle is part of the group. I don’t know if this group assignment applies to child nodes (the CSGBox3D) or not. At this point the ray seems to be ignoring my group.

So the RID seems like the most likely candidate however it is assigning the RID of the NavObstacle, not the CSGBox3D. I’m trying to get the RID but get_rid() is not part of the CSGBox3D. It supposedly is of the mesh for the CSG but get_mesh also isn’t working.

global.rids_to_ignore.append(child_node.get_mesh().get_rid())

So, any ideas? a different approach? At this point everything (in terms of game play) works, it’s just the alignment that is off which feels sloppy in the game. I’m trying to tighten this up.

Upon further experimenting I was able to achieve the accuracy via more detailed collision layers and masks. Effectively, after much trial and error, I put the CSGBox3D nodes on layer 2 and told the ray to ignore layer 2 (in code) and this seems to be working good. Other nodes/scenes are told to acknowledge layer 2 and thus the visitors are walking around and following the NavObstacle avoidance rules.

var ray_query = PhysicsRayQueryParameters3D.create(from, to)
var binary_mask = 0b00000000_00000000_11111111_11111101
ray_query.collision_mask = binary_mask