/*
All material copyright Esri, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/5.0/esri/copyright.txt for details.
*/
import{numberMaxFloat32 as e}from"../core/mathUtils.js";import{multiply as i,fromTranslation as o}from"../core/libs/gl-matrix-2/math/mat4.js";import{create as r}from"../core/libs/gl-matrix-2/factories/mat4f64.js";import{set as t}from"../core/libs/gl-matrix-2/math/vec2.js";import{create as a}from"../core/libs/gl-matrix-2/factories/vec2f64.js";import{h as s}from"./vec32.js";import{create as n}from"../core/libs/gl-matrix-2/factories/vec3f64.js";import{create as c,positiveInfinity as l}from"../geometry/support/aaBoundingBox.js";import{isColor as p}from"../views/3d/webgl-engine/core/shaderLibrary/ShaderOutput.js";import{SlicePlaneParameters as m,RejectBySlice as d}from"../views/3d/webgl-engine/core/shaderLibrary/Slice.glsl.js";import{OutputHighlight as f}from"../views/3d/webgl-engine/core/shaderLibrary/output/OutputHighlight.glsl.js";import{Float2DrawUniform as g}from"../views/3d/webgl-engine/core/shaderModules/Float2DrawUniform.js";import{Float2PassUniform as u}from"../views/3d/webgl-engine/core/shaderModules/Float2PassUniform.js";import{Float3DrawUniform as x}from"../views/3d/webgl-engine/core/shaderModules/Float3DrawUniform.js";import{glsl as S}from"../views/3d/webgl-engine/core/shaderModules/glsl.js";import{Matrix4BindUniform as v}from"../views/3d/webgl-engine/core/shaderModules/Matrix4BindUniform.js";import{Matrix4DrawUniform as h}from"../views/3d/webgl-engine/core/shaderModules/Matrix4DrawUniform.js";import{NoParameters as w}from"../views/webgl/NoParameters.js";import{ShaderBuilder as z}from"../views/webgl/ShaderBuilder.js";class b extends w{constructor(){super(...arguments),this.clipBox=c(l),this.useFixedSizes=!1,this.useRealWorldSymbolSizes=!1,this.scaleFactor=1,this.minSizePx=0,this.size=0,this.sizePx=0}get fixedSize(){return this.drawScreenSpace?this.sizePx:this.size}get screenMinSize(){return this.useFixedSizes?0:this.minSizePx}get drawScreenSpace(){return this.useFixedSizes&&!this.useRealWorldSymbolSizes}}class M extends m{constructor(e,i,o){super(e),this.origin=e,this.isLeaf=i,this.splatSize=o}}function j(r){const a=new z,n=p(r.output),{vertex:c,fragment:l}=a;return a.vertex.include(d,r),a.attributes.add("position","vec3"),a.attributes.add("color","vec3"),c.uniforms.add(new h("modelView",(e,r)=>i(y,r.camera.viewMatrix,o(y,e.origin))),new v("proj",e=>e.camera.projectionMatrix),new g("screenMinMaxSize",(e,i,o)=>t(B,o.useFixedSizes?0:o.minSizePx*i.camera.pixelRatio,P(e.isLeaf)*i.camera.pixelRatio)),r.useFixedSizes?new u("pointScale",(e,i)=>t(B,e.fixedSize*i.camera.pixelRatio,i.camera.fullHeight)):new g("pointScale",(e,i,o)=>t(B,e.splatSize*o.scaleFactor*i.camera.pixelRatio,i.camera.fullHeight/i.camera.pixelRatio))),r.clippingEnabled?c.uniforms.add(new x("clipMin",(e,i,o)=>s(O,o.clipBox[0]-e.origin[0],o.clipBox[1]-e.origin[1],o.clipBox[2]-e.origin[2])),new x("clipMax",(e,i,o)=>s(O,o.clipBox[3]-e.origin[0],o.clipBox[4]-e.origin[1],o.clipBox[5]-e.origin[2]))):(c.constants.add("clipMin","vec3",[-e,-e,-e]),c.constants.add("clipMax","vec3",[e,e,e])),n&&a.varyings.add("vColor","vec3"),c.main.add(S`
    // Move clipped points outside of clipspace
    if (position.x < clipMin.x || position.y < clipMin.y || position.z < clipMin.z ||
      position.x > clipMax.x || position.y > clipMax.y || position.z > clipMax.z) {
      gl_Position = vec4(1e038, 1e038, 1e038, 1.0);
      gl_PointSize = 0.0;
      return;
    }

    if (rejectBySlice(position)) {
      gl_Position = vec4(1e038, 1e038, 1e038, 1.0);
      gl_PointSize = 0.0;
      return;
    }

    // Position in camera space
    vec4 camera = modelView * vec4(position, 1.0);

    float pointSize = pointScale.x;
    vec4 position = proj * camera;
    ${r.drawScreenSize?S`float clampedScreenSize = pointSize;`:S`float pointRadius = 0.5 * pointSize;
           vec4 cameraOffset = camera + vec4(0.0, pointRadius, 0.0, 0.0);
           vec4 positionOffset = proj * cameraOffset;
           float radius = abs(positionOffset.y - position.y);
           float viewHeight = pointScale.y;
           // screen diameter = (2 * r / w) * (h / 2)
           float screenPointSize = (radius / position.w) * viewHeight;
           float clampedScreenSize = clamp(screenPointSize, screenMinMaxSize.x, screenMinMaxSize.y);
           // Shift towards camera, to move rendered point out of terrain i.e. to
           // the camera-facing end of the virtual point when considering it as a
           // 3D sphere.
           camera.xyz -= normalize(camera.xyz) * pointRadius * clampedScreenSize / screenPointSize;
           position = proj * camera;`}

    gl_PointSize = clampedScreenSize;
    gl_Position = position;
    ${n?S`vColor = color;`:""}`),a.include(f,r),l.main.add(S`
    vec2 vOffset = gl_PointCoord - vec2(0.5, 0.5);
    float r2 = dot(vOffset, vOffset);

    if (r2 > 0.25) {
      discard;
    }
    calculateOcclusionAndOutputHighlight();
    ${n?S`fragColor = vec4(vColor, 1.0);`:""}`),a}function P(e){return e?256:64}const y=r(),O=n(),B=a(),R=Object.freeze(Object.defineProperty({__proto__:null,PointRendererDrawParameters:M,PointRendererPassParameters:b,build:j,getMaxPointSizeScreenspace:P},Symbol.toStringTag,{value:"Module"}));export{b as P,M as a,R as b,j as c,P as g};
