diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index a14583842..74c6179da 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -2631,6 +2631,10 @@ void CEngine::SetFocus(float focus) float farPlane = m_deepView[0] * m_clippingDistance; float aspect = static_cast(m_size.x) / static_cast(m_size.y); + + // Compute H-FoV from V-FoV and aspect ratio. + m_hfov = 2.0f * atan(aspect * tan(focus / 2.0f)); + Math::LoadProjectionMatrix(m_matProj, m_focus, aspect, 0.5f, farPlane); } @@ -2639,6 +2643,16 @@ float CEngine::GetFocus() return m_focus; } +float CEngine::GetVFovAngle() +{ + return m_focus; +} + +float CEngine::GetHFovAngle() +{ + return m_hfov; +} + void CEngine::SetShadowColor(float value) { m_shadowColor = value; @@ -4727,8 +4741,9 @@ void CEngine::DrawBackgroundImage() if (a > Math::PI/4.0f) a = Math::PI/4.0f; if (a < -Math::PI/4.0f) a = -Math::PI/4.0f; - u1 = -m_eyeDirH/Math::PI; - u2 = u1+1.0f/Math::PI; + // Note the background covers Math::PI radians, i.e. it repeats twice per rotation! + u1 = (-m_eyeDirH - GetHFovAngle()/2.0f) / Math::PI; + u2 = u1 + (GetHFovAngle() / Math::PI); v1 = (1.0f-h)*(0.5f+a/(2.0f*Math::PI/4.0f))+0.1f; v2 = v1+h; diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index 429bca145..655bc024e 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -921,12 +921,16 @@ class CEngine : public CSingleton void SetTerrainVision(float vision); //@{ - //! Management of camera angle - /** + //! Management of camera vertical field-of-view angle. + /** This is specified in radians. + Horizontal FoV is calculated based on vertical FoV and aspect ratio. 0.75 = normal 1.50 = wide-angle */ void SetFocus(float focus); + //! Deprecated alias for GetVFovAngle float GetFocus(); + float GetVFovAngle(); + float GetHFovAngle(); //@} //@{ @@ -1318,8 +1322,10 @@ class CEngine : public CSingleton Math::Matrix m_matProj; //! View matrix for 3D scene Math::Matrix m_matView; - //! Camera angle for 3D scene + //! Camera vertical field-of-view angle for 3D scene. A.k.a. m_vfov float m_focus; + //! Horizontal field-of-view angle, calculated from vertical FOV and aspect ratio + float m_hfov; //! Projection matrix for rendering shadow maps Math::Matrix m_shadowProjMat; diff --git a/src/graphics/engine/planet.cpp b/src/graphics/engine/planet.cpp index 1aad335e7..44a3ef8bb 100644 --- a/src/graphics/engine/planet.cpp +++ b/src/graphics/engine/planet.cpp @@ -115,8 +115,16 @@ void CPlanet::Draw() Math::Point p1, p2; - float a = eyeDirH + planet.angle.x; - p1.x = Math::Mod(a, Math::PI*2.0f)-0.5f; + // Determine the 2D coordinates of the centre of the planet. + + // Not sure why this is + when you'd expect -. Perhaps one of the angles is inverted. + // Compute the camera-relative angles. (0, 0) is straight ahead (the dead centre of the screen). + + // Why -1.0f? Simply because the old formula included that, and we need it to + // be consistent for the outer space cutscenes to work. + float a = planet.angle.x + eyeDirH - 1.0f; + a = Math::Mod(a+Math::PI, Math::PI*2.0f)-Math::PI; // normalize to -pi <= a < pi + p1.x = a/m_engine->GetHFovAngle() + 0.5f; a = eyeDirV + planet.angle.y; p1.y = 0.4f+(Math::Mod(a+Math::PI, Math::PI*2.0f)-Math::PI)*(2.0f/Math::PI);