]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
strafehud: implement different projection modes and allow the range to be set to...
authorJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Fri, 20 Jan 2023 20:58:50 +0000 (21:58 +0100)
committerJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Tue, 4 Apr 2023 17:47:02 +0000 (19:47 +0200)
_hud_common.cfg
qcsrc/client/hud/panel/strafehud.qc
qcsrc/client/hud/panel/strafehud.qh

index 8428b2443e5276c90dd75e7149cfead5a032de44..272c7594e3dc6ada6f95bceac738d329b65f86ff 100644 (file)
@@ -156,7 +156,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_show "1" "show units"
 seta hud_panel_strafehud_uncapped "0" "set to \"1\" to remove some safety restrictions, useful to set thinner indicator lines down to 1px or for trying out higher values for some performance degrading operations (warning: elements may turn invisible if too thin, other configurations may crash your game or look horribly ugly)"
@@ -221,6 +221,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 bb4dd0cf62c412c1ed2ae275ed122dcde0906b85..c56111934a5f3c90acbb63404935098c9cf11fa6 100644 (file)
@@ -191,6 +191,7 @@ void HUD_StrafeHUD()
                float  range_minangle;
                float  text_offset_top               = 0;
                float  text_offset_bottom            = 0;
+               float  hfov                          = getproperty(VF_FOVX);
 
                // real_* variables which are always positive with no wishangle offset
                float real_bestangle;
@@ -358,11 +359,26 @@ void HUD_StrafeHUD()
                        else
                                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)
                {
@@ -692,28 +708,32 @@ void HUD_StrafeHUD()
                                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);
+                               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);
+                                       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);
+                               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);
+                                       autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_LEFT,
+                                       true, hudangle);
 
                        // draw overturn zone
                        //   this is technically incorrect
@@ -723,14 +743,16 @@ void HUD_StrafeHUD()
                                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);
+                               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);
+                               autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_NONE,
+                               true, hudangle);
 
                        // only draw indicators if minspeed is reached
                        if(autocvar_hud_panel_strafehud_switch && speed >= minspeed && bestangle_width > 0 && autocvar_hud_panel_strafehud_switch_alpha > 0)
@@ -759,14 +781,16 @@ void HUD_StrafeHUD()
                                        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);
+                                       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);
+                                               STRAFEHUD_STYLE_DRAWFILL, STRAFEHUD_GRADIENT_NONE,
+                                               false, hudangle);
                        }
                }
 
@@ -962,6 +986,9 @@ void HUD_StrafeHUD()
                if(autocvar_hud_panel_strafehud_bestangle && direction != STRAFEHUD_DIRECTION_NONE)
                        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:
@@ -1156,8 +1183,33 @@ 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;
@@ -1192,6 +1244,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;
@@ -1206,6 +1263,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:
@@ -1260,13 +1322,13 @@ void HUD_Panel_DrawStrafeHUD(float offset, float width, float hidden_width, vect
 
                        StrafeHUD_drawGradient(
                                color, autocvar_hud_panel_strafehud_bar_neutral_color,
-                               mirror_size, original_width, mirror_offset,
-                               alpha, gradient_mirror_offset, gradientType);
+                               original_mirror_size, original_width, original_mirror_offset,
+                               alpha, gradient_mirror_offset, gradientType, range);
 
                        StrafeHUD_drawGradient(
                                color, autocvar_hud_panel_strafehud_bar_neutral_color,
-                               size, original_width, offset,
-                               alpha, gradient_offset, gradientType);
+                               original_size, original_width, original_offset,
+                               alpha, gradient_offset, gradientType, range);
        }
 }
 
@@ -1281,7 +1343,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;
@@ -1291,8 +1353,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 + segment_size.x / 2 + gradientOffset) / original_width * (gradientType == STRAFEHUD_GRADIENT_BOTH ? 2 : 1);
                if(ratio > 1) ratio = 2 - ratio;
                if(gradientType != STRAFEHUD_GRADIENT_RIGHT) ratio = 1 - ratio;
@@ -1303,7 +1368,7 @@ void StrafeHUD_drawGradient(vector color1, vector color2, vector size, float ori
 
                if(alpha_ratio > 0)
                        drawfill(
-                               panel_pos + eX * (offset + i),
+                               panel_pos + eX * segment_offset,
                                segment_size,
                                StrafeHUD_mixColors(color1, color2, ratio),
                                alpha_ratio,
index 7622ea48abca9ae9a52b81db2064505b243a8ae3..e1ed023bdd8605ed0a12a40b4d4edac72629e725 100644 (file)
@@ -70,14 +70,17 @@ float autocvar_hud_panel_strafehud_sonar_pitch_range = 0.1;
 bool autocvar_hud_panel_strafehud_vangle = false;
 vector autocvar_hud_panel_strafehud_vangle_color = '0.75 0.75 0.75';
 float autocvar_hud_panel_strafehud_vangle_size = 1;
+int autocvar_hud_panel_strafehud_projection = 1;
 
-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, float);
 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;
@@ -105,3 +108,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;