Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/source/simulation2/components/CCmpItineraryPointRenderer.h
/* 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 <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef INCLUDED_CCMPITINERARYPOINTRENDERER | |||||
#define INCLUDED_CCMPITINERARYPOINTRENDERER | |||||
#include "simulation2/MessageTypes.h" | |||||
#include "simulation2/components/ICmpFootprint.h" | |||||
#include "simulation2/components/ICmpObstructionManager.h" | |||||
#include "simulation2/components/ICmpOwnership.h" | |||||
#include "simulation2/components/ICmpPathfinder.h" | |||||
#include "simulation2/components/ICmpPlayer.h" | |||||
#include "simulation2/components/ICmpPlayerManager.h" | |||||
#include "simulation2/components/ICmpPosition.h" | |||||
#include "simulation2/components/ICmpRangeManager.h" | |||||
#include "simulation2/components/ICmpTerrain.h" | |||||
#include "simulation2/components/ICmpVisual.h" | |||||
#include "simulation2/components/ICmpWaterManager.h" | |||||
#include "simulation2/helpers/Render.h" | |||||
#include "simulation2/helpers/Geometry.h" | |||||
#include "simulation2/system/Component.h" | |||||
#include "graphics/Overlay.h" | |||||
#include "graphics/TextureManager.h" | |||||
#include "ps/CLogger.h" | |||||
#include "ps/Profile.h" | |||||
#include "renderer/Renderer.h" | |||||
struct SVisibilitySegment | |||||
{ | |||||
bool m_Visible; | |||||
size_t m_StartIndex; | |||||
size_t m_EndIndex; // inclusive | |||||
SVisibilitySegment(bool visible, size_t startIndex, size_t endIndex) | |||||
: m_Visible(visible), m_StartIndex(startIndex), m_EndIndex(endIndex) | |||||
{} | |||||
bool operator==(const SVisibilitySegment& other) const | |||||
{ | |||||
return (m_Visible == other.m_Visible && m_StartIndex == other.m_StartIndex && m_EndIndex == other.m_EndIndex); | |||||
} | |||||
bool operator!=(const SVisibilitySegment& other) const | |||||
{ | |||||
return !(*this == other); | |||||
} | |||||
bool IsSinglePoint() const | |||||
{ | |||||
return (m_StartIndex == m_EndIndex); | |||||
} | |||||
}; | |||||
class CCmpItineraryPointRenderer | |||||
{ | |||||
public: | |||||
static void ClassInit(CComponentManager& componentManager) | |||||
{ | |||||
componentManager.SubscribeToMessageType(MT_OwnershipChanged); | |||||
componentManager.SubscribeToMessageType(MT_TurnStart); | |||||
componentManager.SubscribeToMessageType(MT_Destroy); | |||||
componentManager.SubscribeToMessageType(MT_PositionChanged); | |||||
} | |||||
virtual void Init(const CParamNode& paramNode); | |||||
virtual void Deinit(); | |||||
virtual void Serialize(ISerializer& UNUSED(serialize)); | |||||
virtual void Deserialize(const CParamNode& paramNode, IDeserializer& UNUSED(deserialize)); | |||||
virtual void AddPosition_wrapper(const CFixedVector2D&) = 0; | |||||
virtual void HandleMessage(const CMessage& msg, bool UNUSED(global)) = 0; | |||||
/** | |||||
* Returns true if at least one display rally point is set; i.e., if we have a point to render our marker/line at. | |||||
*/ | |||||
virtual bool IsSet() const = 0; | |||||
virtual void SetDisplayed(bool displayed) = 0; | |||||
virtual void SetPosition(const CFixedVector2D& pos) = 0; | |||||
protected: | |||||
/// Import some types for less verbosity | |||||
typedef WaypointPath Path; | |||||
typedef PathGoal Goal; | |||||
typedef ICmpRangeManager::CLosQuerier CLosQuerier; | |||||
typedef SOverlayTexturedLine::LineCapType LineCapType; | |||||
///< Should we render the itinerary points and the path lines? (set from JS when e.g. the unit is selected/deselected) | |||||
bool m_Displayed; | |||||
///< Smooth the path before rendering? | |||||
bool m_SmoothPath; | |||||
/// Draw little overlay circles to indicate where the exact path points are? | |||||
bool m_EnableDebugNodeOverlay; | |||||
size_t m_LastMarkerCount; | |||||
///< Last seen owner of this entity (used to keep track of ownership changes). | |||||
player_id_t m_LastOwner; | |||||
CColor m_LineColor; | |||||
CColor m_LineDashColor; | |||||
CTexturePtr m_Texture; | |||||
CTexturePtr m_TextureMask; | |||||
/// Marker connector line settings (loaded from XML) | |||||
float m_LineThickness; | |||||
LineCapType m_LineStartCapType; | |||||
LineCapType m_LineEndCapType; | |||||
/// Display position of the points. Note that this are merely the display positions; they not necessarily the same as the | |||||
/// actual positions used in the simulation at any given time. In particular, we need this separate copy to support | |||||
/// instantaneously rendering the way point markers/lines when the user sets one in-game (instead of waiting until the | |||||
/// network-synchronization code sets it on the WayPoint component, which might take up to half a second). | |||||
std::deque<CFixedVector2D> m_ItineraryPoints; | |||||
/// Full path to the itinerary points as returned by the pathfinder, with some post-processing applied to reduce zig/zagging. | |||||
std::deque<std::vector<CVector2D> > m_Path; | |||||
/// Visibility segments of the rally point paths; splits the path into SoD/non-SoD segments. | |||||
std::deque<std::deque<SVisibilitySegment> > m_VisibilitySegments; | |||||
/// Entity IDs of the rally point markers. | |||||
std::deque<entity_id_t> m_MarkerEntityIds; | |||||
std::deque<std::deque<SOverlayLine> > m_DebugNodeOverlays; | |||||
/// Textured overlay lines to be used for rendering the marker line. There can be multiple because we may need to render | |||||
/// dashes for segments that are inside the SoD. | |||||
std::list<std::list<SOverlayTexturedLine> > m_TexturedOverlayLines; | |||||
/// Pathfinder passability class to use for computing the (long-range) marker line path. | |||||
std::string m_LinePassabilityClass; | |||||
/// Template name of the rally point markers. | |||||
std::wstring m_MarkerTemplate; | |||||
std::wstring m_LineTexturePath; | |||||
std::wstring m_LineTextureMaskPath; | |||||
///< Pathfinder cost class to use for computing the (long-range) marker line path. | |||||
std::string m_LineCostClass; | |||||
/** | |||||
* Helper function for AddPosition_wrapper and SetPosition. | |||||
*/ | |||||
virtual void AddPosition(CFixedVector2D pos, bool recompute) = 0; | |||||
/** | |||||
* Sets up all overlay lines for rendering according to the current full path and visibility segments. Splits the line into solid | |||||
* and dashed pieces (for the SoD). Should be called whenever the SoD has changed. If no full path is currently set, this method | |||||
* does nothing. | |||||
*/ | |||||
virtual void ConstructAllOverlayLines() = 0; | |||||
/** | |||||
* Sets up the overlay lines for rendering according to the full path and visibility segments at @p index. Splits the line into | |||||
* solid and dashed pieces (for the SoD). Should be called whenever the SoD of the path at @p index has changed. | |||||
*/ | |||||
virtual void ConstructOverlayLines(size_t index) = 0; | |||||
virtual void FixFootprintWaypoints(std::vector<CVector2D>& coords, CmpPtr<ICmpPosition> cmpPosition, CmpPtr<ICmpFootprint> cmpFootprint) const = 0; | |||||
virtual void GetClosestsEdgePointFrom(CFixedVector2D& result, CFixedVector2D& start, CmpPtr<ICmpPosition> cmpPosition, CmpPtr<ICmpFootprint> cmpFootprint) const = 0; | |||||
/** | |||||
* Returns a list of indices of waypoints in the current path (m_Path[index]) where the LOS visibility changes, ordered from | |||||
* building/previous rally point to rally point. Used to construct the overlay line segments and track changes to the SoD. | |||||
*/ | |||||
virtual void GetVisibilitySegments(std::deque<SVisibilitySegment>& out, size_t index) const = 0; | |||||
/** | |||||
* Helper function to GetVisibilitySegments, factored out for testing. Merges single-point segments with its neighbouring | |||||
* segments. You should not have to call this method directly. | |||||
*/ | |||||
virtual void RecomputeAllItineraryPointPaths() = 0; | |||||
/** | |||||
* Recomputes the full path from this entity/the previous rally point to the next rally point, and does all the necessary | |||||
* post-processing to make it prettier. This doesn't check if we have a valid position or if a rally point is set. | |||||
* | |||||
* You shouldn't need to call this method directly. | |||||
*/ | |||||
virtual void RecomputeItineraryPointPath(size_t index, CmpPtr<ICmpPosition>& cmpPosition, CmpPtr<ICmpFootprint>& cmpFootprint, CmpPtr<ICmpPathfinder> cmpPathfinder) = 0; | |||||
/** | |||||
* Recomputes the full path for m_Path[ @p index], and does all the necessary post-processing to make it prettier. | |||||
* | |||||
* Should be called whenever either the starting position or the rally point's position changes. | |||||
*/ | |||||
virtual void RecomputeItineraryPointPath_wrapper(size_t index) = 0; | |||||
/** | |||||
* Repositions the way point markers; moves them outside of the world (ie. hides them), or positions them at the currently | |||||
* set way points. Also updates the actor's variation according to the entity's current owning player's civilization. | |||||
* | |||||
* Should be called whenever either the position of a way point changes (including whether it is set or not), or the display | |||||
* flag changes, or the ownership of the entity changes. | |||||
*/ | |||||
virtual void UpdateMarkers() = 0; | |||||
/* | |||||
* Must be called whenever m_Displayed or the size of m_RallyPoints change, | |||||
* to determine whether we need to respond to render messages. | |||||
*/ | |||||
virtual void UpdateMessageSubscriptions() = 0; | |||||
/** | |||||
* Checks for changes to the SoD to the previously saved state, and reconstructs the visibility segments and overlay lines to | |||||
* match if necessary. Does nothing if the rally point lines are not currently set to be displayed, or if no rally point is set. | |||||
*/ | |||||
virtual void UpdateOverlayLines() = 0; | |||||
/** | |||||
* Simplifies the path by removing waypoints that lie between two points that are visible from one another. This is primarily | |||||
* intended to reduce some unnecessary curviness of the path; the pathfinder returns a mathematically (near-)optimal path, which | |||||
* will happily curve and bend to reduce costs. Visually, it doesn't make sense for a rally point path to curve and bend when it | |||||
* could just as well have gone in a straight line; that's why we have this, to make it look more natural. | |||||
* | |||||
* @p coords array of path coordinates to simplify | |||||
* @p maxSegmentLinks if non-zero, indicates the maximum amount of consecutive node-to-node links that can be joined into a | |||||
* single link. If this value is set to e.g. 1, then no reductions will be performed. A value of 3 means that | |||||
* at most 3 consecutive node links will be joined into a single link. | |||||
* @p floating whether to consider nodes who are under the water level as floating on top of the water | |||||
*/ | |||||
virtual void ReduceSegmentsByVisibility(std::vector<CVector2D>& coords, unsigned maxSegmentLinks = 0, bool floating = true) const = 0; | |||||
virtual void RenderSubmit(SceneCollector& collector) = 0; | |||||
}; | |||||
#endif // INCLUDED_CCMPITINERARYPOINTRENDERER | |||||
No newline at end of file |
Wildfire Games · Phabricator