1// This code is in the public domain -- castanyo@yahoo.es
2
3#ifndef NV_MATH_VECTOR_INL
4#define NV_MATH_VECTOR_INL
5
6#include "vector.h"
7#include "nvcore/utils.h" // min, max
8#include "nvcore/hash.h" // hash
9
10namespace nv
11{
12
13    // Helpers to convert vector types. Assume T has x,y members and 2 argument constructor.
14    //template <typename T> T to(Vector2::Arg v) { return T(v.x, v.y); }
15
16    // Helpers to convert vector types. Assume T has x,y,z members and 3 argument constructor.
17    //template <typename T> T to(Vector3::Arg v) { return T(v.x, v.y, v.z); }
18
19    // Helpers to convert vector types. Assume T has x,y,z members and 3 argument constructor.
20    //template <typename T> T to(Vector4::Arg v) { return T(v.x, v.y, v.z, v.w); }
21
22
23    // Vector2
24    inline Vector2::Vector2() {}
25    inline Vector2::Vector2(float f) : x(f), y(f) {}
26    inline Vector2::Vector2(float x, float y) : x(x), y(y) {}
27    inline Vector2::Vector2(Vector2::Arg v) : x(v.x), y(v.y) {}
28
29    inline const Vector2 & Vector2::operator=(Vector2::Arg v)
30    {
31        x = v.x;
32        y = v.y;
33        return *this;
34    }
35
36    inline const float * Vector2::ptr() const
37    {
38        return &x;
39    }
40
41    inline void Vector2::set(float x, float y)
42    {
43        this->x = x;
44        this->y = y;
45    }
46
47    inline Vector2 Vector2::operator-() const
48    {
49        return Vector2(-x, -y);
50    }
51
52    inline void Vector2::operator+=(Vector2::Arg v)
53    {
54        x += v.x;
55        y += v.y;
56    }
57
58    inline void Vector2::operator-=(Vector2::Arg v)
59    {
60        x -= v.x;
61        y -= v.y;
62    }
63
64    inline void Vector2::operator*=(float s)
65    {
66        x *= s;
67        y *= s;
68    }
69
70    inline void Vector2::operator*=(Vector2::Arg v)
71    {
72        x *= v.x;
73        y *= v.y;
74    }
75
76    inline bool operator==(Vector2::Arg a, Vector2::Arg b)
77    {
78        return a.x == b.x && a.y == b.y;
79    }
80    inline bool operator!=(Vector2::Arg a, Vector2::Arg b)
81    {
82        return a.x != b.x || a.y != b.y;
83    }
84
85
86    // Vector3
87    inline Vector3::Vector3() {}
88    inline Vector3::Vector3(float f) : x(f), y(f), z(f) {}
89    inline Vector3::Vector3(float x, float y, float z) : x(x), y(y), z(z) {}
90    inline Vector3::Vector3(Vector2::Arg v, float z) : x(v.x), y(v.y), z(z) {}
91    inline Vector3::Vector3(Vector3::Arg v) : x(v.x), y(v.y), z(v.z) {}
92
93    inline const Vector3 & Vector3::operator=(Vector3::Arg v)
94    {
95        x = v.x;
96        y = v.y;
97        z = v.z;
98        return *this;
99    }
100
101
102    inline Vector2 Vector3::xy() const
103    {
104        return Vector2(x, y);
105    }
106
107    inline const float * Vector3::ptr() const
108    {
109        return &x;
110    }
111
112    inline void Vector3::set(float x, float y, float z)
113    {
114        this->x = x;
115        this->y = y;
116        this->z = z;
117    }
118
119    inline Vector3 Vector3::operator-() const
120    {
121        return Vector3(-x, -y, -z);
122    }
123
124    inline void Vector3::operator+=(Vector3::Arg v)
125    {
126        x += v.x;
127        y += v.y;
128        z += v.z;
129    }
130
131    inline void Vector3::operator-=(Vector3::Arg v)
132    {
133        x -= v.x;
134        y -= v.y;
135        z -= v.z;
136    }
137
138    inline void Vector3::operator*=(float s)
139    {
140        x *= s;
141        y *= s;
142        z *= s;
143    }
144
145    inline void Vector3::operator/=(float s)
146    {
147        float is = 1.0f / s;
148        x *= is;
149        y *= is;
150        z *= is;
151    }
152
153    inline void Vector3::operator*=(Vector3::Arg v)
154    {
155        x *= v.x;
156        y *= v.y;
157        z *= v.z;
158    }
159
160    inline void Vector3::operator/=(Vector3::Arg v)
161    {
162        x /= v.x;
163        y /= v.y;
164        z /= v.z;
165    }
166
167    inline bool operator==(Vector3::Arg a, Vector3::Arg b)
168    {
169        return a.x == b.x && a.y == b.y && a.z == b.z;
170    }
171    inline bool operator!=(Vector3::Arg a, Vector3::Arg b)
172    {
173        return a.x != b.x || a.y != b.y || a.z != b.z;
174    }
175
176
177    // Vector4
178    inline Vector4::Vector4() {}
179    inline Vector4::Vector4(float f) : x(f), y(f), z(f), w(f) {}
180    inline Vector4::Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}
181    inline Vector4::Vector4(Vector2::Arg v, float z, float w) : x(v.x), y(v.y), z(z), w(w) {}
182    inline Vector4::Vector4(Vector2::Arg v, Vector2::Arg u) : x(v.x), y(v.y), z(u.x), w(u.y) {}
183    inline Vector4::Vector4(Vector3::Arg v, float w) : x(v.x), y(v.y), z(v.z), w(w) {}
184    inline Vector4::Vector4(Vector4::Arg v) : x(v.x), y(v.y), z(v.z), w(v.w) {}
185
186    inline const Vector4 & Vector4::operator=(const Vector4 & v)
187    {
188        x = v.x;
189        y = v.y;
190        z = v.z;
191        w = v.w;
192        return *this;
193    }
194
195    inline Vector2 Vector4::xy() const
196    {
197        return Vector2(x, y);
198    }
199
200    inline Vector2 Vector4::zw() const
201    {
202        return Vector2(z, w);
203    }
204
205    inline Vector3 Vector4::xyz() const
206    {
207        return Vector3(x, y, z);
208    }
209
210    inline const float * Vector4::ptr() const
211    {
212        return &x;
213    }
214
215    inline void Vector4::set(float x, float y, float z, float w)
216    {
217        this->x = x;
218        this->y = y;
219        this->z = z;
220        this->w = w;
221    }
222
223    inline Vector4 Vector4::operator-() const
224    {
225        return Vector4(-x, -y, -z, -w);
226    }
227
228    inline void Vector4::operator+=(Vector4::Arg v)
229    {
230        x += v.x;
231        y += v.y;
232        z += v.z;
233        w += v.w;
234    }
235
236    inline void Vector4::operator-=(Vector4::Arg v)
237    {
238        x -= v.x;
239        y -= v.y;
240        z -= v.z;
241        w -= v.w;
242    }
243
244    inline void Vector4::operator*=(float s)
245    {
246        x *= s;
247        y *= s;
248        z *= s;
249        w *= s;
250    }
251
252    inline void Vector4::operator/=(float s)
253    {
254        x /= s;
255        y /= s;
256        z /= s;
257        w /= s;
258    }
259
260    inline void Vector4::operator*=(Vector4::Arg v)
261    {
262        x *= v.x;
263        y *= v.y;
264        z *= v.z;
265        w *= v.w;
266    }
267
268    inline void Vector4::operator/=(Vector4::Arg v)
269    {
270        x /= v.x;
271        y /= v.y;
272        z /= v.z;
273        w /= v.w;
274    }
275
276    inline bool operator==(Vector4::Arg a, Vector4::Arg b)
277    {
278        return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;
279    }
280    inline bool operator!=(Vector4::Arg a, Vector4::Arg b)
281    {
282        return a.x != b.x || a.y != b.y || a.z != b.z || a.w != b.w;
283    }
284
285
286
287    // Functions
288
289
290    // Vector2
291
292    inline Vector2 add(Vector2::Arg a, Vector2::Arg b)
293    {
294        return Vector2(a.x + b.x, a.y + b.y);
295    }
296    inline Vector2 operator+(Vector2::Arg a, Vector2::Arg b)
297    {
298        return add(a, b);
299    }
300
301    inline Vector2 sub(Vector2::Arg a, Vector2::Arg b)
302    {
303        return Vector2(a.x - b.x, a.y - b.y);
304    }
305    inline Vector2 operator-(Vector2::Arg a, Vector2::Arg b)
306    {
307        return sub(a, b);
308    }
309
310    inline Vector2 scale(Vector2::Arg v, float s)
311    {
312        return Vector2(v.x * s, v.y * s);
313    }
314
315    inline Vector2 scale(Vector2::Arg v, Vector2::Arg s)
316    {
317        return Vector2(v.x * s.x, v.y * s.y);
318    }
319
320    inline Vector2 operator*(Vector2::Arg v, float s)
321    {
322        return scale(v, s);
323    }
324
325    inline Vector2 operator*(Vector2::Arg v1, Vector2::Arg v2)
326    {
327        return Vector2(v1.x*v2.x, v1.y*v2.y);
328    }
329
330    inline Vector2 operator*(float s, Vector2::Arg v)
331    {
332        return scale(v, s);
333    }
334
335    inline Vector2 operator/(Vector2::Arg v, float s)
336    {
337        return scale(v, 1.0f/s);
338    }
339
340    inline Vector2 lerp(Vector2::Arg v1, Vector2::Arg v2, float t)
341    {
342        const float s = 1.0f - t;
343        return Vector2(v1.x * s + t * v2.x, v1.y * s + t * v2.y);
344    }
345
346    inline float dot(Vector2::Arg a, Vector2::Arg b)
347    {
348        return a.x * b.x + a.y * b.y;
349    }
350
351    inline float lengthSquared(Vector2::Arg v)
352    {
353        return v.x * v.x + v.y * v.y;
354    }
355
356    inline float length(Vector2::Arg v)
357    {
358        return sqrtf(lengthSquared(v));
359    }
360
361    inline float distance(Vector2::Arg a, Vector2::Arg b)
362    {
363        return length(a - b);
364    }
365
366    inline float inverseLength(Vector2::Arg v)
367    {
368        return 1.0f / sqrtf(lengthSquared(v));
369    }
370
371    inline bool isNormalized(Vector2::Arg v, float epsilon = NV_NORMAL_EPSILON)
372    {
373        return equal(length(v), 1, epsilon);
374    }
375
376    inline Vector2 normalize(Vector2::Arg v, float epsilon = NV_EPSILON)
377    {
378        float l = length(v);
379        NV_UNUSED(epsilon);
380        nvDebugCheck(!isZero(l, epsilon));
381        Vector2 n = scale(v, 1.0f / l);
382        nvDebugCheck(isNormalized(n));
383        return n;
384    }
385
386    inline Vector2 normalizeSafe(Vector2::Arg v, Vector2::Arg fallback, float epsilon = NV_EPSILON)
387    {
388        float l = length(v);
389        if (isZero(l, epsilon)) {
390            return fallback;
391        }
392        return scale(v, 1.0f / l);
393    }
394
395    // Safe, branchless normalization from Andy Firth. All error checking ommitted.
396    // http://altdevblogaday.com/2011/08/21/practical-flt-point-tricks/
397    inline Vector2 normalizeFast(Vector2::Arg v)
398    {
399        const float very_small_float = 1.0e-037f;
400        float l = very_small_float + length(v);
401        return scale(v, 1.0f / l);
402    }
403
404    inline bool equal(Vector2::Arg v1, Vector2::Arg v2, float epsilon = NV_EPSILON)
405    {
406        return equal(v1.x, v2.x, epsilon) && equal(v1.y, v2.y, epsilon);
407    }
408
409    inline Vector2 min(Vector2::Arg a, Vector2::Arg b)
410    {
411        return Vector2(min(a.x, b.x), min(a.y, b.y));
412    }
413
414    inline Vector2 max(Vector2::Arg a, Vector2::Arg b)
415    {
416        return Vector2(max(a.x, b.x), max(a.y, b.y));
417    }
418
419    inline Vector2 clamp(Vector2::Arg v, float min, float max)
420    {
421        return Vector2(clamp(v.x, min, max), clamp(v.y, min, max));
422    }
423
424    inline Vector2 saturate(Vector2::Arg v)
425    {
426        return Vector2(saturate(v.x), saturate(v.y));
427    }
428
429    inline bool isFinite(Vector2::Arg v)
430    {
431        return isFinite(v.x) && isFinite(v.y);
432    }
433
434    inline Vector2 validate(Vector2::Arg v, Vector2::Arg fallback = Vector2(0.0f))
435    {
436        if (!isFinite(v)) return fallback;
437        Vector2 vf = v;
438        nv::floatCleanup(vf.component, 2);
439        return vf;
440    }
441
442    // Note, this is the area scaled by 2!
443    inline float triangleArea(Vector2::Arg v0, Vector2::Arg v1)
444    {
445	    return (v0.x * v1.y - v0.y * v1.x); // * 0.5f;
446    }
447    inline float triangleArea(Vector2::Arg a, Vector2::Arg b, Vector2::Arg c)
448    {
449        // IC: While it may be appealing to use the following expression:
450        //return (c.x * a.y + a.x * b.y + b.x * c.y - b.x * a.y - c.x * b.y - a.x * c.y); // * 0.5f;
451
452        // That's actually a terrible idea. Small triangles far from the origin can end up producing fairly large floating point
453        // numbers and the results becomes very unstable and dependent on the order of the factors.
454
455        // Instead, it's preferable to substract the vertices first, and multiply the resulting small values together. The result
456        // in this case is always much more accurate (as long as the triangle is small) and less dependent of the location of
457        // the triangle.
458
459        //return ((a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x)); // * 0.5f;
460        return triangleArea(a-c, b-c);
461    }
462
463
464    template <>
465    inline uint hash(const Vector2 & v, uint h)
466    {
467        return sdbmFloatHash(v.component, 2, h);
468    }
469
470
471
472    // Vector3
473
474    inline Vector3 add(Vector3::Arg a, Vector3::Arg b)
475    {
476        return Vector3(a.x + b.x, a.y + b.y, a.z + b.z);
477    }
478    inline Vector3 add(Vector3::Arg a, float b)
479    {
480        return Vector3(a.x + b, a.y + b, a.z + b);
481    }
482    inline Vector3 operator+(Vector3::Arg a, Vector3::Arg b)
483    {
484        return add(a, b);
485    }
486    inline Vector3 operator+(Vector3::Arg a, float b)
487    {
488        return add(a, b);
489    }
490
491    inline Vector3 sub(Vector3::Arg a, Vector3::Arg b)
492    {
493        return Vector3(a.x - b.x, a.y - b.y, a.z - b.z);
494    }
495    inline Vector3 sub(Vector3::Arg a, float b)
496    {
497        return Vector3(a.x - b, a.y - b, a.z - b);
498    }
499    inline Vector3 operator-(Vector3::Arg a, Vector3::Arg b)
500    {
501        return sub(a, b);
502    }
503    inline Vector3 operator-(Vector3::Arg a, float b)
504    {
505        return sub(a, b);
506    }
507
508    inline Vector3 cross(Vector3::Arg a, Vector3::Arg b)
509    {
510        return Vector3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
511    }
512
513    inline Vector3 scale(Vector3::Arg v, float s)
514    {
515        return Vector3(v.x * s, v.y * s, v.z * s);
516    }
517
518    inline Vector3 scale(Vector3::Arg v, Vector3::Arg s)
519    {
520        return Vector3(v.x * s.x, v.y * s.y, v.z * s.z);
521    }
522
523    inline Vector3 operator*(Vector3::Arg v, float s)
524    {
525        return scale(v, s);
526    }
527
528    inline Vector3 operator*(float s, Vector3::Arg v)
529    {
530        return scale(v, s);
531    }
532
533    inline Vector3 operator*(Vector3::Arg v, Vector3::Arg s)
534    {
535        return scale(v, s);
536    }
537
538    inline Vector3 operator/(Vector3::Arg v, float s)
539    {
540        return scale(v, 1.0f/s);
541    }
542
543    /*inline Vector3 add_scaled(Vector3::Arg a, Vector3::Arg b, float s)
544    {
545        return Vector3(a.x + b.x * s, a.y + b.y * s, a.z + b.z * s);
546    }*/
547
548    inline Vector3 lerp(Vector3::Arg v1, Vector3::Arg v2, float t)
549    {
550        const float s = 1.0f - t;
551        return Vector3(v1.x * s + t * v2.x, v1.y * s + t * v2.y, v1.z * s + t * v2.z);
552    }
553
554    inline float dot(Vector3::Arg a, Vector3::Arg b)
555    {
556        return a.x * b.x + a.y * b.y + a.z * b.z;
557    }
558
559    inline float lengthSquared(Vector3::Arg v)
560    {
561        return v.x * v.x + v.y * v.y + v.z * v.z;
562    }
563
564    inline float length(Vector3::Arg v)
565    {
566        return sqrtf(lengthSquared(v));
567    }
568
569    inline float distance(Vector3::Arg a, Vector3::Arg b)
570    {
571        return length(a - b);
572    }
573
574    inline float distanceSquared(Vector3::Arg a, Vector3::Arg b)
575    {
576        return lengthSquared(a - b);
577    }
578
579    inline float inverseLength(Vector3::Arg v)
580    {
581        return 1.0f / sqrtf(lengthSquared(v));
582    }
583
584    inline bool isNormalized(Vector3::Arg v, float epsilon = NV_NORMAL_EPSILON)
585    {
586        return equal(length(v), 1, epsilon);
587    }
588
589    inline Vector3 normalize(Vector3::Arg v, float epsilon = NV_EPSILON)
590    {
591        float l = length(v);
592        NV_UNUSED(epsilon);
593        nvDebugCheck(!isZero(l, epsilon));
594        Vector3 n = scale(v, 1.0f / l);
595        nvDebugCheck(isNormalized(n));
596        return n;
597    }
598
599    inline Vector3 normalizeSafe(Vector3::Arg v, Vector3::Arg fallback, float epsilon = NV_EPSILON)
600    {
601        float l = length(v);
602        if (isZero(l, epsilon)) {
603            return fallback;
604        }
605        return scale(v, 1.0f / l);
606    }
607
608    // Safe, branchless normalization from Andy Firth. All error checking ommitted.
609    // http://altdevblogaday.com/2011/08/21/practical-flt-point-tricks/
610    inline Vector3 normalizeFast(Vector3::Arg v)
611    {
612        const float very_small_float = 1.0e-037f;
613        float l = very_small_float + length(v);
614        return scale(v, 1.0f / l);
615    }
616
617    inline bool equal(Vector3::Arg v1, Vector3::Arg v2, float epsilon = NV_EPSILON)
618    {
619        return equal(v1.x, v2.x, epsilon) && equal(v1.y, v2.y, epsilon) && equal(v1.z, v2.z, epsilon);
620    }
621
622    inline Vector3 min(Vector3::Arg a, Vector3::Arg b)
623    {
624        return Vector3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z));
625    }
626
627    inline Vector3 max(Vector3::Arg a, Vector3::Arg b)
628    {
629        return Vector3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z));
630    }
631
632    inline Vector3 clamp(Vector3::Arg v, float min, float max)
633    {
634        return Vector3(clamp(v.x, min, max), clamp(v.y, min, max), clamp(v.z, min, max));
635    }
636
637    inline Vector3 saturate(Vector3::Arg v)
638    {
639        return Vector3(saturate(v.x), saturate(v.y), saturate(v.z));
640    }
641
642    inline Vector3 floor(Vector3::Arg v)
643    {
644        return Vector3(floorf(v.x), floorf(v.y), floorf(v.z));
645    }
646
647    inline Vector3 ceil(Vector3::Arg v)
648    {
649        return Vector3(ceilf(v.x), ceilf(v.y), ceilf(v.z));
650    }
651
652    inline bool isFinite(Vector3::Arg v)
653    {
654        return isFinite(v.x) && isFinite(v.y) && isFinite(v.z);
655    }
656
657    inline Vector3 validate(Vector3::Arg v, Vector3::Arg fallback = Vector3(0.0f))
658    {
659        if (!isFinite(v)) return fallback;
660        Vector3 vf = v;
661        nv::floatCleanup(vf.component, 3);
662        return vf;
663    }
664
665    inline Vector3 reflect(Vector3::Arg v, Vector3::Arg n)
666    {
667	    return v - (2 * dot(v, n)) * n;
668    }
669
670    template <>
671    inline uint hash(const Vector3 & v, uint h)
672    {
673        return sdbmFloatHash(v.component, 3, h);
674    }
675
676
677    // Vector4
678
679    inline Vector4 add(Vector4::Arg a, Vector4::Arg b)
680    {
681        return Vector4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
682    }
683    inline Vector4 operator+(Vector4::Arg a, Vector4::Arg b)
684    {
685        return add(a, b);
686    }
687
688    inline Vector4 sub(Vector4::Arg a, Vector4::Arg b)
689    {
690        return Vector4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
691    }
692    inline Vector4 operator-(Vector4::Arg a, Vector4::Arg b)
693    {
694        return sub(a, b);
695    }
696
697    inline Vector4 scale(Vector4::Arg v, float s)
698    {
699        return Vector4(v.x * s, v.y * s, v.z * s, v.w * s);
700    }
701
702    inline Vector4 scale(Vector4::Arg v, Vector4::Arg s)
703    {
704        return Vector4(v.x * s.x, v.y * s.y, v.z * s.z, v.w * s.w);
705    }
706
707    inline Vector4 operator*(Vector4::Arg v, float s)
708    {
709        return scale(v, s);
710    }
711
712    inline Vector4 operator*(float s, Vector4::Arg v)
713    {
714        return scale(v, s);
715    }
716
717    inline Vector4 operator*(Vector4::Arg v, Vector4::Arg s)
718    {
719        return scale(v, s);
720    }
721
722    inline Vector4 operator/(Vector4::Arg v, float s)
723    {
724        return scale(v, 1.0f/s);
725    }
726
727    /*inline Vector4 add_scaled(Vector4::Arg a, Vector4::Arg b, float s)
728    {
729        return Vector4(a.x + b.x * s, a.y + b.y * s, a.z + b.z * s, a.w + b.w * s);
730    }*/
731
732    inline Vector4 lerp(Vector4::Arg v1, Vector4::Arg v2, float t)
733    {
734        const float s = 1.0f - t;
735        return Vector4(v1.x * s + t * v2.x, v1.y * s + t * v2.y, v1.z * s + t * v2.z, v1.w * s + t * v2.w);
736    }
737
738    inline float dot(Vector4::Arg a, Vector4::Arg b)
739    {
740        return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
741    }
742
743    inline float lengthSquared(Vector4::Arg v)
744    {
745        return v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w;
746    }
747
748    inline float length(Vector4::Arg v)
749    {
750        return sqrtf(lengthSquared(v));
751    }
752
753    inline float inverseLength(Vector4::Arg v)
754    {
755        return 1.0f / sqrtf(lengthSquared(v));
756    }
757
758    inline bool isNormalized(Vector4::Arg v, float epsilon = NV_NORMAL_EPSILON)
759    {
760        return equal(length(v), 1, epsilon);
761    }
762
763    inline Vector4 normalize(Vector4::Arg v, float epsilon = NV_EPSILON)
764    {
765        float l = length(v);
766        NV_UNUSED(epsilon);
767        nvDebugCheck(!isZero(l, epsilon));
768        Vector4 n = scale(v, 1.0f / l);
769        nvDebugCheck(isNormalized(n));
770        return n;
771    }
772
773    inline Vector4 normalizeSafe(Vector4::Arg v, Vector4::Arg fallback, float epsilon = NV_EPSILON)
774    {
775        float l = length(v);
776        if (isZero(l, epsilon)) {
777            return fallback;
778        }
779        return scale(v, 1.0f / l);
780    }
781
782    // Safe, branchless normalization from Andy Firth. All error checking ommitted.
783    // http://altdevblogaday.com/2011/08/21/practical-flt-point-tricks/
784    inline Vector4 normalizeFast(Vector4::Arg v)
785    {
786        const float very_small_float = 1.0e-037f;
787        float l = very_small_float + length(v);
788        return scale(v, 1.0f / l);
789    }
790
791    inline bool equal(Vector4::Arg v1, Vector4::Arg v2, float epsilon = NV_EPSILON)
792    {
793        return equal(v1.x, v2.x, epsilon) && equal(v1.y, v2.y, epsilon) && equal(v1.z, v2.z, epsilon) && equal(v1.w, v2.w, epsilon);
794    }
795
796    inline Vector4 min(Vector4::Arg a, Vector4::Arg b)
797    {
798        return Vector4(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z), min(a.w, b.w));
799    }
800
801    inline Vector4 max(Vector4::Arg a, Vector4::Arg b)
802    {
803        return Vector4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w));
804    }
805
806    inline Vector4 clamp(Vector4::Arg v, float min, float max)
807    {
808        return Vector4(clamp(v.x, min, max), clamp(v.y, min, max), clamp(v.z, min, max), clamp(v.w, min, max));
809    }
810
811    inline Vector4 saturate(Vector4::Arg v)
812    {
813        return Vector4(saturate(v.x), saturate(v.y), saturate(v.z), saturate(v.w));
814    }
815
816    inline bool isFinite(Vector4::Arg v)
817    {
818        return isFinite(v.x) && isFinite(v.y) && isFinite(v.z) && isFinite(v.w);
819    }
820
821    inline Vector4 validate(Vector4::Arg v, Vector4::Arg fallback = Vector4(0.0f))
822    {
823        if (!isFinite(v)) return fallback;
824        Vector4 vf = v;
825        nv::floatCleanup(vf.component, 4);
826        return vf;
827    }
828
829    template <>
830    inline uint hash(const Vector4 & v, uint h)
831    {
832        return sdbmFloatHash(v.component, 4, h);
833    }
834
835
836#if NV_OS_IOS // LLVM is not happy with implicit conversion of immediate constants to float
837
838    //int:
839
840    inline Vector2 scale(Vector2::Arg v, int s)
841    {
842        return Vector2(v.x * s, v.y * s);
843    }
844
845    inline Vector2 operator*(Vector2::Arg v, int s)
846    {
847        return scale(v, s);
848    }
849
850    inline Vector2 operator*(int s, Vector2::Arg v)
851    {
852        return scale(v, s);
853    }
854
855    inline Vector2 operator/(Vector2::Arg v, int s)
856    {
857        return scale(v, 1.0f/s);
858    }
859
860    inline Vector3 scale(Vector3::Arg v, int s)
861    {
862        return Vector3(v.x * s, v.y * s, v.z * s);
863    }
864
865    inline Vector3 operator*(Vector3::Arg v, int s)
866    {
867        return scale(v, s);
868    }
869
870    inline Vector3 operator*(int s, Vector3::Arg v)
871    {
872        return scale(v, s);
873    }
874
875    inline Vector3 operator/(Vector3::Arg v, int s)
876    {
877        return scale(v, 1.0f/s);
878    }
879
880    inline Vector4 scale(Vector4::Arg v, int s)
881    {
882        return Vector4(v.x * s, v.y * s, v.z * s, v.w * s);
883    }
884
885    inline Vector4 operator*(Vector4::Arg v, int s)
886    {
887        return scale(v, s);
888    }
889
890    inline Vector4 operator*(int s, Vector4::Arg v)
891    {
892        return scale(v, s);
893    }
894
895    inline Vector4 operator/(Vector4::Arg v, int s)
896    {
897        return scale(v, 1.0f/s);
898    }
899
900    //double:
901
902    inline Vector3 operator*(Vector3::Arg v, double s)
903    {
904        return scale(v, (float)s);
905    }
906
907    inline Vector3 operator*(double s, Vector3::Arg v)
908    {
909        return scale(v, (float)s);
910    }
911
912    inline Vector3 operator/(Vector3::Arg v, double s)
913    {
914        return scale(v, 1.f/((float)s));
915    }
916
917#endif //NV_OS_IOS
918
919} // nv namespace
920
921#endif // NV_MATH_VECTOR_INL
922