UNPKG

rc-js-util

Version:

A collection of TS and C++ utilities to help writing performant and correct applications, achieved through strict typing and (removable) invariant checking.

142 lines (122 loc) 4.45 kB
import { ITypedArrayCtor } from "../i-typed-array-ctor.js"; import { IMat4Ctor, Mat4 } from "./mat4.js"; import { Mat4Factory } from "./mat4-factory.js"; import { _Debug } from "../../../debug/_debug.js"; import { TTypedArrayCtor } from "../t-typed-array-ctor.js"; import { NormalizedDataViewProvider } from "../normalized-data-view/normalized-data-view-provider.js"; import { IReadonlyVec4, Vec4 } from "../vec4/vec4.js"; import { TTypedArray } from "../t-typed-array.js"; /** * @internal */ export function getMat4Ctor<TCtor extends TTypedArrayCtor> ( ctor: TCtor ) : IMat4Ctor<InstanceType<TCtor>> { return class Mat4Impl extends (ctor as unknown as ITypedArrayCtor<Mat4<InstanceType<TCtor>>>) { public static factory: Mat4Factory<Mat4<InstanceType<TCtor>>> = new Mat4Factory(Mat4Impl, NormalizedDataViewProvider.getView(ctor)); protected static vec4Ctor = Vec4.getCtor(ctor); public ["constructor"]!: typeof Mat4Impl; public constructor ( bufferOrLength: number | ArrayBufferLike = 16, offset?: number, length?: number, ) { super(bufferOrLength as ArrayBufferLike, offset, length); } public override isEqualTo(other: Mat4<TTypedArray>): boolean { let isEqual = true; for (let i = 0; i < 16 && isEqual; ++i) { isEqual &&= this[i as 0] === other[i as 0]; } return isEqual; } public override setIdentityMatrix(): Mat4<InstanceType<TCtor>> { this.fill(0); this[0] = 1; this[5] = 1; this[10] = 1; this[15] = 1; return this; } public override getValueAt(column: number, row: number): number { _BUILD.DEBUG && _Debug.assert(column >= 0 && column < 4 && row >= 0 && row < 4, "out of bounds"); return this[row * 4 + column as Extract<keyof Mat4<never>, number>]; } public override setValueAt(column: number, row: number, value: number): void { _BUILD.DEBUG && _Debug.assert(column >= 0 && column < 4 && row >= 0 && row < 4, "out of bounds"); this[row * 4 + column as Extract<keyof Mat4<never>, number>] = value; } public override getRow<TResult extends TTypedArray = InstanceType<TCtor>> ( row: number, writeTo: Vec4<TResult> = this.constructor.vec4Ctor.factory.createOneEmpty() as Vec4<TResult>, ) : Vec4<TResult> { _BUILD.DEBUG && _Debug.assert(row >= 0 && row < 4, "index out of bounds"); writeTo[0] = this.getValueAt(0, row); writeTo[1] = this.getValueAt(1, row); writeTo[2] = this.getValueAt(2, row); writeTo[3] = this.getValueAt(3, row); return writeTo; } public override setRow ( row: number, writeFrom: IReadonlyVec4<TTypedArray>, ) : void { _BUILD.DEBUG && _Debug.assert(row >= 0 && row < 4, "index out of bounds"); this.setValueAt(0, row, writeFrom[0]); this.setValueAt(1, row, writeFrom[1]); this.setValueAt(2, row, writeFrom[2]); this.setValueAt(3, row, writeFrom[3]); } public override getLoggableValue(): number[][] { return [ [this[0], this[1], this[2], this[3]], [this[4], this[5], this[6], this[7]], [this[8], this[9], this[10], this[11]], [this[12], this[13], this[14], this[15]], ]; } public copyFromBuffer ( memoryDataView: DataView, pointer: number, littleEndian?: boolean, ) : void { this.constructor.factory.copyFromBuffer(memoryDataView, pointer, this, littleEndian); } public copyToBuffer ( memoryDataView: DataView, pointer: number, littleEndian?: boolean, ) : void { this.constructor.factory.copyToBuffer(memoryDataView, this, pointer, littleEndian); } public castToBaseType(): InstanceType<TCtor> { return this as InstanceType<TCtor>; } }; }