summaryrefslogtreecommitdiff
path: root/thirdparty/thekla_atlas/nvmath/Vector.h
blob: ad18672a8a09da609fb392fbb49e349fb7bd9ec1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// This code is in the public domain -- castanyo@yahoo.es

#pragma once
#ifndef NV_MATH_VECTOR_H
#define NV_MATH_VECTOR_H

#include "nvmath.h"

namespace nv
{
    class NVMATH_CLASS Vector2
    {
    public:
        typedef Vector2 const & Arg;

        Vector2();
        explicit Vector2(float f);
        Vector2(float x, float y);
        Vector2(Vector2::Arg v);

        //template <typename T> explicit Vector2(const T & v) : x(v.x), y(v.y) {}
        //template <typename T> operator T() const { return T(x, y); }

        const Vector2 & operator=(Vector2::Arg v);

        const float * ptr() const;

        void set(float x, float y);

        Vector2 operator-() const;
        void operator+=(Vector2::Arg v);
        void operator-=(Vector2::Arg v);
        void operator*=(float s);
        void operator*=(Vector2::Arg v);

        friend bool operator==(Vector2::Arg a, Vector2::Arg b);
        friend bool operator!=(Vector2::Arg a, Vector2::Arg b);

        union {
            struct {
                float x, y;
            };
            float component[2];
        };
    };

    class NVMATH_CLASS Vector3
    {
    public:
        typedef Vector3 const & Arg;

        Vector3();
        explicit Vector3(float x);
        //explicit Vector3(int x) : x(float(x)), y(float(x)), z(float(x)) {}
        Vector3(float x, float y, float z);
        Vector3(Vector2::Arg v, float z);
        Vector3(Vector3::Arg v);

        //template <typename T> explicit Vector3(const T & v) : x(v.x), y(v.y), z(v.z) {}
        //template <typename T> operator T() const { return T(x, y, z); }

        const Vector3 & operator=(Vector3::Arg v);

        Vector2 xy() const;

        const float * ptr() const;

        void set(float x, float y, float z);

        Vector3 operator-() const;
        void operator+=(Vector3::Arg v);
        void operator-=(Vector3::Arg v);
        void operator*=(float s);
        void operator/=(float s);
        void operator*=(Vector3::Arg v);
        void operator/=(Vector3::Arg v);

        friend bool operator==(Vector3::Arg a, Vector3::Arg b);
        friend bool operator!=(Vector3::Arg a, Vector3::Arg b);

        union {
            struct {
                float x, y, z;
            };
            float component[3];
        };
    };

    class NVMATH_CLASS Vector4
    {
    public:
        typedef Vector4 const & Arg;

        Vector4();
        explicit Vector4(float x);
        Vector4(float x, float y, float z, float w);
        Vector4(Vector2::Arg v, float z, float w);
        Vector4(Vector2::Arg v, Vector2::Arg u);
        Vector4(Vector3::Arg v, float w);
        Vector4(Vector4::Arg v);
        //	Vector4(const Quaternion & v);

        //template <typename T> explicit Vector4(const T & v) : x(v.x), y(v.y), z(v.z), w(v.w) {}
        //template <typename T> operator T() const { return T(x, y, z, w); }

        const Vector4 & operator=(Vector4::Arg v);

        Vector2 xy() const;
        Vector2 zw() const;
        Vector3 xyz() const;

        const float * ptr() const;

        void set(float x, float y, float z, float w);

        Vector4 operator-() const;
        void operator+=(Vector4::Arg v);
        void operator-=(Vector4::Arg v);
        void operator*=(float s);
        void operator/=(float s);
        void operator*=(Vector4::Arg v);
        void operator/=(Vector4::Arg v);

        friend bool operator==(Vector4::Arg a, Vector4::Arg b);
        friend bool operator!=(Vector4::Arg a, Vector4::Arg b);

        union {
            struct {
                float x, y, z, w;
            };
            float component[4];
        };
    };

} // nv namespace

// If we had these functions, they would be ambiguous, the compiler would not know which one to pick:
//template <typename T> Vector2 to(const T & v) { return Vector2(v.x, v.y); }
//template <typename T> Vector3 to(const T & v) { return Vector3(v.x, v.y, v.z); }
//template <typename T> Vector4 to(const T & v) { return Vector4(v.x, v.y, v.z, v.z); }

// We could use a cast operator so that we could infer the expected type, but that doesn't work the same way in all compilers and produces horrible error messages.

// Instead we simply have explicit casts:
template <typename T> T to(const nv::Vector2 & v) { NV_COMPILER_CHECK(sizeof(T) == sizeof(nv::Vector2)); return T(v.x, v.y); }
template <typename T> T to(const nv::Vector3 & v) { NV_COMPILER_CHECK(sizeof(T) == sizeof(nv::Vector3)); return T(v.x, v.y, v.z); }
template <typename T> T to(const nv::Vector4 & v) { NV_COMPILER_CHECK(sizeof(T) == sizeof(nv::Vector4)); return T(v.x, v.y, v.z, v.w); }

#endif // NV_MATH_VECTOR_H