Nasty interpolation bug - and fix!
Moderator: InsideQC Admins
13 posts
• Page 1 of 1
Nasty interpolation bug - and fix!
I suppose most people have implemented some variant on the old QER interpolation tutorials, but there is an incredibly nasty bug in them which you won't really notice owing to the way Quake handles memory.
The cause of this is the fact that Quake reuses entities; so if you gib a zombie, it will reuse the zombie entity but switch it's model to h_zombie. Of course, the old interpolation data for the zombie will reference pose numbers that the h_zombie model doesn't have, and so you'll have a stray pointer for a period of one frame until things settle back down. As Quake's memory is one big contiguous block, this won't matter too much - you'll just have some invalid data in there for that one frame (unless you're really tight on memory), but if you do any work on changing the memory system (such as to full dynamic with no limits) you'll begin to be bitten.
The fix is really simple, just find the CL_ParseUpdate function (in cl_parse.c), and look for the block starting "if (model != ent->model)". You'll want to add this code somewhere in the block:
That's about it; I'm not certain if all of these are needed, but when switching models it's probably better to start with a totally clean slate.
The cause of this is the fact that Quake reuses entities; so if you gib a zombie, it will reuse the zombie entity but switch it's model to h_zombie. Of course, the old interpolation data for the zombie will reference pose numbers that the h_zombie model doesn't have, and so you'll have a stray pointer for a period of one frame until things settle back down. As Quake's memory is one big contiguous block, this won't matter too much - you'll just have some invalid data in there for that one frame (unless you're really tight on memory), but if you do any work on changing the memory system (such as to full dynamic with no limits) you'll begin to be bitten.
The fix is really simple, just find the CL_ParseUpdate function (in cl_parse.c), and look for the block starting "if (model != ent->model)". You'll want to add this code somewhere in the block:
- Code: Select all
// if the model has changed we must also reset the interpolation data
// pose1 and pose2 are critical as they might be pointing to invalid frames in the new model!!!
ent->frame_start_time = 0;
ent->frame_interval = 0;
ent->pose1 = ent->pose2 = 0;
ent->translate_start_time = 0;
ent->origin1[0] = ent->origin1[1] = ent->origin1[2] = 0;
ent->origin2[0] = ent->origin2[1] = ent->origin2[2] = 0;
ent->rotate_start_time = 0;
ent->angles1[0] = ent->angles1[1] = ent->angles1[2] = 0;
ent->angles2[0] = ent->angles2[1] = ent->angles2[2] = 0;
That's about it; I'm not certain if all of these are needed, but when switching models it's probably better to start with a totally clean slate.
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
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
ugh i got to get back to engine exparaments soon again, the last time i used pheniox's interpolation tutorial it had this strange effect with the between map shots [the part that shows you the kills secrets time], it had this kind of cutting off stuf, like some parts of the level wee fine, but most of it was clipping and all the entityes [like dead stuff] wasent showing :S i dont know what i did.
but right now im working onsome kind of a mod [got some weapons in, and the nailgrunt [separate from solder.qc, has a nailgrunt.qc and i got it on a map along with quakeguy and the quakeguy.qc]
but right now im working onsome kind of a mod [got some weapons in, and the nailgrunt [separate from solder.qc, has a nailgrunt.qc and i got it on a map along with quakeguy and the quakeguy.qc]
bah
- MeTcHsteekle
- Posts: 399
- Joined: Thu May 15, 2008 10:46 pm
- Location: its a secret
Yeah, there's lots of things wrong with that code.
It was great for it's time, and a massive step above what vanilla Q1 did, but it still needs a good thorough working over; it's over 8 years old, after all. Bugs come out in the field.
The positional interpolation should be in CL_RelinkEntities rather than in R_RotateForEntity for starters; just so much cleaner and less hacking around special situations required.
Animation interpolation is probably better calculated at load time (especially now that memory is no longer a pressure); expand the verts x3 or x4 and fill in the interpolated verts.
Muzzleflashes.
And this bug, of course...

It was great for it's time, and a massive step above what vanilla Q1 did, but it still needs a good thorough working over; it's over 8 years old, after all. Bugs come out in the field.
The positional interpolation should be in CL_RelinkEntities rather than in R_RotateForEntity for starters; just so much cleaner and less hacking around special situations required.
Animation interpolation is probably better calculated at load time (especially now that memory is no longer a pressure); expand the verts x3 or x4 and fill in the interpolated verts.
Muzzleflashes.
And this bug, of course...
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
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
mh wrote:Muzzleflashes.
Don't forget the problem that chaingun / miniguns have too, given that they rotate...
Another annoyance I've noticed is that when switching weapon models, a lot of engines with interpolation have an annoying tendancy to display the first frame of a model before switching to whatever frame it was on the previous model. (hence destroying the effect of doing quake2 style weapon changes. i.e. weapon gets putaway down, new weapon gets pulled out and up.)
Too bad there isn't some script system where you could like, tell quake the name of the model, then give it a list of frame ranges / frames where it's not allowed to interpolate.
-

Dr. Shadowborg - InsideQC Staff
- Posts: 1110
- Joined: Sat Oct 16, 2004 3:34 pm
Also I have noticed that large angle changes that are interpolated create a noticeable spin especially when I respawn, or go into observer mode. So, i've added this...
in GL_RMAIN.C
in R_RotateForEntity
in GL_RMAIN.C
in R_RotateForEntity
- Code: Select all
// always interpolate along the shortest path
//R00k: don't interpolate angles > 90???
if (VectorLength(d)< 90)
{
for (i=0 ; i<3 ; i++)
{
if (d[i] > 180)
d[i] -= 360;
else if (d[i] < -180)
d[i] += 360;
}
glRotatef (ent->angles1[1] + (lerpfrac * d[1]), 0, 0, 1);
if (!shadow)
{
glRotatef (-ent->angles1[0] + (-lerpfrac * d[0]), 0, 1, 0);
glRotatef (ent->angles1[2] + (lerpfrac * d[2]), 1, 0, 0);
}
}
else
VectorCopy (ent->angles2, ent->angles1);
- r00k
- Posts: 1110
- Joined: Sat Nov 13, 2004 10:39 pm
I seem a bit late to the thread but I have question about the interpolation tutorials mh was talking about: are they available anywhere?
Ken Thompson wrote:One of my most productive days was throwing away 1000 lines of code.
Get off my lawn!
-

dreadlorde - Posts: 268
- Joined: Tue Nov 24, 2009 2:20 am
dreadlorde wrote:I seem a bit late to the thread but I have question about the interpolation tutorials mh was talking about: are they available anywhere?
Late but ...
http://quakewiki.net/archives/qer/tutor ... rial1.html
Lately I've been thinking about interpolation and software renderers. I've looked through the ToChris engine source code (available @ quaddicted.com/engines ) and the software renderer is heavily rewritten.
I am certain I ran across a conservative engine partial interpolation like aguirRe WinQuake or JoeQuake's WinQuake renderer, but at the moment I can't seem to locate it. I think it was motion interpolation only.
I'll probably continue to examine the ToChris engine and see if I can isolate the interpolation. That plus skybox support are things that interest me quite a bit.
At least in my head, it doesn't seem like interpolation in a software renderer should be any harder than in OpenGL ... but maybe I'm just oversimplifying MH's commentary (with Metlslime ?) about alternate interpolation ideas.
The night is young. How else can I annoy the world before sunsrise?
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
I've done frame interpolation in software Quake but haven't released the code.
If memory serves all of the changes are confined to one d_ file, and you have to switch a small bit of asm to C. I'll dig it out this evening.
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
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
FTE had interpolation in its software renderer.
The biggest pain is probably the assembler. Which is hand optimised, and unreadable, not only because it uses the x87 in more than a few places, but yeah, the asm functions can be replaced with their C equivelents.
The engine actually has two methods of drawing models (hence why software rendering was prefered over gl rendering for some time - bigger players, I think). You probably don't actually need to interpolate all paths.
One obscure thing to ensure is correct is bbox aproximations. If the model is completely on-screen, frustum checks are ignored. This means that if your bbox is a single frame and not the max size, you can get obscure crashes when the assumed bbox size is smaller than the actual size with it interpolating near the edge of the screen. Off by 1 pixel = crash.
Tbh, I don't really remember much more.
Hurrah for mh.
The biggest pain is probably the assembler. Which is hand optimised, and unreadable, not only because it uses the x87 in more than a few places, but yeah, the asm functions can be replaced with their C equivelents.
The engine actually has two methods of drawing models (hence why software rendering was prefered over gl rendering for some time - bigger players, I think). You probably don't actually need to interpolate all paths.
One obscure thing to ensure is correct is bbox aproximations. If the model is completely on-screen, frustum checks are ignored. This means that if your bbox is a single frame and not the max size, you can get obscure crashes when the assumed bbox size is smaller than the actual size with it interpolating near the edge of the screen. Off by 1 pixel = crash.
Tbh, I don't really remember much more.
Hurrah for mh.
- Spike
- Posts: 2892
- Joined: Fri Nov 05, 2004 3:12 am
- Location: UK
Never doing a trivial_accept is enough for the bbox thing.
Anyway, I've found the code!
It's actually mostly r_alias.c, but the changes in there were quite extensive, so a tutorial would just consist of "replace this line with that line" over and over again for quite a bit. I'm going to just do a QuakeTastic upload of the full r_alias.c together with a few implementation notes; if anyone's interested in dissecting the changes further they can grab their favourite diff tool and work on it with that.
OK, here we go: Software Quake Frame Interpolation
Anyway, I've found the code!
OK, here we go: Software Quake Frame Interpolation
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
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
13 posts
• Page 1 of 1
Return to Programming Tutorials
Who is online
Users browsing this forum: No registered users and 1 guest