/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { Angle, BoundingSphere, Vector3, } from "@vertexvis/geometry";
export function isValidFrameCamera(camera) {
    if (isPerspectiveFrameCamera(camera)) {
        const lookAtValid = Vector3.isValid(camera.lookAt);
        const positionValid = Vector3.isValid(camera.position);
        const upValid = Vector3.isValid(camera.up);
        return lookAtValid && positionValid && upValid;
    }
    else {
        const asOrthographic = camera;
        const viewVectorValid = Vector3.isValid(asOrthographic.viewVector);
        const lookAtValid = Vector3.isValid(asOrthographic.lookAt);
        const upValid = Vector3.isValid(asOrthographic.up);
        const fovHeightValid = Number.isFinite(asOrthographic.fovHeight);
        return viewVectorValid && lookAtValid && upValid && fovHeightValid;
    }
}
export function isPerspectiveFrameCamera(camera) {
    return (camera.position != null &&
        camera.fovHeight == null);
}
export function isOrthographicFrameCamera(camera) {
    const asOrtho = camera;
    return asOrtho.viewVector != null && asOrtho.fovHeight != null;
}
export function withPositionAndViewVector(camera) {
    if (isOrthographicFrameCamera(camera)) {
        return {
            ...camera,
            position: Vector3.add(camera.lookAt, Vector3.negate(camera.viewVector)),
        };
    }
    else {
        return {
            ...camera,
            viewVector: Vector3.subtract(camera.lookAt, camera.position),
        };
    }
}
export function createPerspective(data = {}) {
    var _a, _b, _c, _d;
    return {
        position: (_a = data.position) !== null && _a !== void 0 ? _a : Vector3.forward(),
        lookAt: (_b = data.lookAt) !== null && _b !== void 0 ? _b : Vector3.origin(),
        up: (_c = data.up) !== null && _c !== void 0 ? _c : Vector3.up(),
        fovY: (_d = data.fovY) !== null && _d !== void 0 ? _d : 45,
    };
}
export function createOrthographic(data = {}) {
    var _a, _b, _c, _d, _e, _f;
    return {
        viewVector: (_a = data.viewVector) !== null && _a !== void 0 ? _a : Vector3.back(),
        lookAt: (_b = data.lookAt) !== null && _b !== void 0 ? _b : Vector3.origin(),
        up: (_c = data.up) !== null && _c !== void 0 ? _c : Vector3.up(),
        fovHeight: (_d = data.fovHeight) !== null && _d !== void 0 ? _d : 1.0,
        rotationPoint: (_f = (_e = data.rotationPoint) !== null && _e !== void 0 ? _e : data.lookAt) !== null && _f !== void 0 ? _f : Vector3.origin(),
    };
}
export function toOrthographic(data, boundingBox) {
    var _a;
    const viewVector = Vector3.subtract(data.lookAt, data.position);
    const boundingSphere = BoundingSphere.create(boundingBox);
    const scale = boundingSphere.radius / Vector3.magnitude(viewVector);
    return {
        viewVector: Vector3.scale(scale, viewVector),
        up: data.up,
        lookAt: data.lookAt,
        fovHeight: 2 *
            Vector3.magnitude(viewVector) *
            Math.tan(Angle.toRadians(((_a = data.fovY) !== null && _a !== void 0 ? _a : 45) / 2.0)),
    };
}
export function toPerspective(data, fovY = 45) {
    const expectedMagnitude = data.fovHeight / (2 * Math.tan(Angle.toRadians(fovY / 2.0)));
    const receivedMagnitude = Vector3.magnitude(data.viewVector);
    const magnitudeScale = expectedMagnitude / receivedMagnitude;
    return {
        position: Vector3.add(data.lookAt, Vector3.negate(Vector3.scale(magnitudeScale, data.viewVector))),
        up: data.up,
        lookAt: data.lookAt,
        fovY,
    };
}
export function toProtobuf(camera) {
    if (isOrthographicFrameCamera(camera)) {
        return {
            orthographic: {
                viewVector: { ...camera.viewVector },
                lookAt: { ...camera.lookAt },
                up: { ...camera.up },
                fovHeight: camera.fovHeight,
            },
        };
    }
    else if (isPerspectiveFrameCamera(camera)) {
        return {
            perspective: {
                position: { ...camera.position },
                lookAt: { ...camera.lookAt },
                up: { ...camera.up },
                fovY: camera.fovY
                    ? {
                        value: camera.fovY,
                    }
                    : null,
            },
            position: { ...camera.position },
            lookAt: { ...camera.lookAt },
            up: { ...camera.up },
        };
    }
    else {
        return {
            ...camera,
        };
    }
}
//# sourceMappingURL=frameCamera.js.map
