Line data Source code
1 : /* Copyright (C) 2020 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 22 : 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 current vertical offset above above the map zero point.
125 : */
126 : virtual entity_pos_t GetHeightFixed() const = 0;
127 :
128 : /**
129 : * Returns the vertical offset above above the map zero point
130 : * the unit would have at the given position.
131 : */
132 : virtual entity_pos_t GetHeightAtFixed(entity_pos_t x, entity_pos_t z) const = 0;
133 :
134 : /**
135 : * Returns true iff the entity will follow the terrain height (possibly with an offset)
136 : */
137 : virtual bool IsHeightRelative() const = 0;
138 :
139 : /**
140 : * When set to true, the entity will follow the terrain height (possibly with an offset)
141 : * When set to false, it's height won't change automatically
142 : */
143 : virtual void SetHeightRelative(bool flag) = 0;
144 :
145 : /**
146 : * Returns whether the entity can float on water.
147 : */
148 : virtual bool CanFloat() const = 0;
149 :
150 : /**
151 : * Set the entity to float on water
152 : */
153 : virtual void SetFloating(bool flag) = 0;
154 :
155 : /**
156 : * Set the entity to float on water, in a non-network-synchronised visual-only way.
157 : * (This is to support the 'floating' flag in actor XMLs.)
158 : */
159 : virtual void SetActorFloating(bool flag) = 0;
160 :
161 : /**
162 : * Set construction progress of the model, this affects the rendered position of the model.
163 : * 0.0 will be fully underground, 1.0 will be fully visible, 0.5 will be half underground.
164 : */
165 : virtual void SetConstructionProgress(fixed progress) = 0;
166 :
167 : /**
168 : * Returns the current x,y,z position (no interpolation).
169 : * Depends on the current terrain heightmap.
170 : * Must not be called unless IsInWorld is true.
171 : */
172 : virtual CFixedVector3D GetPosition() const = 0;
173 :
174 : /**
175 : * Returns the current x,z position (no interpolation).
176 : * Must not be called unless IsInWorld is true.
177 : */
178 : virtual CFixedVector2D GetPosition2D() const = 0;
179 :
180 : /**
181 : * Returns the previous turn's x,y,z position (no interpolation).
182 : * Depends on the current terrain heightmap.
183 : * Must not be called unless IsInWorld is true.
184 : */
185 : virtual CFixedVector3D GetPreviousPosition() const = 0;
186 :
187 : /**
188 : * Returns the previous turn's x,z position (no interpolation).
189 : * Must not be called unless IsInWorld is true.
190 : */
191 : virtual CFixedVector2D GetPreviousPosition2D() const = 0;
192 :
193 : /**
194 : * Returns the turn rate in radians per second.
195 : */
196 : virtual fixed GetTurnRate() const = 0;
197 :
198 : /**
199 : * Rotate smoothly to the given angle around the upwards axis.
200 : * @param y clockwise radians from the +Z axis.
201 : */
202 : virtual void TurnTo(entity_angle_t y) = 0;
203 :
204 : /**
205 : * Rotate immediately to the given angle around the upwards axis.
206 : * @param y clockwise radians from the +Z axis.
207 : */
208 : virtual void SetYRotation(entity_angle_t y) = 0;
209 :
210 : /**
211 : * Rotate immediately to the given angles around the X (pitch) and Z (roll) axes.
212 : * @param x radians around the X axis. (TODO: in which direction?)
213 : * @param z radians around the Z axis.
214 : * @note if either x or z is non-zero, it will override terrain conformance mode
215 : */
216 : virtual void SetXZRotation(entity_angle_t x, entity_angle_t z) = 0;
217 :
218 : // NOTE: we separate Y from XZ because most code will only ever change Y;
219 : // XZ are typically just used in the editor, and other code should never
220 : // worry about them
221 :
222 : /**
223 : * Returns the current rotation (relative to the upwards axis), as Euler
224 : * angles with X=pitch, Y=yaw, Z=roll. (TODO: is that the right way round?)
225 : */
226 : virtual CFixedVector3D GetRotation() const = 0;
227 :
228 : /**
229 : * Returns the distance that the unit will be interpolated over,
230 : * i.e. the distance travelled since the start of the turn.
231 : */
232 : virtual fixed GetDistanceTravelled() const = 0;
233 :
234 : /**
235 : * Get the current interpolated 2D position and orientation, for rendering.
236 : * Must not be called unless IsInWorld is true.
237 : */
238 : virtual void GetInterpolatedPosition2D(float frameOffset, float& x, float& z, float& rotY) const = 0;
239 :
240 : /**
241 : * Get the current interpolated transform matrix, for rendering.
242 : * Must not be called unless IsInWorld is true.
243 : */
244 : virtual CMatrix3D GetInterpolatedTransform(float frameOffset) const = 0;
245 :
246 167 : DECLARE_INTERFACE_TYPE(Position)
247 : };
248 :
249 : #endif // INCLUDED_ICMPPOSITION
|