(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.normalizeTextureName = exports.filterPointsForVisibleHemisphere = exports.isPointInVisibleHemisphere = exports.packPointsIntoFloatTexture = exports.computePointTextureLayout = exports.isFiniteNumber = exports.resolveShaderConfig = exports.DEFAULT_POINT_SHADER_CONFIG = void 0;
    exports.DEFAULT_POINT_SHADER_CONFIG = {
        dataTextureUniform: 'u_pointTexture',
        dataTextureDimensionsUniform: 'u_pointTextureDimensions',
        spriteTextureUniform: 'u_spriteTexture',
        motionTextureUniform: 'u_pointMotionTexture',
        nowSecondsUniform: 'u_nowSeconds',
        maxExtrapolationSecondsUniform: 'u_maxExtrapolationSeconds',
        rotationEnabledUniform: 'u_rotationEnabled',
    };
    const resolveShaderConfig = (raw) => ({
        dataTextureUniform: raw?.dataTextureUniform ?? exports.DEFAULT_POINT_SHADER_CONFIG.dataTextureUniform,
        dataTextureDimensionsUniform: raw?.dataTextureDimensionsUniform ?? exports.DEFAULT_POINT_SHADER_CONFIG.dataTextureDimensionsUniform,
        spriteTextureUniform: raw?.spriteTextureUniform ?? exports.DEFAULT_POINT_SHADER_CONFIG.spriteTextureUniform,
        motionTextureUniform: raw?.motionTextureUniform ?? exports.DEFAULT_POINT_SHADER_CONFIG.motionTextureUniform,
        nowSecondsUniform: raw?.nowSecondsUniform ?? exports.DEFAULT_POINT_SHADER_CONFIG.nowSecondsUniform,
        maxExtrapolationSecondsUniform: raw?.maxExtrapolationSecondsUniform ??
            exports.DEFAULT_POINT_SHADER_CONFIG.maxExtrapolationSecondsUniform,
        rotationEnabledUniform: raw?.rotationEnabledUniform ?? exports.DEFAULT_POINT_SHADER_CONFIG.rotationEnabledUniform,
    });
    exports.resolveShaderConfig = resolveShaderConfig;
    const isFiniteNumber = (value) => typeof value === 'number' && Number.isFinite(value);
    exports.isFiniteNumber = isFiniteNumber;
    const computePointTextureLayout = (capacity) => {
        const safeCapacity = Math.max(1, Math.ceil(capacity));
        const width = Math.ceil(Math.sqrt(safeCapacity));
        const height = Math.ceil(safeCapacity / width);
        return {
            width,
            height,
            capacity: width * height,
        };
    };
    exports.computePointTextureLayout = computePointTextureLayout;
    /**
     * Reuse a single float texture and grow it only when the requested capacity increases.
     */
    const packPointsIntoFloatTexture = (points, previousData, previousLayout, writePoint) => {
        const layout = previousLayout && previousLayout.capacity >= Math.max(1, points.length)
            ? previousLayout
            : (0, exports.computePointTextureLayout)(points.length);
        const requiredLength = layout.capacity * 4;
        const data = previousData && previousData.length === requiredLength
            ? previousData
            : new Float32Array(requiredLength);
        for (let pointIndex = 0; pointIndex < points.length; pointIndex += 1) {
            const point = points[pointIndex];
            writePoint(data, point, pointIndex * 4);
        }
        return {
            data,
            layout,
            count: points.length,
        };
    };
    exports.packPointsIntoFloatTexture = packPointsIntoFloatTexture;
    /**
     * Tests and callers can use this helper for fast broad-hemisphere filtering.
     */
    const isPointInVisibleHemisphere = (point, cameraDirection, scratchDirection = new Cesium.Cartesian3(), scratchCartesian = new Cesium.Cartesian3()) => {
        const pointCartesian = Cesium.Cartesian3.fromDegrees(point.longitude, point.latitude, point.altitudeMeters ?? 0, Cesium.Ellipsoid.WGS84, scratchCartesian);
        const pointDirection = Cesium.Cartesian3.normalize(pointCartesian, scratchDirection);
        return Cesium.Cartesian3.dot(cameraDirection, pointDirection) > 0;
    };
    exports.isPointInVisibleHemisphere = isPointInVisibleHemisphere;
    const filterPointsForVisibleHemisphere = (points, cameraDirection) => {
        const visiblePoints = [];
        for (const point of points) {
            if ((0, exports.isPointInVisibleHemisphere)(point, cameraDirection)) {
                visiblePoints.push(point);
            }
        }
        return visiblePoints;
    };
    exports.filterPointsForVisibleHemisphere = filterPointsForVisibleHemisphere;
    const normalizeTextureName = (textureName) => textureName.trim().toLowerCase().replace(/[^a-z0-9_]/g, '_') || 'point';
    exports.normalizeTextureName = normalizeTextureName;
});
