1.3.2 update: Remove third party library I no longer depend on.
This commit is contained in:
parent
1583863894
commit
90a07ee257
10 changed files with 58 additions and 1170 deletions
|
|
@ -1,28 +1,35 @@
|
|||
// gutamatics projection data caching and other functions from SWWM GZ
|
||||
// screen projection and other functions from SWWM GZ
|
||||
|
||||
|
||||
Struct dt_ProjectionData
|
||||
{
|
||||
dt_GM_Matrix wtc;
|
||||
double tanfovx, tanfovy;
|
||||
Vector3 viewpos, z, x, y;
|
||||
int viewx, viewy, vieww, viewh;
|
||||
}
|
||||
|
||||
Class dt_Utility
|
||||
{
|
||||
// gutamatics caching
|
||||
static clearscope void PrepareProjData( out dt_ProjectionData d, Vector3 viewpos, double angle, double pitch, double roll, double fov )
|
||||
// cache some data that requires trig and quat math
|
||||
static clearscope void PrepareProjData( dt_ProjectionData &d, Vector3 viewpos, double angle, double pitch, double roll, double fov )
|
||||
{
|
||||
// store for internal use
|
||||
d.viewpos = viewpos;
|
||||
// precalc vfov/hfov tangents
|
||||
// (vfov in gzdoom has a small quirk to it)
|
||||
double aspect = Screen.GetAspectRatio();
|
||||
// vertical fov
|
||||
double fovratio = (aspect>=1.3)?1.333333:aspect;
|
||||
double fovy = 2.*atan(tan(clamp(fov,5,170)/2.)/fovratio);
|
||||
// world→clip matrix
|
||||
dt_GM_Matrix view = dt_GM_Matrix.view(viewpos,angle,pitch,roll);
|
||||
dt_GM_Matrix perp = dt_GM_Matrix.perspective(fovy,aspect,5,65535);
|
||||
d.wtc = perp.multiplyMatrix(view);
|
||||
// screen coord data
|
||||
d.tanfovy = tan(clamp(fov,5,170)/2.)/fovratio;
|
||||
d.tanfovx = d.tanfovy*aspect;
|
||||
// precalc view-space axes
|
||||
// (don't forget pixel stretch, very important)
|
||||
Quat r = Quat.FromAngles(angle,pitch,roll);
|
||||
d.z = r*(1.,0.,0.);
|
||||
d.x = r*(0.,1.,0.);
|
||||
d.y = r*(0.,0.,level.pixelstretch);
|
||||
// precalc view origin and clip
|
||||
int sblocks = CVar.FindCVar('screenblocks').GetInt();
|
||||
int viewx, viewy, vieww, viewh;
|
||||
[viewx, viewy, vieww, viewh] = Screen.GetViewWindow();
|
||||
let [viewx, viewy, vieww, viewh] = Screen.GetViewWindow();
|
||||
int sh = Screen.GetHeight();
|
||||
int h = sh;
|
||||
if ( sblocks < 10 ) h = (sblocks*sh/10)&~7;
|
||||
|
|
@ -33,21 +40,43 @@ Class dt_Utility
|
|||
d.viewh = h;
|
||||
}
|
||||
|
||||
static clearscope Vector3 ProjectPoint( dt_ProjectionData d, Vector3 worldpos )
|
||||
// simple projection without matrices, translated from old UnrealScript work
|
||||
// bFast: quit early if point is behind screen, for cases where behind-view coords are not really needed
|
||||
static clearscope Vector3 ProjectPoint( dt_ProjectionData d, Vector3 worldpos, bool bFast = true )
|
||||
{
|
||||
return d.wtc.multiplyVector3(worldpos).asVector3();
|
||||
Vector3 tdir = worldpos-d.viewpos;
|
||||
// early bail, skip behind-view points
|
||||
if ( bFast && (d.z dot tdir <= 0.) )
|
||||
return (0.,0.,0.);
|
||||
double dist = tdir.length();
|
||||
// points are pretty much equal, skip projection
|
||||
if ( dist <= double.epsilon )
|
||||
return (0.,0.,0.);
|
||||
tdir /= dist;
|
||||
Vector3 dir = d.z*(tdir dot d.z);
|
||||
// I don't understand this math, but it works?
|
||||
Vector3 xy = tdir-dir;
|
||||
double dx = xy dot d.x;
|
||||
double dy = xy dot d.y;
|
||||
double dlen = dir.length();
|
||||
// guard against division by zero here?
|
||||
if ( dlen <= double.epsilon )
|
||||
return (0.,0.,0.);
|
||||
double tanx = dx/dlen;
|
||||
double tany = dy/dlen;
|
||||
return (1.-tanx/d.tanfovx,1.-tany/d.tanfovy,dir dot d.z);
|
||||
}
|
||||
|
||||
static clearscope Vector2 NDCToViewport( dt_ProjectionData d, Vector3 ndc )
|
||||
static clearscope Vector2 NDCToViewport( dt_ProjectionData d, Vector3 cpos )
|
||||
{
|
||||
return (d.viewx,d.viewy)+(((ndc.x+1)*d.vieww)/2,((-ndc.y+1)*d.viewh)/2);
|
||||
return (d.viewx+(cpos.x*.5*d.vieww),d.viewy+(cpos.y*.5*d.viewh));
|
||||
}
|
||||
|
||||
// checks if a point is inside the viewport
|
||||
static clearscope bool TestScreenBounds( dt_ProjectionData d, Vector2 vpos )
|
||||
{
|
||||
return ((vpos.x == clamp(vpos.x,d.viewx,d.viewx+d.vieww))
|
||||
&& (vpos.y == clamp(vpos.y,d.viewy,d.viewy+d.viewh)));
|
||||
&& (vpos.y == clamp(vpos.y,d.viewy,d.viewy+d.viewh)));
|
||||
}
|
||||
|
||||
static clearscope Vector3 Vec3FromAngle( double angle, double pitch )
|
||||
|
|
@ -72,7 +101,12 @@ Class dt_Utility
|
|||
return r*x, r*y, r*z;
|
||||
}
|
||||
|
||||
// included here until Gutamatics updates to use native quaternions
|
||||
static double Normalize180( double angle )
|
||||
{
|
||||
angle = ((angle%360.)+360.)%360.;
|
||||
return (angle>180.)?(angle-360.):(angle);
|
||||
}
|
||||
|
||||
static double, double, double ToAngles( Quat q )
|
||||
{
|
||||
double angle = 0., pitch = 0., roll = 0.;
|
||||
|
|
@ -83,13 +117,13 @@ Class dt_Utility
|
|||
{
|
||||
angle = atan2(angY,angX);
|
||||
pitch = 90.;
|
||||
roll = dt_GM_GlobalMaths.Normalize180(angle+(2.*atan2(q.x,q.w)));
|
||||
roll = Normalize180(angle+(2.*atan2(q.x,q.w)));
|
||||
}
|
||||
else if ( stest > .4999995 )
|
||||
{
|
||||
angle = atan2(angY,angX);
|
||||
pitch = -90.;
|
||||
roll = dt_GM_GlobalMaths.Normalize180(angle+(2.*atan2(q.x,q.w)));
|
||||
roll = Normalize180(angle+(2.*atan2(q.x,q.w)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue