import { Matrix3D } from '../geom/Matrix3D'; import { Plane3D } from '../geom/Plane3D'; import { Vector3D } from '../geom/Vector3D'; import { ProjectionEvent } from '../events/ProjectionEvent'; import { ProjectionBase } from '../projections/ProjectionBase'; export class ObliqueNearPlaneProjection extends ProjectionBase { private _baseProjection: ProjectionBase; private _plane: Plane3D; private _onProjectionMatrixChangedDelegate: (event: ProjectionEvent) => void; constructor(baseProjection: ProjectionBase, plane: Plane3D) { super(); this.baseProjection = baseProjection; this.plane = plane; this._onProjectionMatrixChangedDelegate = (event: ProjectionEvent) => this.onProjectionMatrixChanged(event); } //@override public get near(): number { return this._baseProjection.near; } //@override public set near(value: number) { this._baseProjection.near = value; } //@override public get far(): number { return this._baseProjection.far; } //@override public set far(value: number) { this._baseProjection.far = value; } public get plane(): Plane3D { return this._plane; } public set plane(value: Plane3D) { this._plane = value; this._invalidateFrustumMatrix3D(); } public set baseProjection(value: ProjectionBase) { if (this._baseProjection) this._baseProjection.removeEventListener(ProjectionEvent.INVALIDATE_FRUSTUM_MATRIX3D, this._onProjectionMatrixChangedDelegate); this._baseProjection = value; if (this._baseProjection) this._baseProjection.addEventListener(ProjectionEvent.INVALIDATE_FRUSTUM_MATRIX3D, this._onProjectionMatrixChangedDelegate); this._invalidateFrustumMatrix3D(); } private onProjectionMatrixChanged(event: ProjectionEvent): void { this._invalidateFrustumMatrix3D(); } //@override public _updateFrustumMatrix3D(): void { super._updateFrustumMatrix3D(); this._frustumMatrix3D.copyFrom(this._baseProjection.frustumMatrix3D); const cx: number = this._plane.a; const cy: number = this._plane.b; const cz: number = this._plane.c; const cw: number = -this._plane.d + .05; const signX: number = cx >= 0 ? 1 : -1; const signY: number = cy >= 0 ? 1 : -1; const p: Vector3D = new Vector3D(signX, signY, 1, 1); const inverse: Matrix3D = this._frustumMatrix3D.clone(); inverse.invert(); const q: Vector3D = inverse.transformVector(p); this._frustumMatrix3D.copyRowTo(3, p); const a: number = (q.x * p.x + q.y * p.y + q.z * p.z + q.w * p.w) / (cx * q.x + cy * q.y + cz * q.z + cw * q.w); this._frustumMatrix3D.copyRowFrom(2, new Vector3D(cx * a, cy * a, cz * a, cw * a)); } }