Two-way crosshair merging.

This commit is contained in:
Mari the Deer 2022-09-25 14:02:53 +02:00
commit df3e43c935
2 changed files with 28 additions and 16 deletions

View file

@ -32,7 +32,7 @@ extend Class SWWMHandler
transient ui Color tcol[MAX_CROSSHAIRS]; // current crosshair colors
transient ui SWWMProjectionData tprojdata; // cached Gutamatics projection data
transient ui Vector3 lagtndc[MAX_CROSSHAIRS]; // "lagged" NDC for crosshairs
transient ui Weapon lasttw; // last player weapon, to "reset" crosshair positions
transient ui bool tactive[MAX_CROSSHAIRS]; // denotes that the crosshair is "active" for drawing
transient ui double prevframe; // previous frame timestamp
private ui void TraceCrosshairs( RenderEvent e )
@ -43,11 +43,16 @@ extend Class SWWMHandler
if ( !sw )
{
numcrosshairs = 0;
for ( int i=0; i<MAX_CROSSHAIRS; i++ )
tactive[i] = false;
return;
}
numcrosshairs = clamp(sw.NumCrosshairs,1,MAX_CROSSHAIRS);
for ( int i=0; i<numcrosshairs; i++ )
{
traceofs[i] = sw.GetTraceOffset(i);
tactive[i] = true;
}
let mo = players[consoleplayer].mo;
if ( !ctr ) ctr = new("SWWMCrosshairTracer");
ctr.ignoreme = mo;
@ -100,7 +105,8 @@ extend Class SWWMHandler
private ui void RenderCrosshairs( RenderEvent e )
{
double frametime = (MSTimeF()-prevframe)/1000.;
double curframe = MSTimeF();
double frametime = (curframe-prevframe)/1000.;
double theta = clamp(15.*frametime,0.,.5); // naive, but whatever
// draw precise crosshair(s)
if ( automapactive || (players[consoleplayer].Camera != players[consoleplayer].mo) || (players[consoleplayer].cheats&CF_CHASECAM) || (numcrosshairs <= 0) ) return;
@ -119,8 +125,8 @@ extend Class SWWMHandler
if ( cs > 0. ) sz = Screen.GetHeight()*cs/200.;
if ( crosshairgrow ) sz *= StatusBar.CrosshairSize;
SWWMUtility.PrepareProjData(tprojdata,e.ViewPos,e.ViewAngle,e.ViewPitch,e.ViewRoll,players[consoleplayer].fov);
let w = players[consoleplayer].ReadyWeapon;
for ( int i=0; i<numcrosshairs; i++ )
Vector2 actpos[MAX_CROSSHAIRS];
for ( int i=0; i<MAX_CROSSHAIRS; i++ )
{
Vector3 cpos = tpos[i];
Color ccol = tcol[i];
@ -135,17 +141,23 @@ extend Class SWWMHandler
lagtndc[i] = SWWMUtility.LerpVector3(lagtndc[i],ndc,theta);
if ( lagtndc[i].z >= 1. ) continue;
Vector2 lagvpos = SWWMUtility.NDCToViewport(tprojdata,lagtndc[i]);
if ( !tactive[i] ) continue;
// draw
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);
double alph = 1.;
if ( i < numcrosshairs ) actpos[i] = lagvpos;
else
{
// unused crosshairs must "linger" until they merge with the ones that are drawn
int j = (i-numcrosshairs)%numcrosshairs;
double dist = (lagvpos-actpos[j]).length();
if ( (streak <= 0) && (dist < 1.) )
tactive[i] = false;
alph = clamp(dist/max(2,streak+2),0.,1.); // this should make the merge less jarring
}
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)*alph);
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,DTA_Alpha,alph);
}
// copy over used slots to unused slots, so transition between weapons is smoother
int j = 0;
for ( int i=numcrosshairs; i<MAX_CROSSHAIRS; i++ )
{
lagtndc[i] = lagtndc[j];
j = (j+1)%numcrosshairs;
}
prevframe = MSTimeF();
prevframe = curframe;
}
}