TrinityCore
Loading...
Searching...
No Matches
Position.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef Trinity_game_Position_h__
19#define Trinity_game_Position_h__
20
21#include "Define.h"
22#include "StringFormatFwd.h"
23#include <span>
24#include <string>
25#include <cmath>
26
27class ByteBuffer;
28
30{
31 constexpr Position()
32 : m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f) { }
33
34 constexpr Position(float x, float y)
35 : m_positionX(x), m_positionY(y), m_positionZ(0.0f), m_orientation(0.0f) { }
36
37 constexpr Position(float x, float y, float z)
38 : m_positionX(x), m_positionY(y), m_positionZ(z), m_orientation(0.0f) { }
39
40 constexpr Position(float x, float y, float z, float o)
41 : m_positionX(x), m_positionY(y), m_positionZ(z), m_orientation(NormalizeOrientationConstexprWrapper(o)) { }
42
43 // streamer tags
44 struct XY;
45 struct XYZ;
46 struct XYZO;
47 struct PackedXYZ;
48
49 template <class Tag>
51 {
52 explicit ConstStreamer(Position const& pos) : Pos(&pos) { }
53 Position const* Pos;
54 };
55
56 template <class Tag>
57 struct Streamer
58 {
59 explicit Streamer(Position& pos) : Pos(&pos) { }
60 operator ConstStreamer<Tag>() const { return ConstStreamer<Tag>(*Pos); }
62 };
63
67 // Better to limit access to _orientation field, to guarantee the value is normalized
68private:
70
71public:
72 bool operator==(Position const& a) const;
73
74 constexpr void Relocate(float x, float y) { m_positionX = x; m_positionY = y; }
75 constexpr void Relocate(float x, float y, float z) { Relocate(x, y); m_positionZ = z; }
76 constexpr void Relocate(float x, float y, float z, float o) { Relocate(x, y, z); SetOrientation(o); }
77 constexpr void Relocate(Position const& pos) { *this = pos; }
78 constexpr void Relocate(Position const* pos) { *this = *pos; }
79
80 void RelocateOffset(Position const& offset);
81
82 constexpr void SetOrientation(float orientation)
83 {
84 m_orientation = NormalizeOrientationConstexprWrapper(orientation);
85 }
86
87 constexpr float GetPositionX() const { return m_positionX; }
88 constexpr float GetPositionY() const { return m_positionY; }
89 constexpr float GetPositionZ() const { return m_positionZ; }
90 constexpr float GetOrientation() const { return m_orientation; }
91
92 constexpr void GetPosition(float& x, float& y) const { x = m_positionX; y = m_positionY; }
93 constexpr void GetPosition(float& x, float& y, float& z) const { GetPosition(x, y); z = m_positionZ; }
94 constexpr void GetPosition(float& x, float& y, float& z, float& o) const { GetPosition(x, y, z); o = m_orientation; }
95 constexpr Position GetPosition() const { return *this; }
96
105
106 bool IsPositionValid() const;
107
108 constexpr float GetExactDist2dSq(const float x, const float y) const
109 {
110 float dx = x - m_positionX;
111 float dy = y - m_positionY;
112 return dx*dx + dy*dy;
113 }
114 constexpr float GetExactDist2dSq(Position const& pos) const { return GetExactDist2dSq(pos.m_positionX, pos.m_positionY); }
115 constexpr float GetExactDist2dSq(Position const* pos) const { return GetExactDist2dSq(*pos); }
116
117 float GetExactDist2d(const float x, const float y) const { return std::sqrt(GetExactDist2dSq(x, y)); }
118 float GetExactDist2d(Position const& pos) const { return GetExactDist2d(pos.m_positionX, pos.m_positionY); }
119 float GetExactDist2d(Position const* pos) const { return GetExactDist2d(*pos); }
120
121 constexpr float GetExactDistSq(float x, float y, float z) const
122 {
123 float dz = z - m_positionZ;
124 return GetExactDist2dSq(x, y) + dz*dz;
125 }
126 constexpr float GetExactDistSq(Position const& pos) const { return GetExactDistSq(pos.m_positionX, pos.m_positionY, pos.m_positionZ); }
127 constexpr float GetExactDistSq(Position const* pos) const { return GetExactDistSq(*pos); }
128
129 float GetExactDist(float x, float y, float z) const { return std::sqrt(GetExactDistSq(x, y, z)); }
130 float GetExactDist(Position const& pos) const { return GetExactDist(pos.m_positionX, pos.m_positionY, pos.m_positionZ); }
131 float GetExactDist(Position const* pos) const { return GetExactDist(*pos); }
132
133 Position GetPositionOffsetTo(Position const & endPos) const;
134 Position GetPositionWithOffset(Position const& offset) const;
135
136 float GetAbsoluteAngle(float x, float y) const
137 {
138 float dx = x - m_positionX;
139 float dy = y - m_positionY;
140 return NormalizeOrientation(std::atan2(dy, dx));
141 }
142 float GetAbsoluteAngle(Position const& pos) const { return GetAbsoluteAngle(pos.m_positionX, pos.m_positionY); }
143 float GetAbsoluteAngle(Position const* pos) const { return GetAbsoluteAngle(*pos); }
144 float ToAbsoluteAngle(float relAngle) const { return NormalizeOrientation(relAngle + m_orientation); }
145
146 float ToRelativeAngle(float absAngle) const { return NormalizeOrientation(absAngle - m_orientation); }
147 float GetRelativeAngle(float x, float y) const { return ToRelativeAngle(GetAbsoluteAngle(x, y)); }
148 float GetRelativeAngle(Position const& pos) const { return ToRelativeAngle(GetAbsoluteAngle(pos)); }
149 float GetRelativeAngle(Position const* pos) const { return ToRelativeAngle(GetAbsoluteAngle(pos)); }
150
151 constexpr bool IsInDist2d(float x, float y, float dist) const { return GetExactDist2dSq(x, y) < dist * dist; }
152 constexpr bool IsInDist2d(Position const& pos, float dist) const { return GetExactDist2dSq(pos) < dist * dist; }
153 constexpr bool IsInDist2d(Position const* pos, float dist) const { return GetExactDist2dSq(pos) < dist * dist; }
154
155 constexpr bool IsInDist(float x, float y, float z, float dist) const { return GetExactDistSq(x, y, z) < dist * dist; }
156 constexpr bool IsInDist(Position const& pos, float dist) const { return GetExactDistSq(pos) < dist * dist; }
157 constexpr bool IsInDist(Position const* pos, float dist) const { return GetExactDistSq(pos) < dist * dist; }
158
159 bool IsWithinBox(Position const& boxOrigin, float length, float width, float height) const;
160
161 bool IsWithinVerticalCylinder(Position const& cylinderOrigin, float radius, float height, bool isDoubleVertical = false) const;
162
163 bool IsInPolygon2D(Position const& polygonOrigin, std::span<Position const> vertices) const;
164
165 bool HasInArc(float arcangle, Position const* pos, float border = 2.0f) const;
166 bool HasInLine(Position const* pos, float objSize, float width) const;
167 std::string ToString() const;
168
169 // constrain arbitrary radian orientation to interval [0,2*PI)
170 static float NormalizeOrientation(float o);
171
172private:
173 static constexpr float NormalizeOrientationConstexprWrapper(float o)
174 {
175 if (std::is_constant_evaluated())
176 {
177 if (o < 0.0f || o >= 2.0f * static_cast<float>(M_PI))
178 throw "Compile time Position initialization requires orientation to be in 0-2pi range";
179
180 return o;
181 }
182 else
183 {
184 return NormalizeOrientation(o);
185 }
186 }
187};
188
189#define MAPID_INVALID 0xFFFFFFFF
190
192{
193public:
194 constexpr WorldLocation() : m_mapId(MAPID_INVALID) { }
195
196 constexpr WorldLocation(uint32 mapId, float x, float y) : Position(x, y), m_mapId(mapId) { }
197 constexpr WorldLocation(uint32 mapId, float x, float y, float z) : Position(x, y, z), m_mapId(mapId) { }
198 constexpr WorldLocation(uint32 mapId, float x, float y, float z, float o) : Position(x, y, z, o), m_mapId(mapId) { }
199
200 constexpr WorldLocation(uint32 mapId, Position const& position) : Position(position), m_mapId(mapId) { }
201
202 constexpr void WorldRelocate(WorldLocation const& loc) { m_mapId = loc.GetMapId(); Relocate(loc); }
203 constexpr void WorldRelocate(WorldLocation const* loc) { m_mapId = loc->GetMapId(); Relocate(loc); }
204 constexpr void WorldRelocate(uint32 mapId, Position const& pos) { m_mapId = mapId; Relocate(pos); }
205 constexpr void WorldRelocate(uint32 mapId, float x, float y, float z, float o)
206 {
207 m_mapId = mapId;
208 Relocate(x, y, z, o);
209 }
210
212 {
213 return *this;
214 }
215
216 constexpr uint32 GetMapId() const { return m_mapId; }
217
219
220 std::string GetDebugInfo() const;
221};
222
231
232template<class Tag>
234{
235 constexpr TaggedPosition() { }
236 constexpr TaggedPosition(float x, float y) : Pos(x, y) { }
237 constexpr TaggedPosition(float x, float y, float z) : Pos(x, y, z) { }
238 constexpr TaggedPosition(float x, float y, float z, float o) : Pos(x, y, z, o) { }
239 constexpr TaggedPosition(Position const& pos) : Pos(pos) { }
240
241 constexpr TaggedPosition& operator=(Position const& pos)
242 {
243 Pos.Relocate(pos);
244 return *this;
245 }
246
247 constexpr operator Position() const { return Pos; }
248
249 friend bool operator==(TaggedPosition const& left, TaggedPosition const& right) = default;
250
251 friend ByteBuffer& operator<<(ByteBuffer& buf, TaggedPosition const& tagged) { return buf << Position::ConstStreamer<Tag>(tagged.Pos); }
252 friend ByteBuffer& operator>>(ByteBuffer& buf, TaggedPosition& tagged) { return buf >> Position::Streamer<Tag>(tagged.Pos); }
253
255};
256
257template <>
259{
260 template <typename FormatContext>
261 auto format(Position const& position, FormatContext& ctx) const -> decltype(ctx.out());
262};
263
264template <>
265struct fmt::formatter<WorldLocation, char, void> : fmt::formatter<Position, char, void>
266{
267 template <typename FormatContext>
268 auto format(WorldLocation const& worldLocation, FormatContext& ctx) const -> decltype(ctx.out());
269};
270
271template <>
273{
274 template <typename FormatContext>
275 auto format(TaggedPosition<Position::XY> const& position, FormatContext& ctx) const -> decltype(ctx.out());
276};
277
278template <>
280{
281 template <typename FormatContext>
282 auto format(TaggedPosition<Position::XYZ> const& position, FormatContext& ctx) const -> decltype(ctx.out());
283};
284
285template <>
286struct fmt::formatter<TaggedPosition<Position::XYZO>, char, void> : fmt::formatter<Position, char, void>
287{
288};
289
290template <>
291struct fmt::formatter<TaggedPosition<Position::PackedXYZ>, char, void> : fmt::formatter<TaggedPosition<Position::XYZ>, char, void>
292{
293};
294
295#endif // Trinity_game_Position_h__
#define M_PI
Definition Common.h:118
#define TC_GAME_API
Definition Define.h:129
uint32_t uint32
Definition Define.h:154
std::string GetDebugInfo()
Definition Errors.cpp:170
TC_GAME_API ByteBuffer & operator<<(ByteBuffer &buf, Position::ConstStreamer< Position::XY > const &streamer)
Definition Position.cpp:217
#define MAPID_INVALID
Definition Position.h:189
TC_GAME_API ByteBuffer & operator>>(ByteBuffer &buf, Position::Streamer< Position::XY > const &streamer)
Definition Position.cpp:224
constexpr void WorldRelocate(WorldLocation const &loc)
Definition Position.h:202
constexpr WorldLocation()
Definition Position.h:194
constexpr void WorldRelocate(WorldLocation const *loc)
Definition Position.h:203
constexpr void WorldRelocate(uint32 mapId, Position const &pos)
Definition Position.h:204
constexpr uint32 GetMapId() const
Definition Position.h:216
constexpr void WorldRelocate(uint32 mapId, float x, float y, float z, float o)
Definition Position.h:205
constexpr WorldLocation(uint32 mapId, float x, float y, float z)
Definition Position.h:197
uint32 m_mapId
Definition Position.h:218
constexpr WorldLocation GetWorldLocation() const
Definition Position.h:211
constexpr WorldLocation(uint32 mapId, float x, float y)
Definition Position.h:196
constexpr WorldLocation(uint32 mapId, float x, float y, float z, float o)
Definition Position.h:198
constexpr WorldLocation(uint32 mapId, Position const &position)
Definition Position.h:200
ConstStreamer(Position const &pos)
Definition Position.h:52
Position const * Pos
Definition Position.h:53
Position * Pos
Definition Position.h:61
Streamer(Position &pos)
Definition Position.h:59
constexpr float GetExactDist2dSq(Position const &pos) const
Definition Position.h:114
Streamer< XYZO > PositionXYZOStream()
Definition Position.h:101
float GetRelativeAngle(Position const &pos) const
Definition Position.h:148
constexpr void SetOrientation(float orientation)
Definition Position.h:82
constexpr float GetPositionX() const
Definition Position.h:87
constexpr Position()
Definition Position.h:31
float m_positionZ
Definition Position.h:66
static constexpr float NormalizeOrientationConstexprWrapper(float o)
Definition Position.h:173
constexpr void Relocate(float x, float y, float z, float o)
Definition Position.h:76
constexpr float GetPositionY() const
Definition Position.h:88
ConstStreamer< XY > PositionXYStream() const
Definition Position.h:98
constexpr Position(float x, float y, float z)
Definition Position.h:37
Streamer< XY > PositionXYStream()
Definition Position.h:97
float GetExactDist2d(const float x, const float y) const
Definition Position.h:117
float GetRelativeAngle(float x, float y) const
Definition Position.h:147
constexpr bool IsInDist2d(float x, float y, float dist) const
Definition Position.h:151
constexpr void GetPosition(float &x, float &y, float &z, float &o) const
Definition Position.h:94
float GetExactDist(float x, float y, float z) const
Definition Position.h:129
float GetExactDist(Position const &pos) const
Definition Position.h:130
constexpr float GetExactDistSq(Position const &pos) const
Definition Position.h:126
float ToAbsoluteAngle(float relAngle) const
Definition Position.h:144
constexpr float GetExactDist2dSq(Position const *pos) const
Definition Position.h:115
float m_positionX
Definition Position.h:64
float m_positionY
Definition Position.h:65
constexpr float GetExactDistSq(Position const *pos) const
Definition Position.h:127
float GetAbsoluteAngle(Position const &pos) const
Definition Position.h:142
constexpr bool IsInDist(Position const *pos, float dist) const
Definition Position.h:157
Streamer< PackedXYZ > PositionPackedXYZStream()
Definition Position.h:103
constexpr void Relocate(float x, float y, float z)
Definition Position.h:75
float GetExactDist(Position const *pos) const
Definition Position.h:131
float GetExactDist2d(Position const &pos) const
Definition Position.h:118
constexpr void Relocate(Position const *pos)
Definition Position.h:78
float GetAbsoluteAngle(float x, float y) const
Definition Position.h:136
Streamer< XYZ > PositionXYZStream()
Definition Position.h:99
constexpr bool IsInDist2d(Position const *pos, float dist) const
Definition Position.h:153
constexpr float GetExactDist2dSq(const float x, const float y) const
Definition Position.h:108
ConstStreamer< XYZ > PositionXYZStream() const
Definition Position.h:100
constexpr bool IsInDist(Position const &pos, float dist) const
Definition Position.h:156
constexpr void GetPosition(float &x, float &y) const
Definition Position.h:92
constexpr Position(float x, float y)
Definition Position.h:34
ConstStreamer< PackedXYZ > PositionPackedXYZStream() const
Definition Position.h:104
float GetRelativeAngle(Position const *pos) const
Definition Position.h:149
float GetExactDist2d(Position const *pos) const
Definition Position.h:119
ConstStreamer< XYZO > PositionXYZOStream() const
Definition Position.h:102
constexpr Position(float x, float y, float z, float o)
Definition Position.h:40
constexpr void Relocate(Position const &pos)
Definition Position.h:77
constexpr void Relocate(float x, float y)
Definition Position.h:74
float m_orientation
Definition Position.h:69
float GetAbsoluteAngle(Position const *pos) const
Definition Position.h:143
constexpr float GetExactDistSq(float x, float y, float z) const
Definition Position.h:121
constexpr Position GetPosition() const
Definition Position.h:95
constexpr bool IsInDist2d(Position const &pos, float dist) const
Definition Position.h:152
constexpr bool IsInDist(float x, float y, float z, float dist) const
Definition Position.h:155
float ToRelativeAngle(float absAngle) const
Definition Position.h:146
constexpr void GetPosition(float &x, float &y, float &z) const
Definition Position.h:93
constexpr float GetOrientation() const
Definition Position.h:90
constexpr float GetPositionZ() const
Definition Position.h:89
constexpr TaggedPosition(float x, float y, float z)
Definition Position.h:237
constexpr TaggedPosition(Position const &pos)
Definition Position.h:239
friend ByteBuffer & operator>>(ByteBuffer &buf, TaggedPosition &tagged)
Definition Position.h:252
friend ByteBuffer & operator<<(ByteBuffer &buf, TaggedPosition const &tagged)
Definition Position.h:251
friend bool operator==(TaggedPosition const &left, TaggedPosition const &right)=default
constexpr TaggedPosition(float x, float y)
Definition Position.h:236
constexpr TaggedPosition & operator=(Position const &pos)
Definition Position.h:241
constexpr TaggedPosition(float x, float y, float z, float o)
Definition Position.h:238
Position Pos
Definition Position.h:254
constexpr TaggedPosition()
Definition Position.h:235
auto format(Position const &position, FormatContext &ctx) const -> decltype(ctx.out())
auto format(TaggedPosition< Position::XYZ > const &position, FormatContext &ctx) const -> decltype(ctx.out())
auto format(TaggedPosition< Position::XY > const &position, FormatContext &ctx) const -> decltype(ctx.out())
auto format(WorldLocation const &worldLocation, FormatContext &ctx) const -> decltype(ctx.out())