]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - r_lerpanim.c
fix a crash when s->tag_entity is higher than current d->maxedicts
[xonotic/darkplaces.git] / r_lerpanim.c
index 7ac1c62e0154bdc64a17f346ab88b4ffcd8359d0..f736a11ccc31b3e2b96c9b208c43a9995ca76920 100644 (file)
-
 #include "quakedef.h"
 
 // LordHavoc: quite tempting to break apart this function to reuse the
 //            duplicated code, but I suspect it is better for performance
 //            this way
-void R_LerpAnimation(model_t *mod, int frame1, int frame2, double frame1start, double frame2start, double framelerp, frameblend_t *blend)
+// LordHavoc: later note: made FRAMEBLENDINSERT macro
+void R_LerpAnimation(entity_render_t *r)
 {
-       int sub1, sub2, numframes, f, i, data;
-       double sublerp, lerp, l;
-       animscene_t *scene, *scenes;
+       int sub1, sub2, numframes, f, i;
+       double sublerp, lerp, d;
+       animscene_t *scene;
+       frameblend_t *blend;
+
+       if (!r->model || !r->model->type)
+               return;
 
-       data = (int) Mod_Extradata(mod);
-       if (!data)
-               Host_Error("R_LerpAnimation: model not loaded\n");
-       scenes = (animscene_t *) (mod->ofs_scenes + data);
+       blend = r->frameblend;
 
-       numframes = mod->numframes;
+       numframes = r->model->numframes;
 
-       if ((frame1 >= numframes))
+       if (r->frame1 >= numframes)
        {
-               Con_Printf ("R_LerpAnimation: no such frame %d\n", frame1);
-               frame1 = 0;
+               Con_DPrintf("CL_LerpAnimation: no such frame %d\n", r->frame1);
+               r->frame1 = 0;
        }
 
-       if ((frame2 >= numframes))
+       if (r->frame2 >= numframes)
        {
-               Con_Printf ("R_LerpAnimation: no such frame %d\n", frame2);
-               frame2 = 0;
+               Con_DPrintf("CL_LerpAnimation: no such frame %d\n", r->frame2);
+               r->frame2 = 0;
        }
 
-       if (frame1 < 0)
-               Host_Error ("R_LerpAnimation: frame1 is NULL\n");
+       // note: this could be removed, if the rendering code allows an empty blend array
+       if (r->frame1 < 0)
+               Host_Error ("CL_LerpAnimation: frame1 is NULL\n");
 
-       // round off very close blend percentages
-       if (framelerp < (1.0f / 65536.0f))
-               framelerp = 0;
-       if (framelerp >= (65535.0f / 65536.0f))
-               framelerp = 1;
+       // check r_lerpmodels and round off very close blend percentages
+       if (!r_lerpmodels.integer)
+               r->framelerp = 1;
+       else if (r->framelerp >= (65535.0f / 65536.0f))
+               r->framelerp = 1;
+       else if (r->framelerp < (1.0f / 65536.0f))
+               r->framelerp = 0;
 
-       blend[0].frame = blend[1].frame = blend[2].frame = blend[3].frame = -1;
+       blend[0].frame = blend[1].frame = blend[2].frame = blend[3].frame = 0;
        blend[0].lerp = blend[1].lerp = blend[2].lerp = blend[3].lerp = 0;
-       if (framelerp < 1)
+       if (r->model->animscenes)
        {
-               scene = scenes + frame1;
-               lerp = 1 - framelerp;
-
-               if (scene->framecount > 1)
+               if (r->framelerp < 1 && r->frame1 >= 0)
                {
-                       sublerp = scene->framerate * (cl.time - frame1start);
-                       sub1 = (int) (sublerp);
-                       sub2 = sub1 + 1;
-                       sublerp -= sub1;
-                       if (sublerp < (1.0f / 65536.0f))
-                               sublerp = 0;
-                       if (sublerp >= (65535.0f / 65536.0f))
-                               sublerp = 1;
-                       if (scene->loop)
-                       {
-                               sub1 = (sub1 % scene->framecount) + scene->firstframe;
-                               sub2 = (sub2 % scene->framecount) + scene->firstframe;
-                       }
-                       else
+                       scene = r->model->animscenes + r->frame1;
+                       lerp = 1 - r->framelerp;
+
+                       if (scene->framecount > 1)
                        {
+                               sublerp = scene->framerate * (cl.time - r->frame1time);
+                               sub1 = (int) (sublerp);
+                               sub2 = sub1 + 1;
+                               sublerp -= sub1;
+                               if (!r_lerpmodels.integer)
+                                       sublerp = 1;
+                               else if (sublerp >= (65535.0f / 65536.0f))
+                                       sublerp = 1;
+                               else if (sublerp < (1.0f / 65536.0f))
+                                       sublerp = 0;
+                               if (scene->loop)
+                               {
+                                       sub1 = (sub1 % scene->framecount);
+                                       sub2 = (sub2 % scene->framecount);
+                               }
                                sub1 = bound(0, sub1, (scene->framecount - 1)) + scene->firstframe;
                                sub2 = bound(0, sub2, (scene->framecount - 1)) + scene->firstframe;
+                               f = sub1;
+                               d = (1 - sublerp) * lerp;
+#define FRAMEBLENDINSERT\
+                               if (d > 0)\
+                               {\
+                                       for (i = 0;i < 4;i++)\
+                                       {\
+                                               if (blend[i].frame == f)\
+                                               {\
+                                                       blend[i].lerp += d;\
+                                                       break;\
+                                               }\
+                                               if (blend[i].lerp <= 0)\
+                                               {\
+                                                       blend[i].frame = f;\
+                                                       blend[i].lerp = d;\
+                                                       break;\
+                                               }\
+                                       }\
+                               }
+                               FRAMEBLENDINSERT
+                               f = sub2;
+                               d = sublerp * lerp;
                        }
-                       f = sub1;
-                       l = (1 - sublerp) * lerp;
-                       if (l > 0)
+                       else
                        {
-                               for (i = 0;i < 4;i++)
-                               {
-                                       if (blend[i].frame == f)
-                                       {
-                                               blend[i].lerp += l;
-                                               break;
-                                       }
-                                       if (blend[i].lerp <= 0)
-                                       {
-                                               blend[i].frame = f;
-                                               blend[i].lerp = l;
-                                               break;
-                                       }
-                               }
+                               f = scene->firstframe;
+                               d = lerp;
                        }
-                       f = sub2;
-                       l = sublerp * lerp;
-               }
-               else
-               {
-                       f = scene->firstframe;
-                       l = lerp;
+                       FRAMEBLENDINSERT
                }
-               if (l > 0)
+               if (r->framelerp > 0 && r->frame2 >= 0)
                {
-                       for (i = 0;i < 4;i++)
+                       scene = r->model->animscenes + r->frame2;
+                       lerp = r->framelerp;
+
+                       if (scene->framecount > 1)
                        {
-                               if (blend[i].frame == f)
-                               {
-                                       blend[i].lerp += l;
-                                       break;
-                               }
-                               if (blend[i].lerp <= 0)
+                               sublerp = scene->framerate * (cl.time - r->frame1time);
+                               sub1 = (int) (sublerp);
+                               sub2 = sub1 + 1;
+                               sublerp -= sub1;
+                               if (!r_lerpmodels.integer)
+                                       sublerp = 1;
+                               else if (sublerp >= (65535.0f / 65536.0f))
+                                       sublerp = 1;
+                               else if (sublerp < (1.0f / 65536.0f))
+                                       sublerp = 0;
+                               if (scene->loop)
                                {
-                                       blend[i].frame = f;
-                                       blend[i].lerp = l;
-                                       break;
+                                       sub1 = (sub1 % scene->framecount);
+                                       sub2 = (sub2 % scene->framecount);
                                }
-                       }
-               }
-       }
-       if (framelerp > 0 && frame2 >= 0)
-       {
-               scene = scenes + frame2;
-               lerp = framelerp;
-
-               if (scene->framecount > 1)
-               {
-                       sublerp = scene->framerate * (cl.time - frame1start);
-                       sub1 = (int) (sublerp);
-                       sub2 = sub1 + 1;
-                       sublerp -= sub1;
-                       if (sublerp < (1.0f / 65536.0f))
-                               sublerp = 0;
-                       if (sublerp >= (65535.0f / 65536.0f))
-                               sublerp = 1;
-                       if (scene->loop)
-                       {
-                               sub1 = (sub1 % scene->framecount) + scene->firstframe;
-                               sub2 = (sub2 % scene->framecount) + scene->firstframe;
-                       }
-                       else
-                       {
                                sub1 = bound(0, sub1, (scene->framecount - 1)) + scene->firstframe;
                                sub2 = bound(0, sub2, (scene->framecount - 1)) + scene->firstframe;
+                               f = sub1;
+                               d = (1 - sublerp) * lerp;
+                               FRAMEBLENDINSERT
+                               f = sub2;
+                               d = sublerp * lerp;
                        }
-                       f = sub1;
-                       l = (1 - sublerp) * lerp;
-                       if (l > 0)
+                       else
                        {
-                               for (i = 0;i < 4;i++)
-                               {
-                                       if (blend[i].frame == f)
-                                       {
-                                               blend[i].lerp += l;
-                                               break;
-                                       }
-                                       if (blend[i].lerp <= 0)
-                                       {
-                                               blend[i].frame = f;
-                                               blend[i].lerp = l;
-                                               break;
-                                       }
-                               }
+                               f = scene->firstframe;
+                               d = lerp;
                        }
-                       f = sub2;
-                       l = sublerp * lerp;
+                       FRAMEBLENDINSERT
                }
-               else
+       }
+       else
+       {
+               // if there are no scenes, assume it is all single-frame groups
+               if (r->framelerp < 1 && r->frame1 >= 0)
                {
-                       f = scene->firstframe;
-                       l = lerp;
+                       f = r->frame1;
+                       d = 1 - r->framelerp;
+                       FRAMEBLENDINSERT
                }
-               if (l > 0)
+               if (r->framelerp > 0 && r->frame2 >= 0)
                {
-                       for (i = 0;i < 4;i++)
-                       {
-                               if (blend[i].frame == f)
-                               {
-                                       blend[i].lerp += l;
-                                       break;
-                               }
-                               if (blend[i].lerp <= 0)
-                               {
-                                       blend[i].frame = f;
-                                       blend[i].lerp = l;
-                                       break;
-                               }
-                       }
+                       f = r->frame2;
+                       d = r->framelerp;
+                       FRAMEBLENDINSERT
                }
        }
 }
+