From aa2be95cac4543cdd49fae01e9dc412f7e95b801 Mon Sep 17 00:00:00 2001 From: havoc Date: Fri, 31 Jan 2003 07:27:31 +0000 Subject: [PATCH] chthon lightning no longer uses beam polygons 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 | 56 ++++++++++++++++++++++++++++++++++++++++++++---------- cl_parse.c | 22 +++++++++++++++------ client.h | 8 ++++++++ 3 files changed, 70 insertions(+), 16 deletions(-) diff --git a/cl_main.c b/cl_main.c index bc39115f..56b8a500 100644 --- 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(); diff --git a/cl_parse.c b/cl_parse.c index 7aee6a55..50d1aea4 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -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: diff --git a/client.h b/client.h index 1168ba86..08c98223 100644 --- 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; -- 2.39.2