]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Add patch from Juhu/strafehud-features branch: "strafehud: implement different projec...
authorJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Fri, 20 Jan 2023 21:40:12 +0000 (22:40 +0100)
committerJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Fri, 20 Jan 2023 21:40:12 +0000 (22:40 +0100)
_hud_common.cfg
qcsrc/client/hud/panel/strafehud.qc
qcsrc/client/hud/panel/strafehud.qh

index b85631d805eea18fb814f9cd55fa0d7c04207de8..1089cac6463bf98dfefedc81d959ebb2af293af8 100644 (file)
@@ -150,7 +150,7 @@ seta hud_panel_scoreboard_itemstats_showdelay_minpos 0.75 "delay displaying the
 
 seta _hud_panel_strafehud_demo "0" "strafehud changes angle during configure"
 seta hud_panel_strafehud_mode "0" "strafehud mode which controls whether the strafehud is centered at \"0\" = view angle, \"1\" = velocity angle"
-seta hud_panel_strafehud_range "90" "the angle range up to 360 degrees displayed on the strafehud, \"0\" = dynamic (chooses the minimum range required to still see the whole area needed for accelerating)"
+seta hud_panel_strafehud_range "90" "the angle range up to 360 degrees displayed on the strafehud, \"-1\" = current fov, \"0\" = dynamic (chooses the minimum range required to still see the whole area needed for accelerating)"
 seta hud_panel_strafehud_style "2" "\"0\" = no styling, \"1\" = progress bar style for the strafe bar, \"2\" = gradient for the strafe bar"
 seta hud_panel_strafehud_unit "1" "speed unit (1 = qu/s, 2 = m/s, 3 = km/h, 4 = mph, 5 = knots), length unit (1 = qu, 2 = m, 3 = km, 4 = mi, 5 = nmi)"
 seta hud_panel_strafehud_unit_show "1" "show units"
@@ -216,6 +216,7 @@ seta hud_panel_strafehud_sonar_pitch_range "0.1" "dynamic playback speed range o
 seta hud_panel_strafehud_vangle "0" "set to \"1\" to enable the vertical angle indicator"
 seta hud_panel_strafehud_vangle_color "0.75 0.75 0.75" "color of the vertical angle text"
 seta hud_panel_strafehud_vangle_size "1" "size of the vertical angle text (relative to the panel height)"
+seta hud_panel_strafehud_projection "0" "strafehud projection mode, \"0\" = Linear, \"1\" = Perspective, \"2\" = Panoramic"
 
 // hud panel aliases
 alias quickmenu "cl_cmd hud quickmenu ${* ?}"
index cf2e36cb3452d37c01344e949d229988be2088db..6d82481272e82ed452a1d469bdd9db494fb9647e 100644 (file)
@@ -199,6 +199,7 @@ void HUD_StrafeHUD()
         float  arrow_size = max(panel_size.y * min(autocvar_hud_panel_strafehud_angle_arrow_size, 10), 0); // there's only one size cvar for the arrows, they will always have a 45° angle to ensure proper rendering without antialiasing
         float  text_offset_top = 0;
         float  text_offset_bottom = 0;
+        float  hfov                     = getproperty(VF_FOVX);
 
         if(onground)
         {
@@ -377,11 +378,25 @@ void HUD_StrafeHUD()
                 hudangle = range_minangle; // use minimum angle required if dynamically setting hud angle
             }
         }
+        else if(autocvar_hud_panel_strafehud_range < 0)
+        {
+            hudangle = hfov;
+        }
         else
         {
             hudangle = bound(0, fabs(autocvar_hud_panel_strafehud_range), 360); // limit HUD range to 360 degrees, higher values don't make sense
         }
 
+        // limit strafe-meter angle to values suitable for the current projection mode
+        switch(autocvar_hud_panel_strafehud_projection) {
+            case STRAFEHUD_PROJECTION_PERSPECTIVE:
+                hudangle = min(hudangle, 170);
+                break;
+            case STRAFEHUD_PROJECTION_PANORAMIC:
+                hudangle = min(hudangle, 350);
+                break;
+        }
+
         // detect air strafe turning
         if((!strafekeys && vlen(vec2(movement)) > 0) || onground || autocvar__hud_configure)
         {
@@ -707,20 +722,20 @@ void HUD_StrafeHUD()
             overturn_offset += shift_offset;
 
             // draw left acceleration zone
-            HUD_Panel_DrawStrafeHUD(accelzone_left_offset, accelzone_width, hidden_width, autocvar_hud_panel_strafehud_bar_accel_color, autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_LEFT);
+            HUD_Panel_DrawStrafeHUD(accelzone_left_offset, accelzone_width, hidden_width, autocvar_hud_panel_strafehud_bar_accel_color, autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_LEFT, true, hudangle);
             if(autocvar_hud_panel_strafehud_bar_preaccel)
-                HUD_Panel_DrawStrafeHUD(preaccelzone_left_offset, preaccelzone_width, hidden_width, autocvar_hud_panel_strafehud_bar_accel_color, autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_RIGHT);
+                HUD_Panel_DrawStrafeHUD(preaccelzone_left_offset, preaccelzone_width, hidden_width, autocvar_hud_panel_strafehud_bar_accel_color, autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_RIGHT, true, hudangle);
 
             // draw right acceleration zone
-            HUD_Panel_DrawStrafeHUD(accelzone_right_offset, accelzone_width, hidden_width, autocvar_hud_panel_strafehud_bar_accel_color, autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_RIGHT);
+            HUD_Panel_DrawStrafeHUD(accelzone_right_offset, accelzone_width, hidden_width, autocvar_hud_panel_strafehud_bar_accel_color, autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_RIGHT, true, hudangle);
             if(autocvar_hud_panel_strafehud_bar_preaccel)
-                HUD_Panel_DrawStrafeHUD(preaccelzone_right_offset, preaccelzone_width, hidden_width, autocvar_hud_panel_strafehud_bar_accel_color, autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_LEFT);
+                HUD_Panel_DrawStrafeHUD(preaccelzone_right_offset, preaccelzone_width, hidden_width, autocvar_hud_panel_strafehud_bar_accel_color, autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_LEFT, true, hudangle);
 
             // draw overturn zone (technically incorrect, acceleration decreases at 90 degrees but speed loss happens a little bit after 90 degrees, however due to sv_airstopaccelerate that's hard to calculate)
-            HUD_Panel_DrawStrafeHUD(overturn_offset, overturn_width, hidden_width, autocvar_hud_panel_strafehud_bar_overturn_color, autocvar_hud_panel_strafehud_bar_overturn_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_BOTH);
+            HUD_Panel_DrawStrafeHUD(overturn_offset, overturn_width, hidden_width, autocvar_hud_panel_strafehud_bar_overturn_color, autocvar_hud_panel_strafehud_bar_overturn_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_BOTH, true, hudangle);
 
             // draw neutral zone
-            HUD_Panel_DrawStrafeHUD(neutral_offset, neutral_width, hidden_width, autocvar_hud_panel_strafehud_bar_neutral_color, autocvar_hud_panel_strafehud_bar_neutral_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_NONE);
+            HUD_Panel_DrawStrafeHUD(neutral_offset, neutral_width, hidden_width, autocvar_hud_panel_strafehud_bar_neutral_color, autocvar_hud_panel_strafehud_bar_neutral_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_NONE, true, hudangle);
 
             if(autocvar_hud_panel_strafehud_switch && speed >= minspeed && bestangle_width > 0 && autocvar_hud_panel_strafehud_switch_alpha > 0) // only draw indicators if minspeed is reached
             {
@@ -744,8 +759,8 @@ void HUD_StrafeHUD()
                         offset -= bestangle_width;
                 }
 
-                HUD_Panel_DrawStrafeHUD(switch_offset, bestangle_width, hidden_width, autocvar_hud_panel_strafehud_switch_color, autocvar_hud_panel_strafehud_switch_alpha * panel_fg_alpha, STRAFEHUD_STYLE_DRAWFILL, STRAFEHUD_GRADIENT_NONE);
-                if(direction == STRAFEHUD_DIRECTION_NONE) HUD_Panel_DrawStrafeHUD(offset, bestangle_width, hidden_width, autocvar_hud_panel_strafehud_switch_color, autocvar_hud_panel_strafehud_switch_alpha * panel_fg_alpha, STRAFEHUD_STYLE_DRAWFILL, STRAFEHUD_GRADIENT_NONE);
+                HUD_Panel_DrawStrafeHUD(switch_offset, bestangle_width, hidden_width, autocvar_hud_panel_strafehud_switch_color, autocvar_hud_panel_strafehud_switch_alpha * panel_fg_alpha, STRAFEHUD_STYLE_DRAWFILL, STRAFEHUD_GRADIENT_NONE, false, hudangle);
+                if(direction == STRAFEHUD_DIRECTION_NONE) HUD_Panel_DrawStrafeHUD(offset, bestangle_width, hidden_width, autocvar_hud_panel_strafehud_switch_color, autocvar_hud_panel_strafehud_switch_alpha * panel_fg_alpha, STRAFEHUD_STYLE_DRAWFILL, STRAFEHUD_GRADIENT_NONE, false, hudangle);
             }
         }
 
@@ -910,6 +925,9 @@ void HUD_StrafeHUD()
             ghost_offset = bound(0, (odd_angles ? odd_bestangle_offset : bestangle_offset), panel_size.x);
         }
 
+        currentangle_offset = StrafeHUD_projectOffset(currentangle_offset, hudangle);
+        ghost_offset = StrafeHUD_projectOffset(ghost_offset, hudangle);
+
         switch(autocvar_hud_panel_strafehud_angle_style)
         {
             case STRAFEHUD_INDICATOR_SOLID:
@@ -1050,8 +1068,30 @@ void HUD_StrafeHUD()
     hud_lasttime = time;
 }
 
+float StrafeHUD_projectOffset(float offset, float range) {
+    range *= DEG2RAD / 2;
+    float angle = (offset - (panel_size.x/2)) / (panel_size.x/2) * range;
+    switch(autocvar_hud_panel_strafehud_projection) {
+        default:
+        case STRAFEHUD_PROJECTION_LINEAR:
+            return offset;
+        case STRAFEHUD_PROJECTION_PERSPECTIVE:
+            offset = tan(angle) / tan(range);
+            break;
+        case STRAFEHUD_PROJECTION_PANORAMIC:
+            offset = tan(angle/2) / tan(range/2);
+            break;
+    }
+    offset = offset * (panel_size.x/2) + (panel_size.x/2);
+    return offset;
+}
+
+float StrafeHUD_projectWidth(float offset, float width, float range) {
+    return StrafeHUD_projectOffset(offset + width, range) - StrafeHUD_projectOffset(offset, range);
+}
+
 // functions to make hud elements align perfectly in the hud area
-void HUD_Panel_DrawStrafeHUD(float offset, float width, float hidden_width, vector color, float alpha, int type, int gradientType)
+void HUD_Panel_DrawStrafeHUD(float offset, float width, float hidden_width, vector color, float alpha, int type, int gradientType, bool projectWidth, float range)
 {
     float mirror_offset, mirror_width;
     vector size = panel_size;
@@ -1084,6 +1124,11 @@ void HUD_Panel_DrawStrafeHUD(float offset, float width, float hidden_width, vect
     }
     size.x = width;
 
+    vector original_size = size;
+    float original_offset = offset;
+    if(projectWidth && size.x > 0) size.x = StrafeHUD_projectWidth(offset, size.x, range);
+    offset = StrafeHUD_projectOffset(offset, range);
+
     if(mirror_offset < 0)
     {
         mirror_width += mirror_offset;
@@ -1098,6 +1143,11 @@ void HUD_Panel_DrawStrafeHUD(float offset, float width, float hidden_width, vect
     }
     mirror_size.x = mirror_width;
 
+    vector original_mirror_size = mirror_size;
+    float original_mirror_offset = mirror_offset;
+    if(projectWidth && mirror_size.x > 0) mirror_size.x = StrafeHUD_projectWidth(mirror_offset, mirror_size.x, range);
+    mirror_offset = StrafeHUD_projectOffset(mirror_offset, range);
+
     switch(type)
     {
         default:
@@ -1136,8 +1186,8 @@ void HUD_Panel_DrawStrafeHUD(float offset, float width, float hidden_width, vect
                     gradient_mirror_offset = 0;
             }
 
-            StrafeHUD_drawGradient(color, autocvar_hud_panel_strafehud_bar_neutral_color, mirror_size, original_width, mirror_offset, alpha, gradient_mirror_offset, gradientType);
-            StrafeHUD_drawGradient(color, autocvar_hud_panel_strafehud_bar_neutral_color, size, original_width, offset, alpha, gradient_offset, gradientType);
+            StrafeHUD_drawGradient(color, autocvar_hud_panel_strafehud_bar_neutral_color, original_mirror_size, original_width, original_mirror_offset, alpha, gradient_mirror_offset, gradientType, range);
+            StrafeHUD_drawGradient(color, autocvar_hud_panel_strafehud_bar_neutral_color, original_size, original_width, original_offset, alpha, gradient_offset, gradientType, range);
     }
 }
 
@@ -1152,7 +1202,7 @@ vector StrafeHUD_mixColors(vector color1, vector color2, float ratio)
     return mixedColor;
 }
 
-void StrafeHUD_drawGradient(vector color1, vector color2, vector size, float original_width, float offset, float alpha, float gradientOffset, int gradientType)
+void StrafeHUD_drawGradient(vector color1, vector color2, vector size, float original_width, float offset, float alpha, float gradientOffset, int gradientType, float range)
 {
     float color_ratio, alpha1, alpha2;
     vector segment_size = size;
@@ -1162,8 +1212,11 @@ void StrafeHUD_drawGradient(vector color1, vector color2, vector size, float ori
     color_ratio = alpha1/(alpha1+alpha2);
     for(int i = 0; i < size.x; ++i)
     {
-        float ratio, alpha_ratio, combine_ratio1, combine_ratio2;
+        float ratio, alpha_ratio, combine_ratio1, combine_ratio2, segment_offset;
+        segment_offset = offset + i;
         segment_size.x = min(size.x - i, 1); // each gradient segment is 1 unit wide except if there is less than 1 unit of gradient remaining
+        segment_size.x = StrafeHUD_projectWidth(segment_offset, segment_size.x, range);
+        segment_offset = StrafeHUD_projectOffset(segment_offset, range);
         ratio = (i + gradientOffset) / original_width * (gradientType == STRAFEHUD_GRADIENT_BOTH ? 2 : 1);
         if(ratio > 1) ratio = 2 - ratio;
         if(gradientType != STRAFEHUD_GRADIENT_RIGHT) ratio = 1 - ratio;
@@ -1171,7 +1224,7 @@ void StrafeHUD_drawGradient(vector color1, vector color2, vector size, float ori
         combine_ratio1 = ratio*(1-color_ratio);
         combine_ratio2 = (1-ratio)*color_ratio;
         ratio = (combine_ratio1 + combine_ratio2) == 0 ? 1 : combine_ratio1/(combine_ratio1 + combine_ratio2);
-        if(alpha_ratio > 0) drawfill(panel_pos + eX * (offset + i), segment_size, StrafeHUD_mixColors(color1, color2, ratio), alpha_ratio, DRAWFLAG_NORMAL);
+        if(alpha_ratio > 0) drawfill(panel_pos + eX * segment_offset, segment_size, StrafeHUD_mixColors(color1, color2, ratio), alpha_ratio, DRAWFLAG_NORMAL);
     }
 }
 
index 295fa83a8556eb12b7d4b55d68201cce6d7e4ae1..afa53f5d4d0f97953328ed1cfe467128cabe41d1 100644 (file)
@@ -5,7 +5,7 @@ AUTOCVAR_SAVE(hud_panel_strafehud, int, 3, "enable this panel, 1 = show if not o
 AUTOCVAR_SAVE(_hud_panel_strafehud_demo, bool, false, "strafehud changes angle during configure");
 AUTOCVAR_SAVE(hud_panel_strafehud_dynamichud, bool, true, "apply the dynamic hud effects to this panel");
 AUTOCVAR_SAVE(hud_panel_strafehud_mode, int, 0, "strafehud mode which controls whether the strafehud is centered at \"0\" = view angle, \"1\" = velocity angle");
-AUTOCVAR_SAVE(hud_panel_strafehud_range, float, 90, "the angle range up to 360 degrees displayed on the strafehud, \"0\" = dynamic (chooses the minimum range required to still see the whole area needed for accelerating)");
+AUTOCVAR_SAVE(hud_panel_strafehud_range, float, 90, "the angle range up to 360 degrees displayed on the strafehud, \"-1\" = current fov, \"0\" = dynamic (chooses the minimum range required to still see the whole area needed for accelerating)");
 AUTOCVAR_SAVE(hud_panel_strafehud_style, int, 2, "\"0\" = no styling, \"1\" = progress bar style for the strafe bar, \"2\" = gradient for the strafe bar");
 AUTOCVAR_SAVE(hud_panel_strafehud_unit, int, 1, "speed unit (1 = qu/s, 2 = m/s, 3 = km/h, 4 = mph, 5 = knots), length unit (1 = qu, 2 = m, 3 = km, 4 = mi, 5 = nmi)");
 AUTOCVAR_SAVE(hud_panel_strafehud_unit_show, bool, true, "show units");
@@ -71,14 +71,17 @@ AUTOCVAR_SAVE(hud_panel_strafehud_sonar_pitch_range, float, 0.1, "dynamic playba
 AUTOCVAR_SAVE(hud_panel_strafehud_vangle, bool, false, "set to \"1\" to enable the vertical angle indicator");
 AUTOCVAR_SAVE(hud_panel_strafehud_vangle_color, vector, '0.75 0.75 0.75', "color of the vertical angle text");
 AUTOCVAR_SAVE(hud_panel_strafehud_vangle_size, float, 1, "size of the vertical angle text (relative to the panel height)");
+AUTOCVAR_SAVE(hud_panel_strafehud_projection, int, 1, "strafehud projection mode, \"0\" = Linear, \"1\" = Perspective, \"2\" = Panoramic");
 
-void HUD_Panel_DrawStrafeHUD(float, float, float, vector, float, int, int);
+void HUD_Panel_DrawStrafeHUD(float, float, float, vector, float, int, int, bool, float);
 vector StrafeHUD_mixColors(vector, vector, float);
-void StrafeHUD_drawGradient(vector, vector, vector, float, float, float, float, int);
+void StrafeHUD_drawGradient(vector, vector, vector, float, float, float, float, int, float);
 float GetLengthUnitFactor(int);
 string GetLengthUnit(int);
 void StrafeHUD_drawStrafeArrow(vector, float, vector, float, bool);
 bool StrafeHUD_drawTextIndicator(string, float, vector, float, float, float, int);
+float StrafeHUD_projectOffset(float, float);
+float StrafeHUD_projectWidth(float, float, float);
 
 const int STRAFEHUD_MODE_VIEW_CENTERED = 0;
 const int STRAFEHUD_MODE_VELOCITY_CENTERED = 1;
@@ -106,3 +109,7 @@ const int STRAFEHUD_INDICATOR_DASHED = 2;
 
 const int STRAFEHUD_TEXT_TOP = 0;
 const int STRAFEHUD_TEXT_BOTTOM = 1;
+
+const int STRAFEHUD_PROJECTION_LINEAR = 0;
+const int STRAFEHUD_PROJECTION_PERSPECTIVE = 1;
+const int STRAFEHUD_PROJECTION_PANORAMIC = 2;