migrated a large number of #define MAX values to quakedef.h and added a
[divverent/darkplaces.git] / r_lerpanim.c
1 #include "quakedef.h"
2
3 // LordHavoc: quite tempting to break apart this function to reuse the
4 //            duplicated code, but I suspect it is better for performance
5 //            this way
6 // LordHavoc: later note: made FRAMEBLENDINSERT macro
7 void R_LerpAnimation(entity_render_t *r)
8 {
9         int sub2, numframes, f, i, k;
10         int isfirstframegroup = true;
11         int nolerp;
12         double sublerp, lerp, d;
13         animscene_t *scene;
14         framegroupblend_t *g;
15         frameblend_t *blend;
16         dp_model_t *model = r->model;
17
18         memset(r->frameblend, 0, sizeof(r->frameblend));
19
20         if (!model || !model->surfmesh.isanimated)
21         {
22                 r->frameblend[0].lerp = 1;
23                 return;
24         }
25
26         blend = r->frameblend;
27         nolerp = (model->type == mod_sprite) ? !r_lerpsprites.integer : !r_lerpmodels.integer;
28         numframes = model->numframes;
29         for (k = 0, g = r->framegroupblend;k < MAX_FRAMEGROUPBLENDS;k++, g++)
30         {
31                 if ((unsigned int)g->frame >= (unsigned int)numframes)
32                 {
33                         Con_DPrintf("CL_LerpAnimation: no such frame %d\n", g->frame);
34                         g->frame = 0;
35                 }
36                 f = g->frame;
37                 d = lerp = g->lerp;
38                 if (lerp <= 0)
39                         continue;
40                 if (nolerp)
41                 {
42                         if (isfirstframegroup)
43                         {
44                                 d = lerp = 1;
45                                 isfirstframegroup = false;
46                         }
47                         else
48                                 continue;
49                 }
50                 if (model->animscenes)
51                 {
52                         scene = model->animscenes + f;
53                         f = scene->firstframe;
54                         if (scene->framecount > 1)
55                         {
56                                 // this code path is only used on .zym models and torches
57                                 sublerp = scene->framerate * (cl.time - g->start);
58                                 f = (int) floor(sublerp);
59                                 sublerp -= f;
60                                 sub2 = f + 1;
61                                 if (sublerp < (1.0 / 65536.0f))
62                                         sublerp = 0;
63                                 if (sublerp > (65535.0f / 65536.0f))
64                                         sublerp = 1;
65                                 if (nolerp)
66                                         sublerp = 0;
67                                 if (scene->loop)
68                                 {
69                                         f = (f % scene->framecount);
70                                         sub2 = (sub2 % scene->framecount);
71                                 }
72                                 f = bound(0, f, (scene->framecount - 1)) + scene->firstframe;
73                                 sub2 = bound(0, sub2, (scene->framecount - 1)) + scene->firstframe;
74                                 d = sublerp * lerp;
75                                 // two framelerps produced from one animation
76                                 if (d > 0)
77                                 {
78                                         for (i = 0;i < MAX_FRAMEBLENDS;i++)
79                                         {
80                                                 if (blend[i].lerp <= 0 || blend[i].subframe == sub2)
81                                                 {
82                                                         blend[i].subframe = sub2;
83                                                         blend[i].lerp += d;
84                                                         break;
85                                                 }
86                                         }
87                                 }
88                                 d = (1 - sublerp) * lerp;
89                         }
90                 }
91                 if (d > 0)
92                 {
93                         for (i = 0;i < MAX_FRAMEBLENDS;i++)
94                         {
95                                 if (blend[i].lerp <= 0 || blend[i].subframe == f)
96                                 {
97                                         blend[i].subframe = f;
98                                         blend[i].lerp += d;
99                                         break;
100                                 }
101                         }
102                 }
103         }
104 }
105