@itwin/core-frontend
Version:
iTwin.js frontend components
347 lines • 16.2 kB
JavaScript
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module WebGL
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Matrix4 = exports.Matrix3 = void 0;
exports.fromNormalizedCrossProduct = fromNormalizedCrossProduct;
exports.normalizedDifference = normalizedDifference;
const core_bentley_1 = require("@itwin/core-bentley");
const core_geometry_1 = require("@itwin/core-geometry");
/** @internal */
class Matrix3 {
data = new Float32Array(3 * 3);
constructor() { }
initIdentity() {
this.setValues(1, 0, 0, 0, 1, 0, 0, 0, 1);
}
static fromIdentity(out) {
const mat = undefined !== out ? out : new Matrix3();
mat.initIdentity();
return mat;
}
copyFrom(src) {
for (let i = 0; i < this.data.length; i++) {
this.data[i] = src.data[i];
}
}
clone(out) {
const mat = undefined !== out ? out : new Matrix3();
mat.copyFrom(this);
return mat;
}
setValues(m00, m01, m02, m10, m11, m12, m20, m21, m22) {
this.m00 = m00;
this.m01 = m01;
this.m02 = m02;
this.m10 = m10;
this.m11 = m11;
this.m12 = m12;
this.m20 = m20;
this.m21 = m21;
this.m22 = m22;
}
static fromValues(m00, m01, m02, m10, m11, m12, m20, m21, m22, out) {
const mat = undefined !== out ? out : new Matrix3();
mat.setValues(m00, m01, m02, m10, m11, m12, m20, m21, m22);
return mat;
}
initFromMatrix3d(rot) {
this.setValues(rot.at(0, 0), rot.at(0, 1), rot.at(0, 2), rot.at(1, 0), rot.at(1, 1), rot.at(1, 2), rot.at(2, 0), rot.at(2, 1), rot.at(2, 2));
}
static fromMatrix3d(rot, out) {
const mat = undefined !== out ? out : new Matrix3();
mat.initFromMatrix3d(rot);
return mat;
}
toMatrix3d() {
const data = this.data;
return core_geometry_1.Matrix3d.createRowValues(data[0], data[3], data[6], data[1], data[4], data[7], data[2], data[5], data[8]);
}
swap(firstIndex, secondIndex) {
(0, core_bentley_1.assert)(firstIndex < this.data.length);
(0, core_bentley_1.assert)(secondIndex < this.data.length);
(0, core_bentley_1.assert)(secondIndex !== firstIndex);
const tmp = this.data[firstIndex];
this.data[firstIndex] = this.data[secondIndex];
this.data[secondIndex] = tmp;
}
transpose() {
this.swap(1, 3);
this.swap(5, 7);
this.swap(2, 6);
}
static fromTranspose(src, out) {
const mat = src.clone(out);
mat.transpose();
return mat;
}
get(index) {
(0, core_bentley_1.assert)(index < this.data.length);
return this.data[index];
}
set(index, value) {
(0, core_bentley_1.assert)(index < this.data.length);
this.data[index] = value;
}
at(row, col) { return this.get(col * 3 + row); }
setAt(row, col, value) { this.set(col * 3 + row, value); }
get m00() { return this.at(0, 0); }
set m00(value) { this.setAt(0, 0, value); }
get m01() { return this.at(0, 1); }
set m01(value) { this.setAt(0, 1, value); }
get m02() { return this.at(0, 2); }
set m02(value) { this.setAt(0, 2, value); }
get m10() { return this.at(1, 0); }
set m10(value) { this.setAt(1, 0, value); }
get m11() { return this.at(1, 1); }
set m11(value) { this.setAt(1, 1, value); }
get m12() { return this.at(1, 2); }
set m12(value) { this.setAt(1, 2, value); }
get m20() { return this.at(2, 0); }
set m20(value) { this.setAt(2, 0, value); }
get m21() { return this.at(2, 1); }
set m21(value) { this.setAt(2, 1, value); }
get m22() { return this.at(2, 2); }
set m22(value) { this.setAt(2, 2, value); }
}
exports.Matrix3 = Matrix3;
/** @internal */
class Matrix4 {
data = new Float32Array(4 * 4);
constructor() { }
copyFrom(src) {
for (let i = 0; i < this.data.length; i++) {
this.data[i] = src.data[i];
}
}
clone(out) {
const mat = undefined !== out ? out : new Matrix4();
mat.copyFrom(this);
return mat;
}
initIdentity() {
this.setValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
}
static fromIdentity(out) {
const mat = undefined !== out ? out : new Matrix4();
mat.initIdentity();
return mat;
}
setValues(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
this.m00 = m00;
this.m01 = m01;
this.m02 = m02;
this.m03 = m03;
this.m10 = m10;
this.m11 = m11;
this.m12 = m12;
this.m13 = m13;
this.m20 = m20;
this.m21 = m21;
this.m22 = m22;
this.m23 = m23;
this.m30 = m30;
this.m31 = m31;
this.m32 = m32;
this.m33 = m33;
}
static fromValues(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33, out) {
const mat = undefined !== out ? out : new Matrix4();
mat.setValues(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33);
return mat;
}
getRotation(out) {
const rot = undefined !== out ? out : new Matrix3();
rot.setValues(this.m00, this.m01, this.m02, this.m10, this.m11, this.m12, this.m20, this.m21, this.m22);
return rot;
}
initFromTransform(transform) {
const mat = transform.matrix;
const org = transform.origin;
this.setValues(mat.at(0, 0), mat.at(0, 1), mat.at(0, 2), org.x, mat.at(1, 0), mat.at(1, 1), mat.at(1, 2), org.y, mat.at(2, 0), mat.at(2, 1), mat.at(2, 2), org.z, 0, 0, 0, 1);
}
static fromTransform(transform, out) {
const mat = undefined !== out ? out : new Matrix4();
mat.initFromTransform(transform);
return mat;
}
toTransform() {
const data = this.data;
(0, core_bentley_1.assert)(0.0 === data[3] && 0.0 === data[7] && 0.0 === data[11] && 1.0 === data[15]);
const origin = new core_geometry_1.Point3d(data[12], data[13], data[14]);
const rotMat = core_geometry_1.Matrix3d.createIdentity();
for (let i = 0; i < 3; i++)
for (let j = 0; j < 3; j++)
rotMat.setAt(i, j, data[i + j * 4]);
return core_geometry_1.Transform.createRefs(origin, rotMat);
}
initFromMatrix4d(mat) {
this.setValues(mat.atIJ(0, 0), mat.atIJ(0, 1), mat.atIJ(0, 2), mat.atIJ(0, 3), mat.atIJ(1, 0), mat.atIJ(1, 1), mat.atIJ(1, 2), mat.atIJ(1, 3), mat.atIJ(2, 0), mat.atIJ(2, 1), mat.atIJ(2, 2), mat.atIJ(2, 3), mat.atIJ(3, 0), mat.atIJ(3, 1), mat.atIJ(3, 2), mat.atIJ(3, 3));
}
static fromMatrix4d(mat, out) {
const result = undefined !== out ? out : new Matrix4();
result.initFromMatrix4d(mat);
return result;
}
toMatrix4d(result) {
const data = this.data;
return core_geometry_1.Matrix4d.createRowValues(data[0], data[4], data[8], data[12], data[1], data[5], data[9], data[13], data[2], data[6], data[10], data[14], data[3], data[7], data[11], data[15], result);
}
lookAt(eye, center, up) {
const f = normalizedDifference(center, eye);
if (undefined === f) {
return false;
}
const s = fromNormalizedCrossProduct(f, up);
if (undefined === s) {
return false;
}
const u = core_geometry_1.Vector3d.createCrossProduct(s.x, s.y, s.z, f.x, f.y, f.z);
this.setValues(s.x, s.y, s.z, -s.dotProduct(eye), u.x, u.y, u.z, -u.dotProduct(eye), -f.x, -f.y, -f.z, f.dotProduct(eye), 0, 0, 0, 1);
return true;
}
static fromLookAt(eye, center, up, out) {
const mat = undefined !== out ? out : new Matrix4();
return mat.lookAt(eye, center, up) ? mat : undefined;
}
// left, right, bottom, top, near, far
frustum(l, r, b, t, n, f) {
this.setValues((2 * n) / (r - l), 0, (r + l) / (r - l), 0, 0, (2 * n) / (t - b), (t + b) / (t - b), 0, 0, 0, -(f + n) / (f - n), -(2 * f * n) / (f - n), 0, 0, -1, 0);
}
static fromFrustum(l, r, b, t, n, f, out) {
const mat = undefined !== out ? out : new Matrix4();
mat.frustum(l, r, b, t, n, f);
return mat;
}
perspective(fovY, aspectRatio, nearZ, farZ) {
const frustumHeight = Math.tan(fovY / 360 * Math.PI) * nearZ;
const frustumWidth = frustumHeight * aspectRatio;
this.frustum(-frustumWidth, frustumWidth, -frustumHeight, frustumHeight, nearZ, farZ);
}
static fromPerspective(fovY, aspectRatio, nearZ, farZ, out) {
const mat = undefined !== out ? out : new Matrix4();
mat.perspective(fovY, aspectRatio, nearZ, farZ);
return mat;
}
ortho(l, r, b, t, n, f) {
this.setValues(2 / (r - l), 0, 0, -(r + l) / (r - l), 0, 2 / (t - b), 0, -(t + b) / (t - b), 0, 0, -2 / (f - n), -(f + n) / (f - n), 0, 0, 0, 1);
}
static fromOrtho(l, r, b, t, n, f, out) {
const mat = undefined !== out ? out : new Matrix4();
mat.ortho(l, r, b, t, n, f);
return mat;
}
invert() {
const d = this.data;
const d0 = d[0];
const d1 = d[1];
const d2 = d[2];
const d3 = d[3];
this.setValues(d[5] * d[10] * d[15] - d[5] * d[11] * d[14] - d[9] * d[6] * d[15] + d[9] * d[7] * d[14] + d[13] * d[6] * d[11] - d[13] * d[7] * d[10], -d[4] * d[10] * d[15] + d[4] * d[11] * d[14] + d[8] * d[6] * d[15] - d[8] * d[7] * d[14] - d[12] * d[6] * d[11] + d[12] * d[7] * d[10], d[4] * d[9] * d[15] - d[4] * d[11] * d[13] - d[8] * d[5] * d[15] + d[8] * d[7] * d[13] + d[12] * d[5] * d[11] - d[12] * d[7] * d[9], -d[4] * d[9] * d[14] + d[4] * d[10] * d[13] + d[8] * d[5] * d[14] - d[8] * d[6] * d[13] - d[12] * d[5] * d[10] + d[12] * d[6] * d[9], -d[1] * d[10] * d[15] + d[1] * d[11] * d[14] + d[9] * d[2] * d[15] - d[9] * d[3] * d[14] - d[13] * d[2] * d[11] + d[13] * d[3] * d[10], d[0] * d[10] * d[15] - d[0] * d[11] * d[14] - d[8] * d[2] * d[15] + d[8] * d[3] * d[14] + d[12] * d[2] * d[11] - d[12] * d[3] * d[10], -d[0] * d[9] * d[15] + d[0] * d[11] * d[13] + d[8] * d[1] * d[15] - d[8] * d[3] * d[13] - d[12] * d[1] * d[11] + d[12] * d[3] * d[9], d[0] * d[9] * d[14] - d[0] * d[10] * d[13] - d[8] * d[1] * d[14] + d[8] * d[2] * d[13] + d[12] * d[1] * d[10] - d[12] * d[2] * d[9], d[1] * d[6] * d[15] - d[1] * d[7] * d[14] - d[5] * d[2] * d[15] + d[5] * d[3] * d[14] + d[13] * d[2] * d[7] - d[13] * d[3] * d[6], -d[0] * d[6] * d[15] + d[0] * d[7] * d[14] + d[4] * d[2] * d[15] - d[4] * d[3] * d[14] - d[12] * d[2] * d[7] + d[12] * d[3] * d[6], d[0] * d[5] * d[15] - d[0] * d[7] * d[13] - d[4] * d[1] * d[15] + d[4] * d[3] * d[13] + d[12] * d[1] * d[7] - d[12] * d[3] * d[5], -d[0] * d[5] * d[14] + d[0] * d[6] * d[13] + d[4] * d[1] * d[14] - d[4] * d[2] * d[13] - d[12] * d[1] * d[6] + d[12] * d[2] * d[5], -d[1] * d[6] * d[11] + d[1] * d[7] * d[10] + d[5] * d[2] * d[11] - d[5] * d[3] * d[10] - d[9] * d[2] * d[7] + d[9] * d[3] * d[6], d[0] * d[6] * d[11] - d[0] * d[7] * d[10] - d[4] * d[2] * d[11] + d[4] * d[3] * d[10] + d[8] * d[2] * d[7] - d[8] * d[3] * d[6], -d[0] * d[5] * d[11] + d[0] * d[7] * d[9] + d[4] * d[1] * d[11] - d[4] * d[3] * d[9] - d[8] * d[1] * d[7] + d[8] * d[3] * d[5], d[0] * d[5] * d[10] - d[0] * d[6] * d[9] - d[4] * d[1] * d[10] + d[4] * d[2] * d[9] + d[8] * d[1] * d[6] - d[8] * d[2] * d[5]);
const determinant = d0 * d[0] + d1 * d[4] + d2 * d[8] + d3 * d[12];
if (0 === determinant) {
this.initIdentity();
return false;
}
this.multiplyByScalar(1 / determinant);
return true;
}
static fromInverse(src, out) {
const mat = src.clone(out);
return mat.invert() ? mat : undefined;
}
swap(firstIndex, secondIndex) {
(0, core_bentley_1.assert)(firstIndex < this.data.length);
(0, core_bentley_1.assert)(secondIndex < this.data.length);
(0, core_bentley_1.assert)(secondIndex !== firstIndex);
const tmp = this.data[firstIndex];
this.data[firstIndex] = this.data[secondIndex];
this.data[secondIndex] = tmp;
}
transpose() {
this.swap(1, 4);
this.swap(2, 8);
this.swap(3, 12);
this.swap(6, 9);
this.swap(7, 13);
this.swap(11, 14);
}
static fromTranspose(src, out) {
const mat = src.clone(out);
mat.transpose();
return mat;
}
multiplyBy(other) {
const a = this.data;
const b = other.data;
this.setValues(a[0] * b[0] + a[4] * b[1] + a[8] * b[2] + a[12] * b[3], a[0] * b[4] + a[4] * b[5] + a[8] * b[6] + a[12] * b[7], a[0] * b[8] + a[4] * b[9] + a[8] * b[10] + a[12] * b[11], a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12] * b[15], a[1] * b[0] + a[5] * b[1] + a[9] * b[2] + a[13] * b[3], a[1] * b[4] + a[5] * b[5] + a[9] * b[6] + a[13] * b[7], a[1] * b[8] + a[5] * b[9] + a[9] * b[10] + a[13] * b[11], a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13] * b[15], a[2] * b[0] + a[6] * b[1] + a[10] * b[2] + a[14] * b[3], a[2] * b[4] + a[6] * b[5] + a[10] * b[6] + a[14] * b[7], a[2] * b[8] + a[6] * b[9] + a[10] * b[10] + a[14] * b[11], a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15], a[3] * b[0] + a[7] * b[1] + a[11] * b[2] + a[15] * b[3], a[3] * b[4] + a[7] * b[5] + a[11] * b[6] + a[15] * b[7], a[3] * b[8] + a[7] * b[9] + a[11] * b[10] + a[15] * b[11], a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15]);
}
static fromProduct(a, b, out) {
const mat = a.clone(out);
mat.multiplyBy(b);
return mat;
}
multiplyByScalar(scalar) {
for (let i = 0; i < this.data.length; i++) {
this.data[i] *= scalar;
}
}
get(index) {
(0, core_bentley_1.assert)(index < this.data.length);
return this.data[index];
}
set(index, value) {
(0, core_bentley_1.assert)(index < this.data.length);
this.data[index] = value;
}
at(row, col) { return this.get(col * 4 + row); }
setAt(row, col, value) { this.set(col * 4 + row, value); }
get m00() { return this.at(0, 0); }
set m00(value) { this.setAt(0, 0, value); }
get m01() { return this.at(0, 1); }
set m01(value) { this.setAt(0, 1, value); }
get m02() { return this.at(0, 2); }
set m02(value) { this.setAt(0, 2, value); }
get m03() { return this.at(0, 3); }
set m03(value) { this.setAt(0, 3, value); }
get m10() { return this.at(1, 0); }
set m10(value) { this.setAt(1, 0, value); }
get m11() { return this.at(1, 1); }
set m11(value) { this.setAt(1, 1, value); }
get m12() { return this.at(1, 2); }
set m12(value) { this.setAt(1, 2, value); }
get m13() { return this.at(1, 3); }
set m13(value) { this.setAt(1, 3, value); }
get m20() { return this.at(2, 0); }
set m20(value) { this.setAt(2, 0, value); }
get m21() { return this.at(2, 1); }
set m21(value) { this.setAt(2, 1, value); }
get m22() { return this.at(2, 2); }
set m22(value) { this.setAt(2, 2, value); }
get m23() { return this.at(2, 3); }
set m23(value) { this.setAt(2, 3, value); }
get m30() { return this.at(3, 0); }
set m30(value) { this.setAt(3, 0, value); }
get m31() { return this.at(3, 1); }
set m31(value) { this.setAt(3, 1, value); }
get m32() { return this.at(3, 2); }
set m32(value) { this.setAt(3, 2, value); }
get m33() { return this.at(3, 3); }
set m33(value) { this.setAt(3, 3, value); }
}
exports.Matrix4 = Matrix4;
// missing Vector3d functions
/** @internal */
function fromNormalizedCrossProduct(vec0, vec1) {
return vec0.unitCrossProduct(vec1);
}
/** @internal */
function normalizedDifference(target, origin) {
return core_geometry_1.Vector3d.createStartEnd(origin, target).normalize();
}
//# sourceMappingURL=Matrix.js.map