diff --git a/binaries/data/mods/public/simulation/components/Trigger.js b/binaries/data/mods/public/simulation/components/Trigger.js index 3375d50b55..043c0aac0e 100644 --- a/binaries/data/mods/public/simulation/components/Trigger.js +++ b/binaries/data/mods/public/simulation/components/Trigger.js @@ -19,6 +19,8 @@ Trigger.prototype.eventNames = "Interval", "Range", "TreasureCollected", + "CinemaPathEnded", + "CinemaQueueEnded" ]; Trigger.prototype.Init = function() @@ -242,6 +244,18 @@ Trigger.prototype.OnGlobalResearchFinished = function(msg) // "tech": tech} }; +// Handles "OnCinemaPathEnded" event. +Trigger.prototype.OnGlobalCinemaPathEnded = function(msg) +{ + this.CallEvent("CinemaPathEnded", msg); +} + +// Handles "OnCinemaQueueEnded" event. +Trigger.prototype.OnGlobalCinemaQueueEnded = function(msg) +{ + this.CallEvent("CinemaQueueEnded", msg); +} + Trigger.prototype.OnGlobalOwnershipChanged = function(msg) { this.CallEvent("OwnershipChanged", msg); diff --git a/source/collada/CommonConvert.cpp b/source/collada/CommonConvert.cpp index 49497422bf..1f0a4745d0 100644 --- a/source/collada/CommonConvert.cpp +++ b/source/collada/CommonConvert.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 Wildfire Games. +/* Copyright (C) 2016 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify diff --git a/source/graphics/CinemaManager.cpp b/source/graphics/CinemaManager.cpp index 3d14db2f84..904be50def 100644 --- a/source/graphics/CinemaManager.cpp +++ b/source/graphics/CinemaManager.cpp @@ -18,98 +18,280 @@ #include "precompiled.h" -#include #include +#include -#include "CinemaManager.h" - -#include "CinemaPath.h" -#include "ps/CStr.h" +#include "graphics/Camera.h" +#include "graphics/CinemaManager.h" +#include "graphics/GameView.h" +#include "gui/CGUI.h" +#include "gui/GUIManager.h" +#include "gui/IGUIObject.h" +#include "lib/ogl.h" +#include "maths/MathUtil.h" +#include "maths/Quaternion.h" +#include "maths/Vector3D.h" #include "maths/Vector4D.h" +#include "ps/CLogger.h" +#include "ps/CStr.h" +#include "ps/Game.h" +#include "ps/Hotkey.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/system/ComponentManager.h" +#include "simulation2/Simulation2.h" +#include "renderer/Renderer.h" -CCinemaManager::CCinemaManager() : m_DrawCurrentSpline(false), m_Active(true), m_ValidCurrent(false) + +CCinemaManager::CCinemaManager() + : m_DrawPaths(false) { - m_CurrentPath = m_Paths.end(); } -void CCinemaManager::AddPath(CCinemaPath path, const CStrW& name) +void CCinemaManager::AddPath(const CStrW& name, const CCinemaPath& path) { - ENSURE( m_Paths.find( name ) == m_Paths.end() ); - m_Paths[name] = path; -} - -void CCinemaManager::QueuePath(const CStrW& name, bool queue) -{ - if (!m_PathQueue.empty() && queue == false) + if (m_CinematicSimulationData.m_Paths.find(name) != m_CinematicSimulationData.m_Paths.end()) { + LOGWARNING("Path with name '%s' already exists", name.ToUTF8()); return; } - else - { - ENSURE(HasTrack(name)); - m_PathQueue.push_back(m_Paths[name]); - } + m_CinematicSimulationData.m_Paths[name] = path; } -void CCinemaManager::OverridePath(const CStrW& name) +void CCinemaManager::AddPathToQueue(const CStrW& name) { - m_PathQueue.clear(); - ENSURE(HasTrack(name)); - m_PathQueue.push_back( m_Paths[name] ); + if (!HasPath(name)) + { + LOGWARNING("Path with name '%s' doesn't exist", name.ToUTF8()); + return; + } + m_CinematicSimulationData.m_PathQueue.push_back(m_CinematicSimulationData.m_Paths[name]); +} + +void CCinemaManager::ClearQueue() +{ + m_CinematicSimulationData.m_PathQueue.clear(); } void CCinemaManager::SetAllPaths(const std::map& paths) { - CStrW name; - m_Paths = paths; + m_CinematicSimulationData.m_Paths = paths; } -void CCinemaManager::SetCurrentPath(const CStrW& name, bool current, bool drawLines) + +bool CCinemaManager::HasPath(const CStrW& name) const { - if ( !HasTrack(name) ) - m_ValidCurrent = false; - else - m_ValidCurrent = true; - - m_CurrentPath = m_Paths.find(name); - m_DrawCurrentSpline = current; - m_DrawLines = drawLines; - DrawSpline(); + return m_CinematicSimulationData.m_Paths.find(name) != m_CinematicSimulationData.m_Paths.end(); } -bool CCinemaManager::HasTrack(const CStrW& name) const -{ - return m_Paths.find(name) != m_Paths.end(); -} - -void CCinemaManager::DrawSpline() const +void CCinemaManager::SetEnabled(bool enabled) { - if ( !(m_DrawCurrentSpline && m_ValidCurrent) ) - return; - static const int smoothness = 200; - - m_CurrentPath->second.DrawSpline(CVector4D(0.f, 0.f, 1.f, 1.f), smoothness, m_DrawLines); -} - -void CCinemaManager::MoveToPointAt(float time) -{ - ENSURE(m_CurrentPath != m_Paths.end()); - StopPlaying(); - - m_CurrentPath->second.m_TimeElapsed = time; - if (!m_CurrentPath->second.Validate()) - return; - - m_CurrentPath->second.MoveToPointAt(m_CurrentPath->second.m_TimeElapsed / - m_CurrentPath->second.GetDuration(), m_CurrentPath->second.GetNodeFraction(), - m_CurrentPath->second.m_PreviousRotation); -} - -bool CCinemaManager::Update(const float deltaRealTime) -{ - if (!m_PathQueue.front().Play(deltaRealTime)) + // TODO: maybe assert? + if (m_CinematicSimulationData.m_PathQueue.empty() && enabled) { - m_PathQueue.pop_front(); - return false; + enabled = false; + m_CinematicSimulationData.m_Paused = true; } - return true; + + if (m_CinematicSimulationData.m_Enabled == enabled) + return; + + // TODO: Enabling/Disabling does not work if the session GUI page is not the top page. + // This can happen in various situations, for example when the player wins/looses the game + // while the cinematic is running (a message box is the top page in this case). + // It might be better to disable the whole GUI during the cinematic instead of a specific + // GUI object. + + // sn - session gui object + IGUIObject *sn = g_GUI->FindObjectByName("sn"); + CmpPtr cmpRangeManager(g_Game->GetSimulation2()->GetSimContext().GetSystemEntity()); + CmpPtr cmpTerritoryManager(g_Game->GetSimulation2()->GetSimContext().GetSystemEntity()); + + // GUI visibility + if (sn) + { + if (enabled) + sn->SetSetting("hidden", L"true"); + else + sn->SetSetting("hidden", L"false"); + } + + // Overlay visibility + g_Renderer.SetOptionBool(CRenderer::Option::OPT_SILHOUETTES, !enabled); + if (cmpRangeManager) + { + if (enabled) + m_CinematicSimulationData.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_CinematicSimulationData.m_Enabled = enabled; } + +void CCinemaManager::Play() +{ + m_CinematicSimulationData.m_Paused = false; +} + +void CCinemaManager::Stop() +{ + m_CinematicSimulationData.m_PathQueue.clear(); +} + +void CCinemaManager::Update(const float deltaRealTime) +{ + if (g_Game->m_Paused != m_CinematicSimulationData.m_Paused) + { + m_CinematicSimulationData.m_Paused = g_Game->m_Paused; + + // sn - session gui object + IGUIObject *sn = g_GUI->FindObjectByName("sn"); + + // GUI visibility + if (sn) + { + if (m_CinematicSimulationData.m_Paused) + sn->SetSetting("hidden", L"false"); + else + sn->SetSetting("hidden", L"true"); + } + } + + if (m_CinematicSimulationData.m_PathQueue.empty() || !m_CinematicSimulationData.m_Enabled || m_CinematicSimulationData.m_Paused) + return; + + if (HotkeyIsPressed("leave")) + { + // TODO: implement skip + } + + m_CinematicSimulationData.m_PathQueue.front().Play(deltaRealTime); +} + +void CCinemaManager::Render() +{ + if (GetEnabled()) + { + DrawBars(); + return; + } + + if (!m_DrawPaths) + return; + + // draw all paths + for (auto it : m_CinematicSimulationData.m_Paths) + it.second.Draw(); +} + +void CCinemaManager::DrawBars() const +{ + int height = (float)g_xres / 2.39f; + int shift = (g_yres - height) / 2; + if (shift <= 0) + return; + +#if CONFIG2_GLES + #warning TODO : implement bars for GLES +#else + // Set up transform for GL bars + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + CMatrix3D transform; + transform.SetOrtho(0.f, (float)g_xres, 0.f, (float)g_yres, -1.f, 1000.f); + glLoadMatrixf(&transform._11); + + glColor4f(0.0f, 0.0f, 0.0f, 1.0f); + + glEnable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + + glBegin(GL_QUADS); + glVertex2i(0, 0); + glVertex2i(g_xres, 0); + glVertex2i(g_xres, shift); + glVertex2i(0, shift); + glEnd(); + + glBegin(GL_QUADS); + glVertex2i(0, g_yres - shift); + glVertex2i(g_xres, g_yres - shift); + glVertex2i(g_xres, g_yres); + glVertex2i(0, g_yres); + glEnd(); + + glDisable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + + // Restore transform + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +#endif +} + +InReaction cinema_manager_handler(const SDL_Event_* ev) +{ + // put any events that must be processed even if inactive here + if (!g_Game || !g_Game->IsGameStarted()) + return IN_PASS; + + CCinemaManager* pCinemaManager = g_Game->GetView()->GetCinema(); + + return pCinemaManager->HandleEvent(ev); +} + +InReaction CCinemaManager::HandleEvent(const SDL_Event_* ev) +{ + switch (ev->ev.type) + { + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + if (GetEnabled() && !m_CinematicSimulationData.m_Paused) + return IN_HANDLED; + default: + return IN_PASS; + } +} + +bool CCinemaManager::GetEnabled() const +{ + return m_CinematicSimulationData.m_Enabled; +} + +bool CCinemaManager::IsPlaying() const +{ + return !m_CinematicSimulationData.m_Paused; +} + +const std::map& CCinemaManager::GetAllPaths() +{ + return m_CinematicSimulationData.m_Paths; +} + +CinematicSimulationData* CCinemaManager::GetCinematicSimulationData() +{ + return &m_CinematicSimulationData; +} + +bool CCinemaManager::GetPathsDrawing() const +{ + return m_DrawPaths; +} + +void CCinemaManager::SetPathsDrawing(const bool drawPath) +{ + m_DrawPaths = drawPath; +} \ No newline at end of file diff --git a/source/graphics/CinemaManager.h b/source/graphics/CinemaManager.h index 567b62b198..45e44b65c3 100644 --- a/source/graphics/CinemaManager.h +++ b/source/graphics/CinemaManager.h @@ -22,48 +22,121 @@ #include #include +#include "lib/input.h" // InReaction - can't forward-declare enum + #include "graphics/CinemaPath.h" #include "ps/CStr.h" -//Class for in game playing of cinematics. Should only be instantiated in CGameView. +/* + desc: contains various functions used for cinematic camera paths + See also: CinemaHandler.cpp, CinemaPath.cpp +*/ + +// Cinematic structure for data accessable from the simulation +struct CinematicSimulationData +{ + bool m_Enabled; + bool m_Paused; + std::map m_Paths; + std::list m_PathQueue; + + // States before playing + bool m_MapRevealed; + + fixed m_ElapsedTime, m_TotalTime, m_CurrentPathElapsedTime; + + CinematicSimulationData() + : m_Enabled(false), + m_Paused(true), + m_MapRevealed(false), + m_ElapsedTime(fixed::Zero()), + m_TotalTime(fixed::Zero()), + m_CurrentPathElapsedTime(fixed::Zero()) + {} +}; + +/** + * Class for in game playing of cinematics. Should only be instantiated in CGameView. + */ + class CCinemaManager { public: CCinemaManager(); ~CCinemaManager() {} - void AddPath(CCinemaPath path, const CStrW& name); - - //Adds track to list of being played. - void QueuePath(const CStrW& name, bool queue); - void OverridePath(const CStrW& name); //clears track queue and replaces with 'name' + /** + * Adds the path to the path list + * @param name path name + * @param CCinemaPath path data + */ + void AddPath(const CStrW& name, const CCinemaPath& path); /** + * Adds the path to the playlist + * @param name path name + */ + void AddPathToQueue(const CStrW& name); + + /** + * Clears the playlist + */ + void ClearQueue(); + + /** + * Checks the path name in the path list + * @param name path name + * @return true if path with that name exists, else false + */ + bool HasPath(const CStrW& name) const; + + const std::map& GetAllPaths(); + void SetAllPaths( const std::map& tracks); + + /** + * Starts play paths + */ + void Play(); + void Stop(); + bool IsPlaying() const; + + /** + * Renders black bars and paths (if enabled) + */ + void Render(); + void DrawBars() const; + + /** + * Get current enable state of the cinema manager + */ + bool GetEnabled() const; + + /** + * Sets enable state of the cinema manager (shows/hide gui, show/hide rings, etc) + * @enable new state + */ + void SetEnabled(bool enabled); + + /** + * Updates CCinemManager and current path * @param deltaRealTime Elapsed real time since the last frame. */ - bool Update(const float deltaRealTime); - - //These stop track play, and accept time, not ratio of time - void MoveToPointAt(float time); + void Update(const float deltaRealTime); - inline void StopPlaying() { m_PathQueue.clear(); } - void DrawSpline() const; - - inline bool IsPlaying() const { return !m_PathQueue.empty(); } - bool HasTrack(const CStrW& name) const; - inline bool IsActive() const { return m_Active; } - inline void SetActive(bool active) { m_Active=active; } + InReaction HandleEvent(const SDL_Event_* ev); - inline const std::map& GetAllPaths() { return m_Paths; } - void SetAllPaths( const std::map& tracks); - void SetCurrentPath(const CStrW& name, bool current, bool lines); + CinematicSimulationData* GetCinematicSimulationData(); -private: - - bool m_Active, m_DrawCurrentSpline, m_DrawLines, m_ValidCurrent; - std::map::iterator m_CurrentPath; - std::map m_Paths; - std::list m_PathQueue; + bool GetPathsDrawing() const; + void SetPathsDrawing(const bool drawPath); + +private: + bool m_DrawPaths; + + // Cinematic data is accessed from the simulation + CinematicSimulationData m_CinematicSimulationData; }; +extern InReaction cinema_manager_handler(const SDL_Event_* ev); + #endif diff --git a/source/graphics/CinemaPath.cpp b/source/graphics/CinemaPath.cpp index c2dbdf247c..e661127e77 100644 --- a/source/graphics/CinemaPath.cpp +++ b/source/graphics/CinemaPath.cpp @@ -23,73 +23,81 @@ #include #include "Camera.h" +#include "CinemaManager.h" #include "GameView.h" +#include "gui/CGUI.h" +#include "gui/GUIManager.h" +#include "gui/IGUIObject.h" #include "lib/ogl.h" #include "maths/MathUtil.h" #include "maths/Quaternion.h" #include "maths/Vector3D.h" #include "maths/Vector4D.h" +#include "ps/CLogger.h" #include "ps/CStr.h" #include "ps/Game.h" +#include "renderer/Renderer.h" -CCinemaPath::CCinemaPath(const CCinemaData& data, const TNSpline& spline) - : CCinemaData(data), TNSpline(spline), m_TimeElapsed(0.f) -{ +CCinemaPath::CCinemaPath(const CCinemaData& data, const TNSpline& spline, const TNSpline& targetSpline) + : CCinemaData(data), TNSpline(spline), m_TargetSpline(targetSpline), m_TimeElapsed(0.f) +{ m_TimeElapsed = 0; BuildSpline(); - // Set distortion mode and style - switch(data.m_Mode) + if (m_Orientation == L"target") { - case CCinemaPath::EM_IN: - DistModePtr = &CCinemaPath::EaseIn; - break; - case CCinemaPath::EM_OUT: - DistModePtr = &CCinemaPath::EaseOut; - break; - case CCinemaPath::EM_INOUT: - DistModePtr = &CCinemaPath::EaseInOut; - break; - case CCinemaPath::EM_OUTIN: - DistModePtr = &CCinemaPath::EaseOutIn; - break; - default: - debug_printf("Cinematic mode not found for %d\n", data.m_Mode); - break; + m_LookAtTarget = true; + ENSURE(!m_TargetSpline.GetAllNodes().empty()); } - switch (data.m_Style) + // Set distortion mode and style + if (data.m_Mode == L"ease_in") + DistModePtr = &CCinemaPath::EaseIn; + else if (data.m_Mode == L"ease_out") + DistModePtr = &CCinemaPath::EaseOut; + else if (data.m_Mode == L"ease_inout") + DistModePtr = &CCinemaPath::EaseInOut; + else if (data.m_Mode == L"ease_outin") + DistModePtr = &CCinemaPath::EaseOutIn; + else { - case CCinemaPath::ES_DEFAULT: + LOGWARNING("Cinematic mode not found for '%s'", data.m_Mode.ToUTF8().c_str()); + DistModePtr = &CCinemaPath::EaseInOut; + } + + if (data.m_Style == L"default") DistStylePtr = &CCinemaPath::EaseDefault; - break; - case CCinemaPath::ES_GROWTH: + else if (data.m_Style == L"growth") DistStylePtr = &CCinemaPath::EaseGrowth; - break; - case CCinemaPath::ES_EXPO: + else if (data.m_Style == L"expo") DistStylePtr = &CCinemaPath::EaseExpo; - break; - case CCinemaPath::ES_CIRCLE: + else if (data.m_Style == L"circle") DistStylePtr = &CCinemaPath::EaseCircle; - break; - case CCinemaPath::ES_SINE: + else if (data.m_Style == L"sine") DistStylePtr = &CCinemaPath::EaseSine; - break; - default: - debug_printf("Cinematic mode not found for %d\n", data.m_Style); - break; + else + { + LOGWARNING("Cinematic style not found for '%s'", data.m_Style.ToUTF8().c_str()); + DistStylePtr = &CCinemaPath::EaseDefault; } } -void CCinemaPath::DrawSpline(const CVector4D& RGBA, int smoothness, bool lines) const +void CCinemaPath::Draw() const { - if (NodeCount < 2 || DistModePtr == NULL) + DrawSpline(*this, CVector4D(0.2f, 0.2f, 1.f, 0.5f), 100, true); + DrawSpline(m_TargetSpline, CVector4D(1.0f, 0.2f, 0.2f, 0.5f), 100, true); + DrawNodes(CVector4D(0.5f, 1.0f, 0.f, 0.5f)); +} + +void CCinemaPath::DrawSpline(const RNSpline& spline, const CVector4D& RGBA, int smoothness, bool lines) const +{ + if (spline.NodeCount < 2 || DistModePtr == NULL) return; - if (NodeCount == 2 && lines) + if (spline.NodeCount == 2 && lines) smoothness = 2; - float start = MaxDistance / smoothness; + float start = spline.MaxDistance.ToFloat() / smoothness; float time = 0; #if CONFIG2_GLES @@ -106,8 +114,8 @@ void CCinemaPath::DrawSpline(const CVector4D& RGBA, int smoothness, bool lines) for (int i = 0; i <= smoothness; ++i) { // Find distorted time - time = start*i / MaxDistance; - CVector3D tmp = GetPosition(time); + time = start*i / spline.MaxDistance.ToFloat(); + CVector3D tmp = spline.GetPosition(time); glVertex3f(tmp.X, tmp.Y, tmp.Z); } glEnd(); @@ -117,7 +125,7 @@ void CCinemaPath::DrawSpline(const CVector4D& RGBA, int smoothness, bool lines) else { smoothness /= 2; - start = MaxDistance / smoothness; + start = spline.MaxDistance.ToFloat() / smoothness; glEnable(GL_POINT_SMOOTH); glPointSize(3.0f); glBegin(GL_POINTS); @@ -125,14 +133,18 @@ void CCinemaPath::DrawSpline(const CVector4D& RGBA, int smoothness, bool lines) for (int i = 0; i <= smoothness; ++i) { // Find distorted time - time = (this->*DistModePtr)(start*i / MaxDistance); - CVector3D tmp = GetPosition(time); + time = (this->*DistModePtr)(start*i / spline.MaxDistance.ToFloat()); + CVector3D tmp = spline.GetPosition(time); glVertex3f(tmp.X, tmp.Y, tmp.Z); } glColor3f(1.0f, 1.0f, 0.0f); // yellow - for (size_t i = 0; i < Node.size(); ++i) - glVertex3f(Node[i].Position.X, Node[i].Position.Y, Node[i].Position.Z); + for (size_t i = 0; i < spline.GetAllNodes().size(); ++i) + glVertex3f( + spline.GetAllNodes()[i].Position.X.ToFloat(), + spline.GetAllNodes()[i].Position.Y.ToFloat(), + spline.GetAllNodes()[i].Position.Z.ToFloat() + ); glEnd(); glPointSize(1.0f); @@ -142,23 +154,70 @@ void CCinemaPath::DrawSpline(const CVector4D& RGBA, int smoothness, bool lines) #endif } +void CCinemaPath::DrawNodes(const CVector4D& RGBA) const +{ +#if CONFIG2_GLES + #warning TODO : do something about CCinemaPath on GLES +#else + glEnable(GL_POINT_SMOOTH); + glPointSize(5.0f); + + glColor4f(RGBA.X, RGBA.Y, RGBA.Z, RGBA.W); + glBegin(GL_POINTS); + for (size_t i = 0; i < Node.size(); ++i) + glVertex3f(Node[i].Position.X.ToFloat(), Node[i].Position.Y.ToFloat(), Node[i].Position.Z.ToFloat()); + glEnd(); + + if (!m_LookAtTarget) + { + glPointSize(1.0f); + glDisable(GL_POINT_SMOOTH); + return; + } + + // draw target nodes + glColor4f(RGBA.Y, RGBA.X, RGBA.Z, RGBA.W); + glBegin(GL_POINTS); + for (size_t i = 0; i < m_TargetSpline.GetAllNodes().size(); ++i) + glVertex3f( + m_TargetSpline.GetAllNodes()[i].Position.X.ToFloat(), + m_TargetSpline.GetAllNodes()[i].Position.Y.ToFloat(), + m_TargetSpline.GetAllNodes()[i].Position.Z.ToFloat() + ); + glEnd(); + + glPointSize(1.0f); + glDisable(GL_POINT_SMOOTH); +#endif +} + void CCinemaPath::MoveToPointAt(float t, float nodet, const CVector3D& startRotation) { - CCamera *Cam = g_Game->GetView()->GetCamera(); + CCamera *camera = g_Game->GetView()->GetCamera(); t = (this->*DistModePtr)(t); - - CVector3D nodeRotation = Node[m_CurrentNode + 1].Rotation; - CQuaternion start, end; - start.FromEulerAngles(DEGTORAD(startRotation.X), DEGTORAD(startRotation.Y), DEGTORAD(startRotation.Z)); - end.FromEulerAngles(DEGTORAD(nodeRotation.X), DEGTORAD(nodeRotation.Y), DEGTORAD(nodeRotation.Z)); - start.Slerp(start, end, nodet); + CVector3D pos = GetPosition(t); - CQuaternion quat; - - Cam->m_Orientation.SetIdentity(); - Cam->m_Orientation.Rotate(start); - Cam->m_Orientation.Translate(pos); - Cam->UpdateFrustum(); + + if (m_LookAtTarget) + { + if (m_TimeElapsed <= m_TargetSpline.MaxDistance.ToFloat()) + camera->LookAt(pos, m_TargetSpline.GetPosition(m_TimeElapsed / m_TargetSpline.MaxDistance.ToFloat()), CVector3D(0, 1, 0)); + else + camera->LookAt(pos, m_TargetSpline.GetAllNodes().back().Position, CVector3D(0, 1, 0)); + } + else + { + CVector3D nodeRotation = Node[m_CurrentNode + 1].Rotation; + CQuaternion start, end; + start.FromEulerAngles(DEGTORAD(startRotation.X), DEGTORAD(startRotation.Y), DEGTORAD(startRotation.Z)); + end.FromEulerAngles(DEGTORAD(nodeRotation.X), DEGTORAD(nodeRotation.Y), DEGTORAD(nodeRotation.Z)); + start.Slerp(start, end, nodet); + + camera->m_Orientation.SetIdentity(); + camera->m_Orientation.Rotate(start); + camera->m_Orientation.Translate(pos); + } + camera->UpdateFrustum(); } // Distortion mode functions @@ -228,7 +287,7 @@ float CCinemaPath::EaseSine(float t) const bool CCinemaPath::Validate() { - if (m_TimeElapsed > GetDuration() || m_TimeElapsed < 0.0f) + if (m_TimeElapsed > GetDuration().ToFloat() || m_TimeElapsed < 0.0f) return false; // Find current node and past "node time" @@ -237,7 +296,7 @@ bool CCinemaPath::Validate() // Ignore the last node, since it is a blank (node time values are shifted down one from interface) for (size_t i = 0; i < Node.size() - 1; ++i) { - cumulation += Node[i].Distance; + cumulation += Node[i].Distance.ToFloat(); if (m_TimeElapsed <= cumulation) { m_PreviousNodeTime = previousTime; @@ -245,20 +304,21 @@ bool CCinemaPath::Validate() m_CurrentNode = i; // We're moving toward this next node, so use its rotation return true; } - previousTime += Node[i].Distance; + previousTime += Node[i].Distance.ToFloat(); } + debug_warn("validation of cinema path is wrong\n"); return false; } bool CCinemaPath::Play(const float deltaRealTime) { - m_TimeElapsed += m_Timescale * deltaRealTime; + m_TimeElapsed += m_Timescale.ToFloat() * deltaRealTime; if (!Validate()) { m_TimeElapsed = 0.0f; return false; } - MoveToPointAt(m_TimeElapsed / GetDuration(), GetNodeFraction(), m_PreviousRotation); + MoveToPointAt(m_TimeElapsed / GetDuration().ToFloat(), GetNodeFraction(), m_PreviousRotation); return true; } \ No newline at end of file diff --git a/source/graphics/CinemaPath.h b/source/graphics/CinemaPath.h index 5b2a222f78..1e789f8e71 100644 --- a/source/graphics/CinemaPath.h +++ b/source/graphics/CinemaPath.h @@ -15,19 +15,11 @@ * along with 0 A.D. If not, see . */ - #ifndef INCLUDED_CINEMAPATH #define INCLUDED_CINEMAPATH -#include -#include -#include "ps/CStr.h" #include "maths/NUSpline.h" - -/* - desc: contains various functions used for cinematic camera paths - See also: CinemaHandler.cpp, Cinematic.h/.cpp -*/ +#include "ps/CStr.h" class CVector3D; class CVector4D; @@ -37,20 +29,24 @@ class CCamera; class CCinemaData { public: - CCinemaData() : m_GrowthCount(0), m_Growth(0), m_Switch(0), - m_Mode(0), m_Style(0), m_Timescale(1) {} + CCinemaData() : m_LookAtTarget(false), m_GrowthCount(0), m_Growth(1), m_Switch(1), m_Timescale(fixed::FromInt(1)) {} virtual ~CCinemaData() {} const CCinemaData* GetData() const { return this; } - + + CStrW m_Name; + CStrW m_Orientation; + CStrW m_Mode; + CStrW m_Style; + + bool m_LookAtTarget; + + fixed m_Timescale; // a negative timescale results in backwards play + // Distortion variables mutable float m_GrowthCount; float m_Growth; float m_Switch; - int m_Mode; - int m_Style; - float m_Timescale; // a negative timescale results in backwards play - }; @@ -61,16 +57,13 @@ public: class CCinemaPath : private CCinemaData, public TNSpline { public: - CCinemaPath() { m_TimeElapsed = 0.0f; m_PreviousNodeTime = 0.0f; } - CCinemaPath(const CCinemaData& data, const TNSpline& spline); + CCinemaPath() : m_TimeElapsed(0), m_PreviousNodeTime(0) {} + CCinemaPath(const CCinemaData& data, const TNSpline& spline, const TNSpline& targetSpline); ~CCinemaPath() { DistStylePtr = NULL; DistModePtr = NULL; } - - enum { EM_IN, EM_OUT, EM_INOUT, EM_OUTIN }; - enum { ES_DEFAULT, ES_GROWTH, ES_EXPO, ES_CIRCLE, ES_SINE }; - + // Sets camera position to calculated point on spline void MoveToPointAt(float t, float nodet, const CVector3D&); - + // Distortion mode functions-change how ratio is passed to distortion style functions float EaseIn(float t) const; float EaseOut(float t) const; @@ -91,16 +84,20 @@ public: public: - void DrawSpline(const CVector4D& RGBA, int smoothness, bool lines) const; + void Draw() const; + void DrawSpline(const RNSpline& spline, const CVector4D& RGBA, int smoothness, bool lines) const; + void DrawNodes(const CVector4D& RGBA) const; inline CVector3D GetNodePosition(const int index) const { return Node[index].Position; } - inline float GetNodeDuration(const int index) const { return Node[index].Distance; } - inline float GetDuration() const { return MaxDistance; } + inline fixed GetNodeDuration(const int index) const { return Node[index].Distance; } + inline fixed GetDuration() const { return MaxDistance; } - inline float GetNodeFraction() const { return (m_TimeElapsed - m_PreviousNodeTime) / Node[m_CurrentNode].Distance; } + inline float GetNodeFraction() const { return (m_TimeElapsed - m_PreviousNodeTime) / Node[m_CurrentNode].Distance.ToFloat(); } inline float GetElapsedTime() const { return m_TimeElapsed; } - inline void SetTimescale(float scale) { m_Timescale = scale; } + CStrW GetName() const { return m_Name; } + + inline void SetTimescale(fixed scale) { m_Timescale = scale; } float m_TimeElapsed; float m_PreviousNodeTime; // How much time has passed before the current node @@ -112,13 +109,28 @@ public: /** * Returns false if finished. - * * @param deltaRealTime Elapsed real time since the last frame. */ bool Play(const float deltaRealTime); + + /** + * Validate the path + * @return true if the path is valid + */ bool Validate(); - inline float GetTimescale() const { return m_Timescale; } + /** + * Returns true if path doesn't contain nodes + */ + bool Empty() { return Node.empty(); } + + fixed GetTimescale() const { return m_Timescale; } + + TNSpline* getTargetSpline() { return &m_TargetSpline; } + +private: + + TNSpline m_TargetSpline; }; -#endif +#endif // INCLUDED_CINEMAPATH diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp index daeb634d09..30cc654030 100644 --- a/source/graphics/GameView.cpp +++ b/source/graphics/GameView.cpp @@ -626,12 +626,9 @@ void CGameView::Update(const float deltaRealTime) if (!g_app_has_focus) return; - if (m->CinemaManager.IsActive() && m->CinemaManager.IsPlaying()) + if (m->CinemaManager.GetEnabled()) { - if (! m->CinemaManager.Update(deltaRealTime)) - { -// ResetCamera(); - } + m->CinemaManager.Update(deltaRealTime); return; } diff --git a/source/graphics/MapReader.cpp b/source/graphics/MapReader.cpp index 84d915b265..4dc0667809 100644 --- a/source/graphics/MapReader.cpp +++ b/source/graphics/MapReader.cpp @@ -456,7 +456,7 @@ private: void ReadTerrain(XMBElement parent); void ReadEnvironment(XMBElement parent); void ReadCamera(XMBElement parent); - void ReadCinema(XMBElement parent); + void ReadPaths(XMBElement parent); void ReadTriggers(XMBElement parent); int ReadEntities(XMBElement parent, double end_time); }; @@ -839,120 +839,115 @@ void CXMLReader::ReadCamera(XMBElement parent) } } -void CXMLReader::ReadCinema(XMBElement parent) +void CXMLReader::ReadPaths(XMBElement parent) { #define EL(x) int el_##x = xmb_file.GetElementID(#x) #define AT(x) int at_##x = xmb_file.GetAttributeID(#x) EL(path); EL(rotation); - EL(distortion); EL(node); EL(position); - EL(time); + EL(target); AT(name); AT(timescale); + AT(orientation); AT(mode); AT(style); - AT(growth); - AT(switch); AT(x); AT(y); AT(z); + AT(deltatime); #undef EL #undef AT - - std::map pathList; + XERO_ITER_EL(parent, element) { int elementName = element.GetNodeName(); if (elementName == el_path) { - XMBAttributeList attrs = element.GetAttributes(); - CStrW name(attrs.GetNamedItem(at_name).FromUTF8()); - float timescale = attrs.GetNamedItem(at_timescale).ToFloat(); CCinemaData pathData; - pathData.m_Timescale = timescale; - TNSpline spline, backwardSpline; + XMBAttributeList attrs = element.GetAttributes(); + CStrW pathName(attrs.GetNamedItem(at_name).FromUTF8()); + pathData.m_Timescale = fixed::FromString(attrs.GetNamedItem(at_timescale)); + TNSpline pathSpline, targetSpline; + fixed lastTargetTime = fixed::Zero(); + + pathData.m_Name = pathName; + pathData.m_Orientation = attrs.GetNamedItem(at_orientation).FromUTF8(); + pathData.m_Mode = attrs.GetNamedItem(at_mode).FromUTF8(); + pathData.m_Style = attrs.GetNamedItem(at_style).FromUTF8(); XERO_ITER_EL(element, pathChild) { elementName = pathChild.GetNodeName(); attrs = pathChild.GetAttributes(); - //Load distortion attributes - if (elementName == el_distortion) - { - pathData.m_Mode = attrs.GetNamedItem(at_mode).ToInt(); - pathData.m_Style = attrs.GetNamedItem(at_style).ToInt(); - pathData.m_Growth = attrs.GetNamedItem(at_growth).ToInt(); - pathData.m_Switch = attrs.GetNamedItem(at_switch).ToInt(); - } - - //Load node data used for spline - else if (elementName == el_node) + // Load node data used for spline + if (elementName == el_node) { + bool positionDeclared = false; SplineData data; + data.Distance = fixed::FromString(attrs.GetNamedItem(at_deltatime)); + lastTargetTime += fixed::FromString(attrs.GetNamedItem(at_deltatime)); XERO_ITER_EL(pathChild, nodeChild) { elementName = nodeChild.GetNodeName(); attrs = nodeChild.GetAttributes(); - - //Fix?: assumes that time is last element + if (elementName == el_position) { - data.Position.X = attrs.GetNamedItem(at_x).ToFloat(); - data.Position.Y = attrs.GetNamedItem(at_y).ToFloat(); - data.Position.Z = attrs.GetNamedItem(at_z).ToFloat(); - continue; + data.Position.X = fixed::FromString(attrs.GetNamedItem(at_x)); + data.Position.Y = fixed::FromString(attrs.GetNamedItem(at_y)); + data.Position.Z = fixed::FromString(attrs.GetNamedItem(at_z)); + positionDeclared = true; } else if (elementName == el_rotation) { - data.Rotation.X = attrs.GetNamedItem(at_x).ToFloat(); - data.Rotation.Y = attrs.GetNamedItem(at_y).ToFloat(); - data.Rotation.Z = attrs.GetNamedItem(at_z).ToFloat(); - continue; + data.Rotation.X = fixed::FromString(attrs.GetNamedItem(at_x)); + data.Rotation.Y = fixed::FromString(attrs.GetNamedItem(at_y)); + data.Rotation.Z = fixed::FromString(attrs.GetNamedItem(at_z)); + } + else if (elementName == el_target) + { + CFixedVector3D targetPosition; + targetPosition.X = fixed::FromString(attrs.GetNamedItem(at_x)); + targetPosition.Y = fixed::FromString(attrs.GetNamedItem(at_y)); + targetPosition.Z = fixed::FromString(attrs.GetNamedItem(at_z)); + + targetSpline.AddNode(targetPosition, CFixedVector3D(), lastTargetTime); + lastTargetTime = fixed::Zero(); } - else if (elementName == el_time) - data.Distance = nodeChild.GetText().ToFloat(); else - debug_warn(L"Invalid cinematic element for node child"); - - backwardSpline.AddNode(data.Position, data.Rotation, data.Distance); + LOGWARNING("Invalid cinematic element for node child"); } + + // Skip the node if no position + if (positionDeclared) + pathSpline.AddNode(data.Position, data.Rotation, data.Distance); } else - debug_warn(L"Invalid cinematic element for path child"); - - + LOGWARNING("Invalid cinematic element for path child"); } - //Construct cinema path with data gathered - CCinemaPath temp(pathData, backwardSpline); - const std::vector& nodes = temp.GetAllNodes(); - if (nodes.empty()) + // Construct cinema path with data gathered + CCinemaPath path(pathData, pathSpline, targetSpline); + if (path.Empty()) { - debug_warn(L"Failure loading cinematics"); + LOGWARNING("Path with name '%s' is empty", pathName.ToUTF8()); return; } - for (std::vector::const_reverse_iterator it = nodes.rbegin(); - it != nodes.rend(); ++it) - { - spline.AddNode(it->Position, it->Rotation, it->Distance); - } - - CCinemaPath path(pathData, spline); - pathList[name] = path; + if (!m_MapReader.pCinema->HasPath(pathName)) + m_MapReader.pCinema->AddPath(pathName, path); + else + LOGWARNING("Path with name '%s' already exists", pathName.ToUTF8()); } else - ENSURE("Invalid cinema child"); + LOGWARNING("Invalid path child with name '%s'", element.GetText()); } - - if (m_MapReader.pCinema) - m_MapReader.pCinema->SetAllPaths(pathList); } void CXMLReader::ReadTriggers(XMBElement UNUSED(parent)) @@ -1125,7 +1120,7 @@ void CXMLReader::ReadXML() } else if (name == "Paths") { - ReadCinema(node); + ReadPaths(node); } else if (name == "Triggers") { diff --git a/source/graphics/MapWriter.cpp b/source/graphics/MapWriter.cpp index 20e407d18f..dd850a844d 100644 --- a/source/graphics/MapWriter.cpp +++ b/source/graphics/MapWriter.cpp @@ -408,27 +408,25 @@ void CMapWriter::WriteXML(const VfsPath& filename, for ( ; it != paths.end(); ++it ) { - CStrW name = it->first; - float timescale = it->second.GetTimescale(); - - XML_Element("Path"); - XML_Attribute("name", name); - XML_Attribute("timescale", timescale); - + fixed timescale = it->second.GetTimescale(); const std::vector& nodes = it->second.GetAllNodes(); const CCinemaData* data = it->second.GetData(); - { - XML_Element("Distortion"); - XML_Attribute("mode", data->m_Mode); - XML_Attribute("style", data->m_Style); - XML_Attribute("growth", data->m_Growth); - XML_Attribute("switch", data->m_Switch); - } + XML_Element("Path"); + XML_Attribute("name", data->m_Name); + XML_Attribute("timescale", timescale); + XML_Attribute("orientation", data->m_Orientation); + XML_Attribute("mode", data->m_Mode); + XML_Attribute("style", data->m_Style); - for ( ssize_t j=nodes.size()-1; j >= 0; --j ) + // TODO: write target nodes + for (size_t j = 0; j < nodes.size(); ++j) { XML_Element("Node"); + if (j > 0) + XML_Attribute("deltatime", nodes[j - 1].Distance); + else + XML_Attribute("deltatime", 0.0f); { XML_Element("Position"); @@ -443,8 +441,6 @@ void CMapWriter::WriteXML(const VfsPath& filename, XML_Attribute("y", nodes[j].Rotation.Y); XML_Attribute("z", nodes[j].Rotation.Z); } - - XML_Setting("Time", nodes[j].Distance); } } } diff --git a/source/lib/input.cpp b/source/lib/input.cpp index e8965ae596..3b2d9277d6 100644 --- a/source/lib/input.cpp +++ b/source/lib/input.cpp @@ -32,7 +32,7 @@ #include "lib/external_libraries/libsdl.h" -const size_t MAX_HANDLERS = 8; +const size_t MAX_HANDLERS = 9; static InHandler handler_stack[MAX_HANDLERS]; static size_t handler_stack_top = 0; diff --git a/source/maths/NUSpline.cpp b/source/maths/NUSpline.cpp index 8712f96e9f..a52ffd2ca7 100644 --- a/source/maths/NUSpline.cpp +++ b/source/maths/NUSpline.cpp @@ -45,13 +45,12 @@ CVector3D GetPositionOnCubic(const CVector3D& startPos, const CVector3D& startVe /*********************************** R N S **************************************************/ // adds node and updates segment length -void RNSpline::AddNode(const CVector3D& pos) +void RNSpline::AddNode(const CFixedVector3D& pos) { if (NodeCount >= MAX_SPLINE_NODES) return; - if (NodeCount == 0) - MaxDistance = 0.f; + MaxDistance = fixed::Zero(); else { Node[NodeCount-1].Distance = (Node[NodeCount-1].Position - pos).Length(); @@ -97,25 +96,32 @@ CVector3D RNSpline::GetPosition(float time) const { if (NodeCount < 2) return CVector3D(0.0f, 0.0f, 0.0f); - + if (time < 0.0f) + time = 0.0f; if (time > 1.0f) time = 1.0f; - float Distance = time * MaxDistance; + float Distance = time * MaxDistance.ToFloat(); float CurrentDistance = 0.f; int i = 0; - //Find which node we're on - while (CurrentDistance + Node[i].Distance < Distance && i < NodeCount - 2) + // Find which node we're on + while (CurrentDistance + Node[i].Distance.ToFloat() < Distance && i < NodeCount - 2) { - CurrentDistance += Node[i].Distance; + CurrentDistance += Node[i].Distance.ToFloat(); ++i; } ENSURE(i < NodeCount - 1); float t = Distance - CurrentDistance; - t /= Node[i].Distance; // scale t in range 0 - 1 - CVector3D startVel = Node[i].Velocity * Node[i].Distance; - CVector3D endVel = Node[i+1].Velocity * Node[i].Distance; - return GetPositionOnCubic(Node[i].Position, startVel, Node[i+1].Position, endVel, t); + // TODO: reimplement CVector3D comparator (float comparing is bad without EPS) + if (Node[i].Position == Node[i+1].Position || Node[i].Distance.ToFloat() < 1e-7) // distance too small or zero + { + return Node[i+1].Position; + } + t /= Node[i].Distance.ToFloat(); // scale t in range 0 - 1 + CVector3D startVel = Node[i].Velocity * Node[i].Distance.ToFloat(); + CVector3D endVel = Node[i+1].Velocity * Node[i].Distance.ToFloat(); + return GetPositionOnCubic(Node[i].Position, startVel, + Node[i+1].Position, endVel, t); } // internal. Based on Equation 14 @@ -123,8 +129,7 @@ CVector3D RNSpline::GetStartVelocity(int index) { if (index >= NodeCount - 1 || index < 0) return CVector3D(0.0f, 0.0f, 0.0f); - - CVector3D temp = (Node[index+1].Position - Node[index].Position) * 3.0f * (1.0f / Node[index].Distance); + CVector3D temp = CVector3D(Node[index+1].Position - Node[index].Position) * 3.0f * (1.0f / Node[index].Distance.ToFloat()); return (temp - Node[index+1].Velocity)*0.5f; } @@ -133,8 +138,7 @@ CVector3D RNSpline::GetEndVelocity(int index) { if (index >= NodeCount || index < 1) return CVector3D(0.0f, 0.0f, 0.0f); - - CVector3D temp = (Node[index].Position - Node[index-1].Position) * 3.0f * (1.0f / Node[index-1].Distance); + CVector3D temp = CVector3D(Node[index].Position - Node[index-1].Position) * 3.0f * (1.0f / Node[index-1].Distance.ToFloat()); return (temp - Node[index-1].Velocity) * 0.5f; } @@ -151,8 +155,8 @@ void SNSpline::Smooth() for (int i = 1; i < NodeCount-1; ++i) { // Equation 12 - newVel = GetEndVelocity(i) * Node[i].Distance + GetStartVelocity(i) * Node[i-1].Distance; - newVel = newVel * ( 1 / (Node[i-1].Distance + Node[i].Distance) ); + newVel = GetEndVelocity(i) * Node[i].Distance.ToFloat() + GetStartVelocity(i) * Node[i-1].Distance.ToFloat(); + newVel = newVel * (1 / (Node[i-1].Distance + Node[i].Distance).ToFloat()); Node[i-1].Velocity = oldVel; oldVel = newVel; } @@ -164,13 +168,13 @@ void SNSpline::Smooth() // as with RNSpline but use timePeriod in place of actual node spacing // ie time period is time from last node to this node -void TNSpline::AddNode(const CVector3D& pos, const CVector3D& rotation, float timePeriod) +void TNSpline::AddNode(const CFixedVector3D& pos, const CFixedVector3D& rotation, fixed timePeriod) { if (NodeCount >= MAX_SPLINE_NODES) return; if (NodeCount == 0) - MaxDistance = 0.f; + MaxDistance = fixed::Zero(); else { Node[NodeCount-1].Distance = timePeriod; @@ -181,7 +185,7 @@ void TNSpline::AddNode(const CVector3D& pos, const CVector3D& rotation, float ti temp.Position = pos; //make sure we don't end up using undefined numbers... - temp.Distance = 0.0f; + temp.Distance = fixed::Zero(); temp.Velocity = CVector3D(0.0f, 0.0f, 0.0f); temp.Rotation = rotation; Node.push_back(temp); @@ -189,13 +193,12 @@ void TNSpline::AddNode(const CVector3D& pos, const CVector3D& rotation, float ti } //Inserts node before position -void TNSpline::InsertNode(const int index, const CVector3D& pos, const CVector3D& rotation, float timePeriod) +void TNSpline::InsertNode(const int index, const CFixedVector3D& pos, const CFixedVector3D& rotation, fixed timePeriod) { if (NodeCount >= MAX_SPLINE_NODES || index < NodeCount - 1) return; - if (NodeCount == 0) - MaxDistance = 0.f; + MaxDistance = fixed::Zero(); else { Node[NodeCount-1].Distance = timePeriod; @@ -216,20 +219,18 @@ void TNSpline::RemoveNode(const int index) MaxDistance -= Node[index].Distance; MaxDistance -= Node[index-1].Distance; - Node[index-1].Distance = 0.0f; + Node[index-1].Distance = fixed::Zero(); Node.erase(Node.begin() + index, Node.begin() + index + 1); --NodeCount; } - -void TNSpline::UpdateNodeTime(const int index, float time) +void TNSpline::UpdateNodeTime(const int index, fixed time) { if (NodeCount == 0 || index > NodeCount - 1) return; Node[index].Distance = time; } - -void TNSpline::UpdateNodePos(const int index, const CVector3D& pos) +void TNSpline::UpdateNodePos(const int index, const CFixedVector3D& pos) { if (NodeCount == 0 || index > NodeCount - 1) return; @@ -245,9 +246,9 @@ void TNSpline::Constrain() for (int i = 1; i < NodeCount-1; ++i) { // Equation 13 - float r0 = (Node[i].Position-Node[i-1].Position).Length() / Node[i-1].Distance; - float r1 = (Node[i+1].Position - Node[i].Position).Length() / Node[i].Distance; - Node[i].Velocity *= 4.0f*r0*r1/((r0+r1)*(r0+r1)); + float r0 = (Node[i].Position - Node[i - 1].Position).Length().ToFloat() / Node[i-1].Distance.ToFloat(); + float r1 = (Node[i+1].Position - Node[i].Position).Length().ToFloat() / Node[i].Distance.ToFloat(); + Node[i].Velocity *= 4.0f*r0*r1 / ((r0 + r1)*(r0 + r1)); } } diff --git a/source/maths/NUSpline.h b/source/maths/NUSpline.h index afcee72ffe..e6c11710d5 100644 --- a/source/maths/NUSpline.h +++ b/source/maths/NUSpline.h @@ -24,14 +24,18 @@ #define MAX_SPLINE_NODES 40 #include + +#include "FixedVector3D.h" #include "Vector3D.h" struct SplineData { - CVector3D Position; + // Should be fixed, because used in the simulation + CFixedVector3D Position; CVector3D Velocity; - CVector3D Rotation; - float Distance/*, DistanceOffset*/; //DistanceOffset is to keep track of how far into the spline this node is + // TODO: make rotation as other spline + CFixedVector3D Rotation; + fixed Distance/*, DistanceOffset*/; //DistanceOffset is to keep track of how far into the spline this node is }; class RNSpline @@ -41,13 +45,13 @@ public: RNSpline() { NodeCount = 0; } virtual ~RNSpline() {} - void AddNode(const CVector3D& pos); + void AddNode(const CFixedVector3D& pos); void BuildSpline(); CVector3D GetPosition(float time) const; CVector3D GetRotation(float time) const; const std::vector& GetAllNodes() const { return Node; } - float MaxDistance; + fixed MaxDistance; int NodeCount; protected: @@ -70,12 +74,12 @@ class TNSpline : public SNSpline public: virtual ~TNSpline() {} - void AddNode(const CVector3D& pos, const CVector3D& rotation, float timePeriod); + void AddNode(const CFixedVector3D& pos, const CFixedVector3D& rotation, fixed timePeriod); void PushNode() { Node.push_back( SplineData() ); } - void InsertNode(const int index, const CVector3D& pos, const CVector3D& rotation, float timePeriod); + void InsertNode(const int index, const CFixedVector3D& pos, const CFixedVector3D& rotation, fixed timePeriod); void RemoveNode(const int index); - void UpdateNodeTime(const int index, float time); - void UpdateNodePos(const int index, const CVector3D& pos); + void UpdateNodeTime(const int index, fixed time); + void UpdateNodePos(const int index, const CFixedVector3D& pos); void BuildSpline(){ RNSpline::BuildSpline(); Smooth(); Smooth(); Smooth(); } void Smooth(){ for (int x = 0; x < 3; ++x) { SNSpline::Smooth(); Constrain(); } } diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index 4a926db09f..7af1286781 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -35,6 +35,7 @@ #include "lib/sysdep/os/win/wversion.h" #endif +#include "graphics/CinemaManager.h" #include "graphics/CinemaPath.h" #include "graphics/FontMetrics.h" #include "graphics/GameView.h" @@ -228,6 +229,11 @@ void Render() g_Renderer.RenderTextOverlays(); + if (g_Game && g_Game->IsGameStarted()) + g_Game->GetView()->GetCinema()->Render(); + + ogl_WarnIfError(); + if (g_DoRenderGui) g_GUI->Draw(); @@ -568,6 +574,8 @@ static void InitInput() in_add_handler(gui_handler); in_add_handler(touch_input_handler); + + in_add_handler(cinema_manager_handler); // must be registered after (called before) the GUI which relies on these globals in_add_handler(GlobalsInputHandler); diff --git a/source/simulation2/MessageTypes.h b/source/simulation2/MessageTypes.h index fa9a52115f..5c0f4ba094 100644 --- a/source/simulation2/MessageTypes.h +++ b/source/simulation2/MessageTypes.h @@ -29,6 +29,8 @@ #include "maths/Vector3D.h" +#include "ps/CStr.h" + #define DEFAULT_MESSAGE_IMPL(name) \ virtual int GetType() const { return MT_##name; } \ virtual const char* GetScriptHandlerName() const { return "On" #name; } \ @@ -538,4 +540,27 @@ public: } }; +/** +* Cinematics events +*/ + +class CMessageCinemaPathEnded : public CMessage +{ +public: + DEFAULT_MESSAGE_IMPL(CinemaPathEnded) + + CMessageCinemaPathEnded(CStrW name) : + name(name) + { + } + + CStrW name; +}; + +class CMessageCinemaQueueEnded : public CMessage +{ +public: + DEFAULT_MESSAGE_IMPL(CinemaQueueEnded) +}; + #endif // INCLUDED_MESSAGETYPES diff --git a/source/simulation2/TypeList.h b/source/simulation2/TypeList.h index 7b71ce1f46..e0d9c6ad88 100644 --- a/source/simulation2/TypeList.h +++ b/source/simulation2/TypeList.h @@ -57,6 +57,8 @@ MESSAGE(ValueModification) MESSAGE(TemplateModification) MESSAGE(VisionRangeChanged) MESSAGE(MinimapPing) +MESSAGE(CinemaPathEnded) +MESSAGE(CinemaQueueEnded) // TemplateManager must come before all other (non-test) components, // so that it is the first to be (de)serialized @@ -75,6 +77,9 @@ COMPONENT(AIInterfaceScripted) INTERFACE(AIManager) COMPONENT(AIManager) +INTERFACE(CinemaManager) +COMPONENT(CinemaManager) + INTERFACE(CommandQueue) COMPONENT(CommandQueue) diff --git a/source/simulation2/components/CCmpCinemaManager.cpp b/source/simulation2/components/CCmpCinemaManager.cpp new file mode 100644 index 0000000000..360e5117ad --- /dev/null +++ b/source/simulation2/components/CCmpCinemaManager.cpp @@ -0,0 +1,253 @@ +/* Copyright (C) 2016 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 "ps/CLogger.h" +#include "ps/Game.h" +#include "simulation2/MessageTypes.h" +#include "simulation2/Simulation2.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)) + { + // ... + } + + virtual void Deinit() + { + // ... + } + + virtual void Serialize(ISerializer& serialize) + { + if (!g_Game || !g_Game->GetView()) + { + LOGERROR("Trying to serialize cinematics when GameView isn't initialized!"); + return; + } + CinematicSimulationData* p_CinematicSimulationData = g_Game->GetView()->GetCinema()->GetCinematicSimulationData(); + serialize.Bool("MapRevealed", p_CinematicSimulationData->m_MapRevealed); + serialize.NumberU32_Unbounded("NumberOfPaths", p_CinematicSimulationData->m_Paths.size()); + for (auto it : p_CinematicSimulationData->m_Paths) + { + CCinemaPath& path = it.second; + const CCinemaData* data = path.GetData(); + + // 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; + + 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", 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); + } + } + } + + virtual void Deserialize(const CParamNode& UNUSED(paramNode), IDeserializer& deserialize) + { + if (!g_Game || !g_Game->GetView()) + { + LOGERROR("Trying to deserialize cinematics when GameView isn't initialized!"); + return; + } + CinematicSimulationData* p_CinematicSimulationData = g_Game->GetView()->GetCinema()->GetCinematicSimulationData(); + deserialize.Bool("MapRevealed", p_CinematicSimulationData->m_MapRevealed); + uint32_t numberOfPaths = 0; + deserialize.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); + + targetSpline.AddNode(node.Position, CFixedVector3D(), node.Distance); + } + } + + // Construct cinema path with data gathered + CCinemaPath path(data, pathSpline, targetSpline); + p_CinematicSimulationData->m_Paths[data.m_Name] = path; + } + g_Game->GetView()->GetCinema()->SetEnabled(p_CinematicSimulationData->m_Enabled); + } + + virtual void HandleMessage(const CMessage& msg, bool UNUSED(global)) + { + switch (msg.GetType()) + { + case MT_Update: + { + const CMessageUpdate &msgData = static_cast(msg); + CinematicSimulationData* pCinematicSimulationData = g_Game->GetView()->GetCinema()->GetCinematicSimulationData(); + if (!pCinematicSimulationData->m_Enabled) + break; + + if (pCinematicSimulationData->m_ElapsedTime >= pCinematicSimulationData->m_TotalTime) + { + pCinematicSimulationData->m_ElapsedTime = fixed::Zero(); + pCinematicSimulationData->m_TotalTime = fixed::Zero(); + g_Game->GetView()->GetCinema()->SetEnabled(false); + g_Game->GetSimulation2()->PostMessage(SYSTEM_ENTITY, CMessageCinemaQueueEnded()); + } + else + { + pCinematicSimulationData->m_ElapsedTime += msgData.turnLength; + pCinematicSimulationData->m_CurrentPathElapsedTime += msgData.turnLength; + if (pCinematicSimulationData->m_CurrentPathElapsedTime >= pCinematicSimulationData->m_PathQueue.front().GetDuration()) + { + CMessageCinemaPathEnded msgCinemaPathEnded(pCinematicSimulationData->m_PathQueue.front().GetName()); + pCinematicSimulationData->m_PathQueue.pop_front(); + g_Game->GetSimulation2()->PostMessage(SYSTEM_ENTITY, msgCinemaPathEnded); + } + } + break; + } + default: + break; + } + } + + virtual void AddCinemaPathToQueue(CStrW name) + { + if (!g_Game || !g_Game->GetView()) + { + LOGERROR("Trying to add cinema path when GameView isn't initialized!"); + return; + } + g_Game->GetView()->GetCinema()->AddPathToQueue(name); + CinematicSimulationData* pGetCinematicSimulationData = g_Game->GetView()->GetCinema()->GetCinematicSimulationData(); + pGetCinematicSimulationData->m_TotalTime += pGetCinematicSimulationData->m_Paths[name].GetDuration(); + } + + virtual void Play() + { + if (!g_Game || !g_Game->GetView()) + { + LOGERROR("Trying to play cinematics when GameView isn't initialized!"); + return; + } + g_Game->GetView()->GetCinema()->Play(); + g_Game->GetView()->GetCinema()->SetEnabled(true); + } + + virtual void Stop() + { + if (!g_Game || !g_Game->GetView()) + { + LOGERROR("Trying to stop cinematics when GameView isn't initialized!"); + return; + } + g_Game->GetView()->GetCinema()->Stop(); + g_Game->GetView()->GetCinema()->SetEnabled(false); + } + +}; + +REGISTER_COMPONENT_TYPE(CinemaManager) diff --git a/source/simulation2/components/CCmpOverlayRenderer.cpp b/source/simulation2/components/CCmpOverlayRenderer.cpp index abcc0e126b..33736e9c0a 100644 --- a/source/simulation2/components/CCmpOverlayRenderer.cpp +++ b/source/simulation2/components/CCmpOverlayRenderer.cpp @@ -166,7 +166,7 @@ public: void RenderSubmit(SceneCollector& collector) { - if (!m_Enabled) + if (!m_Enabled || !ICmpOverlayRenderer::m_OverrideVisible) return; for (size_t i = 0; i < m_Sprites.size(); ++i) diff --git a/source/simulation2/components/CCmpSelectable.cpp b/source/simulation2/components/CCmpSelectable.cpp index 5146fe1fad..1e942a11dd 100644 --- a/source/simulation2/components/CCmpSelectable.cpp +++ b/source/simulation2/components/CCmpSelectable.cpp @@ -587,6 +587,9 @@ void CCmpSelectable::UpdateDynamicOverlay(float frameOffset) void CCmpSelectable::RenderSubmit(SceneCollector& collector) { // don't render selection overlay if it's not gonna be visible + if (!ICmpSelectable::m_OverrideVisible) + return; + if (m_Visible && m_Color.a > 0) { if (!m_Cached) diff --git a/source/simulation2/components/CCmpTerritoryManager.cpp b/source/simulation2/components/CCmpTerritoryManager.cpp index 1f453a9196..109d1f5247 100644 --- a/source/simulation2/components/CCmpTerritoryManager.cpp +++ b/source/simulation2/components/CCmpTerritoryManager.cpp @@ -123,6 +123,7 @@ public: m_TriggerEvent = true; m_EnableLineDebugOverlays = false; m_DirtyID = 1; + m_Visible = true; m_AnimTime = 0.0; @@ -275,6 +276,15 @@ public: void Interpolate(float frameTime, float frameOffset); void RenderSubmit(SceneCollector& collector); + + void SetVisibility(bool visible) + { + m_Visible = visible; + } + +private: + + bool m_Visible; }; REGISTER_COMPONENT_TYPE(TerritoryManager) @@ -644,6 +654,9 @@ void CCmpTerritoryManager::Interpolate(float frameTime, float UNUSED(frameOffset void CCmpTerritoryManager::RenderSubmit(SceneCollector& collector) { + if (!m_Visible) + return; + for (size_t i = 0; i < m_BoundaryLines.size(); ++i) collector.Submit(&m_BoundaryLines[i].overlay); diff --git a/source/simulation2/components/ICmpCinemaManager.cpp b/source/simulation2/components/ICmpCinemaManager.cpp new file mode 100644 index 0000000000..51e4fb42af --- /dev/null +++ b/source/simulation2/components/ICmpCinemaManager.cpp @@ -0,0 +1,28 @@ +/* Copyright (C) 2016 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 "ICmpCinemaManager.h" + +#include "simulation2/system/InterfaceScripted.h" + +BEGIN_INTERFACE_WRAPPER(CinemaManager) +DEFINE_INTERFACE_METHOD_1("AddCinemaPathToQueue", void, ICmpCinemaManager, AddCinemaPathToQueue, CStrW) +DEFINE_INTERFACE_METHOD_0("Play", void, ICmpCinemaManager, Play) +DEFINE_INTERFACE_METHOD_0("Stop", void, ICmpCinemaManager, Stop) +END_INTERFACE_WRAPPER(CinemaManager) diff --git a/source/simulation2/components/ICmpCinemaManager.h b/source/simulation2/components/ICmpCinemaManager.h new file mode 100644 index 0000000000..8b694e3c50 --- /dev/null +++ b/source/simulation2/components/ICmpCinemaManager.h @@ -0,0 +1,42 @@ +/* Copyright (C) 2016 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 . + */ + +#ifndef INCLUDED_ICMPCINEMAMANAGER +#define INCLUDED_ICMPCINEMAMANAGER + +#include "simulation2/system/Interface.h" + +#include "ps/CStr.h" + +/** + * Component for CCinemaManager class + * TODO: write description + */ + +class ICmpCinemaManager : public IComponent +{ +public: + // TODO: add path name and description + virtual void AddCinemaPathToQueue(CStrW name) = 0; + + virtual void Play() = 0; + virtual void Stop() = 0; + + DECLARE_INTERFACE_TYPE(CinemaManager) +}; + +#endif // INCLUDED_ICMPCINEMAMANAGER \ No newline at end of file diff --git a/source/simulation2/components/ICmpOverlayRenderer.cpp b/source/simulation2/components/ICmpOverlayRenderer.cpp index 1fc287bdc1..3bc0baaed6 100644 --- a/source/simulation2/components/ICmpOverlayRenderer.cpp +++ b/source/simulation2/components/ICmpOverlayRenderer.cpp @@ -25,3 +25,5 @@ BEGIN_INTERFACE_WRAPPER(OverlayRenderer) DEFINE_INTERFACE_METHOD_0("Reset", void, ICmpOverlayRenderer, Reset) DEFINE_INTERFACE_METHOD_5("AddSprite", void, ICmpOverlayRenderer, AddSprite, VfsPath, CFixedVector2D, CFixedVector2D, CFixedVector3D, std::string) END_INTERFACE_WRAPPER(OverlayRenderer) + +bool ICmpOverlayRenderer::m_OverrideVisible = true; \ No newline at end of file diff --git a/source/simulation2/components/ICmpOverlayRenderer.h b/source/simulation2/components/ICmpOverlayRenderer.h index 3e6e4ca32d..9dfb18c05b 100644 --- a/source/simulation2/components/ICmpOverlayRenderer.h +++ b/source/simulation2/components/ICmpOverlayRenderer.h @@ -52,7 +52,19 @@ public: */ virtual void AddSprite(VfsPath textureName, CFixedVector2D corner0, CFixedVector2D corner1, CFixedVector3D offset, std::string color = "255 255 255 255") = 0; + /** + * Enables or disables rendering of all sprites. + * @param visible Whether the selectable should be visible. + */ + static void SetOverrideVisibility(bool visible) + { + ICmpOverlayRenderer::m_OverrideVisible = visible; + } + DECLARE_INTERFACE_TYPE(OverlayRenderer) + +protected: + static bool m_OverrideVisible; }; #endif // INCLUDED_ICMPOVERLAYRENDERER diff --git a/source/simulation2/components/ICmpSelectable.cpp b/source/simulation2/components/ICmpSelectable.cpp index a947855d04..a4caea4989 100644 --- a/source/simulation2/components/ICmpSelectable.cpp +++ b/source/simulation2/components/ICmpSelectable.cpp @@ -28,3 +28,4 @@ DEFINE_INTERFACE_METHOD_2("SetSelectionHighlight", void, ICmpSelectable, SetSele END_INTERFACE_WRAPPER(Selectable) bool ICmpSelectable::ms_EnableDebugOverlays = false; +bool ICmpSelectable::m_OverrideVisible = true; diff --git a/source/simulation2/components/ICmpSelectable.h b/source/simulation2/components/ICmpSelectable.h index 37339ce29f..57eb55c86f 100644 --- a/source/simulation2/components/ICmpSelectable.h +++ b/source/simulation2/components/ICmpSelectable.h @@ -66,6 +66,15 @@ public: */ virtual void SetVisibility(bool visible) = 0; + /** + * Enables or disables rendering of all entities selectable. + * @param visible Whether the selectable should be visible. + */ + static void SetOverrideVisibility(bool visible) + { + ICmpSelectable::m_OverrideVisible = visible; + } + /** * Set the alpha of the selection highlight. Set to 0 to hide the highlight. */ @@ -77,6 +86,9 @@ public: // and methods, where we can keep settings like these. Note that any such data store would need to be per-component-manager // and not entirely global, to support multiple simulation instances. static bool ms_EnableDebugOverlays; // ms for member static + +protected: + static bool m_OverrideVisible; }; #endif // INCLUDED_ICMPSELECTABLE diff --git a/source/simulation2/components/ICmpTerritoryManager.h b/source/simulation2/components/ICmpTerritoryManager.h index df123bddeb..a2768914bf 100644 --- a/source/simulation2/components/ICmpTerritoryManager.h +++ b/source/simulation2/components/ICmpTerritoryManager.h @@ -78,6 +78,11 @@ public: */ virtual u8 GetTerritoryPercentage(player_id_t player) = 0; + /** + * Enables or disables rendering of an territory borders. + */ + virtual void SetVisibility(bool visible) = 0; + DECLARE_INTERFACE_TYPE(TerritoryManager) }; diff --git a/source/simulation2/scripting/MessageTypeConversions.cpp b/source/simulation2/scripting/MessageTypeConversions.cpp index ed951e0b4c..01518a4d2c 100644 --- a/source/simulation2/scripting/MessageTypeConversions.cpp +++ b/source/simulation2/scripting/MessageTypeConversions.cpp @@ -470,6 +470,36 @@ CMessage* CMessageMinimapPing::FromJSVal(ScriptInterface& UNUSED(scriptInterface return new CMessageMinimapPing(); } +//////////////////////////////// + +JS::Value CMessageCinemaPathEnded::ToJSVal(ScriptInterface& scriptInterface) const +{ + TOJSVAL_SETUP(); + SET_MSG_PROPERTY(name); + return JS::ObjectValue(*obj); +} + +CMessage* CMessageCinemaPathEnded::FromJSVal(ScriptInterface& scriptInterface, JS::HandleValue val) +{ + FROMJSVAL_SETUP(); + GET_MSG_PROPERTY(CStrW, name); + return new CMessageCinemaPathEnded(name); +} + +//////////////////////////////// + +JS::Value CMessageCinemaQueueEnded::ToJSVal(ScriptInterface& scriptInterface) const +{ + TOJSVAL_SETUP(); + return JS::ObjectValue(*obj); +} + +CMessage* CMessageCinemaQueueEnded::FromJSVal(ScriptInterface& scriptInterface, JS::HandleValue val) +{ + FROMJSVAL_SETUP(); + return new CMessageCinemaQueueEnded(); +} + //////////////////////////////////////////////////////////////// CMessage* CMessageFromJSVal(int mtid, ScriptInterface& scriptingInterface, JS::HandleValue val) diff --git a/source/simulation2/system/ComponentManager.cpp b/source/simulation2/system/ComponentManager.cpp index fb8e0383e4..b4f4f38830 100644 --- a/source/simulation2/system/ComponentManager.cpp +++ b/source/simulation2/system/ComponentManager.cpp @@ -711,6 +711,7 @@ void CComponentManager::AddSystemComponents(bool skipScriptedComponents, bool sk { CParamNode noParam; AddComponent(m_SystemEntity, CID_TemplateManager, noParam); + AddComponent(m_SystemEntity, CID_CinemaManager, noParam); AddComponent(m_SystemEntity, CID_CommandQueue, noParam); AddComponent(m_SystemEntity, CID_ObstructionManager, noParam); AddComponent(m_SystemEntity, CID_ParticleManager, noParam); diff --git a/source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp b/source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp index 22c96f6274..ad237efb50 100644 --- a/source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp +++ b/source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp @@ -38,10 +38,10 @@ sCinemaPath ConstructCinemaPath(const CCinemaPath* source) { sCinemaPath path; const CCinemaData* data = source->GetData(); - path.mode = data->m_Mode; - path.style = data->m_Style; + //path.mode = data->m_Mode; + //path.style = data->m_Style; path.growth = data->m_Growth; - path.timescale = data->m_Timescale; + path.timescale = data->m_Timescale.ToFloat(); path.change = data->m_Switch; return path; @@ -51,22 +51,22 @@ CCinemaData ConstructCinemaData(const sCinemaPath& path) CCinemaData data; data.m_Growth = data.m_GrowthCount = path.growth; data.m_Switch = path.change; - data.m_Mode = path.mode; - data.m_Style = path.style; + //data.m_Mode = path.mode; + //data.m_Style = path.style; return data; } sCinemaSplineNode ConstructCinemaNode(const SplineData& data) { sCinemaSplineNode node; - node.px = data.Position.X; - node.py = data.Position.Y; - node.pz = data.Position.Z; + node.px = data.Position.X.ToFloat(); + node.py = data.Position.Y.ToFloat(); + node.pz = data.Position.Z.ToFloat(); - node.rx = data.Rotation.X; - node.ry = data.Rotation.Y; - node.rz = data.Rotation.Z; - node.t = data.Distance; + node.rx = data.Rotation.X.ToFloat(); + node.ry = data.Rotation.Y.ToFloat(); + node.rz = data.Rotation.Z.ToFloat(); + node.t = data.Distance.ToFloat(); return node; } @@ -112,7 +112,7 @@ void SetCurrentPaths(const std::vector& atlasPaths) { CStrW pathName(*it->name); paths[pathName] = CCinemaPath(); - paths[pathName].SetTimescale(it->timescale); + paths[pathName].SetTimescale(fixed::FromFloat(it->timescale)); const sCinemaPath& atlasPath = *it; const std::vector nodes = *atlasPath.nodes; @@ -121,10 +121,10 @@ void SetCurrentPaths(const std::vector& atlasPaths) for ( size_t j=0; jGetView()->GetCinema()->SetAllPaths(paths); @@ -155,16 +155,15 @@ MESSAGEHANDLER(CinemaEvent) { CCinemaManager* manager = g_Game->GetView()->GetCinema(); - if ( msg->mode == eCinemaEventMode::SMOOTH ) - manager->OverridePath(*msg->path); - else if ( msg->mode == eCinemaEventMode::IMMEDIATE_PATH ) - manager->MoveToPointAt(msg->t); + if (msg->mode == eCinemaEventMode::SMOOTH) + { + manager->ClearQueue(); + manager->AddPathToQueue(*msg->path); + } else if ( msg->mode == eCinemaEventMode::RESET ) { // g_Game->GetView()->ResetCamera(); } - else if ( msg->mode == eCinemaEventMode::SELECT ) - manager->SetCurrentPath(*msg->path, msg->drawCurrent, msg->lines); else ENSURE(false); } diff --git a/source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp index f7ac490bc7..7ca7b9cd73 100644 --- a/source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp @@ -56,9 +56,6 @@ MESSAGEHANDLER(Screenshot) QUERYHANDLER(CinemaRecord) { - CCinemaManager* manager = g_Game->GetView()->GetCinema(); - manager->SetCurrentPath(*msg->path, false, false); - const int w = msg->width, h = msg->height; { @@ -82,7 +79,6 @@ QUERYHANDLER(CinemaRecord) { AtlasView::GetView_Game()->Update(1.f / msg->framerate); - manager->MoveToPointAt((float)frame/msg->framerate); Render(); Atlas_GLSwapBuffers((void*)g_AtlasGameLoop->glCanvas);