Index: source/gui/ObjectTypes/CMiniMap.cpp =================================================================== --- source/gui/ObjectTypes/CMiniMap.cpp +++ source/gui/ObjectTypes/CMiniMap.cpp @@ -37,6 +37,7 @@ #include "lib/external_libraries/libsdl.h" #include "lib/ogl.h" #include "lib/timer.h" +#include "maths/MathUtil.h" #include "ps/CLogger.h" #include "ps/ConfigDB.h" #include "ps/CStrInternStatic.h" @@ -345,19 +346,36 @@ // which represents the view of the camera in the world. void CMiniMap::DrawViewRect(const CMatrix3D& transform) const { - // Compute the camera frustum intersected with a fixed-height plane. - // Use the water height as a fixed base height, which should be the lowest we can go - float h = g_Renderer.GetWaterManager()->m_WaterHeight; + // Compute the camera frustum intersected with an imaginary plane derived from the + // average height of terrain in view, or the height of water, whichever is higher. + const float width = m_CachedActualSize.GetWidth(); const float height = m_CachedActualSize.GetHeight(); const float invTileMapSize = 1.0f / float(TERRAIN_TILE_SIZE * m_MapSize); const CCamera* camera = g_Game->GetView()->GetCamera(); + const CVector3D cameraFocus = camera->GetFocus(); + const CVector3D cameraPosition = camera->GetOrientation().GetTranslation(); + const CVector3D cameraDirection = camera->GetOrientation().GetIn(); + const float cameraDistanceToFocus = cameraPosition.Y - cameraFocus.Y; + const float focusDiameter = sqrtf(SQR(cameraDirection.X) + SQR(cameraDirection.Z)) * cameraDistanceToFocus; + + const float groundOrWaterHeight = std::max( + g_Game->GetWorld()->GetTerrain()->GetFilteredGroundLevel( + cameraFocus.X, + cameraFocus.Z, + focusDiameter / 2.f + ), + g_Renderer.GetWaterManager()->m_WaterHeight + ); + + const int viewHeight = g_Renderer.GetHeight(); + const int viewWidth = g_Renderer.GetWidth(); const std::array hitPoints = { - camera->GetWorldCoordinates(0, g_Renderer.GetHeight(), h), - camera->GetWorldCoordinates(g_Renderer.GetWidth(), g_Renderer.GetHeight(), h), - camera->GetWorldCoordinates(g_Renderer.GetWidth(), 0, h), - camera->GetWorldCoordinates(0, 0, h) + camera->GetWorldCoordinates(0, viewHeight, groundOrWaterHeight), + camera->GetWorldCoordinates(viewWidth, viewHeight, groundOrWaterHeight), + camera->GetWorldCoordinates(viewWidth, 0, groundOrWaterHeight), + camera->GetWorldCoordinates(0, 0, groundOrWaterHeight) }; std::vector lines;