CGVIS Utils
Loading...
Searching...
No Matches
Vec3.h
Go to the documentation of this file.
1#pragma once
2
3#include <ostream>
4#include <sstream>
5#include <string>
6#include <array>
7#include <cmath>
8#include <optional>
9
10#include "Rand.h"
11#include "Vec2.h"
12
27
28template <typename T>
29union Vec3t {
30public:
32 std::array<T, 3> e;
33 struct { T x; T y; T z; };
34 struct { T r; T g; T b; };
36
39 e{0,0,0}
40 {}
41
48 Vec3t(T x, T y, T z) :
49 e{x,y,z}
50 {}
51
56 Vec3t(const Vec3t& other) :
57 e{other.x, other.y, other.z}
58 {}
59
65 Vec3t(const Vec2t<T>& other, T z) :
66 e{other.x, other.y, z}
67 {}
68
74 template <typename U>
75 explicit Vec3t(const Vec3t<U>& other) :
76 e{T(other.x), T(other.y), T(other.z)}
77 {}
78
85 template <typename U>
86 explicit Vec3t(const Vec2t<U>& other, T z) :
87 e{T(other.x), T(other.y), z}
88 {}
89
94 const std::string toString() const {
95 std::stringstream s;
96 s << "[" << e[0] << ", " << e[1] << ", " << e[2] << "]";
97 return s.str();
98 }
99
105 Vec3t operator+(const Vec3t& val) const {
106 return Vec3t{e[0]+val.e[0],
107 e[1]+val.e[1],
108 e[2]+val.e[2]};
109 }
110
116 Vec3t operator-(const Vec3t& val) const {
117 return Vec3t{e[0]-val.e[0],
118 e[1]-val.e[1],
119 e[2]-val.e[2]};
120 }
121
127 Vec3t operator*(const Vec3t& val) const{
128 return Vec3t{e[0]*val.e[0],
129 e[1]*val.e[1],
130 e[2]*val.e[2]};
131 }
132
138 Vec3t operator/(const Vec3t& val) const{
139 return Vec3t{e[0]/val.e[0],
140 e[1]/val.e[1],
141 e[2]/val.e[2]};
142 }
143
149 Vec3t operator*(const T& val) const {
150 return {e[0]*val,e[1]*val,e[2]*val};
151 }
152
158 Vec3t operator/(const T& val) const{
159 return {e[0]/val,e[1]/val,e[2]/val};
160 }
161
167 Vec3t operator+(const T& val) const {
168 return {e[0]+val,e[1]+val,e[2]+val};
169 }
170
176 Vec3t operator-(const T& val) const{
177 return {e[0]-val,e[1]-val,e[2]-val};
178 }
179
185 bool operator == (const Vec3t& other) const {
186 return e[0] == other.e[0] &&
187 e[1] == other.e[1] &&
188 e[2] == other.e[2];
189 }
190
196 bool operator != (const Vec3t& other) const {
197 return e[0] != other.e[0] ||
198 e[1] != other.e[1] ||
199 e[2] != other.e[2];
200 }
201
206 T length() const {
207 return sqrt(sqlength());
208 }
209
214 T sqlength() const {
215 return e[0]*e[0]+e[1]*e[1]+e[2]*e[2];
216 }
217
223 operator T*(void) {return e.data();}
224
229 operator const T*(void) const {return e.data();}
230
237 static float dot(const Vec3t& a, const Vec3t& b) {
238 return a.e[0]*b.e[0]+a.e[1]*b.e[1]+a.e[2]*b.e[2];
239 }
240
247 static Vec3t cross(const Vec3t& a, const Vec3t& b) {
248 return Vec3t{a.e[1] * b.e[2] - a.e[2] * b.e[1],
249 a.e[2] * b.e[0] - a.e[0] * b.e[2],
250 a.e[0] * b.e[1] - a.e[1] * b.e[0]};
251 }
252
258 static Vec3t normalize(const Vec3t& a) {
259 const float l = a.length();
260 return (l != 0.0f) ? a/T(l) : Vec3t{0,0,0};
261 }
262
269 static Vec3t reflect(const Vec3t& a, const Vec3t& n) {
270 return a-n*dot(a,n)*T(2);
271 }
272
284 static std::optional<Vec3t> refract(const Vec3t& a, const Vec3t& normal, const T IOR) {
285 const T cosI = Vec3t::dot(a, normal);
286 int sign = (cosI < 0) ? -1 : 1;
287
288 // we assume that if we look from the back side we are exiting the material
289 // back side means that the sign/cosI is positive because the incoming ray
290 // is assumed to point
291 // towards the surface and the normal away
292 const T n = (sign == 1) ? IOR : 1.0f / IOR;
293 const T sinThetaSq = n * n * (1.0f - cosI * cosI);
294
295 if (sinThetaSq > 1.0f) {
296 // Total internal reflection
297 return {};
298 } else {
299 const Vec3t d = a * n;
300 const T c = n * cosI -sign * sqrt(1.0f - sinThetaSq);
301 const Vec3t b = normal * c;
302 return d - b;
303 }
304 }
305
312 static Vec3t minV(const Vec3t& a, const Vec3t& b) {
313 return {std::min(a.x,b.x), std::min(a.y,b.y), std::min(a.z,b.z)};
314 }
315
322 static Vec3t maxV(const Vec3t& a, const Vec3t& b) {
323 return {std::max(a.x,b.x), std::max(a.y,b.y), std::max(a.z,b.z)};
324 }
325
333 return {staticRand.rand01(),staticRand.rand01(),staticRand.rand01()};
334 }
335
341 while (true) {
342 Vec3t<float> p{staticRand.rand11(),staticRand.rand11(),staticRand.rand11()};
343 if (p.sqlength() > 1) continue;
344 return p;
345 }
346 }
347
353 while (true) {
354 Vec3t<float> p{staticRand.rand01(),staticRand.rand01(),staticRand.rand01()};
355 if (p.sqlength() > 1) continue;
356 return p;
357 }
358 }
359
365 while (true) {
366 Vec3t<float> p{staticRand.rand11(),staticRand.rand11(),0};
367 if (p.sqlength() > 1) continue;
368 return p;
369 }
370 }
371
377 const float a = staticRand.rand0Pi();
378 const float z = staticRand.rand11();
379 const float r = sqrt(1.0f - z*z);
380 return {r*cosf(a), r*sinf(a), z};
381 }
382
390 static Vec3t<float> clamp(const Vec3t& val, float minVal, float maxVal) {
391 return { std::clamp(val.x, minVal, maxVal),
392 std::clamp(val.y, minVal, maxVal),
393 std::clamp(val.z, minVal, maxVal)
394 };
395 }
396};
397
405template <typename T>
406std::ostream & operator<<(std::ostream & os, const Vec3t<T> & v) {
407 os << v.toString();
408 return os;
409}
410
418template <typename T>
419Vec3t<T> operator*(float scalar, const Vec3t<T>& vec) {
420 return vec * scalar;
421}
422
Random staticRand
Global PRNG instance for convenience functions.
Definition Rand.cpp:52
Simple random number utility wrapping std::mt19937 with common ranges.
2D vector template with arithmetic, length utilities, and helpers.
Vec3t< int32_t > Vec3i
3D 32-bit signed integer vector (x,y,z).
Definition Vec3.h:426
Vec3t< uint32_t > Vec3ui
3D 32-bit unsigned integer vector (x,y,z).
Definition Vec3.h:428
std::ostream & operator<<(std::ostream &os, const Vec3t< T > &v)
Stream insertion for string representation of a vector.
Definition Vec3.h:406
Vec3t< float > Vec3
3D float vector (x,y,z).
Definition Vec3.h:424
Vec3t< T > operator*(float scalar, const Vec3t< T > &vec)
Scalar multiplication with scalar on the left.
Definition Vec3.h:419
Definition Vec2.h:27
Definition Vec3.h:29
Vec3t(T x, T y, T z)
Construct from three component values.
Definition Vec3.h:48
float y
Definition Vec3.h:33
static Vec3t cross(const Vec3t &a, const Vec3t &b)
Cross product of two vectors.
Definition Vec3.h:247
const std::string toString() const
String representation "[x, y, z]".
Definition Vec3.h:94
Vec3t operator-(const T &val) const
Subtract scalar from all components.
Definition Vec3.h:176
Vec3t operator/(const T &val) const
Scalar division.
Definition Vec3.h:158
static std::optional< Vec3t > refract(const Vec3t &a, const Vec3t &normal, const T IOR)
Refract a vector through a surface with index-of-refraction ratio.
Definition Vec3.h:284
Vec2t< float > xy
Definition Vec3.h:35
Vec3t operator/(const Vec3t &val) const
Component-wise division.
Definition Vec3.h:138
Vec3t(const Vec3t &other)
Copy-construct from the same type.
Definition Vec3.h:56
T sqlength() const
Squared length (avoids sqrt).
Definition Vec3.h:214
static Vec3t reflect(const Vec3t &a, const Vec3t &n)
Reflect a vector about a unit normal.
Definition Vec3.h:269
Vec3t(const Vec3t< U > &other)
Explicitly convert from another Vec3t with different component type.
Definition Vec3.h:75
float x
Definition Vec3.h:33
static float dot(const Vec3t &a, const Vec3t &b)
Dot product of two vectors.
Definition Vec3.h:237
Vec3t(const Vec2t< U > &other, T z)
Explicitly convert from a 2D vector of a different type and a z value.
Definition Vec3.h:86
Vec3t()
Default-construct to (0,0,0).
Definition Vec3.h:38
static Vec3t minV(const Vec3t &a, const Vec3t &b)
Component-wise minimum of two vectors.
Definition Vec3.h:312
float g
Definition Vec3.h:34
Vec3t operator*(const T &val) const
Scalar multiplication.
Definition Vec3.h:149
static Vec3t< float > random()
Create a vector with components sampled from [0,1).
Definition Vec3.h:332
bool operator!=(const Vec3t &other) const
Inequality comparison (component-wise inequality).
Definition Vec3.h:196
float z
Definition Vec3.h:33
Vec3t operator+(const Vec3t &val) const
Component-wise addition.
Definition Vec3.h:105
static Vec3t< float > randomPointInSphere()
Uniform random point inside the unit sphere.
Definition Vec3.h:340
static Vec3t< float > randomUnitVector()
Uniform random unit vector on the sphere.
Definition Vec3.h:376
T length() const
Euclidean length (magnitude).
Definition Vec3.h:206
std::array< float, 3 > e
Definition Vec3.h:32
Vec3t operator-(const Vec3t &val) const
Component-wise subtraction.
Definition Vec3.h:116
float r
Definition Vec3.h:34
Vec3t operator+(const T &val) const
Add scalar to all components.
Definition Vec3.h:167
static Vec3t< float > randomPointInDisc()
Uniform random point inside the unit disc on the xy-plane.
Definition Vec3.h:364
bool operator==(const Vec3t &other) const
Equality comparison (component-wise equality).
Definition Vec3.h:185
static Vec3t normalize(const Vec3t &a)
Return the normalized (unit-length) version of a vector.
Definition Vec3.h:258
Vec3t(const Vec2t< T > &other, T z)
Construct from a 2D vector and a z value.
Definition Vec3.h:65
static Vec3t< float > randomPointInHemisphere()
Uniform random point inside the upper unit hemisphere (z>=0).
Definition Vec3.h:352
static Vec3t maxV(const Vec3t &a, const Vec3t &b)
Component-wise maximum of two vectors.
Definition Vec3.h:322
Vec3t operator*(const Vec3t &val) const
Component-wise multiplication.
Definition Vec3.h:127
static Vec3t< float > clamp(const Vec3t &val, float minVal, float maxVal)
Clamp each component to [minVal, maxVal].
Definition Vec3.h:390
float b
Definition Vec3.h:34