-
-
Notifications
You must be signed in to change notification settings - Fork 21k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PhysicsDirectSpaceState] Impossible to retrieve shape if owner_id has more than one shape #57452
Comments
At the risk of not understanding how the shapes are indexed here, this seems a bit odd:
So this function looks like what one would need to get the appropriate "child index" in the p_owner's vector of shapes, however if we look at how they are added:
we can see that My intuition tells me that shape_owner_get_shape_index should look something like the following instead:
Now I'm not sure if the RID is what we would be comparing here, but hopefully you see what I'm trying to get across. |
This is a documentation issue. The return values of The |
Here's the method I use to obtain the shape from # Usage:
# var results = get_world_2d().direct_space_state.intersect_shape(params)
# for result in results:
# var shape_info = get_shape_info(result)
func get_shape_info(result: Dictionary) -> Dictionary:
var collider = result["collider"] as CollisionObject2D
var shape_index = result["shape"] as int
var owner_id = collider.shape_find_owner(shape_index)
var shape_count = collider.shape_owner_get_shape_count(owner_id)
var shape: Shape2D
var shape_transform: Transform2D = collider.global_transform * collider.shape_owner_get_transform(owner_id)
for i in range(shape_count):
var index = collider.shape_owner_get_shape_index(owner_id, i)
if index == shape_index:
shape = collider.shape_owner_get_shape(owner_id, i)
break
return {"shape": shape, "transform": shape_transform} This is kind of a mess... I don't know how we can improve this without breaking compatibility. The terms "shape id" and "shape index" are treated as interchangeable in the current API, which is pretty misleading ( Improving documentation is probably the best we can do for now. |
Godot version
3.4.2.stable [Bullet Physics]
System information
Win10
Issue description
I've been doing some custom collision stuff, and that has involved using
intersect_shape
fromPhysicsDirectSpaceState
.Now according to the documentation for this we have the following:
To retrieve the actual
Shape
, I have this code running:In this case,
s_idx
is 500. When I get theshape_owner_id
, it's also 500. This is expected since I'm using regular CollisionShapes, and they appear to create one owner_id for one Shape.However it all breaks down in the final line -
shape_owner_get_shape
actually expects the index of the shape in its own internal array of shapes, and not the actual shape index that Godot generates for a Shape.Simple solution, right? Change the last line to:
var colshape = col.collider.shape_owner_get_shape(shape_owner_id, 0);
and it all works fine. Awesome!
So what's the issue?
Well according to the documentation on
CollisionObject
, we can read the following:Now this is a problem! If we have more than one Shape per
owner_id
, then how do we know what index to pass intoshape_owner_get_shape()
?For proof that this function is not behaving as documented, I've taken this directly from Godot's C++ source:
That
shapes
member is a simple Vector, and not a mapping of any kind.This means there's either an oversight or a bug somewhere. If
intersect_shape
were to return a local array offset index, then we would never be able to get theowner_id
. But in its current state, we'll never be able to find our Shape if the owner has more than one, assuming that the shape was created with a shape index that's higher than the length of the internally stored array of owned shapes.Steps to reproduce
I've attached a minimal example project to demonstrate the following steps:
Create a bunch of CollisionShapes on a StaticBody
When the game starts, remove the first owner_id (since one owner_id will be created for each shape)
Grab the now-unreferenced shape and add it to a different owner_id [There will now be one owner_id with two shapes]
Perform a intersect_shape against the shapes in the scene
Try and find a way to obtain the 2nd shape from the owner_id containing multiple shapes using the result of the intersect_shape, the shape index it provides and the CollisionObject.shape_owner_* functions.
You'll quickly notice it's impossible using the methods given to us.
Of course, there's probably a hackaround by comparing instance_ids, but this seems like a bug or an oversight and I believe it requires some attention.
===
MINIMAL REPRO PROJECT
Please see
multiple_shapes.gs
to see what I'm doing regarding setting up collision shapes and their owners.Then take a look in
reproduce.gd
to see where the problems lie with intersect_shapes.Minimal reproduction project
shape_id_problem.zip
The text was updated successfully, but these errors were encountered: