Add "smooth streaks" to projected crosshairs.

This commit is contained in:
Mari the Deer 2022-05-29 17:51:59 +02:00
commit be9aba89ae
6 changed files with 55 additions and 12 deletions

View file

@ -45,6 +45,27 @@ Class SWWMGesture : SWWMWeapon
{
return false;
}
override void HUDTick()
{
if ( !Owner ) return;
[cpos, ccol] = TraceForCrosshair();
// avoid jumpy switching
if ( formerweapon is 'SWWMWeapon' )
{
SWWMWeapon(formerweapon).lagvpos = lagvpos;
SWWMWeapon(formerweapon).prevframe = prevframe;
}
}
override void RenderUnderlay( RenderEvent e )
{
Super.RenderUnderlay(e);
// avoid jumpy switching
if ( formerweapon is 'SWWMWeapon' )
{
SWWMWeapon(formerweapon).lagvpos = lagvpos;
SWWMWeapon(formerweapon).prevframe = prevframe;
}
}
override void DoEffect()
{
Super.DoEffect();
@ -651,6 +672,17 @@ Class SWWMItemGesture : SWWMWeapon abstract
{
return false;
}
override void HUDTick()
{
if ( !Owner ) return;
[cpos, ccol] = TraceForCrosshair();
// avoid jumpy switching
if ( gest && (gest.formerweapon is 'SWWMWeapon') )
{
SWWMWeapon(gest.formerweapon).lagvpos = lagvpos;
SWWMWeapon(gest.formerweapon).prevframe = prevframe;
}
}
override void DoEffect()
{
Super.DoEffect();

View file

@ -229,6 +229,11 @@ Class SWWMUtility
return (a<0)?(a+floor(a)):(a-floor(a));
}
static clearscope double lerp( double a, double b, double theta )
{
return a*(1.-theta)+b*theta;
}
static clearscope Color LerpColor( Color a, Color b, double theta )
{
Color c = Color(

View file

@ -46,7 +46,6 @@ extend Class SWWMWeapon
// avoid jumpy switching
if ( Owner.player.PendingWeapon is 'SWWMWeapon' )
{
SWWMWeapon(Owner.player.PendingWeapon).cpos = cpos;
SWWMWeapon(Owner.player.PendingWeapon).lagvpos = lagvpos;
SWWMWeapon(Owner.player.PendingWeapon).prevframe = prevframe;
}
@ -67,11 +66,12 @@ extend Class SWWMWeapon
Vector3 ndc = SWWMUtility.ProjectPoint(sb.projdata,e.ViewPos+tdir);
if ( ndc.z >= 1. ) return;
Vector2 vpos = SWWMUtility.NDCToViewport(sb.projdata,ndc);
double frametime = ((gametic+e.fractic)-prevframe)/GameTicRate;
double theta = clamp(30.*frametime,0.,1.); // naive, but whatever
if ( !prevframe || (lagvpos == (0,0)) ) lagvpos = vpos;
double frametime = (MSTimeF()-prevframe)/1000.;
double theta = clamp(15.*frametime,0.,1.); // naive, but whatever
Vector2 oldvpos = lagvpos;
if ( !prevframe || (lagvpos == (0,0)) ) oldvpos = lagvpos = vpos;
else lagvpos = lagvpos*(1.-theta)+vpos*theta;
prevframe = gametic+e.fractic;
prevframe = MSTimeF();
int cnum = abs(CVar.FindCVar('crosshair').GetInt());
if ( !cnum ) return;
String tn = String.Format("XHAIR%s%d",(Screen.GetWidth()<640)?"S":"B",cnum);
@ -83,6 +83,8 @@ extend Class SWWMWeapon
double sz = 1.;
if ( cs > 0. ) sz = Screen.GetHeight()*cs/200.;
if ( crosshairgrow ) sz *= sb.CrosshairSize;
int streak = int(max(abs(oldvpos.x-lagvpos.x),abs(oldvpos.y-lagvpos.y)));
for ( int i=0; i<streak; i++ ) Screen.DrawTexture(ctex,false,int(SWWMUtility.lerp(oldvpos.x,lagvpos.x,i/double(streak))),int(SWWMUtility.lerp(oldvpos.y,lagvpos.y,i/double(streak))),DTA_DestWidthF,ts.x*sz,DTA_DestHeightF,ts.y*sz,DTA_AlphaChannel,true,DTA_FillColor,ccol,DTA_Alpha,(i*.5)/streak);
Screen.DrawTexture(ctex,false,int(lagvpos.x),int(lagvpos.y),DTA_DestWidthF,ts.x*sz,DTA_DestHeightF,ts.y*sz,DTA_AlphaChannel,true,DTA_FillColor,ccol);
}
ui Vector3, Color TraceForCrosshair()

View file

@ -159,23 +159,26 @@ Class Wallbuster : SWWMWeapon
Vector3 ndc = SWWMUtility.ProjectPoint(sb.projdata,e.ViewPos+tdir);
if ( ndc.z >= 1. ) return;
Vector2 vpos = SWWMUtility.NDCToViewport(sb.projdata,ndc);
double frametime = ((gametic+e.fractic)-prevframe)/GameTicRate;
double theta = clamp(30.*frametime,0.,1.); // naive, but whatever
double frametime = (MSTimeF()-prevframe)/1000.;
double theta = clamp(15.*frametime,0.,1.); // naive, but whatever
if ( !prevframe || (lagvpos == (0,0)) ) lagvpos = vpos;
else lagvpos = lagvpos*(1.-theta)+vpos*theta;
Vector2 oldvpos;
for ( int i=0; i<25; i++ )
{
tdir = level.Vec3Diff(e.ViewPos,cpos25[i]);
// project
ndc = SWWMUtility.ProjectPoint(sb.projdata,e.ViewPos+tdir);
if ( ndc.z >= 1. ) return;
vpos = SWWMUtility.NDCToViewport(sb.projdata,ndc);
if ( !prevframe || (lagvpos25[i] == (0,0)) ) lagvpos25[i] = vpos;
oldvpos = lagvpos25[i];
if ( !prevframe || (lagvpos25[i] == (0,0)) ) oldvpos = lagvpos25[i] = vpos;
else lagvpos25[i] = lagvpos25[i]*(1.-theta)+vpos*theta;
int streak = int(max(abs(oldvpos.x-lagvpos25[i].x),abs(oldvpos.y-lagvpos25[i].y)));
for ( int j=0; j<streak; j++ ) Screen.DrawTexture(ctex,false,int(SWWMUtility.lerp(oldvpos.x,lagvpos25[i].x,j/double(streak))),int(SWWMUtility.lerp(oldvpos.y,lagvpos25[i].y,j/double(streak))),DTA_DestWidthF,ts.x*sz,DTA_DestHeightF,ts.y*sz,DTA_AlphaChannel,true,DTA_FillColor,ccol,DTA_Alpha,(j*.5)/streak);
Screen.DrawTexture(ctex,false,int(lagvpos25[i].x),int(lagvpos25[i].y),DTA_DestWidthF,ts.x*sz,DTA_DestHeightF,ts.y*sz,DTA_AlphaChannel,true,DTA_FillColor,ccol25[i]);
}
prevframe = gametic+e.fractic;
prevframe = MSTimeF();
}
ui Vector3, Color TraceForCrosshair25( int i )

View file

@ -31,6 +31,7 @@ Class ExplodiumGun : SWWMWeapon
{
SWWMWeapon(Owner.player.PendingWeapon).cpos = cpos;
SWWMWeapon(Owner.player.PendingWeapon).lagvpos = lagvpos;
SWWMWeapon(Owner.player.PendingWeapon).prevframe = prevframe;
}
[sw.cpos, sw.ccol] = sw.TraceForCrosshair();
}