@rr0/ufoathome 0.126.0 → 0.127.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.
Files changed (34) hide show
  1. package/dist-embed-scene/RailwaySystem-BSqu6iHY.js +41 -0
  2. package/dist-embed-scene/RoadMarkings-C3oJCHLk.js +1 -0
  3. package/dist-embed-scene/UfoMessages_es-BRCWkzr3.js +1 -0
  4. package/dist-embed-scene/UfoMessages_fr-Cs2GCHEt.js +1 -0
  5. package/dist-embed-scene/UfoMessages_it-B2hvjhgb.js +1 -0
  6. package/dist-embed-scene/rr0-scene.mjs +381 -283
  7. package/dist-embed-sighting/RailwaySystem-BXRi4IAz.js +41 -0
  8. package/dist-embed-sighting/RoadMarkings-DKxgMzE-.js +1 -0
  9. package/dist-embed-sighting/UfoMessages_es-BRCWkzr3.js +1 -0
  10. package/dist-embed-sighting/UfoMessages_fr-Cs2GCHEt.js +1 -0
  11. package/dist-embed-sighting/UfoMessages_it-B2hvjhgb.js +1 -0
  12. package/dist-embed-sighting/rr0-sighting.mjs +376 -278
  13. package/dist-embed-sighting-editor/RailwaySystem-BCDMPAEx.js +41 -0
  14. package/dist-embed-sighting-editor/RoadMarkings-CVibbxgC.js +1 -0
  15. package/dist-embed-sighting-editor/UfoMessages_es-BRCWkzr3.js +1 -0
  16. package/dist-embed-sighting-editor/UfoMessages_fr-Cs2GCHEt.js +1 -0
  17. package/dist-embed-sighting-editor/UfoMessages_it-B2hvjhgb.js +1 -0
  18. package/dist-embed-sighting-editor/rr0-sighting-editor.mjs +397 -299
  19. package/package.json +1 -1
  20. package/dist-embed-scene/RailwaySystem-usuVIAY1.js +0 -41
  21. package/dist-embed-scene/RoadMarkings-DbE4nCJ2.js +0 -1
  22. package/dist-embed-scene/UfoMessages_es-LFW_B5H2.js +0 -1
  23. package/dist-embed-scene/UfoMessages_fr-bJNAf-AU.js +0 -1
  24. package/dist-embed-scene/UfoMessages_it-B-jnc4M-.js +0 -1
  25. package/dist-embed-sighting/RailwaySystem-BMOTAo7T.js +0 -41
  26. package/dist-embed-sighting/RoadMarkings-DtoEUDmh.js +0 -1
  27. package/dist-embed-sighting/UfoMessages_es-LFW_B5H2.js +0 -1
  28. package/dist-embed-sighting/UfoMessages_fr-bJNAf-AU.js +0 -1
  29. package/dist-embed-sighting/UfoMessages_it-B-jnc4M-.js +0 -1
  30. package/dist-embed-sighting-editor/RailwaySystem-BNAIqpAH.js +0 -41
  31. package/dist-embed-sighting-editor/RoadMarkings-aj_cbh3H.js +0 -1
  32. package/dist-embed-sighting-editor/UfoMessages_es-LFW_B5H2.js +0 -1
  33. package/dist-embed-sighting-editor/UfoMessages_fr-bJNAf-AU.js +0 -1
  34. package/dist-embed-sighting-editor/UfoMessages_it-B-jnc4M-.js +0 -1
@@ -0,0 +1,41 @@
1
+ import{G as F,f as w,C as H,g as P,B as K,h as N,b as U,i as k}from"./rr0-sighting.mjs";class S{static HOLLOW_M=1;static COVERED_M=3;static WINDOW_M=30;static SAMPLE_M=4;static MAX_GRADE={rail:.025,highSpeed:.035,subway:.04,light_rail:.06,tram:.08,funicular:1/0};static heights(t,n,s){const e=t.map(r=>r.level===0),o=t.map((r,l)=>e[l]?S.targets(r,n,s):[]),c=t.map((r,l)=>e[l]?S.samples(r,o[l]):[]),a=new Map;t.forEach((r,l)=>{if(e[l])for(const p of S.ends(r)){const h=S.key(p),f=a.get(h);f?f.push(l):a.set(h,[l])}});const M=r=>{const l=a.get(S.key(r));if(l)return S.median(l.flatMap(p=>c[p]),r)};return t.map((r,l)=>{if(e[l]){const p=[...new Set([l,...S.ends(r).flatMap(g=>a.get(S.key(g))??[])])].flatMap(g=>c[g]),h=r.centre.map((g,D)=>S.median(p,g)??o[l][D]),[f,z]=S.ends(r);return h[0]=M(f)??h[0],h[h.length-1]=M(z)??h[h.length-1],S.graded(h,r.along,r.highSpeed?S.MAX_GRADE.highSpeed:S.MAX_GRADE[r.kind])}return S.carried(r,n,s,M)})}static targets(t,n,s){return t.centre.map(e=>{const o=n(e.x,e.z);if(s===void 0||e.altitudeM===void 0)return o;const c=e.altitudeM+s;return c-o>S.HOLLOW_M||o-c>S.COVERED_M?c:o})}static samples(t,n){const s=[];let e=0;return t.centre.forEach((o,c)=>{t.along[c]+1e-6<e&&c<t.centre.length-1||(s.push({x:o.x,z:o.z,y:n[c]}),e=t.along[c]+S.SAMPLE_M)}),s}static median(t,n){const s=[];for(const o of t)Math.hypot(o.x-n.x,o.z-n.z)<=S.WINDOW_M&&s.push(o.y);if(s.length===0)return;s.sort((o,c)=>o-c);const e=s.length>>1;return s.length%2===1?s[e]:(s[e-1]+s[e])/2}static graded(t,n,s){if(!Number.isFinite(s)||t.length<3)return t;const e=[...t],o=e.length-1,c=n[o];if(Math.abs(e[o]-e[0])>s*c)return n.map(a=>e[0]+(e[o]-e[0])*a/c);for(let a=1;a<o;a++){const M=s*(n[a]-n[a-1]);e[a]=Math.min(e[a-1]+M,Math.max(e[a-1]-M,e[a]))}for(let a=o-1;a>0;a--){const M=s*(n[a+1]-n[a]);e[a]=Math.min(e[a+1]+M,Math.max(e[a+1]-M,e[a]))}return e}static carried(t,n,s,e){const[o,c]=S.ends(t),a=t.along[t.along.length-1],M=e(o),r=e(c);if(s!==void 0&&t.centre.every(h=>h.altitudeM!==void 0)){const h=t.centre.map(g=>g.altitudeM+s),f=M!==void 0?M-h[0]:0,z=r!==void 0?r-h[h.length-1]:0;return h.map((g,D)=>g+f+(z-f)*t.along[D]/a)}const l=M??n(o.x,o.z),p=r??n(c.x,c.z);return t.along.map(h=>l+(p-l)*h/a)}static ends(t){return[t.centre[0],t.centre[t.centre.length-1]]}static key(t){return`${Math.round(t.x*2)},${Math.round(t.z*2)}`}}class I{positions=[];indices=[];along=[];get vertexCount(){return this.positions.length/3}strip(t,n,s){const e=this.vertexCount;for(let o=0;o<t.length;o++)this.positions.push(t[o].x,t[o].y,t[o].z,n[o].x,n[o].y,n[o].z),s&&this.along.push(s[o],s[o]);for(let o=0;o<t.length-1;o++){const c=e+o*2;this.indices.push(c,c+2,c+1,c+1,c+2,c+3)}}beam(t,n,s,e=!0){const o=n.x-t.x,c=n.y-t.y,a=n.z-t.z,M=Math.hypot(o,c,a);if(M<1e-6)return;const r={x:o/M,y:c/M,z:a/M},l=Math.abs(r.y)>.9?{x:1,y:0,z:0}:{x:0,y:1,z:0},p=r.y*l.z-r.z*l.y,h=r.z*l.x-r.x*l.z,f=r.x*l.y-r.y*l.x,z=Math.hypot(p,h,f),g={x:p/z*s/2,y:h/z*s/2,z:f/z*s/2},D={x:r.y*g.z-r.z*g.y,y:r.z*g.x-r.x*g.z,z:r.x*g.y-r.y*g.x},E=(u,A,d)=>({x:u.x+g.x*A+D.x*d,y:u.y+g.y*A+D.y*d,z:u.z+g.z*A+D.z*d}),_=[[1,1],[-1,1],[-1,-1],[1,-1]];for(let u=0;u<4;u++){const[A,d]=_[u],[v,x]=_[(u+1)%4];this.quad(E(t,A,d),E(t,v,x),E(n,v,x),E(n,A,d))}e&&(this.quad(...[..._].reverse().map(([u,A])=>E(t,u,A))),this.quad(..._.map(([u,A])=>E(n,u,A))))}quad(t,n,s,e){const o=this.vertexCount;this.positions.push(t.x,t.y,t.z,n.x,n.y,n.z,s.x,s.y,s.z,e.x,e.y,e.z),this.indices.push(o,o+1,o+2,o,o+2,o+3)}}class i{static STEP_M=6;static BALLAST_HEIGHT_M=.5;static BALLAST_SLOPE=1.5;static BALLAST_SHOULDER_M=.45;static DECK_DEPTH_M=.8;static BANK_SLOPE=1.5;static SLEEPER_LENGTH_M=2.4;static SLEEPER_WIDTH_M=.29;static SLEEPER_SPACING_M=.6;static RAIL_HEAD_M=.072;static RAIL_HEIGHT_M=.18;static TRAM_RAIL_HEIGHT_M=.03;static LIFT_M=.06;static CATENARY={rail:{contactM:5.5,systemM:1.4,spanM:54,staggerM:.2},highSpeed:{contactM:5.08,systemM:1.4,spanM:63,staggerM:.2},service:{contactM:5.5,systemM:1.2,spanM:45,staggerM:.2},tram:{contactM:6,systemM:0,spanM:30,staggerM:.2}};static MESSENGER_SAG_M=.55;static MAST_SIDE_M=.26;static MAST_OFFSET_M=3.1;static MAST_ABOVE_M=.6;static CONTACT_DIAMETER_M=.012;static MESSENGER_DIAMETER_M=.011;static ARM_SIDE_M=.06;static TRACK_SPACING_M={rail:3.7,highSpeed:4.5,tram:3.1,subway:3.4,light_rail:3.4,funicular:3.2};static BALLAST_ALBEDO=[.17,.16,.15];static BANK_ALBEDO=[.085,.09,.05];static DECK_ALBEDO=[.26,.255,.24];static CONCRETE_ALBEDO=[.36,.35,.33];static WOOD_ALBEDO=[.07,.055,.045];static RUST_ALBEDO=[.085,.068,.058];static STEEL_ALBEDO=[.3,.31,.32];static COPPER_ALBEDO=[.09,.085,.07];group=new F;stepM=i.STEP_M;drawn=0;ballastMaterial=i.pebbled(i.lambert(i.BALLAST_ALBEDO,!0));earthMaterial=i.lambert(i.BANK_ALBEDO,!0);deckMaterial=i.lambert(i.DECK_ALBEDO,!1);concreteSleepers=i.sleeperMaterial(i.CONCRETE_ALBEDO);woodSleepers=i.sleeperMaterial(i.WOOD_ALBEDO);rustMaterial=i.lambert(i.RUST_ALBEDO,!0);headMaterial=new w({color:new H(.62,.62,.62),metalness:1,roughness:.28,polygonOffset:!0,polygonOffsetFactor:-2,polygonOffsetUnits:-2});steelMaterial=i.lambert(i.STEEL_ALBEDO,!1);wireMaterial=i.lambert(i.COPPER_ALBEDO,!1);constructor(){this.group.name="railways"}get count(){return this.drawn}setGroundSpacing(t){this.stepM=Number.isFinite(t)&&t>0?Math.min(i.STEP_M,Math.max(1.5,t/2)):i.STEP_M}set(t,n,s,e,o=1/0){this.clear();const a=t.map(f=>({line:f,path:f.points.map(z=>({...P(z.lat,z.lng,n,s),altitudeM:z.altitudeM}))})).filter(({line:f,path:z})=>f.level>=0&&i.within(z,o)),M=i.altitudeOffset(a,e),r=a.flatMap(({line:f,path:z})=>{const g=this.layoutOf(f,z);return g?[{line:f,layout:g}]:[]}),l=S.heights(r.map(({layout:f})=>f),e,M),p={ballast:new I,earth:new I,deck:new I,concrete:new I,wood:new I,rust:new I,head:new I,steel:new I,wire:new I};r.forEach(({line:f,layout:z},g)=>{this.lay(f,{...z,y:l[g]},e,p),this.drawn++});const h=[[p.ballast,this.ballastMaterial,"ballast",!1],[p.earth,this.earthMaterial,"embankments",!1],[p.deck,this.deckMaterial,"decks",!0],[p.concrete,this.concreteSleepers,"sleepers",!1],[p.wood,this.woodSleepers,"sleepers wood",!1],[p.rust,this.rustMaterial,"rails",!1],[p.head,this.headMaterial,"rail heads",!1],[p.steel,this.steelMaterial,"catenary masts",!0],[p.wire,this.wireMaterial,"catenary wires",!1]];for(const[f,z,g,D]of h){const E=i.meshOf(f,z);E&&(E.name=`railways ${g}`,E.castShadow=D,E.receiveShadow=!0,this.group.add(E))}}clear(){for(const t of[...this.group.children])this.group.remove(t),t.geometry?.dispose();this.drawn=0}dispose(){this.clear();for(const t of[this.ballastMaterial,this.earthMaterial,this.deckMaterial,this.concreteSleepers,this.woodSleepers,this.rustMaterial,this.headMaterial,this.steelMaterial,this.wireMaterial])t.dispose()}static within(t,n){if(!Number.isFinite(n))return!0;const s=n*1.1+100;return t.some((e,o)=>Math.hypot(e.x,e.z)<=s||o>0&&Math.hypot((e.x+t[o-1].x)/2,(e.z+t[o-1].z)/2)<=s)}static altitudeOffset(t,n){const s=[];for(const{line:e,path:o}of t)if(e.level===0)for(const c of o)c.altitudeM!==void 0&&s.push(n(c.x,c.z)-c.altitudeM);if(!(s.length<5))return s.sort((e,o)=>e-o),s[Math.floor(s.length/2)]}layoutOf(t,n){const s=[];for(let c=0;c<n.length-1;c++){const a=n[c],M=n[c+1],r=Math.max(1,Math.ceil(Math.hypot(M.x-a.x,M.z-a.z)/this.stepM));for(let l=0;l<r;l++){const p=l/r,h=a.altitudeM!==void 0&&M.altitudeM!==void 0?a.altitudeM+(M.altitudeM-a.altitudeM)*p:void 0;s.push({x:a.x+(M.x-a.x)*p,z:a.z+(M.z-a.z)*p,altitudeM:h})}}if(s.push(n[n.length-1]),s.length<2)return;const e=[0];for(let c=1;c<s.length;c++)e.push(e[c-1]+Math.hypot(s[c].x-s[c-1].x,s[c].z-s[c-1].z));if(e[e.length-1]<.5)return;const o=s.map((c,a)=>{const M=s[Math.max(0,a-1)],r=s[Math.min(s.length-1,a+1)],l=r.x-M.x,p=r.z-M.z,h=Math.hypot(l,p);return h<1e-6?{x:1,z:0}:{x:l/h,z:p/h}});return{kind:t.kind,...t.highSpeed?{highSpeed:!0}:{},level:t.level,centre:s,along:e,dir:o}}lay(t,n,s,e){const o=t.highSpeed?i.TRACK_SPACING_M.highSpeed:i.TRACK_SPACING_M[t.kind],c=Math.min(8,Math.max(1,t.tracks)),a=Array.from({length:c},(E,_)=>(_-(c-1)/2)*o),M=t.kind==="tram",r=M?0:i.BALLAST_HEIGHT_M,l=i.LIFT_M,p=(E,_,u)=>({x:n.centre[E].x-n.dir[E].z*_,y:n.y[E]+u,z:n.centre[E].z+n.dir[E].x*_}),h=n.centre.map((E,_)=>_);if(!M){const E=i.SLEEPER_LENGTH_M/2+i.BALLAST_SHOULDER_M+(a[a.length-1]??0),_=h.map(A=>p(A,E,r+l)),u=h.map(A=>p(A,-E,r+l));if(e.ballast.strip(_,u),t.level===0){const A=E+r*i.BALLAST_SLOPE;for(const d of[1,-1]){const v=[],x=[];let m=!1;for(const L of h){const b=p(L,d*A,l),C=s(b.x,b.z)+l,T=b.y-C;T<0&&(b.y=Math.min(C,n.y[L]+r-.05+l)),v.push(b);const B=p(L,d*(A+Math.max(0,T)*i.BANK_SLOPE),l);B.y=Math.min(s(B.x,B.z)+l,b.y),b.y-B.y>.02&&(m=!0),x.push(B)}const O=d>0?_:u;d>0?e.ballast.strip(v,O):e.ballast.strip(O,v),m&&(d>0?e.earth.strip(x,v):e.earth.strip(v,x))}}else{const A=-i.DECK_DEPTH_M,d=E+.15,v=h.map(L=>p(L,d,r+l+.1)),x=h.map(L=>p(L,-d,r+l+.1)),m=h.map(L=>p(L,d,A)),O=h.map(L=>p(L,-d,A));e.deck.strip(m,v),e.deck.strip(x,O),e.deck.strip(O,m),e.deck.strip(v,h.map(L=>p(L,E,r+l+.1))),e.deck.strip(h.map(L=>p(L,-E,r+l+.1)),x)}}const f=t.service?e.wood:e.concrete,z=t.gaugeMm/2e3+i.RAIL_HEAD_M/2,g=M?i.TRAM_RAIL_HEIGHT_M:i.RAIL_HEIGHT_M,D=r+l;for(const E of a){if(!M){const _=i.SLEEPER_LENGTH_M/2;f.strip(h.map(u=>p(u,E+_,D+.004)),h.map(u=>p(u,E-_,D+.004)),n.along)}for(const _ of[1,-1]){const u=E+_*z,A=i.RAIL_HEAD_M/2,d=h.map(x=>p(x,u+A,D+g)),v=h.map(x=>p(x,u-A,D+g));e.head.strip(d,v),e.rust.strip(h.map(x=>p(x,u+A,D)),d),e.rust.strip(v,h.map(x=>p(x,u-A,D)))}}t.electrification==="overhead"&&t.kind!=="subway"&&t.kind!=="funicular"&&this.catenary(t,n,a,D+g,p,s,e)}catenary(t,n,s,e,o,c,a){const M=t.kind==="tram"?i.CATENARY.tram:t.highSpeed?i.CATENARY.highSpeed:t.service?i.CATENARY.service:i.CATENARY.rail,r=n.along[n.along.length-1],l=Math.max(1,Math.round(r/M.spanM)),p=r/l,h=Array.from({length:l},(d,v)=>(v+.5)*p),f=e+M.contactM,z=f+M.systemM,g=(M.systemM>0?z:f)+i.MAST_ABOVE_M,D=s[s.length-1],E=s.length>2,_=s.length===1?[1]:[1,-1],u=(d,v,x)=>{let m=0,O=n.along.length-2;for(;m<O;){const T=m+O+1>>1;n.along[T]<=d?m=T:O=T-1}const L=Math.min(1,Math.max(0,(d-n.along[m])/Math.max(1e-6,n.along[m+1]-n.along[m]))),b=o(m,v,x),C=o(m+1,v,x);return{x:b.x+(C.x-b.x)*L,y:b.y+(C.y-b.y)*L,z:b.z+(C.z-b.z)*L}};for(const d of h){const v=u(d,0,f);if(!(t.level===0&&c(v.x,v.z)>v.y)){for(const x of _){const m=x*(D+i.MAST_OFFSET_M),O=u(d,m,0);t.level===0&&(O.y=Math.min(O.y,c(O.x,O.z)));const L=u(d,m,g);if(a.steel.beam(O,L,i.MAST_SIDE_M),E)continue;const C=(_.length===1?s[0]:x*D)-x*.6,T=M.systemM>0?z:f+.3;a.steel.beam(u(d,m,T),u(d,C,T),i.ARM_SIDE_M),a.steel.beam(u(d,m,f-.4),u(d,C,T),i.ARM_SIDE_M)}if(E){const x=D+i.MAST_OFFSET_M;a.steel.beam(u(d,x,g-.2),u(d,-x,g-.2),i.MAST_SIDE_M*.8)}}}const A=[0,...h,r];for(const[d,v]of s.entries()){const x=m=>m===0||m===A.length-1?0:((m+d)%2===0?1:-1)*M.staggerM;for(let m=0;m<A.length-1;m++){const O=A[m],L=A[m+1];if(L-O<.1||(a.wire.beam(u(O,v+x(m),f),u(L,v+x(m+1),f),i.CONTACT_DIAMETER_M,!1),M.systemM<=0))continue;const b=4,C=T=>{const B=m===0?.5+T/2:m===A.length-2?T/2:T;return z-i.MESSENGER_SAG_M*4*B*(1-B)};for(let T=0;T<b;T++){const B=T/b,G=(T+1)/b;a.wire.beam(u(O+(L-O)*B,v,C(B)),u(O+(L-O)*G,v,C(G)),i.MESSENGER_DIAMETER_M,!1)}}}}static meshOf(t,n){if(t.indices.length===0)return;const s=new K;return s.setAttribute("position",new N(new Float32Array(t.positions),3)),t.along.length>0&&s.setAttribute("aAlong",new N(new Float32Array(t.along),1)),s.setIndex(new N(new Uint32Array(t.indices),1)),s.computeVertexNormals(),new U(s,n)}static lambert(t,n){return new k({color:new H(...t),...n?{polygonOffset:!0,polygonOffsetFactor:-2,polygonOffsetUnits:-2}:{}})}static pebbled(t){return t.onBeforeCompile=n=>{n.vertexShader=n.vertexShader.replace("#include <common>",`#include <common>
2
+ varying vec3 vBallast;`).replace("#include <begin_vertex>",`#include <begin_vertex>
3
+ vBallast = position;`),n.fragmentShader=n.fragmentShader.replace("#include <common>",`#include <common>
4
+ varying vec3 vBallast;
5
+ float ballastHash(vec2 p) {
6
+ p = fract(p * vec2(127.1, 311.7));
7
+ p += dot(p, p + 34.5);
8
+ return fract(p.x * p.y);
9
+ }
10
+ float ballastNoise(vec2 p) {
11
+ vec2 i = floor(p);
12
+ vec2 f = fract(p);
13
+ f = f * f * (3.0 - 2.0 * f);
14
+ return mix(mix(ballastHash(i), ballastHash(i + vec2(1.0, 0.0)), f.x), mix(ballastHash(i + vec2(0.0, 1.0)), ballastHash(i + vec2(1.0, 1.0)), f.x), f.y);
15
+ }`).replace("#include <map_fragment>",`#include <map_fragment>
16
+ {
17
+ float eye = length(vViewPosition);
18
+ vec2 at = vBallast.xz + vec2(0.0, vBallast.y);
19
+ float stones = (ballastHash(floor(at * 22.0)) - 0.5) * 0.9 * (1.0 - smoothstep(4.0, 18.0, eye))
20
+ + (ballastNoise(at * 6.0) - 0.5) * 0.5 * (1.0 - smoothstep(15.0, 60.0, eye))
21
+ + (ballastNoise(at * 0.7) - 0.5) * 0.35 * (1.0 - smoothstep(80.0, 300.0, eye));
22
+ diffuseColor.rgb *= 1.0 + stones;
23
+ }`)},t.customProgramCacheKey=()=>"rr0-railway-ballast",t}static sleeperMaterial(t){const n=new k({color:new H(1,1,1),polygonOffset:!0,polygonOffsetFactor:-3,polygonOffsetUnits:-3}),s=new H(...t),e=new H(...i.BALLAST_ALBEDO);return n.onBeforeCompile=o=>{o.uniforms.uSleeper={value:s},o.uniforms.uCrib={value:e},o.uniforms.uSpacing={value:i.SLEEPER_SPACING_M},o.uniforms.uDuty={value:i.SLEEPER_WIDTH_M/i.SLEEPER_SPACING_M},o.vertexShader=o.vertexShader.replace("#include <common>",`#include <common>
24
+ attribute float aAlong;
25
+ varying float vAlong;`).replace("#include <begin_vertex>",`#include <begin_vertex>
26
+ vAlong = aAlong;`),o.fragmentShader=o.fragmentShader.replace("#include <common>",`#include <common>
27
+ varying float vAlong;
28
+ uniform vec3 uSleeper;
29
+ uniform vec3 uCrib;
30
+ uniform float uSpacing;
31
+ uniform float uDuty;
32
+ // How much of [0, x] periods is sleeper: the integral of a pulse of width uDuty at the start of each period.
33
+ float sleeperIntegral(float x) {
34
+ return floor(x) * uDuty + min(fract(x), uDuty);
35
+ }`).replace("#include <map_fragment>",`#include <map_fragment>
36
+ {
37
+ float u = vAlong / uSpacing;
38
+ float w = max(fwidth(u), 1e-4);
39
+ float cover = (sleeperIntegral(u + 0.5 * w) - sleeperIntegral(u - 0.5 * w)) / w;
40
+ diffuseColor.rgb *= mix(uCrib, uSleeper, clamp(cover, 0.0, 1.0));
41
+ }`)},n.customProgramCacheKey=()=>"rr0-railway-sleepers",n}}export{i as RailwaySystem};
@@ -0,0 +1 @@
1
+ import{g as D}from"./rr0-sighting.mjs";class M{static MIN_ROAD_M=5.5;static WIDE_ROAD_M=9;static LINE_WIDTH_M=.12;static DASH_M=3;static GAP_M=10;static RIVE_DASH_M=2.5;static RIVE_GAP_M=3.5;static MIN_DASH_M=.5;static LANE_M=3.5;static SHOULDER_MIN_M=1.5;static SOLID_EDGE_FROM_M=7;static SOLID_EDGE_FROM_KMH=80;static BEND_RADIUS_M=300;static EDGE_SETBACK_M=.4;static PAINT_RADIUS_M=450;static LIFT_M=.015;static BARRIER_MAX_AXES_M=40;static BARRIER_MIN_AXES_M=5;static BARRIER_HEIGHT_M=.8;static BARRIER_HALF_WIDTH_M=.2;static BARRIER_STEP_M=4;static painted(t){return t.surface==="paved"&&t.widthM>=M.MIN_ROAD_M&&t.kind!=="roundabout"}static plan(t){if(!M.painted(t))return[];const u=t.widthM,l=u/2,i=M.EDGE_SETBACK_M;if(!(t.direction!==void 0&&t.lanes!==void 0)){const I=[{offsetM:l-i,pattern:"solid"},{offsetM:-(l-i),pattern:"solid"}],A=u>=M.WIDE_ROAD_M?[-u/4,u/4]:[0];for(const x of A)I.push({offsetM:x,pattern:"dashed"});return I}const s=t.lanes,n=u>=M.SOLID_EDGE_FROM_M||(t.speedKmh??0)>=M.SOLID_EDGE_FROM_KMH?"solid":"rive";if(t.direction==="both"){if(s<2)return[];const I=[{offsetM:l-i,pattern:n},{offsetM:-(l-i),pattern:n}];if(s>=4){I.push({offsetM:.1,pattern:"solid"},{offsetM:-.1,pattern:"solid"});const A=Math.floor(s/2),x=u/s;for(let z=1;z<A;z++)I.push({offsetM:z*x,pattern:"dashed"},{offsetM:-z*x,pattern:"dashed"})}else I.push({offsetM:0,pattern:"dashed",solidInBends:!0});return I}const r=t.direction==="backward"?-1:1,o=I=>r*(l-I),c=Math.min(M.LANE_M,u/Math.max(s,1)),h=s*c,d=u-h,_=(t.kind==="motorway"||t.kind==="dual")&&d>=M.SHOULDER_MIN_M,E=[{offsetM:o(i),pattern:t.kind==="motorway"||t.kind==="dual"?"solid":n}];E.push({offsetM:o(_?h:u-i),pattern:t.kind==="motorway"||t.kind==="dual"?"solid":n});for(let I=1;I<s;I++)E.push({offsetM:o(I*c),pattern:"dashed"});return E}static lay(t,u,l,i){let e=0;const s=(f,n)=>{i(f,M.LINE_WIDTH_M,{offsetM:n,liftM:M.LIFT_M,minHalfM:M.LINE_WIDTH_M/2}),e++};for(const f of t){const n=M.plan(f);if(n.length===0)continue;const r=f.points.map(o=>D(o.lat,o.lng,u,l));for(const o of M.near(r,M.PAINT_RADIUS_M))for(const c of n){if(c.pattern==="solid"){s(o,c.offsetM);continue}const[h,d]=c.pattern==="dashed"?[M.DASH_M,M.GAP_M]:[M.RIVE_DASH_M,M.RIVE_GAP_M];for(const _ of c.solidInBends?M.byBends(o):[{path:o,bend:!1}])if(_.bend)s(_.path,c.offsetM);else for(const E of M.dashes(_.path,h,d))s(E,c.offsetM)}}return e}static byBends(t){if(t.length<3)return[{path:t,bend:!1}];const u=(e,s)=>Math.atan2(s.x-e.x,-(s.z-e.z)),l=new Array(t.length-1).fill(!1);for(let e=1;e<t.length-1;e++){const s=Math.hypot(t[e].x-t[e-1].x,t[e].z-t[e-1].z),f=Math.hypot(t[e+1].x-t[e].x,t[e+1].z-t[e].z);if(s<1e-6||f<1e-6)continue;let n=Math.abs(u(t[e],t[e+1])-u(t[e-1],t[e]));n>Math.PI&&(n=2*Math.PI-n),(s+f)/2/Math.max(n,1e-6)<M.BEND_RADIUS_M&&(l[e-1]=!0,l[e]=!0)}const i=[];for(let e=0;e<l.length;e++){const s=i.at(-1);s&&s.bend===l[e]?s.path.push(t[e+1]):i.push({path:[t[e],t[e+1]],bend:l[e]})}return i}static barriers(t,u,l){const i=t.filter(n=>(n.kind==="motorway"||n.kind==="dual")&&(n.direction==="forward"||n.direction==="backward")),e=i.map(n=>{const r=n.points.map(o=>D(o.lat,o.lng,u,l));return n.direction==="backward"?[...r].reverse():r}),s=[],f=M.BARRIER_STEP_M;return i.forEach((n,r)=>{for(const o of M.near(e[r],M.PAINT_RADIUS_M)){let c=[];for(const h of M.resample(o,f)){const d=M.midwayToOpposite(h,r,i,e);d?c.push(d):c.length>0&&(c.length>=2&&s.push(c),c=[])}c.length>=2&&s.push(c)}}),s}static midwayToOpposite(t,u,l,i){let e;for(let s=0;s<i.length;s++){if(s===u||l[s].id<l[u].id)continue;const f=i[s];for(let n=0;n<f.length-1;n++){const r=f[n+1].x-f[n].x,o=f[n+1].z-f[n].z,c=r*r+o*o;if(c<1e-9||(r*t.dx+o*t.dz)/Math.sqrt(c)>-.9)continue;const h=Math.max(0,Math.min(1,((t.x-f[n].x)*r+(t.z-f[n].z)*o)/c)),d={x:f[n].x+r*h,z:f[n].z+o*h},_=Math.hypot(t.x-d.x,t.z-d.z);_<M.BARRIER_MIN_AXES_M||_>M.BARRIER_MAX_AXES_M||(!e||_<e.distance)&&(e={distance:_,point:d})}}return e?{x:(t.x+e.point.x)/2,z:(t.z+e.point.z)/2}:void 0}static resample(t,u){const l=[];for(let e=0;e<t.length-1;e++){const s=Math.hypot(t[e+1].x-t[e].x,t[e+1].z-t[e].z);if(s<1e-6)continue;const f=(t[e+1].x-t[e].x)/s,n=(t[e+1].z-t[e].z)/s;for(let r=0;r<s;r+=u)l.push({x:t[e].x+f*r,z:t[e].z+n*r,dx:f,dz:n})}const i=l.at(-1);return i&&l.push({...t[t.length-1],dx:i.dx,dz:i.dz}),l}static barrierGeometry(t,u){const l=[],i=[],e=M.BARRIER_HALF_WIDTH_M;for(const s of t){if(s.length<2)continue;const f=l.length/3;for(let n=0;n<s.length;n++){const r=s[Math.max(0,n-1)],o=s[Math.min(s.length-1,n+1)],c=Math.hypot(o.x-r.x,o.z-r.z)||1,h=-(o.z-r.z)/c*e,d=(o.x-r.x)/c*e,_=u(s[n].x,s[n].z);l.push(s[n].x+h,_,s[n].z+d,s[n].x+h,_+M.BARRIER_HEIGHT_M,s[n].z+d,s[n].x-h,_+M.BARRIER_HEIGHT_M,s[n].z-d,s[n].x-h,_,s[n].z-d)}for(let n=0;n<s.length-1;n++){const r=f+n*4,o=r+4;for(let c=0;c<3;c++)i.push(r+c,o+c,r+c+1,r+c+1,o+c,o+c+1)}}return{positions:l,indices:i}}static near(t,u){const l=[];let i;for(let e=0;e<t.length-1;e++)Math.min(Math.hypot(t[e].x,t[e].z),Math.hypot(t[e+1].x,t[e+1].z))<=u||Math.hypot((t[e].x+t[e+1].x)/2,(t[e].z+t[e+1].z)/2)<=u?(i||(i=[t[e]]),i.push(t[e+1])):i&&(l.push(i),i=void 0);return i&&l.push(i),l}static dashes(t,u,l){const i=[],e=u+l;let s=0,f;const n=(o,c)=>({x:t[o].x+(t[o+1].x-t[o].x)*c,z:t[o].z+(t[o+1].z-t[o].z)*c});for(let o=0;o<t.length-1;o++){const c=Math.hypot(t[o+1].x-t[o].x,t[o+1].z-t[o].z);if(c<1e-6)continue;let h=0;for(;h<c;){const d=(s+h)%e,_=d<u,E=_?u-d:e-d,I=Math.min(c,h+E);_&&(f||(f=[n(o,h/c)]),f.push(n(o,I/c)),I-h>=E-1e-9&&(i.push(f),f=void 0)),h=I}s+=c}f&&f.length>=2&&i.push(f);const r=o=>o.slice(1).reduce((c,h,d)=>c+Math.hypot(h.x-o[d].x,h.z-o[d].z),0);return i.filter(o=>o.length>=2&&r(o)>=M.MIN_DASH_M)}}export{M as RoadMarkings};
@@ -0,0 +1 @@
1
+ const e={play:"Reproducir",clickToPlay:"Haz clic para reproducir",pause:"Pausa",noDuration:"Sin duración de observación",currentPosition:"Posición actual",duration:"Duración",switchToElapsed:"haz clic para mostrar el tiempo transcurrido",switchToClockTime:"haz clic para mostrar la hora del día",fullscreen:"Pantalla completa",exitFullscreen:"Salir de pantalla completa",mute:"Silenciar",unmute:"Activar el sonido",noSound:"Sin sonido registrado",moments:"Momentos",moreControls:"Más controles",fewerControls:"Menos controles",showObserverMap:"Ver dónde estaba el observador",hideObserverMap:"Ocultar dónde estaba el observador",mapImageryUnavailable:"Vista aérea no disponible",zoomMapIn:"Acercar",zoomMapOut:"Alejar",fitMap:"Volver al trayecto completo",placeObserverHere:"Poner al observador aquí",showReferences:"Ver las fotos del lugar",hideReferences:"Ocultar las fotos del lugar",showTraces:"Ver los trazos del investigador",hideTraces:"Ocultar los trazos del investigador",referenceOpacity:"Opacidad de las fotos",referencesMenu:"Fotos del lugar",showMilestones:"Ver los momentos del relato",hideMilestones:"Ocultar los momentos del relato",observerHere:"El observador, aquí",decorHere:"Elemento del decorado",recordingIssues:"{count} problema(s) en esta grabación: puede que no se reproduzca como su autor quería",issueTemplates:{"unknown-key":"{path}: clave desconocida, ignorada","wrong-type":"{path}: se esperaba {expected}, se encontró {found}","not-in-list":"{path}: {found} no es uno de {expected}",defaulted:"{path}: ausente, se usa {expected}",unplaced:"{path}: sin aim (ni bounds), dibujado en el centro de la vista",unsized:"{path}: sin tamaño angular (ni bounds), dibujado de un píxel de ancho","pixels-over-angles":"{path}: bounds repetido sin aim ni angular, así que la forma sigue los píxeles"}};export{e as ufoMessages_es};
@@ -0,0 +1 @@
1
+ const e={play:"Lecture",clickToPlay:"Cliquer pour lire",pause:"Pause",noDuration:"Aucune durée d'observation",currentPosition:"Position actuelle",duration:"Durée",switchToElapsed:"cliquer pour afficher la durée écoulée",switchToClockTime:"cliquer pour afficher l'heure de l'observation",fullscreen:"Plein écran",exitFullscreen:"Quitter le plein écran",mute:"Couper le son",unmute:"Rétablir le son",noSound:"Pas de son enregistré",moments:"Moments",moreControls:"Plus de commandes",fewerControls:"Moins de commandes",showObserverMap:"Voir où était l'observateur",hideObserverMap:"Masquer où était l'observateur",mapImageryUnavailable:"Vue aérienne indisponible",zoomMapIn:"Zoomer",zoomMapOut:"Dézoomer",fitMap:"Revenir au trajet entier",placeObserverHere:"Placer l'observateur ici",showReferences:"Voir les photos des lieux",hideReferences:"Masquer les photos des lieux",showTraces:"Voir les tracés d'enquêteur",hideTraces:"Masquer les tracés d'enquêteur",referenceOpacity:"Opacité des photos",referencesMenu:"Photos des lieux",showMilestones:"Voir les moments du récit",hideMilestones:"Masquer les moments du récit",observerHere:"L'observateur, ici",decorHere:"Élément de décor",recordingIssues:"{count} problème(s) dans cet enregistrement : il peut ne pas jouer ce que son auteur voulait",issueTemplates:{"unknown-key":"{path} : clé inconnue, ignorée","wrong-type":"{path} : {expected} attendu, {found} trouvé","not-in-list":"{path} : {found} ne fait pas partie de {expected}",defaulted:"{path} : absent, {expected} utilisé",unplaced:"{path} : ni aim ni bounds, dessiné au milieu de la vue",unsized:"{path} : ni taille angulaire ni bounds, dessiné large d'un pixel","pixels-over-angles":"{path} : bounds redonné sans aim ni angular, la forme suit les pixels"}};export{e as ufoMessages_fr};
@@ -0,0 +1 @@
1
+ const e={play:"Riproduci",clickToPlay:"Clicca per riprodurre",pause:"Pausa",noDuration:"Nessuna durata di osservazione",currentPosition:"Posizione attuale",duration:"Durata",switchToElapsed:"fai clic per mostrare il tempo trascorso",switchToClockTime:"fai clic per mostrare l'ora del giorno",fullscreen:"Schermo intero",exitFullscreen:"Esci dallo schermo intero",mute:"Disattiva audio",unmute:"Attiva audio",noSound:"Nessun suono registrato",moments:"Momenti",moreControls:"Altri controlli",fewerControls:"Meno controlli",showObserverMap:"Mostra dove si trovava l'osservatore",hideObserverMap:"Nascondi dove si trovava l'osservatore",mapImageryUnavailable:"Vista aerea non disponibile",zoomMapIn:"Ingrandisci",zoomMapOut:"Riduci",fitMap:"Torna all'intero percorso",placeObserverHere:"Metti qui l'osservatore",showReferences:"Mostra le foto del luogo",hideReferences:"Nascondi le foto del luogo",showTraces:"Mostra i tracciati dell'investigatore",hideTraces:"Nascondi i tracciati dell'investigatore",referenceOpacity:"Opacità delle foto",referencesMenu:"Foto del luogo",showMilestones:"Mostra i momenti del resoconto",hideMilestones:"Nascondi i momenti del resoconto",observerHere:"L'osservatore, qui",decorHere:"Elemento della scenografia",recordingIssues:"{count} problema/i in questa registrazione: potrebbe non essere riprodotta come voleva il suo autore",issueTemplates:{"unknown-key":"{path}: chiave sconosciuta, ignorata","wrong-type":"{path}: atteso {expected}, trovato {found}","not-in-list":"{path}: {found} non è tra {expected}",defaulted:"{path}: assente, usato {expected}",unplaced:"{path}: nessun aim (né bounds), disegnato al centro della vista",unsized:"{path}: nessuna dimensione angolare (né bounds), disegnato largo un pixel","pixels-over-angles":"{path}: bounds ripetuto senza aim né angular, quindi la forma segue i pixel"}};export{e as ufoMessages_it};