- Migrated screen projection code to libeye. - Some pickups emit light, like in Doomreal. - Backported map revealer item from Doomreal. - Brand new Invulnerability and Night Vision powerups. - Add option to allow Shield Belt and armors simultaneously. - Backported armor bonus model from Doomreal. - Added Dual Enforcers icon for HUD. - Changed player class names to their character names, like in Doomreal. - Terrain splashes. - Translocator doesn't telefrag other players in coop. - Reduced view shake from Impact Hammer. - Various other updates and bug fixes.
193 lines
4.8 KiB
Text
193 lines
4.8 KiB
Text
/* kd:
|
|
|
|
Here's how to do projections and deprojections. You'd use the subclasses
|
|
to do anything worthwhile. You may project world to screen and backwards.
|
|
|
|
*/
|
|
|
|
class dtLe_ProjScreen {
|
|
|
|
// kd: Screen info
|
|
protected vector2 resolution;
|
|
protected vector2 origin;
|
|
protected vector2 tan_fov_2;
|
|
protected double pixel_stretch;
|
|
protected double aspect_ratio;
|
|
|
|
// kd: Setup calls which you'll need to call at least once.
|
|
void CacheResolution () {
|
|
CacheCustomResolution((Screen.GetWidth(), Screen.GetHeight()) );
|
|
}
|
|
|
|
void CacheCustomResolution (vector2 new_resolution) {
|
|
|
|
// kd: This is for convenience and converting normal <-> screen pos.
|
|
resolution = new_resolution;
|
|
|
|
// kd: This isn't really necessary but I kinda like it.
|
|
pixel_stretch = level.pixelstretch;
|
|
|
|
// kd: Get the aspect ratio. 5:4 is handled just like 4:3... I GUESS
|
|
// this'll do.
|
|
aspect_ratio = max(4.0 / 3, Screen.GetAspectRatio());
|
|
}
|
|
|
|
double AspectRatio () const {
|
|
return aspect_ratio;
|
|
}
|
|
|
|
// kd: Once you know you got screen info, you can call this whenever your
|
|
// fov changes. Like CacheFov(player.fov) will do.
|
|
void CacheFov (double hor_fov = 90) {
|
|
|
|
// kd: This holds: aspect ratio = tan(horizontal fov) / tan(ver fov).
|
|
// gzd always uses hor fov, but the fov only holds in 4:3 (in a 4:3 box
|
|
// in your screen centre), so we just extend it.
|
|
tan_fov_2.x = tan(hor_fov / 2) * aspect_ratio / (4.0 / 3);
|
|
tan_fov_2.y = tan_fov_2.x / aspect_ratio;
|
|
}
|
|
|
|
// kd: Also need some view info. Angle is yaw, pitch, roll in world format
|
|
// so positive pitch is up. Call one of the following functions.
|
|
protected vector3 view_ang;
|
|
protected vector3 view_pos;
|
|
|
|
ui void OrientForRenderOverlay (RenderEvent event) {
|
|
Reorient(
|
|
event.viewpos, (
|
|
event.viewangle,
|
|
event.viewpitch,
|
|
event.viewroll));
|
|
}
|
|
|
|
ui void OrientForRenderUnderlay (RenderEvent event) {
|
|
Reorient(
|
|
event.viewpos, (
|
|
event.viewangle,
|
|
event.viewpitch,
|
|
event.viewroll));
|
|
}
|
|
|
|
void OrientForPlayer (PlayerInfo player) {
|
|
Reorient(
|
|
player.mo.vec3offset(0, 0, player.viewheight), (
|
|
player.mo.angle,
|
|
player.mo.pitch,
|
|
player.mo.roll));
|
|
}
|
|
|
|
virtual void Reorient (vector3 world_view_pos, vector3 world_ang) {
|
|
view_ang = world_ang;
|
|
view_pos = world_view_pos;
|
|
}
|
|
|
|
// kd: Now we can do projections and such (position in the level, go to
|
|
// your screen).
|
|
protected double depth;
|
|
protected vector2 proj_pos;
|
|
protected vector3 diff;
|
|
|
|
virtual void BeginProjection () {}
|
|
virtual void ProjectWorldPos (vector3 world_pos) {}
|
|
virtual void ProjectActorPos (
|
|
Actor mo,
|
|
vector3 offset = (0,0,0),
|
|
double t = 1) {}
|
|
|
|
// kd: Portal aware version.
|
|
virtual void ProjectActorPosPortal (
|
|
Actor mo,
|
|
vector3 offset = (0,0,0),
|
|
double t = 1) {}
|
|
|
|
virtual vector2 ProjectToNormal () const { return (0, 0); }
|
|
virtual vector2 ProjectToScreen () const { return (0, 0); }
|
|
|
|
virtual vector2 ProjectToCustom (
|
|
vector2 origin,
|
|
vector2 resolution) const {
|
|
return (0, 0);
|
|
}
|
|
|
|
bool IsInFront () const {
|
|
return 0 < depth;
|
|
}
|
|
|
|
bool IsInScreen () const {
|
|
if( proj_pos.x < -depth || depth < proj_pos.x ||
|
|
proj_pos.y < -depth || depth < proj_pos.y) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// kd: Deprojection (point on screen, go into the world):
|
|
virtual void BeginDeprojection () {}
|
|
|
|
virtual vector3 DeprojectNormalToDiff (
|
|
vector2 normal_pos,
|
|
double depth = 1) const {
|
|
return (0, 0, 0);
|
|
}
|
|
|
|
virtual vector3 DeprojectScreenToDiff (
|
|
vector2 screen_pos,
|
|
double depth = 1) const {
|
|
return (0, 0, 0);
|
|
}
|
|
|
|
virtual vector3 DeprojectCustomToDiff (
|
|
vector2 origin,
|
|
vector2 resolution,
|
|
vector2 screen_pos,
|
|
double depth = 1) const {
|
|
return (0, 0, 0);
|
|
}
|
|
|
|
// kd: A normal position is in the -1 <= x, y <= 1 range on your screen.
|
|
// This will be your screen no matter the resolution:
|
|
|
|
/*
|
|
|
|
(-1, -1) -- --- --- (0, -1) --- --- --- --- (1, -1)
|
|
| |
|
|
| |
|
|
| |
|
|
(-1, 0) (0, 0) (1, 0)
|
|
| |
|
|
| |
|
|
| |
|
|
(-1, 1) --- --- --- (0, 1) --- --- --- --- (1, 1)
|
|
|
|
*/
|
|
|
|
// So this scales such a position back into your drawing resolution.
|
|
|
|
vector2 NormalToScreen (vector2 normal_pos) const {
|
|
normal_pos = 0.5 * (normal_pos + (1, 1));
|
|
return (
|
|
normal_pos.x * resolution.x,
|
|
normal_pos.y * resolution.y);
|
|
}
|
|
|
|
// kd: And this brings a screen position to normal. Make sure the resolution
|
|
// is the same for your cursor.
|
|
|
|
vector2 ScreenToNormal (vector2 screen_pos) const {
|
|
screen_pos = (
|
|
screen_pos.x / resolution.x,
|
|
screen_pos.y / resolution.y);
|
|
return 2 * screen_pos - (1, 1);
|
|
}
|
|
|
|
// kd: Other interesting stuff.
|
|
|
|
vector3 Difference () const {
|
|
return diff;
|
|
}
|
|
|
|
double Distance () const {
|
|
return diff.length();
|
|
}
|
|
}
|