-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmath.qc
134 lines (110 loc) · 2.83 KB
/
math.qc
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
// General-purpose math functions
static const float MIN_ANG = -180;
static const float MAX_ANG = 180;
const float NAN = 0/0;
const float INF = 1/0;
float(float x) isnan = {
return x != x;
};
float(float x) isfinite = {
return x == x && x != INF && x != -INF;
};
float(float a, float b) max = {
if (a > b) {
return a;
} else {
return b;
}
};
float(float a, float b) min = {
if (a < b) {
return a;
} else {
return b;
}
};
float(float a, float b) mod = {
return a - floor(a / b) * b;
};
// reflect incident over normal, dampening it against the normal
vector(vector incident, vector normal, float dampening) reflect = {
// project incident along normal
float d = incident * normal;
vector p = d * normal;
vector i2p = p - incident;
vector reflected = incident + 2 * i2p;
return reflected - d * dampening * normal;
};
float(float in, float min, float max) wrap = {
return mod(in - min, max - min) + min;
};
vector(vector in) normalize_angles = {
vector out;
float flip = 0;
out_x = wrap(in_x, MIN_ANG, MAX_ANG);
if (out_x < -90 || out_x > 90) {
if (out_x < -90) {
out_x = -180 - out_x;
} else {
out_x = 180 - out_x;
}
flip = 180;
}
out_y = wrap(in_y + flip, MIN_ANG, MAX_ANG);
out_z = wrap(in_z + flip, MIN_ANG, MAX_ANG);
return out;
};
vector(vector in) normalize_delta_angles = {
vector out;
out_x = wrap(in_x, MIN_ANG, MAX_ANG);
out_y = wrap(in_y, MIN_ANG, MAX_ANG);
out_z = wrap(in_z, MIN_ANG, MAX_ANG);
return out;
};
/*
* Find the sqrt of an integer by leveraging vlen in O(log x) instructions
*/
float(float x) isqrt {
float quot, rem, rt;
quot = floor(x/2);
rem = x - quot * 2;
if (quot > 1) {
rt = isqrt(quot);
return vlen([rt, rt, rem]);
} else {
return vlen([quot, quot, rem]);
}
};
/*
* Approximate the sqrt of a number in O(log x) instructions
*/
float(float x) sqrt {
// boost precision for low values while avoiding saturation on high values
if (x < 256) {
return isqrt(rint(x * 256)) / 16;
} else if (x <= 0xFFFFFF) { // check for EXCEEDINGLY large values
return isqrt(rint(x));
} else {
return isqrt(x);
}
};
/* Find the roots to a quadratic equation
* a - Quadratic coefficient
* b - Linear coefficient
* c - Constant coefficient
*
* Roots are returned as _x and _y of vector, or 1 is returned for _z of vector
*/
vector(float a, float b, float c) quadratic {
float det, det_sqrt;
vector ret_vec;
det = b*b - 4 * a * c;
if (det < 0) {
return [NAN, NAN, 1];
}
ret_vec = '0 0 0';
det_sqrt = sqrt(det);
ret_vec_x = (-b + det_sqrt) / 2 / a;
ret_vec_y = (-b - det_sqrt) / 2 / a;
return ret_vec;
};