godot: intersect_shape not working with Area3D in @tool
Tested versions
Reproducible in v4.3.dev2.official [352434668]
System information
Godot v4.3.dev2 - Ubuntu 22.04.3 LTS 22.04 - X11 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 2060 (nvidia; 535.146.02) - Intel® Core™ i5-9400F CPU @ 2.90GHz (6 Threads)
Issue description
In the code below, I place collision nodes (under an Area3D) at each of the four boxes. The last should cause an intersection, but if one happens at all, it seems random. This is in a plugin/tool and I am trying to find a way to scatter meshes but avoid overlaps.
I have spent a week trying various ways (even using PhysicsServer3D) but nothing works. I have asked online and in the Godot Forums, but there has been no progress. I’m not 100% sure this is a bug, but I’m guessing it is.
The code is:
@tool
extends Node3D
## Area intersection isue
##
## Trying to make an Aread3D by using nodes and
## test for intersection with a box shape.
##
## Open the scene and click the bool Tog in the inspector
## Observe the printed output.
##
## I expect to see:
## *****************************
## one
## two
## three
## TEST HIT
## Bingo!
var A:Area3D
var state:PhysicsDirectSpaceState3D
@export var WTF:bool:
set(b):
WTF = false
await set_state()
await wtf()
func set_state():
state = null
await get_tree().physics_frame
if not state:
state = get_world_3d().direct_space_state
func wtf():
await create_area3d_node()
await node_probe()
func create_area3d_node():
print()
print("*****************************")
var _a = find_child("AREANODE")
if _a:
remove_child(_a)
_a.queue_free()
A = null
A = Area3D.new()
A.name = "AREANODE"
add_child(A)
A.set_owner(self.owner)
await get_tree().physics_frame
func node_probe():
var box:BoxShape3D
# make a shape, the same size as b
var poke = [$one, $two, $three]
for b in poke:
print(b.name)
box = BoxShape3D.new()
box.size = b.mesh.size
var newt:Transform3D = b.transform
var coll:CollisionShape3D
coll = CollisionShape3D.new()
coll.name = b.name
coll.transform = b.transform
coll.shape = box
A.add_child(coll)
coll.set_owner(A.owner)
await get_tree().physics_frame
#As per docs
var params:PhysicsShapeQueryParameters3D = PhysicsShapeQueryParameters3D.new()
var shape_rid = PhysicsServer3D.box_shape_create()
PhysicsServer3D.shape_set_data(shape_rid, $overlapper.mesh.size)
params.shape_rid = shape_rid
params.transform = $overlapper.transform
params.collide_with_areas = true
params.collide_with_bodies = false
print("TEST HIT")
var surrounds = state.intersect_shape(params, 6)
PhysicsServer3D.free_rid(shape_rid)
if surrounds:
print("Bingo!")
Steps to reproduce
Try the MRP below.
Minimal reproduction project (MRP)
https://gitlab.com/dbat/server_area_issue
Update
As requested, the code does work outside the editor. I have pushed the gitlab repo with that test code too. Output for reference:
one
two
three
TEST HIT
Bingo!
Latest
This was bumped to a proposal discussion. I started it here: https://github.com/godotengine/godot-proposals/issues/8963 (ETA, redid the proposal because I posted in the wrong dimension.)
Tentative solution
https://github.com/godotengine/godot-proposals/issues/8963#issuecomment-1910048689
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)
https://github.com/godotengine/godot-proposals/issues/8963#issuecomment-1910286572
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.
Update on RenderingServer.instances_cull_aabb
There’s a bug: https://github.com/godotengine/godot/issues/87709
About this issue
- Original URL
- State: open
- Created 5 months ago
- Comments: 28 (14 by maintainers)
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.
This isn’t entirely true.
PhysicsDirectSpaceState3D’sintersect_raydoes work in@toolscripts. In fact, the linked addon by HungryProton in this thread still works and makes use of it, and I’ve also usedintersect_rayin my own@toolscripts. You might come across some instances where it doesn’t auto-update, but it does work.Couple related issues: https://github.com/godotengine/godot/issues/43744 (fixed in master apparently) https://github.com/godotengine/godot/issues/82912
Sorry I overreacted.
Can we also start a conversation about support for intersect_X in the editor? If there’s a way for a tool/plugin to turn it on, use it, then turn it off, would that impact the editor badly?
For example, in my “Dabber” plugin, I need to send rays down to colliders to pick points where I will place a transform to go into a multimesh. I believe Hungy Proton’s Scatter plugin does the same. There are also a few plugins out now that allow painting on a landscape and all that requires these kinds of intersect functions.
I had opened an issue a while back related to my next scatter use-case: ( https://github.com/godotengine/godot-proposals/issues/7811#issuecomment-1750783242 )
I need to know where other things are before I place a new thing. In that thread I was asking about whether Godot had/could-have some API for spacial queries. 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.
I have heard another person talk about a plugin that drops physics objects to let them settle as a part of level design.
The reality is that some phyics must be accessible from plugins because levels and stuff are designed in Godot.
I had no clue some features were available because all features I tried personally didn’t work (and when someone else pointed that out, they were told it was by design)
Definitely in need of better documentation!
I just confirmed that it does work when you run it as a scene. (I made another scene with a button and script without
@toolto test). The output was as expected:Using the
@toolversion I get:I’ve had a good sleep and have nothing but respect for you devs. I am sure we’ll work something out.
Okay, we haven’t even established this is:
So please calm down, we don’t know what solution to apply for this, so don’t blow this out of proportion and have some patience 🙂
So the first step is for you to make sure this works outside of the editor, as a baseline
However I’d suggest first that you take a break and come back in a bit and see if someone has looked into it, before or after you’ve verified the code itself is correct, no need of reason to rush things
Rays work fine, as demonstrated above, shapes I’m not so sure about, so please have patience and we’ll see if someone has an answer or explanation regarding the physics engine and editor
Can you confirm this works in a running version of the game? And you haven’t configured things wrong or are using the methods wrong?
Yes, I am hurt. I have spent a long time developing my plugin. What do you expect? No warning. Nothing suggested. Indeed, the opposite: the code works. All fine until I get to intersect_shape.
Please, don’t see this as drama. I am being open and honest. If this is a thing, physics is banned in tools, then fine. But give us a clue and some kind of future. How do you expect plugins to progress?
I’ve contributed to HungryProton’s Scatter plugin on a handful of occasions. As you can see in these linked lines, the plugin registers physics objects and colliders with the physics server so that the collision tests can be done. Is it possible for you to use a similar technique for your plugin?
https://github.com/HungryProton/scatter/blob/6821b63a120f4c003da7e4d6f9ec28658e8337dc/addons/proton_scatter/src/scatter.gd#L555-L567
Suggestion for docs text:
"Note
This class is intended for use only at run-time. Writers of Plugins or tool-scripts should look at RenderingServer [link] for intersect methods that function in the editor."
“Plugins and tool-scripts: If you need intersection methods for bounding-boxes, convex shapes and rays, have a look at the methods that start with
instances_cullbelow, which will not impact performance of the editor. Note that they will not function at run-time, for that look at the PhysicsDirectSpaceState3D [link] class.”Complexities
If
PhysicsDirectSpaceState3D.intersect_ray ( PhysicsRayQueryParameters3D parameters )is going to remain active in the editor:rayrelated methods. It also makes ambiguous the split between in-editor and in-game methods.RenderingsServer.instances_cull_raymethod does not offer 2 and 3 above. (There would have to be a lot more filtering done in script to imitate the functionality.)It seems to me that for the
raymethods, the one in RenderingServer should be brought-up to the same level (and syntax) as the one in PhysicsDirectSpaceState3D.I have been searching around looking for projects that use the
cullmethods and so far I’ve not found any. It may be possible to rethink, re-form, rename and move the methods around without damaging existing code. Under a deprecation notice oc.Naming
On a user-level, it was surprising that these
instances_cullmethods were not in the same class as theintersect_methods. I am glad you guys found them, but the reason I did not is that the docs guided me to PhysicsDirectSpaceState3D.I had no reason to search the long list of methods in RenderingServer, and if I did I would not have noticed instances_cull as something akin to intersect_. Does that make sense?
It might be better to have all those methods in a similar family somehow, but naming things is hard and I defer to your experience.
I linked you above to where to open it, you can’t move it because it’s a different organization, follow the instructions here 🙂
(please make sure to put annotations between backticks to not tag accounts)
If it is a design choice, i would like to point that some way of enabling them would be great. For example, i was thinking about creating a simple tool to use physics to place objects on the editor, kind of like unreal or source does.
Perfectly fine. Please just make it obvious in the docs. I hate to think of the impact on others trying new things and falling into the same sitch.
I have a few problems with this:
@toolWhat am I to feel?
Can you offer me any hope? Gdextension perhaps? Anything? (https://github.com/HungryProton/scatter)
Scattering meshes (and multimeshes) is a much required need. Have you told @HungryProton that he’s sol with his plugin?
Please read this as a very serious make-or-break concern.