Skip to content
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

_integrate_forces / KinematicCollision3D bug #85561

Open
prominentdetail opened this issue Nov 30, 2023 · 9 comments
Open

_integrate_forces / KinematicCollision3D bug #85561

prominentdetail opened this issue Nov 30, 2023 · 9 comments

Comments

@prominentdetail
Copy link
Contributor

Godot version

4.2 rc 6 and newer

System information

windows 10

Issue description

I've attached a minimum reproduction project.
The KinematicCollision3D seems to not work the same after 4.2 rc 5.. In rc 6 and newer version it is broken.

rc5:
rc5

rc6:
rc6

Steps to reproduce

Run example project in rc5 or older, compare to rc6 and newer.

Minimal reproduction project

RigidBody Character Bug.zip

@prominentdetail
Copy link
Contributor Author

I narrowed the issue down to this recent change that causes the issue:
a3278c7
When I revert that change, it works fine.

@akien-mga
Copy link
Member

CC @mihe

@mihe
Copy link
Contributor

mihe commented Nov 30, 2023

Yeah, I've spoken to @prominentdetail elsewhere already. I'm looking at it.

(Also, the mentions of "rc5" and "rc6" are meant to say "beta5" and "beta6" respectively.)

@mihe
Copy link
Contributor

mihe commented Nov 30, 2023

@prominentdetail Are you sure that a3278c7 is the offending commit? Reverting that commit shouldn't make any difference as far as 3D physics is concerned, since the force_update_transform() that was replaced in that commit had largely the same behavior anyway. It was also merged between 4.2-beta6 and 4.2-rc1, which wouldn't line up with you seeing a difference between 4.2-beta5 and 4.2-beta6.

When bisecting I'm finding #84799 (aka 6415006) is where this behavior changed, which makes more sense, since that one was merged between 4.2-beta5 and 4.2-beta6.

I can't speak to whether the regression itself is a valid one just yet though. I need to take a closer look at why this would affect body_test_motion of all things.

@prominentdetail
Copy link
Contributor Author

@mihe

I'm not sure- maybe I am not referencing the right commit, but when I commented out these lines from the latest version, it works:


void RigidBody3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) {
	lock_callback();

	if (GDVIRTUAL_IS_OVERRIDDEN(_integrate_forces)) {
		_sync_body_state(p_state);

		//Transform3D old_transform = get_global_transform();
		GDVIRTUAL_CALL(_integrate_forces, p_state);
		//Transform3D new_transform = get_global_transform();

		/*if (new_transform != old_transform) {
			// Update the physics server with the new transform, to prevent it from being overwritten at the sync below.
			PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_TRANSFORM, new_transform);
		}*/
	}

	_sync_body_state(p_state);
	_on_transform_changed();

	if (contact_monitor) {
		contact_monitor->locked = true;

@mihe
Copy link
Contributor

mihe commented Nov 30, 2023

Ah, right. Removing the code is different from a revert. Then you effectively end up reverting #84799 (aka 6415006) in this case, and not #84924 (aka a3278c7).

@mihe
Copy link
Contributor

mihe commented Dec 4, 2023

Just to give a minor update here: I've come to understand what the problem is here, and it breaks down to something quite fundamental about the intended purpose of _integrate_forces.

I've been pondering over this for a few days now, trying to think of how to best fix this, but I think I'll just end up submitting multiple PRs and start some kind of discussion about which might be the best approach.

As far as your specific problem is concerned, @prominentdetail, by commenting out that code you showed above you are effectively turning your "body will sink into floor when landing" workaround into a no-op, since any transform changes you make in _integrate_forces will be overwritten in that _sync_body_state below. So if commenting out that code works for you in your actual project, then you might as well just remove that workaround altogether, which should let you use Godot 4.2-stable as-is.

I also get the feeling that your workaround maybe wasn't doing what you hoped it would, as you (in 4.1) would end up setting the linear velocity for this physics step, but you'd actually end up setting the transform (in the physics server) on the next physics step, which is why your character keeps falling down in that repro (in 4.1) when it rightfully should come to a dead stop as soon as it touches the ground. You can achieve the proper effect (in 4.1) by changing state.transform instead of transform.

@prominentdetail
Copy link
Contributor Author

prominentdetail commented Dec 4, 2023

@mihe , thanks- I can confirm that 4.2stable as-is works if I just remove the workaround in my main project. I think I remember that the workaround didn't really solve the issue entirely anyway, and I had to do some other things to make stuff work how I wanted it to. That is interesting to know about the difference between state.transform and transform. Is that still the case with 4.2? So if I understand- state.transform will change the current step whereas transform will change the next step?

@mihe
Copy link
Contributor

mihe commented Dec 4, 2023

Is that still the case with 4.2? So if I understand- state.transform will change the current step whereas transform will change the next step?

Yes and no. This is what unfortunately changed/broke in 4.2, and which requires further discussion on how to fix properly.

The physics engine in Godot is always one step ahead of the idle tick (and the rendering), and prior to #79977 the state parameter in _integrate_forces essentially served as the input for this next physics frame, without affecting the current physics frame. But now since #79977 we are pulling that state input back into the current physics frame and essentially mixing the two physics frames together, causing these weird problems.

So reverting #79977 and everything that followed from that is one solution to all this, but it re-introduces other weird and unintuitive behaviors, hence why some bigger discussion needs to be had.

I'll try to have it written up properly within the next couple of days.

@KoBeWi KoBeWi modified the milestones: 4.3, 4.x Aug 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants