1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "Prerequisites/BsPrerequisitesUtil.h"
6#include "Math/BsVector3.h"
7
8namespace bs
9{
10 /** @addtogroup Math
11 * @{
12 */
13
14 /** A four dimensional vector. */
15 class BS_UTILITY_EXPORT Vector4
16 {
17 public:
18 float x, y, z, w;
19
20 public:
21 Vector4() = default;
22
23 constexpr Vector4(BS_ZERO)
24 :x(0.0f), y(0.0f), z(0.0f), w(0.0f)
25 { }
26
27 constexpr Vector4(float x, float y, float z, float w)
28 :x(x), y(y), z(z), w(w)
29 { }
30
31 constexpr explicit Vector4(const Vector3& vec, float w = 0.0f)
32 :x(vec.x), y(vec.y), z(vec.z), w(w)
33 { }
34
35 /** Exchange the contents of this vector with another. */
36 void swap(Vector4& other)
37 {
38 std::swap(x, other.x);
39 std::swap(y, other.y);
40 std::swap(z, other.z);
41 std::swap(w, other.w);
42 }
43
44 float operator[] (UINT32 i) const
45 {
46 assert (i < 4);
47
48 return *(&x+i);
49 }
50
51 float& operator[] (UINT32 i)
52 {
53 assert(i < 4);
54
55 return *(&x+i);
56 }
57
58 /** Pointer accessor for direct copying. */
59 float* ptr()
60 {
61 return &x;
62 }
63
64 /** Pointer accessor for direct copying. */
65 const float* ptr() const
66 {
67 return &x;
68 }
69
70 Vector4& operator= (float rhs)
71 {
72 x = rhs;
73 y = rhs;
74 z = rhs;
75 w = rhs;
76
77 return *this;
78 }
79
80 bool operator== (const Vector4& rhs) const
81 {
82 return (x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w);
83 }
84
85 bool operator!= (const Vector4& rhs) const
86 {
87 return (x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w);
88 }
89
90 Vector4& operator= (const Vector3& rhs)
91 {
92 x = rhs.x;
93 y = rhs.y;
94 z = rhs.z;
95 w = 1.0f;
96
97 return *this;
98 }
99
100 Vector4 operator+ (const Vector4& rhs) const
101 {
102 return Vector4(x + rhs.x, y + rhs.y, z + rhs.z, w + rhs.w);
103 }
104
105 Vector4 operator- (const Vector4& rhs) const
106 {
107 return Vector4(x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w);
108 }
109
110 Vector4 operator* (float rhs) const
111 {
112 return Vector4(x * rhs, y * rhs, z * rhs, w * rhs);
113 }
114
115 Vector4 operator* (const Vector4& rhs) const
116 {
117 return Vector4(rhs.x * x, rhs.y * y, rhs.z * z, rhs.w * w);
118 }
119
120 Vector4 operator/ (float rhs) const
121 {
122 assert(rhs != 0.0f);
123
124 float inv = 1.0f / rhs;
125 return Vector4(x * inv, y * inv, z * inv, w * inv);
126 }
127
128 Vector4 operator/ (const Vector4& rhs) const
129 {
130 return Vector4(x / rhs.x, y / rhs.y, z / rhs.z, w / rhs.w);
131 }
132
133 const Vector4& operator+ () const
134 {
135 return *this;
136 }
137
138 Vector4 operator- () const
139 {
140 return Vector4(-x, -y, -z, -w);
141 }
142
143 friend Vector4 operator* (float lhs, const Vector4& rhs)
144 {
145 return Vector4(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z, lhs * rhs.w);
146 }
147
148 friend Vector4 operator/ (float lhs, const Vector4& rhs)
149 {
150 return Vector4(lhs / rhs.x, lhs / rhs.y, lhs / rhs.z, lhs / rhs.w);
151 }
152
153 friend Vector4 operator+ (const Vector4& lhs, float rhs)
154 {
155 return Vector4(lhs.x + rhs, lhs.y + rhs, lhs.z + rhs, lhs.w + rhs);
156 }
157
158 friend Vector4 operator+ (float lhs, const Vector4& rhs)
159 {
160 return Vector4(lhs + rhs.x, lhs + rhs.y, lhs + rhs.z, lhs + rhs.w);
161 }
162
163 friend Vector4 operator- (const Vector4& lhs, float rhs)
164 {
165 return Vector4(lhs.x - rhs, lhs.y - rhs, lhs.z - rhs, lhs.w - rhs);
166 }
167
168 friend Vector4 operator- (float lhs, Vector4& rhs)
169 {
170 return Vector4(lhs - rhs.x, lhs - rhs.y, lhs - rhs.z, lhs - rhs.w);
171 }
172
173 Vector4& operator+= (const Vector4& rhs)
174 {
175 x += rhs.x;
176 y += rhs.y;
177 z += rhs.z;
178 w += rhs.w;
179
180 return *this;
181 }
182
183 Vector4& operator-= (const Vector4& rhs)
184 {
185 x -= rhs.x;
186 y -= rhs.y;
187 z -= rhs.z;
188 w -= rhs.w;
189
190 return *this;
191 }
192
193 Vector4& operator*= (float rhs)
194 {
195 x *= rhs;
196 y *= rhs;
197 z *= rhs;
198 w *= rhs;
199
200 return *this;
201 }
202
203 Vector4& operator+= (float rhs)
204 {
205 x += rhs;
206 y += rhs;
207 z += rhs;
208 w += rhs;
209
210 return *this;
211 }
212
213 Vector4& operator-= (float rhs)
214 {
215 x -= rhs;
216 y -= rhs;
217 z -= rhs;
218 w -= rhs;
219
220 return *this;
221 }
222
223 Vector4& operator*= (Vector4& rhs)
224 {
225 x *= rhs.x;
226 y *= rhs.y;
227 z *= rhs.z;
228 w *= rhs.w;
229
230 return *this;
231 }
232
233 Vector4& operator/= (float rhs)
234 {
235 assert(rhs != 0.0f);
236
237 float inv = 1.0f / rhs;
238
239 x *= inv;
240 y *= inv;
241 z *= inv;
242 w *= inv;
243
244 return *this;
245 }
246
247 Vector4& operator/= (const Vector4& rhs)
248 {
249 x /= rhs.x;
250 y /= rhs.y;
251 z /= rhs.z;
252 w /= rhs.w;
253
254 return *this;
255 }
256
257 /** Calculates the dot (scalar) product of this vector with another. */
258 float dot(const Vector4& vec) const
259 {
260 return x * vec.x + y * vec.y + z * vec.z + w * vec.w;
261 }
262
263 /** Checks are any of the vector components NaN. */
264 inline bool isNaN() const;
265
266 static const Vector4 ZERO;
267 };
268
269 /** @} */
270
271 /** @cond SPECIALIZATIONS */
272 BS_ALLOW_MEMCPY_SERIALIZATION(Vector4);
273 /** @endcond */
274}
275
276