- VectorSet(gunangles, cl.viewmodel_push_x, cl.viewmodel_push_y, viewangles[2]);
-
- // gun model following code
- if(cl_followmodel_side.value && cl_followmodel_side_speed.value * ef_speed < 1) // bad things happen if this goes over 1, so prevent the effect
- {
- vec_t d0 = vieworg[0] - cl.gunorg_follow[0];
- vec_t d1 = vieworg[1] - cl.gunorg_follow[1];
- d = sqrt(d0 * d0 + d1 * d1);
- if(d > 0)
- {
- cl.gunorg_follow[0] = cl.gunorg_follow[0] + d0 * cl_followmodel_side_speed.value * ef_speed;
- cl.gunorg_follow[1] = cl.gunorg_follow[1] + d1 * cl_followmodel_side_speed.value * ef_speed;
- d *= (1 - cl_followmodel_side_speed.value * ef_speed);
- if(d > cl_followmodel_side_limit.value)
- {
- cl.gunorg_follow[0] = vieworg[0] - (d0 / d) * cl_followmodel_side_limit.value;
- cl.gunorg_follow[1] = vieworg[1] - (d1 / d) * cl_followmodel_side_limit.value;
- }
- }
- }
- else
- {
- cl.gunorg_follow[0] = vieworg[0];
- cl.gunorg_follow[1] = vieworg[1];
- }
-
- if(cl_followmodel_up.value && cl_followmodel_up_speed.value * ef_speed < 1) // bad things happen if this goes over 1, so prevent the effect
- {
- d = vieworg[2] - cl.gunorg_follow[2];
- cl.gunorg_follow[2] = bound(vieworg[2] - cl_followmodel_up_limit.value, cl.gunorg_follow[2] + d * cl_followmodel_up_speed.value * ef_speed, vieworg[2] + cl_followmodel_up_limit.value);
- }
- else
- cl.gunorg_follow[2] = vieworg[2];
-
- VectorCopy(cl.gunorg_follow, gunorg);
-
- // view bobbing code
- xyspeed = sqrt(cl.movement_velocity[0]*cl.movement_velocity[0] + cl.movement_velocity[1]*cl.movement_velocity[1]);
+ // 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(cl.velocity[0]*cl.velocity[0] + cl.velocity[1]*cl.velocity[1]), 400);
+
+ // vertical view bobbing code