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

Models stutter due to client side interpolation #3228

Open
SamVanheer opened this issue Jan 19, 2022 · 5 comments
Open

Models stutter due to client side interpolation #3228

SamVanheer opened this issue Jan 19, 2022 · 5 comments

Comments

@SamVanheer
Copy link

SamVanheer commented Jan 19, 2022

When Half-Life 1 was updated to handle studio model rendering in the client dll with SDK 2.0 a bug started occurring where studio models moved by other entities like func_tracktrain would stutter.

Here's a video that shows the stuttering as well as the expected behavior: video

The most likely cause is that the time value used by model rendering is being overwritten by an older time value used by the client side prediction code. The animation time values jump back and forth from the present to the past in a way that causes interpolation to sometimes interpolate to some point in the future and sometimes to some point in the past, causing the model to "pinball" between the past and future interpolated positions.

The cause of this is somewhere in the engine, not fixable in SDK code as-is. A workaround exists to disable interpolation in these cases to prevent the stuttering effect from occurring, originally provided by Uncle Mike on the HLFX forums: https://hlfx.ru/forum/showthread.php?s=&threadid=15&highlight=%C8%ED%F2%E5%F0%EF%EE%EB%FF%F6%E8%FF

(Unfortunately you need an account to access this thread)

The changes required are as follows:

Change this line:

pev->flags |= FL_MONSTER;

To this:

pev->flags |= FL_MONSTER | FL_FLY;

Change this line:

pev->flags |= FL_MONSTER;

To this:

pev->flags |= FL_MONSTER | FL_FLY;

(the same change is needed in Opposing Force's Black Ops Osprey code)

After this line:

CBaseEntity *m_pLink;// used for temporary link-list operations.

Add this:

/**
*	@brief Entity flags sent to the client in ::AddToFullPack
*/
byte m_EFlags = 0;

After this line:

DEFINE_FIELD( CBaseEntity, m_pGoalEnt, FIELD_CLASSPTR ),

Add this:

DEFINE_FIELD(CBaseEntity, m_EFlags, FIELD_CHARACTER),

After this line:

pev->sequence = 0;

Add this:

//Always interpolate tentacles since they don't actually move.
m_EFlags |= EFLAG_SLERP;

After this line:

int i;

Add this:

auto entity = reinterpret_cast<CBaseEntity*>(GET_PRIVATE(ent));

Change this logic:

halflife/dlls/client.cpp

Lines 1194 to 1201 in c7240b9

if ( !player &&
ent->v.animtime &&
ent->v.velocity[ 0 ] == 0 &&
ent->v.velocity[ 1 ] == 0 &&
ent->v.velocity[ 2 ] == 0 )
{
state->eflags |= EFLAG_SLERP;
}

To this:

if ((ent->v.flags & FL_FLY) != 0)
{
	state->eflags |= EFLAG_SLERP;
}
else
{
	state->eflags &= ~EFLAG_SLERP;
}

state->eflags |= entity->m_EFlags;

Change this logic:

for (i = 0; i < 3; i++)
{
modelpos[i] += (m_pCurrentEntity->origin[i] - m_pCurrentEntity->latched.prevorigin[i]) * f;
}

To this:

const auto pseqdesc = (mstudioseqdesc_t*)((byte*)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->curstate.sequence;

if ((pseqdesc->motiontype & STUDIO_LX) != 0 || (m_pCurrentEntity->curstate.eflags & EFLAG_SLERP) != 0)
{
	for (i = 0; i < 3; i++)
	{
		modelpos[i] += (m_pCurrentEntity->origin[i] - m_pCurrentEntity->latched.prevorigin[i]) * f;
	}
}

These changes restrict model interpolation to animations that have movement on the X axis and entities that have interpolation enabled, which is enabled for any entity that sets the FL_FLY flag. Entities can also force interpolation by setting the EFLAG_SLERP flag on CBaseEntity::m_EFlags.

Tentacles will not interpolate correctly when loading a save game made before these code changes were applied.

A better solution would be to identify the cause of the bug (likely the incorrect time values) and fixing that, but that would require an investigation and testing to verify that the fix doesn't break anything that may be depending on this buggy behavior somehow.

@di57inct
Copy link

Is this somehow related to the bug where if a player would stand on top of another crouching player his camera would stutter vertically?

@SamVanheer
Copy link
Author

Is this somehow related to the bug where if a player would stand on top of another crouching player his camera would stutter vertically?

I don't think so, this only affects the model's render position, not the player's camera position.

@di57inct
Copy link

Understood. Thanks.

@SamVanheer
Copy link
Author

Added additional step to fix monster_osprey not interpolating.

SamVanheer added a commit to twhl-community/halflife-updated that referenced this issue Mar 14, 2022
@SamVanheer
Copy link
Author

Added additional steps to fix monster_tentacle not interpolating.

SamVanheer added a commit to twhl-community/halflife-updated that referenced this issue Mar 28, 2022
hammermaps added a commit to sohl-modders/Updated-SOHL-1.2 that referenced this issue Apr 24, 2023
@SamVanheer SamVanheer reopened this May 23, 2023
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