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

vsg 1.1.3 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 };
55
56 constexpr t_vec4() :
57 value{} {}
58 constexpr t_vec4(const t_vec4& v) :
59 value{v.x, v.y, v.z, v.w} {}
60 constexpr t_vec4& operator=(const t_vec4&) = default;
61
62 constexpr t_vec4(value_type in_x, value_type in_y, value_type in_z, value_type in_w) :
63 value{in_x, in_y, in_z, in_w} {}
64
65 constexpr explicit t_vec4(const VkClearColorValue& v) :
66 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])} {}
67
68 template<typename R>
69 constexpr explicit t_vec4(const t_vec4<R>& v) :
70 value{static_cast<T>(v.x), static_cast<T>(v.y), static_cast<T>(v.z), static_cast<T>(v.w)} {}
71
72 template<typename R>
73 constexpr t_vec4(const t_vec2<R>& v, value_type in_z, value_type in_w) :
74 value{static_cast<T>(v.x), static_cast<T>(v.y), in_z, in_w} {}
75
76 template<typename R>
77 constexpr t_vec4(const t_vec3<R>& v, value_type in_w) :
78 value{static_cast<T>(v.x), static_cast<T>(v.y), static_cast<T>(v.z), in_w} {}
79
80 constexpr std::size_t size() const { return 4; }
81
82 value_type& operator[](std::size_t i) { return value[i]; }
83 value_type operator[](std::size_t i) const { return value[i]; }
84
85 template<typename R>
86 t_vec4& operator=(const t_vec4<R>& rhs)
87 {
88 value[0] = static_cast<value_type>(rhs[0]);
89 value[1] = static_cast<value_type>(rhs[1]);
90 value[2] = static_cast<value_type>(rhs[2]);
91 value[3] = static_cast<value_type>(rhs[3]);
92 return *this;
93 }
94
95 t_vec4& operator=(const VkClearColorValue& v)
96 {
97 value[0] = static_cast<value_type>(v.float32[0]);
98 value[1] = static_cast<value_type>(v.float32[1]);
99 value[2] = static_cast<value_type>(v.float32[2]);
100 value[3] = static_cast<value_type>(v.float32[3]);
101 return *this;
102 }
103
104 T* data() { return value; }
105 const T* data() const { return value; }
106
107 void set(value_type in_x, value_type in_y, value_type in_z, value_type in_w)
108 {
109 x = in_x;
110 y = in_y;
111 z = in_z;
112 w = in_w;
113 }
114
115 inline t_vec4& operator+=(const t_vec4& rhs)
116 {
117 value[0] += rhs.value[0];
118 value[1] += rhs.value[1];
119 value[2] += rhs.value[2];
120 value[3] += rhs.value[3];
121 return *this;
122 }
123
124 inline t_vec4& operator-=(const t_vec4& rhs)
125 {
126 value[0] -= rhs.value[0];
127 value[1] -= rhs.value[1];
128 value[2] -= rhs.value[2];
129 value[3] -= rhs.value[3];
130 return *this;
131 }
132
133 inline t_vec4& operator*=(value_type rhs)
134 {
135 value[0] *= rhs;
136 value[1] *= rhs;
137 value[2] *= rhs;
138 value[3] *= rhs;
139 return *this;
140 }
141
142 inline t_vec4& operator*=(const t_vec4& rhs)
143 {
144 value[0] *= rhs.value[0];
145 value[1] *= rhs.value[1];
146 value[2] *= rhs.value[2];
147 value[3] *= rhs.value[3];
148 return *this;
149 }
150
151 inline t_vec4& operator/=(value_type rhs)
152 {
153 if constexpr (std::is_floating_point_v<value_type>)
154 {
155 value_type inv = static_cast<value_type>(1.0) / rhs;
156 value[0] *= inv;
157 value[1] *= inv;
158 value[2] *= inv;
159 value[3] *= inv;
160 }
161 else
162 {
163 value[0] /= rhs;
164 value[1] /= rhs;
165 value[2] /= rhs;
166 value[3] /= rhs;
167 }
168 return *this;
169 }
170
171 operator VkClearColorValue() const noexcept { return VkClearColorValue{{r, g, b, a}}; }
172
173 explicit operator bool() const noexcept { return value[0] != 0.0 || value[1] != 0.0 || value[2] != 0.0 || value[3] != 0.0; }
174 };
175
176 using vec4 = t_vec4<float>; // float 4D vector
177 using dvec4 = t_vec4<double>; // double 4D vector
178 using bvec4 = t_vec4<int8_t>; // signed 8 bit integer 4D vector
179 using svec4 = t_vec4<int16_t>; // signed 16 bit integer 4D vector
180 using ivec4 = t_vec4<int32_t>; // signed 32 bit integer 4D vector
181 using ubvec4 = t_vec4<uint8_t>; // unsigned 8 bit integer 4D vector
182 using usvec4 = t_vec4<uint16_t>; // unsigned 16 bit integer 4D vector
183 using uivec4 = t_vec4<uint32_t>; // unsigned 32 bit integer 4D vector
184
185 VSG_type_name(vsg::vec4);
186 VSG_type_name(vsg::dvec4);
187 VSG_type_name(vsg::bvec4);
188 VSG_type_name(vsg::svec4);
189 VSG_type_name(vsg::ivec4);
190 VSG_type_name(vsg::ubvec4);
191 VSG_type_name(vsg::usvec4);
192 VSG_type_name(vsg::uivec4);
193
194 template<typename T>
195 constexpr bool operator==(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
196 {
197 return lhs[0] == rhs[0] && lhs[1] == rhs[1] && lhs[2] == rhs[2] && lhs[3] == rhs[3];
198 }
199
200 template<typename T>
201 constexpr bool operator!=(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
202 {
203 return lhs[0] != rhs[0] || lhs[1] != rhs[1] || lhs[2] != rhs[2] || lhs[3] != rhs[3];
204 }
205
206 template<typename T>
207 constexpr bool operator<(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
208 {
209 if (lhs[0] < rhs[0]) return true;
210 if (lhs[0] > rhs[0]) return false;
211 if (lhs[1] < rhs[1]) return true;
212 if (lhs[1] > rhs[1]) return false;
213 if (lhs[2] < rhs[2]) return true;
214 if (lhs[2] > rhs[2]) return false;
215 return lhs[3] < rhs[3];
216 }
217
218 template<typename T>
219 constexpr t_vec4<T> operator-(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
220 {
221 return t_vec4<T>(lhs[0] - rhs[0], lhs[1] - rhs[1], lhs[2] - rhs[2], lhs[3] - rhs[3]);
222 }
223
224 template<typename T>
225 constexpr t_vec4<T> operator-(const t_vec4<T>& v)
226 {
227 return t_vec4<T>(-v[0], -v[1], -v[2], -v[3]);
228 }
229
230 template<typename T>
231 constexpr t_vec4<T> operator+(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
232 {
233 return t_vec4<T>(lhs[0] + rhs[0], lhs[1] + rhs[1], lhs[2] + rhs[2], lhs[3] + rhs[3]);
234 }
235
236 template<typename T>
237 constexpr t_vec4<T> operator*(const t_vec4<T>& lhs, T rhs)
238 {
239 return t_vec4<T>(lhs[0] * rhs, lhs[1] * rhs, lhs[2] * rhs, lhs[3] * rhs);
240 }
241
242 template<typename T>
243 constexpr t_vec4<T> operator*(const t_vec4<T>& lhs, const t_vec4<T>& rhs)
244 {
245 return t_vec4<T>(lhs[0] * rhs[0], lhs[1] * rhs[1], lhs[2] * rhs[2], lhs[3] * rhs[3]);
246 }
247
248 template<typename T>
249 constexpr t_vec4<T> operator/(const t_vec4<T>& lhs, T rhs)
250 {
251 if constexpr (std::is_floating_point_v<T>)
252 {
253 T inv = static_cast<T>(1.0) / rhs;
254 return t_vec4<T>(lhs[0] * inv, lhs[1] * inv, lhs[2] * inv, lhs[3] * inv);
255 }
256 else
257 {
258 return t_vec4<T>(lhs[0] / rhs, lhs[1] / rhs, lhs[2] / rhs, lhs[3] / rhs);
259 }
260 }
261
262 template<typename T>
263 constexpr T length(const t_vec4<T>& v)
264 {
265 return std::sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]);
266 }
267
268 template<typename T>
269 constexpr T length2(const t_vec4<T>& v)
270 {
271 return v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3];
272 }
273
274 template<typename T>
275 constexpr t_vec4<T> normalize(const t_vec4<T>& v)
276 {
277 return v / length(v);
278 }
279
280 template<typename T>
281 constexpr t_vec4<T> mix(const t_vec4<T>& start, const t_vec4<T>& end, T r)
282 {
283 T one_minus_r = 1 - r;
284 return t_vec4<T>(start[0] * one_minus_r + end[0] * r,
285 start[1] * one_minus_r + end[1] * r,
286 start[2] * one_minus_r + end[2] * r,
287 start[3] * one_minus_r + end[3] * r);
288 }
289
290} // namespace vsg
291
292#if defined(__clang__)
293# pragma clang diagnostic pop
294#endif
295#if defined(__GNUC__)
296# pragma GCC diagnostic pop
297#endif
vsg::allocator_affinity_nodes
std container adapter for allocating with MEMORY_AFFINITY_NODES
Definition Allocator.h:138
vsg::t_vec4
t_vec4 template class that represents a 4D vector
Definition vec4.h:35