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.

image

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)

Most upvoted comments

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.

physics_active

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.

There is no physics in the editor by design.

This isn’t entirely true. PhysicsDirectSpaceState3D’s intersect_ray does work in @tool scripts. In fact, the linked addon by HungryProton in this thread still works and makes use of it, and I’ve also used intersect_ray in my own @tool scripts. 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

some physics features are available

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!

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.

some physics features are available

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!

So the first step is for you to make sure this works outside of the editor, as a baseline

I just confirmed that it does work when you run it as a scene. (I made another scene with a button and script without @tool to test). The output was as expected:

*****************************
one
two
three
TEST HIT
Bingo!

Using the @tool version I get:

*****************************
one
two
three
TEST HIT

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

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:

  • A limitation in the engine and not user error
  • If it is a limitation as a bug, or a design choice
  • how to proceed

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?

ome physics features are available, some only in certain ways

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?

You can use the function, the function is not going away, it’s just not going to return what you expect it to. The physics engine does not run in editor by design, as it would negatively affect performance.

I have a few problems with this:

  1. It’s not said in the docs, afiact
  2. I have spent an unpaid year developing my plugin that relies on intersect_ray in a @tool
  3. You are dismissing all of that with a few words

What 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.

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:

  1. PhysicsDirectSpaceState3D : Add a Note

"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."

  1. Then, over in RenderingServer, in the Description add:

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_cull below, 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:

  1. It causes a weird doubling of ray related methods. It also makes ambiguous the split between in-editor and in-game methods.
  2. The PhysicsRayQueryParameters3D are vital to the in-editor use of that function.
  3. The Dictionary returned by it is also vital
  4. The RenderingsServer.instances_cull_ray method 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 ray methods, 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 cull methods 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_cull methods were not in the same class as the intersect_ 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.

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?

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.

You can use the function, the function is not going away, it’s just not going to return what you expect it to. The physics engine does not run in editor by design, as it would negatively affect performance.

I have a few problems with this:

  1. It’s not said in the docs, afiact
  2. I have spent an unpaid year developing my plugin that relies on intersect_ray in a @tool
  3. You are dismissing all of that with a few words

What 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.