godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.26k stars 101 forks source link

Ability in GridMap to get cell position of collision shape hit by raycast #12636

Open andris1 opened 2 weeks ago

andris1 commented 2 weeks ago

Describe the project you are working on

A grid-based rpg.

Describe the problem or limitation you are having in your project

If I have an object positioned at 0,0,0 that has a 4x4x4 collision shape, raycasting the object will not get me the cell position it's at.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

It would be great if there was a way to get to the cell when the object's collision shape is not constrained to the cell.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Not sure, raycast result could also return cell position?

If this enhancement will not be used often, can it be worked around with a few lines of script?

I am unaware of a workaround.

Is there a reason why this should be core and not an add-on in the asset library?

This is about core gridmap functionality.

smix8 commented 2 weeks ago

The physics engine does not know what a GridMap is, and the GridMap barely cares about what physics engine exists, and that separation is important. So that the generic physics ray tests return anything from GridMap directly is out of the question.

So what could be actually done?

Well, theoretically the GridMap could have a function with a physics body RID and physics shape RID parameter as input that returns the rasterization cell id when found. It would require a new internal mapping for at least the physic shape RID to GridMap rasterization cell id as you can't just "good luck" loop search over all octants and cells to find those if you want any performance.

Such a mapping does not come for free so this proposal would be only do-able by causing a GridMap performance and memory regression. That is why it would need to be made entirely optional and disabled by default, aka even more user settings and more documentation required.

Castro1709 commented 2 weeks ago

In addition am totally sure this can be done already. for example getting the collision point, converting it to the grid cords and adjust if needed using the collision normal.

Nodragem commented 2 weeks ago

It would require a new internal mapping for at least the physic shape RID to GridMap rasterization cell id as you can't just "good luck" loop search over all octants and cells to find those if you want any performance. Such a mapping does not come for free so this proposal would be only do-able by causing a GridMap performance and memory regression.

I thought the data structure needed an overhaul as it is difficult to find what's under the cursor at the moment.

If I have an object positioned at 0,0,0 that has a 4x4x4 collision shape, raycasting the object will not get me the cell position it's at.

In terms of the collision shapes, ideally (maybe one day), Gridmap should optimise the shapes by merging them into bigger blocks (e.g. 10 adjacent cubes into 1 big rectangular shape). In that scenario, we would not be able to use the collision shape to find an item.

I would say the best is to really support multicell items, as in: storing the size of an items, so that we can detect which item in occuping the cell.

This being say, to support multicell items would also allow to have an option "avoid overlap", which in fact, could make my proposal to have a brush spacing setting obsolete: https://github.com/godotengine/godot-proposals/issues/9612

smix8 commented 2 weeks ago

I thought the data structure needed an overhaul as it is difficult to find what's under the cursor at the moment.

Yes, but also no related to this proposal here that is not about straight cell picking but collision picking. Not every GridMap cell has collision, I would even go as far and say that most GridMaps are not used with collision as it is creates very low performance and quality collision.

Even among the projects that do use collision with GridMap, how many of them require actual ray picking like this proposal? Adding mapping collision automatically for a cost when most projects do not need it sounds wrong in my book and that is why it imo needs to stay optional, e.g. be a bool toggle on the GridMap.

In terms of the collision shapes, ideally (maybe one day), Gridmap should optimise the shapes by merging them into bigger blocks (e.g. 10 adjacent cubes into 1 big rectangular shape). In that scenario, we would not be able to use the collision shape to find an item.

In general GridMap needs to be 100% functional without anything from physics. So all generic features that involve geometry checks should work without every touching anything from the PhysicsServer if the check is not physics related. E.g. using physics for object picking as the goto to pick cells is a non-option for GridMap. That is the hacky way how people can do it in their own addons but not in the core engine.

TileMap is already trying that in Godot 4.5 with the collision quadrant baking. Let's see how that turns out and how much spacebar heating problems it attracts before we try that in 3D for GridMap. Baking physics body quadrants is trivial to implement with CSG/Manifold lib, but not trivial to do performant depending on what is the user input or expectations. Never underestimate the feature roadblock that can be caused by spacebar heaters united, not everyone just uses "blocks" or accepts processing delays, else there wouldnt be so many issues open about "why does my raycast not hit the not yet existing collision of a fresh spawned GridMap/TileMap".