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