1/**************************************************************************/
2/* vector3i.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#ifndef VECTOR3I_H
32#define VECTOR3I_H
33
34#include "core/error/error_macros.h"
35#include "core/math/math_funcs.h"
36
37class String;
38struct Vector3;
39
40struct _NO_DISCARD_ Vector3i {
41 static const int AXIS_COUNT = 3;
42
43 enum Axis {
44 AXIS_X,
45 AXIS_Y,
46 AXIS_Z,
47 };
48
49 union {
50 struct {
51 int32_t x;
52 int32_t y;
53 int32_t z;
54 };
55
56 int32_t coord[3] = { 0 };
57 };
58
59 _FORCE_INLINE_ const int32_t &operator[](const int p_axis) const {
60 DEV_ASSERT((unsigned int)p_axis < 3);
61 return coord[p_axis];
62 }
63
64 _FORCE_INLINE_ int32_t &operator[](const int p_axis) {
65 DEV_ASSERT((unsigned int)p_axis < 3);
66 return coord[p_axis];
67 }
68
69 Vector3i::Axis min_axis_index() const;
70 Vector3i::Axis max_axis_index() const;
71
72 Vector3i min(const Vector3i &p_vector3i) const {
73 return Vector3i(MIN(x, p_vector3i.x), MIN(y, p_vector3i.y), MIN(z, p_vector3i.z));
74 }
75
76 Vector3i max(const Vector3i &p_vector3i) const {
77 return Vector3i(MAX(x, p_vector3i.x), MAX(y, p_vector3i.y), MAX(z, p_vector3i.z));
78 }
79
80 _FORCE_INLINE_ int64_t length_squared() const;
81 _FORCE_INLINE_ double length() const;
82
83 _FORCE_INLINE_ void zero();
84
85 _FORCE_INLINE_ Vector3i abs() const;
86 _FORCE_INLINE_ Vector3i sign() const;
87 Vector3i clamp(const Vector3i &p_min, const Vector3i &p_max) const;
88 Vector3i snapped(const Vector3i &p_step) const;
89
90 /* Operators */
91
92 _FORCE_INLINE_ Vector3i &operator+=(const Vector3i &p_v);
93 _FORCE_INLINE_ Vector3i operator+(const Vector3i &p_v) const;
94 _FORCE_INLINE_ Vector3i &operator-=(const Vector3i &p_v);
95 _FORCE_INLINE_ Vector3i operator-(const Vector3i &p_v) const;
96 _FORCE_INLINE_ Vector3i &operator*=(const Vector3i &p_v);
97 _FORCE_INLINE_ Vector3i operator*(const Vector3i &p_v) const;
98 _FORCE_INLINE_ Vector3i &operator/=(const Vector3i &p_v);
99 _FORCE_INLINE_ Vector3i operator/(const Vector3i &p_v) const;
100 _FORCE_INLINE_ Vector3i &operator%=(const Vector3i &p_v);
101 _FORCE_INLINE_ Vector3i operator%(const Vector3i &p_v) const;
102
103 _FORCE_INLINE_ Vector3i &operator*=(const int32_t p_scalar);
104 _FORCE_INLINE_ Vector3i operator*(const int32_t p_scalar) const;
105 _FORCE_INLINE_ Vector3i &operator/=(const int32_t p_scalar);
106 _FORCE_INLINE_ Vector3i operator/(const int32_t p_scalar) const;
107 _FORCE_INLINE_ Vector3i &operator%=(const int32_t p_scalar);
108 _FORCE_INLINE_ Vector3i operator%(const int32_t p_scalar) const;
109
110 _FORCE_INLINE_ Vector3i operator-() const;
111
112 _FORCE_INLINE_ bool operator==(const Vector3i &p_v) const;
113 _FORCE_INLINE_ bool operator!=(const Vector3i &p_v) const;
114 _FORCE_INLINE_ bool operator<(const Vector3i &p_v) const;
115 _FORCE_INLINE_ bool operator<=(const Vector3i &p_v) const;
116 _FORCE_INLINE_ bool operator>(const Vector3i &p_v) const;
117 _FORCE_INLINE_ bool operator>=(const Vector3i &p_v) const;
118
119 operator String() const;
120 operator Vector3() const;
121
122 _FORCE_INLINE_ Vector3i() {}
123 _FORCE_INLINE_ Vector3i(const int32_t p_x, const int32_t p_y, const int32_t p_z) {
124 x = p_x;
125 y = p_y;
126 z = p_z;
127 }
128};
129
130int64_t Vector3i::length_squared() const {
131 return x * (int64_t)x + y * (int64_t)y + z * (int64_t)z;
132}
133
134double Vector3i::length() const {
135 return Math::sqrt((double)length_squared());
136}
137
138Vector3i Vector3i::abs() const {
139 return Vector3i(Math::abs(x), Math::abs(y), Math::abs(z));
140}
141
142Vector3i Vector3i::sign() const {
143 return Vector3i(SIGN(x), SIGN(y), SIGN(z));
144}
145
146/* Operators */
147
148Vector3i &Vector3i::operator+=(const Vector3i &p_v) {
149 x += p_v.x;
150 y += p_v.y;
151 z += p_v.z;
152 return *this;
153}
154
155Vector3i Vector3i::operator+(const Vector3i &p_v) const {
156 return Vector3i(x + p_v.x, y + p_v.y, z + p_v.z);
157}
158
159Vector3i &Vector3i::operator-=(const Vector3i &p_v) {
160 x -= p_v.x;
161 y -= p_v.y;
162 z -= p_v.z;
163 return *this;
164}
165
166Vector3i Vector3i::operator-(const Vector3i &p_v) const {
167 return Vector3i(x - p_v.x, y - p_v.y, z - p_v.z);
168}
169
170Vector3i &Vector3i::operator*=(const Vector3i &p_v) {
171 x *= p_v.x;
172 y *= p_v.y;
173 z *= p_v.z;
174 return *this;
175}
176
177Vector3i Vector3i::operator*(const Vector3i &p_v) const {
178 return Vector3i(x * p_v.x, y * p_v.y, z * p_v.z);
179}
180
181Vector3i &Vector3i::operator/=(const Vector3i &p_v) {
182 x /= p_v.x;
183 y /= p_v.y;
184 z /= p_v.z;
185 return *this;
186}
187
188Vector3i Vector3i::operator/(const Vector3i &p_v) const {
189 return Vector3i(x / p_v.x, y / p_v.y, z / p_v.z);
190}
191
192Vector3i &Vector3i::operator%=(const Vector3i &p_v) {
193 x %= p_v.x;
194 y %= p_v.y;
195 z %= p_v.z;
196 return *this;
197}
198
199Vector3i Vector3i::operator%(const Vector3i &p_v) const {
200 return Vector3i(x % p_v.x, y % p_v.y, z % p_v.z);
201}
202
203Vector3i &Vector3i::operator*=(const int32_t p_scalar) {
204 x *= p_scalar;
205 y *= p_scalar;
206 z *= p_scalar;
207 return *this;
208}
209
210Vector3i Vector3i::operator*(const int32_t p_scalar) const {
211 return Vector3i(x * p_scalar, y * p_scalar, z * p_scalar);
212}
213
214// Multiplication operators required to workaround issues with LLVM using implicit conversion.
215
216_FORCE_INLINE_ Vector3i operator*(const int32_t p_scalar, const Vector3i &p_vector) {
217 return p_vector * p_scalar;
218}
219
220_FORCE_INLINE_ Vector3i operator*(const int64_t p_scalar, const Vector3i &p_vector) {
221 return p_vector * p_scalar;
222}
223
224_FORCE_INLINE_ Vector3i operator*(const float p_scalar, const Vector3i &p_vector) {
225 return p_vector * p_scalar;
226}
227
228_FORCE_INLINE_ Vector3i operator*(const double p_scalar, const Vector3i &p_vector) {
229 return p_vector * p_scalar;
230}
231
232Vector3i &Vector3i::operator/=(const int32_t p_scalar) {
233 x /= p_scalar;
234 y /= p_scalar;
235 z /= p_scalar;
236 return *this;
237}
238
239Vector3i Vector3i::operator/(const int32_t p_scalar) const {
240 return Vector3i(x / p_scalar, y / p_scalar, z / p_scalar);
241}
242
243Vector3i &Vector3i::operator%=(const int32_t p_scalar) {
244 x %= p_scalar;
245 y %= p_scalar;
246 z %= p_scalar;
247 return *this;
248}
249
250Vector3i Vector3i::operator%(const int32_t p_scalar) const {
251 return Vector3i(x % p_scalar, y % p_scalar, z % p_scalar);
252}
253
254Vector3i Vector3i::operator-() const {
255 return Vector3i(-x, -y, -z);
256}
257
258bool Vector3i::operator==(const Vector3i &p_v) const {
259 return (x == p_v.x && y == p_v.y && z == p_v.z);
260}
261
262bool Vector3i::operator!=(const Vector3i &p_v) const {
263 return (x != p_v.x || y != p_v.y || z != p_v.z);
264}
265
266bool Vector3i::operator<(const Vector3i &p_v) const {
267 if (x == p_v.x) {
268 if (y == p_v.y) {
269 return z < p_v.z;
270 } else {
271 return y < p_v.y;
272 }
273 } else {
274 return x < p_v.x;
275 }
276}
277
278bool Vector3i::operator>(const Vector3i &p_v) const {
279 if (x == p_v.x) {
280 if (y == p_v.y) {
281 return z > p_v.z;
282 } else {
283 return y > p_v.y;
284 }
285 } else {
286 return x > p_v.x;
287 }
288}
289
290bool Vector3i::operator<=(const Vector3i &p_v) const {
291 if (x == p_v.x) {
292 if (y == p_v.y) {
293 return z <= p_v.z;
294 } else {
295 return y < p_v.y;
296 }
297 } else {
298 return x < p_v.x;
299 }
300}
301
302bool Vector3i::operator>=(const Vector3i &p_v) const {
303 if (x == p_v.x) {
304 if (y == p_v.y) {
305 return z >= p_v.z;
306 } else {
307 return y > p_v.y;
308 }
309 } else {
310 return x > p_v.x;
311 }
312}
313
314void Vector3i::zero() {
315 x = y = z = 0;
316}
317
318#endif // VECTOR3I_H
319