r_shadows: use the parent entity's light direction for shadowing attached entities...
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 10 Nov 2008 13:58:11 +0000 (13:58 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 10 Nov 2008 13:58:11 +0000 (13:58 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8554 d7cf8633-e32d-0410-b094-e92efae38249

cl_main.c
r_shadow.c

index dbb23b4..39f46ab 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -881,7 +881,10 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat
        e->render.flags = e->state_current.flags;
        e->render.effects = e->state_current.effects;
        VectorScale(e->state_current.colormod, (1.0f / 32.0f), e->render.colormod);
-       e->render.entitynumber = e - cl.entities;
+       if(e >= cl.entities && e < cl.entities + cl.num_entities)
+               e->render.entitynumber = e - cl.entities;
+       else
+               e->render.entitynumber = 0;
        if (e->state_current.flags & RENDER_COLORMAPPED)
                CL_SetEntityColormapColors(&e->render, e->state_current.colormap);
        else if (e->state_current.colormap > 0 && e->state_current.colormap <= cl.maxclients && cl.scores != NULL)
index 48d9755..17dc96b 100644 (file)
@@ -3182,6 +3182,7 @@ void R_DrawModelShadows(void)
        vec3_t relativelightorigin;
        vec3_t relativelightdirection;
        vec3_t relativeshadowmins, relativeshadowmaxs;
+       vec3_t tmp;
        float vertex3f[12];
 
        if (!r_drawentities.integer || !gl_stencil)
@@ -3210,7 +3211,33 @@ void R_DrawModelShadows(void)
                        relativethrowdistance = r_shadows_throwdistance.value * Matrix4x4_ScaleFromMatrix(&ent->inversematrix);
                        VectorSet(relativeshadowmins, -relativethrowdistance, -relativethrowdistance, -relativethrowdistance);
                        VectorSet(relativeshadowmaxs, relativethrowdistance, relativethrowdistance, relativethrowdistance);
-                       VectorNegate(ent->modellight_lightdir, relativelightdirection);
+
+                       if(ent->entitynumber != 0)
+                       {
+                               // networked entity - might be attached in some way (then we should use the parent's light direction, to not tear apart attached entities)
+                               int entnum, entnum2, recursion;
+                               entnum = entnum2 = ent->entitynumber;
+                               for(recursion = 32; recursion > 0; --recursion)
+                               {
+                                       entnum2 = cl.entities[entnum].state_current.tagentity;
+                                       if(entnum2 >= 1 && entnum2 < cl.num_entities && cl.entities_active[entnum2])
+                                               entnum = entnum2;
+                                       else
+                                               break;
+                               }
+                               if(recursion && recursion != 32) // if we followed a valid non-empty attachment chain
+                               {
+                                       VectorNegate(cl.entities[entnum].render.modellight_lightdir, relativelightdirection);
+                                       // transform into modelspace of OUR entity
+                                       Matrix4x4_Transform3x3(&cl.entities[entnum].render.matrix, relativelightdirection, tmp);
+                                       Matrix4x4_Transform3x3(&ent->inversematrix, tmp, relativelightdirection);
+                               }
+                               else
+                                       VectorNegate(ent->modellight_lightdir, relativelightdirection);
+                       }
+                       else
+                               VectorNegate(ent->modellight_lightdir, relativelightdirection);
+
                        VectorScale(relativelightdirection, -relativethrowdistance, relativelightorigin);
                        RSurf_ActiveModelEntity(ent, false, false);
                        ent->model->DrawShadowVolume(ent, relativelightorigin, relativelightdirection, relativethrowdistance, ent->model->nummodelsurfaces, ent->model->surfacelist, relativeshadowmins, relativeshadowmaxs);