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

vsg 1.1.9 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 inline t_vec4& operator/=(value_type rhs)
153 {
154 if constexpr (std::is_floating_point_v<value_type>)
155 {
156 value_type inv = static_cast<value_type>(1.0) / rhs;
157 value[0] *= inv;
158 value[1] *= inv;
159 value[2] *= inv;
160 value[3] *= inv;
161 }
162 else
163 {
164 value[0] /= rhs;
165 value[1] /= rhs;
166 value[2] /= rhs;
167 value[3] /= rhs;
168 }
169 return *this;
170 }
171
172 operator VkClearColorValue() const noexcept { return VkClearColorValue{{r, g, b, a}}; }
173
174 explicit operator bool() const noexcept { return value[0] != 0.0 || value[1] != 0.0 || value[2] != 0.0 || value[3] != 0.0; }
175 };
176
177 using vec4 = t_vec4<float>; // float 4D vector
178 using dvec4 = t_vec4<double>; // double 4D vector
179 using ldvec4 = t_vec4<long double>; // long double 4D vector
180 using bvec4 = t_vec4<int8_t>; // signed 8 bit integer 4D vector
181 using svec4 = t_vec4<int16_t>; // signed 16 bit integer 4D vector
182 using ivec4 = t_vec4<int32_t>; // signed 32 bit integer 4D vector
183 using ubvec4 = t_vec4<uint8_t>; // unsigned 8 bit integer 4D vector
184 using usvec4 = t_vec4<uint16_t>; // unsigned 16 bit integer 4D vector
185 using uivec4 = t_vec4<uint32_t>; // unsigned 32 bit integer 4D vector
186
187 VSG_type_name(vsg::vec4);
188 VSG_type_name(vsg::dvec4);
189 VSG_type_name(vsg::ldvec4);
190 VSG_type_name(vsg::bvec4);
191 VSG_type_name(vsg::svec4);
192 VSG_type_name(vsg::ivec4);
193 VSG_type_name(vsg::ubvec4);
194 VSG_type_name(vsg::usvec4);
195 VSG_type_name(vsg::uivec4);
196
197 template<typename T>
198 constexpr bool operator==(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
199 {
200 return lhs[0] == rhs[0] && lhs[1] == rhs[1] && lhs[2] == rhs[2] && lhs[3] == rhs[3];
201 }
202
203 template<typename T>
204 constexpr bool operator!=(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
205 {
206 return lhs[0] != rhs[0] || lhs[1] != rhs[1] || lhs[2] != rhs[2] || lhs[3] != rhs[3];
207 }
208
209 template<typename T>
210 constexpr bool operator<(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
211 {
212 if (lhs[0] < rhs[0]) return true;
213 if (lhs[0] > rhs[0]) return false;
214 if (lhs[1] < rhs[1]) return true;
215 if (lhs[1] > rhs[1]) return false;
216 if (lhs[2] < rhs[2]) return true;
217 if (lhs[2] > rhs[2]) return false;
218 return lhs[3] < rhs[3];
219 }
220
221 template<typename T>
222 constexpr t_vec4<T> operator-(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
223 {
224 return t_vec4<T>(lhs[0] - rhs[0], lhs[1] - rhs[1], lhs[2] - rhs[2], lhs[3] - rhs[3]);
225 }
226
227 template<typename T>
228 constexpr t_vec4<T> operator-(const t_vec4<T>& v)
229 {
230 return t_vec4<T>(-v[0], -v[1], -v[2], -v[3]);
231 }
232
233 template<typename T>
234 constexpr t_vec4<T> operator+(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
235 {
236 return t_vec4<T>(lhs[0] + rhs[0], lhs[1] + rhs[1], lhs[2] + rhs[2], lhs[3] + rhs[3]);
237 }
238
239 template<typename T>
240 constexpr t_vec4<T> operator*(const t_vec4<T>& lhs, T rhs)
241 {
242 return t_vec4<T>(lhs[0] * rhs, lhs[1] * rhs, lhs[2] * rhs, lhs[3] * rhs);
243 }
244
245 template<typename T>
246 constexpr t_vec4<T> operator*(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
247 {
248 return t_vec4<T>(lhs[0] * rhs[0], lhs[1] * rhs[1], lhs[2] * rhs[2], lhs[3] * rhs[3]);
249 }
250
251 template<typename T>
252 constexpr t_vec4<T> operator/(const t_vec4<T>& lhs, T rhs)
253 {
254 if constexpr (std::is_floating_point_v<T>)
255 {
256 T inv = static_cast<T>(1.0) / rhs;
257 return t_vec4<T>(lhs[0] * inv, lhs[1] * inv, lhs[2] * inv, lhs[3] * inv);
258 }
259 else
260 {
261 return t_vec4<T>(lhs[0] / rhs, lhs[1] / rhs, lhs[2] / rhs, lhs[3] / rhs);
262 }
263 }
264
265 template<typename T>
266 constexpr T length(const t_vec4<T>& v)
267 {
268 return std::sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]);
269 }
270
271 template<typename T>
272 constexpr T length2(const t_vec4<T>& v)
273 {
274 return v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3];
275 }
276
277 template<typename T>
278 constexpr t_vec4<T> normalize(const t_vec4<T>& v)
279 {
280 return v / length(v);
281 }
282
283 template<typename T>
284 constexpr t_vec4<T> mix(const t_vec4<T>& start, const t_vec4<T>& end, T r)
285 {
286 T one_minus_r = 1 - r;
287 return t_vec4<T>(start[0] * one_minus_r + end[0] * r,
288 start[1] * one_minus_r + end[1] * r,
289 start[2] * one_minus_r + end[2] * r,
290 start[3] * one_minus_r + end[3] * r);
291 }
292
293} // namespace vsg
294
295#if defined(__clang__)
296# pragma clang diagnostic pop
297#endif
298#if defined(__GNUC__)
299# pragma GCC diagnostic pop
300#endif
vsg::t_vec2
t_vec2 template class that represents a 2D vector
Definition vec2.h:38
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