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