|
1 | 1 | import { Matrix } from "@galacean/engine-math";
|
2 | 2 |
|
3 | 3 | export class Utils {
|
4 |
| - /** |
5 |
| - * @internal |
6 |
| - */ |
7 |
| - static _floatMatrixMultiply(left: Matrix, re: Float32Array, rOffset: number, oe: Float32Array, offset: number): void { |
8 |
| - const le = left.elements; |
9 |
| - |
10 |
| - // prettier-ignore |
11 |
| - const l11 = le[0], l12 = le[1], l13 = le[2], l14 = le[3], |
12 |
| - l21 = le[4], l22 = le[5], l23 = le[6], l24 = le[7], |
13 |
| - l31 = le[8], l32 = le[9], l33 = le[10], l34 = le[11], |
14 |
| - l41 = le[12], l42 = le[13], l43 = le[14], l44 = le[15]; |
15 |
| - |
16 |
| - // prettier-ignore |
17 |
| - const r11 = re[rOffset], r12 = re[rOffset + 1], r13 = re[rOffset + 2], r14 = re[rOffset + 3], |
18 |
| - r21 = re[rOffset + 4], r22 = re[rOffset + 5], r23 = re[rOffset + 6], r24 = re[rOffset + 7], |
19 |
| - r31 = re[rOffset + 8], r32 = re[rOffset + 9], r33 = re[rOffset + 10], r34 = re[rOffset + 11], |
20 |
| - r41 = re[rOffset + 12], r42 = re[rOffset + 13], r43 = re[rOffset + 14], r44 = re[rOffset + 15]; |
21 |
| - |
22 |
| - oe[offset] = l11 * r11 + l21 * r12 + l31 * r13 + l41 * r14; |
23 |
| - oe[offset + 1] = l12 * r11 + l22 * r12 + l32 * r13 + l42 * r14; |
24 |
| - oe[offset + 2] = l13 * r11 + l23 * r12 + l33 * r13 + l43 * r14; |
25 |
| - oe[offset + 3] = l14 * r11 + l24 * r12 + l34 * r13 + l44 * r14; |
26 |
| - |
27 |
| - oe[offset + 4] = l11 * r21 + l21 * r22 + l31 * r23 + l41 * r24; |
28 |
| - oe[offset + 5] = l12 * r21 + l22 * r22 + l32 * r23 + l42 * r24; |
29 |
| - oe[offset + 6] = l13 * r21 + l23 * r22 + l33 * r23 + l43 * r24; |
30 |
| - oe[offset + 7] = l14 * r21 + l24 * r22 + l34 * r23 + l44 * r24; |
31 |
| - |
32 |
| - oe[offset + 8] = l11 * r31 + l21 * r32 + l31 * r33 + l41 * r34; |
33 |
| - oe[offset + 9] = l12 * r31 + l22 * r32 + l32 * r33 + l42 * r34; |
34 |
| - oe[offset + 10] = l13 * r31 + l23 * r32 + l33 * r33 + l43 * r34; |
35 |
| - oe[offset + 11] = l14 * r31 + l24 * r32 + l34 * r33 + l44 * r34; |
36 |
| - |
37 |
| - oe[offset + 12] = l11 * r41 + l21 * r42 + l31 * r43 + l41 * r44; |
38 |
| - oe[offset + 13] = l12 * r41 + l22 * r42 + l32 * r43 + l42 * r44; |
39 |
| - oe[offset + 14] = l13 * r41 + l23 * r42 + l33 * r43 + l43 * r44; |
40 |
| - oe[offset + 15] = l14 * r41 + l24 * r42 + l34 * r43 + l44 * r44; |
41 |
| - } |
42 |
| - |
43 |
| - /** |
44 |
| - * @internal |
45 |
| - * Simplify lodash get: https://github.com/lodash/lodash/blob/master/get.js. |
46 |
| - * @param target - The object to query. |
47 |
| - * @param path - The path of the property to get. |
48 |
| - * @returns Returns the resolved value. |
49 |
| - */ |
50 |
| - static _reflectGet(target: Object, path: string) { |
51 |
| - const pathArr = this._stringToPath(path); |
52 |
| - |
53 |
| - let object = target; |
54 |
| - let index = 0; |
55 |
| - const length = pathArr.length; |
56 |
| - |
57 |
| - while (object != null && index < length) { |
58 |
| - object = object[pathArr[index++]]; |
59 |
| - } |
60 |
| - return index && index == length ? object : undefined; |
61 |
| - } |
62 |
| - |
63 | 4 | /**
|
64 | 5 | * Fast remove an element from array.
|
65 | 6 | * @param array - Array
|
@@ -127,6 +68,152 @@ export class Utils {
|
127 | 68 | return baseUrl.substring(0, baseUrl.lastIndexOf("/") + 1) + this._formatRelativePath(relativeUrl);
|
128 | 69 | }
|
129 | 70 |
|
| 71 | + /** |
| 72 | + * @internal |
| 73 | + */ |
| 74 | + static _floatMatrixMultiply(left: Matrix, re: Float32Array, rOffset: number, oe: Float32Array, offset: number): void { |
| 75 | + const le = left.elements; |
| 76 | + |
| 77 | + // prettier-ignore |
| 78 | + const l11 = le[0], l12 = le[1], l13 = le[2], l14 = le[3], |
| 79 | + l21 = le[4], l22 = le[5], l23 = le[6], l24 = le[7], |
| 80 | + l31 = le[8], l32 = le[9], l33 = le[10], l34 = le[11], |
| 81 | + l41 = le[12], l42 = le[13], l43 = le[14], l44 = le[15]; |
| 82 | + |
| 83 | + // prettier-ignore |
| 84 | + const r11 = re[rOffset], r12 = re[rOffset + 1], r13 = re[rOffset + 2], r14 = re[rOffset + 3], |
| 85 | + r21 = re[rOffset + 4], r22 = re[rOffset + 5], r23 = re[rOffset + 6], r24 = re[rOffset + 7], |
| 86 | + r31 = re[rOffset + 8], r32 = re[rOffset + 9], r33 = re[rOffset + 10], r34 = re[rOffset + 11], |
| 87 | + r41 = re[rOffset + 12], r42 = re[rOffset + 13], r43 = re[rOffset + 14], r44 = re[rOffset + 15]; |
| 88 | + |
| 89 | + oe[offset] = l11 * r11 + l21 * r12 + l31 * r13 + l41 * r14; |
| 90 | + oe[offset + 1] = l12 * r11 + l22 * r12 + l32 * r13 + l42 * r14; |
| 91 | + oe[offset + 2] = l13 * r11 + l23 * r12 + l33 * r13 + l43 * r14; |
| 92 | + oe[offset + 3] = l14 * r11 + l24 * r12 + l34 * r13 + l44 * r14; |
| 93 | + |
| 94 | + oe[offset + 4] = l11 * r21 + l21 * r22 + l31 * r23 + l41 * r24; |
| 95 | + oe[offset + 5] = l12 * r21 + l22 * r22 + l32 * r23 + l42 * r24; |
| 96 | + oe[offset + 6] = l13 * r21 + l23 * r22 + l33 * r23 + l43 * r24; |
| 97 | + oe[offset + 7] = l14 * r21 + l24 * r22 + l34 * r23 + l44 * r24; |
| 98 | + |
| 99 | + oe[offset + 8] = l11 * r31 + l21 * r32 + l31 * r33 + l41 * r34; |
| 100 | + oe[offset + 9] = l12 * r31 + l22 * r32 + l32 * r33 + l42 * r34; |
| 101 | + oe[offset + 10] = l13 * r31 + l23 * r32 + l33 * r33 + l43 * r34; |
| 102 | + oe[offset + 11] = l14 * r31 + l24 * r32 + l34 * r33 + l44 * r34; |
| 103 | + |
| 104 | + oe[offset + 12] = l11 * r41 + l21 * r42 + l31 * r43 + l41 * r44; |
| 105 | + oe[offset + 13] = l12 * r41 + l22 * r42 + l32 * r43 + l42 * r44; |
| 106 | + oe[offset + 14] = l13 * r41 + l23 * r42 + l33 * r43 + l43 * r44; |
| 107 | + oe[offset + 15] = l14 * r41 + l24 * r42 + l34 * r43 + l44 * r44; |
| 108 | + } |
| 109 | + |
| 110 | + /** |
| 111 | + * @internal |
| 112 | + * Simplify lodash get: https://github.com/lodash/lodash/blob/master/get.js. |
| 113 | + * @param target - The object to query. |
| 114 | + * @param path - The path of the property to get. |
| 115 | + * @returns Returns the resolved value. |
| 116 | + */ |
| 117 | + static _reflectGet(target: Object, path: string) { |
| 118 | + const pathArr = this._stringToPath(path); |
| 119 | + |
| 120 | + let object = target; |
| 121 | + let index = 0; |
| 122 | + const length = pathArr.length; |
| 123 | + |
| 124 | + while (object != null && index < length) { |
| 125 | + object = object[pathArr[index++]]; |
| 126 | + } |
| 127 | + return index && index == length ? object : undefined; |
| 128 | + } |
| 129 | + |
| 130 | + /** |
| 131 | + * @internal |
| 132 | + * @remarks |
| 133 | + * Modified based on v8. |
| 134 | + * https://github.com/v8/v8/blob/7.2-lkgr/src/js/array.js |
| 135 | + */ |
| 136 | + static _quickSort<T>(a: T[], from: number, to: number, compareFunc: Function): void { |
| 137 | + while (true) { |
| 138 | + // Insertion sort is faster for short arrays. |
| 139 | + if (to - from <= 10) { |
| 140 | + this._insertionSort(a, from, to, compareFunc); |
| 141 | + return; |
| 142 | + } |
| 143 | + const third_index = (from + to) >> 1; |
| 144 | + // Find a pivot as the median of first, last and middle element. |
| 145 | + let v0 = a[from]; |
| 146 | + let v1 = a[to - 1]; |
| 147 | + let v2 = a[third_index]; |
| 148 | + const c01 = compareFunc(v0, v1); |
| 149 | + if (c01 > 0) { |
| 150 | + // v1 < v0, so swap them. |
| 151 | + const tmp = v0; |
| 152 | + v0 = v1; |
| 153 | + v1 = tmp; |
| 154 | + } // v0 <= v1. |
| 155 | + const c02 = compareFunc(v0, v2); |
| 156 | + if (c02 >= 0) { |
| 157 | + // v2 <= v0 <= v1. |
| 158 | + const tmp = v0; |
| 159 | + v0 = v2; |
| 160 | + v2 = v1; |
| 161 | + v1 = tmp; |
| 162 | + } else { |
| 163 | + // v0 <= v1 && v0 < v2 |
| 164 | + const c12 = compareFunc(v1, v2); |
| 165 | + if (c12 > 0) { |
| 166 | + // v0 <= v2 < v1 |
| 167 | + const tmp = v1; |
| 168 | + v1 = v2; |
| 169 | + v2 = tmp; |
| 170 | + } |
| 171 | + } |
| 172 | + // v0 <= v1 <= v2 |
| 173 | + a[from] = v0; |
| 174 | + a[to - 1] = v2; |
| 175 | + const pivot = v1; |
| 176 | + let low_end = from + 1; // Upper bound of elements lower than pivot. |
| 177 | + let high_start = to - 1; // Lower bound of elements greater than pivot. |
| 178 | + a[third_index] = a[low_end]; |
| 179 | + a[low_end] = pivot; |
| 180 | + |
| 181 | + // From low_end to i are elements equal to pivot. |
| 182 | + // From i to high_start are elements that haven't been compared yet. |
| 183 | + partition: for (let i = low_end + 1; i < high_start; i++) { |
| 184 | + let element = a[i]; |
| 185 | + let order = compareFunc(element, pivot); |
| 186 | + if (order < 0) { |
| 187 | + a[i] = a[low_end]; |
| 188 | + a[low_end] = element; |
| 189 | + low_end++; |
| 190 | + } else if (order > 0) { |
| 191 | + do { |
| 192 | + high_start--; |
| 193 | + if (high_start == i) break partition; |
| 194 | + const top_elem = a[high_start]; |
| 195 | + order = compareFunc(top_elem, pivot); |
| 196 | + } while (order > 0); |
| 197 | + a[i] = a[high_start]; |
| 198 | + a[high_start] = element; |
| 199 | + if (order < 0) { |
| 200 | + element = a[i]; |
| 201 | + a[i] = a[low_end]; |
| 202 | + a[low_end] = element; |
| 203 | + low_end++; |
| 204 | + } |
| 205 | + } |
| 206 | + } |
| 207 | + if (to - high_start < low_end - from) { |
| 208 | + this._quickSort(a, high_start, to, compareFunc); |
| 209 | + to = low_end; |
| 210 | + } else { |
| 211 | + this._quickSort(a, from, low_end, compareFunc); |
| 212 | + from = high_start; |
| 213 | + } |
| 214 | + } |
| 215 | + } |
| 216 | + |
130 | 217 | private static _stringToPath(string): string[] {
|
131 | 218 | const result = [];
|
132 | 219 | if (string.charCodeAt(0) === charCodeOfDot) {
|
@@ -156,6 +243,23 @@ export class Utils {
|
156 | 243 | }, [])
|
157 | 244 | .join("/");
|
158 | 245 | }
|
| 246 | + |
| 247 | + private static _insertionSort<T>(a: T[], from: number, to: number, compareFunc: Function): void { |
| 248 | + for (let i = from + 1; i < to; i++) { |
| 249 | + let j; |
| 250 | + const element = a[i]; |
| 251 | + for (j = i - 1; j >= from; j--) { |
| 252 | + const tmp = a[j]; |
| 253 | + const order = compareFunc(tmp, element); |
| 254 | + if (order > 0) { |
| 255 | + a[j + 1] = tmp; |
| 256 | + } else { |
| 257 | + break; |
| 258 | + } |
| 259 | + } |
| 260 | + a[j + 1] = element; |
| 261 | + } |
| 262 | + } |
159 | 263 | }
|
160 | 264 |
|
161 | 265 | const charCodeOfDot = ".".charCodeAt(0);
|
|
0 commit comments