jdolan / quetoo

Quetoo ("Q2") is a free first person shooter based on id Tech2. GPL v2 license.
http://quetoo.org
204 stars 28 forks source link

Rotating BSP models have collision issues #587

Closed jdolan closed 3 years ago

jdolan commented 3 years ago

Lava Tomb is a great test case for this, as it has a func_rotating and a func_door_rotating, both near each other.

Riding the func_rotating wheel of death will produce lots of jitter for the player's view origin.

Attempting to walk onto the func_door_rotating in its rotated position (from the red armor) will cause the player to get hung up and eventually fall through the door into the lava.

Not sure what is going on here. Perhaps the bounds of rotated inline models need to be expanded a bit to prevent clipping errors? I think Quake2 had some code to spread them by 1 unit in all directions, and I'm not sure that we still have that code.

It should be noted that when the rotators are in their original positions, they clip just fine.

@Paril this feels like something up your alley. Would you have time to take a look at this?

Paril commented 3 years ago

Honestly, I think this issue just needs to be titled "pmove/trace precision is busted".

There's a few different issues at play, and this is a subject I've been trying to figure out for a long time.

The first issue is related to getting stuck in walls. Currently, we have two mechanisms to prevent this from happening:

Both Q2 nor Q3 have the bugs we have with movement. In Q2, player positions are snapped to integers, meaning that player position traces always start on integers, and for some reason that just ends up working. They have the downside, though, of players drifting towards a certain axis, because of the truncation and loss of precision. Q3, however, stores everything as floats, and for some reason does not suffer from any of these issues.

When you approach a wall and "clip" against it (like sliding against a wall at an angle) and note your position, you will (usually) slide inwards on your position in very small precision steps (like 0.0001), until the system eventually finds you "all_solid" and pushes you back out. Note that this is a valid trace endpoint, but that endpoint ends up becoming all_solid after clipping against the plane.

I scanned Quake III's PMove and, despite bringing over many fixes from Q3, I'm still at a loss as to why Quake III's pmove seems perfect whereas ours suffers from these very strange bugs.

jdolan commented 3 years ago

f328b3bcc5f8c80871ec80db9ce42bde75e2ee4d was committed against this.

Paril commented 3 years ago

This seems to fix a bunch of PMove-related issues, but, a few still remain. The jitter from the giant rotator is gone, at least.

I did notice another interesting piece of code in Quake III Arena's source. See here: https://github.com/id-Software/Quake-III-Arena/blob/master/code/qcommon/cm_trace.c#L1184 This seems to deal with tracing and rotating bboxes, and is a bit of code we don't have.

An interesting optimization in Q3A: https://github.com/id-Software/Quake-III-Arena/blob/master/code/qcommon/cm_trace.c#L212 the first 6 sides of a brush in Q3A's BSP are always axial, and those are tested by the Vec3_BoxIntersect check (they do it by hand above this big block), but they skip the first 6 sides since they only need to test the remainder. That'd be something nice to bring over.

They also have a note on their transformed box trace about incorrect behavior on rotations: https://github.com/id-Software/Quake-III-Arena/blob/master/code/qcommon/cm_trace.c#L1436

Paril commented 3 years ago

I can confirm that this likely has nothing to do with TransformedBoxTrace (as in, the matrix code) - I re-implemented it using q2pro's methods, and the issues were the same.

I'm going to investigate the pusher code next.

Paril commented 3 years ago

Made a bit of headway on this one.

The issue with the Red Armor rotator on LavaTomb is because of Cm_EntityBounds. It's not returning a proper abs_min/abs_max for the mover. The bit that you get stuck in is not included in the bounds returned, so it's not traced against until you get stuck inside of it. You can verify this by expanding the "max" by * 2 - the trace works as expected, but bmodel's abs are so large that you're needlessly testing traces. Exactly why or when this broke, I don't know. Is the server sending bad abs_min/abs_max? Is the client calculating it incorrectly?

The issue with the giant rotator, however, is a bit more baffling. I haven't yet been able to figure out what's with this one.

jdolan commented 3 years ago

For posterity.

image

This looks good to me. I'm able to run onto the func_door_rotating from the red armor on Lava Tomb. I'm able to walk, run and crouch across the large func_rotating on Lava Tomb as well. Let's call this done!