1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2 
3 #ifndef QTPFS_NODELAYER_HDR
4 #define QTPFS_NODELAYER_HDR
5 
6 #include <limits>
7 #include <vector>
8 #include <list> // for QTPFS_STAGGERED_LAYER_UPDATES
9 #include <boost/cstdint.hpp>
10 
11 #include "System/Rectangle.h"
12 #include "PathDefines.hpp"
13 
14 struct MoveDef;
15 
16 namespace QTPFS {
17 	struct INode;
18 
19 	#ifdef QTPFS_STAGGERED_LAYER_UPDATES
20 	struct LayerUpdate {
21 		SRectangle rectangle;
22 
23 		std::vector<float> speedMods;
24 		std::vector<int  > blockBits;
25 
26 		unsigned int counter;
27 	};
28 	#endif
29 
30 	struct NodeLayer {
31 	public:
32 		typedef unsigned char SpeedModType;
33 		typedef unsigned char SpeedBinType;
34 
35 		static void InitStatic();
MaxSpeedModTypeValueQTPFS::NodeLayer36 		static size_t MaxSpeedModTypeValue() { return (std::numeric_limits<SpeedModType>::max()); }
MaxSpeedBinTypeValueQTPFS::NodeLayer37 		static size_t MaxSpeedBinTypeValue() { return (std::numeric_limits<SpeedBinType>::max()); }
38 
39 		NodeLayer();
40 
41 		void Init(unsigned int layerNum);
42 		void Clear();
43 
44 		#ifdef QTPFS_STAGGERED_LAYER_UPDATES
45 		void QueueUpdate(const SRectangle& r, const MoveDef* md);
PopQueuedUpdateQTPFS::NodeLayer46 		void PopQueuedUpdate() { layerUpdates.pop_front(); }
47 		bool ExecQueuedUpdate();
HaveQueuedUpdateQTPFS::NodeLayer48 		bool HaveQueuedUpdate() const { return (!layerUpdates.empty()); }
GetQueuedUpdateQTPFS::NodeLayer49 		const LayerUpdate& GetQueuedUpdate() const { return (layerUpdates.front()); }
NumQueuedUpdatesQTPFS::NodeLayer50 		unsigned int NumQueuedUpdates() const { return (layerUpdates.size()); }
51 		#endif
52 
53 		bool Update(
54 			const SRectangle& r,
55 			const MoveDef* md,
56 			const std::vector<float>* luSpeedMods = NULL,
57 			const std::vector<  int>* luBlockBits = NULL
58 		);
59 
60 		void ExecNodeNeighborCacheUpdate(unsigned int currFrameNum, unsigned int currMagicNum);
61 		void ExecNodeNeighborCacheUpdates(const SRectangle& ur, unsigned int currMagicNum);
62 
GetNodeRatioQTPFS::NodeLayer63 		float GetNodeRatio() const { return (numLeafNodes / std::max(1.0f, float(xsize * zsize))); }
GetNodeQTPFS::NodeLayer64 		const INode* GetNode(unsigned int x, unsigned int z) const { return nodeGrid[z * xsize + x]; }
GetNodeQTPFS::NodeLayer65 		      INode* GetNode(unsigned int x, unsigned int z)       { return nodeGrid[z * xsize + x]; }
GetNodeQTPFS::NodeLayer66 		const INode* GetNode(unsigned int i) const { return nodeGrid[i]; }
GetNodeQTPFS::NodeLayer67 		      INode* GetNode(unsigned int i)       { return nodeGrid[i]; }
68 
GetOldSpeedBinsQTPFS::NodeLayer69 		const std::vector<SpeedBinType>& GetOldSpeedBins() const { return oldSpeedBins; }
GetCurSpeedBinsQTPFS::NodeLayer70 		const std::vector<SpeedBinType>& GetCurSpeedBins() const { return curSpeedBins; }
GetOldSpeedModsQTPFS::NodeLayer71 		const std::vector<SpeedModType>& GetOldSpeedMods() const { return oldSpeedMods; }
GetCurSpeedModsQTPFS::NodeLayer72 		const std::vector<SpeedModType>& GetCurSpeedMods() const { return curSpeedMods; }
73 
GetNodesQTPFS::NodeLayer74 		std::vector<INode*>& GetNodes() { return nodeGrid; }
75 		void RegisterNode(INode* n);
76 
SetNumLeafNodesQTPFS::NodeLayer77 		void SetNumLeafNodes(unsigned int n) { numLeafNodes = n; }
GetNumLeafNodesQTPFS::NodeLayer78 		unsigned int GetNumLeafNodes() const { return numLeafNodes; }
79 
GetMaxRelSpeedModQTPFS::NodeLayer80 		float GetMaxRelSpeedMod() const { return maxRelSpeedMod; }
GetAvgRelSpeedModQTPFS::NodeLayer81 		float GetAvgRelSpeedMod() const { return avgRelSpeedMod; }
82 
83 		SpeedBinType GetSpeedModBin(float absSpeedMod, float relSpeedMod) const;
84 
GetMemFootPrintQTPFS::NodeLayer85 		boost::uint64_t GetMemFootPrint() const {
86 			boost::uint64_t memFootPrint = sizeof(NodeLayer);
87 			memFootPrint += (curSpeedMods.size() * sizeof(SpeedModType));
88 			memFootPrint += (oldSpeedMods.size() * sizeof(SpeedModType));
89 			memFootPrint += (curSpeedBins.size() * sizeof(SpeedBinType));
90 			memFootPrint += (oldSpeedBins.size() * sizeof(SpeedBinType));
91 			memFootPrint += (nodeGrid.size() * sizeof(INode*));
92 			return memFootPrint;
93 		}
94 
95 	private:
96 		std::vector<INode*> nodeGrid;
97 
98 		std::vector<SpeedModType> curSpeedMods;
99 		std::vector<SpeedModType> oldSpeedMods;
100 		std::vector<SpeedBinType> curSpeedBins;
101 		std::vector<SpeedBinType> oldSpeedBins;
102 
103 		#ifdef QTPFS_STAGGERED_LAYER_UPDATES
104 		std::list<LayerUpdate> layerUpdates;
105 		#endif
106 
107 		// NOTE:
108 		//   we need a fixed range that does not become wider / narrower
109 		//   during terrain deformations (otherwise the bins would change
110 		//   across ALL nodes)
111 		static unsigned int NUM_SPEEDMOD_BINS;
112 		static float        MIN_SPEEDMOD_VALUE;
113 		static float        MAX_SPEEDMOD_VALUE;
114 
115 		unsigned int layerNumber;
116 		unsigned int numLeafNodes;
117 		unsigned int updateCounter;
118 
119 		unsigned int xsize;
120 		unsigned int zsize;
121 
122 		float maxRelSpeedMod;
123 		float avgRelSpeedMod;
124 	};
125 }
126 
127 #endif
128 
129