@rr0/ufoathome 0.82.0 → 0.83.0

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.
@@ -0,0 +1,393 @@
1
+ import{I as ee,F,a as G,b as M,W as te,B as j,d as $,V as E,e as ie,f as I,U as J,g as ne,h as O,M as se,i as B,L as oe,j as ae,k as re,G as le,C as ce,D as de,l as fe,P as ue,m as pe,n as he,o as me,q as V,r as ge}from"./rr0-sighting.mjs";const k=new j,P=new E;class Q extends ee{constructor(){super(),this.isLineSegmentsGeometry=!0,this.type="LineSegmentsGeometry";const e=[-1,2,0,1,2,0,-1,1,0,1,1,0,-1,0,0,1,0,0,-1,-1,0,1,-1,0],n=[-1,2,1,2,-1,1,1,1,-1,-1,1,-1,-1,-2,1,-2],i=[0,2,1,2,3,1,2,4,3,4,5,3,4,6,5,6,7,5];this.setIndex(i),this.setAttribute("position",new F(e,3)),this.setAttribute("uv",new F(n,2))}applyMatrix4(e){const n=this.attributes.instanceStart,i=this.attributes.instanceEnd;return n!==void 0&&(n.applyMatrix4(e),i.applyMatrix4(e),n.needsUpdate=!0),this.boundingBox!==null&&this.computeBoundingBox(),this.boundingSphere!==null&&this.computeBoundingSphere(),this}setPositions(e){let n;e instanceof Float32Array?n=e:Array.isArray(e)&&(n=new Float32Array(e));const i=new G(n,6,1);return this.setAttribute("instanceStart",new M(i,3,0)),this.setAttribute("instanceEnd",new M(i,3,3)),this.instanceCount=this.attributes.instanceStart.count,this.computeBoundingBox(),this.computeBoundingSphere(),this}setColors(e){let n;e instanceof Float32Array?n=e:Array.isArray(e)&&(n=new Float32Array(e));const i=new G(n,6,1);return this.setAttribute("instanceColorStart",new M(i,3,0)),this.setAttribute("instanceColorEnd",new M(i,3,3)),this}fromWireframeGeometry(e){return this.setPositions(e.attributes.position.array),this}fromEdgesGeometry(e){return this.setPositions(e.attributes.position.array),this}fromMesh(e){return this.fromWireframeGeometry(new te(e.geometry)),this}fromLineSegments(e){const n=e.geometry;return this.setPositions(n.attributes.position.array),this}computeBoundingBox(){this.boundingBox===null&&(this.boundingBox=new j);const e=this.attributes.instanceStart,n=this.attributes.instanceEnd;e!==void 0&&n!==void 0&&(this.boundingBox.setFromBufferAttribute(e),k.setFromBufferAttribute(n),this.boundingBox.union(k))}computeBoundingSphere(){this.boundingSphere===null&&(this.boundingSphere=new $),this.boundingBox===null&&this.computeBoundingBox();const e=this.attributes.instanceStart,n=this.attributes.instanceEnd;if(e!==void 0&&n!==void 0){const i=this.boundingSphere.center;this.boundingBox.getCenter(i);let t=0;for(let o=0,l=e.count;o<l;o++)P.fromBufferAttribute(e,o),t=Math.max(t,i.distanceToSquared(P)),P.fromBufferAttribute(n,o),t=Math.max(t,i.distanceToSquared(P));this.boundingSphere.radius=Math.sqrt(t),isNaN(this.boundingSphere.radius)&&console.error("THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.",this)}}toJSON(){}}O.line={worldUnits:{value:1},linewidth:{value:1},resolution:{value:new ne},dashOffset:{value:0},dashScale:{value:1},dashSize:{value:1},gapSize:{value:1}};I.line={uniforms:J.merge([O.common,O.fog,O.line]),vertexShader:`
2
+ #include <common>
3
+ #include <color_pars_vertex>
4
+ #include <fog_pars_vertex>
5
+ #include <logdepthbuf_pars_vertex>
6
+ #include <clipping_planes_pars_vertex>
7
+
8
+ uniform float linewidth;
9
+ uniform vec2 resolution;
10
+
11
+ attribute vec3 instanceStart;
12
+ attribute vec3 instanceEnd;
13
+
14
+ attribute vec3 instanceColorStart;
15
+ attribute vec3 instanceColorEnd;
16
+
17
+ #ifdef WORLD_UNITS
18
+
19
+ varying vec4 worldPos;
20
+ varying vec3 worldStart;
21
+ varying vec3 worldEnd;
22
+
23
+ #ifdef USE_DASH
24
+
25
+ varying vec2 vUv;
26
+
27
+ #endif
28
+
29
+ #else
30
+
31
+ varying vec2 vUv;
32
+
33
+ #endif
34
+
35
+ #ifdef USE_DASH
36
+
37
+ uniform float dashScale;
38
+ attribute float instanceDistanceStart;
39
+ attribute float instanceDistanceEnd;
40
+ varying float vLineDistance;
41
+
42
+ #endif
43
+
44
+ float trimSegmentAlpha( const in vec4 start, const in vec4 end ) {
45
+
46
+ // compute the interpolation factor needed to trim the segment so it terminates
47
+ // between the camera plane and the near plane
48
+
49
+ // conservative estimate of the near plane
50
+ float a = projectionMatrix[ 2 ][ 2 ]; // 3nd entry in 3th column
51
+ float b = projectionMatrix[ 3 ][ 2 ]; // 3nd entry in 4th column
52
+
53
+ // we need different nearEstimate formula for reversed and default depth buffer
54
+ // a is positive with a reversed depth buffer so it can be used for controlling the code flow
55
+ float nearEstimate = ( a > 0.0 ) ? ( - b / ( a + 1.0 ) ) : ( - 0.5 * b / a );
56
+
57
+ return ( nearEstimate - start.z ) / ( end.z - start.z );
58
+
59
+ }
60
+
61
+ void main() {
62
+
63
+ #ifdef USE_COLOR
64
+
65
+ vColor.xyz = ( position.y < 0.5 ) ? instanceColorStart : instanceColorEnd;
66
+
67
+ #endif
68
+
69
+ float aspect = resolution.x / resolution.y;
70
+
71
+ // camera space
72
+ vec4 start = modelViewMatrix * vec4( instanceStart, 1.0 );
73
+ vec4 end = modelViewMatrix * vec4( instanceEnd, 1.0 );
74
+
75
+ #ifdef USE_DASH
76
+
77
+ float lineDistanceStart = dashScale * instanceDistanceStart;
78
+ float lineDistanceEnd = dashScale * instanceDistanceEnd;
79
+
80
+ #endif
81
+
82
+ #ifdef WORLD_UNITS
83
+
84
+ worldStart = start.xyz;
85
+ worldEnd = end.xyz;
86
+
87
+ #else
88
+
89
+ vUv = uv;
90
+
91
+ #endif
92
+
93
+ // special case for perspective projection, and segments that terminate either in, or behind, the camera plane
94
+ // clearly the gpu firmware has a way of addressing this issue when projecting into ndc space
95
+ // but we need to perform ndc-space calculations in the shader, so we must address this issue directly
96
+ // perhaps there is a more elegant solution -- WestLangley
97
+
98
+ bool perspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 ); // 4th entry in the 3rd column
99
+
100
+ if ( perspective ) {
101
+
102
+ if ( start.z < 0.0 && end.z >= 0.0 ) {
103
+
104
+ float alpha = trimSegmentAlpha( start, end );
105
+ end.xyz = mix( start.xyz, end.xyz, alpha );
106
+
107
+ #ifdef USE_DASH
108
+
109
+ lineDistanceEnd = mix( lineDistanceStart, lineDistanceEnd, alpha );
110
+
111
+ #endif
112
+
113
+ } else if ( end.z < 0.0 && start.z >= 0.0 ) {
114
+
115
+ float alpha = trimSegmentAlpha( end, start );
116
+ start.xyz = mix( end.xyz, start.xyz, alpha );
117
+
118
+ #ifdef USE_DASH
119
+
120
+ lineDistanceStart = mix( lineDistanceEnd, lineDistanceStart, alpha );
121
+
122
+ #endif
123
+
124
+ }
125
+
126
+ }
127
+
128
+ #ifdef USE_DASH
129
+
130
+ vLineDistance = ( position.y < 0.5 ) ? lineDistanceStart : lineDistanceEnd;
131
+ vUv = uv;
132
+
133
+ #endif
134
+
135
+ // clip space
136
+ vec4 clipStart = projectionMatrix * start;
137
+ vec4 clipEnd = projectionMatrix * end;
138
+
139
+ // ndc space
140
+ vec3 ndcStart = clipStart.xyz / clipStart.w;
141
+ vec3 ndcEnd = clipEnd.xyz / clipEnd.w;
142
+
143
+ // direction
144
+ vec2 dir = ndcEnd.xy - ndcStart.xy;
145
+
146
+ // account for clip-space aspect ratio
147
+ dir.x *= aspect;
148
+ dir = normalize( dir );
149
+
150
+ #ifdef WORLD_UNITS
151
+
152
+ vec3 worldDir = normalize( end.xyz - start.xyz );
153
+ vec3 tmpFwd = normalize( mix( start.xyz, end.xyz, 0.5 ) );
154
+ vec3 worldUp = normalize( cross( worldDir, tmpFwd ) );
155
+ vec3 worldFwd = cross( worldDir, worldUp );
156
+ worldPos = position.y < 0.5 ? start: end;
157
+
158
+ // height offset
159
+ float hw = linewidth * 0.5;
160
+ worldPos.xyz += position.x < 0.0 ? hw * worldUp : - hw * worldUp;
161
+
162
+ // don't extend the line if we're rendering dashes because we
163
+ // won't be rendering the endcaps
164
+ #ifndef USE_DASH
165
+
166
+ // cap extension
167
+ worldPos.xyz += position.y < 0.5 ? - hw * worldDir : hw * worldDir;
168
+
169
+ // add width to the box
170
+ worldPos.xyz += worldFwd * hw;
171
+
172
+ // endcaps
173
+ if ( position.y > 1.0 || position.y < 0.0 ) {
174
+
175
+ worldPos.xyz -= worldFwd * 2.0 * hw;
176
+
177
+ }
178
+
179
+ #endif
180
+
181
+ // project the worldpos
182
+ vec4 clip = projectionMatrix * worldPos;
183
+
184
+ // shift the depth of the projected points so the line
185
+ // segments overlap neatly
186
+ vec3 clipPose = ( position.y < 0.5 ) ? ndcStart : ndcEnd;
187
+ clip.z = clipPose.z * clip.w;
188
+
189
+ #else
190
+
191
+ vec2 offset = vec2( dir.y, - dir.x );
192
+ // undo aspect ratio adjustment
193
+ dir.x /= aspect;
194
+ offset.x /= aspect;
195
+
196
+ // sign flip
197
+ if ( position.x < 0.0 ) offset *= - 1.0;
198
+
199
+ // endcaps
200
+ if ( position.y < 0.0 ) {
201
+
202
+ offset += - dir;
203
+
204
+ } else if ( position.y > 1.0 ) {
205
+
206
+ offset += dir;
207
+
208
+ }
209
+
210
+ // adjust for linewidth
211
+ offset *= linewidth;
212
+
213
+ // adjust for clip-space to screen-space conversion // maybe resolution should be based on viewport ...
214
+ offset /= resolution.y;
215
+
216
+ // select end
217
+ vec4 clip = ( position.y < 0.5 ) ? clipStart : clipEnd;
218
+
219
+ // back to clip space
220
+ offset *= clip.w;
221
+
222
+ clip.xy += offset;
223
+
224
+ #endif
225
+
226
+ gl_Position = clip;
227
+
228
+ vec4 mvPosition = ( position.y < 0.5 ) ? start : end; // this is an approximation
229
+
230
+ #include <logdepthbuf_vertex>
231
+ #include <clipping_planes_vertex>
232
+ #include <fog_vertex>
233
+
234
+ }
235
+ `,fragmentShader:`
236
+ uniform vec3 diffuse;
237
+ uniform float opacity;
238
+ uniform float linewidth;
239
+
240
+ #ifdef USE_DASH
241
+
242
+ uniform float dashOffset;
243
+ uniform float dashSize;
244
+ uniform float gapSize;
245
+
246
+ #endif
247
+
248
+ varying float vLineDistance;
249
+
250
+ #ifdef WORLD_UNITS
251
+
252
+ varying vec4 worldPos;
253
+ varying vec3 worldStart;
254
+ varying vec3 worldEnd;
255
+
256
+ #ifdef USE_DASH
257
+
258
+ varying vec2 vUv;
259
+
260
+ #endif
261
+
262
+ #else
263
+
264
+ varying vec2 vUv;
265
+
266
+ #endif
267
+
268
+ #include <common>
269
+ #include <color_pars_fragment>
270
+ #include <fog_pars_fragment>
271
+ #include <logdepthbuf_pars_fragment>
272
+ #include <clipping_planes_pars_fragment>
273
+
274
+ vec2 closestLineToLine(vec3 p1, vec3 p2, vec3 p3, vec3 p4) {
275
+
276
+ float mua;
277
+ float mub;
278
+
279
+ vec3 p13 = p1 - p3;
280
+ vec3 p43 = p4 - p3;
281
+
282
+ vec3 p21 = p2 - p1;
283
+
284
+ float d1343 = dot( p13, p43 );
285
+ float d4321 = dot( p43, p21 );
286
+ float d1321 = dot( p13, p21 );
287
+ float d4343 = dot( p43, p43 );
288
+ float d2121 = dot( p21, p21 );
289
+
290
+ float denom = d2121 * d4343 - d4321 * d4321;
291
+
292
+ float numer = d1343 * d4321 - d1321 * d4343;
293
+
294
+ mua = numer / denom;
295
+ mua = clamp( mua, 0.0, 1.0 );
296
+ mub = ( d1343 + d4321 * ( mua ) ) / d4343;
297
+ mub = clamp( mub, 0.0, 1.0 );
298
+
299
+ return vec2( mua, mub );
300
+
301
+ }
302
+
303
+ void main() {
304
+
305
+ float alpha = opacity;
306
+ vec4 diffuseColor = vec4( diffuse, alpha );
307
+
308
+ #include <clipping_planes_fragment>
309
+
310
+ #ifdef USE_DASH
311
+
312
+ if ( vUv.y < - 1.0 || vUv.y > 1.0 ) discard; // discard endcaps
313
+
314
+ if ( mod( vLineDistance + dashOffset, dashSize + gapSize ) > dashSize ) discard; // todo - FIX
315
+
316
+ #endif
317
+
318
+ #ifdef WORLD_UNITS
319
+
320
+ // Find the closest points on the view ray and the line segment
321
+ vec3 rayEnd = normalize( worldPos.xyz ) * 1e5;
322
+ vec3 lineDir = worldEnd - worldStart;
323
+ vec2 params = closestLineToLine( worldStart, worldEnd, vec3( 0.0, 0.0, 0.0 ), rayEnd );
324
+
325
+ vec3 p1 = worldStart + lineDir * params.x;
326
+ vec3 p2 = rayEnd * params.y;
327
+ vec3 delta = p1 - p2;
328
+ float len = length( delta );
329
+ float norm = len / linewidth;
330
+
331
+ #ifndef USE_DASH
332
+
333
+ #ifdef USE_ALPHA_TO_COVERAGE
334
+
335
+ float dnorm = fwidth( norm );
336
+ alpha = 1.0 - smoothstep( 0.5 - dnorm, 0.5 + dnorm, norm );
337
+
338
+ #else
339
+
340
+ if ( norm > 0.5 ) {
341
+
342
+ discard;
343
+
344
+ }
345
+
346
+ #endif
347
+
348
+ #endif
349
+
350
+ #else
351
+
352
+ #ifdef USE_ALPHA_TO_COVERAGE
353
+
354
+ // artifacts appear on some hardware if a derivative is taken within a conditional
355
+ float a = vUv.x;
356
+ float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;
357
+ float len2 = a * a + b * b;
358
+ float dlen = fwidth( len2 );
359
+
360
+ if ( abs( vUv.y ) > 1.0 ) {
361
+
362
+ alpha = 1.0 - smoothstep( 1.0 - dlen, 1.0 + dlen, len2 );
363
+
364
+ }
365
+
366
+ #else
367
+
368
+ if ( abs( vUv.y ) > 1.0 ) {
369
+
370
+ float a = vUv.x;
371
+ float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;
372
+ float len2 = a * a + b * b;
373
+
374
+ if ( len2 > 1.0 ) discard;
375
+
376
+ }
377
+
378
+ #endif
379
+
380
+ #endif
381
+
382
+ #include <logdepthbuf_fragment>
383
+ #include <color_fragment>
384
+
385
+ gl_FragColor = vec4( diffuseColor.rgb, alpha );
386
+
387
+ #include <tonemapping_fragment>
388
+ #include <colorspace_fragment>
389
+ #include <fog_fragment>
390
+ #include <premultiplied_alpha_fragment>
391
+
392
+ }
393
+ `};class N extends ie{constructor(e){super({type:"LineMaterial",uniforms:J.clone(I.line.uniforms),vertexShader:I.line.vertexShader,fragmentShader:I.line.fragmentShader,clipping:!0}),this.isLineMaterial=!0,this.setValues(e)}get color(){return this.uniforms.diffuse.value}set color(e){this.uniforms.diffuse.value=e}get worldUnits(){return"WORLD_UNITS"in this.defines}set worldUnits(e){e===!0!==this.worldUnits&&(this.needsUpdate=!0),e===!0?this.defines.WORLD_UNITS="":delete this.defines.WORLD_UNITS}get linewidth(){return this.uniforms.linewidth.value}set linewidth(e){this.uniforms.linewidth&&(this.uniforms.linewidth.value=e)}get dashed(){return"USE_DASH"in this.defines}set dashed(e){e===!0!==this.dashed&&(this.needsUpdate=!0),e===!0?this.defines.USE_DASH="":delete this.defines.USE_DASH}get dashScale(){return this.uniforms.dashScale.value}set dashScale(e){this.uniforms.dashScale.value=e}get dashSize(){return this.uniforms.dashSize.value}set dashSize(e){this.uniforms.dashSize.value=e}get dashOffset(){return this.uniforms.dashOffset.value}set dashOffset(e){this.uniforms.dashOffset.value=e}get gapSize(){return this.uniforms.gapSize.value}set gapSize(e){this.uniforms.gapSize.value=e}get opacity(){return this.uniforms.opacity.value}set opacity(e){this.uniforms&&(this.uniforms.opacity.value=e)}get resolution(){return this.uniforms.resolution.value}set resolution(e){this.uniforms.resolution.value.copy(e)}get alphaToCoverage(){return"USE_ALPHA_TO_COVERAGE"in this.defines}set alphaToCoverage(e){this.defines&&(e===!0!==this.alphaToCoverage&&(this.needsUpdate=!0),e===!0?this.defines.USE_ALPHA_TO_COVERAGE="":delete this.defines.USE_ALPHA_TO_COVERAGE)}}const H=new B,q=new E,X=new E,f=new B,u=new B,x=new B,W=new E,R=new ae,p=new oe,K=new E,T=new j,C=new $,S=new B;let b,z;function Z(h,e,n){return S.set(0,0,-e,1).applyMatrix4(h.projectionMatrix),S.multiplyScalar(1/S.w),S.x=z/n.width,S.y=z/n.height,S.applyMatrix4(h.projectionMatrixInverse),S.multiplyScalar(1/S.w),Math.abs(Math.max(S.x,S.y))}function ve(h,e){const n=h.matrixWorld,i=h.geometry,t=i.attributes.instanceStart,o=i.attributes.instanceEnd,l=Math.min(i.instanceCount,t.count);for(let s=0,a=l;s<a;s++){p.start.fromBufferAttribute(t,s),p.end.fromBufferAttribute(o,s),p.applyMatrix4(n);const d=new E,m=new E;b.distanceSqToSegment(p.start,p.end,m,d),m.distanceTo(d)<z*.5&&e.push({point:m,pointOnLine:d,distance:b.origin.distanceTo(m),object:h,face:null,faceIndex:s,uv:null,uv1:null})}}function ye(h,e,n){const i=e.projectionMatrix,o=h.material.resolution,l=h.matrixWorld,s=h.geometry,a=s.attributes.instanceStart,d=s.attributes.instanceEnd,m=Math.min(s.instanceCount,a.count),c=-e.near;b.at(1,x),x.w=1,x.applyMatrix4(e.matrixWorldInverse),x.applyMatrix4(i),x.multiplyScalar(1/x.w),x.x*=o.x/2,x.y*=o.y/2,x.z=0,W.copy(x),R.multiplyMatrices(e.matrixWorldInverse,l);for(let g=0,r=m;g<r;g++){if(f.fromBufferAttribute(a,g),u.fromBufferAttribute(d,g),f.w=1,u.w=1,f.applyMatrix4(R),u.applyMatrix4(R),f.z>c&&u.z>c)continue;if(f.z>c){const _=f.z-u.z,w=(f.z-c)/_;f.lerp(u,w)}else if(u.z>c){const _=u.z-f.z,w=(u.z-c)/_;u.lerp(f,w)}f.applyMatrix4(i),u.applyMatrix4(i),f.multiplyScalar(1/f.w),u.multiplyScalar(1/u.w),f.x*=o.x/2,f.y*=o.y/2,u.x*=o.x/2,u.y*=o.y/2,p.start.copy(f),p.start.z=0,p.end.copy(u),p.end.z=0;const y=p.closestPointToPointParameter(W,!0);p.at(y,K);const L=re.lerp(f.z,u.z,y),U=L>=-1&&L<=1,D=W.distanceTo(K)<z*.5;if(U&&D){p.start.fromBufferAttribute(a,g),p.end.fromBufferAttribute(d,g),p.start.applyMatrix4(l),p.end.applyMatrix4(l);const _=new E,w=new E;b.distanceSqToSegment(p.start,p.end,w,_),n.push({point:w,pointOnLine:_,distance:b.origin.distanceTo(w),object:h,face:null,faceIndex:g,uv:null,uv1:null})}}}class we extends se{constructor(e=new Q,n=new N({color:Math.random()*16777215})){super(e,n),this.isLineSegments2=!0,this.type="LineSegments2"}computeLineDistances(){const e=this.geometry,n=e.attributes.instanceStart,i=e.attributes.instanceEnd,t=new Float32Array(2*n.count);for(let l=0,s=0,a=n.count;l<a;l++,s+=2)q.fromBufferAttribute(n,l),X.fromBufferAttribute(i,l),t[s]=s===0?0:t[s-1],t[s+1]=t[s]+q.distanceTo(X);const o=new G(t,2,1);return e.setAttribute("instanceDistanceStart",new M(o,1,0)),e.setAttribute("instanceDistanceEnd",new M(o,1,1)),this}raycast(e,n){const i=this.material.worldUnits,t=e.camera;if(t===null&&!i&&console.error('LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2 while worldUnits is set to false.'),i===!1&&(this.material.resolution.x===0||this.material.resolution.y===0))return;const o=e.params.Line2!==void 0&&e.params.Line2.threshold||0;b=e.ray;const l=this.matrixWorld,s=this.geometry,a=this.material;z=a.linewidth+o,s.boundingSphere===null&&s.computeBoundingSphere(),C.copy(s.boundingSphere).applyMatrix4(l);let d;if(i)d=z*.5;else{const c=Math.max(t.near,C.distanceToPoint(b.origin));d=Z(t,c,a.resolution)}if(C.radius+=d,b.intersectsSphere(C)===!1)return;s.boundingBox===null&&s.computeBoundingBox(),T.copy(s.boundingBox).applyMatrix4(l);let m;if(i)m=z*.5;else{const c=Math.max(t.near,T.distanceToPoint(b.origin));m=Z(t,c,a.resolution)}T.expandByScalar(m),b.intersectsBox(T)!==!1&&(i?ve(this,n):ye(this,t,n))}onBeforeRender(e){const n=this.material.uniforms;n&&n.resolution&&(e.getViewport(H),this.material.uniforms.resolution.value.set(H.z,H.w))}}class Y extends Q{constructor(){super(),this.isLineGeometry=!0,this.type="LineGeometry"}setPositions(e){const n=e.length-3,i=new Float32Array(2*n);for(let t=0;t<n;t+=3)i[2*t]=e[t],i[2*t+1]=e[t+1],i[2*t+2]=e[t+2],i[2*t+3]=e[t+3],i[2*t+4]=e[t+4],i[2*t+5]=e[t+5];return super.setPositions(i),this}setColors(e){const n=e.length-3,i=new Float32Array(2*n);for(let t=0;t<n;t+=3)i[2*t]=e[t],i[2*t+1]=e[t+1],i[2*t+2]=e[t+2],i[2*t+3]=e[t+3],i[2*t+4]=e[t+4],i[2*t+5]=e[t+5];return super.setColors(i),this}setFromPoints(e){const n=e.length-1,i=new Float32Array(6*n);for(let t=0;t<n;t++)i[6*t]=e[t].x,i[6*t+1]=e[t].y,i[6*t+2]=e[t].z||0,i[6*t+3]=e[t+1].x,i[6*t+4]=e[t+1].y,i[6*t+5]=e[t+1].z||0;return super.setPositions(i),this}fromLine(e){const n=e.geometry;return this.setPositions(n.attributes.position.array),this}}class xe extends we{constructor(e=new Y,n=new N({color:Math.random()*16777215})){super(e,n),this.isLine2=!0,this.type="Line2"}}class A{constructor(e){this.layer=e,this.group.name="traces"}static LINE_WIDTH_PX=2.5;static MARKER_SIZE_PX=9;static LABEL_HEIGHT_PX=15;static STEP_M=15;static LIFT_M=.3;group=new le;materials=[];pointsMaterials=[];labels=[];viewportHeightPx=720;fovDeg=60;set(e,n,i,t,o,l){this.empty();for(const s of e){const a=this.positions(s,i,t,o,l),d=new ce(s.color??de),m=n.get(s.id);if(m&&a.length>=3&&this.addLabel(m,this.labelAnchor(a,s.kind)),s.kind==="point"){const c=new fe;c.setAttribute("position",new F(a.slice(0,3),3));const g=new ue({color:d,size:A.MARKER_SIZE_PX,sizeAttenuation:!1,depthTest:!1,fog:!1});this.pointsMaterials.push(g);const r=new pe(c,g);r.name="trace point",r.frustumCulled=!1,r.layers.set(this.layer),this.group.add(r)}else if(a.length>=6){const c=new Y;c.setPositions(s.kind==="polygon"?[...a,a[0],a[1],a[2]]:a);const g=new N({color:d.getHex(),linewidth:A.LINE_WIDTH_PX,worldUnits:!1,transparent:!0,opacity:.92,depthTest:!1,fog:!1});this.materials.push(g);const r=new xe(c,g);r.name=`trace ${s.kind}`,r.frustumCulled=!1,r.layers.set(this.layer),this.group.add(r)}}}setView(e,n){for(const i of this.materials)i.resolution.copy(e);e.y===this.viewportHeightPx&&n===this.fovDeg||(this.viewportHeightPx=e.y,this.fovDeg=n,this.scaleLabels())}get any(){return this.group.children.length>0}dispose(){this.empty()}labelAnchor(e,n){let i=0;if(n==="line"){let t=-1;for(let o=0;o+2<e.length;o+=3){const l=Math.hypot(e[o],e[o+2]);l>t&&(t=l,i=o)}}return[e[i],e[i+1],e[i+2]]}addLabel(e,n){const i=document.createElement("canvas"),t=i.getContext("2d");if(!t)return;const o="bold 30px sans-serif";t.font=o;const l=10;i.width=Math.ceil(t.measureText(e).width)+l*2,i.height=44,t.font=o,t.fillStyle="rgba(0, 0, 0, 0.6)",t.beginPath(),t.roundRect(0,0,i.width,i.height,10),t.fill(),t.fillStyle="#ffffff",t.textBaseline="middle",t.fillText(e,l,i.height/2+2);const s=new he({map:new me(i),depthTest:!1,depthWrite:!1,fog:!1,sizeAttenuation:!1}),a=new V(s);a.name="trace name",a.center.set(0,0),a.position.set(n[0],n[1],n[2]),a.frustumCulled=!1,a.layers.set(this.layer),this.labels.push({sprite:a,aspect:i.width/i.height}),this.group.add(a),this.scaleLabels()}scaleLabels(){const e=A.LABEL_HEIGHT_PX/(this.viewportHeightPx/2)*Math.tan(this.fovDeg*Math.PI/360);for(const{sprite:n,aspect:i}of this.labels)n.scale.set(e*i,e,1)}empty(){for(const e of[...this.group.children])this.group.remove(e),e instanceof V?(e.material.map?.dispose(),e.material.dispose()):e.geometry.dispose();this.labels.length=0;for(const e of this.materials.splice(0))e.dispose();for(const e of this.pointsMaterials.splice(0))e.dispose()}positions(e,n,i,t,o){const l=e.altitude??"ground",s=e.points.map(r=>{const{x:v,z:y}=ge(r.lat,r.lng,n,i);return{x:v,z:y,altM:r.altM??0}}),a=l!=="absolute",d=[],m=(r,v,y)=>l==="absolute"?y-t:o(r,v)+(l==="relative"?y:0)+A.LIFT_M,c=e.kind==="polygon",g=c?s.length:s.length-1;for(let r=0;r<Math.max(g,1);r++){const v=s[r],y=s[(r+1)%s.length],L=a&&e.kind!=="point"?Math.max(1,Math.ceil(Math.hypot(y.x-v.x,y.z-v.z)/A.STEP_M)):1;for(let U=0;U<L;U++){const D=U/L,_=v.x+(y.x-v.x)*D,w=v.z+(y.z-v.z)*D;d.push(_,m(_,w,v.altM+(y.altM-v.altM)*D),w)}}if(!c&&e.kind!=="point"){const r=s[s.length-1];d.push(r.x,m(r.x,r.z,r.altM),r.z)}return d}}export{A as TraceSystem};