godotengine / godot

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

apply_torque_impulse() not working on a RigidBody2d that uses CollisionPolygon2d "Segments" build mode #69576

Open KevinStirling opened 1 year ago

KevinStirling commented 1 year ago

Godot version

v3.5.1.stable.official [6fed1ffa3], v4.0.beta7.official [0bb1e89fb]

System information

Windows 10, AMD 6800xt on 22.11.1 Adrenalin drivers, GLES3 & Vulkan

Issue description

Using a CollisionPolygon2d as the collision shape for a RigidBody2d, apply_torque_impulse() seems to have no effect while the Build Mode is set to "Segments". This is not an issue when using the "Solids" build mode.

The attached repro zip file is for 3.5.1, but this exists in 4.0 beta 7 aswell

Steps to reproduce

In project settings > physics 2d, set default gravity to 0, default gravity vector to (0, 0), and default linear and angular damp to 0.

Make a 2d scene, with a RigidBody2d that uses a CollisionPolygon2d as the collision shape.

On the RigidBody2d, disable Can Sleep. Attach a script to the node, and add some code that will apply a torque impulse.

extends RigidBody2D

var torque = 300

func _integrate_forces(state):
    if Input.is_action_pressed("ui_left"):
        apply_torque_impulse(torque)
    if Input.is_action_pressed("ui_right"):
        apply_torque_impulse(-torque)

On the CollisionPolygon2d, change the Build Mode to "Segments".

In debug menu, enable "Visible Collision Shapes"

Run the scene and nothing should happen when pressing the ui_left or ui_right keybinds. Changing the Build Mode to "Solids" and rerunning will then show the application of the torque impulse that is expected.

Minimal reproduction project

CollisionPolygon2dTest35.zip

rburing commented 1 year ago

This is related to https://github.com/godotengine/godot/issues/68068. In this case, applying a torque impulse requires (inverse) inertia to be set/nonzero:

https://github.com/godotengine/godot/blob/e82d66f23b987f9380b666179f25b44813509106/servers/physics_2d/godot_body_2d.h#L235-L237

The (inverse) inertia is by default computed based on the shapes:

https://github.com/godotengine/godot/blob/e82d66f23b987f9380b666179f25b44813509106/servers/physics_2d/godot_body_2d.cpp#L98

But the GodotConcavePolygonShape2D doesn't support this:

https://github.com/godotengine/godot/blob/e82d66f23b987f9380b666179f25b44813509106/servers/physics_2d/godot_shape_2d.h#L524

Using the "Segments" build mode on a CollisionPolygon2D creates such a GodotConcavePolygonShape2D.

This should be documented. In 4.0, a workaround is to set the inertia property on the RigidBody2D to 14084.51.

KevinStirling commented 1 year ago

Thanks for the in depth explanation! Are there plans to add support for applying torque like this to a GodotConcavePolygonShape2d? Or is this not desired for this type of physics object? It would be nice if the inertia was set correctly by default, but I'm not familiar enough with the physics server to know if that would mess with anything else.