aboutsummaryrefslogtreecommitdiff
path: root/src/math/mat4.h
blob: adb20592deafe1e6a99c2e4bc1bb9f555daab795 (plain) (blame)
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
150
151
152
153
154
155
156
157
158
159
#ifndef MATH_MAT4_H
#define MATH_MAT4_H

#include <array>
#include <cmath>
#include "math/vector.h"

namespace engine::math {

struct Matrix4 {
    static constexpr Matrix4 idty() {
        return {
            1.f, 0.f, 0.f, 0.f,
            0.f, 1.f, 0.f, 0.f,
            0.f, 0.f, 1.f, 0.f,
            0.f, 0.f, 0.f, 1.f,
        };
    }

    static constexpr Matrix4 translate(const Vector3& v) {
        return {
            1.f, 0.f, 0.f, v.x,
            0.f, 1.f, 0.f, v.y,
            0.f, 0.f, 1.f, v.z,
            0.f, 0.f, 0.f, 1.f,
        };
    }

    static constexpr Matrix4 scale(float fac) {
        return {
            fac, 0.f, 0.f, 0.f,
            0.f, fac, 0.f, 0.f,
            0.f, 0.f, fac, 0.f,
            0.f, 0.f, 0.f, 1.f,
        };
    }

    static constexpr Matrix4 scale(const Vector3& facs) {
        return {
            facs.x,    0.f,    0.f, 0.f,
               0.f, facs.y,    0.f, 0.f,
               0.f,    0.f, facs.z, 0.f,
               0.f,    0.f,    0.f, 1.f,
        };
    }

    static constexpr Matrix4 rot_x(float a) {
        float c = std::cos(a);
        float s = std::sin(a);
        return {
            1.f, 0.f, 0.f, 0.f,
            0.f,   c,  -s, 0.f,
            0.f,   s,   c, 0.f,
            0.f, 0.f, 0.f, 1.f,
        };
    }

    static constexpr Matrix4 rot_y(float a) {
        float c = std::cos(a);
        float s = std::sin(a);
        return {
              c, 0.f,   s, 0.f,
            0.f, 1.f, 0.f, 0.f,
             -s, 0.f,   c, 0.f,
            0.f, 0.f, 0.f, 1.f,
        };
    }

    static constexpr Matrix4 rot_z(float a) {
        float c = std::cos(a);
        float s = std::sin(a);
        return {
              c,  -s, 0.f, 0.f,
              s,   c, 0.f, 0.f,
            0.f, 0.f, 1.f, 0.f,
            0.f, 0.f, 0.f, 1.f,
        };
    }

    static constexpr Matrix4 projection(float aspect_ratio, float min_z, float max_z) {
        return {{
            aspect_ratio, 0.f, 0.f, 0.f,
            0.f, -1.f, 0.f, 0.f,
            0.f, 0.f, -2.f / (max_z - min_z), -(max_z + min_z) / (max_z - min_z),
            0.f, 0.f, -1.f, 0.f,
        }};
    }

    std::array<float, 4 * 4> values;

    constexpr Matrix4 operator+() const & {
        return *this;
    }

    constexpr Matrix4 operator-() const & {
        return {
            -values[ 0], -values[ 1], -values[ 2], -values[ 3],
            -values[ 4], -values[ 5], -values[ 6], -values[ 7],
            -values[ 8], -values[ 9], -values[10], -values[11],
            -values[12], -values[13], -values[14], -values[15],
        };
    }

    constexpr Matrix4 operator+(const Matrix4& m) const & {
        return {
            values[ 0] + m.values[ 0], values[ 1] + m.values[ 1], values[ 2] + m.values[ 2], values[ 3] + m.values[ 3],
            values[ 4] + m.values[ 4], values[ 5] + m.values[ 5], values[ 6] + m.values[ 6], values[ 7] + m.values[ 7],
            values[ 8] + m.values[ 8], values[ 9] + m.values[ 9], values[10] + m.values[10], values[11] + m.values[11],
            values[12] + m.values[12], values[13] + m.values[13], values[14] + m.values[14], values[15] + m.values[15],
        };
    }

    constexpr Matrix4 operator-(const Matrix4& m) const & {
        return *this + (-m);
    }

    constexpr Matrix4 operator*(const Matrix4& m) const & {
        Matrix4 ret;
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                ret.values[i * 4 + j] = 0.f;
                for (int k = 0; k < 4; k++)
                    ret.values[i * 4 + j] += values[i * 4 + k] * m.values[k * 4 + j];
            }
        }
        return ret;
    }

    constexpr Vector4 operator*(const Vector4& v) const & {
        return {
            values[ 0] * v.x + values[ 1] * v.y + values[ 2] * v.z + values[ 3] * v.w,
            values[ 4] * v.x + values[ 5] * v.y + values[ 6] * v.z + values[ 7] * v.w,
            values[ 8] * v.x + values[ 9] * v.y + values[10] * v.z + values[11] * v.w,
            values[12] * v.x + values[13] * v.y + values[14] * v.z + values[15] * v.w,
        };
    }

    constexpr std::array<Vector4, 4> to_vecs() const & {
        return {{
            { values[ 0], values[ 4], values[ 8], values[12] },
            { values[ 1], values[ 5], values[ 9], values[13] },
            { values[ 2], values[ 6], values[10], values[14] },
            { values[ 3], values[ 7], values[11], values[15] },
        }};
    }
};

constexpr Matrix4 operator*(float fac, const Matrix4& m) {
    return {
        fac * m.values[ 0], fac * m.values[ 1], fac * m.values[ 2], fac * m.values[ 3],
        fac * m.values[ 4], fac * m.values[ 5], fac * m.values[ 6], fac * m.values[ 7],
        fac * m.values[ 8], fac * m.values[ 9], fac * m.values[10], fac * m.values[11],
        fac * m.values[12], fac * m.values[13], fac * m.values[14], fac * m.values[15],
    };
}

}

#endif // MATH_MAT4_H