Line data Source code
1 : #pragma once
2 : #include "math3d/core.hpp"
3 :
4 : namespace m3d
5 : {
6 :
7 : struct vec3
8 : {
9 : scalar x, y, z;
10 :
11 : // Constructors
12 530840 : vec3() : x(0), y(0), z(0) {}
13 1885899 : vec3(scalar _x, scalar _y, scalar _z) : x(_x), y(_y), z(_z) {}
14 8076 : vec3(scalar _d) : x(_d), y(_d), z(_d) {}
15 :
16 : // Operator Overloading for clean syntax
17 202731 : vec3 operator+(const vec3 &rhs) const { return {x + rhs.x, y + rhs.y, z + rhs.z}; }
18 111454 : vec3 operator-(const vec3 &rhs) const { return {x - rhs.x, y - rhs.y, z - rhs.z}; }
19 234600 : vec3 operator*(scalar s) const { return {x * s, y * s, z * s}; }
20 8723 : vec3 operator/(scalar s) const
21 : {
22 8723 : scalar inv = 1.0 / s;
23 8723 : return {x * inv, y * inv, z * inv};
24 : }
25 :
26 : // Unary negation
27 15100 : vec3 operator-() const { return {-x, -y, -z}; }
28 :
29 : // In-place operators (important for performance)
30 59764 : vec3 &operator+=(const vec3 &rhs)
31 : {
32 59764 : x += rhs.x;
33 59764 : y += rhs.y;
34 59764 : z += rhs.z;
35 59764 : return *this;
36 : }
37 :
38 6 : vec3 &operator-=(const vec3 &rhs)
39 : {
40 6 : x -= rhs.x;
41 6 : y -= rhs.y;
42 6 : z -= rhs.z;
43 6 : return *this;
44 : }
45 :
46 1 : vec3 &operator*=(scalar s)
47 : {
48 1 : x *= s;
49 1 : y *= s;
50 1 : z *= s;
51 1 : return *this;
52 : }
53 :
54 32 : bool operator==(const vec3 &other) const
55 : {
56 32 : return x == other.x && y == other.y && z == other.z;
57 : }
58 :
59 1 : bool operator!=(const vec3 &other) const
60 : {
61 1 : return !(*this == other);
62 : }
63 :
64 : // For physics-safe comparison
65 13 : bool is_approx(const vec3 &other, scalar precision = EPSILON) const
66 : {
67 24 : return m3d::abs(x - other.x) < precision &&
68 24 : m3d::abs(y - other.y) < precision &&
69 24 : m3d::abs(z - other.z) < precision;
70 : }
71 :
72 : // Meber acces via indices
73 21 : scalar &operator[](int i)
74 : {
75 : return (i == 0) ? x : (i == 1) ? y
76 21 : : z;
77 : }
78 :
79 4539 : const scalar &operator[](int i) const
80 : {
81 : return (i == 0) ? x : (i == 1) ? y
82 4539 : : z;
83 : }
84 :
85 1 : friend std::ostream &operator<<(std::ostream &os, const vec3 &v)
86 : {
87 1 : return os << "vec3(" << v.x << ", " << v.y << ", " << v.z << ")";
88 : }
89 : };
90 :
91 : // Left-side scalar multiplication (s * v)
92 37450 : inline vec3 operator*(scalar s, const vec3 &v) { return {v.x * s, v.y * s, v.z * s}; }
93 :
94 : // --- Vector Functions ---
95 :
96 26640 : inline scalar dot(const vec3 &a, const vec3 &b)
97 : {
98 26640 : return a.x * b.x + a.y * b.y + a.z * b.z;
99 : }
100 :
101 184892 : inline vec3 cross(const vec3 &a, const vec3 &b)
102 : {
103 : return {
104 184892 : a.y * b.z - a.z * b.y,
105 184892 : a.z * b.x - a.x * b.z,
106 184892 : a.x * b.y - a.y * b.x};
107 : }
108 :
109 22686 : inline scalar length_sq(const vec3 &v)
110 : {
111 22686 : return v.x * v.x + v.y * v.y + v.z * v.z;
112 : }
113 :
114 21834 : inline scalar length(const vec3 &v)
115 : {
116 21834 : return m3d::sqrt(length_sq(v));
117 : }
118 :
119 : // Alias for magnitude (Its intuitive to call it like that in some contexts)
120 11074 : inline scalar magnitude(const vec3 &v)
121 : {
122 11074 : return length(v);
123 : }
124 :
125 580 : inline vec3 normalize(const vec3 &v)
126 : {
127 580 : scalar len_sq = length_sq(v);
128 580 : if (len_sq < EPSILON)
129 1 : return {0, 0, 0};
130 579 : scalar inv_len = 1.0 / m3d::sqrt(len_sq);
131 579 : return v * inv_len;
132 : }
133 :
134 : } // namespace m3d
|