/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { e as dimensions, p as point, v as vector3, r as ray, g as rectangle } from './bundle-DfdVaPrt.js';

/**
 * A `Viewport` represents the drawing area in the viewer.
 *
 * When a frame is received from the rendering pipeline, it might not be the
 * same dimensions of the viewport because of an interactive frame or because of
 * bandwidth limitations or other performance reasons.
 *
 * The viewport contains methods to scale an image to the viewport, as well as
 * translate 2D coordinates between the viewport and the frame.
 */
class Viewport {
    constructor(
    /**
     * The width of the viewport.
     */
    width, 
    /**
     * The height of the viewport.
     */
    height) {
        this.width = width;
        this.height = height;
        this.center = dimensions.center(this.dimensions);
    }
    /**
     * Returns a new viewport with the given dimensions.
     * @param dimensions The dimensions of the viewport
     * @returns A new viewport.
     */
    static fromDimensions(dimensions) {
        return new Viewport(dimensions.width, dimensions.height);
    }
    /**
     * Transforms a normalized device coordinate to a 2D point within the
     * viewport.
     *
     * @param ndc A 2D point in NDC.
     * @returns A 2D point in the coordinate space of the viewport.
     */
    transformNdcPointToViewport(ndc) {
        return point.create(ndc.x * this.center.x + this.center.x, -ndc.y * this.center.y + this.center.y);
    }
    /**
     * Transforms a normalized device coordinate to a 2D point within the
     * viewport.
     *
     * @param ndc A 3D point in NDC.
     * @returns A 2D point in the coordinate space of the viewport.
     */
    transformVectorToViewport(ndc) {
        return this.transformNdcPointToViewport(ndc);
    }
    /**
     * Transforms a world point to 2D point in viewport space.
     *
     * @param worldPt The world point to transform.
     * @param projectionViewMatrix The projection matrix to transform a 3D point to 2D point.
     * @returns A point in viewport space.
     */
    transformWorldToViewport(worldPt, projectionViewMatrix) {
        const ndc = vector3.transformMatrix(worldPt, projectionViewMatrix);
        return this.transformVectorToViewport(ndc);
    }
    transformPointToViewport(pt, image) {
        const { x: scaleX, y: scaleY } = this.calculateFrameScale(image);
        return point.scale(pt, 1 * scaleX, 1 * scaleY);
    }
    /**
     * Transforms a point in viewport coordinate space to a point in a frame's
     * coordinate space.
     *
     * @param pt A point in viewport coordinate space.
     * @param image An image of a frame.
     * @returns A point in the coordinate space of the frame.
     */
    transformPointToFrame(pt, image) {
        const { x: scaleX, y: scaleY } = this.calculateFrameScale(image);
        return point.scale(pt, 1 / scaleX, 1 / scaleY);
    }
    /**
     * Transforms a point in viewport coordinates to a point in world space
     * coordinates. This method expects a depth buffer in order to compute a value
     * for the Z axis.
     *
     * @param pt A point in viewport coordinates.
     * @param depthBuffer A depth buffer for computing the Z axis.
     * @param fallbackNormalizedDepth A fallback value if the depth is the max
     *   depth value, or cannot be determined.
     * @returns
     */
    transformPointToWorldSpace(pt, depthBuffer, fallbackNormalizedDepth) {
        const depthPt = this.transformPointToFrame(pt, depthBuffer);
        const ray = this.transformPointToRay(pt, depthBuffer, depthBuffer.camera);
        return depthBuffer.getWorldPoint(depthPt, ray, fallbackNormalizedDepth);
    }
    /**
     * Transforms a point in viewport coordinates to a ray.
     *
     * For perspective cameras, the returned ray will have an
     * origin that is at the position of the camera with a direction
     * that is pointing into world space away from the camera.
     *
     * For orthographic cameras, the returned ray will have an
     * origin that is at the world point of viewport coordinate
     * with a direction that is pointing into world space away
     * from the camera.
     *
     * @param pt A point in viewport coordinates.
     * @param image An image of a frame.
     * @param camera A camera used to determine orientation of the scene.
     * @returns A ray
     */
    transformPointToRay(pt, image, camera) {
        const ndc = this.transformScreenPointToNdc(pt, image);
        // Calculate the ray depending on the camera type
        if (camera.isPerspective()) {
            const origin = vector3.fromMatrixPosition(camera.worldMatrix);
            const lookAtPoint = vector3.transformNdcToWorldSpace(vector3.create(ndc.x, ndc.y, 0.5), camera.worldMatrix, camera.projectionMatrixInverse);
            const direction = vector3.normalize(vector3.subtract(lookAtPoint, origin));
            return ray.create({ origin, direction });
        }
        else {
            const origin = vector3.transformNdcToWorldSpace(vector3.create(ndc.x, ndc.y, 0), camera.worldMatrix, camera.projectionMatrixInverse);
            return ray.create({
                origin,
                direction: vector3.normalize(camera.viewVector),
            });
        }
    }
    /**
     * Maps a screen point to normalized device coordinates (NDC). A screen point
     * at 0,0 represents the top-left of the viewport.
     *
     * @param screenPt A screen point.
     */
    transformScreenPointToNdc(screenPt, image) {
        const framePt = this.transformPointToFrame(screenPt, image);
        return point.create((framePt.x / image.imageAttr.frameDimensions.width) * 2 - 1, -(framePt.y / image.imageAttr.frameDimensions.height) * 2 + 1);
    }
    /**
     * Computes a rectangle that is scaled correctly to be drawn within the
     * viewport.
     *
     * @param image The image to be drawn.
     * @param imageDimensions The dimensions of the received image.
     * @returns A rectangle.
     */
    calculateDrawRect(image) {
        const { x: scaleX, y: scaleY } = this.calculateFrameScale(image);
        return rectangle.scale(image.imageAttr.imageRect, scaleX, scaleY);
    }
    calculateFrameScale(image) {
        const { frameDimensions: dimensions } = image.imageAttr;
        const imageRect = rectangle.fromDimensions(dimensions);
        const viewport = rectangle.fromDimensions(this.dimensions);
        const fit = rectangle.containFit(viewport, imageRect);
        const scaleX = fit.width / imageRect.width;
        const scaleY = fit.height / imageRect.height;
        return point.create(scaleX, scaleY);
    }
    get dimensions() {
        return dimensions.create(this.width, this.height);
    }
}

export { Viewport as V };
//# sourceMappingURL=viewport-DbTg_ax4.js.map

//# sourceMappingURL=viewport-DbTg_ax4.js.map