@tolokoban/tgd
Version:
ToloGameDev library for WebGL2
88 lines • 7.6 kB
JavaScript
/* eslint-disable unicorn/prefer-single-call */
import { TgdMat4, TgdVec3 } from "./../math/index.js";
import { TgdCamera } from "./camera.js";
import { mat4 } from "gl-matrix";
export class TgdCameraPerspective extends TgdCamera {
constructor(options = {}) {
var _a;
super(options);
this._matrixProjection = new TgdMat4();
this._fovy = Math.PI / 4;
this._ray = {
origin: new TgdVec3(),
direction: new TgdVec3(),
};
this._fovy = (_a = options.fovy) !== null && _a !== void 0 ? _a : Math.PI / 4;
}
copyProjectionFrom(camera) {
this.fovy = camera.fovy;
this.near = camera.near;
this.far = camera.far;
return this;
}
castRay(screenX, screenY) {
const { transfo } = this;
const { origin, direction } = this._ray;
origin.from(transfo.actualPosition);
const h = Math.atan(this.fovy * 0.5);
const w = h * this.screenAspectRatio;
direction
.fromOpposite(transfo.axisZ)
.addWithScale(transfo.axisX, w * screenX)
.addWithScale(transfo.axisY, h * screenY)
.normalize();
return this._ray;
}
/**
* Vertical field of view in radians.
*
* The revealed space at a distance of 1 from the camera
* will have a height of `2 * tan(fovy / 2)`.
*/
get fovy() {
return this._fovy;
}
set fovy(v) {
if (v === this._fovy)
return;
this._fovy = v;
this.dirtyProjection = true;
}
get matrixProjection() {
this.updateProjectionIfNeeded();
return this._matrixProjection;
}
getSpaceHeightAtTarget() {
return 2 * Math.tan(this.fovy * 0.5) * this.transfo.distance;
}
setSpaceHeightAtTarget(v) {
this.transfo.setDistance(v / (2 * Math.tan(this.fovy * 0.5)));
}
updateProjectionIfNeeded() {
if (!this.dirtyProjection)
return;
const fovy = this._fovy;
const aspect = this.screenAspectRatio;
const near = this._near;
const far = this._far;
const out = this._matrixProjection;
mat4.perspective(out, fovy, aspect, near, far);
out[0] *= this.zoom;
out[5] *= this.zoom;
this.dirtyProjection = true;
}
toCode(caption) {
const code = [];
if (caption)
code.push(`// ${caption}`);
code.push(`const camera = new TgdCameraPerspective({`);
if (this.name)
code.push(` name: ${JSON.stringify(this.name)},`);
code.push(` fovy: ${this._fovy},`, ` near: ${this._near},`, ` far: ${this._far},`, ` zoom: ${this.zoom},`, ` transfo: {`, ` distance: ${this.transfo.distance},`);
code.push(` position: ${JSON.stringify([...this.transfo.position])},`);
code.push(` orientation: ${JSON.stringify([...this.transfo.orientation])},`);
code.push(` scale: ${JSON.stringify([...this.transfo.scale])},`, ` }`, "}");
return code.join("\n");
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FtZXJhLXBlcnNwZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NhbWVyYS9jYW1lcmEtcGVyc3BlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQzVDLE9BQU8sRUFBRSxTQUFTLEVBQW9CLE1BQU0sVUFBVSxDQUFBO0FBQ3RELE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFZaEMsTUFBTSxPQUFPLG9CQUFxQixTQUFRLFNBQVM7SUFRL0MsWUFBWSxVQUF1QyxFQUFFOztRQUNqRCxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUE7UUFSRCxzQkFBaUIsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFBO1FBQzFDLFVBQUssR0FBRyxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQTtRQUNWLFNBQUksR0FBRztZQUNwQixNQUFNLEVBQUUsSUFBSSxPQUFPLEVBQUU7WUFDckIsU0FBUyxFQUFFLElBQUksT0FBTyxFQUFFO1NBQzNCLENBQUE7UUFJRyxJQUFJLENBQUMsS0FBSyxHQUFHLE1BQUEsT0FBTyxDQUFDLElBQUksbUNBQUksSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUE7SUFDNUMsQ0FBQztJQUVELGtCQUFrQixDQUFDLE1BQTRCO1FBQzNDLElBQUksQ0FBQyxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQTtRQUN2QixJQUFJLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUE7UUFDdkIsSUFBSSxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFBO1FBQ3JCLE9BQU8sSUFBSSxDQUFBO0lBQ2YsQ0FBQztJQUVELE9BQU8sQ0FDSCxPQUFlLEVBQ2YsT0FBZTtRQUVmLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUE7UUFDeEIs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