-
Notifications
You must be signed in to change notification settings - Fork 1
/
MBEMathUtilities.m
149 lines (120 loc) · 3.83 KB
/
MBEMathUtilities.m
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
//
// MBEMathUtilities.m
// TextRendering
//
// Created by Warren Moore on 11/10/14.
// Copyright (c) 2014 Metal By Example. All rights reserved.
//
#import "MBEMathUtilities.h"
float random_float(float min, float max)
{
return min + (arc4random() / (float)UINT32_MAX) * (max - min);
}
vector_float3 vector_orthogonal(vector_float3 v)
{
// This algorithm is due to Sam Hocevar.
return fabs(v.x) > fabs(v.z) ? (vector_float3){ -v.y, v.x, 0.0 } : (vector_float3) { 0.0, -v.z, v.y };
}
matrix_float4x4 matrix_identity()
{
vector_float4 X = { 1, 0, 0, 0 };
vector_float4 Y = { 0, 1, 0, 0 };
vector_float4 Z = { 0, 0, 1, 0 };
vector_float4 W = { 0, 0, 0, 1 };
matrix_float4x4 identity = { X, Y, Z, W };
return identity;
}
matrix_float4x4 matrix_rotation(vector_float3 axis, float angle)
{
float c = cos(angle);
float s = sin(angle);
vector_float4 X;
X.x = axis.x * axis.x + (1 - axis.x * axis.x) * c;
X.y = axis.x * axis.y * (1 - c) - axis.z*s;
X.z = axis.x * axis.z * (1 - c) + axis.y * s;
X.w = 0.0;
vector_float4 Y;
Y.x = axis.x * axis.y * (1 - c) + axis.z * s;
Y.y = axis.y * axis.y + (1 - axis.y * axis.y) * c;
Y.z = axis.y * axis.z * (1 - c) - axis.x * s;
Y.w = 0.0;
vector_float4 Z;
Z.x = axis.x * axis.z * (1 - c) - axis.y * s;
Z.y = axis.y * axis.z * (1 - c) + axis.x * s;
Z.z = axis.z * axis.z + (1 - axis.z * axis.z) * c;
Z.w = 0.0;
vector_float4 W;
W.x = 0.0;
W.y = 0.0;
W.z = 0.0;
W.w = 1.0;
matrix_float4x4 mat = { X, Y, Z, W };
return mat;
}
matrix_float4x4 matrix_translation(vector_float3 t) __attribute((overloadable))
{
vector_float4 X = { 1, 0, 0, 0 };
vector_float4 Y = { 0, 1, 0, 0 };
vector_float4 Z = { 0, 0, 1, 0 };
vector_float4 W = { t.x, t.y, t.z, 1 };
matrix_float4x4 mat = { X, Y, Z, W };
return mat;
}
matrix_float4x4 matrix_scale(vector_float3 s) __attribute((overloadable))
{
vector_float4 X = { s.x, 0, 0, 0 };
vector_float4 Y = { 0, s.y, 0, 0 };
vector_float4 Z = { 0, 0, s.z, 0 };
vector_float4 W = { 0, 0, 0, 1 };
matrix_float4x4 mat = { X, Y, Z, W };
return mat;
}
matrix_float4x4 matrix_uniform_scale(float s)
{
vector_float4 X = { s, 0, 0, 0 };
vector_float4 Y = { 0, s, 0, 0 };
vector_float4 Z = { 0, 0, s, 0 };
vector_float4 W = { 0, 0, 0, 1 };
matrix_float4x4 mat = { X, Y, Z, W };
return mat;
}
matrix_float4x4 matrix_perspective_projection(float aspect, float fovy, float near, float far)
{
float yScale = 1 / tan(fovy * 0.5);
float xScale = yScale / aspect;
float zRange = far - near;
float zScale = -(far + near) / zRange;
float wzScale = -2 * far * near / zRange;
vector_float4 P = { xScale, 0, 0, 0 };
vector_float4 Q = { 0, yScale, 0, 0 };
vector_float4 R = { 0, 0, zScale, -1 };
vector_float4 S = { 0, 0, wzScale, 0 };
matrix_float4x4 mat = { P, Q, R, S };
return mat;
}
matrix_float4x4 matrix_orthographic_projection(float left, float right, float top, float bottom)
{
float near = 0;
float far = 1;
float sx = 2 / (right - left);
float sy = 2 / (top - bottom);
float sz = 1 / (far - near);
float tx = (right + left) / (left - right);
float ty = (top + bottom) / (bottom - top);
float tz = near / (far - near);
vector_float4 P = { sx, 0, 0, 0 };
vector_float4 Q = { 0, sy, 0, 0 };
vector_float4 R = { 0, 0, sz, 0 };
vector_float4 S = { tx, ty, tz, 1 };
matrix_float4x4 mat = { P, Q, R, S };
return mat;
}
matrix_float4x4 matrix_extract_linear(const matrix_float4x4 mat)
{
matrix_float4x4 lin = mat;
lin.columns[0][3] = 0;
lin.columns[1][3] = 0;
lin.columns[2][3] = 0;
lin.columns[3] = (vector_float4){ 0, 0, 0, 1 };
return lin;
}