initial commit
[gph-math] / src / vector.inl
1 #include <math.h>
2
3 namespace gph {
4
5 #undef GPH_SWIZZLE2
6 #undef GPH_SWIZZLE3
7 #undef GPH_SWIZZLE4
8 #define GPH_SWIZZLE2(T, a, b)           inline Vector2 T::a##b() const { return Vector2(a, b); }
9 #define GPH_SWIZZLE3(T, a, b, c)        inline Vector3 T::a##b##c() const { return Vector3(a, b, c); }
10 #define GPH_SWIZZLE4(T, a, b, c, d)     inline Vector4 T::a##b##c##d() const { return Vector4(a, b, c, d); }
11
12 // ---- Vector3 ----
13
14 inline void Vector3::normalize()
15 {
16         float len = (float)sqrt(x * x + y * y + z * z);
17         if(len != 0.0f) {
18                 x /= len;
19                 y /= len;
20                 z /= len;
21         }
22 }
23
24 inline float &Vector3::operator[] (int idx)
25 {
26         return idx == 0 ? x : (idx == 1 ? y : z);
27 }
28
29 inline const float &Vector3::operator[] (int idx) const
30 {
31         return idx == 0 ? x : (idx == 1 ? y : z);
32 }
33
34 inline Vector3 operator -(const Vector3 &v)
35 {
36         return Vector3(-v.x, -v.y, -v.z);
37 }
38
39 inline Vector3 operator +(const Vector3 &a, const Vector3 &b)
40 {
41         return Vector3(a.x + b.x, a.y + b.y, a.z + b.z);
42 }
43
44 inline Vector3 operator -(const Vector3 &a, const Vector3 &b)
45 {
46         return Vector3(a.x - b.x, a.y - b.y, a.z - b.z);
47 }
48
49 inline Vector3 operator *(const Vector3 &a, const Vector3 &b)
50 {
51         return Vector3(a.x * b.x, a.y * b.y, a.z * b.z);
52 }
53
54 inline Vector3 operator /(const Vector3 &a, const Vector3 &b)
55 {
56         return Vector3(a.x / b.x, a.y / b.y, a.z / b.z);
57 }
58
59 inline Vector3 operator *(const Vector3 &v, float s)
60 {
61         return Vector3(v.x * s, v.y * s, v.z * s);
62 }
63
64 inline Vector3 operator *(float s, const Vector3 &v)
65 {
66         return Vector3(s * v.x, s * v.y, s * v.z);
67 }
68
69 inline Vector3 operator /(const Vector3 &v, float s)
70 {
71         return Vector3(v.x / s, v.y / s, v.z / s);
72 }
73
74 inline Vector3 operator /(float s, const Vector3 &v)
75 {
76         return Vector3(s / v.x, s / v.y, s / v.z);
77 }
78
79 inline Vector3 &operator +=(Vector3 &a, const Vector3 &b)
80 {
81         a.x += b.x;
82         a.y += b.y;
83         a.z += b.z;
84         return a;
85 }
86
87 inline Vector3 &operator -=(Vector3 &a, const Vector3 &b)
88 {
89         a.x -= b.x;
90         a.y -= b.y;
91         a.z -= b.z;
92         return a;
93 }
94
95 inline Vector3 &operator *=(Vector3 &a, const Vector3 &b)
96 {
97         a.x *= b.x;
98         a.y *= b.y;
99         a.z *= b.z;
100         return a;
101 }
102
103 inline Vector3 &operator /=(Vector3 &a, const Vector3 &b)
104 {
105         a.x /= b.x;
106         a.y /= b.y;
107         a.z /= b.z;
108         return a;
109 }
110
111 inline Vector3 &operator *=(Vector3 &v, float s)
112 {
113         v.x *= s;
114         v.y *= s;
115         v.z *= s;
116         return v;
117 }
118
119 inline Vector3 &operator /=(Vector3 &v, float s)
120 {
121         v.x /= s;
122         v.y /= s;
123         v.z /= s;
124         return v;
125 }
126
127 inline bool operator ==(const Vector3 &a, const Vector3 &b)
128 {
129         return a.x == b.x && a.y == b.y && a.z == b.z;
130 }
131
132 inline bool operator !=(const Vector3 &a, const Vector3 &b)
133 {
134         return !(a == b);
135 }
136
137 inline float dot(const Vector3 &a, const Vector3 &b)
138 {
139         return a.x * b.x + a.y * b.y + a.z * b.z;
140 }
141
142 inline Vector3 cross(const Vector3 &a, const Vector3 &b)
143 {
144         return Vector3(a.y * b.z - a.z * b.y,
145                         a.z * b.x - a.x * b.z,
146                         a.x * b.y - a.y * b.x);
147 }
148
149 inline float length(const Vector3 &v)
150 {
151         return (float)sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
152 }
153
154 inline float length_sq(const Vector3 &v)
155 {
156         return v.x * v.x + v.y * v.y + v.z * v.z;
157 }
158
159 inline Vector3 normalize(const Vector3 &v)
160 {
161         float len = length(v);
162         if(len == 0.0f) {
163                 return v;
164         }
165
166         return Vector3(v.x / len, v.y / len, v.z / len);
167 }
168
169 inline Vector3 reflect(const Vector3 &v, const Vector3 &n)
170 {
171         return v - n * dot(n, v) * 2.0;
172 }
173
174 inline Vector3 refract(const Vector3 &v, const Vector3 &n, float ior)
175 {
176         float ndotv = dot(n, v);
177         float k = 1.0f - ior * ior * (1.0f - ndotv * ndotv);
178         if(k < 0.0f) {
179                 return Vector3();
180         }
181         return ior * v - (ior * ndotv + sqrt(k)) * n;
182 }
183
184 inline Vector3 refract(const Vector3 &v, const Vector3 &n, float from_ior, float to_ior)
185 {
186         if(to_ior == 0.0f) to_ior = 1.0f;
187         return refract(v, n, from_ior / to_ior);
188 }
189
190 inline float distance(const Vector3 &a, const Vector3 &b)
191 {
192         return length(a - b);
193 }
194
195 inline float distance_sq(const Vector3 &a, const Vector3 &b)
196 {
197         return length_sq(a - b);
198 }
199
200 inline Vector3 faceforward(const Vector3 &n, const Vector3 &vi, const Vector3 &ng)
201 {
202         return dot(ng, vi) < 0.0f ? n : -n;
203 }
204
205 inline Vector3 major(const Vector3 &v)
206 {
207         int m = major_idx(v);
208         Vector3 res;
209         res[m] = v[m];
210         return res;
211 }
212
213 inline int major_idx(const Vector3 &v)
214 {
215         return fabs(v.x) >= fabs(v.y) && fabs(v.x) > fabs(v.z) ? 0 :
216                 (fabs(v.y) >= fabs(v.z) ? 1 : 2);
217 }
218
219 inline Vector3 proj_axis(const Vector3 &v, const Vector3 &axis)
220 {
221         return axis * dot(v, axis);
222 }
223
224
225 inline Vector3 rotate(const Vector3 &v, const Quaternion &q)
226 {
227         return v;       // TODO
228 }
229
230 inline Vector3 rotate(const Vector3 &v, const Vector3 &axis, float angle)
231 {
232         return v;       // TODO
233 }
234
235 inline Vector3 rotate(const Vector3 &v, const Vector3 &euler)
236 {
237         return v;       // TODO
238 }
239
240
241 GPH_VEC3_SWIZZLE
242
243 // ---- Vector4 ----
244
245
246 inline void Vector4::normalize()
247 {
248         float len = (float)sqrt(x * x + y * y + z * z + w * w);
249         if(len != 0.0f) {
250                 x /= len;
251                 y /= len;
252                 z /= len;
253                 w /= len;
254         }
255 }
256
257 inline float &Vector4::operator[] (int idx)
258 {
259         return idx == 0 ? x : (idx == 1 ? y : (idx == 2 ? z : w));
260 }
261
262 inline const float &Vector4::operator[] (int idx) const
263 {
264         return idx == 0 ? x : (idx == 1 ? y : (idx == 2 ? z : w));
265 }
266
267 GPH_VEC4_SWIZZLE
268
269 // ---- Vector2 ----
270
271 inline void Vector2::normalize()
272 {
273         float len = (float)sqrt(x * x + y * y);
274         if(len != 0.0f) {
275                 x /= len;
276                 y /= len;
277         }
278 }
279
280 inline float &Vector2::operator[] (int idx)
281 {
282         return idx == 0 ? x : y;
283 }
284
285 inline const float &Vector2::operator[] (int idx) const
286 {
287         return idx == 0 ? x : y;
288 }
289
290 GPH_VEC2_SWIZZLE
291
292 }       // namespace gph