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

Player gets stuck on diagonal geometry due to float imprecision #3586

Open
AltimorTASDK opened this issue Nov 24, 2023 · 4 comments
Open

Player gets stuck on diagonal geometry due to float imprecision #3586

AltimorTASDK opened this issue Nov 24, 2023 · 4 comments

Comments

@AltimorTASDK
Copy link

Subtracting N(V dot N) isn't enough to ensure velocity/endpos is no longer directed towards the surface after float rounding. This is especially noticeable at high FPS where you have more chances to hit unlucky coordinates while sliding.

The original Quake 2 code passes an overbounce of 1.01 to PM_ClipVelocity to hack around this, but GoldSrc changed overbounce to 1 with no alternative solution.

Source Engine fixes it with the following check at the end of CGameMovement::ClipVelocity:

// iterate once to make sure we aren't still moving through the plane
float adjust = DotProduct( out, normal );
if ( adjust < 0.0f )
{
	// min this against a small number (but no further from zero than -DIST_EPSILON) to account for crossing a plane with a near-parallel normal
	adjust = MIN( adjust, -DIST_EPSILON );
	out -= ( normal * adjust );
}
@AltimorTASDK
Copy link
Author

Demonstration:

2023-11-24_13-53-59.mp4

@pierow
Copy link

pierow commented Nov 25, 2023

I'd like to see this fixed as well, but I'm not sure if the proposed solutions fix it. I just tried both in my mod and am still getting the issue. Then again, I think I've had this issue with diagonal walls manifest in a couple of ways, so maybe it does fix it in some cases.

I tried debugging this recently and from my testing narrowed it down to the PM_PlayerTrace call in this line returning different results for both server and client even when on a listen server. I haven't had the chance to dig deeper yet.

trace = pmove->PM_PlayerTrace (pmove->origin, end, PM_NORMAL, -1 );

Notably, this issue only happens when above 99fps, and then scales with fps.

@AltimorTASDK
Copy link
Author

This happens at <100fps, but it’s less likely you end up in an unlucky spot along the wall.

Traces may differ due to networked coordinate quantization. DIST_EPSILON is 1/32 for Source’s quantization, may be different for goldsrc.

@AltimorTASDK
Copy link
Author

Changing the < 0.0f to <= 0.0f to account for rounding towards zero seems to handle all cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants