Timing Fixes

Discuss programming topics for the various GPL'd game engine sources.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Timing Fixes

Post by Spike »

vanilla QW actually copies all entities into the visedicts array, where NQ merely stores a pointer.
Q3 also makes a copy, but has explicit rentity_t types with all the stuff used by only the renderer. a bit better for threading the renderer that way, I suppose.
the client should not be drilling down to poses, poking the model file randomly like that will hurt cache - save that for the bit of code which will read the pointers to the data too (or vbo indexes... same thing, kinda). you also have the issue of potentially stale pointers to renderer-owned data within the client. especially if it points to a different model.

the other possibility is putting the interpolation in the client. fully. including vertex blending (if you don't have glsl).
this is quite relevent with skeletal model formats, where you're blending bones with many influences. with ragdoll you even need to bypass frames entirely. With glsl you might want to deal with those bones and animate the verticies themselves in glsl.
I'd say ragdoll should be part of the client, purely from the 'pure' perspective in that the only data you should read back from the renderer is constant stuff in the form of model data.
In fte, I support passing bone data to the renderer (in the form of a bonecount+bone pointer), which overrides any frame numbers. For skeletal models, if there's no bone pointer passed in then it does an implicit internal 'skel_build' call using the frame info passed in. Yes, you can call skel_build on other models than the one that's to be drawn, thereby importing frames from animation-only models like md5anim.
Whether you have some generic 'PrepForRendering'/'AddEntity' call or directly write/reuse raw entities and have the renderer do it doesn't really matter too much. The pain comes in freeing any such temporary bone memory.
All I really care about is that you don't cache anything in it for longer than a frame. :P

I hope baker doesn't mind that this isn't really about timing any more. :s
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Timing Fixes

Post by Baker »

Spike wrote:I hope baker doesn't mind that this isn't really about timing any more. :s
Really in a larger way, it is. :D When. Where. How.
mh wrote:For CL_LerpPoint interpolation:
- movement in the x and y directions doesn't lerp.
- movement in the z direction does lerp if x and y haven't moved, otherwise it doesn't.
- angles never lerp.
Does this fix the silly (jerky, stuttery ...) way scrags fall out of the air when they die like in demo1.dem? Just wondering.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
taniwha
Posts: 401
Joined: Thu Jan 14, 2010 7:11 am
Contact:

Re: Timing Fixes

Post by taniwha »

Baker: probably. Since I made everything lerped, scrags fall smoothly in QF. It's actually quite a strange feel after years of the stuttery movement.
Leave others their otherness.
http://quakeforge.net/
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Timing Fixes

Post by Baker »

taniwha wrote:Baker: probably. Since I made everything lerped, scrags fall smoothly in QF. It's actually quite a strange feel after years of the stuttery movement.
Probably not in your Feb 2012 release, right?
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
taniwha
Posts: 401
Joined: Thu Jan 14, 2010 7:11 am
Contact:

Re: Timing Fixes

Post by taniwha »

Indeed not. I did it in the last week or so. I plan on rolling out a release soonish.
Leave others their otherness.
http://quakeforge.net/
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Timing Fixes

Post by Baker »

A FitzQuake implementation of MH's transform lerp tweak (works great!):

I don't know what the "Angles never lerp" comment means (like the context ... if x and y changed? Didn't change? Always as in always (which doesn't sound right off hand).

Find this code ....
#if 1 // MH transform interpolation fix for Z so scrags fall nicely (when killed)
// Does not fix monsters on lifts and moving rise/fall all jerky (that's gotta be serverside I bet)
// Monsters moving and on platform probably move jerky too (that's gotta be serverside I bet)

// MH ... "if x and y didn't change, always lerp z; If x and y did change, do not lerp z"
if (d[0] || d[1]) // X or Y changed
lerpdata->origin[2] = e->origin[2]; // frac = 1
// TODO: "Angles never lerp" (if x and y haven't moved? Or IF they did?)
#endif
in this function of r_alias.c --> R_SetupEntityTransform

Code: Select all

/*
=================
R_SetupEntityTransform -- johnfitz -- set up transform part of lerpdata
=================
*/
void R_SetupEntityTransform (entity_t *e, lerpdata_t *lerpdata)
{
	float blend;
	vec3_t d;
	int i;

	// if LERP_RESETMOVE, kill any lerps in progress
	if (e->lerpflags & LERP_RESETMOVE)
	{
		e->movelerpstart = 0;
		VectorCopy (e->origin, e->previousorigin);
		VectorCopy (e->origin, e->currentorigin);
		VectorCopy (e->angles, e->previousangles);
		VectorCopy (e->angles, e->currentangles);
		e->lerpflags -= LERP_RESETMOVE;
	}
	else if (!VectorCompare (e->origin, e->currentorigin) || !VectorCompare (e->angles, e->currentangles)) // origin/angles changed, start new lerp
	{
		e->movelerpstart = cl.time;
		VectorCopy (e->currentorigin, e->previousorigin);
		VectorCopy (e->origin,  e->currentorigin);
		VectorCopy (e->currentangles, e->previousangles);
		VectorCopy (e->angles,  e->currentangles);
	}

	//set up values
	if (r_lerpmove.value && e != &cl.viewent && e->lerpflags & LERP_MOVESTEP)
	{
		if (e->lerpflags & LERP_FINISH)
			blend = CLAMP (0, (cl.time - e->movelerpstart) / (e->lerpfinish - e->movelerpstart), 1);
		else
			blend = CLAMP (0, (cl.time - e->movelerpstart) / 0.1, 1);

		//translation
		VectorSubtract (e->currentorigin, e->previousorigin, d);
		lerpdata->origin[0] = e->previousorigin[0] + d[0] * blend;
		lerpdata->origin[1] = e->previousorigin[1] + d[1] * blend;
		lerpdata->origin[2] = e->previousorigin[2] + d[2] * blend;

#if 1   // MH transform interpolation fix for Z so scrags fall nicely (when killed)
		// Does not fix monsters on lifts and moving rise/fall all jerky (that's gotta be serverside I bet)
		// Monsters moving and on platform probably move jerky too (that's gotta be serverside I bet)

		// MH ... "if x and y didn't change, always lerp z; If x and y did change, do not lerp z"
		if (d[0] || d[1]) // X or Y changed
			lerpdata->origin[2] = e->origin[2]; // frac = 1 
		// TODO: "Angles never lerp"  (if x and y haven't moved? Or IF they did?)
#endif

		//rotation
		VectorSubtract (e->currentangles, e->previousangles, d);
		for (i = 0; i < 3; i++)
		{
			if (d[i] > 180)  d[i] -= 360;
			if (d[i] < -180) d[i] += 360;
		}
		lerpdata->angles[0] = e->previousangles[0] + d[0] * blend;
		lerpdata->angles[1] = e->previousangles[1] + d[1] * blend;
		lerpdata->angles[2] = e->previousangles[2] + d[2] * blend;
	}
	else //don't lerp
	{
		VectorCopy (e->origin, lerpdata->origin);
		VectorCopy (e->angles, lerpdata->angles);
	}
}
taniwha wrote:Indeed not. I did it in the last week or so. I plan on rolling out a release soonish.
Was wondering, dealing with step movetype is a pain. I always like to look at others "homework". Actually, scrags aren't movetype_step ... so ... uh ... I guess I mean the U_NOLERP / U_STEP flag in general.
Last edited by Baker on Fri Jul 06, 2012 6:07 am, edited 3 times in total.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
taniwha
Posts: 401
Joined: Thu Jan 14, 2010 7:11 am
Contact:

Re: Timing Fixes

Post by taniwha »

Baker wrote:A FitzQuake implementation of MH's transform tweak (works great!):

Find this code ....
#if 1 // MH transform interpolation fix for Z so scrags fall nicely (when killed)
// Does not fix monsters on lifts and moving rise/fall all jerky (that's gotta be serverside I bet)
// Monsters moving and on platform probably move jerky too (that's gotta be serverside I bet)

// MH ... "if x and y didn't change, always lerp z; If x and y did change, do not lerp z"
if (d[0] && d[1]) // X or Y changed
lerpdata->origin[2] = e->origin[2]; // frac = 1
// TODO: "Angles never lerp" (if x and y haven't moved? Or IF they did?)
#endif
That && should be ||. Your current logic is actually "X and Y changed".
Leave others their otherness.
http://quakeforge.net/
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Timing Fixes

Post by Baker »

taniwha wrote:That && should be ||. Your current logic is actually "X and Y changed".
Fixed in above post and code.

(Thanks. A small glitch like that could have potentially been a major time waster to debug and really, really hard to re-create the circumstances of the problem without knowing the source.)
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Timing Fixes

Post by Baker »

Something unaddressed: What causes the rare "killer lifts" problems with a high fps in a NetQuake engine?
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Timing Fixes

Post by Spike »

the big pain with stepping monsters is that they can move based upon both movetogoal/walkmove, and velocity.
Theoretically you can just clear the U_STEP flag if its not onground/flying then the client knows which sort to use as they're mostly mutually exclusive.
I say mostly mutually exclusive because a stepping monster may be standing upon a moving platform, so you have the stepping nature of the monster on top, and the velocity based nature of the platform underneath pushing it a little every single server frame.
mh's solution works fine for things moving up and down, but I wonder how it reacts to trains. :P
taniwha
Posts: 401
Joined: Thu Jan 14, 2010 7:11 am
Contact:

Re: Timing Fixes

Post by taniwha »

Has anybody actually tried lerping U_STEP monsters? They actually look fairly good to me.
Leave others their otherness.
http://quakeforge.net/
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Timing Fixes

Post by Spike »

depends how you lerp them.
if you're lerping them from one network frame to another, then they'll be jerky. you need to lerp based upon the times they actually change, or it'll be motionless for about 6/7ths of the time.

fte lerps stepping things based upon the times the frame changes. this retains any foot sync in the original anims. it also guesstimates the interval based between about 10hz and 20hz, thus covering any quake/hexen2 differences.

fitzquake actually sends the time-till-next-think over the wire, which can be used for more accurate timings for stepping monsters.
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Re: Timing Fixes

Post by mh »

The big problem is that the protocol just doesn't have enough information to do this cleanly. Any solution that cares about retaining compatibility is going to be missing bits and pieces, so it's a matter of which bits and pieces it's least objectionable to be missing.

"Killer lifts" are caused by fps-dependent physics. Most entities in Quake are actually in free-fall most of the time, so they move down until blocked and then may or may not get additional friction/sliding applied depending on what blocks them. That's important to realise - I mentioned the first (YA) secret in e1m4 a while ago, and you really should check that out as it's a great illustration of this. What's happening there is that the plat is moving normally along it's assigned path, but the YA is free-falling down towards it. So the plat is not getting standard physics, the YA entity is. Same happens to a player on a lift - it's not just a visual glitch; it's deeply rooted in the physics code.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Timing Fixes

Post by Spike »

regarding the yellow armour on the plat, the yellow armour should not be in free-fall at any point. Its FL_ONGROUND should be set the whole time, if its not then you're just wasting cpu cycles.
*anything* sitting on top of a platform is meant to move with the platform, up+down+sideways. which is why trains move players sideways (due to absmin/absmax being slightly extended, anything on top is within the abs bounding box of the pusher).
The only way the armour can really free-fall is if its not able to follow the plat as it goes down, say a player standing on the edge of the plat ending up standing on some other surface instead, in which case it should get a new groundentity pretty quickly.
I notice that vanilla SV_TestEntityPosition considers the ogres as solid on that platform with respect to the armour, which can result in one or both of them starting to freefall instead of following the platform. Check the difference between SV_TestEntityPosition and SV_PushEntity regarding the solidity of the enity that is being pushed/tested. This bug won't affect players however.
I also notice that in vanilla, the onground flag gets cleared for non-player riding entities every frame, which really shouldn't be needed, and will indeed judder if the acceleration due to gravity is so small (due to low grav or high framerates) that it cannot catch up with the lift's motion/velocity within a single frame. As the downwards-moving plat *should* have moved the armour with it, the armour should be off-ground but with 0 units to fall, so even a tiny tiny amount of gravity/frametime should be enough to simply reset that onground flag, and that's all that should result from the armour's toss movement - gravity should not actually move it, only reassert that onground flag so its moved the next frame too, regardless of the speed of the platform. Thus this is really only an issue when combined with the prior bug.

FTE has a nice bug with hexen2 (portals at least, map tibet5 - 'Temple of Kalachakra'):
an entity sitting on top of an entity sitting on top of a pusher.
the pusher moves up. the entity in the middle cannot move upwards because it is blocked. this blocks the pusher.
this results in a puzzle peice (ie: a key) not being given to the player (noclip is required to complete this map in fte).
Quake's pusher code is woefully simplistic for this (actually, these are rotating pushers... but hey, same idea).
Post Reply