From f7bec90e748119d64d1fa1528e1f087b17852f49 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Thu, 18 Jun 2020 20:24:46 +0200 Subject: [PATCH] Interpolate positions and angles in the automap for smoother appearance --- src/am_map.cpp | 101 +++++++++++++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 45 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index a3b1782372c..2227ac189d1 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -85,8 +85,8 @@ enum // C++ cannot do static const floats in a class, so these need to be global... static const double PLAYERRADIUS = 16.; // player radius for automap checking -static const double M_ZOOMIN = (1.02); // how much zoom-in per tic - goes to 2x in 1 second -static const double M_ZOOMOUT = (1 / 1.02); // how much zoom-out per tic - pulls out to 0.5x in 1 second +static const double M_ZOOMIN = 2; // how much zoom-in per second +static const double M_ZOOMOUT = 0.25; // how much zoom-out per second static FTextureID marknums[AM_NUMMARKPOINTS]; // numbers used for marking by the automap bool automapactive = false; @@ -1005,7 +1005,7 @@ class DAutomap :public DAutomapBase void ScrollParchment(double dmapx, double dmapy); void changeWindowLoc(); void maxOutWindowScale(); - void changeWindowScale(); + void changeWindowScale(double delta); void clearFB(const AMColor &color); bool clipMline(mline_t *ml, fline_t *fl); void drawMline(mline_t *ml, const AMColor &color); @@ -1280,7 +1280,7 @@ void DAutomap::changeWindowLoc () oincy = incy = m_paninc.y * twod->GetHeight() / 200; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { - rotate(&incx, &incy, players[consoleplayer].camera->Angles.Yaw - 90.); + rotate(&incx, &incy, players[consoleplayer].camera->InterpolatedAngles(r_viewpoint.TicFrac).Yaw - 90.); } m_x += incx; @@ -1457,8 +1457,9 @@ bool DAutomap::Responder (event_t *ev, bool last) // //============================================================================= -void DAutomap::changeWindowScale () +void DAutomap::changeWindowScale (double delta) { + double mtof_zoommul; if (am_zoomdir > 0) @@ -1471,11 +1472,11 @@ void DAutomap::changeWindowScale () } else if (buttonMap.ButtonDown(Button_AM_ZoomIn)) { - mtof_zoommul = M_ZOOMIN; + mtof_zoommul = (1 + (M_ZOOMIN - 1) * delta); } else if (buttonMap.ButtonDown(Button_AM_ZoomOut)) { - mtof_zoommul = M_ZOOMOUT; + mtof_zoommul = (1 + (M_ZOOMOUT - 1) * delta); } else { @@ -1506,7 +1507,7 @@ void DAutomap::doFollowPlayer () if (cam != nullptr) { double delta = cam->player ? cam->player->viewz - cam->Z() : cam->GetCameraHeight(); - DVector3 ampos = cam->GetPortalTransition(delta); + DVector3 ampos = cam->InterpolatedPosition(r_viewpoint.TicFrac); if (f_oldloc.x != ampos.X || f_oldloc.y != ampos.Y) { @@ -1520,7 +1521,7 @@ void DAutomap::doFollowPlayer () sy = (f_oldloc.y - ampos.Y); if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { - rotate(&sx, &sy, cam->Angles.Yaw - 90); + rotate(&sx, &sy, cam->InterpolatedAngles(r_viewpoint.TicFrac).Yaw - 90); } ScrollParchment(sx, sy); @@ -1542,27 +1543,6 @@ void DAutomap::Ticker () return; amclock++; - - if (am_followplayer) - { - doFollowPlayer(); - } - else - { - m_paninc.x = m_paninc.y = 0; - if (buttonMap.ButtonDown(Button_AM_PanLeft)) m_paninc.x -= FTOM(F_PANINC); - if (buttonMap.ButtonDown(Button_AM_PanRight)) m_paninc.x += FTOM(F_PANINC); - if (buttonMap.ButtonDown(Button_AM_PanUp)) m_paninc.y += FTOM(F_PANINC); - if (buttonMap.ButtonDown(Button_AM_PanDown)) m_paninc.y -= FTOM(F_PANINC); - } - - // Change the zoom if necessary - if (buttonMap.ButtonDown(Button_AM_ZoomIn) || buttonMap.ButtonDown(Button_AM_ZoomOut) || am_zoomdir != 0) - changeWindowScale(); - - // Change x,y location - //if (m_paninc.x || m_paninc.y) - changeWindowLoc(); } @@ -1842,7 +1822,7 @@ sector_t * AM_FakeFlat(AActor *viewer, sector_t * sec, sector_t * dest) { if (sec->GetHeightSec() == nullptr) return sec; - DVector3 pos = viewer->Pos(); + DVector3 pos = viewer->InterpolatedPosition(r_viewpoint.TicFrac); if (viewer->player) { @@ -2089,7 +2069,7 @@ void DAutomap::drawSubsectors() // Apply the automap's rotation to the texture origin. if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { - rotation = rotation + 90. - players[consoleplayer].camera->Angles.Yaw; + rotation = rotation + 90. - players[consoleplayer].camera->InterpolatedAngles(r_viewpoint.TicFrac).Yaw; rotatePoint(&originpt.x, &originpt.y); } originx = f_x + ((originpt.x - m_x) * scale); @@ -2685,7 +2665,7 @@ void DAutomap::rotatePoint (double *x, double *y) double pivoty = m_y + m_h/2; *x -= pivotx; *y -= pivoty; - rotate (x, y, -players[consoleplayer].camera->Angles.Yaw + 90.); + rotate (x, y, -players[consoleplayer].camera->InterpolatedAngles(r_viewpoint.TicFrac).Yaw + 90.); *x += pivotx; *y += pivoty; } @@ -2760,7 +2740,7 @@ void DAutomap::drawPlayers () int numarrowlines; double vh = players[consoleplayer].viewheight; - DVector2 pos = am_portaloverlay? players[consoleplayer].camera->GetPortalTransition(vh) : players[consoleplayer].camera->Pos(); + DVector2 pos = players[consoleplayer].camera->InterpolatedPosition(r_viewpoint.TicFrac); pt.x = pos.X; pt.y = pos.Y; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) @@ -2770,7 +2750,7 @@ void DAutomap::drawPlayers () } else { - angle = players[consoleplayer].camera->Angles.Yaw; + angle = players[consoleplayer].camera->InterpolatedAngles(r_viewpoint.TicFrac).Yaw; } if (am_cheat != 0 && CheatMapArrow.Size() > 0) @@ -2828,12 +2808,12 @@ void DAutomap::drawPlayers () pt.x = pos.X; pt.y = pos.Y; - angle = p->mo->Angles.Yaw; + angle = p->mo->InterpolatedAngles(r_viewpoint.TicFrac).Yaw; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { rotatePoint (&pt.x, &pt.y); - angle -= players[consoleplayer].camera->Angles.Yaw - 90.; + angle -= players[consoleplayer].camera->InterpolatedAngles(r_viewpoint.TicFrac).Yaw - 90.; } drawLineCharacter(&MapArrow[0], MapArrow.Size(), 0, angle, color, pt.x, pt.y); @@ -2862,12 +2842,12 @@ void DAutomap::drawKeys () p.x = pos.X; p.y = pos.Y; - angle = key->Angles.Yaw; + angle = key->InterpolatedAngles(r_viewpoint.TicFrac).Yaw; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { rotatePoint (&p.x, &p.y); - angle += -players[consoleplayer].camera->Angles.Yaw + 90.; + angle += -players[consoleplayer].camera->InterpolatedAngles(r_viewpoint.TicFrac).Yaw + 90.; } if (key->flags & MF_SPECIAL) @@ -2904,7 +2884,7 @@ void DAutomap::drawThings () if (am_cheat > 0 || !(t->flags6 & MF6_NOTONAUTOMAP) || (am_thingrenderstyles && !(t->renderflags & RF_INVISIBLE) && !(t->flags6 & MF6_NOTONAUTOMAP))) { - DVector3 pos = t->PosRelative(MapPortalGroup); + DVector3 pos = t->InterpolatedPosition(r_viewpoint.TicFrac) + t->Level->Displacements.getOffset(sec.PortalGroup, MapPortalGroup); p.x = pos.X; p.y = pos.Y; @@ -2921,11 +2901,11 @@ void DAutomap::drawThings () const size_t spriteIndex = sprite.spriteframes + (show > 1 ? t->frame : 0); frame = &SpriteFrames[spriteIndex]; - DAngle angle = 270. + 22.5 - t->Angles.Yaw; + DAngle angle = 270. + 22.5 - t->InterpolatedAngles(r_viewpoint.TicFrac).Yaw; if (frame->Texture[0] != frame->Texture[1]) angle += 180. / 16; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { - angle += players[consoleplayer].camera->Angles.Yaw - 90.; + angle += players[consoleplayer].camera->InterpolatedAngles(r_viewpoint.TicFrac).Yaw - 90.; } rotation = int((angle.Normalized360() * (16. / 360.)).Degrees); @@ -2946,12 +2926,12 @@ void DAutomap::drawThings () else { drawTriangle: - angle = t->Angles.Yaw; + angle = t->InterpolatedAngles(r_viewpoint.TicFrac).Yaw; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { rotatePoint (&p.x, &p.y); - angle += -players[consoleplayer].camera->Angles.Yaw + 90.; + angle += -players[consoleplayer].camera->InterpolatedAngles(r_viewpoint.TicFrac).Yaw + 90.; } color = AMColors[AMColors.ThingColor]; @@ -3010,7 +2990,7 @@ void DAutomap::drawThings () { { -1, 1 }, { -1, -1 } }, }; - drawLineCharacter (box, 4, t->radius, angle - t->Angles.Yaw, color, p.x, p.y); + drawLineCharacter (box, 4, t->radius, angle - t->InterpolatedAngles(r_viewpoint.TicFrac).Yaw, color, p.x, p.y); } } } @@ -3179,9 +3159,38 @@ void DAutomap::drawCrosshair (const AMColor &color) void DAutomap::Drawer (int bottom) { + static uint64_t LastMS = 0; + // Use a delta to zoom/pan at a constant speed regardless of current FPS + uint64_t ms = screen->FrameTime; + double delta = (ms - LastMS) * 0.001; + if (!automapactive) return; + if (am_followplayer) + { + doFollowPlayer(); + } + else + { + m_paninc.x = m_paninc.y = 0; + if (buttonMap.ButtonDown(Button_AM_PanLeft)) + m_paninc.x -= FTOM(F_PANINC) * delta * TICRATE; + if (buttonMap.ButtonDown(Button_AM_PanRight)) + m_paninc.x += FTOM(F_PANINC) * delta * TICRATE; + if (buttonMap.ButtonDown(Button_AM_PanUp)) + m_paninc.y += FTOM(F_PANINC) * delta * TICRATE; + if (buttonMap.ButtonDown(Button_AM_PanDown)) + m_paninc.y -= FTOM(F_PANINC) * delta * TICRATE; + } + + // Change the zoom if necessary + if (buttonMap.ButtonDown(Button_AM_ZoomIn) || buttonMap.ButtonDown(Button_AM_ZoomOut) || am_zoomdir != 0) + changeWindowScale(delta); + + // Change x,y location + changeWindowLoc(); + bool allmap = (Level->flags2 & LEVEL2_ALLMAP) != 0; bool allthings = allmap && players[consoleplayer].mo->FindInventory(NAME_PowerScanner, true) != nullptr; @@ -3234,6 +3243,8 @@ void DAutomap::Drawer (int bottom) drawMarks(); showSS(); + + LastMS = ms; } //=============================================================================