diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp index 381ffaf72b..b3aa0f7a25 100644 --- a/source/graphics/GameView.cpp +++ b/source/graphics/GameView.cpp @@ -191,11 +191,16 @@ CObjectManager& CGameView::GetObjectManager() return m->ObjectManager; } -CCamera& CGameView::GetCamera() +const CCamera& CGameView::GetCamera() const { return m->ViewCamera; } +void CGameView::SetCamera(const CCamera& camera) +{ + m->ViewCamera = camera; +} + CCinemaManager* CGameView::GetCinema() { return &m->CinemaManager; diff --git a/source/graphics/GameView.h b/source/graphics/GameView.h index a54d374850..c99161dddb 100644 --- a/source/graphics/GameView.h +++ b/source/graphics/GameView.h @@ -78,7 +78,9 @@ public: #undef DECLARE_BOOLEAN_SETTING - CCamera& GetCamera(); + const CCamera& GetCamera() const; + void SetCamera(const CCamera& camera); + CCinemaManager* GetCinema(); CObjectManager& GetObjectManager(); diff --git a/source/graphics/MapReader.cpp b/source/graphics/MapReader.cpp index 005b4fa01f..1b3c9fc2ba 100644 --- a/source/graphics/MapReader.cpp +++ b/source/graphics/MapReader.cpp @@ -867,10 +867,12 @@ void CXMLReader::ReadCamera(XMBElement parent) if (m_MapReader.pGameView) { - m_MapReader.pGameView->GetCamera().m_Orientation.SetXRotation(declination); - m_MapReader.pGameView->GetCamera().m_Orientation.RotateY(rotation); - m_MapReader.pGameView->GetCamera().m_Orientation.Translate(translation); - m_MapReader.pGameView->GetCamera().UpdateFrustum(); + CCamera camera{m_MapReader.pGameView->GetCamera()}; + camera.m_Orientation.SetXRotation(declination); + camera.m_Orientation.RotateY(rotation); + camera.m_Orientation.Translate(translation); + camera.UpdateFrustum(); + m_MapReader.pGameView->SetCamera(camera); } } @@ -1631,10 +1633,12 @@ int CMapReader::ParseCamera() if (pGameView) { - pGameView->GetCamera().m_Orientation.SetXRotation(declination); - pGameView->GetCamera().m_Orientation.RotateY(rotation); - pGameView->GetCamera().m_Orientation.Translate(translation); - pGameView->GetCamera().UpdateFrustum(); + CCamera camera{pGameView->GetCamera()}; + camera.m_Orientation.SetXRotation(declination); + camera.m_Orientation.RotateY(rotation); + camera.m_Orientation.Translate(translation); + camera.UpdateFrustum(); + pGameView->SetCamera(camera); } return 0; diff --git a/source/ps/TouchInput.cpp b/source/ps/TouchInput.cpp index bc3f656d99..eb50859a8c 100644 --- a/source/ps/TouchInput.cpp +++ b/source/ps/TouchInput.cpp @@ -141,11 +141,12 @@ void CTouchInput::OnFingerMotion(int id, int x, int y) if (m_State == STATE_PANNING && id == 0) { - CCamera& camera{g_Game->GetView()->GetCamera()}; + CCamera camera{g_Game->GetView()->GetCamera()}; auto [origin, dir] = camera.BuildCameraRay(x, y); dir *= m_PanDist / dir.Y; camera.GetOrientation().Translate(m_PanFocus - dir - origin); camera.UpdateFrustum(); + g_Game->GetView()->SetCamera(camera); } if (m_State == STATE_ZOOMING && id == 1) @@ -154,11 +155,12 @@ void CTouchInput::OnFingerMotion(int id, int x, int y) float newDist = (m_Pos[id] - m_Pos[1 - id]).Length(); float zoomDist = (newDist - oldDist) * -0.005f * m_PanDist; - CCamera& camera{g_Game->GetView()->GetCamera()}; + CCamera camera{g_Game->GetView()->GetCamera()}; CVector3D dir{camera.BuildCameraRay(m_Pos[0].X, m_Pos[0].Y).direction}; dir *= zoomDist; camera.GetOrientation().Translate(dir); camera.UpdateFrustum(); + g_Game->GetView()->SetCamera(camera); m_PanFocus = camera.GetWorldCoordinates(m_Pos[0].X, m_Pos[0].Y, true); m_PanDist = (m_PanFocus - camera.GetOrientation().GetTranslation()).Y; diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index 7c6478d165..24d3fc0297 100644 --- a/source/renderer/Renderer.cpp +++ b/source/renderer/Renderer.cpp @@ -887,7 +887,9 @@ void CRenderer::RenderBigScreenShot(const bool needsPresent) oldCamera.GetFOV(), aspectRatio, oldCamera.GetNearPlane(), oldCamera.GetFarPlane(), tiles, tileX, tileY); } - g_Game->GetView()->GetCamera().SetProjection(projection); + CCamera camera{g_Game->GetView()->GetCamera()}; + camera.SetProjection(projection); + g_Game->GetView()->SetCamera(camera); Renderer::Backend::ISwapChain* swapChain{g_VideoMode.GetOrCreateSwapChain()}; if (!swapChain || !swapChain->IsValid()) @@ -919,7 +921,7 @@ void CRenderer::RenderBigScreenShot(const bool needsPresent) g_Renderer.Resize(g_xres, g_yres); SViewPort vp = { 0, 0, g_xres, g_yres }; g_Game->GetView()->SetViewport(vp); - g_Game->GetView()->GetCamera().SetProjectionFromCamera(oldCamera); + g_Game->GetView()->SetCamera(oldCamera); } if (tex_write(&t, filename) == INFO::OK) diff --git a/source/tools/atlas/GameInterface/Handlers/CameraCtrlHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/CameraCtrlHandlers.cpp index e6f3095ca1..15e7ac0e98 100644 --- a/source/tools/atlas/GameInterface/Handlers/CameraCtrlHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/CameraCtrlHandlers.cpp @@ -95,14 +95,14 @@ MESSAGEHANDLER(Scroll) static CVector3D targetPos; static float targetDistance = 0.f; - CMatrix3D& camera = g_Game->GetView()->GetCamera().m_Orientation; + CCamera camera{g_Game->GetView()->GetCamera()}; - static CVector3D lastCameraPos = camera.GetTranslation(); + static CVector3D lastCameraPos{camera.m_Orientation.GetTranslation()}; // Ensure roughly correct motion when dragging is combined with other // movements. - if (lastCameraPos != camera.GetTranslation()) - targetPos += camera.GetTranslation() - lastCameraPos; + if (lastCameraPos != camera.m_Orientation.GetTranslation()) + targetPos += camera.m_Orientation.GetTranslation() - lastCameraPos; // General operation: // @@ -118,7 +118,7 @@ MESSAGEHANDLER(Scroll) if (msg->type == eScrollType::FROM) { targetPos = msg->pos->GetWorldSpace(); - targetDistance = (targetPos - camera.GetTranslation()).Length(); + targetDistance = (targetPos - camera.m_Orientation.GetTranslation()).Length(); } else if (msg->type == eScrollType::TO) { @@ -126,14 +126,15 @@ MESSAGEHANDLER(Scroll) msg->pos->GetScreenSpace(x, y); auto [origin, dir] = g_Game->GetView()->GetCamera().BuildCameraRay((int)x, (int)y); dir *= targetDistance; - camera.Translate(targetPos - dir - origin); - g_Game->GetView()->GetCamera().UpdateFrustum(); + camera.m_Orientation.Translate(targetPos - dir - origin); + camera.UpdateFrustum(); + g_Game->GetView()->SetCamera(camera); } else { debug_warn(L"Scroll: Invalid type"); } - lastCameraPos = camera.GetTranslation(); + lastCameraPos = camera.m_Orientation.GetTranslation(); } MESSAGEHANDLER(SmoothZoom) @@ -152,7 +153,7 @@ MESSAGEHANDLER(RotateAround) static CVector3D focusPos; static float lastX = 0.f, lastY = 0.f; - CMatrix3D& camera = g_Game->GetView()->GetCamera().m_Orientation; + CCamera camera{g_Game->GetView()->GetCamera()}; if (msg->type == eRotateAroundType::FROM) { @@ -169,24 +170,25 @@ MESSAGEHANDLER(RotateAround) float rotY = 6.f * (x-lastX) / g_Renderer.GetWidth(); CQuaternion q0, q1; - q0.FromAxisAngle(camera.GetLeft(), -rotX); + q0.FromAxisAngle(camera.m_Orientation.GetLeft(), -rotX); q1.FromAxisAngle(CVector3D(0.f, 1.f, 0.f), rotY); CQuaternion q = q0*q1; - CVector3D origin = camera.GetTranslation(); + CVector3D origin = camera.m_Orientation.GetTranslation(); CVector3D offset = q.Rotate(origin - focusPos); - q *= camera.GetRotation(); + q *= camera.m_Orientation.GetRotation(); q.Normalize(); // to avoid things blowing up when turning upside-down, for some reason I don't understand - q.ToMatrix(camera); + q.ToMatrix(camera.m_Orientation); // Make sure up is still pointing up, regardless of any rounding errors. // (Maybe this distorts the camera in other ways, but at least the errors // are far less noticeable to me.) - camera._21 = 0.f; // (_21 = Y component returned by GetLeft()) + camera.m_Orientation._21 = 0.f; // (_21 = Y component returned by GetLeft()) - camera.Translate(focusPos + offset); - g_Game->GetView()->GetCamera().UpdateFrustum(); + camera.m_Orientation.Translate(focusPos + offset); + camera.UpdateFrustum(); + g_Game->GetView()->SetCamera(camera); lastX = x; lastY = y; @@ -200,7 +202,7 @@ MESSAGEHANDLER(RotateAround) MESSAGEHANDLER(LookAt) { // TODO: different camera depending on msg->view - CCamera& camera = AtlasView::GetView_Actor()->GetCamera(); + CCamera camera{AtlasView::GetView_Actor()->GetCamera()}; CVector3D tgt = msg->target->GetWorldSpace(); CVector3D eye = msg->pos->GetWorldSpace(); @@ -225,6 +227,8 @@ MESSAGEHANDLER(LookAt) camera.m_Orientation.Translate(-eye); camera.UpdateFrustum(); + + AtlasView::GetView_Actor()->SetCamera(camera); } QUERYHANDLER(GetView) @@ -272,9 +276,9 @@ MESSAGEHANDLER(ToggleBirdsEyeView) static float declination{0.f}; - CCamera& camera = AtlasView::GetView_Game()->GetCamera(); - CMatrix3D& orientation = camera.GetOrientation(); - CVector3D focus = camera.GetFocus(); + CCamera camera{AtlasView::GetView_Game()->GetCamera()}; + CMatrix3D& orientation{camera.GetOrientation()}; + const CVector3D focus{camera.GetFocus()}; if (!g_BirdEyeView) { @@ -298,6 +302,7 @@ MESSAGEHANDLER(ToggleBirdsEyeView) orientation.Translate(focus + offset); camera.UpdateFrustum(); + g_Game->GetView()->SetCamera(camera); g_BirdEyeView = !g_BirdEyeView; } diff --git a/source/tools/atlas/GameInterface/InputProcessor.cpp b/source/tools/atlas/GameInterface/InputProcessor.cpp index e0867f9558..17f17a5dca 100644 --- a/source/tools/atlas/GameInterface/InputProcessor.cpp +++ b/source/tools/atlas/GameInterface/InputProcessor.cpp @@ -52,11 +52,10 @@ bool InputProcessor::ProcessInput(GameLoopState* state) if (! g_Game) return false; - CCamera& camera{g_Game->GetView()->GetCamera()}; + CCamera camera{g_Game->GetView()->GetCamera()}; - CVector3D leftwards = camera.m_Orientation.GetLeft(); - - CVector3D inwards = camera.m_Orientation.GetIn(); + const CVector3D leftwards{camera.m_Orientation.GetLeft()}; + const CVector3D inwards{camera.m_Orientation.GetIn()}; // Calculate a vector pointing forwards, parallel to the ground CVector3D forwards = inwards; @@ -119,7 +118,10 @@ bool InputProcessor::ProcessInput(GameLoopState* state) } if (moved) + { camera.UpdateFrustum(); + g_Game->GetView()->SetCamera(camera); + } return moved; } diff --git a/source/tools/atlas/GameInterface/View.cpp b/source/tools/atlas/GameInterface/View.cpp index d7b7e4f103..371ca8eea6 100644 --- a/source/tools/atlas/GameInterface/View.cpp +++ b/source/tools/atlas/GameInterface/View.cpp @@ -94,20 +94,26 @@ void AtlasViewActor::Update(float realFrameLength) void AtlasViewActor::Render() { SViewPort vp = { 0, 0, g_xres, g_yres }; - CCamera& camera = GetCamera(); + CCamera camera{GetCamera()}; camera.SetViewPort(vp); camera.SetPerspectiveProjection(2.f, 512.f, DEGTORAD(20.f)); camera.UpdateFrustum(); + SetCamera(camera); m_ActorViewer->Render(); Atlas_GLSwapBuffers((void*)g_AtlasGameLoop->glCanvas); } -CCamera& AtlasViewActor::GetCamera() +const CCamera& AtlasViewActor::GetCamera() const { return m_Camera; } +void AtlasViewActor::SetCamera(const CCamera& camera) +{ + m_Camera = camera; +} + CSimulation2* AtlasViewActor::GetSimulation2() { return m_ActorViewer->GetSimulation2(); @@ -229,7 +235,9 @@ void AtlasViewGame::Update(float realFrameLength) // Cinematic motion should be independent of simulation update, so we can // preview the cinematics by themselves - g_Game->GetView()->GetCinema()->Update(realFrameLength, g_Game->GetView()->GetCamera()); + CCamera camera{g_Game->GetView()->GetCamera()}; + g_Game->GetView()->GetCinema()->Update(realFrameLength, camera); + g_Game->GetView()->SetCamera(camera); } void AtlasViewGame::Render() @@ -239,10 +247,11 @@ void AtlasViewGame::Render() return; SViewPort vp = { 0, 0, g_xres, g_yres }; - CCamera& camera = GetCamera(); + CCamera camera{GetCamera()}; camera.SetViewPort(vp); camera.SetProjectionFromCamera(g_Game->GetView()->GetCamera()); camera.UpdateFrustum(); + SetCamera(camera); g_Renderer.RenderFrame(false); Atlas_GLSwapBuffers((void*)g_AtlasGameLoop->glCanvas); @@ -335,11 +344,16 @@ void AtlasViewGame::SetParam(const std::wstring& name, const std::wstring& value } } -CCamera& AtlasViewGame::GetCamera() +const CCamera& AtlasViewGame::GetCamera() const { return g_Game->GetView()->GetCamera(); } +void AtlasViewGame::SetCamera(const CCamera& camera) +{ + g_Game->GetView()->SetCamera(camera); +} + bool AtlasViewGame::GetSmoothFramerate() const { if (g_Game->GetView()->GetCinema()->IsPlaying()) diff --git a/source/tools/atlas/GameInterface/View.h b/source/tools/atlas/GameInterface/View.h index 2279d29ee0..cf7d4ed20c 100644 --- a/source/tools/atlas/GameInterface/View.h +++ b/source/tools/atlas/GameInterface/View.h @@ -46,7 +46,8 @@ public: virtual void Render() { }; virtual void DrawCinemaPathTool(Renderer::Backend::IDeviceCommandContext&) { }; virtual void DrawOverlays(CCanvas2D& /*canvas*/) { }; - virtual CCamera& GetCamera() = 0; + virtual const CCamera& GetCamera() const = 0; + virtual void SetCamera(const CCamera& camera) = 0; virtual CSimulation2* GetSimulation2() { return NULL; } virtual entity_id_t GetEntityId(AtlasMessage::ObjectID obj) { return (entity_id_t)obj; } virtual bool GetSmoothFramerate() const { return false; } @@ -74,9 +75,10 @@ public: class AtlasViewNone : public AtlasView { public: - virtual CCamera& GetCamera() { return dummyCamera; } + virtual const CCamera& GetCamera() const { return m_DummyCamera; } + virtual void SetCamera(const CCamera& camera) { m_DummyCamera = camera; } private: - CCamera dummyCamera; + CCamera m_DummyCamera; }; ////////////////////////////////////////////////////////////////////////// @@ -95,7 +97,8 @@ public: virtual void Render(); virtual void DrawCinemaPathTool(Renderer::Backend::IDeviceCommandContext& deviceCommandContext); virtual void DrawOverlays(CCanvas2D& canvas); - virtual CCamera& GetCamera(); + virtual const CCamera& GetCamera() const; + virtual void SetCamera(const CCamera& camera); virtual CSimulation2* GetSimulation2(); virtual bool GetSmoothFramerate() const; virtual void SetSmoothFramerate(const bool enabled); @@ -139,7 +142,8 @@ public: virtual void Update(float realFrameLength); virtual void Render(); - virtual CCamera& GetCamera(); + virtual const CCamera& GetCamera() const; + virtual void SetCamera(const CCamera& camera); virtual CSimulation2* GetSimulation2(); virtual entity_id_t GetEntityId(AtlasMessage::ObjectID obj); virtual bool GetSmoothFramerate() const;