• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"use strict";
2/*
3 * Copyright (c) 2022-2025 Huawei Device Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16Object.defineProperty(exports, "__esModule", { value: true });
17exports.Matrix44 = exports.mat44 = void 0;
18const compat_1 = require("#koalaui/compat");
19const Matrix33_1 = require("./Matrix33");
20const Point3_1 = require("./Point3");
21// TODO: this is because ArkTS doesn allow interface literal instances.
22class TranslateOptionsImpl {
23    get x() { return this._x; }
24    get y() { return this._y; }
25    get z() { return this._z; }
26    set x(x) { this._x = x; }
27    set y(y) { this._y = y; }
28    set z(z) { this._z = z; }
29    constructor(x, y, z) {
30        this._x = x;
31        this._y = y;
32        this._z = z;
33    }
34}
35function mat44(array) {
36    return (array == undefined) ? new Matrix44() : new Matrix44(array);
37}
38exports.mat44 = mat44;
39/**
40 * 4x4 matrix with right-handed coordinate system:
41 * +x goes to the right
42 * +y goes down
43 * +z goes into the screen (away from the viewer)
44 */
45class Matrix44 {
46    constructor(array = new Float32Array((0, compat_1.Array_from_number)([
47        1.0, 0.0, 0.0, 0.0,
48        0.0, 1.0, 0.0, 0.0,
49        0.0, 0.0, 1.0, 0.0,
50        0.0, 0.0, 0.0, 1.0
51    ]))) {
52        this.array = array.slice();
53    }
54    static identity() {
55        return mat44();
56    }
57    static zero() {
58        return mat44(new Float32Array((0, compat_1.Array_from_number)([
59            0.0, 0.0, 0.0, 0.0,
60            0.0, 0.0, 0.0, 0.0,
61            0.0, 0.0, 0.0, 0.0,
62            0.0, 0.0, 0.0, 0.0,
63        ])));
64    }
65    static lookAt(eye, center, up) {
66        const f = center.subtract(eye).normalize();
67        const u = up.normalize();
68        const s = f.cross(u).normalize();
69        const sf = s.cross(f);
70        return new Matrix44(new Float32Array((0, compat_1.Array_from_number)([
71            s.x, sf.x, -f.x, eye.x,
72            s.y, sf.y, -f.y, eye.y,
73            s.z, sf.z, -f.z, eye.z,
74            0, 0, 0, 1,
75        ]))).invert();
76    }
77    static perspective(depth) {
78        return new Matrix44(new Float32Array((0, compat_1.Array_from_number)([
79            1.0, 0.0, 0.0, 0.0,
80            0.0, 1.0, 0.0, 0.0,
81            0.0, 0.0, 1.0, 0.0,
82            0.0, 0.0, -1.0 / depth, 1.0,
83        ])));
84    }
85    static perspectiveFov(fov, near, far) {
86        const denomInv = (far - near);
87        const halfAngle = fov * 0.5;
88        const cot = Math.cos(halfAngle) / Math.sin(halfAngle);
89        return new Matrix44(new Float32Array((0, compat_1.Array_from_number)([
90            cot, 0.0, 0.0, 0.0,
91            0.0, cot, 0.0, 0.0,
92            0.0, 0.0, (far + near) * denomInv, 2 * far * near * denomInv,
93            0.0, 0.0, -1.0, 0.0,
94        ])));
95    }
96    /**
97     * Returns new matrix, made from Matrix33.
98     *
99     * @param matrix - 3x3 matrix
100     * @returns the new instance of Matrix44
101     *
102     */
103    static makeFromMatrix33(matrix) {
104        return new Matrix44(new Float32Array((0, compat_1.Array_from_number)([
105            matrix.array[0], matrix.array[1], 0.0, matrix.array[2],
106            matrix.array[3], matrix.array[4], 0.0, matrix.array[5],
107            0.0, 0.0, 1.0, 0.0,
108            matrix.array[6], matrix.array[7], 0.0, matrix.array[8]
109        ])));
110    }
111    /**
112     * Returns new 3x3 matrix, made from this matrix by dropping the third row and the third column.
113     *
114     * @returns the new instance of Matrix33
115     *
116     */
117    asMatrix33() {
118        return new Matrix33_1.Matrix33(new Float32Array((0, compat_1.Array_from_number)([
119            this.array[0], this.array[1], this.array[3],
120            this.array[4], this.array[5], this.array[7],
121            this.array[12], this.array[13], this.array[15]
122        ])));
123    }
124    copy() {
125        return new Matrix44(new Float32Array((0, compat_1.Array_from_number)([
126            this.array[0], this.array[1], this.array[2], this.array[3],
127            this.array[4], this.array[5], this.array[6], this.array[7],
128            this.array[8], this.array[9], this.array[10], this.array[11],
129            this.array[12], this.array[13], this.array[14], this.array[15]
130        ])));
131    }
132    concat(matrix) {
133        const result = new Float32Array((0, compat_1.Array_from_number)([
134            1.0, 0.0, 0.0, 0.0,
135            0.0, 1.0, 0.0, 0.0,
136            0.0, 0.0, 1.0, 0.0,
137            0.0, 0.0, 0.0, 1.0,
138        ]));
139        for (let row = 0; row < 4; row++) {
140            for (let col = 0; col < 4; col++) {
141                let num = 0;
142                for (let k = 0; k < 4; k++) {
143                    num += this.array[row * 4 + k] * matrix.array[col + 4 * k];
144                }
145                result[row * 4 + col] = num;
146            }
147        }
148        for (let i = 0; i < this.array.length; i++) {
149            this.array[i] = result[i];
150        }
151        return this;
152    }
153    scale(options) {
154        var _a, _b, _c, _d, _e, _f, _g, _h, _j;
155        const scaled = new Matrix44();
156        scaled.array[0] = (_a = options.x) !== null && _a !== void 0 ? _a : 1.0;
157        scaled.array[5] = (_b = options.y) !== null && _b !== void 0 ? _b : 1.0;
158        scaled.array[10] = (_c = options.z) !== null && _c !== void 0 ? _c : 1.0;
159        this.translate(new TranslateOptionsImpl(-((_d = options.pivotX) !== null && _d !== void 0 ? _d : 0.0) * ((_e = options.x) !== null && _e !== void 0 ? _e : 1.0) + ((_f = options.pivotX) !== null && _f !== void 0 ? _f : 0.0), -((_g = options.pivotY) !== null && _g !== void 0 ? _g : 0.0) * ((_h = options.y) !== null && _h !== void 0 ? _h : 1.0) + ((_j = options.pivotY) !== null && _j !== void 0 ? _j : 0.0), undefined)).concat(scaled);
160        return this;
161    }
162    rotate(options) {
163        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
164        const translationToPivot = mat44().translate(new TranslateOptionsImpl(((_a = options.pivotX) !== null && _a !== void 0 ? _a : 0.0), ((_b = options.pivotY) !== null && _b !== void 0 ? _b : 0.0), ((_c = options.pivotZ) !== null && _c !== void 0 ? _c : 0.0)));
165        const translationToBack = mat44().translate(new TranslateOptionsImpl(-((_d = options.pivotX) !== null && _d !== void 0 ? _d : 0.0), -((_e = options.pivotY) !== null && _e !== void 0 ? _e : 0.0), -((_f = options.pivotZ) !== null && _f !== void 0 ? _f : 0.0)));
166        const vec = new Point3_1.Point3((_g = options.x) !== null && _g !== void 0 ? _g : 0.0, (_h = options.y) !== null && _h !== void 0 ? _h : 0.0, (_j = options.z) !== null && _j !== void 0 ? _j : 0.0).normalize();
167        const rads = ((_k = options.angle) !== null && _k !== void 0 ? _k : 0.0) * Math.PI / 180;
168        let c = Math.cos(rads);
169        let s = Math.sin(rads);
170        const tolerance = (1.0 / (1 << 12));
171        if (Math.abs(s) <= tolerance)
172            s = 0.0;
173        if (Math.abs(c) <= tolerance)
174            c = 0.0;
175        let t = 1 - c;
176        const x = vec.x;
177        const y = vec.y;
178        const z = vec.z;
179        const rotation = mat44();
180        rotation.array[0] = t * x * x + c;
181        rotation.array[1] = t * x * y - s * z;
182        rotation.array[2] = t * x * z + s * y;
183        rotation.array[3] = 0;
184        rotation.array[4] = t * x * y + s * z;
185        rotation.array[5] = t * y * y + c;
186        rotation.array[6] = t * y * z - s * x;
187        rotation.array[7] = 0;
188        rotation.array[8] = t * x * z - s * y;
189        rotation.array[9] = t * y * z + s * x;
190        rotation.array[10] = t * z * z + c;
191        rotation.array[11] = 0;
192        rotation.array[12] = 0;
193        rotation.array[13] = 0;
194        rotation.array[14] = 0;
195        rotation.array[15] = 1;
196        this.concat(translationToPivot).concat(rotation).concat(translationToBack);
197        return this;
198    }
199    translate(options) {
200        var _a, _b, _c;
201        this.array[3] = (_a = options.x) !== null && _a !== void 0 ? _a : 0.0;
202        this.array[7] = (_b = options.y) !== null && _b !== void 0 ? _b : 0.0;
203        this.array[11] = (_c = options.z) !== null && _c !== void 0 ? _c : 0.0;
204        return this;
205    }
206    invert() {
207        const result = new Float32Array(16);
208        let a00 = this.array[0];
209        let a01 = this.array[1];
210        let a02 = this.array[2];
211        let a03 = this.array[3];
212        let a10 = this.array[4];
213        let a11 = this.array[5];
214        let a12 = this.array[6];
215        let a13 = this.array[7];
216        let a20 = this.array[8];
217        let a21 = this.array[9];
218        let a22 = this.array[10];
219        let a23 = this.array[11];
220        let a30 = this.array[12];
221        let a31 = this.array[13];
222        let a32 = this.array[14];
223        let a33 = this.array[15];
224        let b00 = a00 * a11 - a01 * a10;
225        let b01 = a00 * a12 - a02 * a10;
226        let b02 = a00 * a13 - a03 * a10;
227        let b03 = a01 * a12 - a02 * a11;
228        let b04 = a01 * a13 - a03 * a11;
229        let b05 = a02 * a13 - a03 * a12;
230        let b06 = a20 * a31 - a21 * a30;
231        let b07 = a20 * a32 - a22 * a30;
232        let b08 = a20 * a33 - a23 * a30;
233        let b09 = a21 * a32 - a22 * a31;
234        let b10 = a21 * a33 - a23 * a31;
235        let b11 = a22 * a33 - a23 * a32;
236        let determinant = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
237        let invdet = 1.0 / determinant;
238        b00 *= invdet;
239        b01 *= invdet;
240        b02 *= invdet;
241        b03 *= invdet;
242        b04 *= invdet;
243        b05 *= invdet;
244        b06 *= invdet;
245        b07 *= invdet;
246        b08 *= invdet;
247        b09 *= invdet;
248        b10 *= invdet;
249        b11 *= invdet;
250        result[0] = a11 * b11 - a12 * b10 + a13 * b09;
251        result[1] = a02 * b10 - a01 * b11 - a03 * b09;
252        result[2] = a31 * b05 - a32 * b04 + a33 * b03;
253        result[3] = a22 * b04 - a21 * b05 - a23 * b03;
254        result[4] = a12 * b08 - a10 * b11 - a13 * b07;
255        result[5] = a00 * b11 - a02 * b08 + a03 * b07;
256        result[6] = a32 * b02 - a30 * b05 - a33 * b01;
257        result[7] = a20 * b05 - a22 * b02 + a23 * b01;
258        result[8] = a10 * b10 - a11 * b08 + a13 * b06;
259        result[9] = a01 * b08 - a00 * b10 - a03 * b06;
260        result[10] = a30 * b04 - a31 * b02 + a33 * b00;
261        result[11] = a21 * b02 - a20 * b04 - a23 * b00;
262        result[12] = a11 * b07 - a10 * b09 - a12 * b06;
263        result[13] = a00 * b09 - a01 * b07 + a02 * b06;
264        result[14] = a31 * b01 - a30 * b03 - a32 * b00;
265        result[15] = a20 * b03 - a21 * b01 + a22 * b00;
266        // If 1/det overflows to infinity (i.e. det is denormalized) or any of the inverted matrix
267        // values is non-finite, return zero to indicate a non-invertible matrix.
268        let prod = 0;
269        for (let i = 0; i < result.length; ++i) {
270            prod *= result[i];
271        }
272        // At this point, prod will either be NaN or 0
273        // if prod is NaN, this check will return false
274        if (prod == 0) {
275            for (let i = 0; i < this.array.length; i++) {
276                this.array[i] = result[i];
277            }
278        }
279        return this;
280    }
281    transpose() {
282        const result = new Float32Array(16);
283        result[0] = this.array[0];
284        result[1] = this.array[4];
285        result[2] = this.array[8];
286        result[3] = this.array[12];
287        result[4] = this.array[1];
288        result[5] = this.array[5];
289        result[6] = this.array[9];
290        result[7] = this.array[13];
291        result[8] = this.array[2];
292        result[9] = this.array[6];
293        result[10] = this.array[10];
294        result[11] = this.array[14];
295        result[12] = this.array[3];
296        result[13] = this.array[7];
297        result[14] = this.array[11];
298        result[15] = this.array[15];
299        for (let i = 0; i < this.array.length; i++) {
300            this.array[i] = result[i];
301        }
302        return this;
303    }
304    skew(x, y) {
305        this.array[1] += x !== null && x !== void 0 ? x : 0.0;
306        this.array[4] += y !== null && y !== void 0 ? y : 0.0;
307        return this;
308    }
309}
310exports.Matrix44 = Matrix44;
311//# sourceMappingURL=Matrix44.js.map