upgraded both QuakeC VMs to use a table of negative string indices for all dynamic...
[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 sub1, sub2, numframes, f, i;
10         double sublerp, lerp, d;
11         animscene_t *scene;
12         frameblend_t *blend;
13
14         if (!r->model || !r->model->type)
15                 return;
16
17         blend = r->frameblend;
18
19         numframes = r->model->numframes;
20
21         if (r->frame1 >= numframes)
22         {
23                 Con_DPrintf("CL_LerpAnimation: no such frame %d\n", r->frame1);
24                 r->frame1 = 0;
25         }
26
27         if (r->frame2 >= numframes)
28         {
29                 Con_DPrintf("CL_LerpAnimation: no such frame %d\n", r->frame2);
30                 r->frame2 = 0;
31         }
32
33         // note: this could be removed, if the rendering code allows an empty blend array
34         if (r->frame1 < 0)
35                 Host_Error ("CL_LerpAnimation: frame1 is NULL\n");
36
37         // check r_lerpmodels and round off very close blend percentages
38         if (!r_lerpmodels.integer)
39                 r->framelerp = 1;
40         else if (r->framelerp >= (65535.0f / 65536.0f))
41                 r->framelerp = 1;
42         else if (r->framelerp < (1.0f / 65536.0f))
43                 r->framelerp = 0;
44
45         blend[0].frame = blend[1].frame = blend[2].frame = blend[3].frame = 0;
46         blend[0].lerp = blend[1].lerp = blend[2].lerp = blend[3].lerp = 0;
47         if (r->model->animscenes)
48         {
49                 if (r->framelerp < 1 && r->frame1 >= 0)
50                 {
51                         scene = r->model->animscenes + r->frame1;
52                         lerp = 1 - r->framelerp;
53
54                         if (scene->framecount > 1)
55                         {
56                                 sublerp = scene->framerate * (cl.time - r->frame1time);
57                                 sub1 = (int) (sublerp);
58                                 sub2 = sub1 + 1;
59                                 sublerp -= sub1;
60                                 if (!r_lerpmodels.integer)
61                                         sublerp = 1;
62                                 else if (sublerp >= (65535.0f / 65536.0f))
63                                         sublerp = 1;
64                                 else if (sublerp < (1.0f / 65536.0f))
65                                         sublerp = 0;
66                                 if (scene->loop)
67                                 {
68                                         sub1 = (sub1 % scene->framecount);
69                                         sub2 = (sub2 % scene->framecount);
70                                 }
71                                 sub1 = bound(0, sub1, (scene->framecount - 1)) + scene->firstframe;
72                                 sub2 = bound(0, sub2, (scene->framecount - 1)) + scene->firstframe;
73                                 f = sub1;
74                                 d = (1 - sublerp) * lerp;
75 #define FRAMEBLENDINSERT\
76                                 if (d > 0)\
77                                 {\
78                                         for (i = 0;i < 4;i++)\
79                                         {\
80                                                 if (blend[i].frame == f)\
81                                                 {\
82                                                         blend[i].lerp += d;\
83                                                         break;\
84                                                 }\
85                                                 if (blend[i].lerp <= 0)\
86                                                 {\
87                                                         blend[i].frame = f;\
88                                                         blend[i].lerp = d;\
89                                                         break;\
90                                                 }\
91                                         }\
92                                 }
93                                 FRAMEBLENDINSERT
94                                 f = sub2;
95                                 d = sublerp * lerp;
96                         }
97                         else
98                         {
99                                 f = scene->firstframe;
100                                 d = lerp;
101                         }
102                         FRAMEBLENDINSERT
103                 }
104                 if (r->framelerp > 0 && r->frame2 >= 0)
105                 {
106                         scene = r->model->animscenes + r->frame2;
107                         lerp = r->framelerp;
108
109                         if (scene->framecount > 1)
110                         {
111                                 sublerp = scene->framerate * (cl.time - r->frame1time);
112                                 sub1 = (int) (sublerp);
113                                 sub2 = sub1 + 1;
114                                 sublerp -= sub1;
115                                 if (!r_lerpmodels.integer)
116                                         sublerp = 1;
117                                 else if (sublerp >= (65535.0f / 65536.0f))
118                                         sublerp = 1;
119                                 else if (sublerp < (1.0f / 65536.0f))
120                                         sublerp = 0;
121                                 if (scene->loop)
122                                 {
123                                         sub1 = (sub1 % scene->framecount);
124                                         sub2 = (sub2 % scene->framecount);
125                                 }
126                                 sub1 = bound(0, sub1, (scene->framecount - 1)) + scene->firstframe;
127                                 sub2 = bound(0, sub2, (scene->framecount - 1)) + scene->firstframe;
128                                 f = sub1;
129                                 d = (1 - sublerp) * lerp;
130                                 FRAMEBLENDINSERT
131                                 f = sub2;
132                                 d = sublerp * lerp;
133                         }
134                         else
135                         {
136                                 f = scene->firstframe;
137                                 d = lerp;
138                         }
139                         FRAMEBLENDINSERT
140                 }
141         }
142         else
143         {
144                 // if there are no scenes, assume it is all single-frame groups
145                 if (r->framelerp < 1 && r->frame1 >= 0)
146                 {
147                         f = r->frame1;
148                         d = 1 - r->framelerp;
149                         FRAMEBLENDINSERT
150                 }
151                 if (r->framelerp > 0 && r->frame2 >= 0)
152                 {
153                         f = r->frame2;
154                         d = r->framelerp;
155                         FRAMEBLENDINSERT
156                 }
157         }
158 }
159