vsg: include/vsg/maths/vec4.h Source File

vsg 1.1.13 VulkanSceneGraph library

Loading...
Searching...
No Matches
vec4.h
1#pragma once
2
3/* <editor-fold desc="MIT License">
4
5Copyright(c) 2018 Robert Osfield
6
7Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
9The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
11THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12
13</editor-fold> */
14
15// we can't implement the anonymous union/structs combination without causing warnings, so disable them for just this header
16#if defined(__GNUC__)
17# pragma GCC diagnostic push
18# pragma GCC diagnostic ignored "-Wpedantic"
19#endif
20#if defined(__clang__)
21# pragma clang diagnostic push
22# pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
23# pragma clang diagnostic ignored "-Wnested-anon-types"
24#endif
25
26#include <vsg/maths/vec3.h>
27#include <vsg/vk/vulkan.h>
28
29namespace vsg
30{
31
33 template<typename T>
34 struct t_vec4
35 {
36 using value_type = T;
37
38 union
39 {
40 value_type value[4];
41 struct
42 {
43 value_type x, y, z, w;
44 };
45 struct
46 {
47 value_type r, g, b, a;
48 };
49 struct
50 {
51 value_type s, t, p, q;
52 };
53 t_vec3<T> xyz;
54 t_vec3<T> rgb;
55 };
56
57 constexpr t_vec4() :
58 value{} {}
59 constexpr t_vec4(const t_vec4& v) :
60 value{v.x, v.y, v.z, v.w} {}
61 constexpr t_vec4& operator=(const t_vec4&) = default;
62
63 constexpr t_vec4(value_type in_x, value_type in_y, value_type in_z, value_type in_w) :
64 value{in_x, in_y, in_z, in_w} {}
65
66 constexpr explicit t_vec4(const VkClearColorValue& v) :
67 value{static_cast<value_type>(v.float32[0]), static_cast<value_type>(v.float32[1]), static_cast<value_type>(v.float32[2]), static_cast<value_type>(v.float32[3])} {}
68
69 template<typename R>
70 constexpr explicit t_vec4(const t_vec4<R>& v) :
71 value{static_cast<T>(v.x), static_cast<T>(v.y), static_cast<T>(v.z), static_cast<T>(v.w)} {}
72
73 template<typename R>
74 constexpr t_vec4(const t_vec2<R>& v, value_type in_z, value_type in_w) :
75 value{static_cast<T>(v.x), static_cast<T>(v.y), in_z, in_w} {}
76
77 template<typename R>
78 constexpr t_vec4(const t_vec3<R>& v, value_type in_w) :
79 value{static_cast<T>(v.x), static_cast<T>(v.y), static_cast<T>(v.z), in_w} {}
80
81 constexpr std::size_t size() const { return 4; }
82
83 value_type& operator[](std::size_t i) { return value[i]; }
84 value_type operator[](std::size_t i) const { return value[i]; }
85
86 template<typename R>
87 t_vec4& operator=(const t_vec4<R>& rhs)
88 {
89 value[0] = static_cast<value_type>(rhs[0]);
90 value[1] = static_cast<value_type>(rhs[1]);
91 value[2] = static_cast<value_type>(rhs[2]);
92 value[3] = static_cast<value_type>(rhs[3]);
93 return *this;
94 }
95
96 t_vec4& operator=(const VkClearColorValue& v)
97 {
98 value[0] = static_cast<value_type>(v.float32[0]);
99 value[1] = static_cast<value_type>(v.float32[1]);
100 value[2] = static_cast<value_type>(v.float32[2]);
101 value[3] = static_cast<value_type>(v.float32[3]);
102 return *this;
103 }
104
105 T* data() { return value; }
106 const T* data() const { return value; }
107
108 void set(value_type in_x, value_type in_y, value_type in_z, value_type in_w)
109 {
110 x = in_x;
111 y = in_y;
112 z = in_z;
113 w = in_w;
114 }
115
116 inline t_vec4& operator+=(const t_vec4& rhs)
117 {
118 value[0] += rhs.value[0];
119 value[1] += rhs.value[1];
120 value[2] += rhs.value[2];
121 value[3] += rhs.value[3];
122 return *this;
123 }
124
125 inline t_vec4& operator-=(const t_vec4& rhs)
126 {
127 value[0] -= rhs.value[0];
128 value[1] -= rhs.value[1];
129 value[2] -= rhs.value[2];
130 value[3] -= rhs.value[3];
131 return *this;
132 }
133
134 inline t_vec4& operator*=(value_type rhs)
135 {
136 value[0] *= rhs;
137 value[1] *= rhs;
138 value[2] *= rhs;
139 value[3] *= rhs;
140 return *this;
141 }
142
143 inline t_vec4& operator*=(const t_vec4& rhs)
144 {
145 value[0] *= rhs.value[0];
146 value[1] *= rhs.value[1];
147 value[2] *= rhs.value[2];
148 value[3] *= rhs.value[3];
149 return *this;
150 }
151
152 friend constexpr t_vec4<T> operator*(const t_vec4<T>& lhs, T rhs)
153 {
154 return t_vec4<T>(lhs[0] * rhs, lhs[1] * rhs, lhs[2] * rhs, lhs[3] * rhs);
155 }
156
157 friend constexpr t_vec4<T> operator*(T lhs, const t_vec4<T>& rhs)
158 {
159 return t_vec4<T>(lhs * rhs[0], lhs * rhs[1], lhs * rhs[2], lhs * rhs[3]);
160 }
161
162 inline t_vec4& operator/=(value_type rhs)
163 {
164 if constexpr (std::is_floating_point_v<value_type>)
165 {
166 value_type inv = numbers<value_type>::one() / rhs;
167 value[0] *= inv;
168 value[1] *= inv;
169 value[2] *= inv;
170 value[3] *= inv;
171 }
172 else
173 {
174 value[0] /= rhs;
175 value[1] /= rhs;
176 value[2] /= rhs;
177 value[3] /= rhs;
178 }
179 return *this;
180 }
181
182 operator VkClearColorValue() const noexcept { return VkClearColorValue{{r, g, b, a}}; }
183
184 explicit operator bool() const noexcept { return value[0] != numbers<value_type>::zero() || value[1] != numbers<value_type>::zero() || value[2] != numbers<value_type>::zero() || value[3] != numbers<value_type>::zero(); }
185 };
186
187 using vec4 = t_vec4<float>; // float 4D vector
188 using dvec4 = t_vec4<double>; // double 4D vector
189 using ldvec4 = t_vec4<long double>; // long double 4D vector
190 using bvec4 = t_vec4<int8_t>; // signed 8 bit integer 4D vector
191 using svec4 = t_vec4<int16_t>; // signed 16 bit integer 4D vector
192 using ivec4 = t_vec4<int32_t>; // signed 32 bit integer 4D vector
193 using ubvec4 = t_vec4<uint8_t>; // unsigned 8 bit integer 4D vector
194 using usvec4 = t_vec4<uint16_t>; // unsigned 16 bit integer 4D vector
195 using uivec4 = t_vec4<uint32_t>; // unsigned 32 bit integer 4D vector
196
197 VSG_type_name(vsg::vec4);
198 VSG_type_name(vsg::dvec4);
199 VSG_type_name(vsg::ldvec4);
200 VSG_type_name(vsg::bvec4);
201 VSG_type_name(vsg::svec4);
202 VSG_type_name(vsg::ivec4);
203 VSG_type_name(vsg::ubvec4);
204 VSG_type_name(vsg::usvec4);
205 VSG_type_name(vsg::uivec4);
206
207 template<typename T>
208 constexpr bool operator==(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
209 {
210 return lhs[0] == rhs[0] && lhs[1] == rhs[1] && lhs[2] == rhs[2] && lhs[3] == rhs[3];
211 }
212
213 template<typename T>
214 constexpr bool operator!=(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
215 {
216 return lhs[0] != rhs[0] || lhs[1] != rhs[1] || lhs[2] != rhs[2] || lhs[3] != rhs[3];
217 }
218
219 template<typename T>
220 constexpr bool operator<(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
221 {
222 if (lhs[0] < rhs[0]) return true;
223 if (lhs[0] > rhs[0]) return false;
224 if (lhs[1] < rhs[1]) return true;
225 if (lhs[1] > rhs[1]) return false;
226 if (lhs[2] < rhs[2]) return true;
227 if (lhs[2] > rhs[2]) return false;
228 return lhs[3] < rhs[3];
229 }
230
231 template<typename T>
232 constexpr t_vec4<T> operator-(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
233 {
234 return t_vec4<T>(lhs[0] - rhs[0], lhs[1] - rhs[1], lhs[2] - rhs[2], lhs[3] - rhs[3]);
235 }
236
237 template<typename T>
238 constexpr t_vec4<T> operator-(const t_vec4<T>& v)
239 {
240 return t_vec4<T>(-v[0], -v[1], -v[2], -v[3]);
241 }
242
243 template<typename T>
244 constexpr t_vec4<T> operator+(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
245 {
246 return t_vec4<T>(lhs[0] + rhs[0], lhs[1] + rhs[1], lhs[2] + rhs[2], lhs[3] + rhs[3]);
247 }
248
249 template<typename T>
250 constexpr t_vec4<T> operator*(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
251 {
252 return t_vec4<T>(lhs[0] * rhs[0], lhs[1] * rhs[1], lhs[2] * rhs[2], lhs[3] * rhs[3]);
253 }
254
255 template<typename T>
256 constexpr t_vec4<T> operator/(const t_vec4<T>& lhs, T rhs)
257 {
258 if constexpr (std::is_floating_point_v<T>)
259 {
260 T inv = numbers<T>::one() / rhs;
261 return t_vec4<T>(lhs[0] * inv, lhs[1] * inv, lhs[2] * inv, lhs[3] * inv);
262 }
263 else
264 {
265 return t_vec4<T>(lhs[0] / rhs, lhs[1] / rhs, lhs[2] / rhs, lhs[3] / rhs);
266 }
267 }
268
269 template<typename T>
270 constexpr T length(const t_vec4<T>& v)
271 {
272 return std::sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]);
273 }
274
275 template<typename T>
276 constexpr T length2(const t_vec4<T>& v)
277 {
278 return v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3];
279 }
280
281 template<typename T>
282 constexpr t_vec4<T> normalize(const t_vec4<T>& v)
283 {
284 return v / length(v);
285 }
286
287 template<typename T>
288 constexpr t_vec4<T> mix(const t_vec4<T>& start, const t_vec4<T>& end, T r)
289 {
290 T one_minus_r = numbers<T>::one() - r;
291 return t_vec4<T>(start[0] * one_minus_r + end[0] * r,
292 start[1] * one_minus_r + end[1] * r,
293 start[2] * one_minus_r + end[2] * r,
294 start[3] * one_minus_r + end[3] * r);
295 }
296
297} // namespace vsg
298
299#if defined(__clang__)
300# pragma clang diagnostic pop
301#endif
302#if defined(__GNUC__)
303# pragma GCC diagnostic pop
304#endif
vsg::t_vec2
t_vec2 template class that represents a 2D vector
Definition vec2.h:39
vsg::t_vec3
t_vec3 template class that represents a 3D vector
Definition vec3.h:34
vsg::t_vec4
t_vec4 template class that represents a 4D vector
Definition vec4.h:35