/* COPYRIGHT Esri - https://js.arcgis.com/5.1.0/LICENSE.txt */
import{deg2rad as e}from"../core/mathUtils.js";import{set as i}from"../core/libs/gl-matrix-2/math/vec2.js";import{create as t}from"../core/libs/gl-matrix-2/factories/vec2f64.js";import{subtract as n,normalize as a,length as o,distance as r,transformMat4 as l,copy as s,cross as c,add as d}from"../core/libs/gl-matrix-2/math/vec3.js";import{create as f}from"../core/libs/gl-matrix-2/factories/vec3f64.js";import{transformMat4 as p}from"../core/libs/gl-matrix-2/math/vec4.js";import{create as g}from"../core/libs/gl-matrix-2/factories/vec4f64.js";import{pointAt as h}from"../geometry/support/lineSegment.js";import{fromPositionAndNormal as m,create as u}from"../geometry/support/plane.js";import{Laserline as w}from"../views/3d/webgl-engine/core/shaderLibrary/Laserline.glsl.js";import{ScreenSpacePass as x}from"../views/3d/webgl-engine/core/shaderLibrary/ScreenSpacePass.glsl.js";import{Float2PassUniform as b}from"../views/3d/webgl-engine/core/shaderModules/Float2PassUniform.js";import{Float3BindUniform as v}from"../views/3d/webgl-engine/core/shaderModules/Float3BindUniform.js";import{Float3PassUniform as P}from"../views/3d/webgl-engine/core/shaderModules/Float3PassUniform.js";import{Float4PassUniform as D}from"../views/3d/webgl-engine/core/shaderModules/Float4PassUniform.js";import{FloatBindUniform as M}from"../views/3d/webgl-engine/core/shaderModules/FloatBindUniform.js";import{FloatPassUniform as S}from"../views/3d/webgl-engine/core/shaderModules/FloatPassUniform.js";import{glsl as C}from"../views/3d/webgl-engine/core/shaderModules/glsl.js";import{ShaderBuilder as L}from"../views/webgl/ShaderBuilder.js";const A=e(6);function j(e){const i=new L;i.include(x),i.include(w,e);const t=i.fragment;if(e.lineVerticalPlaneEnabled||e.heightManifoldEnabled)if(t.uniforms.add(new S("maxPixelDistance",(i,t)=>e.heightManifoldEnabled?2*t.camera.computeScreenPixelSizeAt(i.heightManifoldTarget):2*t.camera.computeScreenPixelSizeAt(i.lineVerticalPlaneSegment.origin))),t.code.add(C`float planeDistancePixels(vec4 plane, vec3 pos) {
float dist = dot(plane.xyz, pos) + plane.w;
float width = fwidth(dist);
dist /= min(width, maxPixelDistance);
return abs(dist);
}`),e.spherical){const e=(e,i,t)=>l(e,i.heightManifoldTarget,t.camera.viewMatrix),i=(e,i)=>l(e,[0,0,0],i.camera.viewMatrix);t.uniforms.add(new D("heightManifoldOrigin",(t,r)=>(e(R,t,r),i(G,r),n(G,G,R),a(U,G),U[3]=o(G),U)),new v("globalOrigin",e=>i(R,e)),new S("cosSphericalAngleThreshold",(e,i)=>1-Math.max(2,r(i.camera.eye,e.heightManifoldTarget)*i.camera.perRenderPixelRatio)/o(e.heightManifoldTarget))),t.code.add(C`float globeDistancePixels(float posInGlobalOriginLength) {
float dist = abs(posInGlobalOriginLength - heightManifoldOrigin.w);
float width = fwidth(dist);
dist /= min(width, maxPixelDistance);
return abs(dist);
}
float heightManifoldDistancePixels(vec4 heightPlane, vec3 pos) {
vec3 posInGlobalOriginNorm = normalize(globalOrigin - pos);
float cosAngle = dot(posInGlobalOriginNorm, heightManifoldOrigin.xyz);
vec3 posInGlobalOrigin = globalOrigin - pos;
float posInGlobalOriginLength = length(posInGlobalOrigin);
float sphericalDistance = globeDistancePixels(posInGlobalOriginLength);
float planarDistance = planeDistancePixels(heightPlane, pos);
return cosAngle < cosSphericalAngleThreshold ? sphericalDistance : planarDistance;
}`)}else t.code.add(C`float heightManifoldDistancePixels(vec4 heightPlane, vec3 pos) {
return planeDistancePixels(heightPlane, pos);
}`);if(e.pointDistanceEnabled&&(t.uniforms.add(new S("maxPixelDistance",(e,i)=>2*i.camera.computeScreenPixelSizeAt(e.pointDistanceTarget))),t.code.add(C`float sphereDistancePixels(vec4 sphere, vec3 pos) {
float dist = distance(sphere.xyz, pos) - sphere.w;
float width = fwidth(dist);
dist /= min(width, maxPixelDistance);
return abs(dist);
}`)),e.intersectsLineEnabled&&t.uniforms.add(new M("perScreenPixelRatio",e=>e.camera.perScreenPixelRatio)).code.add(C`float lineDistancePixels(vec3 start, vec3 dir, float radius, vec3 pos) {
float dist = length(cross(dir, pos - start)) / (length(pos) * perScreenPixelRatio);
return abs(dist) - radius;
}`),(e.lineVerticalPlaneEnabled||e.intersectsLineEnabled)&&t.code.add(C`bool pointIsWithinLine(vec3 pos, vec3 start, vec3 end) {
vec3 dir = end - start;
float t2 = dot(dir, pos - start);
float l2 = dot(dir, dir);
return t2 >= 0.0 && t2 <= l2;
}`),t.main.add(C`vec3 pos;
vec3 normal;
float angleCutoffAdjust;
float depthDiscontinuityAlpha;
if (!laserlineReconstructFromDepth(pos, normal, angleCutoffAdjust, depthDiscontinuityAlpha)) {
fragColor = vec4(0.0);
return;
}
vec4 color = vec4(0.0);`),e.heightManifoldEnabled){t.uniforms.add(new b("angleCutoff",e=>V(e)),new D("heightPlane",(e,i)=>I(e.heightManifoldTarget,e.renderCoordsHelper.worldUpAtPosition(e.heightManifoldTarget,R),i.camera.viewMatrix)));const i=e.spherical?C`normalize(globalOrigin - pos)`:C`heightPlane.xyz`;t.main.add(C`
      vec2 angleCutoffAdjusted = angleCutoff - angleCutoffAdjust;
      // Fade out laserlines on flat surfaces
      float heightManifoldAlpha = 1.0 - smoothstep(angleCutoffAdjusted.x, angleCutoffAdjusted.y, abs(dot(normal, ${i})));
      vec4 heightManifoldColor = laserlineProfile(heightManifoldDistancePixels(heightPlane, pos));
      color = max(color, heightManifoldColor * heightManifoldAlpha);`)}return e.pointDistanceEnabled&&(t.uniforms.add(new b("angleCutoff",e=>V(e)),new D("pointDistanceSphere",(e,i)=>y(e,i))),t.main.add(C`float pointDistanceSphereDistance = sphereDistancePixels(pointDistanceSphere, pos);
vec4 pointDistanceSphereColor = laserlineProfile(pointDistanceSphereDistance);
float pointDistanceSphereAlpha = 1.0 - smoothstep(angleCutoff.x, angleCutoff.y, abs(dot(normal, normalize(pos - pointDistanceSphere.xyz))));
color = max(color, pointDistanceSphereColor * pointDistanceSphereAlpha);`)),e.lineVerticalPlaneEnabled&&(t.uniforms.add(new b("angleCutoff",e=>V(e)),new D("lineVerticalPlane",(e,i)=>O(e,i)),new P("lineVerticalStart",(e,i)=>E(e,i)),new P("lineVerticalEnd",(e,i)=>z(e,i))),t.main.add(C`if (pointIsWithinLine(pos, lineVerticalStart, lineVerticalEnd)) {
float lineVerticalDistance = planeDistancePixels(lineVerticalPlane, pos);
vec4 lineVerticalColor = laserlineProfile(lineVerticalDistance);
float lineVerticalAlpha = 1.0 - smoothstep(angleCutoff.x, angleCutoff.y, abs(dot(normal, lineVerticalPlane.xyz)));
color = max(color, lineVerticalColor * lineVerticalAlpha);
}`)),e.intersectsLineEnabled&&(t.uniforms.add(new b("angleCutoff",e=>V(e)),new P("intersectsLineStart",(e,i)=>l(R,e.lineStartWorld,i.camera.viewMatrix)),new P("intersectsLineEnd",(e,i)=>l(R,e.lineEndWorld,i.camera.viewMatrix)),new P("intersectsLineDirection",(e,i)=>(s(U,e.intersectsLineSegment.vector),U[3]=0,a(R,p(U,U,i.camera.viewMatrix)))),new S("intersectsLineRadius",e=>e.intersectsLineRadius)),t.main.add(C`if (pointIsWithinLine(pos, intersectsLineStart, intersectsLineEnd)) {
float intersectsLineDistance = lineDistancePixels(intersectsLineStart, intersectsLineDirection, intersectsLineRadius, pos);
vec4 intersectsLineColor = laserlineProfile(intersectsLineDistance);
float intersectsLineAlpha = 1.0 - smoothstep(angleCutoff.x, angleCutoff.y, 1.0 - abs(dot(normal, intersectsLineDirection)));
color = max(color, intersectsLineColor * intersectsLineAlpha);
}`)),t.main.add(C`fragColor = laserlineOutput(color * depthDiscontinuityAlpha);`),i}function V(t){return i(T,Math.cos(t.angleCutoff),Math.cos(Math.max(0,t.angleCutoff-e(2))))}function y(e,i){return l(_,e.pointDistanceOrigin,i.camera.viewMatrix),_[3]=r(e.pointDistanceOrigin,e.pointDistanceTarget),_}function O(e,i){const t=h(e.lineVerticalPlaneSegment,.5,R),n=e.renderCoordsHelper.worldUpAtPosition(t,F),o=a(G,e.lineVerticalPlaneSegment.vector),r=c(R,n,o);return a(r,r),I(e.lineVerticalPlaneSegment.origin,r,i.camera.viewMatrix)}function E(e,i){const t=s(R,e.lineVerticalPlaneSegment.origin);return e.renderCoordsHelper.setAltitude(t,0),l(t,t,i.camera.viewMatrix)}function z(e,i){const t=d(R,e.lineVerticalPlaneSegment.origin,e.lineVerticalPlaneSegment.vector);return e.renderCoordsHelper.setAltitude(t,0),l(t,t,i.camera.viewMatrix)}function I(e,i,t){return l(W,e,t),s(U,i),U[3]=0,p(U,U,t),m(W,U,H)}const T=t(),R=f(),U=g(),F=f(),G=f(),W=f(),H=u(),_=g(),B=Object.freeze(Object.defineProperty({__proto__:null,build:j,defaultAngleCutoff:A},Symbol.toStringTag,{value:"Module"}));export{B as L,j as b,A as d};
