import { Shape } from './shape.js';

/**
 * The plane shape
 * @public
 */ class PlaneShape extends Shape {
    static _defaultOptions = {
        ...Shape._defaultOptions,
        size: 1,
        resolution: 1,
        twoSided: false,
        anchor: 0.5
    };
    /**
   * Creates an instance of plane shape
   * @param options - The creation options
   */ constructor(options){
        super(options);
    }
    clone() {
        return new PlaneShape(this._options);
    }
    /** type of the shape */ get type() {
        return 'Plane';
    }
    /**
   * Intersects the ray with the finite XZ plane (y = 0) whose bounds are
   * determined by size/anchor options.
   */ raycast(ray) {
        const opt = this._options;
        const sizeX = Math.abs(opt.sizeX || opt.size || 1);
        const sizeY = Math.abs(opt.sizeY || opt.size || 1);
        const anchorX = opt.anchorX ?? opt.anchor ?? 0.5;
        const anchorY = opt.anchorY ?? opt.anchor ?? 0.5;
        const minX = -anchorX * sizeX;
        const maxX = minX + sizeX;
        const minZ = -anchorY * sizeY;
        const maxZ = minZ + sizeY;
        // Plane is y = 0 (XZ plane)
        const dy = ray.direction.y;
        if (Math.abs(dy) < 1e-10) {
            return null;
        } // ray parallel to plane
        const t = -ray.origin.y / dy;
        if (t < 0) {
            return null;
        }
        const hx = ray.origin.x + t * ray.direction.x;
        const hz = ray.origin.z + t * ray.direction.z;
        if (hx < minX || hx > maxX || hz < minZ || hz > maxZ) {
            return null;
        }
        return t;
    }
    /**
   * Generates the data for the cylinder shape
   * @param vertices - vertex positions
   * @param normals - vertex normals
   * @param uvs - vertex uvs
   * @param indices - vertex indices
   */ static generateData(opt, vertices, normals, tangents, uvs, indices, bbox, indexOffset, vertexCallback) {
        const options = Object.assign({}, this._defaultOptions, opt ?? {});
        indexOffset = indexOffset ?? 0;
        const start = vertices.length;
        const sizeX = Math.abs(options.sizeX || options.size) || 1;
        const sizeY = Math.abs(options.sizeY || options.size) || 1;
        const anchorX = options.anchorX ?? options.anchor;
        const anchorY = options.anchorY ?? options.anchor;
        const minX = -anchorX * sizeX;
        const maxX = minX + sizeX;
        const minY = -anchorY * sizeY;
        const maxY = minY + sizeY;
        const resolutionX = Math.max(options.resolutionX ?? options.resolution, 1);
        const resolutionY = Math.max(options.resolutionY ?? options.resolution, 1);
        const dx = (maxX - minX) / resolutionX;
        const dy = (maxY - minY) / resolutionY;
        for(let i = 0; i <= resolutionX; i++){
            for(let j = 0; j <= resolutionY; j++){
                uvs?.push(i / resolutionX, j / resolutionY);
                vertices?.push(minX + dx * i, 0, minY + dy * j);
                normals?.push(0, 1, 0);
                tangents?.push(1, 0, 0, 1);
            }
        }
        if (indices) {
            for(let i = 0; i < resolutionX; i++){
                for(let j = 0; j < resolutionY; j++){
                    const tl = j * (resolutionY + 1) + i;
                    const tr = (j + 1) * (resolutionY + 1) + i;
                    const bl = tl + 1;
                    const br = tr + 1;
                    indices.push(tl + indexOffset, bl + indexOffset, br + indexOffset, tl + indexOffset, br + indexOffset, tr + indexOffset);
                    if (options.twoSided) {
                        indices.push(tl + indexOffset, br + indexOffset, bl + indexOffset, tl + indexOffset, tr + indexOffset, br + indexOffset);
                    }
                }
            }
        }
        Shape._transform(options.transform, vertices, normals, start);
        if (bbox || vertexCallback) {
            for(let i = start; i < vertices.length - 2; i += 3){
                if (bbox) {
                    bbox.minPoint.x = Math.min(bbox.minPoint.x, vertices[i]);
                    bbox.minPoint.y = Math.min(bbox.minPoint.y, vertices[i + 1]);
                    bbox.minPoint.z = Math.min(bbox.minPoint.z, vertices[i + 2]);
                    bbox.maxPoint.x = Math.max(bbox.maxPoint.x, vertices[i]);
                    bbox.maxPoint.y = Math.max(bbox.maxPoint.y, vertices[i + 1]);
                    bbox.maxPoint.z = Math.max(bbox.maxPoint.z, vertices[i + 2]);
                }
                vertexCallback?.((i - start) / 3, vertices[i], vertices[i + 1], vertices[i + 2]);
            }
        }
        return 'triangle-list';
    }
}

export { PlaneShape };
//# sourceMappingURL=plane.js.map
