From da1866f3c048815988f5986896f72d3c29d749f4 Mon Sep 17 00:00:00 2001 From: havoc Date: Sun, 30 Apr 2006 03:42:04 +0000 Subject: [PATCH] changed svc_setangle to cause interpolated turning when spectating (two or more consecutive frames with a svc_setangle message), and instant entity updates when teleporting (just one svc_setangle) so you no longer fly through the level when teleporting changed cl_beams_relative to only apply to the local player (unless set to a value of 2 or higher) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6341 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_main.c | 17 +---------------- cl_parse.c | 34 +++++++++++++++++++++++++++++++++- client.h | 6 ++++++ view.c | 24 +++++++++++++++++++----- 4 files changed, 59 insertions(+), 22 deletions(-) diff --git a/cl_main.c b/cl_main.c index 2fd7720d..3b605902 100644 --- a/cl_main.c +++ b/cl_main.c @@ -1358,7 +1358,7 @@ void CL_RelinkBeams(void) // if coming from the player, update the start position //if (b->entity == cl.viewentity) // Matrix4x4_OriginFromMatrix(&cl.entities[cl.viewentity].render.matrix, b->start); - if (cl_beams_relative.integer && b->entity && cl.entities[b->entity].state_current.active && b->relativestartvalid) + if (cl_beams_relative.integer >= 1 && b->entity && (b->entity == cl.viewentity || cl_beams_relative.integer >= 2) && cl.entities[b->entity].state_current.active && b->relativestartvalid) { entity_render_t *r = &cl.entities[b->entity].render; //Matrix4x4_OriginFromMatrix(&r->matrix, origin); @@ -1460,7 +1460,6 @@ static void CL_RelinkQWNails(void) void CL_LerpPlayer(float frac) { int i; - float d; cl.viewzoom = cl.mviewzoom[1] + frac * (cl.mviewzoom[0] - cl.mviewzoom[1]); for (i = 0;i < 3;i++) @@ -1469,20 +1468,6 @@ void CL_LerpPlayer(float frac) cl.punchvector[i] = cl.mpunchvector[1][i] + frac * (cl.mpunchvector[0][i] - cl.mpunchvector[1][i]); cl.velocity[i] = cl.mvelocity[1][i] + frac * (cl.mvelocity[0][i] - cl.mvelocity[1][i]); } - - if (cls.demoplayback) - { - // interpolate the angles - for (i = 0;i < 3;i++) - { - d = cl.mviewangles[0][i] - cl.mviewangles[1][i]; - if (d > 180) - d -= 360; - else if (d < -180) - d += 360; - cl.viewangles[i] = cl.mviewangles[1][i] + frac * d; - } - } } void CSQC_RelinkAllEntities (int drawmask) diff --git a/cl_parse.c b/cl_parse.c index 866a551e..4de0b234 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -1212,9 +1212,11 @@ void CL_MoveLerpEntityStates(entity_t *ent) ent->persistent.muzzleflash = 0; VectorCopy(ent->state_current.origin, ent->persistent.trail_origin); } - else if (cls.timedemo || cl_nolerp.integer || DotProduct(odelta, odelta) > 1000*1000) + else if (cls.timedemo || cl_nolerp.integer || DotProduct(odelta, odelta) > 1000*1000 || (cl.fixangle[0] && !cl.fixangle[1])) { // don't interpolate the move + // (the fixangle[] check detects teleports, but not constant fixangles + // such as when spectating) ent->persistent.lerpdeltatime = 0; ent->persistent.lerpstarttime = cl.mtime[1]; VectorCopy(ent->state_current.origin, ent->persistent.oldorigin); @@ -2095,6 +2097,13 @@ void CL_ParseServerMessage(void) cl.mtime[1] = cl.mtime[0]; cl.mtime[0] = realtime; // qw has no clock cl.movement_needupdate = true; + // if true the cl.viewangles are interpolated from cl.mviewangles[] + // during this frame + // (makes spectating players much smoother and prevents mouse movement from turning) + cl.fixangle[1] = cl.fixangle[0]; + cl.fixangle[0] = false; + if (!cls.demoplayback) + VectorCopy(cl.mviewangles[0], cl.mviewangles[1]); // slightly kill qw player entities each frame for (i = 1;i < cl.maxclients;i++) @@ -2201,6 +2210,14 @@ void CL_ParseServerMessage(void) case qw_svc_setangle: for (i=0 ; i<3 ; i++) cl.viewangles[i] = MSG_ReadAngle (cls.protocol); + if (!cls.demoplayback) + { + cl.fixangle[0] = true; + VectorCopy(cl.viewangles, cl.mviewangles[0]); + // disable interpolation if this is new + if (!cl.fixangle[1]) + VectorCopy(cl.viewangles, cl.mviewangles[1]); + } break; case qw_svc_lightstyle: @@ -2496,6 +2513,13 @@ void CL_ParseServerMessage(void) cl.mtime[1] = cl.mtime[0]; cl.mtime[0] = MSG_ReadFloat (); cl.movement_needupdate = true; + // if true the cl.viewangles are interpolated from cl.mviewangles[] + // during this frame + // (makes spectating players much smoother and prevents mouse movement from turning) + cl.fixangle[1] = cl.fixangle[0]; + cl.fixangle[0] = false; + if (!cls.demoplayback) + VectorCopy(cl.mviewangles[0], cl.mviewangles[1]); break; case svc_clientdata: @@ -2545,6 +2569,14 @@ void CL_ParseServerMessage(void) case svc_setangle: for (i=0 ; i<3 ; i++) cl.viewangles[i] = MSG_ReadAngle (cls.protocol); + if (!cls.demoplayback) + { + cl.fixangle[0] = true; + VectorCopy(cl.viewangles, cl.mviewangles[0]); + // disable interpolation if this is new + if (!cl.fixangle[1]) + VectorCopy(cl.viewangles, cl.mviewangles[1]); + } break; case svc_setview: diff --git a/client.h b/client.h index 260bfc0f..7ded7895 100644 --- a/client.h +++ b/client.h @@ -653,6 +653,12 @@ typedef struct client_state_s vec3_t mvelocity[2], velocity; // update by server, can be used by mods for zooming vec_t mviewzoom[2], viewzoom; + // if true interpolation the mviewangles and other interpolation of the + // player is disabled until the next network packet + // this is used primarily by teleporters, and when spectating players + // special checking of the old fixangle[1] is used to differentiate + // between teleporting and spectating + qboolean fixangle[2]; // client movement simulation // these fields are only updated by CL_ClientMovement (called by CL_SendMove after parsing each network packet) diff --git a/view.c b/view.c index 9c351228..b00c3443 100644 --- a/view.c +++ b/view.c @@ -332,6 +332,25 @@ void V_CalcRefdef (void) { // ent is the view entity (visible when out of body) ent = &cl.entities[cl.viewentity]; + // player can look around, so take the origin from the entity, + // and the angles from the input system + Matrix4x4_OriginFromMatrix(&ent->render.matrix, vieworg); + VectorCopy(cl.viewangles, viewangles); + // interpolate the angles if playing a demo or spectating someone + if (cls.demoplayback || cl.fixangle[0]) + { + int i; + float frac = bound(0, (cl.time - cl.mtime[1]) / (cl.mtime[0] - cl.mtime[1]), 1); + for (i = 0;i < 3;i++) + { + float d = cl.mviewangles[0][i] - cl.mviewangles[1][i]; + if (d > 180) + d -= 360; + else if (d < -180) + d += 360; + viewangles[i] = cl.mviewangles[1][i] + frac * d; + } + } if (cl.intermission) { // entity is a fixed camera, just copy the matrix @@ -346,11 +365,6 @@ void V_CalcRefdef (void) } else { - // player can look around, so take the origin from the entity, - // and the angles from the input system - Matrix4x4_OriginFromMatrix(&ent->render.matrix, vieworg); - VectorCopy(cl.viewangles, viewangles); - // apply qw weapon recoil effect (this did not work in QW) // TODO: add a cvar to disable this viewangles[PITCH] += cl.qw_weaponkick; -- 2.39.2