/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module WebGL
 */
import { assert, dispose } from "@itwin/core-bentley";
import { FeatureIndexType } from "@itwin/core-common";
import { AttributeMap } from "./AttributeMap";
import { CachedGeometry } from "./CachedGeometry";
import { GL } from "./GL";
import { BufferHandle, BufferParameters, BuffersContainer, QBufferHandle3d } from "./AttributeBuffers";
import { System } from "./System";
/** @internal */
export class PointCloudGeometry extends CachedGeometry {
    get isDisposed() { return this.buffers.isDisposed && this._vertices.isDisposed; }
    get asPointCloud() { return this; }
    get supportsThematicDisplay() { return true; }
    get overrideColorMix() { return .5; } // This could be a setting from either the mesh or the override if required.
    dispose() {
        if (!this.noDispose) {
            dispose(this.buffers);
            dispose(this._vertices);
        }
    }
    constructor(pointCloud) {
        super();
        this.renderGeometryType = "point-cloud";
        this.isInstanceable = false;
        this.noDispose = false;
        this._colorHandle = undefined;
        this.buffers = BuffersContainer.create();
        this._vertices = QBufferHandle3d.create(pointCloud.qparams, pointCloud.positions);
        const attrPos = AttributeMap.findAttribute("a_pos", 2 /* TechniqueId.PointCloud */, false);
        assert(undefined !== attrPos);
        const vertexDataType = (pointCloud.positions instanceof Float32Array) ? GL.DataType.Float : ((pointCloud.positions instanceof Uint8Array) ? GL.DataType.UnsignedByte : GL.DataType.UnsignedShort);
        this.buffers.addBuffer(this._vertices, [BufferParameters.create(attrPos.location, 3, vertexDataType, false, 0, 0, false)]);
        this._vertexCount = pointCloud.positions.length / 3;
        this._hasFeatures = FeatureIndexType.Empty !== pointCloud.features.type;
        this.voxelSize = pointCloud.voxelSize;
        this.colorIsBgr = "bgr" === pointCloud.colorFormat;
        if (undefined !== pointCloud.colors) {
            this._colorHandle = BufferHandle.createArrayBuffer(pointCloud.colors);
            const attrColor = AttributeMap.findAttribute("a_color", 2 /* TechniqueId.PointCloud */, false);
            assert(undefined !== attrColor);
            this.buffers.addBuffer(this._colorHandle, [BufferParameters.create(attrColor.location, 3, GL.DataType.UnsignedByte, true, 0, 0, false)]);
        }
    }
    collectStatistics(stats) {
        const bytesUsed = this._vertices.bytesUsed + (undefined !== this._colorHandle ? this._colorHandle.bytesUsed : 0);
        stats.addPointCloud(bytesUsed);
    }
    _wantWoWReversal(_target) { return false; }
    get techniqueId() { return 2 /* TechniqueId.PointCloud */; }
    getPass(target) {
        // Point clouds don't cast shadows.
        return target.isDrawingShadowMap ? "none" : "point-clouds";
    }
    get renderOrder() { return 5 /* RenderOrder.Linear */; }
    get qOrigin() { return this._vertices.origin; }
    get qScale() { return this._vertices.scale; }
    get colors() { return this._colorHandle; }
    get hasFeatures() { return this._hasFeatures; }
    get hasBakedLighting() { return true; }
    draw() {
        this.buffers.bind();
        System.instance.context.drawArrays(GL.PrimitiveType.Points, 0, this._vertexCount);
        this.buffers.unbind();
    }
    // ###TODO delete this.
    getLineWeight(_params) {
        // If line weight < 0 it is real size in meters (voxel size).
        return (this.voxelSize > 0) ? -this.voxelSize : 1;
    }
}
//# sourceMappingURL=PointCloud.js.map