master
ブランチ master
ShaderPlayground / include / util / matrix.hh
4.8 KB、228行 生 Blame 履歴
1/*
2# 076 Free License
3
4Copyright (c) テクニカル諏訪子
5
6Permission is hereby granted to any person obtaining a copy of the software
7C++ Utils (the "Software") to use, modify, merge, copy, publish, distribute,
8sublicense, and/or sell copies of the Software, subject to the following conditions:
9
10 1. **Origin Attribution**:
11 - You must not misrepresent the origin of the Software; you must not claim
12 you created the original Software.
13 2. **Notice Preservation**:
14 - This license and the above copyright notice must remain intact in all copies
15 of the source code.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
19PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
21CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23*/
24#ifndef MATRIX_HH
25#define MATRIX_HH
26
27#include <util/types.hh>
28#include <util/vector.hh>
29
30typedef struct {
31 f32 m[16];
32} Matrix4;
33
34typedef struct {
35 f32 m[16];
36} Matrix4x4;
37
38typedef struct {
39 f32 m[12];
40} Matrix4x3;
41
42inline Matrix4 operator*(const Matrix4 &a, const Matrix4 &b) {
43 Matrix4 out = {};
44
45 for (int i = 0; i < 4; ++i) {
46 for (int j = 0; j < 4; ++j) {
47 float sum = 0.0f;
48 for (int k = 0; k < 4; ++k) {
49 sum += a.m[i + k * 4] * b.m[k + j * 4];
50 }
51 out.m[i + j * 4] = sum;
52 }
53 }
54 return out;
55}
56
57inline Matrix4 &operator*=(Matrix4 &a, const Matrix4 &b) {
58 a = a * b;
59 return a;
60}
61
62inline Matrix4 mat4Identity() {
63 Matrix4 out{};
64
65 out.m[0] = 1.f;
66 out.m[5] = 1.f;
67 out.m[10] = 1.f;
68 out.m[15] = 1.f;
69
70 return out;
71}
72
73inline Matrix4x4 mat4x4Identity() {
74 Matrix4x4 out{};
75
76 out.m[0] = 1.f;
77 out.m[5] = 1.f;
78 out.m[10] = 1.f;
79 out.m[15] = 1.f;
80
81 return out;
82}
83
84inline Matrix4 mat4Mul(const Matrix4 &a, const Matrix4 &b) {
85 Matrix4 out{};
86
87 for (int row = 0; row < 4; ++row) {
88 for (int col = 0; col < 4; ++col) {
89 out.m[col * 4 + row] =
90 a.m[0 * 4 + row] * b.m[col * 4 + 0] +
91 a.m[1 * 4 + row] * b.m[col * 4 + 1] +
92 a.m[2 * 4 + row] * b.m[col * 4 + 2] +
93 a.m[3 * 4 + row] * b.m[col * 4 + 3];
94 }
95 }
96
97 return out;
98}
99
100inline Matrix4 mat4Translate(f32 x, f32 y, f32 z) {
101 Matrix4 out = mat4Identity();
102
103 out.m[12] = x;
104 out.m[13] = y;
105 out.m[14] = z;
106
107 return out;
108}
109
110inline Matrix4 mat4Scale(f32 x, f32 y, f32 z) {
111 Matrix4 out = {};
112
113 out.m[0] = x;
114 out.m[5] = y;
115 out.m[10] = z;
116 out.m[15] = 1.f;
117
118 return out;
119}
120
121inline Matrix4 mat4RotateX(f32 angle) {
122 Matrix4 out = mat4Identity();
123
124 f32 c = cosf(angle);
125 f32 s = sinf(angle);
126
127 out.m[5] = c; // m[1][1]
128 out.m[6] = s; // m[1][2]
129 out.m[9] = -s; // m[2][1]
130 out.m[10] = c; // m[2][2]
131
132 return out;
133}
134
135inline Matrix4 mat4RotateY(f32 angle) {
136 Matrix4 out = mat4Identity();
137
138 f32 c = cosf(angle);
139 f32 s = sinf(angle);
140
141 out.m[0] = c; // m[0][0]
142 out.m[2] = -s; // m[0][2]
143 out.m[8] = s; // m[2][0]
144 out.m[10] = c; // m[2][2]
145
146 return out;
147}
148
149inline Matrix4 mat4RotateZ(f32 angle) {
150 Matrix4 out = mat4Identity();
151
152 f32 c = cosf(angle);
153 f32 s = sinf(angle);
154
155 out.m[0] = c; // m[0][0]
156 out.m[1] = s; // m[0][1]
157 out.m[4] = -s; // m[1][0]
158 out.m[5] = c; // m[1][1]
159
160 return out;
161}
162
163inline Matrix4 mat4Rotate(f32 pitch, f32 yaw, f32 roll) {
164 return mat4RotateZ(roll) * mat4RotateY(yaw) * mat4RotateX(pitch);
165}
166
167inline Matrix4 mat4Perspective(f32 fov, f32 aspect, f32 near, f32 far) {
168 Matrix4 out = {};
169 fov *= (3.14159265f / 180.f);
170
171 f32 tanHalf = tanf(fov * 0.5f);
172
173 out.m[0] = 1.f / (aspect * tanHalf);
174 out.m[5] = 1.f / tanHalf;
175 out.m[10] = -(far + near) / (far - near);
176 out.m[11] = -1.f;
177 out.m[14] = -(2.f * far * near) / (far - near);
178
179 return out;
180}
181
182inline Matrix4 mat4LookAt(Vector3 eye, Vector3 target, Vector3 up) {
183 Vector3 f = vec3Normalize(vec3Sub(target, eye));
184 Vector3 r = vec3Normalize(vec3Cross(f, up));
185 Vector3 u = vec3Cross(r, f);
186
187 Matrix4 out = {};
188
189 out.m[0] = r.pos.x;
190 out.m[1] = u.pos.x;
191 out.m[2] = -f.pos.x;
192 out.m[3] = 0.f;
193
194 out.m[4] = r.pos.y;
195 out.m[5] = u.pos.y;
196 out.m[6] = -f.pos.y;
197 out.m[7] = 0.f;
198
199 out.m[8] = r.pos.z;
200 out.m[9] = u.pos.z;
201 out.m[10] = -f.pos.z;
202 out.m[11] = 0.f;
203
204 out.m[12] = -vec3Dot(r, eye);
205 out.m[13] = -vec3Dot(u, eye);
206 out.m[14] = vec3Dot(f, eye);
207 out.m[15] = 1.f;
208
209 return out;
210}
211
212inline Matrix4 mat4Ortho(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far) {
213 Matrix4 m = {};
214
215 m.m[0] = 2.0f / (right - left);
216 m.m[5] = 2.0f / (top - bottom);
217 m.m[10] = -2.0f / (far - near);
218
219 m.m[12] = -(right + left) / (right - left);
220 m.m[13] = -(top + bottom) / (top - bottom);
221 m.m[14] = -(far + near) / (far - near);
222
223 m.m[15] = 1.0f;
224
225 return m;
226}
227
228#endif // MATRIX_HH