1 /* Copyright (C) 2017 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef INCLUDED_ICMPPOSITION
19 #define INCLUDED_ICMPPOSITION
20 
21 #include "simulation2/system/Interface.h"
22 
23 #include "simulation2/helpers/Position.h"
24 #include "maths/FixedVector3D.h"
25 #include "maths/FixedVector2D.h"
26 
27 #include <set>
28 
29 class CMatrix3D;
30 
31 /**
32  * Represents an entity's position in the world (plus its orientation).
33  *
34  * Entity positions are determined by the following:
35  *   - X, Z coordinates (giving left/right and front/back coordinates on the map)
36  *   - Y offset (height; entities always snap to the ground, then are offset by this amount)
37  *   - 'Floating' flag (snap to surface of water instead of going underneath)
38  * As far as the simulation code is concerned, movements are instantaneous.
39  * The only exception is GetInterpolatedTransform, used for rendering, which may
40  * interpolate between the previous and current positions.
41  * (The "Jump" methods circumvent the interpolation, and should be used whenever immediate
42  * movement is needed.)
43  *
44  * Orientations consist of the following:
45  *   - Rotation around upwards 'Y' axis (the common form of rotation)
46  *   - Terrain conformance mode, one of:
47  *     - Upright (upwards axis is always the world Y axis, e.g. for humans)
48  *     - Pitch (rotates backwards and forwards to match the terrain, e.g. for horses)
49  *     - Pitch-Roll (rotates in all directions to match the terrain, e.g. for carts)
50  *     - Roll (rotates sideways to match the terrain)
51  *      NOTE: terrain conformance is currently only a local, visual effect; it doesn't change
52  *       the network synchronized rotation or the data returned by GetRotation
53  *   - Rotation around relative X (pitch), Z (roll) axes (rare; used for special effects)
54  *      NOTE: if XZ rotation is non-zero, it will override the terrain conformance mode
55  *
56  * Entities can also be 'outside the world' (e.g. hidden inside a building), in which
57  * case they have no position. Callers <b>must</b> check the entity is in the world, before
58  * querying its position.
59  */
60 class ICmpPosition : public IComponent
61 {
62 public:
63 	/**
64 	 * Set this as a turret of an other entity
65 	 */
66 	virtual void SetTurretParent(entity_id_t parent, const CFixedVector3D& offset) = 0;
67 
68 	/**
69 	 * Get the turret parent of this entity
70 	 */
71 	virtual entity_id_t GetTurretParent() const = 0;
72 
73 	/**
74 	 * Has to be called to update the simulation position of the turret
75 	 */
76 	virtual void UpdateTurretPosition() = 0;
77 
78 	/**
79 	 * Get the list of turrets to read or edit
80 	 */
81 	virtual std::set<entity_id_t>* GetTurrets() = 0;
82 
83 	/**
84 	 * Returns true if the entity currently exists at a defined position in the world.
85 	 */
86 	virtual bool IsInWorld() const = 0;
87 
88 	/**
89 	 * Causes IsInWorld to return false. (Use MoveTo() or JumpTo() to move back into the world.)
90 	 */
91 	virtual void MoveOutOfWorld() = 0;
92 
93 	/**
94 	 * Move smoothly to the given location.
95 	 */
96 	virtual void MoveTo(entity_pos_t x, entity_pos_t z) = 0;
97 
98 	/**
99 	 * Combines MoveTo and TurnTo to avoid an uncessary "AdvertisePositionChange"
100 	 */
101 	virtual void MoveAndTurnTo(entity_pos_t x, entity_pos_t z, entity_angle_t ry) = 0;
102 
103 	/**
104 	 * Move immediately to the given location, with no interpolation.
105 	 */
106 	virtual void JumpTo(entity_pos_t x, entity_pos_t z) = 0;
107 
108 	/**
109 	 * Set the vertical offset above the terrain/water surface.
110 	 */
111 	virtual void SetHeightOffset(entity_pos_t dy) = 0;
112 
113 	/**
114 	 * Returns the current vertical offset above the terrain/water surface.
115 	 */
116 	virtual entity_pos_t GetHeightOffset() const = 0;
117 
118 	/**
119 	 * Set the vertical position above the map zero point
120 	 */
121 	virtual void SetHeightFixed(entity_pos_t y) = 0;
122 
123 	/**
124 	 * Returns the vertical offset above the map zero point
125 	 */
126 	virtual entity_pos_t GetHeightFixed() const = 0;
127 
128 	/**
129 	 * Returns true iff the entity will follow the terrain height (possibly with an offset)
130 	 */
131 	virtual bool IsHeightRelative() const = 0;
132 
133 	/**
134 	 * When set to true, the entity will follow the terrain height (possibly with an offset)
135 	 * When set to false, it's height won't change automatically
136 	 */
137 	virtual void SetHeightRelative(bool flag) = 0;
138 
139 	/**
140 	 * Returns whether the entity can float on water.
141 	 */
142 	virtual bool CanFloat() const = 0;
143 
144 	/**
145 	 * Set the entity to float on water
146 	 */
147 	virtual void SetFloating(bool flag) = 0;
148 
149 	/**
150 	 * Set the entity to float on water, in a non-network-synchronised visual-only way.
151 	 * (This is to support the 'floating' flag in actor XMLs.)
152 	 */
153 	virtual void SetActorFloating(bool flag) = 0;
154 
155 	/**
156 	 * Set construction progress of the model, this affects the rendered position of the model.
157 	 * 0.0 will be fully underground, 1.0 will be fully visible, 0.5 will be half underground.
158 	 */
159 	virtual void SetConstructionProgress(fixed progress) = 0;
160 
161 	/**
162 	 * Returns the current x,y,z position (no interpolation).
163 	 * Depends on the current terrain heightmap.
164 	 * Must not be called unless IsInWorld is true.
165 	 */
166 	virtual CFixedVector3D GetPosition() const = 0;
167 
168 	/**
169 	 * Returns the current x,z position (no interpolation).
170 	 * Must not be called unless IsInWorld is true.
171 	 */
172 	virtual CFixedVector2D GetPosition2D() const = 0;
173 
174 	/**
175 	 * Returns the previous turn's x,y,z position (no interpolation).
176 	 * Depends on the current terrain heightmap.
177 	 * Must not be called unless IsInWorld is true.
178 	 */
179 	virtual CFixedVector3D GetPreviousPosition() const = 0;
180 
181 	/**
182 	 * Returns the previous turn's x,z position (no interpolation).
183 	 * Must not be called unless IsInWorld is true.
184 	 */
185 	virtual CFixedVector2D GetPreviousPosition2D() const = 0;
186 
187 	/**
188 	 * Rotate smoothly to the given angle around the upwards axis.
189 	 * @param y clockwise radians from the +Z axis.
190 	 */
191 	virtual void TurnTo(entity_angle_t y) = 0;
192 
193 	/**
194 	 * Rotate immediately to the given angle around the upwards axis.
195 	 * @param y clockwise radians from the +Z axis.
196 	 */
197 	virtual void SetYRotation(entity_angle_t y) = 0;
198 
199 	/**
200 	 * Rotate immediately to the given angles around the X (pitch) and Z (roll) axes.
201 	 * @param x radians around the X axis. (TODO: in which direction?)
202 	 * @param z radians around the Z axis.
203 	 * @note if either x or z is non-zero, it will override terrain conformance mode
204 	 */
205 	virtual void SetXZRotation(entity_angle_t x, entity_angle_t z) = 0;
206 
207 	// NOTE: we separate Y from XZ because most code will only ever change Y;
208 	// XZ are typically just used in the editor, and other code should never
209 	// worry about them
210 
211 	/**
212 	 * Returns the current rotation (relative to the upwards axis), as Euler
213 	 * angles with X=pitch, Y=yaw, Z=roll. (TODO: is that the right way round?)
214 	 */
215 	virtual CFixedVector3D GetRotation() const = 0;
216 
217 	/**
218 	 * Returns the distance that the unit will be interpolated over,
219 	 * i.e. the distance travelled since the start of the turn.
220 	 */
221 	virtual fixed GetDistanceTravelled() const = 0;
222 
223 	/**
224 	 * Get the current interpolated 2D position and orientation, for rendering.
225 	 * Must not be called unless IsInWorld is true.
226 	 */
227 	virtual void GetInterpolatedPosition2D(float frameOffset, float& x, float& z, float& rotY) const = 0;
228 
229 	/**
230 	 * Get the current interpolated transform matrix, for rendering.
231 	 * Must not be called unless IsInWorld is true.
232 	 */
233 	virtual CMatrix3D GetInterpolatedTransform(float frameOffset) const = 0;
234 
235 	DECLARE_INTERFACE_TYPE(Position)
236 };
237 
238 #endif // INCLUDED_ICMPPOSITION
239