While in the latter case this may result in longer loops, it also reduces GC thrashing by not needing to allocate an iterator every time. This also simplifies the DoBlast code as there is no longer a need to manually traverse portals vertically.
116 lines
5 KiB
Text
116 lines
5 KiB
Text
// ported and optimized from old debug test mod
|
|
|
|
extend Class SWWMHandler
|
|
{
|
|
ui SWWMProjectionData projdata;
|
|
|
|
private ui void DrawWorldLine( RenderEvent e, Vector3 apos, Vector3 bpos, Color col )
|
|
{
|
|
Vector3 a = SWWMUtility.ProjectPoint(projdata,e.viewpos+level.Vec3Diff(e.viewpos,apos)),
|
|
b = SWWMUtility.ProjectPoint(projdata,e.viewpos+level.Vec3Diff(e.viewpos,bpos));
|
|
if ( (a.z > 1.) && (b.z > 1.) ) return;
|
|
if ( (a.z == -double.infinity) || (b.z == -double.infinity) ) return; // how???
|
|
double da, db, s;
|
|
Vector3 p;
|
|
da = a dot (0.,0.,-1.)-1.;
|
|
db = b dot (0.,0.,-1.)-1.;
|
|
if ( da-db != 0. )
|
|
{
|
|
s = da/(da-db);
|
|
p = (a.x+s*(b.x-a.x),a.y+s*(b.y-a.y),a.z+s*(b.z-a.z));
|
|
if ( a.z > 1. ) a = p;
|
|
if ( b.z > 1. ) b = p;
|
|
}
|
|
Vector2 va = SWWMUtility.NDCToViewport(projdata,a);
|
|
Vector2 vb = SWWMUtility.NDCToViewport(projdata,b);
|
|
Screen.DrawLine(int(va.x),int(va.y),int(vb.x),int(vb.y),col);
|
|
}
|
|
|
|
private ui void DrawWorldCircle( RenderEvent e, Vector3 pos, double radius, Color col )
|
|
{
|
|
let [x, y, z] = SWWMUtility.GetAxes(e.viewangle,e.viewpitch,e.viewroll);
|
|
Vector3 ndc[64];
|
|
for ( int i=0; i<64; i++ )
|
|
{
|
|
Vector3 wpos = e.viewpos+level.Vec3Diff(e.viewpos,level.Vec3Offset(pos,SWWMUtility.CircleOffset(y,z,i*5.625,radius)));
|
|
ndc[i] = SWWMUtility.ProjectPoint(projdata,wpos);
|
|
}
|
|
for ( int i=0; i<64; i++ )
|
|
{
|
|
Vector3 a = ndc[i], b = ndc[(i+1)%64];
|
|
if ( (a.z > 1.) && (b.z > 1.) ) continue;
|
|
if ( (a.z == -double.infinity) || (b.z == -double.infinity) ) continue; // how???
|
|
double da, db, s;
|
|
Vector3 p;
|
|
da = a dot (0.,0.,-1.)-1.;
|
|
db = b dot (0.,0.,-1.)-1.;
|
|
if ( da-db != 0. )
|
|
{
|
|
s = da/(da-db);
|
|
p = (a.x+s*(b.x-a.x),a.y+s*(b.y-a.y),a.z+s*(b.z-a.z));
|
|
if ( a.z > 1. ) a = p;
|
|
if ( b.z > 1. ) b = p;
|
|
}
|
|
Vector2 va = SWWMUtility.NDCToViewport(projdata,a);
|
|
Vector2 vb = SWWMUtility.NDCToViewport(projdata,b);
|
|
Screen.DrawLine(int(va.x),int(va.y),int(vb.x),int(vb.y),col);
|
|
}
|
|
}
|
|
|
|
private ui void DrawActor( RenderEvent e, Actor a )
|
|
{
|
|
Vector3 pos = SWWMUtility.LerpVector3(a.prev,a.pos,e.FracTic);
|
|
if ( a is 'DynamicLight' ) DrawWorldCircle(e,pos,a.args[3]*2,Color(a.args[0],a.args[1],a.args[2]));
|
|
if ( (a.radius > 0.) && (a.height > 0.) )
|
|
{
|
|
Vector3 b1, b2;
|
|
b1 = pos-(a.radius,a.radius,0);
|
|
b2 = pos+(a.radius,a.radius,a.height);
|
|
DrawWorldLine(e,(b1.x,b1.y,b1.z),(b1.x,b2.y,b1.z),"White");
|
|
DrawWorldLine(e,(b1.x,b2.y,b1.z),(b2.x,b2.y,b1.z),"White");
|
|
DrawWorldLine(e,(b2.x,b2.y,b1.z),(b2.x,b1.y,b1.z),"White");
|
|
DrawWorldLine(e,(b2.x,b1.y,b1.z),(b1.x,b1.y,b1.z),"White");
|
|
DrawWorldLine(e,(b1.x,b1.y,b2.z),(b1.x,b2.y,b2.z),"White");
|
|
DrawWorldLine(e,(b1.x,b2.y,b2.z),(b2.x,b2.y,b2.z),"White");
|
|
DrawWorldLine(e,(b2.x,b2.y,b2.z),(b2.x,b1.y,b2.z),"White");
|
|
DrawWorldLine(e,(b2.x,b1.y,b2.z),(b1.x,b1.y,b2.z),"White");
|
|
DrawWorldLine(e,(b1.x,b1.y,b1.z),(b1.x,b1.y,b2.z),"White");
|
|
DrawWorldLine(e,(b2.x,b1.y,b1.z),(b2.x,b1.y,b2.z),"White");
|
|
DrawWorldLine(e,(b1.x,b2.y,b1.z),(b1.x,b2.y,b2.z),"White");
|
|
DrawWorldLine(e,(b2.x,b2.y,b1.z),(b2.x,b2.y,b2.z),"White");
|
|
}
|
|
let [x, y, z] = SWWMUtility.GetAxes(a.angle,a.pitch,a.roll);
|
|
DrawWorldLine(e,pos,pos+x*16,"Red");
|
|
DrawWorldLine(e,pos,pos+y*16,"Green");
|
|
DrawWorldLine(e,pos,pos+z*16,"Blue");
|
|
if ( a.vel != (0,0,0) ) DrawWorldLine(e,pos,pos+a.vel*GameTicRate,"Yellow");
|
|
if ( a.target ) DrawWorldLine(e,pos,SWWMUtility.LerpVector3(a.target.prev,a.target.pos,e.FracTic),"Gold");
|
|
if ( a.tracer ) DrawWorldLine(e,pos,SWWMUtility.LerpVector3(a.tracer.prev,a.tracer.pos,e.FracTic),"Orange");
|
|
if ( a.master ) DrawWorldLine(e,pos,SWWMUtility.LerpVector3(a.master.prev,a.master.pos,e.FracTic),"Purple");
|
|
double hdiff = a.Height/2;
|
|
if ( a.bFLOATBOB ) hdiff += a.GetBobOffset();
|
|
Vector3 ndc = SWWMUtility.ProjectPoint(projdata,e.viewpos+level.Vec3Diff(e.viewpos,pos+(0,0,hdiff)));
|
|
if ( ndc.z > 1. ) return;
|
|
Vector2 vpos = SWWMUtility.NDCToViewport(projdata,ndc);
|
|
String tag = a.player?a.player.GetUserName():a.GetTag();
|
|
if ( tag == a.GetClassName() ) SWWMUtility.BeautifyClassName(tag);
|
|
Screen.DrawText(NewSmallFont,a.bDROPPED?Font.CR_DARKRED:Font.CR_RED,vpos.x-NewSmallFont.StringWidth(tag)/2,vpos.y-NewSmallFont.GetHeight()/2,tag);
|
|
}
|
|
|
|
private ui void DrawDebug( RenderEvent e )
|
|
{
|
|
if ( !swwm_debugview ) return;
|
|
// prepare projection data, we're going to need this
|
|
SWWMUtility.PrepareProjData(projdata,e.ViewPos,e.ViewAngle,e.ViewPitch,e.ViewRoll,players[consoleplayer].fov);
|
|
foreach ( s:level.Sectors ) for ( Actor a=s.thinglist; a; a=a.snext )
|
|
{
|
|
if ( (a == players[consoleplayer].Camera) && !(players[consoleplayer].cheats&CF_CHASECAM) ) continue;
|
|
if ( a.bINVISIBLE && !(a is 'DynamicLight') ) continue;
|
|
if ( (a is 'Inventory') && Inventory(a).Owner ) continue;
|
|
if ( (a is 'SWWMPickupFlash') && (a.CurState == a.FindState('Pickup')) ) continue;
|
|
if ( (a is 'SWWMShadow') || (a is 'SWWMItemOverlay') || (a is 'HeadpatTracker') || (a is 'SWWMTeleportLine') || (a is 'SWWMTeleportDest') ) continue;
|
|
if ( a.Distance3DSquared(e.Camera) > 1000000 ) continue;
|
|
DrawActor(e,a);
|
|
}
|
|
}
|
|
}
|