14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ciexport class XMat4 {
174514f5e3Sopenharmony_ci  constructor() {
184514f5e3Sopenharmony_ci    this.unit();
194514f5e3Sopenharmony_ci  }
204514f5e3Sopenharmony_ci
214514f5e3Sopenharmony_ci  Get() {
224514f5e3Sopenharmony_ci    return this.mat;
234514f5e3Sopenharmony_ci  }
244514f5e3Sopenharmony_ci  unit() {
254514f5e3Sopenharmony_ci    this.mat = [
264514f5e3Sopenharmony_ci      [1, 0, 0, 0],
274514f5e3Sopenharmony_ci      [0, 1, 0, 0],
284514f5e3Sopenharmony_ci      [0, 0, 1, 0],
294514f5e3Sopenharmony_ci      [0, 0, 0, 1],
304514f5e3Sopenharmony_ci    ];
314514f5e3Sopenharmony_ci    return this;
324514f5e3Sopenharmony_ci  }
334514f5e3Sopenharmony_ci  copy(m) {
344514f5e3Sopenharmony_ci    for (let i = 0; i < 4; i++) {
354514f5e3Sopenharmony_ci      for (let j = 0; j < 4; j++) {
364514f5e3Sopenharmony_ci        this.mat[i][j] = m.mat[i][j];
374514f5e3Sopenharmony_ci      }
384514f5e3Sopenharmony_ci    }
394514f5e3Sopenharmony_ci  }
404514f5e3Sopenharmony_ci  initRotateMatX(hd) {
414514f5e3Sopenharmony_ci    this.unit();
424514f5e3Sopenharmony_ci    let _cos = Math.cos(hd);
434514f5e3Sopenharmony_ci    let _sin = Math.sin(hd);
444514f5e3Sopenharmony_ci    this.mat[1][1] = _cos;
454514f5e3Sopenharmony_ci    this.mat[1][2] = -_sin;
464514f5e3Sopenharmony_ci    this.mat[2][1] = _sin;
474514f5e3Sopenharmony_ci    this.mat[2][2] = _cos;
484514f5e3Sopenharmony_ci  }
494514f5e3Sopenharmony_ci  initRotateMatY(hd) {
504514f5e3Sopenharmony_ci    this.unit();
514514f5e3Sopenharmony_ci    let _cos = Math.cos(hd);
524514f5e3Sopenharmony_ci    let _sin = Math.sin(hd);
534514f5e3Sopenharmony_ci    this.mat[0][0] = _cos;
544514f5e3Sopenharmony_ci    this.mat[0][2] = -_sin;
554514f5e3Sopenharmony_ci    this.mat[2][0] = _sin;
564514f5e3Sopenharmony_ci    this.mat[2][2] = _cos;
574514f5e3Sopenharmony_ci  }
584514f5e3Sopenharmony_ci
594514f5e3Sopenharmony_ci  initRotateMatZ(hd) {
604514f5e3Sopenharmony_ci    this.unit();
614514f5e3Sopenharmony_ci    let _cos = Math.cos(hd);
624514f5e3Sopenharmony_ci    let _sin = Math.sin(hd);
634514f5e3Sopenharmony_ci    this.mat[0][0] = _cos;
644514f5e3Sopenharmony_ci    this.mat[0][1] = -_sin;
654514f5e3Sopenharmony_ci    this.mat[1][0] = _sin;
664514f5e3Sopenharmony_ci    this.mat[1][1] = _cos;
674514f5e3Sopenharmony_ci  }
684514f5e3Sopenharmony_ci  initScaleMat(x, y, z) {
694514f5e3Sopenharmony_ci    this.unit();
704514f5e3Sopenharmony_ci    this.mat[0][0] = x;
714514f5e3Sopenharmony_ci    this.mat[1][1] = y;
724514f5e3Sopenharmony_ci    this.mat[2][2] = z;
734514f5e3Sopenharmony_ci  }
744514f5e3Sopenharmony_ci  move(x, y, z = 0) {
754514f5e3Sopenharmony_ci    this.mat[3][0] += x;
764514f5e3Sopenharmony_ci    this.mat[3][1] += y;
774514f5e3Sopenharmony_ci    this.mat[3][2] += z;
784514f5e3Sopenharmony_ci    return this;
794514f5e3Sopenharmony_ci  }
804514f5e3Sopenharmony_ci  rotate(x, y, z) {
814514f5e3Sopenharmony_ci    if (x != 0) {
824514f5e3Sopenharmony_ci      tmpmat.initRotateMatX((x * Math.PI) / 180);
834514f5e3Sopenharmony_ci      this.mult(tmpmat);
844514f5e3Sopenharmony_ci    }
854514f5e3Sopenharmony_ci    if (y != 0) {
864514f5e3Sopenharmony_ci      tmpmat.initRotateMatY((y * Math.PI) / 180);
874514f5e3Sopenharmony_ci      this.mult(tmpmat);
884514f5e3Sopenharmony_ci    }
894514f5e3Sopenharmony_ci    if (z != 0) {
904514f5e3Sopenharmony_ci      tmpmat.initRotateMatZ((z * Math.PI) / 180);
914514f5e3Sopenharmony_ci      this.mult(tmpmat);
924514f5e3Sopenharmony_ci    }
934514f5e3Sopenharmony_ci    return this;
944514f5e3Sopenharmony_ci  }
954514f5e3Sopenharmony_ci
964514f5e3Sopenharmony_ci  scale(x, y, z = 1) {
974514f5e3Sopenharmony_ci    tmpmat.initScaleMat(x, y, z);
984514f5e3Sopenharmony_ci    this.mult(tmpmat);
994514f5e3Sopenharmony_ci    return this;
1004514f5e3Sopenharmony_ci  }
1014514f5e3Sopenharmony_ci
1024514f5e3Sopenharmony_ci  mult(m4) {
1034514f5e3Sopenharmony_ci    let tmp = [
1044514f5e3Sopenharmony_ci      [1, 0, 0, 0],
1054514f5e3Sopenharmony_ci      [0, 1, 0, 0],
1064514f5e3Sopenharmony_ci      [0, 0, 1, 0],
1074514f5e3Sopenharmony_ci      [0, 0, 0, 1],
1084514f5e3Sopenharmony_ci    ];
1094514f5e3Sopenharmony_ci    for (let i = 0; i < 4; i++) {
1104514f5e3Sopenharmony_ci      for (let j = 0; j < 4; j++) {
1114514f5e3Sopenharmony_ci        tmp[i][j] =
1124514f5e3Sopenharmony_ci          this.mat[i][0] * m4.mat[0][j] +
1134514f5e3Sopenharmony_ci          this.mat[i][1] * m4.mat[1][j] +
1144514f5e3Sopenharmony_ci          this.mat[i][2] * m4.mat[2][j] +
1154514f5e3Sopenharmony_ci          this.mat[i][3] * m4.mat[3][j];
1164514f5e3Sopenharmony_ci      }
1174514f5e3Sopenharmony_ci    }
1184514f5e3Sopenharmony_ci    this.mat = tmp;
1194514f5e3Sopenharmony_ci    return this;
1204514f5e3Sopenharmony_ci  }
1214514f5e3Sopenharmony_ci
1224514f5e3Sopenharmony_ci  MultRight(m4) {
1234514f5e3Sopenharmony_ci    this.mat = np.dot(m4.mat, this.mat);
1244514f5e3Sopenharmony_ci    return this;
1254514f5e3Sopenharmony_ci  }
1264514f5e3Sopenharmony_ci
1274514f5e3Sopenharmony_ci  PerspectiveMatrix(n, f, w = -1, h = -1) {
1284514f5e3Sopenharmony_ci    if (w == -1) w = Scr.logicw;
1294514f5e3Sopenharmony_ci    if (h == -1) h = Scr.logich;
1304514f5e3Sopenharmony_ci    let ret = w / (tan((30 * pi) / 180) * 2);
1314514f5e3Sopenharmony_ci    this.unit();
1324514f5e3Sopenharmony_ci    this.mat[0][0] = 2 / w;
1334514f5e3Sopenharmony_ci    this.mat[1][1] = 2 / h;
1344514f5e3Sopenharmony_ci
1354514f5e3Sopenharmony_ci    this.mat[2][2] = 1 / (f - n);
1364514f5e3Sopenharmony_ci    this.mat[2][3] = 1 / ret; //#2 / f
1374514f5e3Sopenharmony_ci    this.mat[3][2] = -n / (f - n);
1384514f5e3Sopenharmony_ci    this.mat[3][3] = 1;
1394514f5e3Sopenharmony_ci    return ret;
1404514f5e3Sopenharmony_ci  }
1414514f5e3Sopenharmony_ci
1424514f5e3Sopenharmony_ci  orthoMat(x, y, w, h) {
1434514f5e3Sopenharmony_ci    this.move(-w / 2 - x, -h / 2 - y, 0);
1444514f5e3Sopenharmony_ci    this.scale(2 / w, -2 / h, 0);
1454514f5e3Sopenharmony_ci  }
1464514f5e3Sopenharmony_ci
1474514f5e3Sopenharmony_ci  Make2DTransformMat(
1484514f5e3Sopenharmony_ci    mx = 0,
1494514f5e3Sopenharmony_ci    my = 0,
1504514f5e3Sopenharmony_ci    sw = 1,
1514514f5e3Sopenharmony_ci    sh = 1,
1524514f5e3Sopenharmony_ci    ra = 0,
1534514f5e3Sopenharmony_ci    ox = 0,
1544514f5e3Sopenharmony_ci    oy = 0,
1554514f5e3Sopenharmony_ci    realw = 0,
1564514f5e3Sopenharmony_ci    realh = 0
1574514f5e3Sopenharmony_ci  ) {
1584514f5e3Sopenharmony_ci    this.unit();
1594514f5e3Sopenharmony_ci    if (ox == -1) ox = 0;
1604514f5e3Sopenharmony_ci    if (ox == -2) ox = realw / 2;
1614514f5e3Sopenharmony_ci    if (ox == -3) ox = realw;
1624514f5e3Sopenharmony_ci    if (oy == -1) oy = 0;
1634514f5e3Sopenharmony_ci    if (oy == -2) oy = realh / 2;
1644514f5e3Sopenharmony_ci    if (oy == -3) oy = realh;
1654514f5e3Sopenharmony_ci    if (ox != 0 || oy != 0) this.move(-ox, -oy, 0);
1664514f5e3Sopenharmony_ci    if (sw != 1 || sh != 1) this.scale(sw, sh, 1);
1674514f5e3Sopenharmony_ci    if (ra != 0) this.rotate(0, 0, ra);
1684514f5e3Sopenharmony_ci    if (mx != 0 || my != 0) this.move(mx, my, 0);
1694514f5e3Sopenharmony_ci  }
1704514f5e3Sopenharmony_ci
1714514f5e3Sopenharmony_ci  Make2DTransformMat_(mx, my, sw, sh, ra, ox = 0, oy = 0) {
1724514f5e3Sopenharmony_ci    this.unit();
1734514f5e3Sopenharmony_ci    if (mx != 0 || my != 0) this.move(-mx, -my, 0);
1744514f5e3Sopenharmony_ci    if (ra != 0) this.rotate(0, 0, -ra);
1754514f5e3Sopenharmony_ci    if (sw != 1 || sh != 1) this.scale(1 / sw, 1 / sh, 1);
1764514f5e3Sopenharmony_ci    return this;
1774514f5e3Sopenharmony_ci  }
1784514f5e3Sopenharmony_ci}
1794514f5e3Sopenharmony_ci
1804514f5e3Sopenharmony_civar tmpmat = new XMat4();
181