Index: ps/trunk/source/simulation2/components/CCmpCinemaManager.cpp
===================================================================
--- ps/trunk/source/simulation2/components/CCmpCinemaManager.cpp (revision 19381)
+++ ps/trunk/source/simulation2/components/CCmpCinemaManager.cpp (revision 19382)
@@ -1,325 +1,362 @@
/* Copyright (C) 2017 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 .
*/
#include "precompiled.h"
#include "simulation2/system/Component.h"
#include "ICmpCinemaManager.h"
#include "graphics/GameView.h"
#include "graphics/CinemaManager.h"
#include "gui/CGUI.h"
#include "gui/GUIManager.h"
#include "gui/IGUIObject.h"
#include "ps/CLogger.h"
#include "ps/Game.h"
#include "simulation2/components/ICmpOverlayRenderer.h"
#include "simulation2/components/ICmpRangeManager.h"
#include "simulation2/components/ICmpSelectable.h"
#include "simulation2/components/ICmpTerritoryManager.h"
#include "simulation2/MessageTypes.h"
#include "simulation2/Simulation2.h"
#include "renderer/Renderer.h"
class CCmpCinemaManager : public ICmpCinemaManager
{
public:
static void ClassInit(CComponentManager& componentManager)
{
componentManager.SubscribeToMessageType(MT_Update);
}
DEFAULT_COMPONENT_ALLOCATOR(CinemaManager)
static std::string GetSchema()
{
return "";
}
virtual void Init(const CParamNode& UNUSED(paramNode))
{
m_Enabled = false;
m_MapRevealed = false;
m_ElapsedTime = fixed::Zero();
m_TotalTime = fixed::Zero();
m_CurrentPathElapsedTime = fixed::Zero();
}
virtual void Deinit()
{
}
- virtual void Serialize(ISerializer& serialize)
+ virtual void Serialize(ISerializer& serializer)
{
- serialize.Bool("MapRevealed", m_MapRevealed);
- serialize.NumberU32_Unbounded("NumberOfPaths", m_Paths.size());
- for (const std::pair& it : m_Paths)
- {
- const CCinemaPath& path = it.second;
- const CCinemaData* data = path.GetData();
+ serializer.Bool("Enabled", m_Enabled);
+ serializer.NumberFixed_Unbounded("ElapsedTime", m_ElapsedTime);
+ serializer.NumberFixed_Unbounded("CurrentPathElapsedTime", m_CurrentPathElapsedTime);
+ serializer.Bool("MapRevealed", m_MapRevealed);
- // TODO: maybe implement String_Unbounded
- serialize.String("PathName", data->m_Name, 1, 2048);
- serialize.String("PathOrientation", data->m_Orientation, 1, 2048);
- serialize.String("PathMode", data->m_Mode, 1, 2048);
- serialize.String("PathStyle", data->m_Style, 1, 2048);
- serialize.NumberFixed_Unbounded("PathTimescale", data->m_Timescale);
- serialize.Bool("LookAtTarget", data->m_LookAtTarget);
-
- serialize.NumberU32("NumberOfNodes", path.GetAllNodes().size(), 1, MAX_SPLINE_NODES);
- const std::vector& nodes = path.GetAllNodes();
- for (size_t i = 0; i < nodes.size(); ++i)
- {
- if (i > 0)
- serialize.NumberFixed_Unbounded("NodeDeltaTime", nodes[i - 1].Distance);
- else
- serialize.NumberFixed_Unbounded("NodeDeltaTime", fixed::Zero());
- serialize.NumberFixed_Unbounded("PositionX", nodes[i].Position.X);
- serialize.NumberFixed_Unbounded("PositionY", nodes[i].Position.Y);
- serialize.NumberFixed_Unbounded("PositionZ", nodes[i].Position.Z);
-
- serialize.NumberFixed_Unbounded("RotationX", nodes[i].Rotation.X);
- serialize.NumberFixed_Unbounded("RotationY", nodes[i].Rotation.Y);
- serialize.NumberFixed_Unbounded("RotationZ", nodes[i].Rotation.Z);
- }
-
- if (!data->m_LookAtTarget)
- continue;
+ serializer.NumberU32_Unbounded("NumberOfPaths", m_Paths.size());
+ for (const std::pair& it : m_Paths)
+ SerializePath(it.second, serializer);
- const std::vector& targetNodes = path.GetTargetSpline().GetAllNodes();
- serialize.NumberU32("NumberOfTargetNodes", targetNodes.size(), 1, MAX_SPLINE_NODES);
- for (size_t i = 0; i < targetNodes.size(); ++i)
- {
- if (i > 0)
- serialize.NumberFixed_Unbounded("NodeDeltaTime", targetNodes[i - 1].Distance);
- else
- serialize.NumberFixed_Unbounded("NodeDeltaTime", fixed::Zero());
- serialize.NumberFixed_Unbounded("PositionX", targetNodes[i].Position.X);
- serialize.NumberFixed_Unbounded("PositionY", targetNodes[i].Position.Y);
- serialize.NumberFixed_Unbounded("PositionZ", targetNodes[i].Position.Z);
- }
- }
+ serializer.NumberU32_Unbounded("NumberOfQueuedPaths", m_PathQueue.size());
+ for (const CCinemaPath& path : m_PathQueue)
+ serializer.String("PathName", path.GetName(), 1, 128);
}
- virtual void Deserialize(const CParamNode& UNUSED(paramNode), IDeserializer& deserialize)
+ virtual void Deserialize(const CParamNode& UNUSED(paramNode), IDeserializer& deserializer)
{
- deserialize.Bool("MapRevealed", m_MapRevealed);
+ deserializer.Bool("Enabled", m_Enabled);
+ deserializer.NumberFixed_Unbounded("ElapsedTime", m_ElapsedTime);
+ deserializer.NumberFixed_Unbounded("CurrentPathElapsedTime", m_CurrentPathElapsedTime);
+ deserializer.Bool("MapRevealed", m_MapRevealed);
+
uint32_t numberOfPaths = 0;
- deserialize.NumberU32_Unbounded("NumberOfPaths", numberOfPaths);
+ deserializer.NumberU32_Unbounded("NumberOfPaths", numberOfPaths);
for (uint32_t i = 0; i < numberOfPaths; ++i)
{
- CCinemaData data;
-
- deserialize.String("PathName", data.m_Name, 1, 2048);
- deserialize.String("PathOrientation", data.m_Orientation, 1, 2048);
- deserialize.String("PathMode", data.m_Mode, 1, 2048);
- deserialize.String("PathStyle", data.m_Style, 1, 2048);
- deserialize.NumberFixed_Unbounded("PathTimescale", data.m_Timescale);
- deserialize.Bool("LookAtTarget", data.m_LookAtTarget);
-
- TNSpline pathSpline, targetSpline;
- uint32_t numberOfNodes = 0;
- deserialize.NumberU32("NumberOfNodes", numberOfNodes, 1, MAX_SPLINE_NODES);
- for (uint32_t j = 0; j < numberOfNodes; ++j)
- {
- SplineData node;
- deserialize.NumberFixed_Unbounded("NodeDeltaTime", node.Distance);
-
- deserialize.NumberFixed_Unbounded("PositionX", node.Position.X);
- deserialize.NumberFixed_Unbounded("PositionY", node.Position.Y);
- deserialize.NumberFixed_Unbounded("PositionZ", node.Position.Z);
-
- deserialize.NumberFixed_Unbounded("RotationX", node.Rotation.X);
- deserialize.NumberFixed_Unbounded("RotationY", node.Rotation.Y);
- deserialize.NumberFixed_Unbounded("RotationZ", node.Rotation.Z);
-
- pathSpline.AddNode(node.Position, node.Rotation, node.Distance);
- }
-
- if (data.m_LookAtTarget)
- {
- uint32_t numberOfTargetNodes = 0;
- deserialize.NumberU32("NumberOfTargetNodes", numberOfTargetNodes, 1, MAX_SPLINE_NODES);
- for (uint32_t j = 0; j < numberOfTargetNodes; ++j)
- {
- SplineData node;
- deserialize.NumberFixed_Unbounded("NodeDeltaTime", node.Distance);
-
- deserialize.NumberFixed_Unbounded("PositionX", node.Position.X);
- deserialize.NumberFixed_Unbounded("PositionY", node.Position.Y);
- deserialize.NumberFixed_Unbounded("PositionZ", node.Position.Z);
+ CCinemaPath path = DeserializePath(deserializer);
+ m_Paths[path.GetName()] = path;
+ }
- targetSpline.AddNode(node.Position, CFixedVector3D(), node.Distance);
- }
- }
+ uint32_t numberOfQueuedPaths = 0;
+ deserializer.NumberU32_Unbounded("NumberOfQueuedPaths", numberOfQueuedPaths);
+ for (uint32_t i = 0; i < numberOfQueuedPaths; ++i)
+ {
+ CStrW pathName;
+ deserializer.String("PathName", pathName, 1, 128);
+ ENSURE(HasPath(pathName));
+ AddCinemaPathToQueue(pathName);
+ }
- // Construct cinema path with data gathered
- m_Paths[data.m_Name] = CCinemaPath(data, pathSpline, targetSpline);
+ if (!m_PathQueue.empty())
+ {
+ m_PathQueue.front().m_TimeElapsed = m_CurrentPathElapsedTime.ToFloat();
+ m_PathQueue.front().Validate();
}
+
SetEnabled(m_Enabled);
}
virtual void HandleMessage(const CMessage& msg, bool UNUSED(global))
{
switch (msg.GetType())
{
case MT_Update:
{
const CMessageUpdate &msgData = static_cast(msg);
if (!m_Enabled)
break;
m_ElapsedTime += msgData.turnLength;
m_CurrentPathElapsedTime += msgData.turnLength;
if (m_CurrentPathElapsedTime >= m_PathQueue.front().GetDuration())
{
CMessageCinemaPathEnded msgCinemaPathEnded(m_PathQueue.front().GetName());
m_PathQueue.pop_front();
GetSimContext().GetComponentManager().PostMessage(SYSTEM_ENTITY, msgCinemaPathEnded);
m_CurrentPathElapsedTime = fixed::Zero();
if (!m_PathQueue.empty())
m_PathQueue.front().Reset();
}
if (m_ElapsedTime >= m_TotalTime)
{
m_CurrentPathElapsedTime = fixed::Zero();
m_ElapsedTime = fixed::Zero();
m_TotalTime = fixed::Zero();
SetEnabled(false);
GetSimContext().GetComponentManager().PostMessage(SYSTEM_ENTITY, CMessageCinemaQueueEnded());
}
break;
}
default:
break;
}
}
virtual void AddPath(const CStrW& name, const CCinemaPath& path)
{
if (m_Paths.find(name) != m_Paths.end())
{
LOGWARNING("Path with name '%s' already exists", name.ToUTF8());
return;
}
m_Paths[name] = path;
}
virtual void AddCinemaPathToQueue(const CStrW& name)
{
if (!HasPath(name))
{
LOGWARNING("Path with name '%s' doesn't exist", name.ToUTF8());
return;
}
m_PathQueue.push_back(m_Paths[name]);
if (m_PathQueue.size() == 1)
m_PathQueue.front().Reset();
m_TotalTime += m_Paths[name].GetDuration();
}
virtual void Play()
{
SetEnabled(true);
}
virtual void Stop()
{
SetEnabled(false);
}
virtual bool HasPath(const CStrW& name) const
{
return m_Paths.find(name) != m_Paths.end();
}
virtual void ClearQueue()
{
m_PathQueue.clear();
}
virtual const std::map& GetPaths() const
{
return m_Paths;
}
virtual void SetPaths(const std::map& newPaths)
{
m_Paths = newPaths;
}
virtual const std::list& GetQueue() const
{
return m_PathQueue;
}
virtual bool IsEnabled() const
{
return m_Enabled;
}
virtual void SetEnabled(bool enabled)
{
if (m_PathQueue.empty() && enabled)
enabled = false;
if (m_Enabled == enabled)
return;
CmpPtr cmpRangeManager(GetSimContext().GetSystemEntity());
CmpPtr cmpTerritoryManager(GetSimContext().GetSystemEntity());
if (cmpRangeManager)
{
if (enabled)
m_MapRevealed = cmpRangeManager->GetLosRevealAll(-1);
// TODO: improve m_MapRevealed state and without fade in
cmpRangeManager->SetLosRevealAll(-1, enabled);
}
if (cmpTerritoryManager)
cmpTerritoryManager->SetVisibility(!enabled);
ICmpSelectable::SetOverrideVisibility(!enabled);
ICmpOverlayRenderer::SetOverrideVisibility(!enabled);
m_Enabled = enabled;
}
virtual void PlayQueue(const float deltaRealTime, CCamera* camera)
{
if (m_PathQueue.empty())
return;
m_PathQueue.front().Play(deltaRealTime, camera);
}
private:
+
+ void SerializePath(const CCinemaPath& path, ISerializer& serializer)
+ {
+ const CCinemaData* data = path.GetData();
+
+ serializer.String("PathName", data->m_Name, 1, 128);
+ serializer.String("PathOrientation", data->m_Orientation, 1, 128);
+ serializer.String("PathMode", data->m_Mode, 1, 128);
+ serializer.String("PathStyle", data->m_Style, 1, 128);
+ serializer.NumberFixed_Unbounded("PathTimescale", data->m_Timescale);
+ serializer.Bool("LookAtTarget", data->m_LookAtTarget);
+
+ serializer.NumberU32("NumberOfNodes", path.GetAllNodes().size(), 1, MAX_SPLINE_NODES);
+ const std::vector& nodes = path.GetAllNodes();
+ for (size_t i = 0; i < nodes.size(); ++i)
+ {
+ if (i > 0)
+ serializer.NumberFixed_Unbounded("NodeDeltaTime", nodes[i - 1].Distance);
+ else
+ serializer.NumberFixed_Unbounded("NodeDeltaTime", fixed::Zero());
+
+ serializer.NumberFixed_Unbounded("PositionX", nodes[i].Position.X);
+ serializer.NumberFixed_Unbounded("PositionY", nodes[i].Position.Y);
+ serializer.NumberFixed_Unbounded("PositionZ", nodes[i].Position.Z);
+
+ serializer.NumberFixed_Unbounded("RotationX", nodes[i].Rotation.X);
+ serializer.NumberFixed_Unbounded("RotationY", nodes[i].Rotation.Y);
+ serializer.NumberFixed_Unbounded("RotationZ", nodes[i].Rotation.Z);
+ }
+
+ if (!data->m_LookAtTarget)
+ return;
+
+ const std::vector& targetNodes = path.GetTargetSpline().GetAllNodes();
+ serializer.NumberU32("NumberOfTargetNodes", targetNodes.size(), 1, MAX_SPLINE_NODES);
+ for (size_t i = 0; i < targetNodes.size(); ++i)
+ {
+ if (i > 0)
+ serializer.NumberFixed_Unbounded("NodeDeltaTime", targetNodes[i - 1].Distance);
+ else
+ serializer.NumberFixed_Unbounded("NodeDeltaTime", fixed::Zero());
+ serializer.NumberFixed_Unbounded("PositionX", targetNodes[i].Position.X);
+ serializer.NumberFixed_Unbounded("PositionY", targetNodes[i].Position.Y);
+ serializer.NumberFixed_Unbounded("PositionZ", targetNodes[i].Position.Z);
+ }
+ }
+
+ CCinemaPath DeserializePath(IDeserializer& deserializer)
+ {
+ CCinemaData data;
+
+ deserializer.String("PathName", data.m_Name, 1, 128);
+ deserializer.String("PathOrientation", data.m_Orientation, 1, 128);
+ deserializer.String("PathMode", data.m_Mode, 1, 128);
+ deserializer.String("PathStyle", data.m_Style, 1, 128);
+ deserializer.NumberFixed_Unbounded("PathTimescale", data.m_Timescale);
+ deserializer.Bool("LookAtTarget", data.m_LookAtTarget);
+
+ TNSpline pathSpline, targetSpline;
+ uint32_t numberOfNodes = 0;
+ deserializer.NumberU32("NumberOfNodes", numberOfNodes, 1, MAX_SPLINE_NODES);
+ for (uint32_t j = 0; j < numberOfNodes; ++j)
+ {
+ SplineData node;
+ deserializer.NumberFixed_Unbounded("NodeDeltaTime", node.Distance);
+
+ deserializer.NumberFixed_Unbounded("PositionX", node.Position.X);
+ deserializer.NumberFixed_Unbounded("PositionY", node.Position.Y);
+ deserializer.NumberFixed_Unbounded("PositionZ", node.Position.Z);
+
+ deserializer.NumberFixed_Unbounded("RotationX", node.Rotation.X);
+ deserializer.NumberFixed_Unbounded("RotationY", node.Rotation.Y);
+ deserializer.NumberFixed_Unbounded("RotationZ", node.Rotation.Z);
+
+ pathSpline.AddNode(node.Position, node.Rotation, node.Distance);
+ }
+
+ if (data.m_LookAtTarget)
+ {
+ uint32_t numberOfTargetNodes = 0;
+ deserializer.NumberU32("NumberOfTargetNodes", numberOfTargetNodes, 1, MAX_SPLINE_NODES);
+ for (uint32_t j = 0; j < numberOfTargetNodes; ++j)
+ {
+ SplineData node;
+ deserializer.NumberFixed_Unbounded("NodeDeltaTime", node.Distance);
+
+ deserializer.NumberFixed_Unbounded("PositionX", node.Position.X);
+ deserializer.NumberFixed_Unbounded("PositionY", node.Position.Y);
+ deserializer.NumberFixed_Unbounded("PositionZ", node.Position.Z);
+
+ targetSpline.AddNode(node.Position, CFixedVector3D(), node.Distance);
+ }
+ }
+
+ return CCinemaPath(data, pathSpline, targetSpline);
+ }
+
bool m_Enabled;
std::map m_Paths;
std::list m_PathQueue;
// States before playing
bool m_MapRevealed;
fixed m_ElapsedTime;
fixed m_TotalTime;
fixed m_CurrentPathElapsedTime;
};
REGISTER_COMPONENT_TYPE(CinemaManager)