vsg  1.1.0
VulkanSceneGraph library
vec4.h
1 #pragma once
2 
3 /* <editor-fold desc="MIT License">
4 
5 Copyright(c) 2018 Robert Osfield
6 
7 Permission 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 
9 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10 
11 THE 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 
29 namespace 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 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
t_vec2 template class that represents a 2D vector
Definition: vec2.h:38
t_vec3 template class that represents a 3D vector
Definition: vec3.h:34
t_vec4 template class that represents a 4D vector
Definition: vec4.h:35