-
#include "quakedef.h"
// LordHavoc: quite tempting to break apart this function to reuse the
// duplicated code, but I suspect it is better for performance
// this way
-void R_LerpAnimation(model_t *mod, int frame1, int frame2, double frame1start, double frame2start, double framelerp, frameblend_t *blend)
+// LordHavoc: later note: made FRAMEBLENDINSERT macro
+void R_LerpAnimation(entity_render_t *r)
{
- int sub1, sub2, numframes, f, i, data;
- double sublerp, lerp, l;
- animscene_t *scene, *scenes;
+ int sub1, sub2, numframes, f, i;
+ double sublerp, lerp, d;
+ animscene_t *scene;
+ frameblend_t *blend;
+
+ if (!r->model || !r->model->type)
+ return;
- data = (int) Mod_Extradata(mod);
- if (!data)
- Host_Error("R_LerpAnimation: model not loaded\n");
- scenes = (animscene_t *) (mod->ofs_scenes + data);
+ blend = r->frameblend;
- numframes = mod->numframes;
+ numframes = r->model->numframes;
- if ((frame1 >= numframes))
+ if (r->frame1 >= numframes)
{
- Con_Printf ("R_LerpAnimation: no such frame %d\n", frame1);
- frame1 = 0;
+ Con_DPrintf ("CL_LerpAnimation: no such frame %d\n", r->frame1);
+ r->frame1 = 0;
}
- if ((frame2 >= numframes))
+ if (r->frame2 >= numframes)
{
- Con_Printf ("R_LerpAnimation: no such frame %d\n", frame2);
- frame2 = 0;
+ Con_DPrintf ("CL_LerpAnimation: no such frame %d\n", r->frame2);
+ r->frame2 = 0;
}
- if (frame1 < 0)
- Host_Error ("R_LerpAnimation: frame1 is NULL\n");
+ // 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 (framelerp < (1.0f / 65536.0f))
- framelerp = 0;
- if (framelerp >= (65535.0f / 65536.0f))
- framelerp = 1;
+ // check r_lerpmodels and round off very close blend percentages
+ if (!r_lerpmodels.integer)
+ r->framelerp = 1;
+ else if (r->framelerp >= (65535.0f / 65536.0f))
+ r->framelerp = 1;
+ else if (r->framelerp < (1.0f / 65536.0f))
+ r->framelerp = 0;
- blend[0].frame = blend[1].frame = blend[2].frame = blend[3].frame = -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 (framelerp < 1)
+ if (r->model->animscenes)
{
- scene = scenes + frame1;
- lerp = 1 - framelerp;
-
- if (scene->framecount > 1)
+ if (r->framelerp < 1 && r->frame1 >= 0)
{
- sublerp = scene->framerate * (cl.time - frame1start);
- 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)
+ scene = r->model->animscenes + r->frame1;
+ lerp = 1 - r->framelerp;
+
+ if (scene->framecount > 1)
{
- sub1 = (sub1 % scene->framecount) + scene->firstframe;
- sub2 = (sub2 % scene->framecount) + scene->firstframe;
+ sublerp = scene->framerate * (cl.time - r->frame1time);
+ sub1 = (int) (sublerp);
+ sub2 = sub1 + 1;
+ sublerp -= sub1;
+ if (!r_lerpmodels.integer)
+ sublerp = 1;
+ else if (sublerp >= (65535.0f / 65536.0f))
+ sublerp = 1;
+ else if (sublerp < (1.0f / 65536.0f))
+ sublerp = 0;
+ 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;
}
else
{
- sub1 = bound(0, sub1, (scene->framecount - 1)) + scene->firstframe;
- sub2 = bound(0, sub2, (scene->framecount - 1)) + scene->firstframe;
+ f = scene->firstframe;
+ d = lerp;
}
- f = sub1;
- l = (1 - sublerp) * lerp;
- if (l > 0)
- {
- for (i = 0;i < 4;i++)
- {
- if (blend[i].frame == f)
- {
- blend[i].lerp += l;
- break;
- }
- if (blend[i].lerp <= 0)
- {
- blend[i].frame = f;
- blend[i].lerp = l;
- break;
- }
- }
- }
- f = sub2;
- l = sublerp * lerp;
+ FRAMEBLENDINSERT
}
- else
+ if (r->framelerp > 0 && r->frame2 >= 0)
{
- f = scene->firstframe;
- l = lerp;
- }
- if (l > 0)
- {
- for (i = 0;i < 4;i++)
+ scene = r->model->animscenes + r->frame2;
+ lerp = r->framelerp;
+
+ if (scene->framecount > 1)
{
- if (blend[i].frame == f)
+ sublerp = scene->framerate * (cl.time - r->frame1time);
+ sub1 = (int) (sublerp);
+ sub2 = sub1 + 1;
+ sublerp -= sub1;
+ if (!r_lerpmodels.integer)
+ sublerp = 1;
+ else if (sublerp >= (65535.0f / 65536.0f))
+ sublerp = 1;
+ else if (sublerp < (1.0f / 65536.0f))
+ sublerp = 0;
+ if (scene->loop)
{
- blend[i].lerp += l;
- break;
+ sub1 = (sub1 % scene->framecount);
+ sub2 = (sub2 % scene->framecount);
}
- if (blend[i].lerp <= 0)
+ else
{
- blend[i].frame = f;
- blend[i].lerp = l;
- break;
+ sub1 = bound(0, sub1, (scene->framecount - 1));
+ sub2 = bound(0, sub2, (scene->framecount - 1));
}
- }
- }
- }
- if (framelerp > 0 && frame2 >= 0)
- {
- scene = scenes + frame2;
- lerp = framelerp;
-
- if (scene->framecount > 1)
- {
- sublerp = scene->framerate * (cl.time - frame1start);
- 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) + scene->firstframe;
- sub2 = (sub2 % scene->framecount) + scene->firstframe;
+ sub1 += scene->firstframe;
+ sub2 += scene->firstframe;
+ f = sub1;
+ d = (1 - sublerp) * lerp;
+ FRAMEBLENDINSERT
+ f = sub2;
+ d = sublerp * lerp;
}
else
{
- sub1 = bound(0, sub1, (scene->framecount - 1)) + scene->firstframe;
- sub2 = bound(0, sub2, (scene->framecount - 1)) + scene->firstframe;
- }
- f = sub1;
- l = (1 - sublerp) * lerp;
- if (l > 0)
- {
- for (i = 0;i < 4;i++)
- {
- if (blend[i].frame == f)
- {
- blend[i].lerp += l;
- break;
- }
- if (blend[i].lerp <= 0)
- {
- blend[i].frame = f;
- blend[i].lerp = l;
- break;
- }
- }
+ f = scene->firstframe;
+ d = lerp;
}
- f = sub2;
- l = sublerp * lerp;
+ FRAMEBLENDINSERT
}
- else
+ }
+ else
+ {
+ // if there are no scenes, assume it is all single-frame groups
+ if (r->framelerp < 1 && r->frame1 >= 0)
{
- f = scene->firstframe;
- l = lerp;
+ f = r->frame1;
+ d = 1 - r->framelerp;
+ FRAMEBLENDINSERT
}
- if (l > 0)
+ if (r->framelerp > 0 && r->frame2 >= 0)
{
- for (i = 0;i < 4;i++)
- {
- if (blend[i].frame == f)
- {
- blend[i].lerp += l;
- break;
- }
- if (blend[i].lerp <= 0)
- {
- blend[i].frame = f;
- blend[i].lerp = l;
- break;
- }
- }
+ f = r->frame2;
+ d = r->framelerp;
+ FRAMEBLENDINSERT
}
}
}
+