// Prophecy camera pitchangle by Alexander "motorsep" Zubov
cvar_t chase_pitchangle = {CVAR_SAVE, "chase_pitchangle", "55", "chase cam pitch angle"};
+cvar_t v_yshearing = {0, "v_yshearing", "0", "be all out of gum (set this to the maximum angle to allow Y shearing for - try values like 75)"};
+
float v_dmg_time, v_dmg_roll, v_dmg_pitch;
Used by view and sv_user
===============
*/
-float V_CalcRoll (vec3_t angles, vec3_t velocity)
+float V_CalcRoll (const vec3_t angles, const vec3_t velocity)
{
vec3_t right;
float sign;
out[2] = highpass_limited(value[2], fracz, limitz, &store[2]);
}
-void V_CalcRefdefUsing (const matrix4x4_t *entrendermatrix, const vec3_t clviewangles, qboolean teleported, qboolean clonground, qboolean clcmdjump)
+/*
+ * State:
+ * cl.bob2_smooth
+ * cl.bobfall_speed
+ * cl.bobfall_swing
+ * cl.gunangles_adjustment_highpass
+ * cl.gunangles_adjustment_lowpass
+ * cl.gunangles_highpass
+ * cl.gunangles_prev
+ * cl.gunorg_adjustment_highpass
+ * cl.gunorg_adjustment_lowpass
+ * cl.gunorg_highpass
+ * cl.gunorg_prev
+ * cl.hitgroundtime
+ * cl.lastongroundtime
+ * cl.oldongrounbd
+ * cl.stairsmoothtime
+ * cl.stairsmoothz
+ * cl.calcrefdef_prevtime
+ * Extra input:
+ * cl.movecmd[0].time
+ * cl.movevars_stepheight
+ * cl.movevars_timescale
+ * cl.oldtime
+ * cl.punchangle
+ * cl.punchvector
+ * cl.qw_intermission_angles
+ * cl.qw_intermission_origin
+ * cl.qw_weaponkick
+ * cls.protocol
+ * cl.time
+ * Output:
+ * cl.csqc_viewanglesfromengine
+ * cl.csqc_viewmodelmatrixfromengine
+ * cl.csqc_vieworiginfromengine
+ * r_refdef.view.matrix
+ * viewmodelmatrix_nobob
+ * viewmodelmatrix_withbob
+ */
+void V_CalcRefdefUsing (const matrix4x4_t *entrendermatrix, const vec3_t clviewangles, qboolean teleported, qboolean clonground, qboolean clcmdjump, float clstatsviewheight, qboolean cldead, qboolean clintermission, const vec3_t clvelocity)
{
float vieworg[3], viewangles[3], smoothtime;
float gunorg[3], gunangles[3];
cl.lastongroundtime = cl.movecmd[0].time;
}
cl.oldonground = clonground;
+ cl.calcrefdef_prevtime = max(cl.calcrefdef_prevtime, cl.oldtime);
+ VectorClear(gunangles);
VectorClear(gunorg);
viewmodelmatrix_nobob = identitymatrix;
viewmodelmatrix_withbob = identitymatrix;
if (v_dmg_time > 0)
v_dmg_time -= bound(0, smoothtime, 0.1);
- if (cl.intermission)
+ if (clintermission)
{
// entity is a fixed camera, just copy the matrix
if (cls.protocol == PROTOCOL_QUAKEWORLD)
else
{
r_refdef.view.matrix = *entrendermatrix;
- Matrix4x4_AdjustOrigin(&r_refdef.view.matrix, 0, 0, cl.stats[STAT_VIEWHEIGHT]);
+ Matrix4x4_AdjustOrigin(&r_refdef.view.matrix, 0, 0, clstatsviewheight);
}
+ if (v_yshearing.value > 0)
+ Matrix4x4_QuakeToDuke3D(&r_refdef.view.matrix, &r_refdef.view.matrix, v_yshearing.value);
Matrix4x4_Copy(&viewmodelmatrix_nobob, &r_refdef.view.matrix);
Matrix4x4_ConcatScale(&viewmodelmatrix_nobob, cl_viewmodel_scale.value);
Matrix4x4_Copy(&viewmodelmatrix_withbob, &viewmodelmatrix_nobob);
+
+ VectorCopy(vieworg, cl.csqc_vieworiginfromengine);
+ VectorCopy(viewangles, cl.csqc_viewanglesfromengine);
+
+ Matrix4x4_Invert_Simple(&tmpmatrix, &r_refdef.view.matrix);
+ Matrix4x4_CreateScale(&cl.csqc_viewmodelmatrixfromengine, cl_viewmodel_scale.value);
}
else
{
// apply the viewofs (even if chasecam is used)
// Samual: Lets add smoothing for this too so that things like crouching are done with a transition.
- viewheight = bound(0, (cl.time - cl.oldtime) / max(0.0001, cl_smoothviewheight.value), 1);
- viewheightavg = viewheightavg * (1 - viewheight) + cl.stats[STAT_VIEWHEIGHT] * viewheight;
+ viewheight = bound(0, (cl.time - cl.calcrefdef_prevtime) / max(0.0001, cl_smoothviewheight.value), 1);
+ viewheightavg = viewheightavg * (1 - viewheight) + clstatsviewheight * viewheight;
vieworg[2] += viewheightavg;
if (chase_active.value)
#else
// trace from first person view location to our chosen third person view location
#if 1
- trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false, true);
+ trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false, true);
#else
- trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false);
+ trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false);
#endif
VectorCopy(trace.endpos, bestvieworg);
offset[2] = 0;
chase_dest[1] = vieworg[1] - forward[1] * camback + up[1] * camup + offset[1];
chase_dest[2] = vieworg[2] - forward[2] * camback + up[2] * camup + offset[2];
#if 1
- trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false, true);
+ trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false, true);
#else
- trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false);
+ trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false);
#endif
if (bestvieworg[2] > trace.endpos[2])
bestvieworg[2] = trace.endpos[2];
chase_dest[0] = vieworg[0] + forward[0] * dist;
chase_dest[1] = vieworg[1] + forward[1] * dist;
chase_dest[2] = vieworg[2] + forward[2] * dist + camup;
- trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false, true);
+ trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, collision_extendmovelength.value, true, false, NULL, false, true);
VectorMAMAM(1, trace.endpos, 8, forward, 4, trace.plane.normal, vieworg);
}
}
{
// first person view from entity
// angles
- if (cl.stats[STAT_HEALTH] <= 0 && v_deathtilt.integer)
+ if (cldead && v_deathtilt.integer)
viewangles[ROLL] = v_deathtiltangle.value;
VectorAdd(viewangles, cl.punchangle, viewangles);
- viewangles[ROLL] += V_CalcRoll(cl.viewangles, cl.velocity);
+ viewangles[ROLL] += V_CalcRoll(clviewangles, clvelocity);
if (v_dmg_time > 0)
{
viewangles[ROLL] += v_dmg_time/v_kicktime.value*v_dmg_roll;
}
// origin
VectorAdd(vieworg, cl.punchvector, vieworg);
- if (cl.stats[STAT_HEALTH] > 0)
+ if (!cldead)
{
double xyspeed, bob, bobfall;
float cycle;
vec_t frametime;
- //frametime = cl.realframetime * cl.movevars_timescale;
- frametime = (cl.time - cl.oldtime) * cl.movevars_timescale;
+ frametime = (cl.time - cl.calcrefdef_prevtime) * cl.movevars_timescale;
// 1. if we teleported, clear the frametime... the lowpass will recover the previous value then
if(teleported)
VectorAdd(viewangles, gunangles, gunangles);
// bounded XY speed, used by several effects below
- xyspeed = bound (0, sqrt(cl.velocity[0]*cl.velocity[0] + cl.velocity[1]*cl.velocity[1]), 400);
+ xyspeed = bound (0, sqrt(clvelocity[0]*clvelocity[0] + clvelocity[1]*clvelocity[1]), 400);
// vertical view bobbing code
if (cl_bob.value && cl_bobcycle.value)
// calculate the front and side of the player between the X and Y axes
AngleVectors(viewangles, forward, right, up);
// now get the speed based on those angles. The bounds should match the same value as xyspeed's
- side = bound(-400, DotProduct (cl.velocity, right) * cl.bob2_smooth, 400);
- front = bound(-400, DotProduct (cl.velocity, forward) * cl.bob2_smooth, 400);
+ side = bound(-400, DotProduct (clvelocity, right) * cl.bob2_smooth, 400);
+ front = bound(-400, DotProduct (clvelocity, forward) * cl.bob2_smooth, 400);
VectorScale(forward, bob, forward);
VectorScale(right, bob, right);
// we use side with forward and front with right, so the bobbing goes
{
if (!clonground)
{
- cl.bobfall_speed = bound(-400, cl.velocity[2], 0) * bound(0, cl_bobfall.value, 0.1);
- if (cl.velocity[2] < -cl_bobfallminspeed.value)
+ cl.bobfall_speed = bound(-400, clvelocity[2], 0) * bound(0, cl_bobfall.value, 0.1);
+ if (clvelocity[2] < -cl_bobfallminspeed.value)
cl.bobfall_swing = 1;
else
cl.bobfall_swing = 0; // TODO really?
viewangles[2] += v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value;
}
Matrix4x4_CreateFromQuakeEntity(&r_refdef.view.matrix, vieworg[0], vieworg[1], vieworg[2], viewangles[0], viewangles[1], viewangles[2], 1);
+ if (v_yshearing.value > 0)
+ Matrix4x4_QuakeToDuke3D(&r_refdef.view.matrix, &r_refdef.view.matrix, v_yshearing.value);
// calculate a viewmodel matrix for use in view-attached entities
Matrix4x4_Copy(&viewmodelmatrix_nobob, &r_refdef.view.matrix);
Matrix4x4_ConcatScale(&viewmodelmatrix_nobob, cl_viewmodel_scale.value);
Matrix4x4_CreateFromQuakeEntity(&viewmodelmatrix_withbob, gunorg[0], gunorg[1], gunorg[2], gunangles[0], gunangles[1], gunangles[2], cl_viewmodel_scale.value);
+ if (v_yshearing.value > 0)
+ Matrix4x4_QuakeToDuke3D(&viewmodelmatrix_withbob, &viewmodelmatrix_withbob, v_yshearing.value);
+
VectorCopy(vieworg, cl.csqc_vieworiginfromengine);
VectorCopy(viewangles, cl.csqc_viewanglesfromengine);
Matrix4x4_Invert_Simple(&tmpmatrix, &r_refdef.view.matrix);
Matrix4x4_Concat(&cl.csqc_viewmodelmatrixfromengine, &tmpmatrix, &viewmodelmatrix_withbob);
}
+
+ cl.calcrefdef_prevtime = cl.time;
}
void V_CalcRefdef (void)
{
entity_t *ent;
+ qboolean cldead;
- if (cls.state == ca_connected && cls.signon == SIGNONS && !cl.csqc_server2csqcentitynumber[cl.playerentity])
+ if (cls.state == ca_connected && cls.signon == SIGNONS && !cl.csqc_server2csqcentitynumber[cl.viewentity])
{
// ent is the view entity (visible when out of body)
ent = &cl.entities[cl.viewentity];
- V_CalcRefdefUsing(&ent->render.matrix, cl.viewangles, !ent->persistent.trail_allowed, cl.onground, cl.cmd.jump); // FIXME use a better way to detect teleport/warp than trail_allowed
+ cldead = (cl.stats[STAT_HEALTH] <= 0 && cl.stats[STAT_HEALTH] != -666 && cl.stats[STAT_HEALTH] != -2342);
+ V_CalcRefdefUsing(&ent->render.matrix, cl.viewangles, !ent->persistent.trail_allowed, cl.onground, cl.cmd.jump, cl.stats[STAT_VIEWHEIGHT], cldead, cl.intermission != 0, cl.velocity); // FIXME use a better way to detect teleport/warp than trail_allowed
}
else
{
Cvar_RegisterVariable (&v_deathtilt);
Cvar_RegisterVariable (&v_deathtiltangle);
+
+ Cvar_RegisterVariable (&v_yshearing);
}