@soonspacejs/plugin-heat-cloud 2.13.10 → 2.13.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/demo.d.ts +1 -1
- package/dist/index.d.ts +24 -26
- package/dist/index.esm.js +1 -1
- package/dist/types.d.ts +8 -8
- package/package.json +3 -3
package/dist/demo.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,26 +1,24 @@
|
|
|
1
|
-
import { ColorGradient, CreateImageData3DTextureFromGradientOptions, GradientVolumeMaterialOptions, HeatData3DOptions, HeatParticleVolumeFeaturePoint,
|
|
2
|
-
export * from '@three3d/volume';
|
|
3
|
-
import SoonSpace from 'soonspacejs';
|
|
4
|
-
import { CreatLineHeatOptions, CreateHeatCloudOptions, CreateHeatOptions, CreateImageExtrusionOptions } from './types';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
export * from './types';
|
|
26
|
-
export default HeatMapPlugin;
|
|
1
|
+
import { ColorGradient, CreateImageData3DTextureFromGradientOptions, GradientVolumeMaterialOptions, HeatData3DOptions, HeatParticleVolumeFeaturePoint, ParticleVolumeFeaturePoint, SliceMaterialOptions, VolumeMaterial } from '@three3d/volume';
|
|
2
|
+
export * from '@three3d/volume';
|
|
3
|
+
import SoonSpace from 'soonspacejs';
|
|
4
|
+
import { CreatLineHeatOptions, CreateHeatCloudOptions, CreateHeatOptions, CreateImageExtrusionOptions } from './types';
|
|
5
|
+
export declare class HeatMapPlugin {
|
|
6
|
+
readonly ssp: SoonSpace;
|
|
7
|
+
constructor(ssp: SoonSpace);
|
|
8
|
+
defaultColorGradient: ColorGradient;
|
|
9
|
+
defaultGradientVolumeMaterialOptions: GradientVolumeMaterialOptions;
|
|
10
|
+
protected _createTexture(points: HeatData3DOptions['points'], options: CreateHeatOptions, isLine?: boolean): any;
|
|
11
|
+
/**
|
|
12
|
+
* 创建热力云
|
|
13
|
+
* return material
|
|
14
|
+
*/
|
|
15
|
+
createHeatCloud(points: HeatParticleVolumeFeaturePoint[], options?: CreateHeatCloudOptions): any;
|
|
16
|
+
createLineHeat(points: ParticleVolumeFeaturePoint[], options: CreatLineHeatOptions): any;
|
|
17
|
+
createImageExtrusion(imageUrl: string, options?: CreateImageExtrusionOptions & {
|
|
18
|
+
depth?: number;
|
|
19
|
+
}): Promise<any>;
|
|
20
|
+
createSliceMesh(material: VolumeMaterial, options?: SliceMaterialOptions & CreateImageData3DTextureFromGradientOptions): any;
|
|
21
|
+
createImageSlice(material: VolumeMaterial, options?: CreateImageData3DTextureFromGradientOptions): any;
|
|
22
|
+
}
|
|
23
|
+
export * from './types';
|
|
24
|
+
export default HeatMapPlugin;
|
package/dist/index.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{TextureLoader as t,Texture as e,Matrix3 as n,Vector3 as i,Vector4 as a,Vector2 as o,AlphaFormat as r,RedFormat as s,RedIntegerFormat as l,RGFormat as c,RGIntegerFormat as u,RGBAFormat as d,RGBAIntegerFormat as m,LuminanceFormat as p,LuminanceAlphaFormat as f,DepthFormat as h,DepthStencilFormat as v,ShaderMaterial as g,GLSL3 as x,Matrix4 as _,DoubleSide as y,Mesh as w,BoxGeometry as M,Data3DTexture as z,FloatType as D,LinearFilter as S,UnsignedByteType as b,Color as C,FrontSide as N,UniformsUtils as U,ShaderLib as A,Points as P,PlaneGeometry as O,Box3 as I,Line3 as T,Quaternion as F,BackSide as R,RawShaderMaterial as V,BufferGeometry as E,Float32BufferAttribute as G,Uint8ClampedBufferAttribute as j}from"three";import L from"soonspacejs";var B,k=(t=>(t[t.x=0]="x",t[t.y=1]="y",t[t.z=2]="z",t))(k||{});(B=k||(k={})).toKey=function(t){return B[t]},B.toIndex=function(t){return B[t]},B.getCrossAxiss=function(t){return[(t+1)%3,(t+2)%3]};var H=(t=>(t[t.x=0]="x",t[t.y=1]="y",t[t.z=2]="z",t[t.w=3]="w",t))(H||{});(t=>{t.toKey=function(e){return t[e]},t.toIndex=function(e){return t[e]},t.getCrossAxiss=function(t){return[(t+1)%4,(t+2)%4]}})(H||(H={}));var q=Object.defineProperty,K=(t,e,n)=>(((t,e,n)=>{e in t?q(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n})(t,"symbol"!=typeof e?e+"":e,n),n);function W(t,e,n,i="srgb"){const a=new OffscreenCanvas(e,n).getContext("2d"),o=a.createLinearGradient(0,0,256,1);for(const[e,n]of t)o.addColorStop(Number(e),n);return a.fillStyle=o,a.fillRect(0,0,e,n),a.getImageData(0,0,e,n,{colorSpace:i})}function Y(t,e){let{area:n,width:i,height:a,colorSpace:o}=e||{};o=o??"srgb",n=n||{};const r=n.x??0,s=n.y??0,l=X(t),c=n.width??l.width,u=n.height??l.height;i=i??c,a=a??u;const d=new OffscreenCanvas(i,a).getContext("2d");return d.drawImage(t,r,s,c,u,0,0,i,a),d.getImageData(0,0,i,a,{colorSpace:o})}function X(t){let e=0,n=0;return t instanceof HTMLImageElement?(e=t.naturalWidth,n=t.naturalHeight):t instanceof HTMLVideoElement?(e=t.videoWidth,n=t.videoHeight):(e=t.width,n=t.height),{width:e,height:n}}function Z(t){const{data:e,width:n,height:i,colorSpace:a}=t,o=e.length,r=new Uint8ClampedArray(o);for(let t=0;t<i;t++){const i=t*n,a=-(i+n),o=a+n,s=e.slice(4*a,4*o);r.set(s,4*i)}return new ImageData(r,n,i,{colorSpace:a})}function J(t,e){const{data:n,width:i}=t,a=e*i,o=a+i;return n.slice(4*a,4*o)}function Q(t,e,n){const{data:i,width:a}=t,o=4*(e*a+n);return i.slice(o,o+4)}function $(t){const e=document.createElement("canvas"),n=e.getContext("2d");return e.width=t.width,e.height=t.height,n.putImageData(t,0,0),e}function tt(t){return $(t).toDataURL()}function et(t){return t&&null!=t.data&&null!=t.width&&null!=t.height}function nt(t){return et(t)&&null!=t.depth}function it(t,e){for(const[n,i]of Object.entries(t))if(0<=i&&i<=e[n])return!0;return!1}function at(t,e){const{x:n,y:i}=e;return t.z*i*n+t.y*n+t.x}function ot(t,e){const{x:n,y:i}=e,a=Math.trunc(t/n),o=t-a*n,r=Math.trunc(a/i);return{x:o,y:a-r*i,z:r}}function rt(t,e,n=1){let{x:i,y:a,z:o}=e;const r=t.size;return i=Math.max(0,Math.min(r.x-1,i)),a=Math.max(0,Math.min(r.y-1,a)),o=Math.max(0,Math.min(r.z-1,o)),st(t,{x:i,y:a,z:o},n)}function st(t,e,n=1){const{data:i,size:a}=t,o=at(e,a);let r=[];if(n>0){const t=o*n;for(let e=0;e<n;e++)r.push(i[t+e])}return{index:o,value:r}}function lt(t,e){let{x:n,y:i,z:a}=e;const o=t.size;return n=Math.max(0,Math.min(o.x-1,n)),i=Math.max(0,Math.min(o.y-1,i)),a=Math.max(0,Math.min(o.z-1,a)),ct(t,{x:n,y:i,z:a})}function ct(t,e){const{data:n,size:i}=t,a=at(e,i);return{index:a,value:n[a]}}function ut(t,e){const{voidValue:n,valuesAccumulate:i,verifyVoid:a=(()=>!1)}=e;let{x:o,y:r,z:s}=t[0].size;const l=t.length;for(let e=1;e<l;e++){const n=t[e].size;o=Math.max(o,n.x),r=Math.max(r,n.y),s=Math.max(s,n.z)}const c=new Array(o*r*s),u=o*r;for(let e=0;e<s;e++){const s=e*u;for(let l=0;l<r;l++){const r=s+l*o;for(let s=0;s<o;s++){const o=r+s,u={x:s,y:l,z:e},d=[];for(const n of t){const t=n.size;if(s<t.x&&l<t.y&&e<t.z)continue;const{index:i,value:o}=ct(n,u);a(o,n,i)||d.push({value:o,index:i,data3D:n,coord:u})}const m=d.length;let p=n;m>1?p=i(d):1===m&&(p=d[0].value),c[o]=p}}}return{data:c,size:{x:o,y:r,z:s}}}function dt(t,e,n,i=1){const{size:a}=t,o=k.toKey(e),[r,s]=k.getCrossAxiss(e),l=k.toKey(r),c=k.toKey(s),u=a[l],d=a[c],m=[],p=a[o];n=Math.trunc(n),n=Math.max(0,Math.min(p-1,n));let f={x:0,y:0,z:0};f[o]=n;for(let e=0;e<d;e++){f[c]=e;for(let e=0;e<u;e++){f[l]=e;const{value:n}=st(t,f,i);m.push(...n)}}return{data:m,size:{x:u,y:d}}}function mt(t,e,n){e=Math.trunc(e);const{data:i,width:a,height:o,colorSpace:r}=n?Z(t):t,s=i.length,l=new Uint8ClampedArray(s*e);for(let t=0;t<e;t++)l.set(i,t*s);return{data:l,width:a,height:o,depth:e,colorSpace:r}}function pt(t,e,n){const i=n||{},a=i.reverseY,o=i.axis??"z",r=et(t)?t:Y(t,i);return"z"===o?mt(r,e,a):ft(r,o,e,a)}function ft(t,e,n,i){n=Math.trunc(n);const{data:a,width:o,height:r,colorSpace:s}=i?Z(t):t,l=k.toKey(e),c=(e+1)%3,u=(e+2)%3,d=k.toKey(c),m=k.toKey(u),p={[d]:o,[m]:r,[l]:n},f=new Uint8ClampedArray(a.length*n),h={x:0,y:0,z:0};for(let t=0;t<n;t++){h[l]=t;for(let t=0;t<r;t++){h[m]=t;for(let e=0;e<o;e++){h[d]=e;const n=4*(t*o+e),i=n+4,r=a.subarray(n,i),s=4*at(h,p);f.set(r,s)}}}return{data:f,width:p.x,height:p.y,depth:p.z,colorSpace:s}}function ht(t,e){return t.y*e.x+t.x}function vt(t,e){const{x:n}=e,i=Math.trunc(t/n);return{x:t-i*n,y:i}}function gt(t,e,n=1){let{x:i,y:a}=e;const o=t.size;return i=Math.max(0,Math.min(o.x-1,i)),a=Math.max(0,Math.min(o.y-1,a)),xt(t,{x:i,y:a},n)}function xt(t,e,n=1){const{data:i,size:a}=t,o=ht(e,a);let r=[];if(n>0){const t=o*n;for(let e=0;e<n;e++)r.push(i[t+e])}return{index:o,value:r}}function _t(t,e){let{x:n,y:i}=e;const a=t.size;return n=Math.max(0,Math.min(a.x-1,n)),i=Math.max(0,Math.min(a.y-1,i)),yt(t,{x:n,y:i})}function yt(t,e){const{data:n,size:i}=t,a=ht(e,i);return{index:a,value:n[a]}}function wt(t,e,n=1){const{data:i,size:a}=t,o=a.x,r=e*o,s=r+o;return("function"==typeof i.slice?i:Array.from(i)).slice(r*n,s*n)}class Mt{constructor(t){K(this,"isImageData3DSlice",!0),K(this,"_image3D"),K(this,"_canvas"),K(this,"_context"),K(this,"_axis",k.z),K(this,"_depth",0),K(this,"_sliceSize",null),K(this,"_slice"),this.image3D=t}get image3D(){return this._image3D}set image3D(t){this._image3D=t,this.updateSize()}get canvas(){let t=this._canvas;return t||(t=this._canvas=document.createElement("canvas"),t.width=this.sliceSize.x,t.height=this.sliceSize.y),t}get context(){return this._context??(this._context=this.canvas.getContext("2d"))}get axis(){return this._axis}set axis(t){this._axis=t,this.updateSize()}get depth(){return this._depth}set depth(t){this._depth=t,this.updateSlice()}get sliceSize(){let t=this._sliceSize;if(!t){const{axis:e,image3D:n}=this,{width:i,height:a,depth:o}=n,[r,s]=k.getCrossAxiss(e),l=[i,a,o];this._sliceSize=t={x:l[r],y:l[s]}}return t}get slice(){return this._slice??(this._slice=this.getSlice(this.axis,this.depth))}getSlice(t,e){const{data:n,width:i,height:a,depth:o,colorSpace:r}=this.image3D,{data:s,size:l}=dt({data:n,size:{x:i,y:a,z:o}},t,e,4),c=s instanceof Uint8ClampedArray?s:Uint8ClampedArray.from(s);return new ImageData(c,l.x,l.y,{colorSpace:r})}getDataURL(){return this.canvas.toDataURL()}getColor(t){const{x:e,y:n}=t;return Q(this.slice,n,e)}updateSize(){this._sliceSize=null;const t=this.canvas;t.width=this.sliceSize.x,t.height=this.sliceSize.y,this.updateSlice()}updateSlice(){this._slice=null,this.context.putImageData(this.slice,0,0)}}var zt=Object.defineProperty,Dt=(t,e,n)=>(((t,e,n)=>{e in t?zt(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n})(t,"symbol"!=typeof e?e+"":e,n),n);function St(t){const e=t.length,n=[];if(0===e)return n;const[r,s]=function(t){return void 0!==t.w?[a,4]:void 0!==t.z?[i,3]:[o,2]}(t[0]);for(let i=0;i<e;i++){const a=t[i],o=(new r).copy(a),s=a.radius,l=n[i]??(n[i]=[]);for(let a=i+1;a<e;a++){const e=t[a];o.distanceToSquared(e)<=(e.radius+s)**2&&(l.push(a),(n[a]=[]).push(i))}}return n}let bt;function Ct(n){if("string"==typeof n)return(bt||(bt=new t)).load(n);if(n.isTexture)return n;const i=Array.isArray(n)?W(n,256,1):n,a=new e(i);return"srgb"===i.colorSpace&&(a.colorSpace="srgb"),a.needsUpdate=!0,a}function Nt(t,e,n){let i=function(t,e){const n=Math.sqrt(t.lengthSq()*e.lengthSq());if(0===n)return 0;let i=t.dot(e)/n;return i=Math.max(-1,Math.min(1,i)),Math.acos(i)}(t,e);return 0===i?i:t.clone().cross(e).dot(n)<0?-i:i}const Ut=180/Math.PI,At={yaw:[{name:"前",range:[-15,15]},{name:"左",range:[15,165]},{name:"右",range:[-165,-15]},{name:"后",range:[-180.1,-165]},{name:"后",range:[165,180.1]}],pitch:[{name:"前",range:[-15,15]},{name:"上",range:[15,165]},{name:"下",range:[-165,-15]},{name:"后",range:[-180.1,-165]},{name:"后",range:[165,180.1]}],roll:[{name:"上",range:[-15,15]},{name:"左",range:[15,165]},{name:"右",range:[-165,-15]},{name:"下",range:[-180.1,-165]},{name:"下",range:[165,180.1]}]};const Pt={degrees:!0,map:At,front:{x:0,y:0,z:1},up:{x:0,y:1,z:0}};let Ot=class{constructor(t){Dt(this,"_options"),Dt(this,"_listMap"),Dt(this,"_front"),Dt(this,"_up"),t&&(this.options=t)}static get options(){return this._options??(this.options=Pt)}static set options(t){this._options=Object.assign({},structuredClone(At),t)}get defaultOptions(){return this.constructor.options}get options(){return this._options??(this.options=this.defaultOptions)}set options(t){this._options=Object.assign({},structuredClone(this.defaultOptions),t),this._listMap=null,this._front=null,this._up=null}get degrees(){return this.options.degrees??(this.options.degrees=this.defaultOptions.degrees??!0)}set degrees(t){this.options.degrees=t}get map(){return this.options.map||(this.map=this.defaultOptions.map),this.options.map}set map(t){const e=structuredClone(this.defaultOptions.map),n=structuredClone(At);t=t?{yaw:t.yaw??e.yaw??n.yaw,pitch:t.pitch??e.pitch??n.pitch,roll:t.roll??e.roll??n.roll}:e,this.options.map=t,this._listMap=null}get listMap(){return this._listMap??(this._listMap=function(t){const e={};for(const[n,i]of Object.entries(t))e[n]=Array.isArray(i)?i:Object.entries(i).map((([t,e])=>({name:t,range:e})));return e}(this.map??{}))}get front(){return this._front||(this.front=this.options.front??this.defaultOptions.front??Pt.front),this._front}set front(t){this._front=(new i).copy(t)}get up(){return this._up||(this.up=this.options.up??this.defaultOptions.up??Pt.up),this._up}set up(t){this._up=(new i).copy(t)}computeAzimuth(t,e,n){const a=(new i).copy(t),o=(new i).copy(e??this.front),r=(new i).copy(n??this.up);let{yaw:s,pitch:l,roll:c}=function(t,e,n){const i=e.clone().negate(),a=n.clone().projectOnPlane(e),o=Nt(e,t.clone().projectOnPlane(a),a),r=e.clone().cross(a);return{yaw:o,pitch:Nt(e,t.clone().projectOnPlane(r),r),roll:Nt(a,t.clone().projectOnPlane(i),i)}}(a,o,r);return this.degrees&&(s*=Ut,l*=Ut,c*=Ut),{yaw:{angle:s,name:this.findAzimuthNames("yaw",s)},pitch:{angle:l,name:this.findAzimuthNames("pitch",l)},roll:{angle:c,name:this.findAzimuthNames("roll",c)}}}findAzimuthNames(t,e){const n=[],i=this.listMap[t];if(!i)return n;for(const{name:t,range:[a,o]}of i)(e>=a&&e<o||e<=a&&e>o)&&n.push(t);return n}};Dt(Ot,"_options"),new Ot;const It={[r]:1,[s]:1,[l]:1,[c]:3,[u]:2,[d]:4,[m]:4,[p]:1,[f]:2,[h]:1,[v]:2};function Tt(t){return It[t]}new n;var Ft=Object.defineProperty,Rt=(t,e,n)=>(((t,e,n)=>{e in t?Ft(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n})(t,"symbol"!=typeof e?e+"":e,n),n);var Vt=(t=>(t[t.Fill=0]="Fill",t[t.Align=1]="Align",t[t.Raw=2]="Raw",t))(Vt||{});class Et extends g{constructor(t){const{map:e,opacity:n,accFactor:a,steps:r,alphaRange:s,fit:l,atomize:c,side:u,containerMin:d,containerMax:m,uniforms:p,...f}=t??{},h=n??1,v=a??1,g=r??100,_=(new o).copy(s??{x:0,y:.95}),y=l??0,w=c??!0,M=u??N,z=(new i).copy(d??{x:0,y:0,z:0}),D=new i;if(m)D.copy(m);else if(e){const{width:t,height:n,depth:a}=e.image,o=new i(t-1,n-1,a-1);D.addVectors(z,o)}const S={map:{value:e},containerMin:{value:z},containerMax:{value:D},fit:{value:y},opacity:{value:h},alphaRange:{value:_},accFactor:{value:v},steps:{value:g},isDoubleSide:{value:!1},atomize:{value:w},...p};super({glslVersion:x,uniforms:S,transparent:!0,vertexShader:"precision highp sampler3D;\n\nuniform sampler3D map;\nuniform vec3 containerMin;\nuniform vec3 containerMax;\n\n// 0: 充满;1: 对齐;2: 原始\nuniform int fit;\n\n\nout vec3 cameraPos;\nout vec3 lookDir;\nout vec3 displayMin;\nout vec3 displayMax;\n\n\n\nvoid main() {\n cameraPos = vec3( inverse( modelMatrix ) * vec4( cameraPosition, 1.0 ) ).xyz;\n lookDir = position - cameraPos;\n\n vec3 containerSize = containerMax - containerMin;\n vec3 origin = containerMin;\n vec3 textSize = vec3(textureSize(map,0));\n displayMin = containerMin;\n displayMax = containerMax;\n\n switch (fit) {\n case 1:\n displayMax = displayMin + textSize;\n break;\n case 2:\n origin = vec3(0.0);\n break;\n default:\n textSize = containerSize;\n }\n\n vec3 scale = 1.0/textSize;\n cameraPos = (cameraPos - origin)*scale;\n lookDir *= scale;\n\n displayMin = max((displayMin - origin)*scale,vec3(0.0));\n displayMax = min((displayMax - origin)*scale,vec3(1.0));\n \n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",...f}),Rt(this,"isVolumeMaterial",!0),Rt(this,"_side",N),this.opacity=h,this.side=M}get map(){return this.uniforms.map.value}set map(t){this.uniforms.map.value=t,this.uniformsNeedUpdate=!0}get containerMin(){return this.uniforms.containerMin.value}set containerMin(t){this.uniforms.containerMin.value.copy(t),this.uniformsNeedUpdate=!0}get containerMax(){return this.uniforms.containerMax.value}set containerMax(t){this.uniforms.containerMax.value.copy(t),this.uniformsNeedUpdate=!0}get containerSize(){return this.containerMax.clone().sub(this.containerMin)}get fit(){return this.uniforms.fit.value}set fit(t){this.uniforms.fit.value=t,this.uniformsNeedUpdate=!0}getFitTranslate(){return 2===this.fit?new i:this.containerMin.clone()}getFitScale(){var t;const e=new i(1,1,1),n=null==(t=this.map)?void 0:t.image,a=this.fit;if(!n||2===a||1===a)return e;const o=new i(n.width,n.height,n.depth);return e.copy(this.containerSize).divide(o),e}getFitMatrix(){var t;const e=new _,n=null==(t=this.map)?void 0:t.image,a=this.fit;if(!n||2===a)return e;if(0===a){const t=new i(n.width,n.height,n.depth),a=this.containerSize.divide(t);e.makeScale(a.x,a.y,a.z)}return e.setPosition(this.containerMin),e}getFitMatrixInvert(){return this.getFitMatrix().invert()}get side(){return this._side}set side(t){this._side=t,this.uniforms&&(this.uniforms.isDoubleSide.value=t===y,this.uniformsNeedUpdate=!0)}get opacity(){return this.uniforms.opacity.value}set opacity(t){this.uniforms&&(this.uniforms.opacity.value=t),this.uniformsNeedUpdate=!0}get alphaRange(){return this.uniforms.alphaRange.value}set alphaRange(t){this.uniforms.alphaRange.value.copy(t),this.uniformsNeedUpdate=!0}get atomize(){return this.uniforms.atomize.value}set atomize(t){this.uniforms.atomize.value=t,this.uniformsNeedUpdate=!0}get steps(){return this.uniforms.steps.value}set steps(t){this.uniforms.steps.value=t,this.uniformsNeedUpdate=!0}get accFactor(){return this.uniforms.accFactor.value}set accFactor(t){this.uniforms&&(this.uniforms.accFactor.value=t),this.uniformsNeedUpdate=!0}toMapPosition(t){const e=new i(t.x,t.y,t.z).applyMatrix4(this.getFitMatrixInvert());return e.set(Math.trunc(e.x),Math.trunc(e.y),Math.trunc(e.z)),e}toMapDepth(t,e){const a=k.toKey(t),o=new i;o[a]=1;const r=(new n).setFromMatrix4(this.getFitMatrix());return o.applyMatrix3(r),e/=o.length(),Math.trunc(e)}getData3DSlice(t,e){const n=this.map;return null!=n&&n.image?function(t,e,n){const{data:i,width:a,height:o,depth:r}=t.image;return dt({data:i,size:{x:a,y:o,z:r}},e,n,Tt(t.format))}(n,t,e=this.toMapDepth(t,e)):null}getItem(t){const e=this.map;return null!=e&&e.image?function(t,e){const{data:n,width:i,height:a,depth:o}=t.image;return rt({data:n,size:{x:i,y:a,z:o}},e,Tt(t.format))}(e,this.toMapPosition(t)).value:null}}function Gt(t){t.boundingBox||t.computeBoundingBox();const{x:e,y:n,z:i}=t.boundingBox.min;return t.translate(-e,-n,-i),t}class jt extends w{constructor(t){var e;const{width:n,height:i,depth:a}=(null==(e=t.map)?void 0:e.image)||{},o=new M(n,i,a);Gt(o),super(o,t),Rt(this,"isVolumeMesh",!0),Rt(this,"_geometry"),Rt(this,"autoUpdateMaterial",!0),Rt(this,"_material"),Rt(this,"autoUpdateGeometry",!0),Rt(this,"autoNormalize",!1),Object.defineProperties(this,{geometry:{get:()=>this._geometry,set:t=>{this._geometry=t,this.autoNormalize?this.normalize():this.autoUpdateMaterial&&this.updateMaterial()}},material:{get:()=>this._material,set:t=>{this._material=t,this.autoUpdateGeometry&&this.updateGeometry()}}}),this.geometry=o,this.material=t}updateMaterial(){const{geometry:t,material:e}=this;if(!e||!t)return!1;t.boundingBox||t.computeBoundingBox();const{min:n,max:i}=t.boundingBox;e.containerMin=n,e.containerMax=i}updateGeometry(){var t;const{geometry:e,material:n,autoUpdateMaterial:a}=this,o=null==(t=n.map)?void 0:t.image;if(!o)return!1;e.boundingBox||e.computeBoundingBox();const{width:r,height:s,depth:l}=o,c=e.boundingBox.getSize(new i);e.scale(r/c.x,s/c.y,l/c.z),a&&this.updateMaterial()}normalize(){const{geometry:t,autoUpdateMaterial:e}=this;t.boundingBox||t.computeBoundingBox();const{x:n,y:i,z:a}=t.boundingBox.min;t.translate(-n,-i,-a),e&&this.updateMaterial()}toMapPosition(t){const e=this.worldToLocal(new i(t.x,t.y,t.z));return this.material.toMapPosition(e)}toMaterialDepth(t,e){const a=k.toKey(t),o=new i;o[a]=1;const r=(new n).setFromMatrix4(this.matrixWorld);return o.applyMatrix3(r),e/=o.length()}toMapDepth(t,e){return e=this.toMaterialDepth(t,e),this.material.toMapDepth(t,e)}getData3DSlice(t,e){return e=this.toMaterialDepth(t,e),this.material.getData3DSlice(t,e)}getItem(t){const e=this.worldToLocal(new i(t.x,t.y,t.z));return this.material.getItem(e)}}class Lt extends Et{constructor(t){const{gradient:e,range:n,discardOut:i,voidRange:a,...r}=t??{},s=(new o).copy(n??{x:0,y:100}),l=i??!0,c=(new o).copy(a??{x:-100,y:-1});super({...r,fragmentShader:"precision highp float;\nprecision highp sampler3D;\n\nuniform sampler3D map;\nuniform sampler2D gradient;\n\nuniform bool atomize;\nuniform float steps;\n// 颜色累积系数\nuniform float accFactor;\nuniform vec2 range;\n// 是否丢弃超出范围的像素\nuniform bool discardOut;\n// 空值范围\nuniform vec2 voidRange;\nuniform float opacity;\nuniform vec2 alphaRange;\nuniform bool isDoubleSide;\n\nin vec3 cameraPos;\nin vec3 lookDir;\nin vec3 displayMin;\nin vec3 displayMax;\nout vec4 fragColor;\n\nvec4 colorBlend(vec4 near,vec4 far){\n float nA = near.a;\n if (nA >= 1.0){\n return near;\n }\n if (nA <= 0.0){\n return far;\n }\n \n float fA = far.a;\n float a = fA + nA - fA*nA;\n vec3 color = (far.rgb * fA * (1.0 - nA) + near.rgb*nA)/a;\n return vec4(color,a);\n}\n\n\n\n\nvec2 intersectBox( vec3 orig, vec3 dir ) {\n vec3 inv_dir = 1.0 / dir;\n vec3 tmin_tmp = (displayMin - orig ) * inv_dir;\n vec3 tmax_tmp = (displayMax - orig ) * inv_dir;\n vec3 tmin = min( tmin_tmp, tmax_tmp );\n vec3 tmax = max( tmin_tmp, tmax_tmp );\n float t0 = max( tmin.x, max( tmin.y, tmin.z ) );\n float t1 = min( tmax.x, min( tmax.y, tmax.z ) );\n return vec2( t0, t1 );\n}\n\nfloat getValue( vec3 point ) {\n return texture( map, point ).r;\n}\n\n// 获取梯度颜色\nvec4 getGradientColor(float val) {\n val = clamp( val, 0.0,1.0);\n return texture2D(gradient, vec2(val, 0.5));\n}\n\n\n\n\nvoid main(){\n vec3 rayDir = normalize( lookDir );\n\n vec2 times = intersectBox( cameraPos, rayDir );\n float tMin = times.x;\n float tMax = times.y;\n if ( tMin > tMax || tMax < 0.0 ) discard;\n tMin = max( tMin, 0.0 );\n\n vec3 point = cameraPos + tMin * rayDir;\n \n float step = 1.0/steps;\n float opacityFactor = atomize ? step * accFactor : 1.0;\n\n\n float invRangeLen = 1.0/(range.y - range.x);\n vec3 stepDir = rayDir * step;\n\n vec4 finalColor = vec4( 0,0,0,0);\n float alphaMax = alphaRange.y;\n\n for ( float t = tMin; t <= tMax; t += step,point += stepDir ) {\n float val = getValue( point);\n if (voidRange.x <= val && val <= voidRange.y ) continue;\n val = (val - range.x) * invRangeLen;\n if (discardOut && (val < 0.0 || val > 1.0)) continue;\n\n vec4 gradientColor = getGradientColor(val);\n gradientColor.a *= opacityFactor;\n finalColor = colorBlend(finalColor,gradientColor);\n if ( finalColor.a >= alphaMax ) break;\n }\n\n finalColor.a *= opacity;\n if ( finalColor.a <= alphaRange.x ) discard;\n if (isDoubleSide){\n finalColor.a = 1.0 - sqrt(1.0 - finalColor.a);\n }\n fragColor = finalColor;\n\n}",uniforms:{gradient:{value:null==e?e:Ct(e)},range:{value:s},discardOut:{value:l},voidRange:{value:c}}}),Rt(this,"isGradientVolumeMaterial",!0)}get gradient(){return this.uniforms.gradient.value}set gradient(t){this.uniforms.gradient.value=t,this.uniformsNeedUpdate=!0}get range(){return this.uniforms.range.value}set range(t){this.uniforms.range.value.copy(t),this.uniformsNeedUpdate=!0}get discardOut(){return this.uniforms.discardOut.value}set discardOut(t){this.uniforms.discardOut.value=t,this.uniformsNeedUpdate=!0}get voidRange(){return this.uniforms.voidRange.value}set voidRange(t){this.uniforms.voidRange.value.copy(t),this.uniformsNeedUpdate=!0}}class Bt extends z{constructor(t,e,n,i,a){super(t,e,n,i),Rt(this,"isGradientData3DTexture",!0),this.format=s,this.type=a??D,this.minFilter=this.magFilter=S,this.unpackAlignment=1,this.needsUpdate=!0}getData3DSlice(t,e){const{data:n,width:i,height:a,depth:o}=this.image;return dt({data:n,size:{x:i,y:a,z:o}},t,e,1)}getItem(t){const{data:e,width:n,height:i,depth:a}=this.image;return rt({data:e,size:{x:n,y:i,z:a}},t).value}getValue(t){const{data:e,width:n,height:i,depth:a}=this.image;return lt({data:e,size:{x:n,y:i,z:a}},t).value}}function kt(t,e){const{data:n,size:i}=t,{x:a,y:o,z:r}=i,s=a*o*r,{voidValue:l=0,uint8:c}=e??{};let u;if(c){u=new Uint8Array(s);for(let t=0;t<s;t++){const e=n[t]??l;u[t]=Math.trunc(e)}}else{u=new Float32Array(s);for(let t=0;t<s;t++){const e=n[t]??l;u[t]=e}}return new Bt(u,a,o,r,c?b:D)}class Ht extends Et{constructor(t){super({...t,fragmentShader:"precision highp float;\nprecision highp sampler3D;\n\nuniform sampler3D map;\n\n\n\n// 颜色累积系数\nuniform float accFactor;\nuniform bool isDoubleSide;\nuniform bool atomize;\n\n\nuniform float opacity;\nuniform vec2 alphaRange;\nuniform float steps;\n\nin vec3 cameraPos;\nin vec3 lookDir;\nin vec3 displayMin;\nin vec3 displayMax;\nout vec4 fragColor;\n\n// 混合颜色\nvec4 colorBlend(vec4 near,vec4 far){\n float nA = near.a;\n if (nA >= 1.0){\n return near;\n }\n if (nA <= 0.0){\n return far;\n }\n \n float fA = far.a;\n float a = fA + nA - fA*nA;\n vec3 color = (far.rgb * fA * (1.0 - nA) + near.rgb*nA)/a;\n return vec4(color,a);\n}\n\n\n\n\n// 包围盒求交\nvec2 intersectBox( vec3 orig, vec3 dir ) {\n vec3 inv_dir = 1.0 / dir;\n vec3 tmin_tmp = (displayMin - orig ) * inv_dir;\n vec3 tmax_tmp = (displayMax - orig ) * inv_dir;\n vec3 tmin = min( tmin_tmp, tmax_tmp );\n vec3 tmax = max( tmin_tmp, tmax_tmp );\n float t0 = max( tmin.x, max( tmin.y, tmin.z ) );\n float t1 = min( tmax.x, min( tmax.y, tmax.z ) );\n return vec2( t0, t1 );\n}\n\n\n\nvoid main(){\n vec3 rayDir = normalize( lookDir );\n\n vec2 times = intersectBox( cameraPos, rayDir );\n float tMin = times.x;\n float tMax = times.y;\n if ( tMin > tMax || tMax < 0.0 ) discard;\n tMin = max( tMin, 0.0 );\n\n vec3 point = cameraPos + tMin * rayDir;\n \n float step = 1.0/steps;\n float opacityFactor = atomize ? step * accFactor : 1.0;\n\n vec3 stepDir = rayDir * step;\n\n vec4 finalColor = vec4( 0,0,0,0);\n float alphaMax = alphaRange.y;\n\n for ( float t = tMin; t <= tMax; t += step,point += stepDir ) {\n vec4 textureColor = texture( map, point );\n textureColor.a *= opacityFactor;\n finalColor = colorBlend(finalColor,textureColor);\n if ( finalColor.a >= alphaMax ) break;\n }\n\n finalColor.a *= opacity;\n if ( finalColor.a <= alphaRange.x ) discard;\n if (isDoubleSide){\n finalColor.a = 1.0 - sqrt(1.0 - finalColor.a);\n }\n fragColor = finalColor;\n\n}"}),Rt(this,"isImageVolumeMaterial",!0)}}function qt(t,e,n){const i=n??{},{x:a,y:o}=i.range??{x:0,y:100},r=i.discardOut??!0,{x:s,y:l}=i.voidRange??{x:-100,y:-1},c=i.voidColor??[0,0,0,0],{width:u,height:d}=e,m=Math.trunc(d/2),p=u-1;function f(t){const n=Math.trunc(p*t);return Q(e,m,n)}const h=1/(o-a),{data:v,size:g}=t,x=v.length,_=[];for(let t=0;t<x;t++){let e=c,n=v[t];(n<=s||l<=n)&&(n=(n-a)*h,r&&(n<0||n>1)||(n=Math.min(Math.max(n,0),1),e=f(n))),_.push(...e)}return{data:_,size:g}}class Kt extends z{constructor(t,e,n,i){super(t,e,n,i),Rt(this,"isImageData3DTexture",!0),this.format=d,this.type=b,this.minFilter=this.magFilter=S,this.unpackAlignment=1,this.needsUpdate=!0}getData3DSlice(t,e){const{data:n,width:i,height:a,depth:o}=this.image;return dt({data:n,size:{x:i,y:a,z:o}},t,e,4)}getItem(t){return this.getColor(t)}getColor(t){const{data:e,width:n,height:i,depth:a}=this.image;return rt({data:e,size:{x:n,y:i,z:a}},t,4).value}}function Wt(t,e,n){const i=(null==n?void 0:n.reverseY)??!0,{data:a,width:o,height:r,depth:s,colorSpace:l}=pt(t,e,{...n,reverseY:i}),c=new Kt(a,o,r,s);return"srgb"===l&&(c.colorSpace="srgb"),c}function Yt(t,e){const n=e.gradient,i=Array.isArray(n)?W(n,256,1):et(n)?n:Y(n);let a=t;nt(t)&&(a={data:t.data,size:{x:t.width,y:t.height,z:t.depth}});const{data:o,size:r}=qt(a,i,e),s=Uint8ClampedArray.from(o);return new Kt(s,r.x,r.y,r.z)}class Xt extends g{constructor(t){const e=t??{},n=e.color??new C(1,1,1),i=e.solid??0,a=e.exp??1,o=e.opacity??1,r=e.side??N;super({glslVersion:x,uniforms:{color:{value:n},solid:{value:i},exp:{value:a},opacity:{value:o},isDoubleSide:{value:!1}},vertexShader:"out vec3 lookDir;\nout vec3 normalDir;\n\n#if defined( USE_COLOR_ALPHA ) || defined( USE_COLOR )\n out vec4 verColor;\n#endif\n\nvoid main() {\n vec3 cameraPos = vec3( inverse( modelMatrix ) * vec4( cameraPosition, 1.0 ) ).xyz;\n lookDir = position - cameraPos;\n normalDir = normal;\n\n #if defined( USE_COLOR_ALPHA )\n verColor = color;\n #elif defined( USE_INSTANCING_COLOR )\n overColor = vec3(instanceColor,1.0);\n #elif defined( USE_COLOR )\n overColor = vec3(color,1.0);\n #endif\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"uniform vec3 color;\nuniform float solid;\nuniform float exp;\n\nuniform float opacity;\nuniform bool isDoubleSide;\n\nin vec3 lookDir;\nin vec3 normalDir;\n\n#if defined( USE_COLOR_ALPHA ) || defined( USE_COLOR )\n in vec4 verColor;\n#endif\n\nout vec4 fragColor;\n\n\nvoid main(){\n #if defined( USE_COLOR_ALPHA ) || defined( USE_COLOR )\n fragColor = verColor;\n #else\n fragColor = vec4(color,1.0);\n #endif\n\n vec3 dir = normalize(lookDir);\n vec3 nor = normalize(normalDir);\n float depth = abs(dot(nor,dir));\n float dist = sqrt(1.0 - pow(depth,2.0));\n\n float finalAlpha = fragColor.a * depth;\n if (dist > solid) {\n float distAlpha = 1.0 - (dist - solid)/(1.0 - solid);\n finalAlpha *= pow(distAlpha,exp);\n }\n \n finalAlpha *= opacity;\n if ( finalAlpha == 0.0 ) discard;\n if (isDoubleSide){\n finalAlpha = 1.0 - sqrt(1.0 - finalAlpha);\n }\n fragColor.a = finalAlpha;\n}",side:N,transparent:!0}),Rt(this,"isSphereFogMaterial",!0),Rt(this,"_side",N),this.opacity=o,this.side=r}get side(){return this._side}set side(t){this._side=t,this.uniforms&&(this.uniforms.isDoubleSide.value=t===y,this.uniformsNeedUpdate=!0)}get color(){return this.uniforms.color.value}set color(t){this.uniforms.color.value.copy(t),this.uniformsNeedUpdate=!0}get opacity(){return this.uniforms.opacity.value}set opacity(t){this.uniforms&&(this.uniforms.opacity.value=t),this.uniformsNeedUpdate=!0}get solid(){return this.uniforms.solid.value}set solid(t){this.uniforms&&(this.uniforms.solid.value=t),this.uniformsNeedUpdate=!0}get exp(){return this.uniforms.exp.value}set exp(t){this.uniforms&&(this.uniforms.exp.value=t),this.uniformsNeedUpdate=!0}}class Zt extends g{constructor(t,e){const{solid:n=0,exp:i=1,useRadius:a=!0,sizeAttenuation:o=!0,star:r=!1,...s}=t??{},{uniforms:l,...c}=e||{},u={star:{value:r},solid:{value:n},exp:{value:i}};super({uniforms:U.merge([A.points.uniforms,u,l]),transparent:!0,depthTest:!1,defines:{useRadius:a},...c}),Rt(this,"isFogPointsMaterial",!0),Rt(this,"sizeAttenuation",!0),Object.assign(this,{...s,solid:n,exp:i,sizeAttenuation:o})}get map(){return this.uniforms.map.value}set map(t){this.uniforms.map.value=t,this.uniformsNeedUpdate=!0}get star(){return this.uniforms.star.value}set star(t){this.uniforms.star.value=t,this.uniformsNeedUpdate=!0}get size(){return this.uniforms.size.value}set size(t){this.uniforms.size.value=t,this.uniformsNeedUpdate=!0}get opacity(){return this.uniforms.opacity.value}set opacity(t){this.uniforms&&(this.uniforms.opacity.value=t),this.uniformsNeedUpdate=!0}get solid(){return this.uniforms.solid.value}set solid(t){this.uniforms&&(this.uniforms.solid.value=t),this.uniformsNeedUpdate=!0}get exp(){return this.uniforms.exp.value}set exp(t){this.uniforms&&(this.uniforms.exp.value=t),this.uniformsNeedUpdate=!0}get scale(){return this.uniforms.scale.value}set scale(t){this.uniforms&&(this.uniforms.scale.value=t),this.uniformsNeedUpdate=!0}get fogDensity(){return this.uniforms.fogDensity.value}set fogDensity(t){this.uniforms&&(this.uniforms.fogDensity.value=t),this.uniformsNeedUpdate=!0}get fogNear(){return this.uniforms.fogNear.value}set fogNear(t){this.uniforms&&(this.uniforms.fogNear.value=t),this.uniformsNeedUpdate=!0}get fogFar(){return this.uniforms.fogFar.value}set fogFar(t){this.uniforms&&(this.uniforms.fogFar.value=t),this.uniformsNeedUpdate=!0}get fogColor(){return this.uniforms.fogColor.value}set fogColor(t){this.uniforms.fogColor.value.copy(t),this.uniformsNeedUpdate=!0}}class Jt extends Zt{constructor(t){super(t,{vertexShader:"#ifdef useRadius\n\tattribute float radius;\n#endif\n\nuniform float size;\nuniform float scale;\n\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\n\n#ifdef USE_POINTS_UV\n\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n\n#endif\n\nvoid main() {\n\n\t#ifdef USE_POINTS_UV\n\n\t\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\n\t#endif\n\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\n\t#ifdef useRadius\n\t\tgl_PointSize = radius;\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\n\t#ifdef USE_SIZEATTENUATION\n\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\n\t#endif\n\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <fog_vertex>\n\n}",fragmentShader:"uniform float solid;\nuniform float exp;\nuniform bool star;\n\nuniform vec3 diffuse;\nuniform float opacity;\n\n#include <common>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\n\n\nvec4 getColor(vec4 originColor){\n\tfloat finalAlpha = originColor.a;\n\tfloat dist = 0.0;\n\tif (star){\n\t\tvec2 coord = abs(gl_PointCoord - vec2(0.5));\n\t\tdist = max(coord.x,coord.y);\n\t}else{\n\t\tdist = distance(gl_PointCoord,vec2(0.5));\n\t\tif (dist>0.5) discard;\n\t}\n\tdist /= 0.5;\n\tfloat depth = sqrt(1.0 - pow(dist,2.0));\n\tfinalAlpha *= depth;\n if (dist > solid) {\n float distAlpha = 1.0 - (dist - solid)/(1.0 - solid);\n finalAlpha *= pow(distAlpha,exp);\n }\n\toriginColor.a = finalAlpha;\n\treturn originColor;\n}\n\nvoid main() {\n\n\t#include <clipping_planes_fragment>\n\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\n\tdiffuseColor = getColor(diffuseColor);\n\toutgoingLight = diffuseColor.rgb;\n\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\n}"}),Rt(this,"isColorFogPointsMaterial",!0)}get color(){return this.uniforms.diffuse.value}set color(t){this.uniforms.diffuse.value.copy(t),this.uniformsNeedUpdate=!0}get alphaMap(){return this.uniforms.alphaMap.value}set alphaMap(t){this.uniforms&&(this.uniforms.alphaMap.value=t),this.uniformsNeedUpdate=!0}get uvTransform(){return this.uniforms.uvTransform.value}set uvTransform(t){this.uniforms&&this.uniforms.uvTransform.value.copy(t),this.uniformsNeedUpdate=!0}}function Qt(t){const e=new Jt(t),n=function(t){const{points:e,radius:n=10,color:i=[0,0,0,0]}=t,a=[],o=[],r=[];for(const{x:t,y:s,z:l,radius:c,color:u}of e){a.push(t,s,l),o.push(c??n);const e=u??i,d=e[3];e[3]=Math.trunc(255*d),r.push(...e)}const s=new E;return s.setAttribute("position",new G(a,3)),s.setAttribute("radius",new G(o,1)),s.setAttribute("color",new j(r,4,!0)),s}(t);return new P(n,e)}class $t extends Zt{constructor(t){const{range:e,...n}=t||{};super(n,{vertexShader:"attribute float value;\nuniform vec2 range;\nvarying float vValue;\n#ifdef useRadius\n\tattribute float radius;\n#endif\n\n\nuniform float size;\nuniform float scale;\n\n#include <common>\n// #include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\n\n#ifdef USE_POINTS_UV\n\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n\n#endif\n\nvoid main() {\n\tvValue = (value - range.x)/(range.y - range.x);\n\n\t#ifdef USE_POINTS_UV\n\n\t\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\n\t#endif\n\n\t// #include <color_vertex>\n\t// #include <morphcolor_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\n\t#ifdef useRadius\n\t\tgl_PointSize = radius;\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\n\t#ifdef USE_SIZEATTENUATION\n\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\n\t#endif\n\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <fog_vertex>\n\n}",fragmentShader:"varying float vValue;\nuniform sampler2D map;\n\n\nuniform float solid;\nuniform float exp;\nuniform bool star;\n\n// uniform vec3 diffuse;\nuniform float opacity;\n\n#include <common>\n// #include <color_pars_fragment>\n// #include <map_particle_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\n\n\n// 获取梯度颜色\nvec4 getGradientColor(float val) {\n\tval = clamp( val, 0.0,1.0);\n return texture2D(map, vec2(val, 0.5));\n}\n\n\nvec4 getColor(){\n\tfloat val = vValue;\n\tfloat dist = 0.0;\n\tif (star){\n\t\tvec2 coord = abs(gl_PointCoord - vec2(0.5));\n\t\tdist = max(coord.x,coord.y);\n\t}else{\n\t\tdist = distance(gl_PointCoord,vec2(0.5));\n\t\tif (dist>0.5) discard;\n\t}\n\tdist /= 0.5;\n\tfloat depth = sqrt(1.0 - pow(dist,2.0));\n if (dist > solid) {\n float solidDist = 1.0 - (dist - solid)/(1.0 - solid);\n val *= pow(solidDist,exp);\n }\n\tvec4 valColor = getGradientColor(val);\n\tvalColor.a *= depth * opacity;\n\treturn valColor;\n}\n\nvoid main() {\n\n\t#include <clipping_planes_fragment>\n\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = getColor();\n\n\t#include <logdepthbuf_fragment>\n\t// #include <map_particle_fragment>\n\t// #include <color_fragment>\n\t#include <alphatest_fragment>\n\n\toutgoingLight = diffuseColor.rgb;\n\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\n}",uniforms:{range:{value:(new o).copy(e??{x:0,y:100})}}}),Rt(this,"isColorFogPointsMaterial",!0)}get range(){return this.uniforms.range.value}set range(t){this.uniforms.range.value.copy(t),this.uniformsNeedUpdate=!0}}function te(t){const e=t.gradient,n=null==e?e:Ct(e),i=new $t({...t,map:n}),a=function(t){const{points:e,radius:n=10,value:i=100}=t,a=[],o=[],r=[];for(const{x:t,y:s,z:l,radius:c,value:u}of e)a.push(t,s,l),o.push(c??n),r.push(u??i);const s=new E;return s.setAttribute("position",new G(a,3)),s.setAttribute("radius",new G(o,1)),s.setAttribute("value",new G(r,1)),s}(t);return new P(a,i)}class ee extends g{constructor(t){const e=t??{};let{map:n,opacity:i,axis:a,depth:o,side:r,...s}=e;i=i??1,a=a??k.z,o=o??0,r=r??y,super({...s,glslVersion:x,uniforms:{map:{value:n},opacity:{value:i},axis:{value:a},depth:{value:o}},transparent:!0,vertexShader:"\tout vec2 vUv;\n \n\tvoid main() {\n\t\tvUv = uv;\n\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\t}",fragmentShader:"precision highp float;\nprecision highp sampler3D;\n\nuniform sampler3D map;\n\nuniform float opacity;\nuniform int axis;\nuniform float depth;\n\nin vec2 vUv;\nout vec4 fragColor;\n\nvoid main(){\n vec3 uv3 = vec3(0.0);\n int depthSize = textureSize(map,0)[axis];\n uv3[axis] = depth/float(depthSize);\n int xIndex = (axis + 1)%3;\n int yIndex = (axis + 2)%3;\n uv3[xIndex] = vUv.x;\n uv3[yIndex] = vUv.y;\n\n fragColor = texture(map, uv3);\n fragColor.a *= opacity;\n}",side:r}),Rt(this,"isSliceMaterial",!0),Rt(this,"_sliceSize",null),this.opacity=i}get map(){return this.uniforms.map.value}set map(t){this.uniforms.map.value=t,this._sliceSize=null,this.uniformsNeedUpdate=!0}get opacity(){return this.uniforms.opacity.value}set opacity(t){this.uniforms&&(this.uniforms.opacity.value=t),this.uniformsNeedUpdate=!0}get axis(){return this.uniforms.axis.value}set axis(t){this.uniforms.axis.value=t,this._sliceSize=null,this.uniformsNeedUpdate=!0}get depth(){return this.uniforms.depth.value}set depth(t){this.uniforms.depth.value=t,this.uniformsNeedUpdate=!0}get sliceSize(){let t=this._sliceSize;if(!t){this._sliceSize=t=new o(1,1);const{axis:e,map:n}=this;if(n){const{width:i,height:a,depth:o}=n.image,[r,s]=k.getCrossAxiss(e),l=[i,a,o];t.set(l[r],l[s])}}return t}}class ne extends w{constructor(t){const e=new ee(t),n=new O;super(n,e),Rt(this,"isSliceMesh",!0),Rt(this,"_geometry"),Rt(this,"_material"),Rt(this,"autoUpdateGeometry",!0),Object.defineProperties(this,{geometry:{get:()=>this._geometry,set:t=>{this._geometry=t,this.autoUpdateGeometry&&this.updateGeometry()}},material:{get:()=>this._material,set:t=>{this._material=t,this.autoUpdateGeometry&&this.updateGeometry()}}}),this.geometry=n,this.material=e}updateGeometry(){var t;const{geometry:e,material:n}=this;if(!n||!(null==(t=n.map)?void 0:t.image))return!1;e.boundingBox||e.computeBoundingBox();const a=n.sliceSize,o=e.boundingBox.getSize(new i);e.scale(a.x/o.x,a.y/o.y,1)}get map(){return this.material.map}set map(t){this.material.map=t,this.material=this.material}get axis(){return this.material.axis}set axis(t){this.material.axis=t,this.material=this.material}get depth(){return this.material.depth}set depth(t){this.material.depth=t}get sliceSize(){return this.material.sliceSize}}class ie extends Mt{constructor(t){super(nt(t)?t:t.image),Rt(this,"isImageData3DTextureSlice",!0)}set texture(t){this.image3D=nt(t)?t:t.image}}function ae({ratio:t,value:e}){return e-e*t}function oe(t,e){const{x:n,y:i}=e;let a=0;for(const{value:e,clim:{x:n,y:i}}of t)a+=(e-n)/(i-n);return a*(i-n)+n}function re(t,e,n){const{size:a,data3D:o,tags:r}=e,{clim:s,radius:l,value:c,hollow:u,valueGradient:d,valuesAccumulate:m}=t,p=(new i).copy(t),f=[],h=[],v={particles:f,values:h},g=l*u,x=p.clone().subScalar(l),_=p.clone().addScalar(l);x.max(new i(0,0,0));const y=(new i).copy(a).subScalar(1);_.min(y);let{x:w,y:M,z:z}=x;w=Math.trunc(w),M=Math.trunc(M),z=Math.trunc(z);let{x:D,y:S,z:b}=_;if(D=Math.trunc(D),S=Math.trunc(S),b=Math.trunc(b),w>D||M>S||z>b)return v;const{x:C,y:N}=a,U=C*N;for(let e=z;e<=b;e++){const a=e*U;for(let v=M;v<=S;v++){const x=a+v*C;t:for(let a=w;a<=D;a++){const _=x+a;if(r[_])continue;const y=new i(a,v,e),w=y.distanceTo(p);if(w>l||w<g)continue;r[_]=!0;const M=[],z={...{radius:l,hollow:u,hollowRadius:g,distance:w,clim:s,value:c},ratio:w/l,distance:w,point:y},D=d(z);M.push({...t,...z,value:D});for(const t of n){const e=y.distanceTo(t),{hollow:n,radius:i}=t;if(e<=i){const a=i*n;if(e<a)continue t;const o={...t,ratio:e/i,distance:e,hollowRadius:a,point:y},r=d(o);M.push({...o,value:r})}}const S=m(M,s);o[_]=S,f.push(y),h.push(S)}}}return v}function se(t){const{points:e,clim:n={x:0,y:100},radius:i=10,value:a=100,hollow:o=0,valueGradient:r=ae,valuesAccumulate:s=oe,size:l}=t,c={clim:n,radius:i,value:a,hollow:o,valueGradient:r,valuesAccumulate:s},u=e.map((t=>({...c,...t})));let d=l;l||(d=(new I).setFromPoints(u).max.addScalar(1));const m=St(u);let{x:p,y:f,z:h}=d;p=d.x=Math.trunc(p),f=d.y=Math.trunc(f),h=d.z=Math.trunc(h);const v=new Array(p*f*h),g={size:d,data3D:v,tags:new Array(p*f*h)},x=u.length;for(let t=0;t<x;t++){re(u[t],g,m[t].map((t=>u[t])))}return{data:v,size:d}}function le({startRadius:t,addedRadius:e,ratio:n}){return e*n+t}function ce({startHollow:t,addedHollow:e,ratio:n}){return e*n+t}function ue({startValue:t,addedValue:e,ratio:n}){return e*n+t}function de(t,e){const{x:n,y:i}=e;return t.reduce(((t,e)=>t+e-n),0)}function me(t){const{points:e,size:n,clim:a={x:0,y:100},radius:o=10,value:r=100,hollow:s=0,valueGradient:l=ae,radiusGradient:c=le,hollowGradient:u=ce,lineValueGradient:d=ue,valuesAccumulate:m=de}=t,p={radius:o,value:r,hollow:s},f=e.map((function(t){return Object.assign(new i,p,t)})),h=n?(new i).copy(n).subScalar(1):(new I).setFromPoints(f).max;h.x=Math.trunc(h.x),h.y=Math.trunc(h.y),h.z=Math.trunc(h.z);const v=h.clone().addScalar(1),{x:g,y:x,z:y}=v,w=g*x,M=new Array(w*y),z=[],D=[],S={particles:z,values:D,size:v,data:M},b=new i(0,0,0),C=e.length,N=Math.trunc(C/2);for(let t=0;t<N;t++){const e=2*t,n=f[e],p=f[e+1],v=new T(n,p),x=v.distance(),y=v.delta(new i).normalize(),C=new F;C.setFromUnitVectors(new i(0,1,0),y);const N=(new _).makeRotationFromQuaternion(C);N.setPosition(n);const{radius:U,value:A,hollow:P}=n,{radius:O,value:R,hollow:V}=p,E={length:x,startRadius:U,endRadius:O,addedRadius:O-U,defaultRadius:o,radius:o,startValue:A,endValue:R,addedValue:R-A,defaultValue:r,startHollow:P,endHollow:V,addedHollow:V-P,defaultHollow:s,clim:a},G=Math.max(U,O),j=new i(-G,0,-G),L=new i(G,x,G),B=new I(j,L);B.applyMatrix4(N);const{min:k,max:H}=B;k.max(b),H.min(h);let{x:q,y:K,z:W}=k;q=Math.trunc(q),K=Math.trunc(K),W=Math.trunc(W);let{x:Y,y:X,z:Z}=H;if(Y=Math.trunc(Y),X=Math.trunc(X),Z=Math.trunc(Z),q>Y||K>X||W>Z)return S;N.invert();for(let t=W;t<=Z;t++){const e=t*w;for(let n=K;n<=X;n++){const o=e+n*g;for(let e=q;e<=Y;e++){const r=o+e,s=new i(e,n,t),p=s.clone();p.applyMatrix4(N);const{x:f,y:h,z:v}=p;if(h<0||h>x)continue;const g=Math.hypot(f,v),_={...E,ratio:h/x,point:s},y=c(_);_.radius=y;const w=u(_),S=y*w;if(g>y||g<S)continue;const b=d(_);let C=l({...E,value:b,ratio:g/y,radius:y,hollow:w,hollowRadius:S,distance:g,point:s});const U=D[r];void 0!==U&&(C=m([U,C],a)),M[r]=C,z.push(s),D.push(C)}}}}return S}function pe(t,e){const a=(new i).setFromMatrixScale(e),o=Math.sqrt(a.lengthSq()/3),r=(new n).setFromMatrix4(e);let{points:s,size:l,radius:c,...u}=t;if(l&&(l=(new i).copy(l).applyMatrix3(r)),c&&(c*=o),s){const t=[];for(let{x:n,y:a,z:r,radius:l,...c}of s){l&&(l*=o);const s=new i(n,a,r).applyMatrix4(e);Object.assign(s,c,{radius:l}),t.push(s)}s=t}return{points:s,size:l,radius:c,...u}}function fe(t,e,n=1){let{points:a,size:o,radius:r,...s}=t;if(r&&(r*=n),a){const t=[];for(let{x:o,y:r,z:s,radius:l,...c}of a){l&&(l*=n);const a=new i(o,r,s).add(e).multiplyScalar(n);Object.assign(a,c,{radius:l}),t.push(a)}a=t}return o&&(o=(new i).copy(o).add(e).multiplyScalar(n)),{points:a,size:o,radius:r,...s}}function he(t,e){const{points:n,radius:a}=t;if(!n)return{options:t,position:new i,scale:1};const o=new I;for(const t of n){const e=(new i).copy(t),n=t.radius??a;n?(o.expandByPoint(e.clone().subScalar(n)),o.expandByPoint(e.addScalar(n))):o.expandByPoint(e)}const r=(new i).max(o.min),s=o.max.clone().sub(r).addScalar(1);t.size&&s.min(t.size);let{scale:l,maxSize:c}=e||{};l||(c=c??100,l=c/Math.max(s.x,s.y,s.z)),s.multiplyScalar(l);const u=fe(t,r.clone().negate(),l);return u.size=s,{options:u,position:r,scale:1/l}}const ve={uniforms:{u_size:{value:new i(1,1,1)},u_renderstyle:{value:0},u_renderthreshold:{value:.5},u_clim:{value:new o(1,1)},u_data:{value:null},u_cmdata:{value:null}},vertexShader:'\n\n\t\tvarying vec4 v_nearpos;\n\t\tvarying vec4 v_farpos;\n\t\tvarying vec3 v_position;\n\n\t\tvoid main() {\n\t\t\t\t// Prepare transforms to map to "camera view". See also:\n\t\t\t\t// https://threejs.org/docs/#api/renderers/webgl/WebGLProgram\n\t\t\t\tmat4 viewtransformf = modelViewMatrix;\n\t\t\t\tmat4 viewtransformi = inverse(modelViewMatrix);\n\n\t\t\t\t// Project local vertex coordinate to camera position. Then do a step\n\t\t\t\t// backward (in cam coords) to the near clipping plane, and project back. Do\n\t\t\t\t// the same for the far clipping plane. This gives us all the information we\n\t\t\t\t// need to calculate the ray and truncate it to the viewing cone.\n\t\t\t\tvec4 position4 = vec4(position, 1.0);\n\t\t\t\tvec4 pos_in_cam = viewtransformf * position4;\n\n\t\t\t\t// Intersection of ray and near clipping plane (z = -1 in clip coords)\n\t\t\t\tpos_in_cam.z = -pos_in_cam.w;\n\t\t\t\tv_nearpos = viewtransformi * pos_in_cam;\n\n\t\t\t\t// Intersection of ray and far clipping plane (z = +1 in clip coords)\n\t\t\t\tpos_in_cam.z = pos_in_cam.w;\n\t\t\t\tv_farpos = viewtransformi * pos_in_cam;\n\n\t\t\t\t// Set varyings and output pos\n\t\t\t\tv_position = position;\n\t\t\t\tgl_Position = projectionMatrix * viewMatrix * modelMatrix * position4;\n\t\t}',fragmentShader:"\n\n\t\t\t\tprecision highp float;\n\t\t\t\tprecision mediump sampler3D;\n\n\t\t\t\tuniform vec3 u_size;\n\t\t\t\tuniform int u_renderstyle;\n\t\t\t\tuniform float u_renderthreshold;\n\t\t\t\tuniform vec2 u_clim;\n\n\t\t\t\tuniform sampler3D u_data;\n\t\t\t\tuniform sampler2D u_cmdata;\n\n\t\t\t\tvarying vec3 v_position;\n\t\t\t\tvarying vec4 v_nearpos;\n\t\t\t\tvarying vec4 v_farpos;\n\n\t\t\t\t// The maximum distance through our rendering volume is sqrt(3).\n\t\t\t\tconst int MAX_STEPS = 887;\t// 887 for 512^3, 1774 for 1024^3\n\t\t\t\tconst int REFINEMENT_STEPS = 4;\n\t\t\t\tconst float relative_step_size = 1.0;\n\t\t\t\tconst vec4 ambient_color = vec4(0.2, 0.4, 0.2, 1.0);\n\t\t\t\tconst vec4 diffuse_color = vec4(0.8, 0.2, 0.2, 1.0);\n\t\t\t\tconst vec4 specular_color = vec4(1.0, 1.0, 1.0, 1.0);\n\t\t\t\tconst float shininess = 40.0;\n\n\t\t\t\tvoid cast_mip(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray);\n\t\t\t\tvoid cast_iso(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray);\n\n\t\t\t\tfloat sample1(vec3 texcoords);\n\t\t\t\tvec4 apply_colormap(float val);\n\t\t\t\tvec4 add_lighting(float val, vec3 loc, vec3 step, vec3 view_ray);\n\n\n\t\t\t\tvoid main() {\n\t\t\t\t\t\t// Normalize clipping plane info\n\t\t\t\t\t\tvec3 farpos = v_farpos.xyz / v_farpos.w;\n\t\t\t\t\t\tvec3 nearpos = v_nearpos.xyz / v_nearpos.w;\n\n\t\t\t\t\t\t// Calculate unit vector pointing in the view direction through this fragment.\n\t\t\t\t\t\tvec3 view_ray = normalize(nearpos.xyz - farpos.xyz);\n\n\t\t\t\t\t\t// Compute the (negative) distance to the front surface or near clipping plane.\n\t\t\t\t\t\t// v_position is the back face of the cuboid, so the initial distance calculated in the dot\n\t\t\t\t\t\t// product below is the distance from near clip plane to the back of the cuboid\n\t\t\t\t\t\tfloat distance = dot(nearpos - v_position, view_ray);\n\t\t\t\t\t\tdistance = max(distance, min((-0.5 - v_position.x) / view_ray.x,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(u_size.x - 0.5 - v_position.x) / view_ray.x));\n\t\t\t\t\t\tdistance = max(distance, min((-0.5 - v_position.y) / view_ray.y,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(u_size.y - 0.5 - v_position.y) / view_ray.y));\n\t\t\t\t\t\tdistance = max(distance, min((-0.5 - v_position.z) / view_ray.z,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(u_size.z - 0.5 - v_position.z) / view_ray.z));\n\n\t\t\t\t\t\t// Now we have the starting position on the front surface\n\t\t\t\t\t\tvec3 front = v_position + view_ray * distance;\n\n\t\t\t\t\t\t// Decide how many steps to take\n\t\t\t\t\t\tint nsteps = int(-distance / relative_step_size + 0.5);\n\t\t\t\t\t\tif ( nsteps < 1 )\n\t\t\t\t\t\t\t\tdiscard;\n\n\t\t\t\t\t\t// Get starting location and step vector in texture coordinates\n\t\t\t\t\t\tvec3 step = ((v_position - front) / u_size) / float(nsteps);\n\t\t\t\t\t\tvec3 start_loc = front / u_size;\n\n\t\t\t\t\t\t// For testing: show the number of steps. This helps to establish\n\t\t\t\t\t\t// whether the rays are correctly oriented\n\t\t\t\t\t\t//'gl_FragColor = vec4(0.0, float(nsteps) / 1.0 / u_size.x, 1.0, 1.0);\n\t\t\t\t\t\t//'return;\n\n\t\t\t\t\t\tif (u_renderstyle == 0)\n\t\t\t\t\t\t\t\tcast_mip(start_loc, step, nsteps, view_ray);\n\t\t\t\t\t\telse if (u_renderstyle == 1)\n\t\t\t\t\t\t\t\tcast_iso(start_loc, step, nsteps, view_ray);\n\n\t\t\t\t\t\tif (gl_FragColor.a < 0.05)\n\t\t\t\t\t\t\t\tdiscard;\n\t\t\t\t}\n\n\n\t\t\t\tfloat sample1(vec3 texcoords) {\n\t\t\t\t\t\t/* Sample float value from a 3D texture. Assumes intensity data. */\n\t\t\t\t\t\treturn texture(u_data, texcoords.xyz).r;\n\t\t\t\t}\n\n\n\t\t\t\tvec4 apply_colormap(float val) {\n\t\t\t\t\t\tval = (val - u_clim[0]) / (u_clim[1] - u_clim[0]);\n\t\t\t\t\t\treturn texture2D(u_cmdata, vec2(val, 0.5));\n\t\t\t\t}\n\n\n\t\t\t\tvoid cast_mip(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray) {\n\n\t\t\t\t\t\tfloat max_val = -1e6;\n\t\t\t\t\t\tint max_i = 100;\n\t\t\t\t\t\tvec3 loc = start_loc;\n\n\t\t\t\t\t\t// Enter the raycasting loop. In WebGL 1 the loop index cannot be compared with\n\t\t\t\t\t\t// non-constant expression. So we use a hard-coded max, and an additional condition\n\t\t\t\t\t\t// inside the loop.\n\t\t\t\t\t\tfor (int iter=0; iter<MAX_STEPS; iter++) {\n\t\t\t\t\t\t\t\tif (iter >= nsteps)\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t// Sample from the 3D texture\n\t\t\t\t\t\t\t\tfloat val = sample1(loc);\n\t\t\t\t\t\t\t\t// Apply MIP operation\n\t\t\t\t\t\t\t\tif (val > max_val) {\n\t\t\t\t\t\t\t\t\t\tmax_val = val;\n\t\t\t\t\t\t\t\t\t\tmax_i = iter;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Advance location deeper into the volume\n\t\t\t\t\t\t\t\tloc += step;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Refine location, gives crispier images\n\t\t\t\t\t\tvec3 iloc = start_loc + step * (float(max_i) - 0.5);\n\t\t\t\t\t\tvec3 istep = step / float(REFINEMENT_STEPS);\n\t\t\t\t\t\tfor (int i=0; i<REFINEMENT_STEPS; i++) {\n\t\t\t\t\t\t\t\tmax_val = max(max_val, sample1(iloc));\n\t\t\t\t\t\t\t\tiloc += istep;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Resolve final color\n\t\t\t\t\t\tgl_FragColor = apply_colormap(max_val);\n\t\t\t\t}\n\n\n\t\t\t\tvoid cast_iso(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray) {\n\n\t\t\t\t\t\tgl_FragColor = vec4(0.0);\t// init transparent\n\t\t\t\t\t\tvec4 color3 = vec4(0.0);\t// final color\n\t\t\t\t\t\tvec3 dstep = 1.5 / u_size;\t// step to sample derivative\n\t\t\t\t\t\tvec3 loc = start_loc;\n\n\t\t\t\t\t\tfloat low_threshold = u_renderthreshold - 0.02 * (u_clim[1] - u_clim[0]);\n\n\t\t\t\t\t\t// Enter the raycasting loop. In WebGL 1 the loop index cannot be compared with\n\t\t\t\t\t\t// non-constant expression. So we use a hard-coded max, and an additional condition\n\t\t\t\t\t\t// inside the loop.\n\t\t\t\t\t\tfor (int iter=0; iter<MAX_STEPS; iter++) {\n\t\t\t\t\t\t\t\tif (iter >= nsteps)\n\t\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\t// Sample from the 3D texture\n\t\t\t\t\t\t\t\tfloat val = sample1(loc);\n\n\t\t\t\t\t\t\t\tif (val > low_threshold) {\n\t\t\t\t\t\t\t\t\t\t// Take the last interval in smaller steps\n\t\t\t\t\t\t\t\t\t\tvec3 iloc = loc - 0.5 * step;\n\t\t\t\t\t\t\t\t\t\tvec3 istep = step / float(REFINEMENT_STEPS);\n\t\t\t\t\t\t\t\t\t\tfor (int i=0; i<REFINEMENT_STEPS; i++) {\n\t\t\t\t\t\t\t\t\t\t\t\tval = sample1(iloc);\n\t\t\t\t\t\t\t\t\t\t\t\tif (val > u_renderthreshold) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tgl_FragColor = add_lighting(val, iloc, dstep, view_ray);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tiloc += istep;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Advance location deeper into the volume\n\t\t\t\t\t\t\t\tloc += step;\n\t\t\t\t\t\t}\n\t\t\t\t}\n\n\n\t\t\t\tvec4 add_lighting(float val, vec3 loc, vec3 step, vec3 view_ray)\n\t\t\t\t{\n\t\t\t\t\t// Calculate color by incorporating lighting\n\n\t\t\t\t\t\t// View direction\n\t\t\t\t\t\tvec3 V = normalize(view_ray);\n\n\t\t\t\t\t\t// calculate normal vector from gradient\n\t\t\t\t\t\tvec3 N;\n\t\t\t\t\t\tfloat val1, val2;\n\t\t\t\t\t\tval1 = sample1(loc + vec3(-step[0], 0.0, 0.0));\n\t\t\t\t\t\tval2 = sample1(loc + vec3(+step[0], 0.0, 0.0));\n\t\t\t\t\t\tN[0] = val1 - val2;\n\t\t\t\t\t\tval = max(max(val1, val2), val);\n\t\t\t\t\t\tval1 = sample1(loc + vec3(0.0, -step[1], 0.0));\n\t\t\t\t\t\tval2 = sample1(loc + vec3(0.0, +step[1], 0.0));\n\t\t\t\t\t\tN[1] = val1 - val2;\n\t\t\t\t\t\tval = max(max(val1, val2), val);\n\t\t\t\t\t\tval1 = sample1(loc + vec3(0.0, 0.0, -step[2]));\n\t\t\t\t\t\tval2 = sample1(loc + vec3(0.0, 0.0, +step[2]));\n\t\t\t\t\t\tN[2] = val1 - val2;\n\t\t\t\t\t\tval = max(max(val1, val2), val);\n\n\t\t\t\t\t\tfloat gm = length(N); // gradient magnitude\n\t\t\t\t\t\tN = normalize(N);\n\n\t\t\t\t\t\t// Flip normal so it points towards viewer\n\t\t\t\t\t\tfloat Nselect = float(dot(N, V) > 0.0);\n\t\t\t\t\t\tN = (2.0 * Nselect - 1.0) * N;\t// ==\tNselect * N - (1.0-Nselect)*N;\n\n\t\t\t\t\t\t// Init colors\n\t\t\t\t\t\tvec4 ambient_color = vec4(0.0, 0.0, 0.0, 0.0);\n\t\t\t\t\t\tvec4 diffuse_color = vec4(0.0, 0.0, 0.0, 0.0);\n\t\t\t\t\t\tvec4 specular_color = vec4(0.0, 0.0, 0.0, 0.0);\n\n\t\t\t\t\t\t// note: could allow multiple lights\n\t\t\t\t\t\tfor (int i=0; i<1; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t // Get light direction (make sure to prevent zero devision)\n\t\t\t\t\t\t\t\tvec3 L = normalize(view_ray);\t//lightDirs[i];\n\t\t\t\t\t\t\t\tfloat lightEnabled = float( length(L) > 0.0 );\n\t\t\t\t\t\t\t\tL = normalize(L + (1.0 - lightEnabled));\n\n\t\t\t\t\t\t\t\t// Calculate lighting properties\n\t\t\t\t\t\t\t\tfloat lambertTerm = clamp(dot(N, L), 0.0, 1.0);\n\t\t\t\t\t\t\t\tvec3 H = normalize(L+V); // Halfway vector\n\t\t\t\t\t\t\t\tfloat specularTerm = pow(max(dot(H, N), 0.0), shininess);\n\n\t\t\t\t\t\t\t\t// Calculate mask\n\t\t\t\t\t\t\t\tfloat mask1 = lightEnabled;\n\n\t\t\t\t\t\t\t\t// Calculate colors\n\t\t\t\t\t\t\t\tambient_color +=\tmask1 * ambient_color;\t// * gl_LightSource[i].ambient;\n\t\t\t\t\t\t\t\tdiffuse_color +=\tmask1 * lambertTerm;\n\t\t\t\t\t\t\t\tspecular_color += mask1 * specularTerm * specular_color;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Calculate final color by componing different components\n\t\t\t\t\t\tvec4 final_color;\n\t\t\t\t\t\tvec4 color = apply_colormap(val);\n\t\t\t\t\t\tfinal_color = color * (ambient_color + diffuse_color) + specular_color;\n\t\t\t\t\t\tfinal_color.a = color.a;\n\t\t\t\t\t\treturn final_color;\n\t\t\t\t}"};var ge=(t=>(t[t.MIP=0]="MIP",t[t.ISO=1]="ISO",t))(ge||{});class xe extends g{constructor(t){const{style:e,threshold:n,clim:a,map:r,gradient:s}=t??{},l=new i(1,1,1);if(r){const{width:t,height:e,depth:n}=r.image;l.set(t,e,n)}const c=null==s?s:Ct(s),u=U.clone(ve.uniforms);u.u_size.value.copy(l),u.u_clim.value.copy(a??new o(1,1)),u.u_renderstyle.value=e??1,u.u_renderthreshold.value=n??.5,u.u_data.value=r??null,u.u_cmdata.value=c??null,super({...ve,uniforms:u,side:R}),Rt(this,"isExampleVolumeMaterial_1",!0),Rt(this,"_gradient")}get map(){return this.uniforms.u_data.value}set map(t){this.uniforms.u_data.value=t,this.uniformsNeedUpdate=!0}get gradientMap(){return this.uniforms.u_cmdata.value}get gradient(){return this._gradient}set gradient(t){this._gradient=t;const e=null==t?t:Ct(t);this.uniforms.u_cmdata.value=e??null,this.uniformsNeedUpdate=!0}get size(){return this.uniforms.u_size.value}set size(t){this.uniforms.u_size.value.copy(t),this.uniformsNeedUpdate=!0}get style(){return this.uniforms.u_renderstyle.value}set style(t){this.uniforms.u_renderstyle.value=t,this.uniformsNeedUpdate=!0}get clim(){return this.uniforms.u_clim.value}set clim(t){this.uniforms.u_clim.value=t,this.uniformsNeedUpdate=!0}get threshold(){return this.uniforms.u_renderthreshold.value}set threshold(t){this.uniforms.u_renderthreshold.value=t,this.uniformsNeedUpdate=!0}}const _e="in vec3 position;\n\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform vec3 cameraPos;\n\nout vec3 vOrigin;\nout vec3 vDirection;\n\nvoid main() {\n vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n vOrigin = vec3( inverse( modelMatrix ) * vec4( cameraPos, 1.0 ) ).xyz;\n vDirection = position - vOrigin;\n gl_Position = projectionMatrix * mvPosition;\n}";class ye extends V{constructor(t){let{color:e,threshold:n,map:a,opacity:o,range:r,steps:s,frame:l,cameraPos:c}=t??{};e=e??new C(1,1,1),n=n??.25,o=o??.25,r=r??.1,s=s??100,l=l??100,c=c??new i,super({glslVersion:x,uniforms:{base:{value:e},map:{value:a},cameraPos:{value:c},threshold:{value:n},opacity:{value:o},range:{value:r},steps:{value:s},frame:{value:l}},vertexShader:_e,fragmentShader:"precision highp float;\nprecision highp sampler3D;\n\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\n\nin vec3 vOrigin;\nin vec3 vDirection;\n\nout vec4 color;\n\nuniform vec3 base;\nuniform sampler3D map;\n\nuniform float threshold;\nuniform float range;\nuniform float opacity;\nuniform float steps;\nuniform float frame;\n\nuint wang_hash(uint seed)\n{\n seed = (seed ^ 61u) ^ (seed >> 16u);\n seed *= 9u;\n seed = seed ^ (seed >> 4u);\n seed *= 0x27d4eb2du;\n seed = seed ^ (seed >> 15u);\n return seed;\n}\n\nfloat randomFloat(inout uint seed)\n{\n return float(wang_hash(seed)) / 4294967296.;\n}\n\nvec2 hitBox( vec3 orig, vec3 dir ) {\n const vec3 box_min = vec3( - 0.5 );\n const vec3 box_max = vec3( 0.5 );\n vec3 inv_dir = 1.0 / dir;\n vec3 tmin_tmp = ( box_min - orig ) * inv_dir;\n vec3 tmax_tmp = ( box_max - orig ) * inv_dir;\n vec3 tmin = min( tmin_tmp, tmax_tmp );\n vec3 tmax = max( tmin_tmp, tmax_tmp );\n float t0 = max( tmin.x, max( tmin.y, tmin.z ) );\n float t1 = min( tmax.x, min( tmax.y, tmax.z ) );\n return vec2( t0, t1 );\n}\n\nfloat sample1( vec3 p ) {\n return texture( map, p ).r;\n}\n\nfloat shading( vec3 coord ) {\n float step = 0.01;\n return sample1( coord + vec3( - step ) ) - sample1( coord + vec3( step ) );\n}\n\nvoid main(){\n vec3 rayDir = normalize( vDirection );\n vec2 bounds = hitBox( vOrigin, rayDir );\n\n if ( bounds.x > bounds.y ) discard;\n\n bounds.x = max( bounds.x, 0.0 );\n\n vec3 p = vOrigin + bounds.x * rayDir;\n vec3 inc = 1.0 / abs( rayDir );\n float delta = min( inc.x, min( inc.y, inc.z ) );\n delta /= steps;\n\n // Jitter\n\n // Nice little seed from\n // https://blog.demofox.org/2020/05/25/casual-shadertoy-path-tracing-1-basic-camera-diffuse-emissive/\n uint seed = uint( gl_FragCoord.x ) * uint( 1973 ) + uint( gl_FragCoord.y ) * uint( 9277 ) + uint( frame ) * uint( 26699 );\n vec3 size = vec3( textureSize( map, 0 ) );\n float randNum = randomFloat( seed ) * 2.0 - 1.0;\n p += rayDir * randNum * ( 1.0 / size );\n\n //\n\n vec4 ac = vec4( base, 0.0 );\n\n for ( float t = bounds.x; t < bounds.y; t += delta ) {\n\n float d = sample1( p + 0.5 );\n\n d = smoothstep( threshold - range, threshold + range, d ) * opacity;\n\n float col = shading( p + 0.5 ) * 3.0 + ( ( p.x + p.y ) * 0.25 ) + 0.2;\n\n ac.rgb += ( 1.0 - ac.a ) * d * col;\n\n ac.a += ( 1.0 - ac.a ) * d;\n\n if ( ac.a >= 0.95 ) break;\n\n p += rayDir * delta;\n\n }\n\n color = ac;\n\n if ( color.a == 0.0 ) discard;\n\n}",side:R,transparent:!0}),Rt(this,"isExampleVolumeMaterial_Cloud",!0),this.opacity=o}get map(){return this.uniforms.map.value}set map(t){this.uniforms.map.value=t,this.uniformsNeedUpdate=!0}get color(){return this.uniforms.base.value}set color(t){this.uniforms.base.value=t,this.uniformsNeedUpdate=!0}get opacity(){return this.uniforms.opacity.value}set opacity(t){this.uniforms&&(this.uniforms.opacity.value=t),this.uniformsNeedUpdate=!0}get threshold(){return this.uniforms.threshold.value}set threshold(t){this.uniforms.threshold.value=t,this.uniformsNeedUpdate=!0}get range(){return this.uniforms.range.value}set range(t){this.uniforms.range.value=t,this.uniformsNeedUpdate=!0}get steps(){return this.uniforms.steps.value}set steps(t){this.uniforms.steps.value=t,this.uniformsNeedUpdate=!0}get frame(){return this.uniforms.frame.value}set frame(t){this.uniforms.frame.value=t,this.uniformsNeedUpdate=!0}get cameraPos(){return this.uniforms.cameraPos.value}set cameraPos(t){this.uniforms.cameraPos.value.copy(t),this.uniformsNeedUpdate=!0}}class we extends V{constructor(t){let{threshold:e,map:n,steps:a,cameraPos:o}=t??{};e=e??.25,a=a??100,o=o??new i,super({glslVersion:x,uniforms:{map:{value:n},cameraPos:{value:o},threshold:{value:e},steps:{value:a}},vertexShader:_e,fragmentShader:"precision highp float;\nprecision highp sampler3D;\n\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\n\nin vec3 vOrigin;\nin vec3 vDirection;\n\nout vec4 color;\n\nuniform sampler3D map;\n\nuniform float threshold;\nuniform float steps;\n\nvec2 hitBox( vec3 orig, vec3 dir ) {\n const vec3 box_min = vec3( - 0.5 );\n const vec3 box_max = vec3( 0.5 );\n vec3 inv_dir = 1.0 / dir;\n vec3 tmin_tmp = ( box_min - orig ) * inv_dir;\n vec3 tmax_tmp = ( box_max - orig ) * inv_dir;\n vec3 tmin = min( tmin_tmp, tmax_tmp );\n vec3 tmax = max( tmin_tmp, tmax_tmp );\n float t0 = max( tmin.x, max( tmin.y, tmin.z ) );\n float t1 = min( tmax.x, min( tmax.y, tmax.z ) );\n return vec2( t0, t1 );\n}\n\nfloat sample1( vec3 p ) {\n return texture( map, p ).r;\n}\n\n#define epsilon .0001\n\nvec3 normal( vec3 coord ) {\n if ( coord.x < epsilon ) return vec3( 1.0, 0.0, 0.0 );\n if ( coord.y < epsilon ) return vec3( 0.0, 1.0, 0.0 );\n if ( coord.z < epsilon ) return vec3( 0.0, 0.0, 1.0 );\n if ( coord.x > 1.0 - epsilon ) return vec3( - 1.0, 0.0, 0.0 );\n if ( coord.y > 1.0 - epsilon ) return vec3( 0.0, - 1.0, 0.0 );\n if ( coord.z > 1.0 - epsilon ) return vec3( 0.0, 0.0, - 1.0 );\n\n float step = 0.01;\n float x = sample1( coord + vec3( - step, 0.0, 0.0 ) ) - sample1( coord + vec3( step, 0.0, 0.0 ) );\n float y = sample1( coord + vec3( 0.0, - step, 0.0 ) ) - sample1( coord + vec3( 0.0, step, 0.0 ) );\n float z = sample1( coord + vec3( 0.0, 0.0, - step ) ) - sample1( coord + vec3( 0.0, 0.0, step ) );\n\n return normalize( vec3( x, y, z ) );\n}\n\nvoid main(){\n\n vec3 rayDir = normalize( vDirection );\n vec2 bounds = hitBox( vOrigin, rayDir );\n\n if ( bounds.x > bounds.y ) discard;\n\n bounds.x = max( bounds.x, 0.0 );\n\n vec3 p = vOrigin + bounds.x * rayDir;\n vec3 inc = 1.0 / abs( rayDir );\n float delta = min( inc.x, min( inc.y, inc.z ) );\n delta /= steps;\n\n for ( float t = bounds.x; t < bounds.y; t += delta ) {\n\n float d = sample1( p + 0.5 );\n\n if ( d > threshold ) {\n\n color.rgb = normal( p + 0.5 ) * 0.5 + ( p * 1.5 + 0.25 );\n color.a = 1.;\n break;\n\n }\n\n p += rayDir * delta;\n\n }\n\n if ( color.a == 0.0 ) discard;\n\n}",side:R,transparent:!0}),Rt(this,"isExampleVolumeMaterial_Perlin",!0)}get map(){return this.uniforms.map.value}set map(t){this.uniforms.map.value=t,this.uniformsNeedUpdate=!0}get threshold(){return this.uniforms.threshold.value}set threshold(t){this.uniforms.threshold.value=t,this.uniformsNeedUpdate=!0}get steps(){return this.uniforms.steps.value}set steps(t){this.uniforms.steps.value=t,this.uniformsNeedUpdate=!0}get cameraPos(){return this.uniforms.cameraPos.value}set cameraPos(t){this.uniforms.cameraPos.value.copy(t),this.uniformsNeedUpdate=!0}}class Me{constructor(t){this.ssp=t,this.defaultColorGradient=[[0,"rgba(0,255,0,0)"],[.5,"rgba(64,255,255,0.5)"],[1,"rgba(255,64,255,1)"]],this.defaultGradientVolumeMaterialOptions={fit:Vt.Raw,accFactor:2,depthTest:!1,side:R,discardOut:!1,gradient:Ct(this.defaultColorGradient)}}_createTexture(t,e,n=!1){const i=he(Object.assign({points:t},e),Object.assign({maxSize:60},e)),{options:a,position:o,scale:r}=i,s=kt(n?me(a):se(a),Object.assign({},e)),l=new Lt(Object.assign(Object.assign(Object.assign({},this.defaultGradientVolumeMaterialOptions),{map:s}),e)),c=new jt(l);return c.position.copy(o),c.scale.set(r,r,r),this.ssp.addObject(c),c}createHeatCloud(t,e){return this._createTexture(t,e)}createLineHeat(t,e){return this._createTexture(t,e,!0)}async createImageExtrusion(t,e){var n;const i=new Ht(Object.assign({side:R,depthTest:!1},e)),a=Wt(await L.utils.imageLoader.loadAsync(t),null!==(n=null==e?void 0:e.depth)&&void 0!==n?n:200,e);i.map=a;const o=new jt(i);return this.ssp.addObject(o),o}createSliceMesh(t,e){let n=t.map;if(!n)return;if(t instanceof Lt){const{gradient:i,range:a,discardOut:o,voidRange:r}=t;n=Yt(n.image,Object.assign({gradient:null==i?void 0:i.image,range:a,discardOut:o,voidRange:r},e))}const i=new ne(Object.assign({map:n},e));return this.ssp.addObject(i),i}createImageSlice(t,e){const n=t.map;if(!n)return;let i=null;if(t instanceof Lt){const{gradient:a,range:o,discardOut:r,voidRange:s}=t;i=Yt(n.image,Object.assign({gradient:null==a?void 0:a.image,range:o,discardOut:r,voidRange:s},e))}if(t instanceof Ht&&(i=n),!i)return;return new ie(i)}}export{Jt as ColorFogPointsMaterial,xe as ExampleVolumeMaterial_1,ye as ExampleVolumeMaterial_Cloud,we as ExampleVolumeMaterial_Perlin,Zt as FogPointsMaterial,Bt as GradientData3DTexture,$t as GradientFogPointsMaterial,Lt as GradientVolumeMaterial,Me as HeatMapPlugin,Mt as ImageData3DSlice,Kt as ImageData3DTexture,ie as ImageData3DTextureSlice,Ht as ImageVolumeMaterial,ee as SliceMaterial,ne as SliceMesh,Xt as SphereFogMaterial,Vt as VolumeFit,Et as VolumeMaterial,jt as VolumeMesh,ge as VolumeRenderStyle,re as computeHeatData3DForPoint,Qt as createColorFogPoints,kt as createGradientData3DTexture,te as createGradientFogPoints,se as createHeatData3D,Wt as createImageData3DTextureByExtrudeImage,Yt as createImageData3DTextureFromGradient,me as createLineData3D,W as createLinearGradientImageData,Ct as createLinearGradientTexture,ht as data2DCoordToIndex,vt as data2DIndexToCoord,at as data3DCoordToIndex,ot as data3DIndexToCoord,Me as default,pt as extrudeImage,mt as extrudeImageData,ft as extrudeImageDataOnAxis,xt as getData2DItem,gt as getData2DItemSafe,wt as getData2DRow,yt as getData2DValue,_t as getData2DValueSafe,st as getData3DItem,rt as getData3DItemSafe,dt as getData3DSlice,ct as getData3DValue,lt as getData3DValueSafe,Q as getImageDateColor,Y as getImageDateOfImage,J as getImageDateRow,X as getNaturalSizeOfImageSource,qt as gradientData3DToImageData3D,ce as hollowGradient_Default,$ as imageDataToCanvas,tt as imageDataToUrl,et as isIImageData2,nt as isIImageData3,it as isOutOfSize,ue as lineValueGradient_Default,Gt as makeOriginOnBoundingBoxMinOfGeometry,ut as mergeData3Ds,de as numberValuesAccumulate_Default,he as optimizeGradientOptions,le as radiusGradient_Default,Z as reverseImageDateY,pe as transformGradientOptions,fe as translateScaleGradientOptions,ae as valueGradient_Default,oe as valuesAccumulate_Default};
|
|
1
|
+
import{TextureLoader as t,Texture as e,Matrix3 as n,Vector4 as i,Vector3 as a,Vector2 as o,AlphaFormat as r,RedFormat as s,RedIntegerFormat as l,RGFormat as c,RGIntegerFormat as u,RGBAFormat as d,RGBAIntegerFormat as m,LuminanceFormat as p,LuminanceAlphaFormat as f,DepthFormat as h,DepthStencilFormat as v,ShaderMaterial as g,GLSL3 as x,Matrix4 as _,DoubleSide as y,Mesh as w,BoxGeometry as M,Data3DTexture as z,FloatType as D,LinearFilter as S,UnsignedByteType as b,Color as C,FrontSide as N,UniformsUtils as U,ShaderLib as A,Points as P,PlaneGeometry as O,Box3 as I,Line3 as T,Quaternion as F,BackSide as R,RawShaderMaterial as V,BufferGeometry as E,Float32BufferAttribute as G,Uint8ClampedBufferAttribute as j}from"three";import L from"soonspacejs";var B,k=(t=>(t[t.x=0]="x",t[t.y=1]="y",t[t.z=2]="z",t))(k||{});(B=k||(k={})).toKey=function(t){return B[t]},B.toIndex=function(t){return B[t]},B.getCrossAxiss=function(t){return[(t+1)%3,(t+2)%3]};var H=(t=>(t[t.x=0]="x",t[t.y=1]="y",t[t.z=2]="z",t[t.w=3]="w",t))(H||{});(t=>{t.toKey=function(e){return t[e]},t.toIndex=function(e){return t[e]},t.getCrossAxiss=function(t){return[(t+1)%4,(t+2)%4]}})(H||(H={}));var q=Object.defineProperty,K=(t,e,n)=>(((t,e,n)=>{e in t?q(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n})(t,"symbol"!=typeof e?e+"":e,n),n);function W(t,e,n,i="srgb"){const a=new OffscreenCanvas(e,n).getContext("2d"),o=a.createLinearGradient(0,0,256,1);for(const[e,n]of t)o.addColorStop(Number(e),n);return a.fillStyle=o,a.fillRect(0,0,e,n),a.getImageData(0,0,e,n,{colorSpace:i})}function Y(t,e){let{area:n,width:i,height:a,colorSpace:o}=e||{};o=o??"srgb",n=n||{};const r=n.x??0,s=n.y??0,l=X(t),c=n.width??l.width,u=n.height??l.height;i=i??c,a=a??u;const d=new OffscreenCanvas(i,a).getContext("2d");return d.drawImage(t,r,s,c,u,0,0,i,a),d.getImageData(0,0,i,a,{colorSpace:o})}function X(t){let e=0,n=0;return t instanceof HTMLImageElement?(e=t.naturalWidth,n=t.naturalHeight):t instanceof HTMLVideoElement?(e=t.videoWidth,n=t.videoHeight):(e=t.width,n=t.height),{width:e,height:n}}function Z(t){const{data:e,width:n,height:i,colorSpace:a}=t,o=e.length,r=new Uint8ClampedArray(o);for(let t=0;t<i;t++){const i=t*n,a=-(i+n),o=a+n,s=e.slice(4*a,4*o);r.set(s,4*i)}return new ImageData(r,n,i,{colorSpace:a})}function J(t,e){const{data:n,width:i}=t,a=e*i,o=a+i;return n.slice(4*a,4*o)}function Q(t,e,n){const{data:i,width:a}=t,o=4*(e*a+n);return i.slice(o,o+4)}function $(t){const e=document.createElement("canvas"),n=e.getContext("2d");return e.width=t.width,e.height=t.height,n.putImageData(t,0,0),e}function tt(t){return $(t).toDataURL()}function et(t){return t&&null!=t.data&&null!=t.width&&null!=t.height}function nt(t){return et(t)&&null!=t.depth}function it(t,e){for(const[n,i]of Object.entries(t))if(0<=i&&i<=e[n])return!0;return!1}function at(t,e){const{x:n,y:i}=e;return t.z*i*n+t.y*n+t.x}function ot(t,e){const{x:n,y:i}=e,a=Math.trunc(t/n),o=t-a*n,r=Math.trunc(a/i);return{x:o,y:a-r*i,z:r}}function rt(t,e,n=1){let{x:i,y:a,z:o}=e;const r=t.size;return i=Math.max(0,Math.min(r.x-1,i)),a=Math.max(0,Math.min(r.y-1,a)),o=Math.max(0,Math.min(r.z-1,o)),st(t,{x:i,y:a,z:o},n)}function st(t,e,n=1){const{data:i,size:a}=t,o=at(e,a);let r=[];if(n>0){const t=o*n;for(let e=0;e<n;e++)r.push(i[t+e])}return{index:o,value:r}}function lt(t,e){let{x:n,y:i,z:a}=e;const o=t.size;return n=Math.max(0,Math.min(o.x-1,n)),i=Math.max(0,Math.min(o.y-1,i)),a=Math.max(0,Math.min(o.z-1,a)),ct(t,{x:n,y:i,z:a})}function ct(t,e){const{data:n,size:i}=t,a=at(e,i);return{index:a,value:n[a]}}function ut(t,e){const{voidValue:n,valuesAccumulate:i,verifyVoid:a=()=>!1}=e;let{x:o,y:r,z:s}=t[0].size;const l=t.length;for(let e=1;e<l;e++){const n=t[e].size;o=Math.max(o,n.x),r=Math.max(r,n.y),s=Math.max(s,n.z)}const c=new Array(o*r*s),u=o*r;for(let e=0;e<s;e++){const s=e*u;for(let l=0;l<r;l++){const r=s+l*o;for(let s=0;s<o;s++){const o=r+s,u={x:s,y:l,z:e},d=[];for(const n of t){const t=n.size;if(s<t.x&&l<t.y&&e<t.z)continue;const{index:i,value:o}=ct(n,u);a(o,n,i)||d.push({value:o,index:i,data3D:n,coord:u})}const m=d.length;let p=n;m>1?p=i(d):1===m&&(p=d[0].value),c[o]=p}}}return{data:c,size:{x:o,y:r,z:s}}}function dt(t,e,n,i=1){const{size:a}=t,o=k.toKey(e),[r,s]=k.getCrossAxiss(e),l=k.toKey(r),c=k.toKey(s),u=a[l],d=a[c],m=[],p=a[o];n=Math.trunc(n),n=Math.max(0,Math.min(p-1,n));let f={x:0,y:0,z:0};f[o]=n;for(let e=0;e<d;e++){f[c]=e;for(let e=0;e<u;e++){f[l]=e;const{value:n}=st(t,f,i);m.push(...n)}}return{data:m,size:{x:u,y:d}}}function mt(t,e,n){e=Math.trunc(e);const{data:i,width:a,height:o,colorSpace:r}=n?Z(t):t,s=i.length,l=new Uint8ClampedArray(s*e);for(let t=0;t<e;t++)l.set(i,t*s);return{data:l,width:a,height:o,depth:e,colorSpace:r}}function pt(t,e,n){const i=n||{},a=i.reverseY,o=i.axis??"z",r=et(t)?t:Y(t,i);return"z"===o?mt(r,e,a):ft(r,o,e,a)}function ft(t,e,n,i){n=Math.trunc(n);const{data:a,width:o,height:r,colorSpace:s}=i?Z(t):t,l=k.toKey(e),c=(e+1)%3,u=(e+2)%3,d=k.toKey(c),m=k.toKey(u),p={[d]:o,[m]:r,[l]:n},f=new Uint8ClampedArray(a.length*n),h={x:0,y:0,z:0};for(let t=0;t<n;t++){h[l]=t;for(let t=0;t<r;t++){h[m]=t;for(let e=0;e<o;e++){h[d]=e;const n=4*(t*o+e),i=n+4,r=a.subarray(n,i),s=4*at(h,p);f.set(r,s)}}}return{data:f,width:p.x,height:p.y,depth:p.z,colorSpace:s}}function ht(t,e){return t.y*e.x+t.x}function vt(t,e){const{x:n}=e,i=Math.trunc(t/n);return{x:t-i*n,y:i}}function gt(t,e,n=1){let{x:i,y:a}=e;const o=t.size;return i=Math.max(0,Math.min(o.x-1,i)),a=Math.max(0,Math.min(o.y-1,a)),xt(t,{x:i,y:a},n)}function xt(t,e,n=1){const{data:i,size:a}=t,o=ht(e,a);let r=[];if(n>0){const t=o*n;for(let e=0;e<n;e++)r.push(i[t+e])}return{index:o,value:r}}function _t(t,e){let{x:n,y:i}=e;const a=t.size;return n=Math.max(0,Math.min(a.x-1,n)),i=Math.max(0,Math.min(a.y-1,i)),yt(t,{x:n,y:i})}function yt(t,e){const{data:n,size:i}=t,a=ht(e,i);return{index:a,value:n[a]}}function wt(t,e,n=1){const{data:i,size:a}=t,o=a.x,r=e*o,s=r+o;return("function"==typeof i.slice?i:Array.from(i)).slice(r*n,s*n)}class Mt{constructor(t){K(this,"isImageData3DSlice",!0),K(this,"_image3D"),K(this,"_canvas"),K(this,"_context"),K(this,"_axis",k.z),K(this,"_depth",0),K(this,"_sliceSize",null),K(this,"_slice"),this.image3D=t}get image3D(){return this._image3D}set image3D(t){this._image3D=t,this.updateSize()}get canvas(){let t=this._canvas;return t||(t=this._canvas=document.createElement("canvas"),t.width=this.sliceSize.x,t.height=this.sliceSize.y),t}get context(){return this._context??(this._context=this.canvas.getContext("2d"))}get axis(){return this._axis}set axis(t){this._axis=t,this.updateSize()}get depth(){return this._depth}set depth(t){this._depth=t,this.updateSlice()}get sliceSize(){let t=this._sliceSize;if(!t){const{axis:e,image3D:n}=this,{width:i,height:a,depth:o}=n,[r,s]=k.getCrossAxiss(e),l=[i,a,o];this._sliceSize=t={x:l[r],y:l[s]}}return t}get slice(){return this._slice??(this._slice=this.getSlice(this.axis,this.depth))}getSlice(t,e){const{data:n,width:i,height:a,depth:o,colorSpace:r}=this.image3D,{data:s,size:l}=dt({data:n,size:{x:i,y:a,z:o}},t,e,4),c=s instanceof Uint8ClampedArray?s:Uint8ClampedArray.from(s);return new ImageData(c,l.x,l.y,{colorSpace:r})}getDataURL(){return this.canvas.toDataURL()}getColor(t){const{x:e,y:n}=t;return Q(this.slice,n,e)}updateSize(){this._sliceSize=null;const t=this.canvas;t.width=this.sliceSize.x,t.height=this.sliceSize.y,this.updateSlice()}updateSlice(){this._slice=null,this.context.putImageData(this.slice,0,0)}}var zt=Object.defineProperty,Dt=(t,e,n)=>(((t,e,n)=>{e in t?zt(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n})(t,"symbol"!=typeof e?e+"":e,n),n);function St(t){const e=t.length,n=[];if(0===e)return n;const[r,s]=function(t){return void 0!==t.w?[i,4]:void 0!==t.z?[a,3]:[o,2]}(t[0]);for(let i=0;i<e;i++){const a=t[i],o=(new r).copy(a),s=a.radius,l=n[i]??(n[i]=[]);for(let a=i+1;a<e;a++){const e=t[a];o.distanceToSquared(e)<=(e.radius+s)**2&&(l.push(a),(n[a]=[]).push(i))}}return n}let bt;function Ct(n){if("string"==typeof n)return(bt||(bt=new t)).load(n);if(n.isTexture)return n;const i=Array.isArray(n)?W(n,256,1):n,a=new e(i);return"srgb"===i.colorSpace&&(a.colorSpace="srgb"),a.needsUpdate=!0,a}function Nt(t,e,n){let i=function(t,e){const n=Math.sqrt(t.lengthSq()*e.lengthSq());if(0===n)return 0;let i=t.dot(e)/n;return i=Math.max(-1,Math.min(1,i)),Math.acos(i)}(t,e);return 0===i?i:t.clone().cross(e).dot(n)<0?-i:i}const Ut=180/Math.PI,At={yaw:[{name:"前",range:[-15,15]},{name:"左",range:[15,165]},{name:"右",range:[-165,-15]},{name:"后",range:[-180.1,-165]},{name:"后",range:[165,180.1]}],pitch:[{name:"前",range:[-15,15]},{name:"上",range:[15,165]},{name:"下",range:[-165,-15]},{name:"后",range:[-180.1,-165]},{name:"后",range:[165,180.1]}],roll:[{name:"上",range:[-15,15]},{name:"左",range:[15,165]},{name:"右",range:[-165,-15]},{name:"下",range:[-180.1,-165]},{name:"下",range:[165,180.1]}]};const Pt={degrees:!0,map:At,front:{x:0,y:0,z:1},up:{x:0,y:1,z:0}};let Ot=class{constructor(t){Dt(this,"_options"),Dt(this,"_listMap"),Dt(this,"_front"),Dt(this,"_up"),t&&(this.options=t)}static get options(){return this._options??(this.options=Pt)}static set options(t){this._options=Object.assign({},structuredClone(At),t)}get defaultOptions(){return this.constructor.options}get options(){return this._options??(this.options=this.defaultOptions)}set options(t){this._options=Object.assign({},structuredClone(this.defaultOptions),t),this._listMap=null,this._front=null,this._up=null}get degrees(){return this.options.degrees??(this.options.degrees=this.defaultOptions.degrees??!0)}set degrees(t){this.options.degrees=t}get map(){return this.options.map||(this.map=this.defaultOptions.map),this.options.map}set map(t){const e=structuredClone(this.defaultOptions.map),n=structuredClone(At);t=t?{yaw:t.yaw??e.yaw??n.yaw,pitch:t.pitch??e.pitch??n.pitch,roll:t.roll??e.roll??n.roll}:e,this.options.map=t,this._listMap=null}get listMap(){return this._listMap??(this._listMap=function(t){const e={};for(const[n,i]of Object.entries(t))e[n]=Array.isArray(i)?i:Object.entries(i).map(([t,e])=>({name:t,range:e}));return e}(this.map??{}))}get front(){return this._front||(this.front=this.options.front??this.defaultOptions.front??Pt.front),this._front}set front(t){this._front=(new a).copy(t)}get up(){return this._up||(this.up=this.options.up??this.defaultOptions.up??Pt.up),this._up}set up(t){this._up=(new a).copy(t)}computeAzimuth(t,e,n){const i=(new a).copy(t),o=(new a).copy(e??this.front),r=(new a).copy(n??this.up);let{yaw:s,pitch:l,roll:c}=function(t,e,n){const i=e.clone().negate(),a=n.clone().projectOnPlane(e),o=Nt(e,t.clone().projectOnPlane(a),a),r=e.clone().cross(a);return{yaw:o,pitch:Nt(e,t.clone().projectOnPlane(r),r),roll:Nt(a,t.clone().projectOnPlane(i),i)}}(i,o,r);return this.degrees&&(s*=Ut,l*=Ut,c*=Ut),{yaw:{angle:s,name:this.findAzimuthNames("yaw",s)},pitch:{angle:l,name:this.findAzimuthNames("pitch",l)},roll:{angle:c,name:this.findAzimuthNames("roll",c)}}}findAzimuthNames(t,e){const n=[],i=this.listMap[t];if(!i)return n;for(const{name:t,range:[a,o]}of i)(e>=a&&e<o||e<=a&&e>o)&&n.push(t);return n}};Dt(Ot,"_options"),new Ot;const It={[r]:1,[s]:1,[l]:1,[c]:3,[u]:2,[d]:4,[m]:4,[p]:1,[f]:2,[h]:1,[v]:2};function Tt(t){return It[t]}new n;var Ft=Object.defineProperty,Rt=(t,e,n)=>(((t,e,n)=>{e in t?Ft(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n})(t,"symbol"!=typeof e?e+"":e,n),n);var Vt=(t=>(t[t.Fill=0]="Fill",t[t.Align=1]="Align",t[t.Raw=2]="Raw",t))(Vt||{});class Et extends g{constructor(t){const{map:e,opacity:n,accFactor:i,steps:r,alphaRange:s,fit:l,atomize:c,side:u,containerMin:d,containerMax:m,uniforms:p,...f}=t??{},h=n??1,v=i??1,g=r??100,_=(new o).copy(s??{x:0,y:.95}),y=l??0,w=c??!0,M=u??N,z=(new a).copy(d??{x:0,y:0,z:0}),D=new a;if(m)D.copy(m);else if(e){const{width:t,height:n,depth:i}=e.image,o=new a(t-1,n-1,i-1);D.addVectors(z,o)}const S={map:{value:e},containerMin:{value:z},containerMax:{value:D},fit:{value:y},opacity:{value:h},alphaRange:{value:_},accFactor:{value:v},steps:{value:g},isDoubleSide:{value:!1},atomize:{value:w},...p};super({glslVersion:x,uniforms:S,transparent:!0,vertexShader:"precision highp sampler3D;\n\nuniform sampler3D map;\nuniform vec3 containerMin;\nuniform vec3 containerMax;\n\n// 0: 充满;1: 对齐;2: 原始\nuniform int fit;\n\n\nout vec3 cameraPos;\nout vec3 lookDir;\nout vec3 displayMin;\nout vec3 displayMax;\n\n\n\nvoid main() {\n cameraPos = vec3( inverse( modelMatrix ) * vec4( cameraPosition, 1.0 ) ).xyz;\n lookDir = position - cameraPos;\n\n vec3 containerSize = containerMax - containerMin;\n vec3 origin = containerMin;\n vec3 textSize = vec3(textureSize(map,0));\n displayMin = containerMin;\n displayMax = containerMax;\n\n switch (fit) {\n case 1:\n displayMax = displayMin + textSize;\n break;\n case 2:\n origin = vec3(0.0);\n break;\n default:\n textSize = containerSize;\n }\n\n vec3 scale = 1.0/textSize;\n cameraPos = (cameraPos - origin)*scale;\n lookDir *= scale;\n\n displayMin = max((displayMin - origin)*scale,vec3(0.0));\n displayMax = min((displayMax - origin)*scale,vec3(1.0));\n \n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",...f}),Rt(this,"isVolumeMaterial",!0),Rt(this,"_side",N),this.opacity=h,this.side=M}get map(){return this.uniforms.map.value}set map(t){this.uniforms.map.value=t,this.uniformsNeedUpdate=!0}get containerMin(){return this.uniforms.containerMin.value}set containerMin(t){this.uniforms.containerMin.value.copy(t),this.uniformsNeedUpdate=!0}get containerMax(){return this.uniforms.containerMax.value}set containerMax(t){this.uniforms.containerMax.value.copy(t),this.uniformsNeedUpdate=!0}get containerSize(){return this.containerMax.clone().sub(this.containerMin)}get fit(){return this.uniforms.fit.value}set fit(t){this.uniforms.fit.value=t,this.uniformsNeedUpdate=!0}getFitTranslate(){return 2===this.fit?new a:this.containerMin.clone()}getFitScale(){var t;const e=new a(1,1,1),n=null==(t=this.map)?void 0:t.image,i=this.fit;if(!n||2===i||1===i)return e;const o=new a(n.width,n.height,n.depth);return e.copy(this.containerSize).divide(o),e}getFitMatrix(){var t;const e=new _,n=null==(t=this.map)?void 0:t.image,i=this.fit;if(!n||2===i)return e;if(0===i){const t=new a(n.width,n.height,n.depth),i=this.containerSize.divide(t);e.makeScale(i.x,i.y,i.z)}return e.setPosition(this.containerMin),e}getFitMatrixInvert(){return this.getFitMatrix().invert()}get side(){return this._side}set side(t){this._side=t,this.uniforms&&(this.uniforms.isDoubleSide.value=t===y,this.uniformsNeedUpdate=!0)}get opacity(){return this.uniforms.opacity.value}set opacity(t){this.uniforms&&(this.uniforms.opacity.value=t),this.uniformsNeedUpdate=!0}get alphaRange(){return this.uniforms.alphaRange.value}set alphaRange(t){this.uniforms.alphaRange.value.copy(t),this.uniformsNeedUpdate=!0}get atomize(){return this.uniforms.atomize.value}set atomize(t){this.uniforms.atomize.value=t,this.uniformsNeedUpdate=!0}get steps(){return this.uniforms.steps.value}set steps(t){this.uniforms.steps.value=t,this.uniformsNeedUpdate=!0}get accFactor(){return this.uniforms.accFactor.value}set accFactor(t){this.uniforms&&(this.uniforms.accFactor.value=t),this.uniformsNeedUpdate=!0}toMapPosition(t){const e=new a(t.x,t.y,t.z).applyMatrix4(this.getFitMatrixInvert());return e.set(Math.trunc(e.x),Math.trunc(e.y),Math.trunc(e.z)),e}toMapDepth(t,e){const i=k.toKey(t),o=new a;o[i]=1;const r=(new n).setFromMatrix4(this.getFitMatrix());return o.applyMatrix3(r),e/=o.length(),Math.trunc(e)}getData3DSlice(t,e){const n=this.map;return null!=n&&n.image?function(t,e,n){const{data:i,width:a,height:o,depth:r}=t.image;return dt({data:i,size:{x:a,y:o,z:r}},e,n,Tt(t.format))}(n,t,e=this.toMapDepth(t,e)):null}getItem(t){const e=this.map;return null!=e&&e.image?function(t,e){const{data:n,width:i,height:a,depth:o}=t.image;return rt({data:n,size:{x:i,y:a,z:o}},e,Tt(t.format))}(e,this.toMapPosition(t)).value:null}}function Gt(t){t.boundingBox||t.computeBoundingBox();const{x:e,y:n,z:i}=t.boundingBox.min;return t.translate(-e,-n,-i),t}class jt extends w{constructor(t){var e;const{width:n,height:i,depth:a}=(null==(e=t.map)?void 0:e.image)||{},o=new M(n,i,a);Gt(o),super(o,t),Rt(this,"isVolumeMesh",!0),Rt(this,"_geometry"),Rt(this,"autoUpdateMaterial",!0),Rt(this,"_material"),Rt(this,"autoUpdateGeometry",!0),Rt(this,"autoNormalize",!1),Object.defineProperties(this,{geometry:{get:()=>this._geometry,set:t=>{this._geometry=t,this.autoNormalize?this.normalize():this.autoUpdateMaterial&&this.updateMaterial()}},material:{get:()=>this._material,set:t=>{this._material=t,this.autoUpdateGeometry&&this.updateGeometry()}}}),this.geometry=o,this.material=t}updateMaterial(){const{geometry:t,material:e}=this;if(!e||!t)return!1;t.boundingBox||t.computeBoundingBox();const{min:n,max:i}=t.boundingBox;e.containerMin=n,e.containerMax=i}updateGeometry(){var t;const{geometry:e,material:n,autoUpdateMaterial:i}=this,o=null==(t=n.map)?void 0:t.image;if(!o)return!1;e.boundingBox||e.computeBoundingBox();const{width:r,height:s,depth:l}=o,c=e.boundingBox.getSize(new a);e.scale(r/c.x,s/c.y,l/c.z),i&&this.updateMaterial()}normalize(){const{geometry:t,autoUpdateMaterial:e}=this;t.boundingBox||t.computeBoundingBox();const{x:n,y:i,z:a}=t.boundingBox.min;t.translate(-n,-i,-a),e&&this.updateMaterial()}toMapPosition(t){const e=this.worldToLocal(new a(t.x,t.y,t.z));return this.material.toMapPosition(e)}toMaterialDepth(t,e){const i=k.toKey(t),o=new a;o[i]=1;const r=(new n).setFromMatrix4(this.matrixWorld);return o.applyMatrix3(r),e/=o.length()}toMapDepth(t,e){return e=this.toMaterialDepth(t,e),this.material.toMapDepth(t,e)}getData3DSlice(t,e){return e=this.toMaterialDepth(t,e),this.material.getData3DSlice(t,e)}getItem(t){const e=this.worldToLocal(new a(t.x,t.y,t.z));return this.material.getItem(e)}}class Lt extends Et{constructor(t){const{gradient:e,range:n,discardOut:i,voidRange:a,...r}=t??{},s=(new o).copy(n??{x:0,y:100}),l=i??!0,c=(new o).copy(a??{x:-100,y:-1});super({...r,fragmentShader:"precision highp float;\nprecision highp sampler3D;\n\nuniform sampler3D map;\nuniform sampler2D gradient;\n\nuniform bool atomize;\nuniform float steps;\n// 颜色累积系数\nuniform float accFactor;\nuniform vec2 range;\n// 是否丢弃超出范围的像素\nuniform bool discardOut;\n// 空值范围\nuniform vec2 voidRange;\nuniform float opacity;\nuniform vec2 alphaRange;\nuniform bool isDoubleSide;\n\nin vec3 cameraPos;\nin vec3 lookDir;\nin vec3 displayMin;\nin vec3 displayMax;\nout vec4 fragColor;\n\nvec4 colorBlend(vec4 near,vec4 far){\n float nA = near.a;\n if (nA >= 1.0){\n return near;\n }\n if (nA <= 0.0){\n return far;\n }\n \n float fA = far.a;\n float a = fA + nA - fA*nA;\n vec3 color = (far.rgb * fA * (1.0 - nA) + near.rgb*nA)/a;\n return vec4(color,a);\n}\n\n\n\n\nvec2 intersectBox( vec3 orig, vec3 dir ) {\n vec3 inv_dir = 1.0 / dir;\n vec3 tmin_tmp = (displayMin - orig ) * inv_dir;\n vec3 tmax_tmp = (displayMax - orig ) * inv_dir;\n vec3 tmin = min( tmin_tmp, tmax_tmp );\n vec3 tmax = max( tmin_tmp, tmax_tmp );\n float t0 = max( tmin.x, max( tmin.y, tmin.z ) );\n float t1 = min( tmax.x, min( tmax.y, tmax.z ) );\n return vec2( t0, t1 );\n}\n\nfloat getValue( vec3 point ) {\n return texture( map, point ).r;\n}\n\n// 获取梯度颜色\nvec4 getGradientColor(float val) {\n val = clamp( val, 0.0,1.0);\n return texture2D(gradient, vec2(val, 0.5));\n}\n\n\n\n\nvoid main(){\n vec3 rayDir = normalize( lookDir );\n\n vec2 times = intersectBox( cameraPos, rayDir );\n float tMin = times.x;\n float tMax = times.y;\n if ( tMin > tMax || tMax < 0.0 ) discard;\n tMin = max( tMin, 0.0 );\n\n vec3 point = cameraPos + tMin * rayDir;\n \n float step = 1.0/steps;\n float opacityFactor = atomize ? step * accFactor : 1.0;\n\n\n float invRangeLen = 1.0/(range.y - range.x);\n vec3 stepDir = rayDir * step;\n\n vec4 finalColor = vec4( 0,0,0,0);\n float alphaMax = alphaRange.y;\n\n for ( float t = tMin; t <= tMax; t += step,point += stepDir ) {\n float val = getValue( point);\n if (voidRange.x <= val && val <= voidRange.y ) continue;\n val = (val - range.x) * invRangeLen;\n if (discardOut && (val < 0.0 || val > 1.0)) continue;\n\n vec4 gradientColor = getGradientColor(val);\n gradientColor.a *= opacityFactor;\n finalColor = colorBlend(finalColor,gradientColor);\n if ( finalColor.a >= alphaMax ) break;\n }\n\n finalColor.a *= opacity;\n if ( finalColor.a <= alphaRange.x ) discard;\n if (isDoubleSide){\n finalColor.a = 1.0 - sqrt(1.0 - finalColor.a);\n }\n fragColor = finalColor;\n\n}",uniforms:{gradient:{value:null==e?e:Ct(e)},range:{value:s},discardOut:{value:l},voidRange:{value:c}}}),Rt(this,"isGradientVolumeMaterial",!0)}get gradient(){return this.uniforms.gradient.value}set gradient(t){this.uniforms.gradient.value=t,this.uniformsNeedUpdate=!0}get range(){return this.uniforms.range.value}set range(t){this.uniforms.range.value.copy(t),this.uniformsNeedUpdate=!0}get discardOut(){return this.uniforms.discardOut.value}set discardOut(t){this.uniforms.discardOut.value=t,this.uniformsNeedUpdate=!0}get voidRange(){return this.uniforms.voidRange.value}set voidRange(t){this.uniforms.voidRange.value.copy(t),this.uniformsNeedUpdate=!0}}class Bt extends z{constructor(t,e,n,i,a){super(t,e,n,i),Rt(this,"isGradientData3DTexture",!0),this.format=s,this.type=a??D,this.minFilter=this.magFilter=S,this.unpackAlignment=1,this.needsUpdate=!0}getData3DSlice(t,e){const{data:n,width:i,height:a,depth:o}=this.image;return dt({data:n,size:{x:i,y:a,z:o}},t,e,1)}getItem(t){const{data:e,width:n,height:i,depth:a}=this.image;return rt({data:e,size:{x:n,y:i,z:a}},t).value}getValue(t){const{data:e,width:n,height:i,depth:a}=this.image;return lt({data:e,size:{x:n,y:i,z:a}},t).value}}function kt(t,e){const{data:n,size:i}=t,{x:a,y:o,z:r}=i,s=a*o*r,{voidValue:l=0,uint8:c}=e??{};let u;if(c){u=new Uint8Array(s);for(let t=0;t<s;t++){const e=n[t]??l;u[t]=Math.trunc(e)}}else{u=new Float32Array(s);for(let t=0;t<s;t++){const e=n[t]??l;u[t]=e}}return new Bt(u,a,o,r,c?b:D)}class Ht extends Et{constructor(t){super({...t,fragmentShader:"precision highp float;\nprecision highp sampler3D;\n\nuniform sampler3D map;\n\n\n\n// 颜色累积系数\nuniform float accFactor;\nuniform bool isDoubleSide;\nuniform bool atomize;\n\n\nuniform float opacity;\nuniform vec2 alphaRange;\nuniform float steps;\n\nin vec3 cameraPos;\nin vec3 lookDir;\nin vec3 displayMin;\nin vec3 displayMax;\nout vec4 fragColor;\n\n// 混合颜色\nvec4 colorBlend(vec4 near,vec4 far){\n float nA = near.a;\n if (nA >= 1.0){\n return near;\n }\n if (nA <= 0.0){\n return far;\n }\n \n float fA = far.a;\n float a = fA + nA - fA*nA;\n vec3 color = (far.rgb * fA * (1.0 - nA) + near.rgb*nA)/a;\n return vec4(color,a);\n}\n\n\n\n\n// 包围盒求交\nvec2 intersectBox( vec3 orig, vec3 dir ) {\n vec3 inv_dir = 1.0 / dir;\n vec3 tmin_tmp = (displayMin - orig ) * inv_dir;\n vec3 tmax_tmp = (displayMax - orig ) * inv_dir;\n vec3 tmin = min( tmin_tmp, tmax_tmp );\n vec3 tmax = max( tmin_tmp, tmax_tmp );\n float t0 = max( tmin.x, max( tmin.y, tmin.z ) );\n float t1 = min( tmax.x, min( tmax.y, tmax.z ) );\n return vec2( t0, t1 );\n}\n\n\n\nvoid main(){\n vec3 rayDir = normalize( lookDir );\n\n vec2 times = intersectBox( cameraPos, rayDir );\n float tMin = times.x;\n float tMax = times.y;\n if ( tMin > tMax || tMax < 0.0 ) discard;\n tMin = max( tMin, 0.0 );\n\n vec3 point = cameraPos + tMin * rayDir;\n \n float step = 1.0/steps;\n float opacityFactor = atomize ? step * accFactor : 1.0;\n\n vec3 stepDir = rayDir * step;\n\n vec4 finalColor = vec4( 0,0,0,0);\n float alphaMax = alphaRange.y;\n\n for ( float t = tMin; t <= tMax; t += step,point += stepDir ) {\n vec4 textureColor = texture( map, point );\n textureColor.a *= opacityFactor;\n finalColor = colorBlend(finalColor,textureColor);\n if ( finalColor.a >= alphaMax ) break;\n }\n\n finalColor.a *= opacity;\n if ( finalColor.a <= alphaRange.x ) discard;\n if (isDoubleSide){\n finalColor.a = 1.0 - sqrt(1.0 - finalColor.a);\n }\n fragColor = finalColor;\n\n}"}),Rt(this,"isImageVolumeMaterial",!0)}}function qt(t,e,n){const i=n??{},{x:a,y:o}=i.range??{x:0,y:100},r=i.discardOut??!0,{x:s,y:l}=i.voidRange??{x:-100,y:-1},c=i.voidColor??[0,0,0,0],{width:u,height:d}=e,m=Math.trunc(d/2),p=u-1;function f(t){const n=Math.trunc(p*t);return Q(e,m,n)}const h=1/(o-a),{data:v,size:g}=t,x=v.length,_=[];for(let t=0;t<x;t++){let e=c,n=v[t];(n<=s||l<=n)&&(n=(n-a)*h,r&&(n<0||n>1)||(n=Math.min(Math.max(n,0),1),e=f(n))),_.push(...e)}return{data:_,size:g}}class Kt extends z{constructor(t,e,n,i){super(t,e,n,i),Rt(this,"isImageData3DTexture",!0),this.format=d,this.type=b,this.minFilter=this.magFilter=S,this.unpackAlignment=1,this.needsUpdate=!0}getData3DSlice(t,e){const{data:n,width:i,height:a,depth:o}=this.image;return dt({data:n,size:{x:i,y:a,z:o}},t,e,4)}getItem(t){return this.getColor(t)}getColor(t){const{data:e,width:n,height:i,depth:a}=this.image;return rt({data:e,size:{x:n,y:i,z:a}},t,4).value}}function Wt(t,e,n){const i=(null==n?void 0:n.reverseY)??!0,{data:a,width:o,height:r,depth:s,colorSpace:l}=pt(t,e,{...n,reverseY:i}),c=new Kt(a,o,r,s);return"srgb"===l&&(c.colorSpace="srgb"),c}function Yt(t,e){const n=e.gradient,i=Array.isArray(n)?W(n,256,1):et(n)?n:Y(n);let a=t;nt(t)&&(a={data:t.data,size:{x:t.width,y:t.height,z:t.depth}});const{data:o,size:r}=qt(a,i,e),s=Uint8ClampedArray.from(o);return new Kt(s,r.x,r.y,r.z)}class Xt extends g{constructor(t){const e=t??{},n=e.color??new C(1,1,1),i=e.solid??0,a=e.exp??1,o=e.opacity??1,r=e.side??N;super({glslVersion:x,uniforms:{color:{value:n},solid:{value:i},exp:{value:a},opacity:{value:o},isDoubleSide:{value:!1}},vertexShader:"out vec3 lookDir;\nout vec3 normalDir;\n\n#if defined( USE_COLOR_ALPHA ) || defined( USE_COLOR )\n out vec4 verColor;\n#endif\n\nvoid main() {\n vec3 cameraPos = vec3( inverse( modelMatrix ) * vec4( cameraPosition, 1.0 ) ).xyz;\n lookDir = position - cameraPos;\n normalDir = normal;\n\n #if defined( USE_COLOR_ALPHA )\n verColor = color;\n #elif defined( USE_INSTANCING_COLOR )\n overColor = vec3(instanceColor,1.0);\n #elif defined( USE_COLOR )\n overColor = vec3(color,1.0);\n #endif\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"uniform vec3 color;\nuniform float solid;\nuniform float exp;\n\nuniform float opacity;\nuniform bool isDoubleSide;\n\nin vec3 lookDir;\nin vec3 normalDir;\n\n#if defined( USE_COLOR_ALPHA ) || defined( USE_COLOR )\n in vec4 verColor;\n#endif\n\nout vec4 fragColor;\n\n\nvoid main(){\n #if defined( USE_COLOR_ALPHA ) || defined( USE_COLOR )\n fragColor = verColor;\n #else\n fragColor = vec4(color,1.0);\n #endif\n\n vec3 dir = normalize(lookDir);\n vec3 nor = normalize(normalDir);\n float depth = abs(dot(nor,dir));\n float dist = sqrt(1.0 - pow(depth,2.0));\n\n float finalAlpha = fragColor.a * depth;\n if (dist > solid) {\n float distAlpha = 1.0 - (dist - solid)/(1.0 - solid);\n finalAlpha *= pow(distAlpha,exp);\n }\n \n finalAlpha *= opacity;\n if ( finalAlpha == 0.0 ) discard;\n if (isDoubleSide){\n finalAlpha = 1.0 - sqrt(1.0 - finalAlpha);\n }\n fragColor.a = finalAlpha;\n}",side:N,transparent:!0}),Rt(this,"isSphereFogMaterial",!0),Rt(this,"_side",N),this.opacity=o,this.side=r}get side(){return this._side}set side(t){this._side=t,this.uniforms&&(this.uniforms.isDoubleSide.value=t===y,this.uniformsNeedUpdate=!0)}get color(){return this.uniforms.color.value}set color(t){this.uniforms.color.value.copy(t),this.uniformsNeedUpdate=!0}get opacity(){return this.uniforms.opacity.value}set opacity(t){this.uniforms&&(this.uniforms.opacity.value=t),this.uniformsNeedUpdate=!0}get solid(){return this.uniforms.solid.value}set solid(t){this.uniforms&&(this.uniforms.solid.value=t),this.uniformsNeedUpdate=!0}get exp(){return this.uniforms.exp.value}set exp(t){this.uniforms&&(this.uniforms.exp.value=t),this.uniformsNeedUpdate=!0}}class Zt extends g{constructor(t,e){const{solid:n=0,exp:i=1,useRadius:a=!0,sizeAttenuation:o=!0,star:r=!1,...s}=t??{},{uniforms:l,...c}=e||{},u={star:{value:r},solid:{value:n},exp:{value:i}};super({uniforms:U.merge([A.points.uniforms,u,l]),transparent:!0,depthTest:!1,defines:{useRadius:a},...c}),Rt(this,"isFogPointsMaterial",!0),Rt(this,"sizeAttenuation",!0),Object.assign(this,{...s,solid:n,exp:i,sizeAttenuation:o})}get map(){return this.uniforms.map.value}set map(t){this.uniforms.map.value=t,this.uniformsNeedUpdate=!0}get star(){return this.uniforms.star.value}set star(t){this.uniforms.star.value=t,this.uniformsNeedUpdate=!0}get size(){return this.uniforms.size.value}set size(t){this.uniforms.size.value=t,this.uniformsNeedUpdate=!0}get opacity(){return this.uniforms.opacity.value}set opacity(t){this.uniforms&&(this.uniforms.opacity.value=t),this.uniformsNeedUpdate=!0}get solid(){return this.uniforms.solid.value}set solid(t){this.uniforms&&(this.uniforms.solid.value=t),this.uniformsNeedUpdate=!0}get exp(){return this.uniforms.exp.value}set exp(t){this.uniforms&&(this.uniforms.exp.value=t),this.uniformsNeedUpdate=!0}get scale(){return this.uniforms.scale.value}set scale(t){this.uniforms&&(this.uniforms.scale.value=t),this.uniformsNeedUpdate=!0}get fogDensity(){return this.uniforms.fogDensity.value}set fogDensity(t){this.uniforms&&(this.uniforms.fogDensity.value=t),this.uniformsNeedUpdate=!0}get fogNear(){return this.uniforms.fogNear.value}set fogNear(t){this.uniforms&&(this.uniforms.fogNear.value=t),this.uniformsNeedUpdate=!0}get fogFar(){return this.uniforms.fogFar.value}set fogFar(t){this.uniforms&&(this.uniforms.fogFar.value=t),this.uniformsNeedUpdate=!0}get fogColor(){return this.uniforms.fogColor.value}set fogColor(t){this.uniforms.fogColor.value.copy(t),this.uniformsNeedUpdate=!0}}class Jt extends Zt{constructor(t){super(t,{vertexShader:"#ifdef useRadius\n\tattribute float radius;\n#endif\n\nuniform float size;\nuniform float scale;\n\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\n\n#ifdef USE_POINTS_UV\n\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n\n#endif\n\nvoid main() {\n\n\t#ifdef USE_POINTS_UV\n\n\t\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\n\t#endif\n\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\n\t#ifdef useRadius\n\t\tgl_PointSize = radius;\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\n\t#ifdef USE_SIZEATTENUATION\n\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\n\t#endif\n\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <fog_vertex>\n\n}",fragmentShader:"uniform float solid;\nuniform float exp;\nuniform bool star;\n\nuniform vec3 diffuse;\nuniform float opacity;\n\n#include <common>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\n\n\nvec4 getColor(vec4 originColor){\n\tfloat finalAlpha = originColor.a;\n\tfloat dist = 0.0;\n\tif (star){\n\t\tvec2 coord = abs(gl_PointCoord - vec2(0.5));\n\t\tdist = max(coord.x,coord.y);\n\t}else{\n\t\tdist = distance(gl_PointCoord,vec2(0.5));\n\t\tif (dist>0.5) discard;\n\t}\n\tdist /= 0.5;\n\tfloat depth = sqrt(1.0 - pow(dist,2.0));\n\tfinalAlpha *= depth;\n if (dist > solid) {\n float distAlpha = 1.0 - (dist - solid)/(1.0 - solid);\n finalAlpha *= pow(distAlpha,exp);\n }\n\toriginColor.a = finalAlpha;\n\treturn originColor;\n}\n\nvoid main() {\n\n\t#include <clipping_planes_fragment>\n\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\n\tdiffuseColor = getColor(diffuseColor);\n\toutgoingLight = diffuseColor.rgb;\n\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\n}"}),Rt(this,"isColorFogPointsMaterial",!0)}get color(){return this.uniforms.diffuse.value}set color(t){this.uniforms.diffuse.value.copy(t),this.uniformsNeedUpdate=!0}get alphaMap(){return this.uniforms.alphaMap.value}set alphaMap(t){this.uniforms&&(this.uniforms.alphaMap.value=t),this.uniformsNeedUpdate=!0}get uvTransform(){return this.uniforms.uvTransform.value}set uvTransform(t){this.uniforms&&this.uniforms.uvTransform.value.copy(t),this.uniformsNeedUpdate=!0}}function Qt(t){const e=new Jt(t),n=function(t){const{points:e,radius:n=10,color:i=[0,0,0,0]}=t,a=[],o=[],r=[];for(const{x:t,y:s,z:l,radius:c,color:u}of e){a.push(t,s,l),o.push(c??n);const e=u??i,d=e[3];e[3]=Math.trunc(255*d),r.push(...e)}const s=new E;return s.setAttribute("position",new G(a,3)),s.setAttribute("radius",new G(o,1)),s.setAttribute("color",new j(r,4,!0)),s}(t);return new P(n,e)}class $t extends Zt{constructor(t){const{range:e,...n}=t||{};super(n,{vertexShader:"attribute float value;\nuniform vec2 range;\nvarying float vValue;\n#ifdef useRadius\n\tattribute float radius;\n#endif\n\n\nuniform float size;\nuniform float scale;\n\n#include <common>\n// #include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\n\n#ifdef USE_POINTS_UV\n\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n\n#endif\n\nvoid main() {\n\tvValue = (value - range.x)/(range.y - range.x);\n\n\t#ifdef USE_POINTS_UV\n\n\t\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\n\t#endif\n\n\t// #include <color_vertex>\n\t// #include <morphcolor_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\n\t#ifdef useRadius\n\t\tgl_PointSize = radius;\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\n\t#ifdef USE_SIZEATTENUATION\n\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\n\t#endif\n\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <fog_vertex>\n\n}",fragmentShader:"varying float vValue;\nuniform sampler2D map;\n\n\nuniform float solid;\nuniform float exp;\nuniform bool star;\n\n// uniform vec3 diffuse;\nuniform float opacity;\n\n#include <common>\n// #include <color_pars_fragment>\n// #include <map_particle_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\n\n\n// 获取梯度颜色\nvec4 getGradientColor(float val) {\n\tval = clamp( val, 0.0,1.0);\n return texture2D(map, vec2(val, 0.5));\n}\n\n\nvec4 getColor(){\n\tfloat val = vValue;\n\tfloat dist = 0.0;\n\tif (star){\n\t\tvec2 coord = abs(gl_PointCoord - vec2(0.5));\n\t\tdist = max(coord.x,coord.y);\n\t}else{\n\t\tdist = distance(gl_PointCoord,vec2(0.5));\n\t\tif (dist>0.5) discard;\n\t}\n\tdist /= 0.5;\n\tfloat depth = sqrt(1.0 - pow(dist,2.0));\n if (dist > solid) {\n float solidDist = 1.0 - (dist - solid)/(1.0 - solid);\n val *= pow(solidDist,exp);\n }\n\tvec4 valColor = getGradientColor(val);\n\tvalColor.a *= depth * opacity;\n\treturn valColor;\n}\n\nvoid main() {\n\n\t#include <clipping_planes_fragment>\n\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = getColor();\n\n\t#include <logdepthbuf_fragment>\n\t// #include <map_particle_fragment>\n\t// #include <color_fragment>\n\t#include <alphatest_fragment>\n\n\toutgoingLight = diffuseColor.rgb;\n\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\n}",uniforms:{range:{value:(new o).copy(e??{x:0,y:100})}}}),Rt(this,"isColorFogPointsMaterial",!0)}get range(){return this.uniforms.range.value}set range(t){this.uniforms.range.value.copy(t),this.uniformsNeedUpdate=!0}}function te(t){const e=t.gradient,n=null==e?e:Ct(e),i=new $t({...t,map:n}),a=function(t){const{points:e,radius:n=10,value:i=100}=t,a=[],o=[],r=[];for(const{x:t,y:s,z:l,radius:c,value:u}of e)a.push(t,s,l),o.push(c??n),r.push(u??i);const s=new E;return s.setAttribute("position",new G(a,3)),s.setAttribute("radius",new G(o,1)),s.setAttribute("value",new G(r,1)),s}(t);return new P(a,i)}class ee extends g{constructor(t){const e=t??{};let{map:n,opacity:i,axis:a,depth:o,side:r,...s}=e;i=i??1,a=a??k.z,o=o??0,r=r??y,super({...s,glslVersion:x,uniforms:{map:{value:n},opacity:{value:i},axis:{value:a},depth:{value:o}},transparent:!0,vertexShader:"\tout vec2 vUv;\n \n\tvoid main() {\n\t\tvUv = uv;\n\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\t}",fragmentShader:"precision highp float;\nprecision highp sampler3D;\n\nuniform sampler3D map;\n\nuniform float opacity;\nuniform int axis;\nuniform float depth;\n\nin vec2 vUv;\nout vec4 fragColor;\n\nvoid main(){\n vec3 uv3 = vec3(0.0);\n int depthSize = textureSize(map,0)[axis];\n uv3[axis] = depth/float(depthSize);\n int xIndex = (axis + 1)%3;\n int yIndex = (axis + 2)%3;\n uv3[xIndex] = vUv.x;\n uv3[yIndex] = vUv.y;\n\n fragColor = texture(map, uv3);\n fragColor.a *= opacity;\n}",side:r}),Rt(this,"isSliceMaterial",!0),Rt(this,"_sliceSize",null),this.opacity=i}get map(){return this.uniforms.map.value}set map(t){this.uniforms.map.value=t,this._sliceSize=null,this.uniformsNeedUpdate=!0}get opacity(){return this.uniforms.opacity.value}set opacity(t){this.uniforms&&(this.uniforms.opacity.value=t),this.uniformsNeedUpdate=!0}get axis(){return this.uniforms.axis.value}set axis(t){this.uniforms.axis.value=t,this._sliceSize=null,this.uniformsNeedUpdate=!0}get depth(){return this.uniforms.depth.value}set depth(t){this.uniforms.depth.value=t,this.uniformsNeedUpdate=!0}get sliceSize(){let t=this._sliceSize;if(!t){this._sliceSize=t=new o(1,1);const{axis:e,map:n}=this;if(n){const{width:i,height:a,depth:o}=n.image,[r,s]=k.getCrossAxiss(e),l=[i,a,o];t.set(l[r],l[s])}}return t}}class ne extends w{constructor(t){const e=new ee(t),n=new O;super(n,e),Rt(this,"isSliceMesh",!0),Rt(this,"_geometry"),Rt(this,"_material"),Rt(this,"autoUpdateGeometry",!0),Object.defineProperties(this,{geometry:{get:()=>this._geometry,set:t=>{this._geometry=t,this.autoUpdateGeometry&&this.updateGeometry()}},material:{get:()=>this._material,set:t=>{this._material=t,this.autoUpdateGeometry&&this.updateGeometry()}}}),this.geometry=n,this.material=e}updateGeometry(){var t;const{geometry:e,material:n}=this;if(!n||!(null==(t=n.map)?void 0:t.image))return!1;e.boundingBox||e.computeBoundingBox();const i=n.sliceSize,o=e.boundingBox.getSize(new a);e.scale(i.x/o.x,i.y/o.y,1)}get map(){return this.material.map}set map(t){this.material.map=t,this.material=this.material}get axis(){return this.material.axis}set axis(t){this.material.axis=t,this.material=this.material}get depth(){return this.material.depth}set depth(t){this.material.depth=t}get sliceSize(){return this.material.sliceSize}}class ie extends Mt{constructor(t){super(nt(t)?t:t.image),Rt(this,"isImageData3DTextureSlice",!0)}set texture(t){this.image3D=nt(t)?t:t.image}}function ae({ratio:t,value:e}){return e-e*t}function oe(t,e){const{x:n,y:i}=e;let a=0;for(const{value:e,clim:{x:n,y:i}}of t)a+=(e-n)/(i-n);return a*(i-n)+n}function re(t,e,n){const{size:i,data3D:o,tags:r}=e,{clim:s,radius:l,value:c,hollow:u,valueGradient:d,valuesAccumulate:m}=t,p=(new a).copy(t),f=[],h=[],v={particles:f,values:h},g=l*u,x=p.clone().subScalar(l),_=p.clone().addScalar(l);x.max(new a(0,0,0));const y=(new a).copy(i).subScalar(1);_.min(y);let{x:w,y:M,z:z}=x;w=Math.trunc(w),M=Math.trunc(M),z=Math.trunc(z);let{x:D,y:S,z:b}=_;if(D=Math.trunc(D),S=Math.trunc(S),b=Math.trunc(b),w>D||M>S||z>b)return v;const{x:C,y:N}=i,U=C*N;for(let e=z;e<=b;e++){const i=e*U;for(let v=M;v<=S;v++){const x=i+v*C;t:for(let i=w;i<=D;i++){const _=x+i;if(r[_])continue;const y=new a(i,v,e),w=y.distanceTo(p);if(w>l||w<g)continue;r[_]=!0;const M=[],z={...{radius:l,hollow:u,hollowRadius:g,distance:w,clim:s,value:c},ratio:w/l,distance:w,point:y},D=d(z);M.push({...t,...z,value:D});for(const t of n){const e=y.distanceTo(t),{hollow:n,radius:i}=t;if(e<=i){const a=i*n;if(e<a)continue t;const o={...t,ratio:e/i,distance:e,hollowRadius:a,point:y},r=d(o);M.push({...o,value:r})}}const S=m(M,s);o[_]=S,f.push(y),h.push(S)}}}return v}function se(t){const{points:e,clim:n={x:0,y:100},radius:i=10,value:a=100,hollow:o=0,valueGradient:r=ae,valuesAccumulate:s=oe,size:l}=t,c={clim:n,radius:i,value:a,hollow:o,valueGradient:r,valuesAccumulate:s},u=e.map(t=>({...c,...t}));let d=l;l||(d=(new I).setFromPoints(u).max.addScalar(1));const m=St(u);let{x:p,y:f,z:h}=d;p=d.x=Math.trunc(p),f=d.y=Math.trunc(f),h=d.z=Math.trunc(h);const v=new Array(p*f*h),g={size:d,data3D:v,tags:new Array(p*f*h)},x=u.length;for(let t=0;t<x;t++){re(u[t],g,m[t].map(t=>u[t]))}return{data:v,size:d}}function le({startRadius:t,addedRadius:e,ratio:n}){return e*n+t}function ce({startHollow:t,addedHollow:e,ratio:n}){return e*n+t}function ue({startValue:t,addedValue:e,ratio:n}){return e*n+t}function de(t,e){const{x:n,y:i}=e;return t.reduce((t,e)=>t+e-n,0)}function me(t){const{points:e,size:n,clim:i={x:0,y:100},radius:o=10,value:r=100,hollow:s=0,valueGradient:l=ae,radiusGradient:c=le,hollowGradient:u=ce,lineValueGradient:d=ue,valuesAccumulate:m=de}=t,p={radius:o,value:r,hollow:s},f=e.map(function(t){return Object.assign(new a,p,t)}),h=n?(new a).copy(n).subScalar(1):(new I).setFromPoints(f).max;h.x=Math.trunc(h.x),h.y=Math.trunc(h.y),h.z=Math.trunc(h.z);const v=h.clone().addScalar(1),{x:g,y:x,z:y}=v,w=g*x,M=new Array(w*y),z=[],D=[],S={particles:z,values:D,size:v,data:M},b=new a(0,0,0),C=e.length,N=Math.trunc(C/2);for(let t=0;t<N;t++){const e=2*t,n=f[e],p=f[e+1],v=new T(n,p),x=v.distance(),y=v.delta(new a).normalize(),C=new F;C.setFromUnitVectors(new a(0,1,0),y);const N=(new _).makeRotationFromQuaternion(C);N.setPosition(n);const{radius:U,value:A,hollow:P}=n,{radius:O,value:R,hollow:V}=p,E={length:x,startRadius:U,endRadius:O,addedRadius:O-U,defaultRadius:o,radius:o,startValue:A,endValue:R,addedValue:R-A,defaultValue:r,startHollow:P,endHollow:V,addedHollow:V-P,defaultHollow:s,clim:i},G=Math.max(U,O),j=new a(-G,0,-G),L=new a(G,x,G),B=new I(j,L);B.applyMatrix4(N);const{min:k,max:H}=B;k.max(b),H.min(h);let{x:q,y:K,z:W}=k;q=Math.trunc(q),K=Math.trunc(K),W=Math.trunc(W);let{x:Y,y:X,z:Z}=H;if(Y=Math.trunc(Y),X=Math.trunc(X),Z=Math.trunc(Z),q>Y||K>X||W>Z)return S;N.invert();for(let t=W;t<=Z;t++){const e=t*w;for(let n=K;n<=X;n++){const o=e+n*g;for(let e=q;e<=Y;e++){const r=o+e,s=new a(e,n,t),p=s.clone();p.applyMatrix4(N);const{x:f,y:h,z:v}=p;if(h<0||h>x)continue;const g=Math.hypot(f,v),_={...E,ratio:h/x,point:s},y=c(_);_.radius=y;const w=u(_),S=y*w;if(g>y||g<S)continue;const b=d(_);let C=l({...E,value:b,ratio:g/y,radius:y,hollow:w,hollowRadius:S,distance:g,point:s});const U=D[r];void 0!==U&&(C=m([U,C],i)),M[r]=C,z.push(s),D.push(C)}}}}return S}function pe(t,e){const i=(new a).setFromMatrixScale(e),o=Math.sqrt(i.lengthSq()/3),r=(new n).setFromMatrix4(e);let{points:s,size:l,radius:c,...u}=t;if(l&&(l=(new a).copy(l).applyMatrix3(r)),c&&(c*=o),s){const t=[];for(let{x:n,y:i,z:r,radius:l,...c}of s){l&&(l*=o);const s=new a(n,i,r).applyMatrix4(e);Object.assign(s,c,{radius:l}),t.push(s)}s=t}return{points:s,size:l,radius:c,...u}}function fe(t,e,n=1){let{points:i,size:o,radius:r,...s}=t;if(r&&(r*=n),i){const t=[];for(let{x:o,y:r,z:s,radius:l,...c}of i){l&&(l*=n);const i=new a(o,r,s).add(e).multiplyScalar(n);Object.assign(i,c,{radius:l}),t.push(i)}i=t}return o&&(o=(new a).copy(o).add(e).multiplyScalar(n)),{points:i,size:o,radius:r,...s}}function he(t,e){const{points:n,radius:i}=t;if(!n)return{options:t,position:new a,scale:1};const o=new I;for(const t of n){const e=(new a).copy(t),n=t.radius??i;n?(o.expandByPoint(e.clone().subScalar(n)),o.expandByPoint(e.addScalar(n))):o.expandByPoint(e)}const r=(new a).max(o.min),s=o.max.clone().sub(r).addScalar(1);t.size&&s.min(t.size);let{scale:l,maxSize:c}=e||{};l||(c=c??100,l=c/Math.max(s.x,s.y,s.z)),s.multiplyScalar(l);const u=fe(t,r.clone().negate(),l);return u.size=s,{options:u,position:r,scale:1/l}}const ve={uniforms:{u_size:{value:new a(1,1,1)},u_renderstyle:{value:0},u_renderthreshold:{value:.5},u_clim:{value:new o(1,1)},u_data:{value:null},u_cmdata:{value:null}},vertexShader:'\n\n\t\tvarying vec4 v_nearpos;\n\t\tvarying vec4 v_farpos;\n\t\tvarying vec3 v_position;\n\n\t\tvoid main() {\n\t\t\t\t// Prepare transforms to map to "camera view". See also:\n\t\t\t\t// https://threejs.org/docs/#api/renderers/webgl/WebGLProgram\n\t\t\t\tmat4 viewtransformf = modelViewMatrix;\n\t\t\t\tmat4 viewtransformi = inverse(modelViewMatrix);\n\n\t\t\t\t// Project local vertex coordinate to camera position. Then do a step\n\t\t\t\t// backward (in cam coords) to the near clipping plane, and project back. Do\n\t\t\t\t// the same for the far clipping plane. This gives us all the information we\n\t\t\t\t// need to calculate the ray and truncate it to the viewing cone.\n\t\t\t\tvec4 position4 = vec4(position, 1.0);\n\t\t\t\tvec4 pos_in_cam = viewtransformf * position4;\n\n\t\t\t\t// Intersection of ray and near clipping plane (z = -1 in clip coords)\n\t\t\t\tpos_in_cam.z = -pos_in_cam.w;\n\t\t\t\tv_nearpos = viewtransformi * pos_in_cam;\n\n\t\t\t\t// Intersection of ray and far clipping plane (z = +1 in clip coords)\n\t\t\t\tpos_in_cam.z = pos_in_cam.w;\n\t\t\t\tv_farpos = viewtransformi * pos_in_cam;\n\n\t\t\t\t// Set varyings and output pos\n\t\t\t\tv_position = position;\n\t\t\t\tgl_Position = projectionMatrix * viewMatrix * modelMatrix * position4;\n\t\t}',fragmentShader:"\n\n\t\t\t\tprecision highp float;\n\t\t\t\tprecision mediump sampler3D;\n\n\t\t\t\tuniform vec3 u_size;\n\t\t\t\tuniform int u_renderstyle;\n\t\t\t\tuniform float u_renderthreshold;\n\t\t\t\tuniform vec2 u_clim;\n\n\t\t\t\tuniform sampler3D u_data;\n\t\t\t\tuniform sampler2D u_cmdata;\n\n\t\t\t\tvarying vec3 v_position;\n\t\t\t\tvarying vec4 v_nearpos;\n\t\t\t\tvarying vec4 v_farpos;\n\n\t\t\t\t// The maximum distance through our rendering volume is sqrt(3).\n\t\t\t\tconst int MAX_STEPS = 887;\t// 887 for 512^3, 1774 for 1024^3\n\t\t\t\tconst int REFINEMENT_STEPS = 4;\n\t\t\t\tconst float relative_step_size = 1.0;\n\t\t\t\tconst vec4 ambient_color = vec4(0.2, 0.4, 0.2, 1.0);\n\t\t\t\tconst vec4 diffuse_color = vec4(0.8, 0.2, 0.2, 1.0);\n\t\t\t\tconst vec4 specular_color = vec4(1.0, 1.0, 1.0, 1.0);\n\t\t\t\tconst float shininess = 40.0;\n\n\t\t\t\tvoid cast_mip(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray);\n\t\t\t\tvoid cast_iso(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray);\n\n\t\t\t\tfloat sample1(vec3 texcoords);\n\t\t\t\tvec4 apply_colormap(float val);\n\t\t\t\tvec4 add_lighting(float val, vec3 loc, vec3 step, vec3 view_ray);\n\n\n\t\t\t\tvoid main() {\n\t\t\t\t\t\t// Normalize clipping plane info\n\t\t\t\t\t\tvec3 farpos = v_farpos.xyz / v_farpos.w;\n\t\t\t\t\t\tvec3 nearpos = v_nearpos.xyz / v_nearpos.w;\n\n\t\t\t\t\t\t// Calculate unit vector pointing in the view direction through this fragment.\n\t\t\t\t\t\tvec3 view_ray = normalize(nearpos.xyz - farpos.xyz);\n\n\t\t\t\t\t\t// Compute the (negative) distance to the front surface or near clipping plane.\n\t\t\t\t\t\t// v_position is the back face of the cuboid, so the initial distance calculated in the dot\n\t\t\t\t\t\t// product below is the distance from near clip plane to the back of the cuboid\n\t\t\t\t\t\tfloat distance = dot(nearpos - v_position, view_ray);\n\t\t\t\t\t\tdistance = max(distance, min((-0.5 - v_position.x) / view_ray.x,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(u_size.x - 0.5 - v_position.x) / view_ray.x));\n\t\t\t\t\t\tdistance = max(distance, min((-0.5 - v_position.y) / view_ray.y,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(u_size.y - 0.5 - v_position.y) / view_ray.y));\n\t\t\t\t\t\tdistance = max(distance, min((-0.5 - v_position.z) / view_ray.z,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(u_size.z - 0.5 - v_position.z) / view_ray.z));\n\n\t\t\t\t\t\t// Now we have the starting position on the front surface\n\t\t\t\t\t\tvec3 front = v_position + view_ray * distance;\n\n\t\t\t\t\t\t// Decide how many steps to take\n\t\t\t\t\t\tint nsteps = int(-distance / relative_step_size + 0.5);\n\t\t\t\t\t\tif ( nsteps < 1 )\n\t\t\t\t\t\t\t\tdiscard;\n\n\t\t\t\t\t\t// Get starting location and step vector in texture coordinates\n\t\t\t\t\t\tvec3 step = ((v_position - front) / u_size) / float(nsteps);\n\t\t\t\t\t\tvec3 start_loc = front / u_size;\n\n\t\t\t\t\t\t// For testing: show the number of steps. This helps to establish\n\t\t\t\t\t\t// whether the rays are correctly oriented\n\t\t\t\t\t\t//'gl_FragColor = vec4(0.0, float(nsteps) / 1.0 / u_size.x, 1.0, 1.0);\n\t\t\t\t\t\t//'return;\n\n\t\t\t\t\t\tif (u_renderstyle == 0)\n\t\t\t\t\t\t\t\tcast_mip(start_loc, step, nsteps, view_ray);\n\t\t\t\t\t\telse if (u_renderstyle == 1)\n\t\t\t\t\t\t\t\tcast_iso(start_loc, step, nsteps, view_ray);\n\n\t\t\t\t\t\tif (gl_FragColor.a < 0.05)\n\t\t\t\t\t\t\t\tdiscard;\n\t\t\t\t}\n\n\n\t\t\t\tfloat sample1(vec3 texcoords) {\n\t\t\t\t\t\t/* Sample float value from a 3D texture. Assumes intensity data. */\n\t\t\t\t\t\treturn texture(u_data, texcoords.xyz).r;\n\t\t\t\t}\n\n\n\t\t\t\tvec4 apply_colormap(float val) {\n\t\t\t\t\t\tval = (val - u_clim[0]) / (u_clim[1] - u_clim[0]);\n\t\t\t\t\t\treturn texture2D(u_cmdata, vec2(val, 0.5));\n\t\t\t\t}\n\n\n\t\t\t\tvoid cast_mip(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray) {\n\n\t\t\t\t\t\tfloat max_val = -1e6;\n\t\t\t\t\t\tint max_i = 100;\n\t\t\t\t\t\tvec3 loc = start_loc;\n\n\t\t\t\t\t\t// Enter the raycasting loop. In WebGL 1 the loop index cannot be compared with\n\t\t\t\t\t\t// non-constant expression. So we use a hard-coded max, and an additional condition\n\t\t\t\t\t\t// inside the loop.\n\t\t\t\t\t\tfor (int iter=0; iter<MAX_STEPS; iter++) {\n\t\t\t\t\t\t\t\tif (iter >= nsteps)\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t// Sample from the 3D texture\n\t\t\t\t\t\t\t\tfloat val = sample1(loc);\n\t\t\t\t\t\t\t\t// Apply MIP operation\n\t\t\t\t\t\t\t\tif (val > max_val) {\n\t\t\t\t\t\t\t\t\t\tmax_val = val;\n\t\t\t\t\t\t\t\t\t\tmax_i = iter;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Advance location deeper into the volume\n\t\t\t\t\t\t\t\tloc += step;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Refine location, gives crispier images\n\t\t\t\t\t\tvec3 iloc = start_loc + step * (float(max_i) - 0.5);\n\t\t\t\t\t\tvec3 istep = step / float(REFINEMENT_STEPS);\n\t\t\t\t\t\tfor (int i=0; i<REFINEMENT_STEPS; i++) {\n\t\t\t\t\t\t\t\tmax_val = max(max_val, sample1(iloc));\n\t\t\t\t\t\t\t\tiloc += istep;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Resolve final color\n\t\t\t\t\t\tgl_FragColor = apply_colormap(max_val);\n\t\t\t\t}\n\n\n\t\t\t\tvoid cast_iso(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray) {\n\n\t\t\t\t\t\tgl_FragColor = vec4(0.0);\t// init transparent\n\t\t\t\t\t\tvec4 color3 = vec4(0.0);\t// final color\n\t\t\t\t\t\tvec3 dstep = 1.5 / u_size;\t// step to sample derivative\n\t\t\t\t\t\tvec3 loc = start_loc;\n\n\t\t\t\t\t\tfloat low_threshold = u_renderthreshold - 0.02 * (u_clim[1] - u_clim[0]);\n\n\t\t\t\t\t\t// Enter the raycasting loop. In WebGL 1 the loop index cannot be compared with\n\t\t\t\t\t\t// non-constant expression. So we use a hard-coded max, and an additional condition\n\t\t\t\t\t\t// inside the loop.\n\t\t\t\t\t\tfor (int iter=0; iter<MAX_STEPS; iter++) {\n\t\t\t\t\t\t\t\tif (iter >= nsteps)\n\t\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\t// Sample from the 3D texture\n\t\t\t\t\t\t\t\tfloat val = sample1(loc);\n\n\t\t\t\t\t\t\t\tif (val > low_threshold) {\n\t\t\t\t\t\t\t\t\t\t// Take the last interval in smaller steps\n\t\t\t\t\t\t\t\t\t\tvec3 iloc = loc - 0.5 * step;\n\t\t\t\t\t\t\t\t\t\tvec3 istep = step / float(REFINEMENT_STEPS);\n\t\t\t\t\t\t\t\t\t\tfor (int i=0; i<REFINEMENT_STEPS; i++) {\n\t\t\t\t\t\t\t\t\t\t\t\tval = sample1(iloc);\n\t\t\t\t\t\t\t\t\t\t\t\tif (val > u_renderthreshold) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tgl_FragColor = add_lighting(val, iloc, dstep, view_ray);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tiloc += istep;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Advance location deeper into the volume\n\t\t\t\t\t\t\t\tloc += step;\n\t\t\t\t\t\t}\n\t\t\t\t}\n\n\n\t\t\t\tvec4 add_lighting(float val, vec3 loc, vec3 step, vec3 view_ray)\n\t\t\t\t{\n\t\t\t\t\t// Calculate color by incorporating lighting\n\n\t\t\t\t\t\t// View direction\n\t\t\t\t\t\tvec3 V = normalize(view_ray);\n\n\t\t\t\t\t\t// calculate normal vector from gradient\n\t\t\t\t\t\tvec3 N;\n\t\t\t\t\t\tfloat val1, val2;\n\t\t\t\t\t\tval1 = sample1(loc + vec3(-step[0], 0.0, 0.0));\n\t\t\t\t\t\tval2 = sample1(loc + vec3(+step[0], 0.0, 0.0));\n\t\t\t\t\t\tN[0] = val1 - val2;\n\t\t\t\t\t\tval = max(max(val1, val2), val);\n\t\t\t\t\t\tval1 = sample1(loc + vec3(0.0, -step[1], 0.0));\n\t\t\t\t\t\tval2 = sample1(loc + vec3(0.0, +step[1], 0.0));\n\t\t\t\t\t\tN[1] = val1 - val2;\n\t\t\t\t\t\tval = max(max(val1, val2), val);\n\t\t\t\t\t\tval1 = sample1(loc + vec3(0.0, 0.0, -step[2]));\n\t\t\t\t\t\tval2 = sample1(loc + vec3(0.0, 0.0, +step[2]));\n\t\t\t\t\t\tN[2] = val1 - val2;\n\t\t\t\t\t\tval = max(max(val1, val2), val);\n\n\t\t\t\t\t\tfloat gm = length(N); // gradient magnitude\n\t\t\t\t\t\tN = normalize(N);\n\n\t\t\t\t\t\t// Flip normal so it points towards viewer\n\t\t\t\t\t\tfloat Nselect = float(dot(N, V) > 0.0);\n\t\t\t\t\t\tN = (2.0 * Nselect - 1.0) * N;\t// ==\tNselect * N - (1.0-Nselect)*N;\n\n\t\t\t\t\t\t// Init colors\n\t\t\t\t\t\tvec4 ambient_color = vec4(0.0, 0.0, 0.0, 0.0);\n\t\t\t\t\t\tvec4 diffuse_color = vec4(0.0, 0.0, 0.0, 0.0);\n\t\t\t\t\t\tvec4 specular_color = vec4(0.0, 0.0, 0.0, 0.0);\n\n\t\t\t\t\t\t// note: could allow multiple lights\n\t\t\t\t\t\tfor (int i=0; i<1; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t // Get light direction (make sure to prevent zero devision)\n\t\t\t\t\t\t\t\tvec3 L = normalize(view_ray);\t//lightDirs[i];\n\t\t\t\t\t\t\t\tfloat lightEnabled = float( length(L) > 0.0 );\n\t\t\t\t\t\t\t\tL = normalize(L + (1.0 - lightEnabled));\n\n\t\t\t\t\t\t\t\t// Calculate lighting properties\n\t\t\t\t\t\t\t\tfloat lambertTerm = clamp(dot(N, L), 0.0, 1.0);\n\t\t\t\t\t\t\t\tvec3 H = normalize(L+V); // Halfway vector\n\t\t\t\t\t\t\t\tfloat specularTerm = pow(max(dot(H, N), 0.0), shininess);\n\n\t\t\t\t\t\t\t\t// Calculate mask\n\t\t\t\t\t\t\t\tfloat mask1 = lightEnabled;\n\n\t\t\t\t\t\t\t\t// Calculate colors\n\t\t\t\t\t\t\t\tambient_color +=\tmask1 * ambient_color;\t// * gl_LightSource[i].ambient;\n\t\t\t\t\t\t\t\tdiffuse_color +=\tmask1 * lambertTerm;\n\t\t\t\t\t\t\t\tspecular_color += mask1 * specularTerm * specular_color;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Calculate final color by componing different components\n\t\t\t\t\t\tvec4 final_color;\n\t\t\t\t\t\tvec4 color = apply_colormap(val);\n\t\t\t\t\t\tfinal_color = color * (ambient_color + diffuse_color) + specular_color;\n\t\t\t\t\t\tfinal_color.a = color.a;\n\t\t\t\t\t\treturn final_color;\n\t\t\t\t}"};var ge=(t=>(t[t.MIP=0]="MIP",t[t.ISO=1]="ISO",t))(ge||{});class xe extends g{constructor(t){const{style:e,threshold:n,clim:i,map:r,gradient:s}=t??{},l=new a(1,1,1);if(r){const{width:t,height:e,depth:n}=r.image;l.set(t,e,n)}const c=null==s?s:Ct(s),u=U.clone(ve.uniforms);u.u_size.value.copy(l),u.u_clim.value.copy(i??new o(1,1)),u.u_renderstyle.value=e??1,u.u_renderthreshold.value=n??.5,u.u_data.value=r??null,u.u_cmdata.value=c??null,super({...ve,uniforms:u,side:R}),Rt(this,"isExampleVolumeMaterial_1",!0),Rt(this,"_gradient")}get map(){return this.uniforms.u_data.value}set map(t){this.uniforms.u_data.value=t,this.uniformsNeedUpdate=!0}get gradientMap(){return this.uniforms.u_cmdata.value}get gradient(){return this._gradient}set gradient(t){this._gradient=t;const e=null==t?t:Ct(t);this.uniforms.u_cmdata.value=e??null,this.uniformsNeedUpdate=!0}get size(){return this.uniforms.u_size.value}set size(t){this.uniforms.u_size.value.copy(t),this.uniformsNeedUpdate=!0}get style(){return this.uniforms.u_renderstyle.value}set style(t){this.uniforms.u_renderstyle.value=t,this.uniformsNeedUpdate=!0}get clim(){return this.uniforms.u_clim.value}set clim(t){this.uniforms.u_clim.value=t,this.uniformsNeedUpdate=!0}get threshold(){return this.uniforms.u_renderthreshold.value}set threshold(t){this.uniforms.u_renderthreshold.value=t,this.uniformsNeedUpdate=!0}}const _e="in vec3 position;\n\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform vec3 cameraPos;\n\nout vec3 vOrigin;\nout vec3 vDirection;\n\nvoid main() {\n vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n vOrigin = vec3( inverse( modelMatrix ) * vec4( cameraPos, 1.0 ) ).xyz;\n vDirection = position - vOrigin;\n gl_Position = projectionMatrix * mvPosition;\n}";class ye extends V{constructor(t){let{color:e,threshold:n,map:i,opacity:o,range:r,steps:s,frame:l,cameraPos:c}=t??{};e=e??new C(1,1,1),n=n??.25,o=o??.25,r=r??.1,s=s??100,l=l??100,c=c??new a,super({glslVersion:x,uniforms:{base:{value:e},map:{value:i},cameraPos:{value:c},threshold:{value:n},opacity:{value:o},range:{value:r},steps:{value:s},frame:{value:l}},vertexShader:_e,fragmentShader:"precision highp float;\nprecision highp sampler3D;\n\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\n\nin vec3 vOrigin;\nin vec3 vDirection;\n\nout vec4 color;\n\nuniform vec3 base;\nuniform sampler3D map;\n\nuniform float threshold;\nuniform float range;\nuniform float opacity;\nuniform float steps;\nuniform float frame;\n\nuint wang_hash(uint seed)\n{\n seed = (seed ^ 61u) ^ (seed >> 16u);\n seed *= 9u;\n seed = seed ^ (seed >> 4u);\n seed *= 0x27d4eb2du;\n seed = seed ^ (seed >> 15u);\n return seed;\n}\n\nfloat randomFloat(inout uint seed)\n{\n return float(wang_hash(seed)) / 4294967296.;\n}\n\nvec2 hitBox( vec3 orig, vec3 dir ) {\n const vec3 box_min = vec3( - 0.5 );\n const vec3 box_max = vec3( 0.5 );\n vec3 inv_dir = 1.0 / dir;\n vec3 tmin_tmp = ( box_min - orig ) * inv_dir;\n vec3 tmax_tmp = ( box_max - orig ) * inv_dir;\n vec3 tmin = min( tmin_tmp, tmax_tmp );\n vec3 tmax = max( tmin_tmp, tmax_tmp );\n float t0 = max( tmin.x, max( tmin.y, tmin.z ) );\n float t1 = min( tmax.x, min( tmax.y, tmax.z ) );\n return vec2( t0, t1 );\n}\n\nfloat sample1( vec3 p ) {\n return texture( map, p ).r;\n}\n\nfloat shading( vec3 coord ) {\n float step = 0.01;\n return sample1( coord + vec3( - step ) ) - sample1( coord + vec3( step ) );\n}\n\nvoid main(){\n vec3 rayDir = normalize( vDirection );\n vec2 bounds = hitBox( vOrigin, rayDir );\n\n if ( bounds.x > bounds.y ) discard;\n\n bounds.x = max( bounds.x, 0.0 );\n\n vec3 p = vOrigin + bounds.x * rayDir;\n vec3 inc = 1.0 / abs( rayDir );\n float delta = min( inc.x, min( inc.y, inc.z ) );\n delta /= steps;\n\n // Jitter\n\n // Nice little seed from\n // https://blog.demofox.org/2020/05/25/casual-shadertoy-path-tracing-1-basic-camera-diffuse-emissive/\n uint seed = uint( gl_FragCoord.x ) * uint( 1973 ) + uint( gl_FragCoord.y ) * uint( 9277 ) + uint( frame ) * uint( 26699 );\n vec3 size = vec3( textureSize( map, 0 ) );\n float randNum = randomFloat( seed ) * 2.0 - 1.0;\n p += rayDir * randNum * ( 1.0 / size );\n\n //\n\n vec4 ac = vec4( base, 0.0 );\n\n for ( float t = bounds.x; t < bounds.y; t += delta ) {\n\n float d = sample1( p + 0.5 );\n\n d = smoothstep( threshold - range, threshold + range, d ) * opacity;\n\n float col = shading( p + 0.5 ) * 3.0 + ( ( p.x + p.y ) * 0.25 ) + 0.2;\n\n ac.rgb += ( 1.0 - ac.a ) * d * col;\n\n ac.a += ( 1.0 - ac.a ) * d;\n\n if ( ac.a >= 0.95 ) break;\n\n p += rayDir * delta;\n\n }\n\n color = ac;\n\n if ( color.a == 0.0 ) discard;\n\n}",side:R,transparent:!0}),Rt(this,"isExampleVolumeMaterial_Cloud",!0),this.opacity=o}get map(){return this.uniforms.map.value}set map(t){this.uniforms.map.value=t,this.uniformsNeedUpdate=!0}get color(){return this.uniforms.base.value}set color(t){this.uniforms.base.value=t,this.uniformsNeedUpdate=!0}get opacity(){return this.uniforms.opacity.value}set opacity(t){this.uniforms&&(this.uniforms.opacity.value=t),this.uniformsNeedUpdate=!0}get threshold(){return this.uniforms.threshold.value}set threshold(t){this.uniforms.threshold.value=t,this.uniformsNeedUpdate=!0}get range(){return this.uniforms.range.value}set range(t){this.uniforms.range.value=t,this.uniformsNeedUpdate=!0}get steps(){return this.uniforms.steps.value}set steps(t){this.uniforms.steps.value=t,this.uniformsNeedUpdate=!0}get frame(){return this.uniforms.frame.value}set frame(t){this.uniforms.frame.value=t,this.uniformsNeedUpdate=!0}get cameraPos(){return this.uniforms.cameraPos.value}set cameraPos(t){this.uniforms.cameraPos.value.copy(t),this.uniformsNeedUpdate=!0}}class we extends V{constructor(t){let{threshold:e,map:n,steps:i,cameraPos:o}=t??{};e=e??.25,i=i??100,o=o??new a,super({glslVersion:x,uniforms:{map:{value:n},cameraPos:{value:o},threshold:{value:e},steps:{value:i}},vertexShader:_e,fragmentShader:"precision highp float;\nprecision highp sampler3D;\n\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\n\nin vec3 vOrigin;\nin vec3 vDirection;\n\nout vec4 color;\n\nuniform sampler3D map;\n\nuniform float threshold;\nuniform float steps;\n\nvec2 hitBox( vec3 orig, vec3 dir ) {\n const vec3 box_min = vec3( - 0.5 );\n const vec3 box_max = vec3( 0.5 );\n vec3 inv_dir = 1.0 / dir;\n vec3 tmin_tmp = ( box_min - orig ) * inv_dir;\n vec3 tmax_tmp = ( box_max - orig ) * inv_dir;\n vec3 tmin = min( tmin_tmp, tmax_tmp );\n vec3 tmax = max( tmin_tmp, tmax_tmp );\n float t0 = max( tmin.x, max( tmin.y, tmin.z ) );\n float t1 = min( tmax.x, min( tmax.y, tmax.z ) );\n return vec2( t0, t1 );\n}\n\nfloat sample1( vec3 p ) {\n return texture( map, p ).r;\n}\n\n#define epsilon .0001\n\nvec3 normal( vec3 coord ) {\n if ( coord.x < epsilon ) return vec3( 1.0, 0.0, 0.0 );\n if ( coord.y < epsilon ) return vec3( 0.0, 1.0, 0.0 );\n if ( coord.z < epsilon ) return vec3( 0.0, 0.0, 1.0 );\n if ( coord.x > 1.0 - epsilon ) return vec3( - 1.0, 0.0, 0.0 );\n if ( coord.y > 1.0 - epsilon ) return vec3( 0.0, - 1.0, 0.0 );\n if ( coord.z > 1.0 - epsilon ) return vec3( 0.0, 0.0, - 1.0 );\n\n float step = 0.01;\n float x = sample1( coord + vec3( - step, 0.0, 0.0 ) ) - sample1( coord + vec3( step, 0.0, 0.0 ) );\n float y = sample1( coord + vec3( 0.0, - step, 0.0 ) ) - sample1( coord + vec3( 0.0, step, 0.0 ) );\n float z = sample1( coord + vec3( 0.0, 0.0, - step ) ) - sample1( coord + vec3( 0.0, 0.0, step ) );\n\n return normalize( vec3( x, y, z ) );\n}\n\nvoid main(){\n\n vec3 rayDir = normalize( vDirection );\n vec2 bounds = hitBox( vOrigin, rayDir );\n\n if ( bounds.x > bounds.y ) discard;\n\n bounds.x = max( bounds.x, 0.0 );\n\n vec3 p = vOrigin + bounds.x * rayDir;\n vec3 inc = 1.0 / abs( rayDir );\n float delta = min( inc.x, min( inc.y, inc.z ) );\n delta /= steps;\n\n for ( float t = bounds.x; t < bounds.y; t += delta ) {\n\n float d = sample1( p + 0.5 );\n\n if ( d > threshold ) {\n\n color.rgb = normal( p + 0.5 ) * 0.5 + ( p * 1.5 + 0.25 );\n color.a = 1.;\n break;\n\n }\n\n p += rayDir * delta;\n\n }\n\n if ( color.a == 0.0 ) discard;\n\n}",side:R,transparent:!0}),Rt(this,"isExampleVolumeMaterial_Perlin",!0)}get map(){return this.uniforms.map.value}set map(t){this.uniforms.map.value=t,this.uniformsNeedUpdate=!0}get threshold(){return this.uniforms.threshold.value}set threshold(t){this.uniforms.threshold.value=t,this.uniformsNeedUpdate=!0}get steps(){return this.uniforms.steps.value}set steps(t){this.uniforms.steps.value=t,this.uniformsNeedUpdate=!0}get cameraPos(){return this.uniforms.cameraPos.value}set cameraPos(t){this.uniforms.cameraPos.value.copy(t),this.uniformsNeedUpdate=!0}}class Me{constructor(t){this.ssp=t,this.defaultColorGradient=[[0,"rgba(0,255,0,0)"],[.5,"rgba(64,255,255,0.5)"],[1,"rgba(255,64,255,1)"]],this.defaultGradientVolumeMaterialOptions={fit:Vt.Raw,accFactor:2,depthTest:!1,side:R,discardOut:!1,gradient:Ct(this.defaultColorGradient)}}_createTexture(t,e,n=!1){const i=he(Object.assign({points:t},e),Object.assign({maxSize:60},e)),{options:a,position:o,scale:r}=i,s=kt(n?me(a):se(a),Object.assign({},e)),l=new Lt(Object.assign(Object.assign(Object.assign({},this.defaultGradientVolumeMaterialOptions),{map:s}),e)),c=new jt(l);return c.position.copy(o),c.scale.set(r,r,r),this.ssp.addObject(c),c}createHeatCloud(t,e){return this._createTexture(t,e)}createLineHeat(t,e){return this._createTexture(t,e,!0)}async createImageExtrusion(t,e){var n;const i=new Ht(Object.assign({side:R,depthTest:!1},e)),a=Wt(await L.utils.imageLoader.loadAsync(t),null!==(n=null==e?void 0:e.depth)&&void 0!==n?n:200,e);i.map=a;const o=new jt(i);return this.ssp.addObject(o),o}createSliceMesh(t,e){let n=t.map;if(!n)return;if(t instanceof Lt){const{gradient:i,range:a,discardOut:o,voidRange:r}=t;n=Yt(n.image,Object.assign({gradient:null==i?void 0:i.image,range:a,discardOut:o,voidRange:r},e))}const i=new ne(Object.assign({map:n},e));return this.ssp.addObject(i),i}createImageSlice(t,e){const n=t.map;if(!n)return;let i=null;if(t instanceof Lt){const{gradient:a,range:o,discardOut:r,voidRange:s}=t;i=Yt(n.image,Object.assign({gradient:null==a?void 0:a.image,range:o,discardOut:r,voidRange:s},e))}if(t instanceof Ht&&(i=n),!i)return;return new ie(i)}}export{Jt as ColorFogPointsMaterial,xe as ExampleVolumeMaterial_1,ye as ExampleVolumeMaterial_Cloud,we as ExampleVolumeMaterial_Perlin,Zt as FogPointsMaterial,Bt as GradientData3DTexture,$t as GradientFogPointsMaterial,Lt as GradientVolumeMaterial,Me as HeatMapPlugin,Mt as ImageData3DSlice,Kt as ImageData3DTexture,ie as ImageData3DTextureSlice,Ht as ImageVolumeMaterial,ee as SliceMaterial,ne as SliceMesh,Xt as SphereFogMaterial,Vt as VolumeFit,Et as VolumeMaterial,jt as VolumeMesh,ge as VolumeRenderStyle,re as computeHeatData3DForPoint,Qt as createColorFogPoints,kt as createGradientData3DTexture,te as createGradientFogPoints,se as createHeatData3D,Wt as createImageData3DTextureByExtrudeImage,Yt as createImageData3DTextureFromGradient,me as createLineData3D,W as createLinearGradientImageData,ht as data2DCoordToIndex,vt as data2DIndexToCoord,at as data3DCoordToIndex,ot as data3DIndexToCoord,Me as default,pt as extrudeImage,mt as extrudeImageData,ft as extrudeImageDataOnAxis,xt as getData2DItem,gt as getData2DItemSafe,wt as getData2DRow,yt as getData2DValue,_t as getData2DValueSafe,st as getData3DItem,rt as getData3DItemSafe,dt as getData3DSlice,ct as getData3DValue,lt as getData3DValueSafe,Q as getImageDateColor,Y as getImageDateOfImage,J as getImageDateRow,X as getNaturalSizeOfImageSource,qt as gradientData3DToImageData3D,ce as hollowGradient_Default,$ as imageDataToCanvas,tt as imageDataToUrl,et as isIImageData2,nt as isIImageData3,it as isOutOfSize,ue as lineValueGradient_Default,Gt as makeOriginOnBoundingBoxMinOfGeometry,ut as mergeData3Ds,de as numberValuesAccumulate_Default,he as optimizeGradientOptions,le as radiusGradient_Default,Z as reverseImageDateY,pe as transformGradientOptions,fe as translateScaleGradientOptions,ae as valueGradient_Default,oe as valuesAccumulate_Default};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { HeatData3DOptions, CreateGradientData3DTextureOptions, GradientOptionsOptimizeOptions, GradientVolumeMaterialOptions, LineData3DOptions, ImageData3DTexture, VolumeMaterialOptions, ExtrudeImageOptions } from '@three3d/volume';
|
|
2
|
-
export type GradientOptions = GradientOptionsOptimizeOptions & CreateGradientData3DTextureOptions & GradientVolumeMaterialOptions;
|
|
3
|
-
export type HeatDataOptions = Omit<HeatData3DOptions, 'points'>;
|
|
4
|
-
export type LineDataOptions = Omit<LineData3DOptions, 'points'>;
|
|
5
|
-
export type CreateHeatCloudOptions = HeatDataOptions & GradientOptions;
|
|
6
|
-
export type CreatLineHeatOptions = LineDataOptions & GradientOptions;
|
|
7
|
-
export type CreateHeatOptions = CreatLineHeatOptions & CreateHeatCloudOptions;
|
|
8
|
-
export type CreateImageExtrusionOptions = VolumeMaterialOptions<ImageData3DTexture> & ExtrudeImageOptions;
|
|
1
|
+
import { HeatData3DOptions, CreateGradientData3DTextureOptions, GradientOptionsOptimizeOptions, GradientVolumeMaterialOptions, LineData3DOptions, ImageData3DTexture, VolumeMaterialOptions, ExtrudeImageOptions } from '@three3d/volume';
|
|
2
|
+
export type GradientOptions = GradientOptionsOptimizeOptions & CreateGradientData3DTextureOptions & GradientVolumeMaterialOptions;
|
|
3
|
+
export type HeatDataOptions = Omit<HeatData3DOptions, 'points'>;
|
|
4
|
+
export type LineDataOptions = Omit<LineData3DOptions, 'points'>;
|
|
5
|
+
export type CreateHeatCloudOptions = HeatDataOptions & GradientOptions;
|
|
6
|
+
export type CreatLineHeatOptions = LineDataOptions & GradientOptions;
|
|
7
|
+
export type CreateHeatOptions = CreatLineHeatOptions & CreateHeatCloudOptions;
|
|
8
|
+
export type CreateImageExtrusionOptions = VolumeMaterialOptions<ImageData3DTexture> & ExtrudeImageOptions;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soonspacejs/plugin-heat-cloud",
|
|
3
3
|
"pluginName": "HeatCloudPlugin",
|
|
4
|
-
"version": "2.13.
|
|
4
|
+
"version": "2.13.12",
|
|
5
5
|
"description": "Haet-cloud plugin for SoonSpace.js",
|
|
6
6
|
"main": "dist/index.esm.js",
|
|
7
7
|
"module": "dist/index.esm.js",
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
],
|
|
14
14
|
"author": "xunwei",
|
|
15
15
|
"license": "UNLICENSED",
|
|
16
|
-
"gitHead": "
|
|
16
|
+
"gitHead": "aa34f472ae1520b537b0a5a1d67f4a746f41236a",
|
|
17
17
|
"peerDependencies": {
|
|
18
|
-
"soonspacejs": "2.13.
|
|
18
|
+
"soonspacejs": "2.13.12"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@three3d/volume": "^1.4.3"
|