Index: source/graphics/Camera.h =================================================================== --- source/graphics/Camera.h +++ source/graphics/Camera.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2024 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -44,7 +44,8 @@ // Represents camera viewport or frustum side in 3D space. using Quad = std::array; - enum class ProjectionType + enum ProjectionType + //CCamera::ProjectionType mirrors ScenarioEditor::ProjectionType { CUSTOM, ORTHO, Index: source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h =================================================================== --- source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h +++ source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2024 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -32,6 +32,15 @@ class ScenarioEditor : public wxFrame { public: + + enum ProjectionType + //ScenarioEditor::ProjectionType mirrors CCamera::ProjectionType + { + CUSTOM, + ORTHO, + PERSPECTIVE, + }; + ScenarioEditor(wxWindow* parent); void OnClose(wxCloseEvent& event); void OnTimer(wxTimerEvent& event); Index: source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.cpp =================================================================== --- source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.cpp +++ source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2024 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -49,6 +49,7 @@ ID_ViewerBoundingBox, ID_ViewerAxesMarker, ID_ViewerPropPoints, + ID_ViewerSetProjection, ID_ViewerPlay, ID_ViewerPause, ID_ViewerSlow @@ -87,6 +88,7 @@ bool m_ViewerPolyCount; bool m_ViewerBoundingBox; bool m_ViewerAxesMarker; + ScenarioEditor::ProjectionType m_ProjectionType; int m_ViewerPropPointsMode; // 0 disabled, 1 for point markers, 2 for point markers + axes wxPanel* m_ViewerPanel; @@ -99,6 +101,7 @@ struct ObjectSidebarImpl { ObjectSidebarImpl(ScenarioEditor& scenarioEditor) : + m_ScenarioEditor(scenarioEditor), m_ObjectListBox(NULL), m_ActorViewerActive(false), m_ActorViewerEntity(L"actor|structures/fndn_1x1.xml"), m_ActorViewerAnimation("idle"), m_ActorViewerSpeed(0.f), @@ -106,6 +109,7 @@ { } + ScenarioEditor& m_ScenarioEditor; wxListBox* m_ObjectListBox; std::vector m_Objects; ObservableScopedConnection m_ToolConn; @@ -525,6 +529,7 @@ m_ViewerPolyCount = false; m_ViewerBoundingBox = false; m_ViewerAxesMarker = false; + m_ProjectionType = ScenarioEditor::ProjectionType::PERSPECTIVE; m_ViewerPropPointsMode = 0; wxSizer* mainSizer = new wxBoxSizer(wxHORIZONTAL); @@ -553,6 +558,7 @@ viewerButtonsRight->Add(Tooltipped(new wxButton(m_ViewerPanel, ID_ViewerBoundingBox, _("Bounding Boxes")), _("Toggle bounding boxes")), wxSizerFlags().Expand()); viewerButtonsRight->Add(Tooltipped(new wxButton(m_ViewerPanel, ID_ViewerAxesMarker, _("Axes Marker")), _("Toggle the axes marker (R=X, G=Y, B=Z)")), wxSizerFlags().Expand()); viewerButtonsRight->Add(Tooltipped(new wxButton(m_ViewerPanel, ID_ViewerPropPoints, _("Prop Points")), _("Toggle prop points (works best in wireframe mode)")), wxSizerFlags().Expand()); + viewerButtonsRight->Add(Tooltipped(new wxButton(m_ViewerPanel, ID_ViewerSetProjection, _("Toggle Perspective")), _("Toggle between perspective and orthogonal projection in the viewer")), wxSizerFlags().Expand()); viewerButtonsSizer->Add(viewerButtonsLeft, wxSizerFlags().Expand()); viewerButtonsSizer->Add(viewerButtonsRight, wxSizerFlags().Expand()); @@ -701,6 +707,7 @@ POST_MESSAGE(SetViewParamB, (AtlasMessage::eRenderView::ACTOR, L"water", m_ViewerWater)); POST_MESSAGE(SetViewParamB, (AtlasMessage::eRenderView::ACTOR, L"stats", m_ViewerPolyCount)); POST_MESSAGE(SetViewParamB, (AtlasMessage::eRenderView::ACTOR, L"bounding_box", m_ViewerBoundingBox)); + POST_MESSAGE(SetViewParamI, (AtlasMessage::eRenderView::ACTOR, L"Set Projection", m_ProjectionType)); POST_MESSAGE(SetViewParamI, (AtlasMessage::eRenderView::ACTOR, L"prop_points", m_ViewerPropPointsMode)); } @@ -749,6 +756,20 @@ m_ViewerPropPointsMode = (m_ViewerPropPointsMode+1) % 3; POST_MESSAGE(SetViewParamI, (AtlasMessage::eRenderView::ACTOR, L"prop_points", m_ViewerPropPointsMode)); break; + case ID_ViewerSetProjection: + if (m_ProjectionType == ScenarioEditor::ProjectionType::ORTHO) + { + m_ProjectionType = ScenarioEditor::ProjectionType::PERSPECTIVE; + p->m_ScenarioEditor.GetToolManager().GetCurrentTool()->OnCommand(_T("Set Perspective"), NULL); + POST_MESSAGE(SetViewParamI, (AtlasMessage::eRenderView::ACTOR, L"Set Projection", m_ProjectionType)); + } + else if (m_ProjectionType == ScenarioEditor::ProjectionType::PERSPECTIVE) + { + m_ProjectionType = ScenarioEditor::ProjectionType::ORTHO; + p->m_ScenarioEditor.GetToolManager().GetCurrentTool()->OnCommand(_T("Set Orthogonal"), NULL); + POST_MESSAGE(SetViewParamI, (AtlasMessage::eRenderView::ACTOR, L"Set Projection", m_ProjectionType)); + } + break; } } @@ -783,4 +804,5 @@ EVT_BUTTON(ID_ViewerBoundingBox, ObjectBottomBar::OnViewerSetting) EVT_BUTTON(ID_ViewerAxesMarker, ObjectBottomBar::OnViewerSetting) EVT_BUTTON(ID_ViewerPropPoints, ObjectBottomBar::OnViewerSetting) + EVT_BUTTON(ID_ViewerSetProjection, ObjectBottomBar::OnViewerSetting) END_EVENT_TABLE(); Index: source/tools/atlas/AtlasUI/ScenarioEditor/Tools/ActorViewerTool.cpp =================================================================== --- source/tools/atlas/AtlasUI/ScenarioEditor/Tools/ActorViewerTool.cpp +++ source/tools/atlas/AtlasUI/ScenarioEditor/Tools/ActorViewerTool.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 Wildfire Games. +/* Copyright (C) 2024 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -38,6 +38,7 @@ float m_Distance; float m_Angle; float m_Elevation; + ScenarioEditor::ProjectionType m_ProjectionType; // Mouse input state int m_LastX, m_LastY; @@ -45,7 +46,10 @@ public: ActorViewerTool() : - m_Distance(20.f), m_Angle(0.f), m_Elevation((float)M_PI / 6.f), + m_Distance(20.f), + m_Angle(0.f), + m_Elevation((float)M_PI / 6.f), + m_ProjectionType(ScenarioEditor::ProjectionType::PERSPECTIVE), m_LastIsValid(false) { } @@ -53,12 +57,30 @@ void PostLookAt() { float offset = 0.3f; // slight fudge so we turn nicely when going over the top of the unit - POST_MESSAGE(LookAt, (AtlasMessage::eRenderView::ACTOR, - Position( - m_Distance*cos(m_Elevation)*sin(m_Angle) + offset*cos(m_Angle), - m_Distance*sin(m_Elevation), - m_Distance*cos(m_Elevation)*cos(m_Angle) - offset*sin(m_Angle)), - Position(0, 0, 0))); + + + + if (m_ProjectionType == ScenarioEditor::ProjectionType::PERSPECTIVE) + { + + POST_MESSAGE(LookAt, (AtlasMessage::eRenderView::ACTOR, + Position( + m_Distance*cos(m_Elevation)*sin(m_Angle) + offset*cos(m_Angle), + m_Distance*sin(m_Elevation), + m_Distance*cos(m_Elevation)*cos(m_Angle) - offset*sin(m_Angle)), + Position(0, 0, 0))); + } + else if (m_ProjectionType == ScenarioEditor::ProjectionType::ORTHO) + { + + POST_MESSAGE(LookAt, (AtlasMessage::eRenderView::ACTOR, + Position( + 20*cos(m_Elevation)*sin(m_Angle) + offset*cos(m_Angle), + 20*sin(m_Elevation), + 20*cos(m_Elevation)*cos(m_Angle) - offset*sin(m_Angle)), + Position(0, 0, 0))); + + } } virtual void Init(void* initData, ScenarioEditor* scenarioEditor) @@ -68,6 +90,20 @@ SetState(&Viewing); } + virtual void OnCommand(const wxString& command, void* WXUNUSED(userdata)) + { + if (command == _T("Set Orthogonal")) + { + m_ProjectionType = ScenarioEditor::ProjectionType::ORTHO; + PostLookAt(); + } + else if (command == _T("Set Perspective")) + { + m_ProjectionType = ScenarioEditor::ProjectionType::PERSPECTIVE; + PostLookAt(); + } + } + void OnEnable() { GetScenarioEditor().GetObjectSettings().SetView(AtlasMessage::eRenderView::ACTOR); @@ -102,7 +138,8 @@ float speed = -1.f * ScenarioEditor::GetSpeedModifier(); obj->m_Distance += evt.GetWheelRotation() * speed / evt.GetWheelDelta(); - + POST_MESSAGE(SetViewParamF, + (AtlasMessage::eRenderView::ACTOR, L"Set orthogonal scale", obj->m_Distance / 3.0)); camera_changed = true; } @@ -124,10 +161,18 @@ obj->m_Angle += dx * M_PI/256.f * ScenarioEditor::GetSpeedModifier(); if (evt.ButtonIsDown(wxMOUSE_BTN_LEFT)) + { obj->m_Distance += dy / 8.f * ScenarioEditor::GetSpeedModifier(); - else // evt.ButtonIsDown(wxMOUSE_BTN_RIGHT)) - obj->m_Elevation += dy * M_PI/256.f * ScenarioEditor::GetSpeedModifier(); + POST_MESSAGE(SetViewParamF, + (AtlasMessage::eRenderView::ACTOR, L"Set orthogonal scale", obj->m_Distance / 3.0)); + + camera_changed = true; + } + else + {// evt.ButtonIsDown(wxMOUSE_BTN_RIGHT)) + obj->m_Elevation += dy * M_PI / 256.f * ScenarioEditor::GetSpeedModifier(); + } camera_changed = true; } else if ((evt.ButtonUp(wxMOUSE_BTN_LEFT) || evt.ButtonUp(wxMOUSE_BTN_RIGHT)) Index: source/tools/atlas/GameInterface/Handlers/GraphicsSetupHandlers.cpp =================================================================== --- source/tools/atlas/GameInterface/Handlers/GraphicsSetupHandlers.cpp +++ source/tools/atlas/GameInterface/Handlers/GraphicsSetupHandlers.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 Wildfire Games. +/* Copyright (C) 2024 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -178,6 +178,13 @@ view->SetParam(*msg->name, msg->value); } +MESSAGEHANDLER(SetViewParamF) +{ + AtlasView* view = AtlasView::GetView(msg->view); + view->SetParam(*msg->name, msg->value); +} + + MESSAGEHANDLER(SetViewParamC) { AtlasView* view = AtlasView::GetView(msg->view); Index: source/tools/atlas/GameInterface/Messages.h =================================================================== --- source/tools/atlas/GameInterface/Messages.h +++ source/tools/atlas/GameInterface/Messages.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 Wildfire Games. +/* Copyright (C) 2024 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -71,6 +71,11 @@ ((std::wstring, name)) ((int, value)) ); +MESSAGE(SetViewParamF, + ((int, view)) // eRenderView + ((std::wstring, name)) + ((float, value)) + ); MESSAGE(SetViewParamC, ((int, view)) // eRenderView ((std::wstring, name)) Index: source/tools/atlas/GameInterface/View.h =================================================================== --- source/tools/atlas/GameInterface/View.h +++ source/tools/atlas/GameInterface/View.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2024 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -142,6 +142,7 @@ virtual void SetParam(const std::wstring& name, bool value); virtual void SetParam(const std::wstring& name, int value); + virtual void SetParam(const std::wstring& name, float value); virtual void SetParam(const std::wstring& name, const AtlasMessage::Color& value); void SetSpeedMultiplier(float speedMultiplier); @@ -151,6 +152,8 @@ float m_SpeedMultiplier; CCamera m_Camera; ActorViewer* m_ActorViewer; + CCamera::ProjectionType m_ProjectionType; + float m_Orthogonal_Scale; }; #endif // INCLUDED_VIEW Index: source/tools/atlas/GameInterface/View.cpp =================================================================== --- source/tools/atlas/GameInterface/View.cpp +++ source/tools/atlas/GameInterface/View.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 Wildfire Games. +/* Copyright (C) 2024 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -71,8 +71,11 @@ ////////////////////////////////////////////////////////////////////////// -AtlasViewActor::AtlasViewActor() -: m_SpeedMultiplier(1.f), m_ActorViewer(new ActorViewer()) +AtlasViewActor::AtlasViewActor() : + m_SpeedMultiplier(1.f), + m_ActorViewer(new ActorViewer()), + m_Orthogonal_Scale(20.0/3.0), + m_ProjectionType(CCamera::ProjectionType::PERSPECTIVE) { } @@ -91,7 +94,14 @@ SViewPort vp = { 0, 0, g_xres, g_yres }; CCamera& camera = GetCamera(); camera.SetViewPort(vp); - camera.SetPerspectiveProjection(2.f, 512.f, DEGTORAD(20.f)); + if (m_ProjectionType == CCamera::ProjectionType::PERSPECTIVE) + { + camera.SetPerspectiveProjection(2.f, 512.f, DEGTORAD(20.f)); + } + else //m_ProjectionType == CCamera::ProjectionType:ORTHO + { + camera.SetOrthoProjection(-2.f, -512.f, m_Orthogonal_Scale); + } camera.UpdateFrustum(); m_ActorViewer->Render(); @@ -163,8 +173,37 @@ { if (name == L"prop_points") m_ActorViewer->SetPropPointsMode(value); -} + else if (name == L"Set Projection") + { + CCamera& camera = AtlasView::GetView_Actor()->GetCamera(); + if (value == CCamera::ProjectionType::PERSPECTIVE) + { + m_ProjectionType = CCamera::ProjectionType::PERSPECTIVE; + camera.SetPerspectiveProjection(2.f, 512.f, DEGTORAD(20.f)); + camera.UpdateFrustum(); + } + else if (value == CCamera::ProjectionType::ORTHO) + { + m_ProjectionType = CCamera::ProjectionType::ORTHO; + camera.SetOrthoProjection(-2.f, -512.f, m_Orthogonal_Scale); + camera.UpdateFrustum(); + } + } +} +void AtlasViewActor::SetParam(const std::wstring& name, float value) +{ + if (name == L"Set orthogonal scale") + { + m_Orthogonal_Scale = value; + if (m_ProjectionType == CCamera::ProjectionType::ORTHO) + { + CCamera &camera = AtlasView::GetView_Actor()->GetCamera(); + camera.SetOrthoProjection(-2.f, -512.f, m_Orthogonal_Scale); + camera.UpdateFrustum(); + } + } +} void AtlasViewActor::SetParam(const std::wstring& UNUSED(name), const AtlasMessage::Color& UNUSED(value)) { }