import { ValidationError } from "../core/index.js";
import { Frustum } from "../math/index.js";
import { extractFrustumPlanes, identityMat4, multiplyMat4, toMathMat4 } from "./MathTypes.js";
import { SceneNode } from "./SceneNode.js";
export class Camera extends SceneNode {
    viewport = { x: 0, y: 0, width: 1, height: 1 };
    frustumPlanes = [];
    frustum = Frustum.fromMatrix(toMathMat4(identityMat4()));
    projectionMatrix;
    viewMatrix;
    viewProjectionMatrix;
    constructor(name, id) {
        super({ id, name });
        this.projectionMatrix = identityMat4();
        this.viewMatrix = this.transform.inverseWorldMatrix;
        this.viewProjectionMatrix = multiplyMat4(this.projectionMatrix, this.viewMatrix);
    }
    updateCameraMatrices() {
        updateAncestors(this);
        this.updateWorldTransform();
        this.projectionMatrix = this.computeProjectionMatrix();
        this.viewMatrix = this.transform.inverseWorldMatrix;
        this.viewProjectionMatrix = multiplyMat4(this.projectionMatrix, this.viewMatrix);
        this.frustum = Frustum.fromMatrix(toMathMat4(this.viewProjectionMatrix));
        this.frustumPlanes.splice(0, this.frustumPlanes.length, ...extractFrustumPlanes(this.viewProjectionMatrix));
    }
    setViewport(viewport) {
        if (viewport.width <= 0 || viewport.height <= 0)
            throw new ValidationError("CAMERA_VIEWPORT", "Camera viewport dimensions must be positive.");
        this.viewport = { ...viewport };
    }
}
function updateAncestors(node) {
    const ancestors = [];
    let parent = node.parent;
    while (parent) {
        ancestors.unshift(parent);
        parent = parent.parent;
    }
    for (const ancestor of ancestors) {
        ancestor.transform.updateWorld(ancestor.parent?.transform.worldMatrix);
    }
}
//# sourceMappingURL=Camera.js.map