File: CameraController.h

package info (click to toggle)
spring 106.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 55,316 kB
  • sloc: cpp: 543,954; ansic: 44,800; python: 12,575; java: 12,201; awk: 5,889; sh: 1,796; asm: 1,546; xml: 655; perl: 405; php: 211; objc: 194; makefile: 76; sed: 2
file content (161 lines) | stat: -rw-r--r-- 4,257 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#ifndef _CAMERA_CONTROLLER_H
#define _CAMERA_CONTROLLER_H

#include <algorithm>
#include <array>
#include <string>

#include "System/float3.h"


class CCameraController
{
public:
	struct StateMap {
	public:
		typedef std::pair<std::string, float> MapPair;
		typedef std::array<MapPair, 32> ArrayMap;

		typedef ArrayMap::iterator iterator;
		typedef ArrayMap::const_iterator const_iterator;

		iterator begin() { return (pairsMap.begin()); }
		iterator end() { return (pairsMap.begin() + numPairs); }

		const_iterator cbegin() const { return (pairsMap.cbegin()); }
		const_iterator cend() const { return (pairsMap.cbegin() + numPairs); }

		const_iterator find(const std::string& s) const {
			const auto pair = std::make_pair(s, 0.0f);
			const auto pred = [](const MapPair& a, const MapPair& b) { return (a.first < b.first); };
			const auto iter = std::lower_bound(cbegin(), cend(), pair, pred);
			if (iter == cend() || iter->first != s)
				return (cend());
			return iter;
		}

		float operator [](const std::string& s) const {
			const auto iter = find(s);
			if (iter == cend())
				return 0.0f;
			return iter->second;
		}

		float& operator [](const std::string& s) {
			const auto iter = find(s);

			if (iter == cend()) {
				// Spring.SetCameraState might be handed a table larger than we can hold
				if (numPairs == pairsMap.size())
					return dummyPair.second;

				pairsMap[numPairs++] = std::make_pair(s, 0.0f);

				// inefficient on repeated insertions, but map size is a small constant
				for (size_t i = numPairs - 1; i > 0; i--) {
					if (pairsMap[i - 1].first < pairsMap[i].first)
						return pairsMap[i].second;

					std::swap(pairsMap[i - 1], pairsMap[i]);
				}

				return pairsMap[0].second;
			}

			return pairsMap[iter - cbegin()].second;
		}

		bool operator == (const StateMap& sm) const {
			return (numPairs == sm.numPairs && pairsMap == sm.pairsMap);
		}

		bool empty() const { return (numPairs == 0); }
		void clear() {
			numPairs = 0;

			for (auto& pair: pairsMap) {
				pair = {};
			}
		}

	private:
		ArrayMap pairsMap;
		MapPair dummyPair;

		size_t numPairs = 0;
	};

public:
	CCameraController();
	virtual ~CCameraController() {}

	virtual const std::string GetName() const = 0;

	virtual void KeyMove(float3 move) = 0;
	virtual void MouseMove(float3 move) = 0;
	virtual void ScreenEdgeMove(float3 move) = 0;
	virtual void MouseWheelMove(float move) = 0;

	virtual void Update() {}

	float GetFOV() const { return fov; } //< In degrees!

	virtual float3 GetPos() const { return pos; }
	virtual float3 GetDir() const { return dir; }
	virtual float3 GetRot() const;

	virtual void SetPos(const float3& newPos) { pos = newPos; }
	virtual void SetDir(const float3& newDir) { dir = newDir; }
	virtual bool DisableTrackingByKey() { return true; }

	// return the position to send to new controllers SetPos
	virtual float3 SwitchFrom() const = 0;
	virtual void SwitchTo(const int oldCam, const bool showText = true) = 0;

	virtual void GetState(StateMap& sm) const;
	virtual bool SetState(const StateMap& sm);
	virtual void SetTrackingInfo(const float3& pos, float radius) { SetPos(pos); }

	/**
	 * Whether the camera's distance to the ground or to the units
	 * should be used to determine whether to show them as icons or normal.
	 * This is called every frame, so it can be dynamically,
	 * eg depend on the current position/angle.
	 */
	virtual bool GetUseDistToGroundForIcons();

	/// should this mode appear when we toggle the camera controller?
	bool enabled;

protected:
	bool SetStateBool(const StateMap& sm, const std::string& name, bool& var);
	bool SetStateFloat(const StateMap& sm, const std::string& name, float& var);


	float fov;
	float3 pos;
	float3 dir;

	/**
	* @brief scrollSpeed
	* scales the scroll speed in general
	* (includes middleclick, arrowkey, screenedge scrolling)
	*/
	float scrollSpeed;

	/**
	 * @brief switchVal
	 * Where to switch from Camera-Unit-distance to Camera-Ground-distance
	 * for deciding whether to draw 3D view or icon of units.
	 * * 1.0 = 0 degree  = overview
	 * * 0.0 = 90 degree = first person
	 */
	float switchVal;

	float pixelSize;
};


#endif // _CAMERA_CONTROLLER_H