changed a lot of Host_Error calls to Con_Printf or Sys_Error according to severity
[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         {
36                 Con_Printf ("CL_LerpAnimation: frame1 is NULL\n");
37                 r->frame1 = 0;
38         }
39
40         // check r_lerpmodels and round off very close blend percentages
41         if (!r_lerpmodels.integer)
42                 r->framelerp = 1;
43         else if (r->framelerp >= (65535.0f / 65536.0f))
44                 r->framelerp = 1;
45         else if (r->framelerp < (1.0f / 65536.0f))
46                 r->framelerp = 0;
47
48         blend[0].frame = blend[1].frame = blend[2].frame = blend[3].frame = 0;
49         blend[0].lerp = blend[1].lerp = blend[2].lerp = blend[3].lerp = 0;
50         if (r->model->animscenes)
51         {
52                 if (r->framelerp < 1 && r->frame1 >= 0)
53                 {
54                         scene = r->model->animscenes + r->frame1;
55                         lerp = 1 - r->framelerp;
56
57                         if (scene->framecount > 1)
58                         {
59                                 sublerp = scene->framerate * (cl.time - r->frame1time);
60                                 sub1 = (int) (sublerp);
61                                 sub2 = sub1 + 1;
62                                 sublerp -= sub1;
63                                 if (!r_lerpmodels.integer)
64                                         sublerp = 1;
65                                 else if (sublerp >= (65535.0f / 65536.0f))
66                                         sublerp = 1;
67                                 else if (sublerp < (1.0f / 65536.0f))
68                                         sublerp = 0;
69                                 if (scene->loop)
70                                 {
71                                         sub1 = (sub1 % scene->framecount);
72                                         sub2 = (sub2 % scene->framecount);
73                                 }
74                                 sub1 = bound(0, sub1, (scene->framecount - 1)) + scene->firstframe;
75                                 sub2 = bound(0, sub2, (scene->framecount - 1)) + scene->firstframe;
76                                 f = sub1;
77                                 d = (1 - sublerp) * lerp;
78 #define FRAMEBLENDINSERT\
79                                 if (d > 0)\
80                                 {\
81                                         for (i = 0;i < 4;i++)\
82                                         {\
83                                                 if (blend[i].frame == f)\
84                                                 {\
85                                                         blend[i].lerp += d;\
86                                                         break;\
87                                                 }\
88                                                 if (blend[i].lerp <= 0)\
89                                                 {\
90                                                         blend[i].frame = f;\
91                                                         blend[i].lerp = d;\
92                                                         break;\
93                                                 }\
94                                         }\
95                                 }
96                                 FRAMEBLENDINSERT
97                                 f = sub2;
98                                 d = sublerp * lerp;
99                         }
100                         else
101                         {
102                                 f = scene->firstframe;
103                                 d = lerp;
104                         }
105                         FRAMEBLENDINSERT
106                 }
107                 if (r->framelerp > 0 && r->frame2 >= 0)
108                 {
109                         scene = r->model->animscenes + r->frame2;
110                         lerp = r->framelerp;
111
112                         if (scene->framecount > 1)
113                         {
114                                 sublerp = scene->framerate * (cl.time - r->frame1time);
115                                 sub1 = (int) (sublerp);
116                                 sub2 = sub1 + 1;
117                                 sublerp -= sub1;
118                                 if (!r_lerpmodels.integer)
119                                         sublerp = 1;
120                                 else if (sublerp >= (65535.0f / 65536.0f))
121                                         sublerp = 1;
122                                 else if (sublerp < (1.0f / 65536.0f))
123                                         sublerp = 0;
124                                 if (scene->loop)
125                                 {
126                                         sub1 = (sub1 % scene->framecount);
127                                         sub2 = (sub2 % scene->framecount);
128                                 }
129                                 sub1 = bound(0, sub1, (scene->framecount - 1)) + scene->firstframe;
130                                 sub2 = bound(0, sub2, (scene->framecount - 1)) + scene->firstframe;
131                                 f = sub1;
132                                 d = (1 - sublerp) * lerp;
133                                 FRAMEBLENDINSERT
134                                 f = sub2;
135                                 d = sublerp * lerp;
136                         }
137                         else
138                         {
139                                 f = scene->firstframe;
140                                 d = lerp;
141                         }
142                         FRAMEBLENDINSERT
143                 }
144         }
145         else
146         {
147                 // if there are no scenes, assume it is all single-frame groups
148                 if (r->framelerp < 1 && r->frame1 >= 0)
149                 {
150                         f = r->frame1;
151                         d = 1 - r->framelerp;
152                         FRAMEBLENDINSERT
153                 }
154                 if (r->framelerp > 0 && r->frame2 >= 0)
155                 {
156                         f = r->frame2;
157                         d = r->framelerp;
158                         FRAMEBLENDINSERT
159                 }
160         }
161 }
162