X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fclient%2Fview.qc;h=0b2b653a7f37217d04906074c8d165c1c0e9c4fb;hp=3f881e7334e81859980b89eceb7ed9c4c7d2219d;hb=d6422602f9bf8fcc2405ca0bf5f5be4ea1e52ba4;hpb=b6073e074358619d1c84bea47c83022f8384fa16 diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index 3f881e733..0b2b653a7 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -82,6 +82,12 @@ float autocvar_cl_leanmodel_lowpass = 0.05; lowpass(value.y, frac, ref_store.y, ref_out.y); \ } MACRO_END +#define lowpass2_limited(value, frac, limit, ref_store, ref_out) MACRO_BEGIN \ +{ \ + lowpass_limited(value.x, frac, limit, ref_store.x, ref_out.x); \ + lowpass_limited(value.y, frac, limit, ref_store.y, ref_out.y); \ +} MACRO_END + #define highpass2(value, frac, ref_store, ref_out) MACRO_BEGIN \ { \ highpass(value.x, frac, ref_store.x, ref_out.x); \ @@ -115,10 +121,17 @@ float autocvar_cl_leanmodel_lowpass = 0.05; highpass_limited(value.z, frac, limit, ref_store.z, ref_out.z); \ } MACRO_END +#define lowpass3_limited(value, frac, limit, ref_store, ref_out) MACRO_BEGIN \ +{ \ + lowpass_limited(value.x, frac, limit, ref_store.x, ref_out.x); \ + lowpass_limited(value.y, frac, limit, ref_store.y, ref_out.y); \ + lowpass_limited(value.z, frac, limit, ref_store.z, ref_out.z); \ +} MACRO_END + void viewmodel_animate(entity this) { static float prevtime; - float frametime = (time - prevtime) * STAT(MOVEVARS_TIMESCALE); + float frametime = (time - prevtime); prevtime = time; if (autocvar_chase_active) return; @@ -139,68 +152,72 @@ void viewmodel_animate(entity this) } oldonground = clonground; - vector gunorg = '0 0 0', gunangles = '0 0 0'; - static vector gunorg_prev = '0 0 0', gunangles_prev = '0 0 0'; bool teleported = view.csqcmodel_teleported; - // 1. if we teleported, clear the frametime... the lowpass will recover the previous value then - if (teleported) + float frac; + if(autocvar_cl_followmodel) { - // try to fix the first highpass; result is NOT - // perfect! TODO find a better fix - gunangles_prev = view_angles; - gunorg_prev = view_origin; + vector gunorg = '0 0 0'; + static vector vel_average; + static vector gunorg_prev = '0 0 0'; + static vector gunorg_adjustment_highpass; + static vector gunorg_adjustment_lowpass; + + vector vel; + vector forward, right = '0 0 0', up = '0 0 0'; + MAKEVECTORS(makevectors, view_angles, forward, right, up); + vel.x = view.velocity * forward; + vel.y = view.velocity * right * -1; + vel.z = view.velocity * up; + frac = avg_factor(autocvar_cl_followmodel_highpass1); + lowpass3_limited(vel, frac, autocvar_cl_followmodel_limit, vel_average, gunorg); + + gunorg *= -autocvar_cl_followmodel_speed * 0.042; + + // 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! + frac = avg_factor(autocvar_cl_followmodel_highpass); + highpass3(gunorg, frac, gunorg_adjustment_highpass, gunorg); + frac = avg_factor(autocvar_cl_followmodel_lowpass); + lowpass3(gunorg, frac, gunorg_adjustment_lowpass, gunorg); + + this.origin += gunorg; } - float frac; - static vector gunorg_highpass = '0 0 0'; - - // 2. for the gun origin, only keep the high frequency (non-DC) parts, which is "somewhat like velocity" - gunorg_highpass += gunorg_prev; - frac = avg_factor(autocvar_cl_followmodel_highpass1); - highpass3_limited(view_origin, frac, autocvar_cl_followmodel_limit, gunorg_highpass, gunorg); - gunorg_prev = view_origin; - gunorg_highpass -= gunorg_prev; - - static vector gunangles_highpass = '0 0 0'; - - // in the highpass, we _store_ the DIFFERENCE to the actual view angles... - gunangles_highpass += gunangles_prev; - PITCH(gunangles_highpass) += 360 * floor((PITCH(view_angles) - PITCH(gunangles_highpass)) / 360 + 0.5); - YAW(gunangles_highpass) += 360 * floor((YAW(view_angles) - YAW(gunangles_highpass)) / 360 + 0.5); - ROLL(gunangles_highpass) += 360 * floor((ROLL(view_angles) - ROLL(gunangles_highpass)) / 360 + 0.5); - frac = avg_factor(autocvar_cl_leanmodel_highpass1); - highpass2_limited(view_angles, frac, autocvar_cl_leanmodel_limit, gunangles_highpass, gunangles); - gunangles_prev = view_angles; - gunangles_highpass -= gunangles_prev; - - // 3. calculate the RAW adjustment vectors - gunorg.x *= (autocvar_cl_followmodel ? -autocvar_cl_followmodel_speed : 0); - gunorg.y *= (autocvar_cl_followmodel ? -autocvar_cl_followmodel_speed : 0); - gunorg.z *= (autocvar_cl_followmodel ? -autocvar_cl_followmodel_speed : 0); - - PITCH(gunangles) *= (autocvar_cl_leanmodel ? -autocvar_cl_leanmodel_speed : 0); - YAW(gunangles) *= (autocvar_cl_leanmodel ? -autocvar_cl_leanmodel_speed : 0); - ROLL(gunangles) = 0; - - static vector gunorg_adjustment_highpass; - static vector gunorg_adjustment_lowpass; - static vector gunangles_adjustment_highpass; - static vector gunangles_adjustment_lowpass; - - // 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! - frac = avg_factor(autocvar_cl_followmodel_highpass); - highpass3(gunorg, frac, gunorg_adjustment_highpass, gunorg); - frac = avg_factor(autocvar_cl_followmodel_lowpass); - lowpass3(gunorg, frac, gunorg_adjustment_lowpass, gunorg); - - // we assume here: PITCH = 0, YAW = 1, ROLL = 2 - frac = avg_factor(autocvar_cl_leanmodel_highpass); - highpass2(gunangles, frac, gunangles_adjustment_highpass, gunangles); - frac = avg_factor(autocvar_cl_leanmodel_lowpass); - lowpass2(gunangles, frac, gunangles_adjustment_lowpass, gunangles); + if(autocvar_cl_leanmodel) + { + vector gunangles = '0 0 0'; + static vector gunangles_prev = '0 0 0'; + static vector gunangles_highpass = '0 0 0'; + static vector gunangles_adjustment_highpass; + static vector gunangles_adjustment_lowpass; + + if (teleported) + gunangles_prev = view_angles; + + // in the highpass, we _store_ the DIFFERENCE to the actual view angles... + gunangles_highpass += gunangles_prev; + PITCH(gunangles_highpass) += 360 * floor((PITCH(view_angles) - PITCH(gunangles_highpass)) / 360 + 0.5); + YAW(gunangles_highpass) += 360 * floor((YAW(view_angles) - YAW(gunangles_highpass)) / 360 + 0.5); + ROLL(gunangles_highpass) += 360 * floor((ROLL(view_angles) - ROLL(gunangles_highpass)) / 360 + 0.5); + frac = avg_factor(autocvar_cl_leanmodel_highpass1); + highpass2_limited(view_angles, frac, autocvar_cl_leanmodel_limit, gunangles_highpass, gunangles); + gunangles_prev = view_angles; + gunangles_highpass -= gunangles_prev; + + PITCH(gunangles) *= -autocvar_cl_leanmodel_speed; + YAW(gunangles) *= -autocvar_cl_leanmodel_speed; + + // we assume here: PITCH = 0, YAW = 1, ROLL = 2 + frac = avg_factor(autocvar_cl_leanmodel_highpass); + highpass2(gunangles, frac, gunangles_adjustment_highpass, gunangles); + frac = avg_factor(autocvar_cl_leanmodel_lowpass); + lowpass2(gunangles, frac, gunangles_adjustment_lowpass, gunangles); + + gunangles.x = -gunangles.x; // pitch was inverted, now that actually matters + this.angles += gunangles; + } float xyspeed = bound(0, vlen(vec2(view.velocity)), 400); @@ -222,7 +239,6 @@ void viewmodel_animate(entity this) // Sajt: I tried to smooth out the transitions between bob and no bob, which works // for the most part, but for some reason when you go through a message trigger or // pick up an item or anything like that it will momentarily jolt the gun. - vector forward, right = '0 0 0', up = '0 0 0'; float bspeed; float t = 1; float s = time * autocvar_cl_bobmodel_speed; @@ -244,17 +260,12 @@ void viewmodel_animate(entity this) t *= 5; } bspeed = xyspeed * 0.01; - MAKEVECTORS(makevectors, view_angles, forward, right, up); - float bobr = bspeed * autocvar_cl_bobmodel_side * autocvar_cl_viewmodel_scale * sin(s) * t; - gunorg += bobr * right; - float bobu = bspeed * autocvar_cl_bobmodel_up * autocvar_cl_viewmodel_scale * cos(s * 2) * t; - gunorg += bobu * up; - } - vector v = rotate(gunorg, YAW(view_angles) * DEG2RAD); // rotate world coordinates to relative ones - v.z = gunorg.z; - this.origin += v; - gunangles.x = -gunangles.x; // pitch was inverted, now that actually matters - this.angles += gunangles; + vector gunorg = '0 0 0'; + gunorg.y += bspeed * autocvar_cl_bobmodel_side * autocvar_cl_viewmodel_scale * sin(s) * t; + gunorg.z += bspeed * autocvar_cl_bobmodel_up * autocvar_cl_viewmodel_scale * cos(s * 2) * t; + + this.origin += gunorg; + } } .vector viewmodel_origin, viewmodel_angles;