1/* 2 * Copyright (c) 2022-2023 Shenzhen Kaihong Digital Industry Development Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16const NO_INITIAL_VAL = -1; 17 18export class XMat4 { 19 constructor() { 20 this.unit(); 21 } 22 23 Get() { 24 return this.mat; 25 } 26 unit() { 27 this.mat = [ 28 [1, 0, 0, 0], 29 [0, 1, 0, 0], 30 [0, 0, 1, 0], 31 [0, 0, 0, 1], 32 ]; 33 return this; 34 } 35 copy(m) { 36 for (let i = 0; i < 4; i++) { 37 for (let j = 0; j < 4; j++) { 38 this.mat[i][j] = m.mat[i][j]; 39 } 40 } 41 } 42 initRotateMatX(hd) { 43 this.unit(); 44 let _cos = Math.cos(hd); 45 let _sin = Math.sin(hd); 46 this.mat[1][1] = _cos; 47 this.mat[1][2] = -_sin; 48 this.mat[2][1] = _sin; 49 this.mat[2][2] = _cos; 50 } 51 initRotateMatY(hd) { 52 this.unit(); 53 let _cos = Math.cos(hd); 54 let _sin = Math.sin(hd); 55 this.mat[0][0] = _cos; 56 this.mat[0][2] = -_sin; 57 this.mat[2][0] = _sin; 58 this.mat[2][2] = _cos; 59 } 60 61 initRotateMatZ(hd) { 62 this.unit(); 63 let _cos = Math.cos(hd); 64 let _sin = Math.sin(hd); 65 this.mat[0][0] = _cos; 66 this.mat[0][1] = -_sin; 67 this.mat[1][0] = _sin; 68 this.mat[1][1] = _cos; 69 } 70 initScaleMat(x, y, z) { 71 this.unit(); 72 this.mat[0][0] = x; 73 this.mat[1][1] = y; 74 this.mat[2][2] = z; 75 } 76 move(x, y, z = 0) { 77 this.mat[3][0] += x; 78 this.mat[3][1] += y; 79 this.mat[3][2] += z; 80 return this; 81 } 82 rotate(x, y, z) { 83 if (x !== 0) { 84 tmpmat.initRotateMatX((x * Math.PI) / 180); 85 this.mult(tmpmat); 86 } 87 if (y !== 0) { 88 tmpmat.initRotateMatY((y * Math.PI) / 180); 89 this.mult(tmpmat); 90 } 91 if (z !== 0) { 92 tmpmat.initRotateMatZ((z * Math.PI) / 180); 93 this.mult(tmpmat); 94 } 95 return this; 96 } 97 98 scale(x, y, z = 1) { 99 tmpmat.initScaleMat(x, y, z); 100 this.mult(tmpmat); 101 return this; 102 } 103 104 mult(m4) { 105 let tmp = [ 106 [1, 0, 0, 0], 107 [0, 1, 0, 0], 108 [0, 0, 1, 0], 109 [0, 0, 0, 1], 110 ]; 111 for (let i = 0; i < 4; i++) { 112 for (let j = 0; j < 4; j++) { 113 tmp[i][j] = 114 this.mat[i][0] * m4.mat[0][j] + 115 this.mat[i][1] * m4.mat[1][j] + 116 this.mat[i][2] * m4.mat[2][j] + 117 this.mat[i][3] * m4.mat[3][j]; 118 } 119 } 120 this.mat = tmp; 121 return this; 122 } 123 124 MultRight(m4) { 125 this.mat = np.dot(m4.mat, this.mat); 126 return this; 127 } 128 129 PerspectiveMatrix(n, f, w = NO_INITIAL_VAL, h = NO_INITIAL_VAL) { 130 if (w === NO_INITIAL_VAL) { 131 w = Scr.logicw; 132 } 133 if (h === NO_INITIAL_VAL) { 134 h = Scr.logich; 135 } 136 let ret = w / (tan((30 * pi) / 180) * 2); 137 this.unit(); 138 this.mat[0][0] = 2 / w; 139 this.mat[1][1] = 2 / h; 140 141 this.mat[2][2] = 1 / (f - n); 142 this.mat[2][3] = 1 / ret; //#2 / f 143 this.mat[3][2] = -n / (f - n); 144 this.mat[3][3] = 1; 145 return ret; 146 } 147 148 orthoMat(x, y, w, h) { 149 this.move(-w / 2 - x, -h / 2 - y, 0); 150 this.scale(2 / w, -2 / h, 0); 151 } 152 153 Make2DTransformMat(mx = 0, my = 0, sw = 1, sh = 1, ra = 0, ox = 0, oy = 0, realw = 0, realh = 0) { 154 const LEFT = -1; 155 const MIDDLE = -2; 156 const RIGHT = -3; 157 const UP = -1; 158 const DOWN = -3; 159 const BY_MIDDLE = 2; 160 this.unit(); 161 if (ox === LEFT) { 162 ox = 0; 163 } 164 if (ox === MIDDLE) { 165 ox = realw / BY_MIDDLE; 166 } 167 if (ox === RIGHT) { 168 ox = realw; 169 } 170 if (oy === UP) { 171 oy = 0; 172 } 173 if (oy === MIDDLE) { 174 oy = realh / BY_MIDDLE; 175 } 176 if (oy === DOWN) { 177 oy = realh; 178 } 179 if (ox !== 0 || oy !== 0) { 180 this.move(-ox, -oy, 0); 181 } 182 if (sw !== 1 || sh !== 1) { 183 this.scale(sw, sh, 1); 184 } 185 if (ra !== 0) { 186 this.rotate(0, 0, ra); 187 } 188 if (mx !== 0 || my !== 0) { 189 this.move(mx, my, 0); 190 } 191 } 192 193 Make2DTransformMat_(mx, my, sw, sh, ra, ox = 0, oy = 0) { 194 this.unit(); 195 if (mx !== 0 || my !== 0) { 196 this.move(-mx, -my, 0); 197 } 198 if (ra !== 0) { 199 this.rotate(0, 0, -ra); 200 } 201 if (sw !== 1 || sh !== 1) { 202 this.scale(1 / sw, 1 / sh, 1); 203 } 204 return this; 205 } 206} 207 208var tmpmat = new XMat4(); 209