X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=view.c;h=df73f194d9a39860816d03e882d98b166f878b71;hp=6f86ac7bafcf0dcb6e2473f0b4bf77118f70ce8a;hb=9d6f77621de650ffaaecb65a3485d51378632925;hpb=28f64beb60928fdcf2a8932a4971ce547fd98062 diff --git a/view.c b/view.c index 6f86ac7b..df73f194 100644 --- a/view.c +++ b/view.c @@ -92,6 +92,25 @@ cvar_t v_ipitch_level = {0, "v_ipitch_level", "0.3", "v_idlescale pitch amount"} cvar_t v_idlescale = {0, "v_idlescale", "0", "how much of the quake 'drunken view' effect to use"}; +cvar_t v_isometric = {0, "v_isometric", "0", "changes view to isometric (non-perspective)"}; +cvar_t v_isometric_verticalfov = { 0, "v_isometric_verticalfov", "512", "vertical field of view in game units (horizontal is computed using aspect ratio based on this)"}; +cvar_t v_isometric_xx = {0, "v_isometric_xx", "0", "camera matrix"}; +cvar_t v_isometric_xy = {0, "v_isometric_xy", "-1", "camera matrix"}; +cvar_t v_isometric_xz = {0, "v_isometric_xz", "0", "camera matrix"}; +cvar_t v_isometric_yx = {0, "v_isometric_yx", "-1", "camera matrix"}; +cvar_t v_isometric_yy = {0, "v_isometric_yy", "0", "camera matrix"}; +cvar_t v_isometric_yz = {0, "v_isometric_yz", "0", "camera matrix"}; +cvar_t v_isometric_zx = {0, "v_isometric_zx", "0", "camera matrix"}; +cvar_t v_isometric_zy = {0, "v_isometric_zy", "0", "camera matrix"}; +cvar_t v_isometric_zz = {0, "v_isometric_zz", "1", "camera matrix"}; +cvar_t v_isometric_tx = {0, "v_isometric_tx", "1767", "camera position"}; +cvar_t v_isometric_ty = {0, "v_isometric_ty", "1767", "camera position"}; +cvar_t v_isometric_tz = {0, "v_isometric_tz", "1425", "camera position"}; +cvar_t v_isometric_rot_pitch = {0, "v_isometric_rot_pitch", "0", "camera rotation"}; +cvar_t v_isometric_rot_yaw = {0, "v_isometric_rot_yaw", "-45", "camera rotation"}; +cvar_t v_isometric_rot_roll = {0, "v_isometric_rot_roll", "-60", "camera rotation"}; +cvar_t v_isometric_locked_orientation = {0, "v_isometric_locked_orientation", "1", "camera rotation is fixed"}; + cvar_t crosshair = {CVAR_SAVE, "crosshair", "0", "selects crosshair to use (0 is none)"}; cvar_t v_centermove = {0, "v_centermove", "0.15", "how long before the view begins to center itself (if freelook/+mlook/+jlook/+klook are off)"}; @@ -589,20 +608,20 @@ void V_CalcRefdefUsing (const matrix4x4_t *entrendermatrix, const vec3_t clviewa chase_dest[2] = vieworg[2] - forward[2] * camback + up[2] * camup; #if 0 #if 1 - //trace = CL_TraceLine(vieworg, eyeboxmins, eyeboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); - trace = CL_TraceLine(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); + //trace = CL_TraceLine(vieworg, eyeboxmins, eyeboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, 0, true, false, NULL, false); + trace = CL_TraceLine(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, 0, true, false, NULL, false); #else - //trace = CL_TraceBox(vieworg, eyeboxmins, eyeboxmaxs, 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, true, false, NULL, false); + //trace = CL_TraceBox(vieworg, eyeboxmins, eyeboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, 0, true, false, NULL, false); + trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, 0, true, false, NULL, false); #endif VectorCopy(trace.endpos, vieworg); vieworg[2] -= 8; #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, collision_extendmovelength.value, true, false, NULL, false, true); + trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, 0, MATERIALFLAGMASK_TRANSLUCENT, 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, collision_extendmovelength.value, true, false, NULL, false); + trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, 0, MATERIALFLAGMASK_TRANSLUCENT, collision_extendmovelength.value, true, false, NULL, false); #endif VectorCopy(trace.endpos, bestvieworg); offset[2] = 0; @@ -615,9 +634,9 @@ void V_CalcRefdefUsing (const matrix4x4_t *entrendermatrix, const vec3_t clviewa 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, collision_extendmovelength.value, true, false, NULL, false, true); + trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, 0, MATERIALFLAGMASK_TRANSLUCENT, 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, collision_extendmovelength.value, true, false, NULL, false); + trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, 0, MATERIALFLAGMASK_TRANSLUCENT, collision_extendmovelength.value, true, false, NULL, false); #endif if (bestvieworg[2] > trace.endpos[2]) bestvieworg[2] = trace.endpos[2]; @@ -643,7 +662,7 @@ void V_CalcRefdefUsing (const matrix4x4_t *entrendermatrix, const vec3_t clviewa 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, collision_extendmovelength.value, true, false, NULL, false, true); + trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, 0, MATERIALFLAGMASK_TRANSLUCENT, collision_extendmovelength.value, true, false, NULL, false, true); VectorMAMAM(1, trace.endpos, 8, forward, 4, trace.plane.normal, vieworg); } } @@ -670,50 +689,59 @@ void V_CalcRefdefUsing (const matrix4x4_t *entrendermatrix, const vec3_t clviewa 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) + if(cl_followmodel.integer || cl_leanmodel.integer) { - // try to fix the first highpass; result is NOT - // perfect! TODO find a better fix - VectorCopy(viewangles, cl.gunangles_prev); + // 1. if we teleported, clear the frametime... the lowpass will recover the previous value then + if(teleported) + { + // try to fix the first highpass; result is NOT + // perfect! TODO find a better fix + VectorCopy(viewangles, cl.gunangles_prev); + VectorCopy(vieworg, cl.gunorg_prev); + } + + // 2. for the gun origin, only keep the high frequency (non-DC) parts, which is "somewhat like velocity" + VectorAdd(cl.gunorg_highpass, cl.gunorg_prev, cl.gunorg_highpass); + highpass3_limited(vieworg, frametime*cl_followmodel_side_highpass1.value, cl_followmodel_side_limit.value, frametime*cl_followmodel_side_highpass1.value, cl_followmodel_side_limit.value, frametime*cl_followmodel_up_highpass1.value, cl_followmodel_up_limit.value, cl.gunorg_highpass, gunorg); VectorCopy(vieworg, cl.gunorg_prev); + VectorSubtract(cl.gunorg_highpass, cl.gunorg_prev, cl.gunorg_highpass); + + // in the highpass, we _store_ the DIFFERENCE to the actual view angles... + VectorAdd(cl.gunangles_highpass, cl.gunangles_prev, cl.gunangles_highpass); + cl.gunangles_highpass[PITCH] += 360 * floor((viewangles[PITCH] - cl.gunangles_highpass[PITCH]) / 360 + 0.5); + cl.gunangles_highpass[YAW] += 360 * floor((viewangles[YAW] - cl.gunangles_highpass[YAW]) / 360 + 0.5); + cl.gunangles_highpass[ROLL] += 360 * floor((viewangles[ROLL] - cl.gunangles_highpass[ROLL]) / 360 + 0.5); + highpass3_limited(viewangles, frametime*cl_leanmodel_up_highpass1.value, cl_leanmodel_up_limit.value, frametime*cl_leanmodel_side_highpass1.value, cl_leanmodel_side_limit.value, 0, 0, cl.gunangles_highpass, gunangles); + VectorCopy(viewangles, cl.gunangles_prev); + VectorSubtract(cl.gunangles_highpass, cl.gunangles_prev, cl.gunangles_highpass); + + // 3. calculate the RAW adjustment vectors + gunorg[0] *= -cl_followmodel_side_speed.value; + gunorg[1] *= -cl_followmodel_side_speed.value; + gunorg[2] *= -cl_followmodel_up_speed.value; + + gunangles[PITCH] *= -cl_leanmodel_up_speed.value; + gunangles[YAW] *= -cl_leanmodel_side_speed.value; + gunangles[ROLL] = 0; + + // 4. perform highpass/lowpass on the adjustment vectors (turning velocity into acceleration!) + // trick: we must do the lowpass LAST, so the lowpass vector IS the final vector! + highpass3(gunorg, frametime*cl_followmodel_side_highpass.value, frametime*cl_followmodel_side_highpass.value, frametime*cl_followmodel_up_highpass.value, cl.gunorg_adjustment_highpass, gunorg); + lowpass3(gunorg, frametime*cl_followmodel_side_lowpass.value, frametime*cl_followmodel_side_lowpass.value, frametime*cl_followmodel_up_lowpass.value, cl.gunorg_adjustment_lowpass, gunorg); + // we assume here: PITCH = 0, YAW = 1, ROLL = 2 + highpass3(gunangles, frametime*cl_leanmodel_up_highpass.value, frametime*cl_leanmodel_side_highpass.value, 0, cl.gunangles_adjustment_highpass, gunangles); + lowpass3(gunangles, frametime*cl_leanmodel_up_lowpass.value, frametime*cl_leanmodel_side_lowpass.value, 0, cl.gunangles_adjustment_lowpass, gunangles); + + // 5. use the adjusted vectors + VectorAdd(vieworg, gunorg, gunorg); + VectorAdd(viewangles, gunangles, gunangles); + } + else + { + // Just initialize gunorg/gunangles. + VectorCopy(vieworg, gunorg); + VectorCopy(viewangles, gunangles); } - - // 2. for the gun origin, only keep the high frequency (non-DC) parts, which is "somewhat like velocity" - VectorAdd(cl.gunorg_highpass, cl.gunorg_prev, cl.gunorg_highpass); - highpass3_limited(vieworg, frametime*cl_followmodel_side_highpass1.value, cl_followmodel_side_limit.value, frametime*cl_followmodel_side_highpass1.value, cl_followmodel_side_limit.value, frametime*cl_followmodel_up_highpass1.value, cl_followmodel_up_limit.value, cl.gunorg_highpass, gunorg); - VectorCopy(vieworg, cl.gunorg_prev); - VectorSubtract(cl.gunorg_highpass, cl.gunorg_prev, cl.gunorg_highpass); - - // in the highpass, we _store_ the DIFFERENCE to the actual view angles... - VectorAdd(cl.gunangles_highpass, cl.gunangles_prev, cl.gunangles_highpass); - cl.gunangles_highpass[PITCH] += 360 * floor((viewangles[PITCH] - cl.gunangles_highpass[PITCH]) / 360 + 0.5); - cl.gunangles_highpass[YAW] += 360 * floor((viewangles[YAW] - cl.gunangles_highpass[YAW]) / 360 + 0.5); - cl.gunangles_highpass[ROLL] += 360 * floor((viewangles[ROLL] - cl.gunangles_highpass[ROLL]) / 360 + 0.5); - highpass3_limited(viewangles, frametime*cl_leanmodel_up_highpass1.value, cl_leanmodel_up_limit.value, frametime*cl_leanmodel_side_highpass1.value, cl_leanmodel_side_limit.value, 0, 0, cl.gunangles_highpass, gunangles); - VectorCopy(viewangles, cl.gunangles_prev); - VectorSubtract(cl.gunangles_highpass, cl.gunangles_prev, cl.gunangles_highpass); - - // 3. calculate the RAW adjustment vectors - gunorg[0] *= (cl_followmodel.value ? -cl_followmodel_side_speed.value : 0); - gunorg[1] *= (cl_followmodel.value ? -cl_followmodel_side_speed.value : 0); - gunorg[2] *= (cl_followmodel.value ? -cl_followmodel_up_speed.value : 0); - - gunangles[PITCH] *= (cl_leanmodel.value ? -cl_leanmodel_up_speed.value : 0); - gunangles[YAW] *= (cl_leanmodel.value ? -cl_leanmodel_side_speed.value : 0); - gunangles[ROLL] = 0; - - // 4. perform highpass/lowpass on the adjustment vectors (turning velocity into acceleration!) - // trick: we must do the lowpass LAST, so the lowpass vector IS the final vector! - highpass3(gunorg, frametime*cl_followmodel_side_highpass.value, frametime*cl_followmodel_side_highpass.value, frametime*cl_followmodel_up_highpass.value, cl.gunorg_adjustment_highpass, gunorg); - lowpass3(gunorg, frametime*cl_followmodel_side_lowpass.value, frametime*cl_followmodel_side_lowpass.value, frametime*cl_followmodel_up_lowpass.value, cl.gunorg_adjustment_lowpass, gunorg); - // we assume here: PITCH = 0, YAW = 1, ROLL = 2 - highpass3(gunangles, frametime*cl_leanmodel_up_highpass.value, frametime*cl_leanmodel_side_highpass.value, 0, cl.gunangles_adjustment_highpass, gunangles); - lowpass3(gunangles, frametime*cl_leanmodel_up_lowpass.value, frametime*cl_leanmodel_side_lowpass.value, 0, cl.gunangles_adjustment_lowpass, gunangles); - - // 5. use the adjusted vectors - VectorAdd(vieworg, gunorg, gunorg); - VectorAdd(viewangles, gunangles, gunangles); // bounded XY speed, used by several effects below xyspeed = bound (0, sqrt(clvelocity[0]*clvelocity[0] + clvelocity[1]*clvelocity[1]), cl_bob_velocity_limit.value); @@ -734,13 +762,13 @@ void V_CalcRefdefUsing (const matrix4x4_t *entrendermatrix, const vec3_t clviewa bob_height_check_dest[0] = vieworg[0]; bob_height_check_dest[1] = vieworg[1]; bob_height_check_dest[2] = vieworg[2] + cl_bob_limit.value * 1.1f; - trace = CL_TraceLine(vieworg, bob_height_check_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY | (cl_bob_limit_heightcheck_dontcrosswatersurface.integer ? SUPERCONTENTS_LIQUIDSMASK : 0), collision_extendmovelength.value, true, false, NULL, false, true); + trace = CL_TraceLine(vieworg, bob_height_check_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY | (cl_bob_limit_heightcheck_dontcrosswatersurface.integer ? SUPERCONTENTS_LIQUIDSMASK : 0), 0, MATERIALFLAGMASK_TRANSLUCENT, collision_extendmovelength.value, true, false, NULL, false, true); trace1fraction = trace.fraction; bob_height_check_dest[0] = vieworg[0]; bob_height_check_dest[1] = vieworg[1]; bob_height_check_dest[2] = vieworg[2] + cl_bob_limit.value * -0.5f; - trace = CL_TraceLine(vieworg, bob_height_check_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY | (cl_bob_limit_heightcheck_dontcrosswatersurface.integer ? SUPERCONTENTS_LIQUIDSMASK : 0), collision_extendmovelength.value, true, false, NULL, false, true); + trace = CL_TraceLine(vieworg, bob_height_check_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY | (cl_bob_limit_heightcheck_dontcrosswatersurface.integer ? SUPERCONTENTS_LIQUIDSMASK : 0), 0, MATERIALFLAGMASK_TRANSLUCENT, collision_extendmovelength.value, true, false, NULL, false, true); trace2fraction = trace.fraction; bob_limit *= min(trace1fraction, trace2fraction); @@ -934,6 +962,45 @@ void V_CalcRefdef (void) } } +void V_MakeViewIsometric(void) +{ + // when using isometric view to play normal games we have to rotate the camera to make the Ortho matrix do the right thing (forward as up the screen, etc) + matrix4x4_t relative; + matrix4x4_t modifiedview; + matrix4x4_t modify; + float t[4][4]; + t[0][0] = v_isometric_xx.value; + t[0][1] = v_isometric_xy.value; + t[0][2] = v_isometric_xz.value; + t[0][3] = 0.0f; + t[1][0] = v_isometric_yx.value; + t[1][1] = v_isometric_yy.value; + t[1][2] = v_isometric_yz.value; + t[1][3] = 0.0f; + t[2][0] = v_isometric_zx.value; + t[2][1] = v_isometric_zy.value; + t[2][2] = v_isometric_zz.value; + t[2][3] = 0.0f; + t[3][0] = 0.0f; + t[3][1] = 0.0f; + t[3][2] = 0.0f; + t[3][3] = 1.0f; + Matrix4x4_FromArrayFloatGL(&modify, t[0]); + + // if the orientation is locked, extract the origin and create just a translate matrix to start with + if (v_isometric_locked_orientation.integer) + { + vec3_t vx, vy, vz, origin; + Matrix4x4_ToVectors(&r_refdef.view.matrix, vx, vy, vz, origin); + Matrix4x4_CreateTranslate(&r_refdef.view.matrix, origin[0], origin[1], origin[2]); + } + + Matrix4x4_Concat(&modifiedview, &r_refdef.view.matrix, &modify); + Matrix4x4_CreateFromQuakeEntity(&relative, v_isometric_tx.value, v_isometric_ty.value, v_isometric_tz.value, v_isometric_rot_pitch.value, v_isometric_rot_yaw.value, v_isometric_rot_roll.value, 1.0f); + Matrix4x4_Concat(&r_refdef.view.matrix, &modifiedview, &relative); +} + + void V_FadeViewFlashs(void) { // don't flash if time steps backwards @@ -1116,6 +1183,25 @@ void V_Init (void) Cvar_RegisterVariable (&v_iroll_level); Cvar_RegisterVariable (&v_ipitch_level); + Cvar_RegisterVariable(&v_isometric); + Cvar_RegisterVariable(&v_isometric_verticalfov); + Cvar_RegisterVariable(&v_isometric_xx); + Cvar_RegisterVariable(&v_isometric_xy); + Cvar_RegisterVariable(&v_isometric_xz); + Cvar_RegisterVariable(&v_isometric_yx); + Cvar_RegisterVariable(&v_isometric_yy); + Cvar_RegisterVariable(&v_isometric_yz); + Cvar_RegisterVariable(&v_isometric_zx); + Cvar_RegisterVariable(&v_isometric_zy); + Cvar_RegisterVariable(&v_isometric_zz); + Cvar_RegisterVariable(&v_isometric_tx); + Cvar_RegisterVariable(&v_isometric_ty); + Cvar_RegisterVariable(&v_isometric_tz); + Cvar_RegisterVariable(&v_isometric_rot_pitch); + Cvar_RegisterVariable(&v_isometric_rot_yaw); + Cvar_RegisterVariable(&v_isometric_rot_roll); + Cvar_RegisterVariable(&v_isometric_locked_orientation); + Cvar_RegisterVariable (&v_idlescale); Cvar_RegisterVariable (&crosshair);