mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 13:23:56 -07:00
The whole map is revealed when starting to play a cinema path and then hidden again when it finished (if necessary). This patch fixes the ugly fade in at the start and fade out after the end previously caused by this.
145 lines
4.5 KiB
C++
145 lines
4.5 KiB
C++
/* Copyright (C) 2026 Wildfire Games.
|
|
* This file is part of 0 A.D.
|
|
*
|
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* 0 A.D. is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "precompiled.h"
|
|
|
|
#include "CinemaManager.h"
|
|
|
|
#include "graphics/Color.h"
|
|
#include "graphics/GameView.h"
|
|
#include "graphics/Terrain.h"
|
|
#include "maths/FixedVector3D.h"
|
|
#include "maths/NUSpline.h"
|
|
#include "maths/Vector3D.h"
|
|
#include "ps/CStr.h"
|
|
#include "ps/Game.h"
|
|
#include "ps/World.h"
|
|
#include "renderer/DebugRenderer.h"
|
|
#include "renderer/Renderer.h"
|
|
#include "renderer/RenderingOptions.h"
|
|
#include "simulation2/Simulation2.h"
|
|
#include "simulation2/components/ICmpCinemaManager.h"
|
|
#include "simulation2/helpers/CinemaPath.h"
|
|
#include "simulation2/system/Component.h"
|
|
|
|
#include <map>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
void CCinemaManager::Update(const float deltaRealTime)
|
|
{
|
|
CmpPtr<ICmpCinemaManager> cmpCinemaManager(g_Game->GetSimulation2()->GetSimContext().GetSystemEntity());
|
|
if (!cmpCinemaManager)
|
|
return;
|
|
|
|
if (IsPlaying())
|
|
{
|
|
if (g_RenderingOptions.GetSmoothLOS())
|
|
{
|
|
g_RenderingOptions.SetSmoothLOS(false);
|
|
m_SmoothLosOverridden = true;
|
|
}
|
|
cmpCinemaManager->UpdateActivePath(deltaRealTime, g_Game->GetView()->GetCamera());
|
|
return;
|
|
}
|
|
|
|
if (std::exchange(m_SmoothLosOverridden, false))
|
|
g_RenderingOptions.SetSmoothLOS(true);
|
|
}
|
|
|
|
void CCinemaManager::Render(Renderer::Backend::IDeviceCommandContext& deviceCommandContext) const
|
|
{
|
|
if (!IsPlaying() && m_DrawPaths)
|
|
DrawPaths(deviceCommandContext);
|
|
}
|
|
|
|
void CCinemaManager::DrawPaths(Renderer::Backend::IDeviceCommandContext& deviceCommandContext) const
|
|
{
|
|
CmpPtr<ICmpCinemaManager> cmpCinemaManager(g_Game->GetSimulation2()->GetSimContext().GetSystemEntity());
|
|
if (!cmpCinemaManager)
|
|
return;
|
|
|
|
for (const std::pair<const CStrW, CCinemaPath>& p : cmpCinemaManager->GetPaths())
|
|
{
|
|
DrawSpline(deviceCommandContext, p.second, CColor(0.2f, 0.2f, 1.f, 0.9f), 128);
|
|
DrawNodes(deviceCommandContext, p.second, CColor(0.1f, 1.f, 0.f, 1.f));
|
|
|
|
if (p.second.GetTargetSpline().GetAllNodes().empty())
|
|
continue;
|
|
|
|
DrawSpline(deviceCommandContext, p.second.GetTargetSpline(), CColor(1.f, 0.3f, 0.4f, 0.9f), 128);
|
|
DrawNodes(deviceCommandContext, p.second.GetTargetSpline(), CColor(1.f, 0.1f, 0.f, 1.f));
|
|
}
|
|
}
|
|
|
|
void CCinemaManager::DrawSpline(Renderer::Backend::IDeviceCommandContext& deviceCommandContext, const RNSpline& spline, const CColor& splineColor, int smoothness) const
|
|
{
|
|
if (spline.GetAllNodes().size() < 2)
|
|
return;
|
|
if (spline.GetAllNodes().size() == 2)
|
|
smoothness = 2;
|
|
|
|
const float start = spline.MaxDistance.ToFloat() / smoothness;
|
|
|
|
std::vector<CVector3D> line;
|
|
for (int i = 0; i <= smoothness; ++i)
|
|
{
|
|
const float time = start * i / spline.MaxDistance.ToFloat();
|
|
line.emplace_back(spline.GetPosition(time));
|
|
}
|
|
|
|
g_Renderer.GetDebugRenderer().DrawLine(deviceCommandContext, line, splineColor, 0.2f, false);
|
|
|
|
// Height indicator
|
|
if (g_Game && g_Game->GetWorld())
|
|
{
|
|
for (int i = 0; i <= smoothness; ++i)
|
|
{
|
|
const float time = start * i / spline.MaxDistance.ToFloat();
|
|
const CVector3D tmp = spline.GetPosition(time);
|
|
const float groundY = g_Game->GetWorld()->GetTerrain().GetExactGroundLevel(tmp.X, tmp.Z);
|
|
g_Renderer.GetDebugRenderer().DrawLine(deviceCommandContext, tmp, CVector3D(tmp.X, groundY, tmp.Z), splineColor, 0.1f, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CCinemaManager::DrawNodes(Renderer::Backend::IDeviceCommandContext& deviceCommandContext, const RNSpline& spline, const CColor& nodeColor) const
|
|
{
|
|
for (const SplineData& node : spline.GetAllNodes())
|
|
{
|
|
g_Renderer.GetDebugRenderer().DrawCircle(
|
|
deviceCommandContext,
|
|
CVector3D(node.Position.X.ToFloat(), node.Position.Y.ToFloat(), node.Position.Z.ToFloat()),
|
|
0.5f, nodeColor);
|
|
}
|
|
}
|
|
|
|
bool CCinemaManager::IsPlaying() const
|
|
{
|
|
CmpPtr<ICmpCinemaManager> cmpCinemaManager(g_Game->GetSimulation2()->GetSimContext().GetSystemEntity());
|
|
return cmpCinemaManager && cmpCinemaManager->IsPlayingQueue();
|
|
}
|
|
|
|
bool CCinemaManager::GetPathsDrawing() const
|
|
{
|
|
return m_DrawPaths;
|
|
}
|
|
|
|
void CCinemaManager::SetPathsDrawing(const bool drawPath)
|
|
{
|
|
m_DrawPaths = drawPath;
|
|
}
|