// LordHavoc: later note: made FRAMEBLENDINSERT macro
void R_LerpAnimation(entity_render_t *r)
{
- int sub1, sub2, numframes, f, i;
+ int sub2, numframes, f, i, k;
+ int isfirstframegroup = true;
+ int nolerp;
double sublerp, lerp, d;
animscene_t *scene;
+ framegroupblend_t *g;
frameblend_t *blend;
- blend = r->frameblend;
+ dp_model_t *model = r->model;
- numframes = r->model->numframes;
+ memset(r->frameblend, 0, sizeof(r->frameblend));
- if (r->frame1 >= numframes)
+ if (!model || !model->surfmesh.isanimated)
{
- Con_DPrintf ("CL_LerpAnimation: no such frame %d\n", r->frame1);
- r->frame1 = 0;
+ r->frameblend[0].lerp = 1;
+ return;
}
- if (r->frame2 >= numframes)
- {
- Con_DPrintf ("CL_LerpAnimation: no such frame %d\n", r->frame2);
- r->frame2 = 0;
- }
-
- // note: this could be removed, if the rendering code allows an empty blend array
- if (r->frame1 < 0)
- Host_Error ("CL_LerpAnimation: frame1 is NULL\n");
-
- // round off very close blend percentages
- if (r->framelerp < (1.0f / 65536.0f))
- r->framelerp = 0;
- if (r->framelerp >= (65535.0f / 65536.0f))
- r->framelerp = 1;
-
- blend[0].frame = blend[1].frame = blend[2].frame = blend[3].frame = 0;
- blend[0].lerp = blend[1].lerp = blend[2].lerp = blend[3].lerp = 0;
- if (r->model->animscenes)
+ blend = r->frameblend;
+ nolerp = (model->type == mod_sprite) ? !r_lerpsprites.integer : !r_lerpmodels.integer;
+ numframes = model->numframes;
+ for (k = 0, g = r->framegroupblend;k < MAX_FRAMEGROUPBLENDS;k++, g++)
{
- if (r->framelerp < 1 && r->frame1 >= 0)
+ if ((unsigned int)g->frame >= (unsigned int)numframes)
{
- scene = r->model->animscenes + r->frame1;
- lerp = 1 - r->framelerp;
-
- if (scene->framecount > 1)
+ Con_DPrintf("CL_LerpAnimation: no such frame %d\n", g->frame);
+ g->frame = 0;
+ }
+ f = g->frame;
+ d = lerp = g->lerp;
+ if (lerp <= 0)
+ continue;
+ if (nolerp)
+ {
+ if (isfirstframegroup)
{
- sublerp = scene->framerate * (cl.time - r->frame1time);
- sub1 = (int) (sublerp);
- sub2 = sub1 + 1;
- sublerp -= sub1;
- if (sublerp < (1.0f / 65536.0f))
- sublerp = 0;
- if (sublerp >= (65535.0f / 65536.0f))
- sublerp = 1;
- if (scene->loop)
- {
- sub1 = (sub1 % scene->framecount);
- sub2 = (sub2 % scene->framecount);
- }
- else
- {
- sub1 = bound(0, sub1, (scene->framecount - 1));
- sub2 = bound(0, sub2, (scene->framecount - 1));
- }
- sub1 += scene->firstframe;
- sub2 += scene->firstframe;
- f = sub1;
- d = (1 - sublerp) * lerp;
-#define FRAMEBLENDINSERT\
- if (d > 0)\
- {\
- for (i = 0;i < 4;i++)\
- {\
- if (blend[i].frame == f)\
- {\
- blend[i].lerp += d;\
- break;\
- }\
- if (blend[i].lerp <= 0)\
- {\
- blend[i].frame = f;\
- blend[i].lerp = d;\
- break;\
- }\
- }\
- }
- FRAMEBLENDINSERT
- f = sub2;
- d = sublerp * lerp;
+ d = lerp = 1;
+ isfirstframegroup = false;
}
else
- {
- f = scene->firstframe;
- d = lerp;
- }
- FRAMEBLENDINSERT
+ continue;
}
- if (r->framelerp > 0 && r->frame2 >= 0)
+ if (model->animscenes)
{
- scene = r->model->animscenes + r->frame2;
- lerp = r->framelerp;
-
+ scene = model->animscenes + f;
+ f = scene->firstframe;
if (scene->framecount > 1)
{
- sublerp = scene->framerate * (cl.time - r->frame1time);
- sub1 = (int) (sublerp);
- sub2 = sub1 + 1;
- sublerp -= sub1;
- if (sublerp < (1.0f / 65536.0f))
+ // this code path is only used on .zym models and torches
+ sublerp = scene->framerate * (cl.time - g->start);
+ f = (int) floor(sublerp);
+ sublerp -= f;
+ sub2 = f + 1;
+ if (sublerp < (1.0 / 65536.0f))
sublerp = 0;
- if (sublerp >= (65535.0f / 65536.0f))
+ if (sublerp > (65535.0f / 65536.0f))
sublerp = 1;
+ if (nolerp)
+ sublerp = 0;
if (scene->loop)
{
- sub1 = (sub1 % scene->framecount);
+ f = (f % scene->framecount);
sub2 = (sub2 % scene->framecount);
}
- else
+ f = bound(0, f, (scene->framecount - 1)) + scene->firstframe;
+ sub2 = bound(0, sub2, (scene->framecount - 1)) + scene->firstframe;
+ d = sublerp * lerp;
+ // two framelerps produced from one animation
+ if (d > 0)
{
- sub1 = bound(0, sub1, (scene->framecount - 1));
- sub2 = bound(0, sub2, (scene->framecount - 1));
+ for (i = 0;i < MAX_FRAMEBLENDS;i++)
+ {
+ if (blend[i].lerp <= 0 || blend[i].subframe == sub2)
+ {
+ blend[i].subframe = sub2;
+ blend[i].lerp += d;
+ break;
+ }
+ }
}
- sub1 += scene->firstframe;
- sub2 += scene->firstframe;
- f = sub1;
d = (1 - sublerp) * lerp;
- FRAMEBLENDINSERT
- f = sub2;
- d = sublerp * lerp;
}
- else
- {
- f = scene->firstframe;
- d = lerp;
- }
- FRAMEBLENDINSERT
- }
- }
- else
- {
- // if there are no scenes, assume it is all single-frame groups
- if (r->framelerp < 1 && r->frame1 >= 0)
- {
- f = r->frame1;
- d = 1 - r->framelerp;
- FRAMEBLENDINSERT
}
- if (r->framelerp > 0 && r->frame2 >= 0)
+ if (d > 0)
{
- f = r->frame2;
- d = r->framelerp;
- FRAMEBLENDINSERT
+ for (i = 0;i < MAX_FRAMEBLENDS;i++)
+ {
+ if (blend[i].lerp <= 0 || blend[i].subframe == f)
+ {
+ blend[i].subframe = f;
+ blend[i].lerp += d;
+ break;
+ }
+ }
}
}
}