godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.29k stars 21.05k forks source link

PhysicsDirectSpaceState3D.intersect_shape does not work when project setting 'physics/3d/run_on_seperate_thread' enabled #67478

Open kdada opened 2 years ago

kdada commented 2 years ago

Godot version

4.0.beta.custom_build [dc4b61659]

System information

Windows 11, Vulkan

Issue description

I want to check all obstructions between 2 players. But the code only works properly when 'physics/3d/run_on_seperate_thread' is off. When it on, intersect_shape sometimes returns correct dictionaries and sometimes returns an empty array.

My Scene: A plane with 2 RigidBody3D [Sphere] and 1 StaticBody3D [Box]. Place the StaticBody3D between the 2 RigidBody3D. image

Steps:

Code:

func _physics_process(_delta: float) -> void:
        # The SeparationRayShape is (0, 0, 1),so we need to look at the direction from player_j to player_i
    var vector_looking_at = player_i.global_position - player_j.global_position
    var length = vector_looking_at.length()
    var matrix = Transform3D.IDENTITY
    matrix = matrix.scaled(Vector3(length, length, length))
    var hasOtherNode = false

    # handle only the direction is not up.
    if vector_looking_at.x != 0 || vector_looking_at.z != 0:
        matrix = matrix * matrix.looking_at(vector_looking_at)
        matrix = matrix.translated(player_i.global_position)

        var space_state  = self.get_world_3d().direct_space_state
        var ray_rid = PhysicsServer3D.separation_ray_shape_create()
        PhysicsServer3D.shape_set_data(ray_rid, {
            "length": 1,
        })
        var parameter = PhysicsShapeQueryParameters3D.new()
        parameter.shape_rid = ray_rid
        parameter.transform = matrix
        var nodes = space_state.intersect_shape(parameter)
        PhysicsServer3D.free_rid(ray_rid)

        for n in nodes:
            if !str(n.collider.name).begins_with("Player"):
                hasOtherNode = true 
                break

        print(player_i.name, " ", player_j.name, " ", nodes, " ", parameter.transform)

When I run it with 'physics/3d/run_on_seperate_thread' disabled, all checks are correct:

Player1302453714 Player1473868966 [{ "rid": RID(2765958938630), "collider_id": 27531412664, "collider": Wall5:<StaticBody3D#27531412664>, "shape": 0 }, { "rid": RID(28630251995144), "collider_id": 33067893983, "collider": Player1473868966:<RigidBody3D#33067893983>, "shape": 0 }] [X: (4.495505, 0, 0), Y: (0, 4.495499, 0.007342), Z: (0, -0.007342, 4.495499), O: (0, 0.556648, -3.168828)]
Player1302453714 Player1473868966 [{ "rid": RID(2765958938630), "collider_id": 27531412664, "collider": Wall5:<StaticBody3D#27531412664>, "shape": 0 }, { "rid": RID(28630251995144), "collider_id": 33067893983, "collider": Player1473868966:<RigidBody3D#33067893983>, "shape": 0 }] [X: (4.48489, 0, 0), Y: (0, 4.484884, 0.007342), Z: (0, -0.007342, 4.484884), O: (0, 0.556648, -3.172246)]
Player1302453714 Player1473868966 [{ "rid": RID(2765958938630), "collider_id": 27531412664, "collider": Wall5:<StaticBody3D#27531412664>, "shape": 0 }, { "rid": RID(28630251995144), "collider_id": 33067893983, "collider": Player1473868966:<RigidBody3D#33067893983>, "shape": 0 }] [X: (4.474407, 0, 0), Y: (0, 4.474401, 0.007342), Z: (0, -0.007342, 4.474401), O: (0, 0.556648, -3.175621)]

When I run it with 'physics/3d/run_on_seperate_thread' enabled, some checks returns [].

Player1474220143 Player699497387 [{ "rid": RID(2765958938630), "collider_id": 27531412664, "collider": Wall5:<StaticBody3D#27531412664>, "shape": 0 }, { "rid": RID(33423435497480), "collider_id": 35903243545, "collider": Player699497387:<RigidBody3D#35903243545>, "shape": 0 }] [X: (2.449536, 0, 0), Y: (0, 2.449535, -0.000789), Z: (0, 0.000789, 2.449535), O: (0, 0.557248, -1.09872)]

Player1474220143 Player699497387 [] [X: (2.450304, 0, 0), Y: (0, 2.450304, -0.000789), Z: (0, 0.000789, 2.450304), O: (0, 0.557248, -1.099295)]
Player1474220143 Player699497387 [] [X: (2.451061, 0, 0), Y: (0, 2.451061, -0.000789), Z: (0, 0.000789, 2.451061), O: (0, 0.557248, -1.099862)]
Player1474220143 Player699497387 [] [X: (2.451811, 0, 0), Y: (0, 2.451811, -0.000789), Z: (0, 0.000789, 2.451811), O: (0, 0.557248, -1.100422)]

Player1474220143 Player699497387 [{ "rid": RID(2765958938630), "collider_id": 27531412664, "collider": Wall5:<StaticBody3D#27531412664>, "shape": 0 }, { "rid": RID(33423435497480), "collider_id": 35903243545, "collider": Player699497387:<RigidBody3D#35903243545>, "shape": 0 }] [X: (2.452552, 0, 0), Y: (0, 2.452552, -0.000789), Z: (0, 0.000789, 2.452552), O: (0, 0.557248, -1.100976)]

Player1474220143 Player699497387 [] [X: (2.453283, 0, 0), Y: (0, 2.453283, -0.000789), Z: (0, 0.000789, 2.453283), O: (0, 0.557248, -1.101523)]
Player1474220143 Player699497387 [] [X: (2.454005, 0, 0), Y: (0, 2.454005, -0.000789), Z: (0, 0.000789, 2.454005), O: (0, 0.557248, -1.102063)]
Player1474220143 Player699497387 [] [X: (2.454718, 0, 0), Y: (0, 2.454718, -0.000789), Z: (0, 0.000789, 2.454718), O: (0, 0.557248, -1.102596)]

Player1474220143 Player699497387 [{ "rid": RID(2765958938630), "collider_id": 27531412664, "collider": Wall5:<StaticBody3D#27531412664>, "shape": 0 }, { "rid": RID(33423435497480), "collider_id": 35903243545, "collider": Player699497387:<RigidBody3D#35903243545>, "shape": 0 }] [X: (2.455422, 0, 0), Y: (0, 2.455422, -0.000789), Z: (0, 0.000789, 2.455422), O: (0, 0.557248, -1.103123)]
Player1474220143 Player699497387 [{ "rid": RID(2765958938630), "collider_id": 27531412664, "collider": Wall5:<StaticBody3D#27531412664>, "shape": 0 }, { "rid": RID(33423435497480), "collider_id": 35903243545, "collider": Player699497387:<RigidBody3D#35903243545>, "shape": 0 }] [X: (2.456118, 0, 0), Y: (0, 2.456118, -0.000789), Z: (0, 0.000789, 2.456118), O: (0, 0.557248, -1.103643)]

Steps to reproduce

See Issue description

Minimal reproduction project

study-godot-67478.zip

rburing commented 2 years ago

Please attach the minimal reproduction project.

kdada commented 2 years ago

@rburing I uploaded the minimal reproduction project.

rburing commented 2 years ago

If you create the separation ray shape once instead of re-creating it every frame, then it works:

var ray_rid: RID

func _enter_tree():
    ray_rid = PhysicsServer3D.separation_ray_shape_create()
    PhysicsServer3D.shape_set_data(ray_rid, {
        "length": 1,
    })

func _exit_tree():
    PhysicsServer3D.free_rid(ray_rid)

Still we should investigate why your way didn't work.

kdada commented 2 years ago

@rburing Thanks for your solution. It works!

Calinou commented 2 years ago

Related to https://github.com/godotengine/godot/issues/60322.

Sarah-Duck commented 2 months ago

We're still getting this issue on Godot 4.3 RC1, it appears to be the only thing stopping us from enabling threaded physics. We're using a ShapeCast3D node instead of intersect_shape however.