added in_pitch_min and in_pitch_max cvars to limit pitch (default: -90 to +90)
[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         blend = r->frameblend;
14
15         numframes = r->model->numframes;
16
17         if (r->frame1 >= numframes)
18         {
19                 Con_Printf ("CL_LerpAnimation: no such frame %d\n", r->frame1);
20                 r->frame1 = 0;
21         }
22
23         if (r->frame2 >= numframes)
24         {
25                 Con_Printf ("CL_LerpAnimation: no such frame %d\n", r->frame2);
26                 r->frame2 = 0;
27         }
28
29         // note: this could be removed, if the rendering code allows an empty blend array
30         if (r->frame1 < 0)
31                 Host_Error ("CL_LerpAnimation: frame1 is NULL\n");
32
33         // round off very close blend percentages
34         if (r->framelerp < (1.0f / 65536.0f))
35                 r->framelerp = 0;
36         if (r->framelerp >= (65535.0f / 65536.0f))
37                 r->framelerp = 1;
38
39         blend[0].frame = blend[1].frame = blend[2].frame = blend[3].frame = 0;
40         blend[0].lerp = blend[1].lerp = blend[2].lerp = blend[3].lerp = 0;
41         if (r->model->animscenes)
42         {
43                 if (r->framelerp < 1 && r->frame1 >= 0)
44                 {
45                         scene = r->model->animscenes + r->frame1;
46                         lerp = 1 - r->framelerp;
47
48                         if (scene->framecount > 1)
49                         {
50                                 sublerp = scene->framerate * (cl.time - r->frame1time);
51                                 sub1 = (int) (sublerp);
52                                 sub2 = sub1 + 1;
53                                 sublerp -= sub1;
54                                 if (sublerp < (1.0f / 65536.0f))
55                                         sublerp = 0;
56                                 if (sublerp >= (65535.0f / 65536.0f))
57                                         sublerp = 1;
58                                 if (scene->loop)
59                                 {
60                                         sub1 = (sub1 % scene->framecount);
61                                         sub2 = (sub2 % scene->framecount);
62                                 }
63                                 else
64                                 {
65                                         sub1 = bound(0, sub1, (scene->framecount - 1));
66                                         sub2 = bound(0, sub2, (scene->framecount - 1));
67                                 }
68                                 sub1 += scene->firstframe;
69                                 sub2 += scene->firstframe;
70                                 f = sub1;
71                                 d = (1 - sublerp) * lerp;
72 #define FRAMEBLENDINSERT\
73                                 if (d > 0)\
74                                 {\
75                                         for (i = 0;i < 4;i++)\
76                                         {\
77                                                 if (blend[i].frame == f)\
78                                                 {\
79                                                         blend[i].lerp += d;\
80                                                         break;\
81                                                 }\
82                                                 if (blend[i].lerp <= 0)\
83                                                 {\
84                                                         blend[i].frame = f;\
85                                                         blend[i].lerp = d;\
86                                                         break;\
87                                                 }\
88                                         }\
89                                 }
90                                 FRAMEBLENDINSERT
91                                 f = sub2;
92                                 d = sublerp * lerp;
93                         }
94                         else
95                         {
96                                 f = scene->firstframe;
97                                 d = lerp;
98                         }
99                         FRAMEBLENDINSERT
100                 }
101                 if (r->framelerp > 0 && r->frame2 >= 0)
102                 {
103                         scene = r->model->animscenes + r->frame2;
104                         lerp = r->framelerp;
105
106                         if (scene->framecount > 1)
107                         {
108                                 sublerp = scene->framerate * (cl.time - r->frame1time);
109                                 sub1 = (int) (sublerp);
110                                 sub2 = sub1 + 1;
111                                 sublerp -= sub1;
112                                 if (sublerp < (1.0f / 65536.0f))
113                                         sublerp = 0;
114                                 if (sublerp >= (65535.0f / 65536.0f))
115                                         sublerp = 1;
116                                 if (scene->loop)
117                                 {
118                                         sub1 = (sub1 % scene->framecount);
119                                         sub2 = (sub2 % scene->framecount);
120                                 }
121                                 else
122                                 {
123                                         sub1 = bound(0, sub1, (scene->framecount - 1));
124                                         sub2 = bound(0, sub2, (scene->framecount - 1));
125                                 }
126                                 sub1 += scene->firstframe;
127                                 sub2 += 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         //Con_Printf("Lerp: %i:%f %i:%f %i:%f %i:%f\n", blend[0].frame, blend[0].lerp, blend[1].frame, blend[1].lerp, blend[2].frame, blend[2].lerp, blend[3].frame, blend[3].lerp);
159 }
160