Support new versions of Kinsie's test map. Switch to new GetAxes implementation across the board. Minor fixes here and there.
136 lines
4.4 KiB
Text
136 lines
4.4 KiB
Text
/*
|
|
Coordinate Utility helper class.
|
|
(C)2018 Marisa Kirisame, UnSX Team.
|
|
Released under the GNU Lesser General Public License version 3 (or later).
|
|
See https://www.gnu.org/licenses/lgpl-3.0.txt for its terms.
|
|
*/
|
|
|
|
Class dt_CoordUtil
|
|
{
|
|
// projects a world point onto screen
|
|
// view matrix setup mostly pulled from gutawer's code
|
|
static Vector3 WorldToScreen( Vector3 vect, Vector3 eye, double pitch, double yaw, double roll, double vfov )
|
|
{
|
|
double ar = Screen.getWidth()/double(Screen.getHeight());
|
|
double fovr = (ar>=1.3)?1.333333:ar;
|
|
double fov = 2*atan(tan(clamp(vfov,5,170)*0.5)/fovr);
|
|
float pr = level.pixelstretch;
|
|
double angx = cos(pitch);
|
|
double angy = sin(pitch)*pr;
|
|
double alen = sqrt(angx*angx+angy*angy);
|
|
double apitch = asin(angy/alen);
|
|
double ayaw = yaw-90;
|
|
// rotations
|
|
dt_Matrix4 mRoll = dt_Matrix4.rotate((0,0,1),roll);
|
|
dt_Matrix4 mPitch = dt_Matrix4.rotate((1,0,0),apitch);
|
|
dt_Matrix4 mYaw = dt_Matrix4.rotate((0,-1,0),ayaw);
|
|
// scaling
|
|
dt_Matrix4 mScale = dt_Matrix4.identity();
|
|
mScale.set(1,1,pr);
|
|
// YZ swap
|
|
dt_Matrix4 mYZ = dt_Matrix4.create();
|
|
mYZ.set(0,0,1);
|
|
mYZ.set(2,1,1);
|
|
mYZ.set(1,2,-1);
|
|
mYZ.set(3,3,1);
|
|
// translation
|
|
dt_Matrix4 mMove = dt_Matrix4.identity();
|
|
mMove.set(3,0,-eye.x);
|
|
mMove.set(3,1,-eye.y);
|
|
mMove.set(3,2,-eye.z);
|
|
// perspective
|
|
dt_Matrix4 mPerspective = dt_Matrix4.perspective(fov,ar,5,65535);
|
|
// full matrix
|
|
dt_Matrix4 mView = mRoll.mul(mPitch);
|
|
mView = mView.mul(mYaw);
|
|
mView = mView.mul(mScale);
|
|
mView = mView.mul(mYZ);
|
|
mView = mView.mul(mMove);
|
|
dt_Matrix4 mWorldToScreen = mPerspective.mul(mView);
|
|
return mWorldToScreen.vmat(vect);
|
|
}
|
|
|
|
// converts a projected screen position to 2D canvas coords
|
|
// thanks once again to gutawer for making this thing screenblocks-aware
|
|
// [NEW] added second return value: true if the point has valid depth (i.e.: it's not behind view)
|
|
// [TODO] handle forced aspect ratio (e.g.: 320x200 scaling)
|
|
static Vector2, bool ToViewport( Vector3 screenpos, bool scrblocks = true )
|
|
{
|
|
if ( scrblocks )
|
|
{
|
|
int winx, winy, winw, winh;
|
|
[winx,winy,winw,winh] = Screen.getViewWindow();
|
|
int sh = Screen.getHeight();
|
|
int ht = sh;
|
|
int screenblocks = CVar.GetCVar("screenblocks",players[consoleplayer]).getInt();
|
|
if ( screenblocks < 10 ) ht = (screenblocks*sh/10)&~7;
|
|
int bt = sh-(ht+winy-((ht-winh)/2));
|
|
return (winx,sh-bt-ht)+((screenpos.x+1)*winw,(-screenpos.y+1)*ht)*0.5, (screenpos.z<=1.0);
|
|
}
|
|
else return ((screenpos.x+1)*Screen.getWidth(),(-screenpos.y+1)*Screen.getHeight())*0.5, (screenpos.z<=1.0);
|
|
}
|
|
|
|
// In Tim Sweeney's own words: "transform by a pitch-yaw-roll rotation"
|
|
static Vector3, Vector3, Vector3 GetUnAxes( double pitch, double yaw, double roll )
|
|
{
|
|
Vector3 x = (1,0,0), y = (0,-1,0), z = (0,0,1); // y inverted for left-handed result
|
|
Vector3 a, b, c;
|
|
// pitch and roll in gzdoom work in reverse compared to UE
|
|
pitch = -pitch;
|
|
roll = -roll;
|
|
// yaw
|
|
a = (cos(yaw),sin(yaw),0);
|
|
b = (-sin(yaw),cos(yaw),0);
|
|
c = (0,0,1);
|
|
x = (x dot a, x dot b, x dot c);
|
|
y = (y dot a, y dot b, y dot c);
|
|
z = (z dot a, z dot b, z dot c);
|
|
// pitch
|
|
a = (cos(pitch),0,sin(pitch));
|
|
b = (0,1,0);
|
|
c = (-sin(pitch),0,cos(pitch));
|
|
x = (x dot a, x dot b, x dot c);
|
|
y = (y dot a, y dot b, y dot c);
|
|
z = (z dot a, z dot b, z dot c);
|
|
// roll
|
|
a = (1,0,0);
|
|
b = (0,cos(roll),-sin(roll));
|
|
c = (0,sin(roll),cos(roll));
|
|
x = (x dot a, x dot b, x dot c);
|
|
y = (y dot a, y dot b, y dot c);
|
|
z = (z dot a, z dot b, z dot c);
|
|
return x, y, z;
|
|
}
|
|
|
|
// In Tim Sweeney's own words: "detransform by a pitch-yaw-roll rotation"
|
|
static Vector3, Vector3, Vector3 GetAxes( double pitch, double yaw, double roll )
|
|
{
|
|
Vector3 x = (1,0,0), y = (0,-1,0), z = (0,0,1); // y inverted for left-handed result
|
|
Vector3 a, b, c;
|
|
// pitch and roll in gzdoom work in reverse compared to UE
|
|
pitch = -pitch;
|
|
roll = -roll;
|
|
// inverse roll
|
|
a = (1,0,0);
|
|
b = (0,cos(roll),sin(roll));
|
|
c = (0,-sin(roll),cos(roll));
|
|
x = (x dot a, x dot b, x dot c);
|
|
y = (y dot a, y dot b, y dot c);
|
|
z = (z dot a, z dot b, z dot c);
|
|
// inverse pitch
|
|
a = (cos(pitch),0,-sin(pitch));
|
|
b = (0,1,0);
|
|
c = (sin(pitch),0,cos(pitch));
|
|
x = (x dot a, x dot b, x dot c);
|
|
y = (y dot a, y dot b, y dot c);
|
|
z = (z dot a, z dot b, z dot c);
|
|
// inverse yaw
|
|
a = (cos(yaw),-sin(yaw),0);
|
|
b = (sin(yaw),cos(yaw),0);
|
|
c = (0,0,1);
|
|
x = (x dot a, x dot b, x dot c);
|
|
y = (y dot a, y dot b, y dot c);
|
|
z = (z dot a, z dot b, z dot c);
|
|
return x, y, z;
|
|
}
|
|
}
|