optimized AngleVectors calls (pass NULL for vectors that should not be generated)
[divverent/darkplaces.git] / r_lerpanim.c
1
2 #include "quakedef.h"
3
4 // LordHavoc: quite tempting to break apart this function to reuse the
5 //            duplicated code, but I suspect it is better for performance
6 //            this way
7 void R_LerpAnimation(model_t *mod, int frame1, int frame2, double frame1start, double frame2start, double framelerp, frameblend_t *blend)
8 {
9         int sub1, sub2, numframes, f, i, data;
10         double sublerp, lerp, l;
11         animscene_t *scene, *scenes;
12
13         data = (int) Mod_Extradata(mod);
14         if (!data)
15                 Host_Error("R_LerpAnimation: model not loaded\n");
16         scenes = (animscene_t *) (mod->ofs_scenes + data);
17
18         numframes = mod->numframes;
19
20         if ((frame1 >= numframes))
21         {
22                 Con_Printf ("R_LerpAnimation: no such frame %d\n", frame1);
23                 frame1 = 0;
24         }
25
26         if ((frame2 >= numframes))
27         {
28                 Con_Printf ("R_LerpAnimation: no such frame %d\n", frame2);
29                 frame2 = 0;
30         }
31
32         if (frame1 < 0)
33                 Host_Error ("R_LerpAnimation: frame1 is NULL\n");
34
35         // round off very close blend percentages
36         if (framelerp < (1.0f / 65536.0f))
37                 framelerp = 0;
38         if (framelerp >= (65535.0f / 65536.0f))
39                 framelerp = 1;
40
41         blend[0].frame = blend[1].frame = blend[2].frame = blend[3].frame = -1;
42         blend[0].lerp = blend[1].lerp = blend[2].lerp = blend[3].lerp = 0;
43         if (framelerp < 1)
44         {
45                 scene = scenes + frame1;
46                 lerp = 1 - framelerp;
47
48                 if (scene->framecount > 1)
49                 {
50                         sublerp = scene->framerate * (cl.time - frame1start);
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) + scene->firstframe;
61                                 sub2 = (sub2 % scene->framecount) + scene->firstframe;
62                         }
63                         else
64                         {
65                                 sub1 = bound(0, sub1, (scene->framecount - 1)) + scene->firstframe;
66                                 sub2 = bound(0, sub2, (scene->framecount - 1)) + scene->firstframe;
67                         }
68                         f = sub1;
69                         l = (1 - sublerp) * lerp;
70                         if (l > 0)
71                         {
72                                 for (i = 0;i < 4;i++)
73                                 {
74                                         if (blend[i].frame == f)
75                                         {
76                                                 blend[i].lerp += l;
77                                                 break;
78                                         }
79                                         if (blend[i].lerp <= 0)
80                                         {
81                                                 blend[i].frame = f;
82                                                 blend[i].lerp = l;
83                                                 break;
84                                         }
85                                 }
86                         }
87                         f = sub2;
88                         l = sublerp * lerp;
89                 }
90                 else
91                 {
92                         f = scene->firstframe;
93                         l = lerp;
94                 }
95                 if (l > 0)
96                 {
97                         for (i = 0;i < 4;i++)
98                         {
99                                 if (blend[i].frame == f)
100                                 {
101                                         blend[i].lerp += l;
102                                         break;
103                                 }
104                                 if (blend[i].lerp <= 0)
105                                 {
106                                         blend[i].frame = f;
107                                         blend[i].lerp = l;
108                                         break;
109                                 }
110                         }
111                 }
112         }
113         if (framelerp > 0 && frame2 >= 0)
114         {
115                 scene = scenes + frame2;
116                 lerp = framelerp;
117
118                 if (scene->framecount > 1)
119                 {
120                         sublerp = scene->framerate * (cl.time - frame1start);
121                         sub1 = (int) (sublerp);
122                         sub2 = sub1 + 1;
123                         sublerp -= sub1;
124                         if (sublerp < (1.0f / 65536.0f))
125                                 sublerp = 0;
126                         if (sublerp >= (65535.0f / 65536.0f))
127                                 sublerp = 1;
128                         if (scene->loop)
129                         {
130                                 sub1 = (sub1 % scene->framecount) + scene->firstframe;
131                                 sub2 = (sub2 % scene->framecount) + scene->firstframe;
132                         }
133                         else
134                         {
135                                 sub1 = bound(0, sub1, (scene->framecount - 1)) + scene->firstframe;
136                                 sub2 = bound(0, sub2, (scene->framecount - 1)) + scene->firstframe;
137                         }
138                         f = sub1;
139                         l = (1 - sublerp) * lerp;
140                         if (l > 0)
141                         {
142                                 for (i = 0;i < 4;i++)
143                                 {
144                                         if (blend[i].frame == f)
145                                         {
146                                                 blend[i].lerp += l;
147                                                 break;
148                                         }
149                                         if (blend[i].lerp <= 0)
150                                         {
151                                                 blend[i].frame = f;
152                                                 blend[i].lerp = l;
153                                                 break;
154                                         }
155                                 }
156                         }
157                         f = sub2;
158                         l = sublerp * lerp;
159                 }
160                 else
161                 {
162                         f = scene->firstframe;
163                         l = lerp;
164                 }
165                 if (l > 0)
166                 {
167                         for (i = 0;i < 4;i++)
168                         {
169                                 if (blend[i].frame == f)
170                                 {
171                                         blend[i].lerp += l;
172                                         break;
173                                 }
174                                 if (blend[i].lerp <= 0)
175                                 {
176                                         blend[i].frame = f;
177                                         blend[i].lerp = l;
178                                         break;
179                                 }
180                         }
181                 }
182         }
183 }