Index: binaries/data/mods/public/gui/credits/texts/programming.json =================================================================== --- binaries/data/mods/public/gui/credits/texts/programming.json +++ binaries/data/mods/public/gui/credits/texts/programming.json @@ -210,6 +210,7 @@ { "nick": "pcpa", "name": "Paulo Andrade" }, { "nick": "Pendingchaos" }, { "nick": "PeteVasi", "name": "Pete Vasiliauskas" }, + { "nick": "phosit" }, { "nick": "pilino1234" }, { "nick": "PingvinBetyar", "name": "Schronk Tamás" }, { "nick": "plugwash", "name": "Peter Michael Green" }, Index: source/graphics/Camera.h =================================================================== --- source/graphics/Camera.h +++ source/graphics/Camera.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -26,6 +26,7 @@ #include "maths/BoundingBoxAligned.h" #include "maths/Frustum.h" #include "maths/Matrix3D.h" +#include "maths/Vector2D.h" #include @@ -83,16 +84,16 @@ float GetOrthoScale() const { return m_OrthoScale; } // Returns a quad of view in camera space at given distance from camera. - void GetViewQuad(float dist, Quad& quad) const; + Quad GetViewQuad(float dist) const; // Builds a ray passing through the screen coordinate (px, py), calculates // origin and direction of the ray. - void BuildCameraRay(int px, int py, CVector3D& origin, CVector3D& dir) const; + std::tuple BuildCameraRay(int px, int py) const; // General helpers that seem to fit here // Get the screen-space coordinates corresponding to a given world-space position - void GetScreenCoordinates(const CVector3D& world, float& x, float& y) const; + CVector2D GetScreenCoordinates(const CVector3D& world) const; // Get the point on the terrain corresponding to pixel (px,py) (or the mouse coordinates) // The aboveWater parameter determines whether we want to stop at the water plane or also get underwater points Index: source/graphics/Camera.cpp =================================================================== --- source/graphics/Camera.cpp +++ source/graphics/Camera.cpp @@ -160,7 +160,7 @@ return static_cast(m_ViewPort.m_Width) / static_cast(m_ViewPort.m_Height); } -void CCamera::GetViewQuad(float dist, Quad& quad) const +CCamera::Quad CCamera::GetViewQuad(float dist) const { if (m_ProjType == ProjectionType::CUSTOM) { @@ -168,6 +168,7 @@ const std::array ndcCorners = { CVector2D{-1.0f, -1.0f}, CVector2D{1.0f, -1.0f}, CVector2D{1.0f, 1.0f}, CVector2D{-1.0f, 1.0f}}; + Quad quad; for (size_t idx = 0; idx < 4; ++idx) { const CVector2D& corner = ndcCorners[idx]; @@ -183,27 +184,22 @@ quad[idx].Y = quadCorner.Y; quad[idx].Z = quadCorner.Z; } - return; + return quad; } const float y = m_ProjType == ProjectionType::PERSPECTIVE ? dist * tanf(m_FOV * 0.5f) : m_OrthoScale * 0.5f; const float x = y * GetAspectRatio(); - quad[0].X = -x; - quad[0].Y = -y; - quad[0].Z = dist; - quad[1].X = x; - quad[1].Y = -y; - quad[1].Z = dist; - quad[2].X = x; - quad[2].Y = y; - quad[2].Z = dist; - quad[3].X = -x; - quad[3].Y = y; - quad[3].Z = dist; + return + { + CVector3D(-x, -y, dist), + CVector3D(x, -y, dist), + CVector3D(x, y, dist), + CVector3D(-x, y, dist) + }; } -void CCamera::BuildCameraRay(int px, int py, CVector3D& origin, CVector3D& dir) const +std::tuple CCamera::BuildCameraRay(int px, int py) const { ENSURE(m_ProjType == ProjectionType::PERSPECTIVE || m_ProjType == ProjectionType::ORTHO); @@ -211,8 +207,7 @@ const float dx = static_cast(px) / m_ViewPort.m_Width; const float dy = 1.0f - static_cast(py) / m_ViewPort.m_Height; - Quad points; - GetViewQuad(m_FarPlane, points); + Quad points = GetViewQuad(m_FarPlane); // Transform from camera space to world space. for (CVector3D& point : points) @@ -222,6 +217,7 @@ const CVector3D basisX = points[1] - points[0]; const CVector3D basisY = points[3] - points[0]; + CVector3D origin, dir; if (m_ProjType == ProjectionType::PERSPECTIVE) { // Build direction for the camera origin to the target point. @@ -235,27 +231,30 @@ dir = m_Orientation.GetIn(); } dir.Normalize(); + + return {origin, dir}; } -void CCamera::GetScreenCoordinates(const CVector3D& world, float& x, float& y) const +CVector2D CCamera::GetScreenCoordinates(const CVector3D& world) const { CMatrix3D transform = m_ProjMat * m_Orientation.GetInverse(); CVector4D screenspace = transform.Transform(CVector4D(world.X, world.Y, world.Z, 1.0f)); - x = screenspace.X / screenspace.W; - y = screenspace.Y / screenspace.W; + float x = screenspace.X / screenspace.W; + float y = screenspace.Y / screenspace.W; x = (x + 1) * 0.5f * m_ViewPort.m_Width; y = (1 - y) * 0.5f * m_ViewPort.m_Height; + return {x, y}; } CVector3D CCamera::GetWorldCoordinates(int px, int py, bool aboveWater) const { CHFTracer tracer(g_Game->GetWorld()->GetTerrain()); int x, z; - CVector3D origin, dir, delta, terrainPoint, waterPoint; + CVector3D delta, terrainPoint, waterPoint; - BuildCameraRay(px, py, origin, dir); + const auto [origin, dir] = BuildCameraRay(px, py); bool gotTerrain = tracer.RayIntersect(origin, dir, x, z, terrainPoint); @@ -321,9 +320,9 @@ CPlane plane; plane.Set(CVector3D(0.f, 1.f, 0.f), CVector3D(0.f, h, 0.f)); // upwards normal, passes through h - CVector3D origin, dir, delta, currentTarget; + CVector3D delta, currentTarget; - BuildCameraRay(px, py, origin, dir); + const auto [origin, dir] = BuildCameraRay(px, py); if (plane.FindRayIntersection(origin, dir, ¤tTarget)) return currentTarget; Index: source/graphics/tests/test_Camera.h =================================================================== --- source/graphics/tests/test_Camera.h +++ source/graphics/tests/test_Camera.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -171,11 +171,9 @@ ); camera.SetPerspectiveProjection(1.0f, 101.0f, DEGTORAD(90.0f)); - CCamera::Quad quad; - // Zero distance point is the origin of all camera rays, // so all plane points should stay there. - camera.GetViewQuad(0.0f, quad); + const CCamera::Quad quad = camera.GetViewQuad(0.0f); for (const CVector3D& point : quad) TS_ASSERT_EQUALS(point, CVector3D(0.0f, 0.0f, 0.0f)); @@ -186,8 +184,7 @@ CVector3D(1.0f, 1.0f, 1.0f), CVector3D(-1.0f, 1.0f, 1.0f) }; - CCamera::Quad nearQuad; - camera.GetViewQuad(camera.GetNearPlane(), nearQuad); + const CCamera::Quad nearQuad = camera.GetViewQuad(camera.GetNearPlane()); CompareQuads(nearQuad, expectedNearQuad); CCamera::Quad expectedWorldSpaceNearQuad = { @@ -205,8 +202,7 @@ CVector3D(101.0f, 101.0f, 101.0f), CVector3D(-101.0f, 101.0f, 101.0f) }; - CCamera::Quad farQuad; - camera.GetViewQuad(camera.GetFarPlane(), farQuad); + const CCamera::Quad farQuad = camera.GetViewQuad(camera.GetFarPlane()); CompareQuads(farQuad, expectedFarQuad); CCamera::Quad expectedWorldSpaceFarQuad = { @@ -237,8 +233,7 @@ // Zero distance is the origin plane of all camera rays, // so all plane points should stay there. - CCamera::Quad quad; - camera.GetViewQuad(0.0f, quad); + const CCamera::Quad quad = camera.GetViewQuad(0.0f); for (const CVector3D& point : quad) { constexpr float EPS = 1e-4f; @@ -252,8 +247,7 @@ CVector3D(5.0f, 5.0f, 2.0f), CVector3D(-5.0f, 5.0f, 2.0f) }; - CCamera::Quad nearQuad; - camera.GetViewQuad(camera.GetNearPlane(), nearQuad); + const CCamera::Quad nearQuad = camera.GetViewQuad(camera.GetNearPlane()); CompareQuads(nearQuad, expectedNearQuad); CCamera::Quad expectedWorldSpaceNearQuad = { @@ -271,8 +265,7 @@ CVector3D(5.0f, 5.0f, 128.0f), CVector3D(-5.0f, 5.0f, 128.0f) }; - CCamera::Quad farQuad; - camera.GetViewQuad(camera.GetFarPlane(), farQuad); + const CCamera::Quad farQuad = camera.GetViewQuad(camera.GetFarPlane()); CompareQuads(farQuad, expectedFarQuad); CCamera::Quad expectedWorldSpaceFarQuad = { @@ -315,11 +308,10 @@ cameraPerspective.GetFarPlane() }; - CCamera::Quad quad, expectedQuad; for (const float distance : distances) { - camera.GetViewQuad(distance, quad); - cameraPerspective.GetViewQuad(distance, expectedQuad); + const CCamera::Quad quad = camera.GetViewQuad(distance); + const CCamera::Quad expectedQuad = cameraPerspective.GetViewQuad(distance); CompareQuads(quad, expectedQuad); } } @@ -345,8 +337,7 @@ ); camera.SetPerspectiveProjection(1.0f, 101.0f, DEGTORAD(90.0f)); - CVector3D origin, dir; - camera.BuildCameraRay(viewPort.m_Width / 2, viewPort.m_Height / 2, origin, dir); + const auto [origin, dir] = camera.BuildCameraRay(viewPort.m_Width / 2, viewPort.m_Height / 2); const CVector3D expectedOrigin = cameraPosition; const CVector3D expectedDir = cameraDirection; CompareVectors(origin, expectedOrigin, EPS); @@ -375,8 +366,7 @@ ); camera.SetOrthoProjection(2.0f, 128.0f, 10.0f); - CVector3D origin, dir; - camera.BuildCameraRay(viewPort.m_Width / 2, viewPort.m_Height / 2, origin, dir); + const auto [origin, dir] = camera.BuildCameraRay(viewPort.m_Width / 2, viewPort.m_Height / 2); const CVector3D expectedOrigin = cameraPosition; const CVector3D expectedDir = cameraDirection; CompareVectors(origin, expectedOrigin, EPS); Index: source/ps/TouchInput.cpp =================================================================== --- source/ps/TouchInput.cpp +++ source/ps/TouchInput.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -137,8 +137,7 @@ if (m_State == STATE_PANNING && id == 0) { CCamera& camera = *(g_Game->GetView()->GetCamera()); - CVector3D origin, dir; - camera.BuildCameraRay(x, y, origin, dir); + auto [origin, dir] = camera.BuildCameraRay(x, y); dir *= m_PanDist / dir.Y; camera.GetOrientation().Translate(m_PanFocus - dir - origin); camera.UpdateFrustum(); @@ -151,8 +150,7 @@ float zoomDist = (newDist - oldDist) * -0.005f * m_PanDist; CCamera& camera = *(g_Game->GetView()->GetCamera()); - CVector3D origin, dir; - camera.BuildCameraRay(m_Pos[0].X, m_Pos[0].Y, origin, dir); + auto [origin, dir] = camera.BuildCameraRay(m_Pos[0].X, m_Pos[0].Y); dir *= zoomDist; camera.GetOrientation().Translate(dir); camera.UpdateFrustum(); Index: source/renderer/DebugRenderer.cpp =================================================================== --- source/renderer/DebugRenderer.cpp +++ source/renderer/DebugRenderer.cpp @@ -193,11 +193,8 @@ UNUSED2(camera); UNUSED2(color); UNUSED2(intermediates); #warning TODO: implement camera frustum for GLES #else - CCamera::Quad nearPoints; - CCamera::Quad farPoints; - - camera.GetViewQuad(camera.GetNearPlane(), nearPoints); - camera.GetViewQuad(camera.GetFarPlane(), farPoints); + CCamera::Quad nearPoints = camera.GetViewQuad(camera.GetNearPlane()); + CCamera::Quad farPoints = camera.GetViewQuad(camera.GetFarPlane()); for (int i = 0; i < 4; ++i) { nearPoints[i] = camera.m_Orientation.Transform(nearPoints[i]); Index: source/renderer/PatchRData.cpp =================================================================== --- source/renderer/PatchRData.cpp +++ source/renderer/PatchRData.cpp @@ -1220,10 +1220,9 @@ pos.X += TERRAIN_TILE_SIZE/4.f; pos.Z += TERRAIN_TILE_SIZE/4.f; - float x, y; - camera.GetScreenCoordinates(pos, x, y); + const CVector2D coordinates = camera.GetScreenCoordinates(pos); - textRenderer.PrintfAt(x, y, L"%d", m_Patch->m_MiniPatches[j][i].Priority); + textRenderer.PrintfAt(coordinates.X, coordinates.Y, L"%d", m_Patch->m_MiniPatches[j][i].Priority); } } } Index: source/renderer/ShadowMap.cpp =================================================================== --- source/renderer/ShadowMap.cpp +++ source/renderer/ShadowMap.cpp @@ -150,16 +150,14 @@ // We can solve 3D problem in 2D space, because the frustum is // symmetric by 2 planes. Than means we can use only one corner // to find a circumscribed sphere. - CCamera::Quad corners; - - camera.GetViewQuad(nearPlane, corners); + CCamera::Quad corners = camera.GetViewQuad(nearPlane); for (CVector3D& corner : corners) corner = camera.GetOrientation().Transform(corner); const CVector3D cornerNear = corners[0]; for (const CVector3D& corner : corners) *frustumBBAA += lightTransform.Transform(corner); - camera.GetViewQuad(farPlane, corners); + corners = camera.GetViewQuad(farPlane); for (CVector3D& corner : corners) corner = camera.GetOrientation().Transform(corner); const CVector3D cornerDist = corners[0]; Index: source/simulation2/helpers/Selection.cpp =================================================================== --- source/simulation2/helpers/Selection.cpp +++ source/simulation2/helpers/Selection.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -34,8 +34,7 @@ entity_id_t EntitySelection::PickEntityAtPoint(CSimulation2& simulation, const CCamera& camera, int screenX, int screenY, player_id_t player, bool allowEditorSelectables) { PROFILE2("PickEntityAtPoint"); - CVector3D origin, dir; - camera.BuildCameraRay(screenX, screenY, origin, dir); + const auto [origin, dir] = camera.BuildCameraRay(screenX, screenY); CmpPtr cmpUnitRenderer(simulation.GetSimContext().GetSystemEntity()); ENSURE(cmpUnitRenderer); @@ -113,10 +112,9 @@ return false; // Compare screen-space coordinates - float x, y; - camera.GetScreenCoordinates(position, x, y); - int ix = (int)x; - int iy = (int)y; + const CVector2D coordinates = camera.GetScreenCoordinates(position); + const int ix = static_cast(coordinates.X); + const int iy = static_cast(coordinates.Y); return sx0 <= ix && ix <= sx1 && sy0 <= iy && iy <= sy1; } Index: source/soundmanager/scripting/SoundGroup.cpp =================================================================== --- source/soundmanager/scripting/SoundGroup.cpp +++ source/soundmanager/scripting/SoundGroup.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -147,8 +147,7 @@ const float yBufferSize = 15.f; const float radianCap = m_MaxStereoAngle; - float x, y; - g_Game->GetView()->GetCamera()->GetScreenCoordinates(position, x, y); + const auto [x, y] = g_Game->GetView()->GetCamera()->GetScreenCoordinates(position); onScreen = true; float answer = 0.f; Index: source/tools/atlas/GameInterface/Handlers/CameraCtrlHandlers.cpp =================================================================== --- source/tools/atlas/GameInterface/Handlers/CameraCtrlHandlers.cpp +++ source/tools/atlas/GameInterface/Handlers/CameraCtrlHandlers.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -114,10 +114,10 @@ } else if (msg->type == eScrollType::TO) { - CVector3D origin, dir; float x, y; msg->pos->GetScreenSpace(x, y); - g_Game->GetView()->GetCamera()->BuildCameraRay((int)x, (int)y, origin, dir); + auto [origin, dir] = g_Game->GetView()->GetCamera()->BuildCameraRay( + static_cast(x), static_cast(y)); dir *= targetDistance; camera.Translate(targetPos - dir - origin); g_Game->GetView()->GetCamera()->UpdateFrustum(); Index: source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp =================================================================== --- source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp +++ source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -292,9 +292,8 @@ float delta = (upper - lower) / 3.0; float middle1 = lower + delta, middle2 = lower + 2.0f * delta; CVector3D p1 = base + dir * middle1, p2 = base + dir * middle2; - CVector2D s1, s2; - g_Game->GetView()->GetCamera()->GetScreenCoordinates(p1, s1.X, s1.Y); - g_Game->GetView()->GetCamera()->GetScreenCoordinates(p2, s2.X, s2.Y); + const CVector2D s1 = g_Game->GetView()->GetCamera()->GetScreenCoordinates(p1); + const CVector2D s2 = g_Game->GetView()->GetCamera()->GetScreenCoordinates(p2); if ((s1 - screen).Length() < (s2 - screen).Length()) upper = middle2; else @@ -462,8 +461,7 @@ data.Position.Y.ToFloat(), data.Position.Z.ToFloat() ); - CVector2D screen_pos; - g_Game->GetView()->GetCamera()->GetScreenCoordinates(position, screen_pos.X, screen_pos.Y); + const CVector2D screen_pos = g_Game->GetView()->GetCamera()->GetScreenCoordinates(position); if ((screen_pos - cursor).Length() < MINIMAL_SCREEN_DISTANCE) { node.index = i; @@ -508,8 +506,7 @@ static bool isAxisPicked(const CVector3D& base, const CVector3D& direction, float length, const CVector2D& cursor) { CVector3D position = GetNearestPointToScreenCoords(base, direction, cursor, 0, length); - CVector2D screen_position; - g_Game->GetView()->GetCamera()->GetScreenCoordinates(position, screen_position.X, screen_position.Y); + const CVector2D screen_position = g_Game->GetView()->GetCamera()->GetScreenCoordinates(position); return (cursor - screen_position).Length() < MINIMAL_SCREEN_DISTANCE; } Index: source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp =================================================================== --- source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp +++ source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -667,11 +667,10 @@ CFixedVector3D fixed = cmpPosition->GetPosition(); CVector3D centre = CVector3D(fixed.X.ToFloat(), fixed.Y.ToFloat(), fixed.Z.ToFloat()); - float cx, cy; - g_Game->GetView()->GetCamera()->GetScreenCoordinates(centre, cx, cy); + const CVector2D screen = g_Game->GetView()->GetCamera()->GetScreenCoordinates(centre); - msg->offsetx = (int)(cx - x); - msg->offsety = (int)(cy - y); + msg->offsetx = static_cast(screen.X - x); + msg->offsety = static_cast(screen.Y - y); } } } Index: source/tools/atlas/GameInterface/Misc.cpp =================================================================== --- source/tools/atlas/GameInterface/Misc.cpp +++ source/tools/atlas/GameInterface/Misc.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -78,9 +78,13 @@ switch (type) { case 0: - g_Game->GetView()->GetCamera()->GetScreenCoordinates(CVector3D(type0.x, type0.y, type0.x), x, y); + { + const CVector2D coordinates = g_Game->GetView()->GetCamera()->GetScreenCoordinates( + CVector3D(type0.x, type0.y, type0.x)); + x = coordinates.X; + y = coordinates.Y; break; - + } case 1: x = type1.x; y = type1.y;