/* COPYRIGHT Esri - https://js.arcgis.com/5.1.2/LICENSE.txt */
import{fromValues as e}from"../../../../../../core/libs/gl-matrix-2/factories/vec2f64.js";import{TextureBackedBufferModule as t}from"../TextureBackedBuffer.glsl.js";import{PathEvaluate as r}from"./PathEvaluate.glsl.js";import{PiUtils as o}from"../shading/PiUtils.glsl.js";import{Float2PassUniform as i}from"../../shaderModules/Float2PassUniform.js";import{Float3PassUniform as a}from"../../shaderModules/Float3PassUniform.js";import{Float4PassUniform as l}from"../../shaderModules/Float4PassUniform.js";import{Float4sPassUniform as s}from"../../shaderModules/Float4sPassUniform.js";import{FloatPassUniform as v}from"../../shaderModules/FloatPassUniform.js";import{FloatsPassUniform as c}from"../../shaderModules/FloatsPassUniform.js";import{glsl as u,If as n}from"../../shaderModules/glsl.js";import{Texture2DUintDrawUniform as f}from"../../shaderModules/Texture2DUintDrawUniform.js";import{circleProfiles as d}from"../../../lib/PathProfile.js";import{getTextureLayout as p}from"../../../materials/PathLayouts.js";import{VisualVariablePassParameters as m,vvColorNumber as x}from"../../../materials/VisualVariablePassParameters.js";const g=8;function h(e,d){const{attributes:m,vertex:h}=e,y=new f("componentTextureBuffer",e=>e.textureBuffer),V=new t({layout:p(d),itemIndexAttribute:"textureElementIndex",bufferUniform:y});e.include(V.TextureBackedBufferModule,d),m.add("textureElementIndex","uint"),h.uniforms.add(new i("size",e=>e.size));const{hasVVSize:b,hasVVColor:z,hasVVOpacity:O}=d;b?(h.uniforms.add(new a("vvSizeMinSize",e=>e.vvSize.minSize),new a("vvSizeMaxSize",e=>e.vvSize.maxSize),new a("vvSizeOffset",e=>e.vvSize.offset),new a("vvSizeFactor",e=>e.vvSize.factor),new a("vvSizeFallback",e=>e.vvSize.fallback)),h.code.add(u`
    vec2 getSize() {
      float value = ${V.getTextureAttribute("sizeFeatureAttribute")};
      if (isnan(value)) {
        return vvSizeFallback.xz;
      }
      return size * clamp(vvSizeOffset + value * vvSizeFactor, vvSizeMinSize, vvSizeMaxSize).xz;
    }
    `)):h.code.add(u`vec2 getSize(){
return size;
}`),O?(h.constants.add("vvOpacityNumber","int",g),h.uniforms.add(new c("vvOpacityValues",g,e=>e.vvOpacity.values),new c("vvOpacityOpacities",g,e=>e.vvOpacity.opacityValues),new v("vvOpacityFallback",e=>e.vvOpacity.fallback,{supportsNaN:!0})),h.code.add(u`
    vec4 applyOpacity(vec4 color) {
      // if we encounter NaN in the color it means the color is in the fallback case where the symbol color
      // is not defined and there is no valid color visual variable override. In this case just return a fully
      // transparent color
      if (isnan(color.r)) {
        return vec4(0);
      }

      float value = ${V.getTextureAttribute("opacityFeatureAttribute")};

      if (isnan(value)) {
        // If there is a color vv then it will already have taken care of applying the fallback
        return ${n(z,"color","vec4(color.rgb, vvOpacityFallback)")};
      }

      if (value <= vvOpacityValues[0]) {
        return vec4(color.rgb, vvOpacityOpacities[0]);
      }

      for (int i = 1; i < vvOpacityNumber; ++i) {
        if (vvOpacityValues[i] >= value) {
          float f = (value - vvOpacityValues[i-1]) / (vvOpacityValues[i] - vvOpacityValues[i-1]);
          return vec4(color.rgb, mix(vvOpacityOpacities[i-1], vvOpacityOpacities[i], f));
        }
      }

      return vec4( color.rgb, vvOpacityOpacities[vvOpacityNumber - 1]);
    }
    `)):h.code.add(u`vec4 applyOpacity(vec4 color){
return color;
}`),z?(h.constants.add("vvColorNumber","int",x),h.uniforms.add(new c("vvColorValues",x,e=>e.vvColor.values),new s("vvColorColors",x,e=>e.vvColor.colors),new l("vvColorFallback",e=>e.vvColor.fallback)),h.code.add(u`
    vec4 getColor() {
      float value = ${V.getTextureAttribute("colorFeatureAttribute")};
      if (isnan(value)) {
        return applyOpacity(vvColorFallback);
      }

      if (value <= vvColorValues[0]) {
        return applyOpacity(vvColorColors[0]);
      }

      for (int i = 1; i < vvColorNumber; ++i) {
        if (vvColorValues[i] >= value) {
          float f = (value - vvColorValues[i-1]) / (vvColorValues[i] - vvColorValues[i-1]);
          return applyOpacity(mix(vvColorColors[i-1], vvColorColors[i], f));
        }
      }

      return applyOpacity(vvColorColors[vvColorNumber - 1]);
    }
    `)):h.code.add(u`vec4 getColor(){
return applyOpacity(vec4(1, 1, 1, 1));
}`),h.include(o),h.code.add(u`
    vec3 decompressAxis(vec2 axis) {
      float z = 1.0 - abs(axis.x) - abs(axis.y);
      return normalize(vec3(axis + sign(axis) * min(z, 0.0), z));
    }

    float getProfileRotation() {
      return PI * ${V.getTextureAttribute("profileRotation")};
    }

    float getMaxStretchDistance() {
      return ${V.getTextureAttribute("pathMaxStretchDistance")};
    }

    vec3 getFrameUp() {
      return decompressAxis(${V.getTextureAttribute("profileUp")});
    }

    vec3 getFrameRight() {
      return decompressAxis(${V.getTextureAttribute("profileRight")});
    }
  `),h.code.add(u`
    vec3 getFrameRotationUp() {
      return ${1===d.upVectorAlignment?u`decompressAxis(${V.getTextureAttribute("pathRotationUp")})`:u`getFrameUp()`};
    }
  `),e.include(r,d),h.code.add(u`
  vec3 calculateVPos(ExtrudedVertex extrudedVertex) {
    vec2 size = getSize();
    vec3 origin = ${V.getTextureAttribute("position")};
    vec3 right = extrudedVertex.frame.right;
    vec3 up = extrudedVertex.frame.up;
    vec2 profileVertex = extrudedVertex.profileVertex * size;
    `),h.code.add(u`if(extrudedVertex.isCap) {
float positionOffsetAlongProfilePlaneNormal = extrudedVertex.capPositionOffset * size[0];
vec3 forward = cross(up, right);
vec3 offset = right * profileVertex.x + up * profileVertex.y + forward * positionOffsetAlongProfilePlaneNormal;
return origin + offset;
}
vec2 rotationRight = extrudedVertex.rotationRight;
float maxDistance = extrudedVertex.maxDistance;`),h.code.add(u`rotationRight *= size;
rotationRight = length(rotationRight) > 0.0 ? normalize(rotationRight) : vec2(0, 0);
float rx = dot(profileVertex, rotationRight);
if (abs(rx) > maxDistance) {
vec2 rotationUp = vec2(-rotationRight.y, rotationRight.x);
float ry = dot(profileVertex, rotationUp);
profileVertex = rotationRight * maxDistance * sign(rx) + rotationUp * ry;
}
vec3 offset = right * profileVertex.x + up * profileVertex.y;
return origin + offset;
}`),h.code.add(u`vec3 localNormal(ExtrudedVertex extrudedVertex) {
vec3 right = extrudedVertex.frame.right;
vec3 up = extrudedVertex.frame.up;
vec2 profileNormal = extrudedVertex.profileNormal;
vec3 normal = right * profileNormal.x + up * profileNormal.y;
if(extrudedVertex.isCap) {
vec3 forward = cross(up, right);
normal += forward * extrudedVertex.capNormalOffset;
}
return normal;
}`)}class y extends m{constructor(){super(...arguments),this.numJoinSubdivisions=1,this.size=e(1,1),this.cutoffAngle=0,this.profile=d.center}}export{h as PathVertexPosition,y as PathVertexPositionPassParameters};
