UNPKG

@tolokoban/tgd

Version:

ToloGameDev library for WebGL2

98 lines 8.37 kB
/* eslint-disable unicorn/prefer-single-call */ import { TgdMat4, TgdVec3 } from "./../math/index.js"; import { mat4 } from "gl-matrix"; import { TgdCamera } from "./camera.js"; export class TgdCameraPerspective extends TgdCamera { constructor(options = {}) { super(options); this._matrixProjection = new TgdMat4(); this._fovy = Math.PI / 4; this._ray = { origin: new TgdVec3(), direction: new TgdVec3(), }; this._fovy = options.fovy ?? Math.PI / 4; } clone() { const camera = new TgdCameraPerspective({ transfo: this.transfo.clone(), }); camera.screenWidth = this.screenWidth; camera.screenHeight = this.screenHeight; camera.near = this.near; camera.far = this.far; camera.fovy = this.fovy; return camera; } 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FtZXJhLXBlcnNwZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NhbWVyYS9jYW1lcmEtcGVyc3BlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQzVDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDaEMsT0FBTyxFQUFFLFNBQVMsRUFBeUIsTUFBTSxVQUFVLENBQUE7QUFZM0QsTUFBTSxPQUFPLG9CQUFxQixTQUFRLFNBQVM7SUFRL0MsWUFBWSxVQUF1QyxFQUFFO1FBQ2pELEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQVJELHNCQUFpQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7UUFDMUMsVUFBSyxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFBO1FBQ1YsU0FBSSxHQUFHO1lBQ3BCLE1BQU0sRUFBRSxJQUFJLE9BQU8sRUFBRTtZQUNyQixTQUFTLEVBQUUsSUFBSSxPQUFPLEVBQUU7U0FDM0IsQ0FBQTtRQUlHLElBQUksQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQTtJQUM1QyxDQUFDO0lBRUQsS0FBSztRQUNELE1BQU0sTUFBTSxHQUFHLElBQUksb0JBQW9CLENBQUM7WUFDcEMsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFO1NBQ2hDLENBQUMsQ0FBQTtRQUNGLE1BQU0sQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQTtRQUNyQyxNQUFNLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUE7UUFDdkMsTUFBTSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFBO1FBQ3ZCLE1BQU0sQ0FBQyxHQUFHLEdBQUcsSUFB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