+1 vote

I am in need of a way to check collision between simple objects (think box, sphere, cone, etc.) at runtime without running an entire physics simulation.
These objects are just proxies used for calculation once and never added to any scene (this makes sense in the context of the project).
The proxies need to be "placed" in a way that none of them collide with each other, hence the need for the collision check.

So far, everything I found about Godot collision leads back to having to run a physics server, in which you might then run queries, get signals, etc.
This is way more than what I need, and also way more complex to setup** than necessary.

AABBs won't work for me since they are only boxes and not rotated (I guess I could use only boxes, but the fixed rotation is a dealbreaker).

** I assume I could somehow use PhysicsServer directly to create a custom area, with custom bodies, with custom shapes... and then run a query via the DirectSpaceState, and finally remove all of that manually again after being used exactly once. But I'm not even sure if that would work instantly or if I'd need to give the PhysicsServer a frame to process, etc. And also, this would very much seem like swatting flies with a sledgehammer.

What I need is something simple along the lines of:

var collisionDetails :Dictionary = {}
someBox3D.collides_with(someSphere3D, collisionDetails)

Unrelated to anything else going on in any scene at runtime, not needing any force/impact/etc information and since those objects only exist for a millisecond, without the need to add them to/remove them from any servers. It would have to be as reduced and fast as possible, basically just 3D maths.

Does something like this exist in Godot or would I have to roll my own, maybe using libccd?

Further explanation:
The reason why I cannot use the normal physics system here is that I need to do hundreds of these calculations in a very short time, as this is a performance critical part of the program. Having to wait for even a short while after "adding" each proxy before checking with another one is not acceptable.

in Engine by (56 points)
edited by

2 Answers

+1 vote
Best answer

In the end, I created a GDNative module for this:

https://github.com/TheSHEEEP/godotccd

With this, you can easily check collisions between boxes, spheres and cylinders unrelated to anything in Godot's physics world and scenes. And much faster, too.

by (56 points)
0 votes

I believe the Area node is what you're looking for:

https://docs.godotengine.org/en/3.1/classes/class_area.html

To prevent it from interacting with any other collision objects, set it to a different collision layer from anything else it shouldn't be interacting with. Areas currently don't work with concave trimesh statics, but it sounds like you're just going to be using other areas with the built-in primitive shapes. In which case, you're good to go.

Use get_overlapping_areas() or get_overlapping_bodies() to return an array of the nodes overlapping it. Otherwise, use overlaps_area(Node area) or overlaps_body(Node body) to check for a specific collision.

The performance cost of what you're trying to do sounds negligible. Trying to do this in any more custom way is, as you put it, "fly swatting with a sledgehammer". It's probably not worth your time. I am curious why you think using something like this is complex to set up. It seems like you might be overthinking this a bit, but I don't know the context of your use case.

by (60 points)

I specifically meant the custom Physics setup with an own physics space, bodies, etc. at runtime with "more complex than necessary".
Sure it isn't that complex compared to other things, but if all you want is to answer a simple "does this collide with that" question unrelated to any visible scene, any kind of elaborate setup to achieve that seems too complex.

Areas could be what I'm looking for, but I'm worried about this part:

For performance reasons (collisions are all processed at the same time) this list is modified once during the physics step, not immediately after objects are moved.

Now, I'm not planning to move anything around, but this could be interpreted as requiring a frame after something was added to even function. But what I'm planning is to add a number of those proxy objects (potentially a very large number, think dozens/hundreds) - I can't allow the engine to run for a frame after each of those adds before checking for collisions. It all has to work immediately. As I said, I actually just need the maths here, not really any kind of engine/scene/node functionality.

Also, there is no overthinking when performance is crucial (and it is very much in this context, unfortunately). "Optimizing performance later" is a mantra that lead to all those horribly perfoming games that have been released lately, because clearly somebody was not thinking about performance when implementing something, but that's really getting off topic...

That "frame" is a physics tick. It's set to match a standard frame rate of 60/sec by default, but is independent of framerate. You can increase it in the project settings if you need more precision.

But, you're being extremely cryptic about what you're trying to do for some reason. To the point where it's hard to recommend anything. You're now firmly in the "XY Problem" zone.

Please tell us what you're trying to do in a broader sense (how would a player describe this feature?), and tell us what you've tried.

"Optimizing performance later" is a mantra that lead to all those horribly performing games that have been released lately, because clearly somebody was not thinking about performance when implementing something

Off topic? Maybe. It does tell me that you know a lot less about game development than you think.

That "frame" is a physics tick. It's set to match a standard frame rate of 60/sec by default, but is independent of framerate. You can increase it in the project settings if you need more precision.

So in other words, some time would need to pass after I add an area before I could check if another added area collides with it? Even if I lowered the rate to a single millisecond, that would mean a delay of half a second for 500 of those proxies and that's not even including the time needed for the actual check.
That's not acceptable for my use case, so I don't think Area is what I'm looking for.
I was going to try my hand at a GDNative module at some point anyway, so why not implement libccd if it adds some functionality I need... might be fun.

But, you're being extremely cryptic about what you're trying to do for some reason. To the point where it's hard to recommend anything. You're now firmly in the "XY Problem" zone.

You know nothing about the bigger problem I'm trying to solve, and somehow that leads you to assume I must be trying to tackle it wrongly, simply because your suggested solution won't work? I have spent months planning through many aspects of my project and broke this particular one down to the point where I could ask a specific question as I don't know the engine well enough, yet.

Though I agree I should have added that I need to do a large number of these calculations in an as-quick-as-possible manner, which is why I do not want to wait for any kind of tick/frame after each and every add. I'll add that to the question.

Rest assured, this is not an XY Problem situation. I'm not trying to do premature optimization here, this simply is an extremely performance sensitive part of the project and every millisecond saved will help.
But really, if you believe me or not is none of my concern, I'm not here to debate approaches or seek approval.

This is also not a discussion forum and I was wrong in making that off-topic remark which got you triggered. We seem to disagree on how to properly develop high-quality software, but this isn't the place for that discussion.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.