godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.15k stars 97 forks source link

Physics, Intersection and Editor Plugins #8963

Open donn-xx opened 9 months ago

donn-xx commented 9 months ago

Describe the project you are working on

Advised to open a proposal here by https://github.com/godotengine/godot/issues/87429#issuecomment-1908761733 Hope I did it right (this time!)

Overview

Can we have a conversation about support for "intersect_X" in editor plugins?

For example, in my "Dabber" plugin, I need to send rays down to mesh surfaces to pick points where I will place a transform to go into a multimesh. I need to know where other things are before I place a new thing. In Related to https://github.com/godotengine/godot-proposals/issues/7811 I asked about whether Godot has an API for spacial queries (in plugins). I only realized recently that the state.intersect_shape() method is pretty much already that; hence my bewilderment at it not working in the editor.

Describe the problem or limitation you are having in your project

I wish to use the intersects functions in the PhysicsDirectSpaceState3D class while in a plugin/tool

  1. intersect_shape() which currently does not work.
  2. intersect_ray() which does work but I am now not at all sure it's even supposed to, nor how long it will.

Examples of use

  1. https://github.com/spimort/TerraBrush
  2. https://github.com/HungryProton/scatter
  3. My own Dabber plugin https://gitlab.com/dbat/godot-scatterator (wip now stalled)
  4. Godot Official is even working on a terrain plugin/feature. https://github.com/godotengine/godot-proposals/issues/6121

What use is terrain if one cannot populate it? The reality is that some physics needs to be accessible from Godot plugins.

Physics is disabled in the editor

Quote from @smix8 at https://github.com/godotengine/godot/issues/87429#issuecomment-1908754228

PhysicsServers are disabled by the EditorNode inside the Editor for both performance reasons and to not have shape conflict with the ray picking done by the Editor Plugins for that node and the Editor Viewport. This means all the more advanced physics stuff that requires an active physics server doing step() updates every physics process do not work in the Editor. As seen by the code comment that the Editor does not run full physics simulation is intentional and by current design.

Most users do not know that when they work with physics nodes inside the editor that there is nearly never physics from those nodes. The "physics" is almost always added by an Editor Plugin for that node and the plugin only adds the bare minimum to keep the object picking functional inside the editor. This means basic stuff like raytesting works because the editor plugin adds a similar "picking" shape as the node has.

Now enabling full physics inside the Editor is not a good idea. There are already many instances of users complaining about editor performance, e.g. all TileMap users at some point. Having full physics run inside the Editor for all objects would make all those users hardware melt and explode. Godot has many users with toaster hardware that need to be considered and supported.

This brings use to ... even if Godot would change this, as an addon maker expecting users to run a full physics simulation so that basic addon functionality works is never a good idea. Basic object placement or ray-testing can be done entirely with simple trigonometry checks not requiring physics at all. E.g. Geometry3D functions and some AABBs to improve performance if you have many objects that your addon needs to care about.

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

Replying to some of that quote

@smix8

Now enabling full physics inside the Editor is not a good idea. There are already many instances of users complaining about editor performance, e.g. all TileMap users at some point. Having full physics run inside the Editor for all objects would make all those users hardware melt and explode. Godot has many users with toaster hardware that need to be considered and supported.

What if a plugin could have a "Go" button which then:

  1. Starts the "physics" (like intersect_shape).
  2. Runs its loop and does it's job, like scattering meshes.
  3. Stops the "physics".

So it need not be on all the time; only while doing a user-initiated job.

@smix8

This brings use to ... even if Godot would change this, as an addon maker expecting users to run a full physics simulation so that basic addon functionality works is never a good idea. Basic object placement or ray-testing can be done entirely with simple trigonometry checks not requiring physics at all. E.g. Geometry3D functions and some AABBs to improve performance if you have many objects that your addon needs to care about.

Picture this:

  1. A terrain made of multiple chunks of meshes (with their colliders).
  2. Other meshes overlaid to build levels and such. It's getting complicated. Meshes all over the place.

Now, please explain how with trig and Geometry3D you can distribute points across all of that such that:

  1. Only the UP direction is involved.
  2. The points don't overlap (below some bounds)
  3. Certain areas do not receive those points at all.
  4. Surfaces underneath (or within) other meshes are ignored.

And that's just to start. I do not believe that it's as simple as the quoted. And, if it is, why can that not be wrapped in an API and made available to users of Godot?

Also, what is the difference between this "simple" approach and what Godot physics is already doing?

Paths to progress

  1. Is there something "simple" within Godot's exisiting "physics" that can be plucked-out and used in plugins via scripting?
  2. Is there any way to use C++ in GDExtension for plugin dev to get access to what Godot can already do (ito "physics")?
  3. Is it perhaps possible for a plugin to play a scene (ie F5) so that it is not in the editor and can then access all the powers required and write some kind of data file out for the plugin to use when back in the editor? This sounds awkward, but might be a solution.

Thanks.

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

I have nothing for this section

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

It seems not. The Editor seems to be the nub of the problem.

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

I am not qualified to know.

AThousandShips commented 9 months ago

which does work but I am now not at all sure it's even supposed to, nor how long it will.

The intersect_ray method is intended to work and is going to remain, it's used by the editor 🙂

Also, what is the difference between this "simple" approach and what Godot physics is already doing?

Quite extreme, the physics engine does a lot of tracking of objects moving, intersecting each other, etc. which isn't needed in the editor, but takes a lot of processing

I haven't dug into the ways the editor simulates these things without the physics engine but I suspect doing ray casting is much easier than shapes, and might not require some of the backing data structures

A lot can be done with just ray-casts, it's how the "snap to floor" method in the editor works for example

donn-xx commented 9 months ago

The intersect_ray method is intended to work and is going to remain, it's used by the editor 🙂

Okay. That's good to know.

Also, what is the difference between this "simple" approach and what Godot physics is already doing?

Quite extreme, the physics engine does a lot of tracking of objects moving, intersecting each other, etc. which isn't needed in the editor, but takes a lot of processing

Fair enough. Is there a case for an editor-available API for non-moving intersections?

A lot can be done with just ray-casts, it's how the "snap to floor" method in the editor works for example

In my use-case I need to know whether a volume (say an AABB) is empty or not. That's why intersect_shape would be perfect.

AThousandShips commented 9 months ago

Fair enough. Is there a case for an editor-available API for non-moving intersections?

Not at the present as far as I know, I'd say if there was it'd be in there

The question here for evaluation and investigation is what ways the current system handles this, and what would be needed to add this, for example the use of the BSP system and space processing, this isn't cheap though, and would be largely limited in use, so it's not necessarily worth it generally

I will dig into the physics of the editor when I find the time and see how it accomplishes this feature

Edit: One thing you can do to accomplish a lot of intersection features, with some trickery as well, is using culling in the rendering server, this is used in some editor plugins as far as I can tell (it even says: This function is primarily intended for editor usage. For in-game use cases, prefer physics collision., so probably the appropriate solution, do test and see)

smix8 commented 9 months ago

The functions that AThousandShips linked are basically the API to query the visual rendering scenario for its spatial info.

E.g. what visuals with a position are inside some convex plane shape, what intersects with a raycast. Not using the physics engine that only has information about physics shapes, but the rendering that only has information about visual geometry and other render objects like lights.

With the ids returned those ids can be used with the ObjectDB / GlobalScope.instance_from_id () to get the actual SceneTree object behind that id, e.g. the node.

It is not something that should be done at runtime, hence the "Use physics for in-game" hint, because it forces stalls and updates on the RenderingServer. For inside the Editor that performance is not much of a concern as long as you do not fire those functions every single frame like mad.

donn-xx commented 9 months ago

Thanks for that info. I will look into it. Perhaps we could add something like what smix8 and AThousandShips just posted to the docs so that other plugin devs don't take the wrong turn into state.intersect_etc.

donn-xx commented 9 months ago

I have run into a problem with instances_cull_aabb — should I open a new issue, or continue here?

ETA - new issue here: https://github.com/godotengine/godot/issues/87709

Calinou commented 9 months ago

I have run into a problem with instances_cull_aabb — should I open a new issue, or continue here?

If it's a bug, please open an issue on the main Godot repository. See also https://github.com/godotengine/godot/issues/39197.