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

3D KinematicBody not affected by area gravity in Bullet Physics #15554

Closed
LeonardMeagher2 opened this Issue Jan 10, 2018 · 5 comments

Comments

Projects
None yet
5 participants
@LeonardMeagher2

LeonardMeagher2 commented Jan 10, 2018

Godot version:
aebdc4c2126789b915b0fb753f0594fec0f0226d

OS/device including version:
Windows 10 64bit

Issue description:
In the Godot physics engine I'm able to get the KinematicBody's direct state and get it's total gravity it's being affected by so I can make kinematic bodies respond to areas with gravity points and gravity in general

var state = PhysicsServer.body_get_direct_state(get_rid())
var gravity = state.get_total_gravity()

I thought I was able to do this before in the Bullet Physics engine but tested today and the gravity is just always Vector3( 0.0, 0.0, 0.0)

Steps to reproduce:

  • Create a KinematicBody with this script attached
extends KinematicBody

func _physics_process(delta):
	var state = PhysicsServer.body_get_direct_state(get_rid())
	print(state.get_total_gravity())
  • In project's settings set Physics > 3D > Physics Engine = Bullet
  • run the scene. It should print (0, 0, 0)

If you switch the 3D physics to GodotPhysics it should print (0, -9.8, 0)

Minimal reproduction project:
Kinematic3dGravityTest.zip

@ghost ghost added bug topic:physics labels Jan 10, 2018

@ghost ghost added this to the 3.0 milestone Jan 10, 2018

@kubecz3k

This comment has been minimized.

Member

kubecz3k commented Jan 15, 2018

@akien-mga akien-mga modified the milestones: 3.0, 3.1 Jan 24, 2018

@Dar13

This comment has been minimized.

Contributor

Dar13 commented Feb 10, 2018

I ran into this on Linux as well and poked around the source to find the cause. Seems to be because the Bullet glue classifies it as a static body with no mass and Bullet doesn't compute gravity for rigid bodies with no mass. The way the Bullet built-in, and seemingly perpetually buggy, btKinematicCharacterController handled this was by re-implementing gravity during the preStep phase of the world simulation that took a gravity vector and had it influence the velocity vector before translation.

I tried replicating the functionality in a GDScript using the _physics_process phase, but ran into some edge cases that made realistic gravity somewhat difficult. Namely knowing when to reset your initial state so your instantaneous velocity is accurate, and how to get it to work with move_and_slide since move_and_slide scales with delta time for you. Those are probably able to be overcome with more work, but that's what I ran into in the few minutes of prototyping I spent on working around this issue.

Of course, adding a pseudo-gravity vector to the final velocity vector on every frame (assuming you tune the gravity vector so it feels right) could work for some cases.

Any input from a more regular dev on what the desired outcome is or how to approach solving this? I'd like to start contributing and figure this could be a good issue to cut my teeth on.

@AndreaCatania

This comment has been minimized.

Member

AndreaCatania commented Feb 10, 2018

I completely forgot this issue, and I will look on this soon.

@Dar13 Also in both engines (Godot and Bullet physics) the kinematic body gravity is not handled by engine since the kinematic body is meant to be moved "Manually".

So it has no sense to handle its gravity inside the physics engine, and it's care by the developer handle it.

handled this was by re-implementing gravity

This is the correct way to handle it, if you don't want control it just use a rigidbody in character mode.

Instead @LeonardMeagher2 is talking about the fact that is not possible to take the gravity "that should affect the kinematic body" from its state object. It's not so difficult to fix it.

I'll keep you updated

@Dar13

This comment has been minimized.

Contributor

Dar13 commented Feb 10, 2018

So it has no sense to handle its gravity inside the physics engine, and it's care by the developer handle it.

Alright, that's what I kept drifting towards while writing that comment.

Instead @LeonardMeagher2 is talking about the fact that is not possible to take the gravity "that should affect the kinematic body" from its state object. It's not so difficult to fix it.

I know you said you'd look at it, but I looked into it anyways as an exercise to get familiar with the codebase. Came up with the attached patch and tested it with both the given project and with an Area with space override set to "Combine" and the gravity changed accordingly.

Patch:

diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index 96a53f9f8..83c5f7b2d 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -832,7 +832,7 @@ void RigidBodyBullet::on_exit_area(AreaBullet *p_area) {
 
 void RigidBodyBullet::reload_space_override_modificator() {
 
-       if (!is_active())
+       if (!is_active() && mode != PhysicsServer::BODY_MODE_KINEMATIC)
                return;
 
        Vector3 newGravity(space->get_gravity_direction() * space->get_gravity_magnitude());

If this seems acceptable to you, I can make a PR tomorrow.

@AndreaCatania

This comment has been minimized.

Member

AndreaCatania commented Feb 10, 2018

@Dar13 Yep, exactly it will fix the issue! Feel free to make the PR, and also thanks you!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment