@awayjs/core
Version:
AwayJS core classes
90 lines (70 loc) • 2.61 kB
text/typescript
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));
}
}