chthon lightning no longer uses beam polygons
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 31 Jan 2003 07:27:31 +0000 (07:27 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 31 Jan 2003 07:27:31 +0000 (07:27 +0000)
lightning beams are now relative to their owner entity (if they have one), this makes aiming lightning look instantaneous for the first time ever in quake

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2723 d7cf8633-e32d-0410-b094-e92efae38249

cl_main.c
cl_parse.c
client.h

index bc39115..56b8a50 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -53,7 +53,8 @@ cvar_t r_draweffects = {0, "r_draweffects", "1"};
 cvar_t cl_explosions = {CVAR_SAVE, "cl_explosions", "1"};
 cvar_t cl_stainmaps = {CVAR_SAVE, "cl_stainmaps", "1"};
 
-cvar_t cl_beampolygons = {CVAR_SAVE, "cl_beampolygons", "1"};
+cvar_t cl_beams_polygons = {CVAR_SAVE, "cl_beams_polygons", "1"};
+cvar_t cl_beams_relative = {CVAR_SAVE, "cl_beams_relative", "1"};
 
 mempool_t *cl_scores_mempool;
 mempool_t *cl_refdef_mempool;
@@ -868,13 +869,42 @@ void CL_RelinkBeams (void)
                // if coming from the player, update the start position
                //if (b->entity == cl.viewentity)
                //      VectorCopy (cl_entities[cl.viewentity].render.origin, b->start);
-               if (b->entity && cl_entities[b->entity].state_current.active)
+               if (cl_beams_relative.integer && b->entity && cl_entities[b->entity].state_current.active && b->relativestartvalid)
                {
-                       VectorCopy (cl_entities[b->entity].render.origin, b->start);
-                       b->start[2] += 16;
+                       entity_state_t *p = &cl_entities[b->entity].state_previous;
+                       //entity_state_t *c = &cl_entities[b->entity].state_current;
+                       entity_render_t *r = &cl_entities[b->entity].render;
+                       matrix4x4_t matrix, imatrix;
+                       if (b->relativestartvalid == 2)
+                       {
+                               // not really valid yet, we need to get the orientation now
+                               // (ParseBeam flagged this because it is received before
+                               //  entities are received, by now they have been received)
+                               // note: because players create lightning in their think
+                               // function (which occurs before movement), they actually
+                               // have some lag in it's location, so compare to the
+                               // previous player state, not the latest
+                               if (b->entity == cl.viewentity)
+                                       Matrix4x4_CreateFromQuakeEntity(&matrix, cl.viewentoriginold[0], cl.viewentoriginold[1], cl.viewentoriginold[2] + 16, cl.viewangles[0], cl.viewangles[1], cl.viewangles[2], 1);
+                               else
+                                       Matrix4x4_CreateFromQuakeEntity(&matrix, p->origin[0], p->origin[1], p->origin[2] + 16, p->angles[0], p->angles[1], p->angles[2], 1);
+                               Matrix4x4_Invert_Simple(&imatrix, &matrix);
+                               Matrix4x4_Transform(&imatrix, b->start, b->relativestart);
+                               Matrix4x4_Transform(&imatrix, b->end, b->relativeend);
+                               b->relativestartvalid = 1;
+                       }
+                       else
+                       {
+                               if (b->entity == cl.viewentity)
+                                       Matrix4x4_CreateFromQuakeEntity(&matrix, cl.viewentorigin[0], cl.viewentorigin[1], cl.viewentorigin[2] + 16, cl.viewangles[0], cl.viewangles[1], cl.viewangles[2], 1);
+                               else
+                                       Matrix4x4_CreateFromQuakeEntity(&matrix, r->origin[0], r->origin[1], r->origin[2] + 16, r->angles[0], r->angles[1], r->angles[2], 1);
+                               Matrix4x4_Transform(&matrix, b->relativestart, b->start);
+                               Matrix4x4_Transform(&matrix, b->relativeend, b->end);
+                       }
                }
 
-               if (cl_beampolygons.integer)
+               if (b->lightning && cl_beams_polygons.integer)
                        continue;
 
                // calculate pitch and yaw
@@ -1058,7 +1088,7 @@ void R_DrawLightningBeamCallback(const void *calldata1, int calldata2)
        CrossProduct(beamdir, up, right);
 
        // calculate T coordinate scrolling (start and end texcoord along the beam)
-       t1 = cl.time * -r_lightningbeam_scroll.value;
+       t1 = cl.time * -r_lightningbeam_scroll.value + beamrepeatscale * DotProduct(b->start, beamdir);
        t1 = t1 - (int) t1;
        t2 = t1 + beamrepeatscale * length;
 
@@ -1109,13 +1139,13 @@ void R_DrawLightningBeams (void)
        beam_t *b;
        vec3_t org;
 
-       if (!cl_beampolygons.integer)
+       if (!cl_beams_polygons.integer)
                return;
 
        beamrepeatscale = 1.0f / r_lightningbeam_repeatdistance.value;
        for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++)
        {
-               if (b->model && b->endtime >= cl.time)
+               if (b->model && b->endtime >= cl.time && b->lightning)
                {
                        VectorAdd(b->start, b->end, org);
                        VectorScale(org, 0.5f, org);
@@ -1137,7 +1167,11 @@ void CL_LerpPlayer(float frac)
                cl.viewentorigin[2] = cl.viewentoriginold[2] + frac * (cl.viewentoriginnew[2] - cl.viewentoriginold[2]);
        }
        else
+       {
+               VectorCopy (cl_entities[cl.viewentity].state_previous.origin, cl.viewentoriginold);
+               VectorCopy (cl_entities[cl.viewentity].state_current.origin, cl.viewentoriginnew);
                VectorCopy (cl_entities[cl.viewentity].render.origin, cl.viewentorigin);
+       }
 
        cl.viewzoom = cl.viewzoomold + frac * (cl.viewzoomnew - cl.viewzoomold);
 
@@ -1172,10 +1206,11 @@ void CL_RelinkEntities (void)
        CL_RelinkStaticEntities();
        CL_RelinkNetworkEntities();
        CL_RelinkEffects();
-       CL_RelinkBeams();
        CL_MoveParticles();
 
        CL_LerpPlayer(frac);
+
+       CL_RelinkBeams();
 }
 
 
@@ -1443,7 +1478,8 @@ void CL_Init (void)
        Cvar_RegisterVariable(&r_draweffects);
        Cvar_RegisterVariable(&cl_explosions);
        Cvar_RegisterVariable(&cl_stainmaps);
-       Cvar_RegisterVariable(&cl_beampolygons);
+       Cvar_RegisterVariable(&cl_beams_polygons);
+       Cvar_RegisterVariable(&cl_beams_relative);
 
        R_LightningBeams_Init();
 
index 7aee6a5..50d1aea 100644 (file)
@@ -929,7 +929,7 @@ void CL_InitTEnts (void)
        cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav", false);
 }
 
-void CL_ParseBeam (model_t *m)
+void CL_ParseBeam (model_t *m, int lightning)
 {
        int i, ent;
        vec3_t start, end;
@@ -939,12 +939,20 @@ void CL_ParseBeam (model_t *m)
        MSG_ReadVector(start);
        MSG_ReadVector(end);
 
+       if (ent >= MAX_EDICTS)
+       {
+               Con_Printf("CL_ParseBeam: invalid entity number %i\n", ent);
+               ent = 0;
+       }
+
        // override any beam with the same entity
        for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++)
        {
                if (b->entity == ent)
                {
                        //b->entity = ent;
+                       b->lightning = lightning;
+                       b->relativestartvalid = (ent && cl_entities[ent].state_current.active) ? 2 : 0;
                        b->model = m;
                        b->endtime = cl.time + 0.2;
                        VectorCopy (start, b->start);
@@ -959,6 +967,8 @@ void CL_ParseBeam (model_t *m)
                if (!b->model || b->endtime < cl.time)
                {
                        b->entity = ent;
+                       b->lightning = lightning;
+                       b->relativestartvalid = (ent && cl_entities[ent].state_current.active) ? 2 : 0;
                        b->model = m;
                        b->endtime = cl.time + 0.2;
                        VectorCopy (start, b->start);
@@ -1246,21 +1256,21 @@ void CL_ParseTempEntity (void)
                // lightning bolts
                if (!cl_model_bolt)
                        cl_model_bolt = Mod_ForName("progs/bolt.mdl", true, false, false);
-               CL_ParseBeam (cl_model_bolt);
+               CL_ParseBeam (cl_model_bolt, true);
                break;
 
        case TE_LIGHTNING2:
                // lightning bolts
                if (!cl_model_bolt2)
                        cl_model_bolt2 = Mod_ForName("progs/bolt2.mdl", true, false, false);
-               CL_ParseBeam (cl_model_bolt2);
+               CL_ParseBeam (cl_model_bolt2, true);
                break;
 
        case TE_LIGHTNING3:
                // lightning bolts
                if (!cl_model_bolt3)
                        cl_model_bolt3 = Mod_ForName("progs/bolt3.mdl", true, false, false);
-               CL_ParseBeam (cl_model_bolt3);
+               CL_ParseBeam (cl_model_bolt3, true);
                break;
 
 // PGM 01/21/97
@@ -1268,13 +1278,13 @@ void CL_ParseTempEntity (void)
                // grappling hook beam
                if (!cl_model_beam)
                        cl_model_beam = Mod_ForName("progs/beam.mdl", true, false, false);
-               CL_ParseBeam (cl_model_beam);
+               CL_ParseBeam (cl_model_beam, false);
                break;
 // PGM 01/21/97
 
 // LordHavoc: for compatibility with the Nehahra movie...
        case TE_LIGHTNING4NEH:
-               CL_ParseBeam (Mod_ForName(MSG_ReadString(), true, false, false));
+               CL_ParseBeam (Mod_ForName(MSG_ReadString(), true, false, false), false);
                break;
 
        case TE_LAVASPLASH:
index 1168ba8..08c9822 100644 (file)
--- a/client.h
+++ b/client.h
@@ -56,9 +56,17 @@ cl_effect_t;
 typedef struct
 {
        int             entity;
+       // draw this as lightning polygons, or a model?
+       int             lightning;
        struct model_s  *model;
        float   endtime;
        vec3_t  start, end;
+       // if this beam is owned by an entity, this is the beam start relative to
+       // that entity's matrix for per frame start updates
+       vec3_t  relativestart;
+       vec3_t  relativeend;
+       // indicates whether relativestart is valid
+       int     relativestartvalid;
 }
 beam_t;