@ndmspc/ndmvr-core 0.0.1
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/README.md +295 -0
- package/dist/index.es.js +2728 -0
- package/dist/index.umd.js +86 -0
- package/dist/ndmvr-core.css +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
(function(B,z){typeof exports=="object"&&typeof module<"u"?z(exports,require("rxjs"),require("jsroot"),require("three")):typeof define=="function"&&define.amd?define(["exports","rxjs","jsroot","three"],z):(B=typeof globalThis<"u"?globalThis:B||self,z(B.ndmvrAframe={},B.rxjs,B.JSROOT,B.THREE))})(this,function(B,z,G,g){"use strict";var $e=Object.defineProperty;var ee=B=>{throw TypeError(B)};var _e=(B,z,G)=>z in B?$e(B,z,{enumerable:!0,configurable:!0,writable:!0,value:G}):B[z]=G;var p=(B,z,G)=>_e(B,typeof z!="symbol"?z+"":z,G),Ae=(B,z,G)=>z.has(B)||ee("Cannot "+G);var w=(B,z,G)=>(Ae(B,z,"read from private field"),G?G.call(B):z.get(B)),I=(B,z,G)=>z.has(B)?ee("Cannot add the same private member more than once"):z instanceof WeakSet?z.add(B):z.set(B,G),X=(B,z,G,g)=>(Ae(B,z,"write to private field"),g?g.call(B,G):z.set(B,G),G);var At,L,lt,nt,rt,ot,vt,yt,Ct,mt,K,$,ht,U,ct,st,J,W,at,pt,bt,ut,_;class xt{constructor(t,e,A,s){this.url=t,this.ws=null,this.channel=A,e&&this.connect(),this.initTime=Date.now(),this.timeout=s||6e4,this.timeFlag=!0}connect(){return this.ws===null&&(console.log("Trying to establish websocket connection on address: "+this.url),this.ws=new WebSocket(this.url)),this.ws.onerror=t=>{this.timeFlag||(this.initTime=Date.now(),this.timeFlag=!0),setTimeout(()=>{this.initTime+this.timeout<Date.now()||this.connect()},500)},this.ws.onclose=t=>{this.disconnect(),this.timeFlag||(this.initTime=Date.now(),this.timeFlag=!0),setTimeout(()=>{this.initTime+this.timeout<Date.now()||this.connect()},500)},this.ws.onmessage=t=>{this.channel.next(t.data)},this.ws.onopen=()=>{console.log("Websocket connection established on address: "+this.url),this.timeFlag=!1},this}disconnect(){this.ws&&(this.ws.close(),this.ws=null)}send(t){this.ws===null&&this.connect(),this.ws.send(t)}subscribe(t){return this.channel.subscribe({next:A=>t(A)})}unsubscribe(t){t.unsubscribe()}}let Bt;class se{constructor(){I(this,At);I(this,L);p(this,"createWsFromParams",t=>{const e=t.get("autoConnect")==="true",A=Number(t.get("timeout"));t.getAll("ws").forEach(s=>{this.createWs(s,e,A)})});p(this,"createWs",(t,e,A)=>{w(this,L).has(t)&&w(this,L).delete(t);const s=new xt(t,e,w(this,At),A);w(this,L).set(t,s)});p(this,"getBrokerByUrl",(t,e)=>{let A=w(this,L).get(t);return A||(A=new xt(t,e,w(this,At)),w(this,L).set(t,A)),e&&A.connect(),A});p(this,"connectWsByUrl",t=>{let e=w(this,L).get(t);return e||(e=new xt(t,!0,w(this,At)),w(this,L).set(t,e)),e.connect(),e});p(this,"disconnectWsByUrl",t=>{t?w(this,L).get(t).disconnect():w(this,L).forEach(e=>{e.disconnect()})});p(this,"getSubject",()=>w(this,At));X(this,At,new z.ReplaySubject(1)),X(this,L,new Map)}}At=new WeakMap,L=new WeakMap;const Nt=()=>(Bt||(Bt=new se),Bt),ie=()=>{Nt().createWsFromParams(new URL(window.location.href).searchParams)},ne=async o=>{try{const t=await fetch(o);if(!t.ok)throw new Error(`Response status: ${t.status}`);return t.json()}catch(t){throw t}};let Dt;class re{constructor(){I(this,lt);X(this,lt,new z.Subject)}getObservable(){return w(this,lt).asObservable()}next(t){w(this,lt).next(t)}}lt=new WeakMap;const jt=()=>(Dt||(Dt=new re),Dt);let zt;class oe{constructor(){I(this,nt);X(this,nt,new z.BehaviorSubject({inputDevice:"keyboard"}))}getObservable(){return w(this,nt).asObservable()}next(t){let e=w(this,nt).getValue();t.inputDevice&&(e.inputDevice=t.inputDevice),w(this,nt).next(t)}}nt=new WeakMap;const Mt=()=>(zt||(zt=new oe),zt);let Ot;class ce{constructor(){I(this,rt);X(this,rt,new z.BehaviorSubject({sets:[],selectedSet:[],arrays:["content"],selectedArray:"content"}))}getObservable(){return w(this,rt).asObservable()}getValue(){return w(this,rt).getValue()}next(t){w(this,rt).next(t)}}rt=new WeakMap;const R=()=>(Ot||(Ot=new ce),Ot);let Ht;class ae{constructor(){I(this,ot);X(this,ot,new z.ReplaySubject)}addFunctions(t){if(!t)return;let e;t instanceof Array?e=t:e=Array.of(t),e.forEach(A=>{let s=A.target.id;s instanceof Array||(s=Array.of(s)),w(this,ot).next({flag:"add",target:{entity:A.target.entity,id:s},event:A.event,function:A.function})})}removeFunctions(t){if(!t)return;let e;t instanceof Array?e=t:e=Array.of(t),e.forEach(A=>{console.log(A);let s=A.target.id;s instanceof Array||(s=Array.of(s)),w(this,ot).next({flag:A.event?"remove":"removeAll",target:{entity:A.target.entity,id:s},event:A.event,function:A.function})})}getObservable(){return w(this,ot).asObservable()}}ot=new WeakMap;const Pt=()=>(Ht||(Ht=new ae),Ht);class le{constructor(t){I(this,vt);I(this,yt);I(this,Ct);I(this,mt);X(this,vt,t),X(this,yt,this.open(t))}static async open(t){return G.openFile(t)}async getHistogram(t,e,A){if(t===0)return w(this,Ct).readObject("hMap");{let s=w(this,mt).reduce((i,r)=>i*r,1);for(let i=0;i<=t;i++)s/=w(this,mt)[i]}}static async parseFile(t){const e=await this.open(t);await this.computeMaxInstancesPerLayer(e)}static async computeMaxInstancesPerLayer(t){if(!t)return;const e=await t.readObject("hMap");e.children={};const A=e.fXaxis.fNbins*e.fYaxis.fNbins*e.fZaxis.fNbins;let s=[];s.push(A);const i=async(c,n)=>{for(const a of Object.keys(e.children))for(let u=0;u<c.length;u+=100){const d=[],m=Math.min(u+100,c.length);for(let b=u;b<m;b++)d.push(n.readObject(`content/${c[b].fName}/${a}`));console.log(`Processing batch: ${u} to ${m-1} (${d.length} items)`),await Promise.all(d)}return console.log("done"),c.forEach(a=>{}),s},r=await t.readObject("content");return(await t.readObject(`content/${r.fKeys[0].fName}`)).fKeys.forEach(c=>{e.children[c.fName]=[]}),console.log(e),i(r.fKeys,t),s}}vt=new WeakMap,yt=new WeakMap,Ct=new WeakMap,mt=new WeakMap;class he{constructor(t){I(this,K);X(this,K,G.parse(t))}static async parseJson(t){return G.parse(t)}computeMaxInstancesPerLayer(){if(!w(this,K))return;const t=w(this,K).fXaxis.fNbins*w(this,K).fYaxis.fNbins*w(this,K).fZaxis.fNbins;let e=[];e.push(t);const A=(s,i=1)=>{let r=0;return i>=e.length&&e.push(0),Object.entries(s).forEach((l,c)=>{l[1].forEach(n=>{n&&(r=n.fXaxis.fNbins*n.fYaxis.fNbins*n.fZaxis.fNbins,r>e[i]&&(e[i]=r),n.children&&A(n.children,i+1))})}),e};return A(w(this,K).children),Promise.resolve(e)}}K=new WeakMap;function ue(o,t,e,{scale:A,padding:s,origin:i}){const r=o.config??{};r.environment||(r.environment={}),r.environment.histogramPads||(r.environment.histogramPads=[]);const l=r.environment.histogramPads;let c=1,n=t.length;if(typeof e=="string"){const d=e.match(/^grid(\d+)x(\d+)$/i);d?(c=parseInt(d[1],10),n=parseInt(d[2],10)):(e==="simple"||e==="flex")&&(c=1,n=t.length)}c*n<t.length&&(n=Math.ceil(Math.sqrt(t.length)),c=Math.ceil(t.length/n));let a=0,u=0;return t.forEach(d=>{const m=i.x+u*(A.x+s.x)+A.x/2,b=i.y+(c-1-a)*(A.y+s.y)+A.y/2,y=i.z-A.z/2;l.push({id:d,position:{x:m,y:b,z:y},scale:{...A},padding:{...s},origin:{...i},grid:{row:a,col:u,rows:c,cols:n,disp_kind:e}}),u++,u>=n&&(u=0,a++)}),o}function de(o){const t={resetHistogram:"r",goToPreviousLayer:"z",hideOutlines:"o"};o.bindings=o.bindings||{};for(const e in t)o.bindings.hasOwnProperty(e)||(o.bindings[e]=t[e]);return o}function Vt(o,t=null){const e=typeof o=="string"?JSON.parse(o):o;function A(c){if(Array.isArray(c))return c;if(c&&typeof c=="object"&&"type"in c){const n=c.prefix??"histogram",h=c.type.match(/grid(\d+)x(\d+)x(\d+)/);if(!h)return[c];const a=+h[1],u=+h[2],d=+h[3],m=c.scale||{x:1,y:1,z:1},b=c.padding||{x:0,y:0,z:0},y=c.origin||{x:0,y:0,z:0},f=new g.Vector3((m.x-b.x*(a-1))/a,(m.y-b.y*(u-1))/u,(m.z-b.z*(d-1))/d),v=[];let x=1;for(let C=0;C<a;C++)for(let M=0;M<u;M++)for(let O=0;O<d;O++)v.push({id:`${n}${x++}`,position:new g.Vector3(y.x+C*(f.x+b.x)+f.x/2,y.y+M*(f.y+b.y)+f.y/2,y.z-O*(f.z+b.z)-f.z/2),scale:f.clone()});return v}return[c]}function s(c){const n={};for(const h in c){const a=c[h];a&&typeof a=="object"&&"x"in a&&"y"in a&&"z"in a&&Object.keys(a).length===3?n[h]=new g.Vector3(a.x,a.y,a.z):typeof a=="string"&&a.startsWith("0x")?n[h]=new g.Color(parseInt(a)):a&&typeof a=="object"&&!Array.isArray(a)?n[h]=s(a):n[h]=a}return n}function i(c,n=null,h=null,a=!1){if(Array.isArray(c))return a?c:c.map(u=>i(u,n,c,!1));if(c&&typeof c=="object"){if(n==="histogramPads")return A(c).map(m=>s(m));if("x"in c&&"y"in c&&"z"in c&&Object.keys(c).length===3)return new g.Vector3(c.x,c.y,c.z);const u={};for(const d in c){const m=d==="histogramPads";u[d]=i(c[d],d,c,m)}return"target"in u||(u.target={entity:"*",id:"*"}),u}return typeof c=="string"&&c.startsWith("0x")?new g.Color(parseInt(c)):c}function r(c,n){if(!c||Array.isArray(n)||!n||typeof n!="object"||n instanceof g.Vector3||n instanceof g.Color)return n;const h={...c};for(const a in n){const u=c[a],d=n[a];u&&typeof u=="object"&&!Array.isArray(u)&&!(u instanceof g.Vector3)&&!(u instanceof g.Color)&&d&&typeof d=="object"&&!Array.isArray(d)&&!(d instanceof g.Vector3)&&!(d instanceof g.Color)?h[a]=r(u,d):h[a]=d}return h}const l=i(e);return r(t,l)}let Yt;class fe{constructor(){I(this,$,new Map)}getStream(t){return w(this,$).has(t)||w(this,$).set(t,new z.ReplaySubject(1)),w(this,$).get(t).asObservable()}async next(t){if(!t.id)throw new Error("Missing id in event");if(console.log(t),typeof t.obj=="string")t.obj=await le.parseFile(t.obj);else if(typeof t.obj=="object")t.obj=await he.parseJson(t.obj),t.opts=t.opts||{},t.opts.config=Vt(t.opts.config);else throw new Error("Unsupported data type");w(this,$).has(t.id)||w(this,$).set(t.id,new z.ReplaySubject(1)),w(this,$).get(t.id).next(t)}}$=new WeakMap;const ge=()=>(Yt||(Yt=new fe),Yt);let qt;class me{constructor(){I(this,ht);X(this,ht,new z.ReplaySubject(1))}getObservable(){return w(this,ht).asObservable()}next(t){w(this,ht).next(t)}}ht=new WeakMap;const It=()=>(qt||(qt=new me),qt),pe={config:{environment:{dbClickTimeout:200,desktopSpeed:10,vrSpeed:10,camera:{position:{x:0,y:1.7,z:10}},canvas:{position:{x:0,y:20,z:-20},rotation:{x:8,y:0,z:0},scale:{x:6,y:5,z:1}},histogramPads:{type:"grid1x1x1",prefix:"histogram",scale:{x:20,y:10,z:10},padding:{x:0,y:0,z:0},origin:{x:-10,y:0,z:-5}}},histogram:{padding:{default:{x:0,y:0,z:0},layer:[],sets:{x:0,y:0,z:0}},scale:{default:{min:.5,max:1},layer:[]},sets:{scale:{maximum:"relative"}},TH1ZScale:{default:.8,layer:[1,1,1,1],set:.01},wireframe:{display:{start:0,end:4},displaySets:!1,layer:[],color:{default:"0x00FF00",layer:["0x000000","0x0000FF","0x00FF00","0x00FFFF"],set:[]}},color:{default:{min:"0x0000ff",max:"0xff0000"},layer:[],set:[{min:"0x222222",max:"0xffaa00"},{min:"0x00ffff",max:"0xff7f00"},{min:"0x00ff00",max:"0x800080"},{min:"0x0000ff",max:"0xff0000"}]}},bindings:{resetHistogram:"r",goToPreviousLayer:"z",hideOutlines:"o"}}};let Gt;class be{constructor(){I(this,U);X(this,U,new z.BehaviorSubject(Vt(pe,{})))}getObservable(){return w(this,U).asObservable()}getValue(){return w(this,U).getValue()}next(t){const e=Vt(t,w(this,U).getValue());return w(this,U).next(e),e}appendPads(t,e,A){const s=ue(w(this,U).getValue(),t,e,A);w(this,U).next(s)}mergeHistogramConfig(t,e=w(this,U).value.config.histogram){if(t==null)return e;if(typeof e!="object"||e===null||typeof t!="object"||t===null)return t;const A=i=>Array.isArray(i)||i instanceof g.Color||i instanceof g.Vector3||i&&i.isColor===!0||i&&i.isVector3===!0;if(A(e))return A(t)?t:e;const s={...e};for(const i in t)t.hasOwnProperty(i)&&t[i]!==void 0&&(A(t[i])||A(s[i])?s[i]=t[i]:typeof t[i]=="object"&&t[i]!==null&&typeof s[i]=="object"&&s[i]!==null?s[i]=this.mergeHistogramConfig(t[i],s[i]):s[i]=t[i]);return s}}U=new WeakMap;const it=()=>(Gt||(Gt=new be),Gt);let Et;class we{constructor(){I(this,ct);X(this,ct,new z.ReplaySubject(1))}getObservable(){return w(this,ct).asObservable()}getValue(){return w(this,ct).getValue()}next(t){w(this,ct).next(t)}}ct=new WeakMap;const Xt=()=>(Et||(Et=new we),Et);let Qt;class ve{constructor(){I(this,st);I(this,J);X(this,st,document.createElement("a-entity")),w(this,st).id="cameraRig",w(this,st).setAttribute("position","0 1.6 0"),w(this,st).innerHTML=`
|
|
2
|
+
<a-camera id="camera" wasd-controls-custom="acceleration: 10" wasd-controls="acceleration: 50">
|
|
3
|
+
</a-camera>
|
|
4
|
+
`,X(this,J,document.createElement("a-entity")),w(this,J).id="oculus-controller",w(this,J).setAttribute("oculus-controller",""),Mt().getObservable().subscribe(this.handleStateChange.bind(this))}handleStateChange(t){const e=document.getElementById("cameraRig");if(t.inputDevice==="oculus"){if(!e||e.contains(w(this,J)))return;e.appendChild(w(this,J))}else{if(!e||!e.contains(w(this,J)))return;e.removeChild(w(this,J))}}getCamera(){return w(this,st)}}st=new WeakMap,J=new WeakMap;const ye=()=>(Qt||(Qt=new ve),Qt.getCamera());let Ft;class Ce{constructor(){I(this,W);I(this,at);p(this,"verticalMoveCamera",(t,e)=>{if(w(this,W)===null&&X(this,W,document.getElementById("cameraRig")),w(this,W)!==null){const A=new g.Vector3,s=w(this,W).object3D.position.clone();t?(A.copy(s).add(new g.Vector3(0,+e,0)),w(this,W).object3D.position.lerp(A,.5)):w(this,W).object3D.position.y>1.6&&(A.copy(s).add(new g.Vector3(0,-e,0)),w(this,W).object3D.position.lerp(A,.5))}});p(this,"horizontalMoveCameraLocal",(t,e,A)=>{if(!w(this,W)||!w(this,at))return;let s=new g.Vector2(t,e),i=w(this,at).object3D.rotation.y;s.rotateAround(new g.Vector3(0,0),-i),s.normalize(),s.multiplyScalar(A),w(this,W).object3D.position.x+=s.x,w(this,W).object3D.position.z+=s.y});setTimeout(()=>{X(this,W,document.getElementById("cameraRig")),X(this,at,document.getElementById("camera"))},100)}getCamera(){return w(this,at)}}W=new WeakMap,at=new WeakMap;const xe=()=>(Ft||(Ft=new Ce),Ft),Ut="data:image/png;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAws/8fNABrcJixPQsAAAAASUVORK5CYII=",Be="data:image/png;base64,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",De="data:image/png;base64,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";class ze{constructor(){I(this,pt);I(this,bt);I(this,ut);I(this,_);X(this,ut,xe()),setTimeout(()=>{this.setUpArrowListener(),this.setDownArrowListener()},100),this.setUpArrowListener=this.setUpArrowListener.bind(this),this.startUpClick=this.startUpClick.bind(this),this.endUpClick=this.endUpClick.bind(this),this.upClickFunction=this.upClickFunction.bind(this),this.setDownArrowListener=this.setDownArrowListener.bind(this),this.startDownClick=this.startDownClick.bind(this),this.endDownClick=this.endDownClick.bind(this),this.downClickFunction=this.downClickFunction.bind(this),this.initController(),Mt().getObservable().subscribe(t=>{if(t.inputDevice==="mobile")document.getElementById("container").appendChild(this.getController());else{const e=document.getElementById("container");if(!e||!e.contains(this.getController()))return;e.removeChild(this.getController())}})}getController(){return w(this,_)}upClickFunction(){w(this,ut).verticalMoveCamera(!0,.15)}downClickFunction(){w(this,ut).verticalMoveCamera(!1,.15)}startUpClick(t){t.preventDefault(),this.upClickFunction(),X(this,pt,setInterval(this.upClickFunction,10))}endUpClick(){clearInterval(w(this,pt))}startDownClick(t){t.preventDefault(),this.downClickFunction(),X(this,bt,setInterval(this.downClickFunction,10))}endDownClick(){clearInterval(w(this,bt))}setUpArrowListener(){const t=document.getElementById("up-arrow");t?(t.addEventListener("touchstart",this.startUpClick),t.addEventListener("touchend",this.endUpClick)):setTimeout(this.setUpArrowListener,100)}setDownArrowListener(){const t=document.getElementById("down-arrow");t?(t.addEventListener("touchstart",this.startDownClick),t.addEventListener("touchend",this.endDownClick)):setTimeout(this.setUpArrowListener,100)}clearUpArrowListener(){const t=document.getElementById("up-arrow");t&&(t.removeEventListener("touchstart",this.startUpClick),t.removeEventListener("touchend",this.endUpClick))}clearDownArrowListener(){const t=document.getElementById("down-arrow");t&&(t.removeEventListener("touchstart",this.startDownClick),t.removeEventListener("touchend",this.endDownClick))}initController(){X(this,_,document.createElement("div")),w(this,_).className="mainUI",w(this,_).id="uiDiv",w(this,_).oncontextmenu=t=>t.preventDefault(),w(this,_).innerHTML=`
|
|
5
|
+
<div class="mainUI" id="uiDiv" oncontextmenu="event.preventDefault()">
|
|
6
|
+
<!-- top-left-->
|
|
7
|
+
<div class="regionUI skyColor" style="top: 10px; left: 10px;" oncontextmenu="event.preventDefault()">
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<!-- top-right-->
|
|
11
|
+
<div class="regionUI" style="top: 10px; right: 10px;">
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<!-- bottom-left-->
|
|
15
|
+
<div class="regionUI" style="bottom: 50px; left: 50px; flex-direction: column;">
|
|
16
|
+
<div style="display: flex; flex-direction: row; margin-left: -32px;">
|
|
17
|
+
<div id="up-arrow" class="buttonUI" style="width: 64px; height: 64px;">
|
|
18
|
+
<img style="transform: rotate(0deg);" src="${Ut}" alt="Up Arrow" />
|
|
19
|
+
</div>
|
|
20
|
+
<div id="down-arrow" class="buttonUI" style="width: 64px; height: 64px;">
|
|
21
|
+
<img style="transform: rotate(180deg);" src="${Ut}" alt="Down Arrow" />
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="buttonUI" style="width: 128px; opacity: 0.8;">
|
|
25
|
+
<img src="${Be}" alt="Joystick Base" />
|
|
26
|
+
<div id="stick1" style="position: absolute;">
|
|
27
|
+
<img src="${De}" alt="Joystick Blue" />
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<!-- bottom-right-->
|
|
33
|
+
<div class="regionUI baseColor" style="bottom: 10px; right: 10px;">
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
`}}pt=new WeakMap,bt=new WeakMap,ut=new WeakMap,_=new WeakMap;const Me=async o=>{let t;o.startsWith("root://")?t=o.replace(/^root:\/\//,"https://").replace(/\/\//g,"/"):t=o,console.log(`Fetching from URL: ${t}`);const e=await fetch(t);if(!e.ok)throw new Error(`Response status: ${e.status}`);return e.json()};class Oe{constructor(t,e){p(this,"raycaster");p(this,"mouse");p(this,"cameraElement");p(this,"sceneElement");p(this,"singleClickTimer");p(this,"dbClickTimeout");p(this,"configSub");p(this,"rendererElement");p(this,"raycastOn");this.singleClickTimer=null,this.dbClickTimeout=190,this.raycastOn=!0,this.rendererElement=e,this.raycaster=new g.Raycaster,this.mouse=new g.Vector2,this.sceneElement=t,this.checkInterval=1,this.lastCheck=void 0,t.traverse(A=>{A.isCamera&&(this.cameraElement=A)}),this.mousemoveEventHandle=this.mousemoveEventHandle.bind(this),this.clickEventHandle=this.clickEventHandle.bind(this),this.setupRaycasting(),this.configSub=it().getObservable().subscribe(A=>{this.dbClickTimeout=A.config.environment.dbClickTimeout??190})}setupRaycasting(){window.addEventListener("mousemove",this.mousemoveEventHandle),window.addEventListener("click",this.clickEventHandle)}destroyRaycasting(){window.removeEventListener("mousemove",this.mousemoveEventHandle),window.removeEventListener("click",this.clickEventHandle)}toggleRaycasting(){this.raycastOn=!this.raycastOn,this.raycastOn?this.setupRaycasting():this.destroyRaycasting()}mousemoveEventHandle(t){const e=performance.now();e-this.lastCheck<this.checkInterval||(this.lastCheck=e,this.updateRaycaster(t))}clickEventHandle(t){const e=this.rendererElement.getBoundingClientRect();this.mouse.x=(t.clientX-e.left)/e.width*2-1,this.mouse.y=-((t.clientY-e.top)/e.height)*2+1,this.raycaster.setFromCamera(this.mouse,this.cameraElement);const A=Date.now(),i=(this.lastClick?A-this.lastClick:1/0)<this.dbClickTimeout;this.singleClickTimer&&(clearTimeout(this.singleClickTimer),this.singleClickTimer=null),i?(this.raycaster._triggerSource=t.shiftKey?"shiftmousedbclick":"mousedbclick",this.handleRaycast()):this.singleClickTimer=setTimeout(()=>{this.raycaster._triggerSource=t.shiftKey?"shiftmouseclick":"mouseclick",this.handleRaycast(),this.singleClickTimer=null},this.dbClickTimeout),this.lastClick=A}handleRaycast(){this.raycaster.intersectObjects(this.sceneElement.children,!0).length>0}updateRaycaster(t){const e=this.rendererElement.getBoundingClientRect();this.mouse.x=(t.clientX-e.left)/e.width*2-1,this.mouse.y=-((t.clientY-e.top)/e.height)*2+1,this.raycaster.setFromCamera(this.mouse,this.cameraElement),this.raycaster._triggerSource="mousemove",this.raycaster.intersectObjects(this.sceneElement.children,!0)}}class Zt{constructor(t){this.limits=new Int32Array(t),this.values=new Int32Array(t.length)}increment(){for(let t=0;t<this.values.length;t++){if(this.values[t]++,this.values[t]<this.limits[t])return!0;this.values[t]=0}return!1}getIndex(){let t=0,e=1;for(let A=0;A<this.values.length;A++)t+=this.values[A]*e,e*=this.limits[A];return t}setFromNumber(t){for(let e=0;e<this.limits.length;e++)this.values[e]=Math.floor(t%this.limits[e]),t=Math.floor(t/this.limits[e])}getValueAt(t){return this.values[t]}getValues(){return[...this.values]}reset(){this.values.fill(0)}}function He(o,t){return t<=0?o.fXmin:t>o.fNbins?o.fXmax:o.GetBinLowEdge(t+1)}function St(o,t,e,A,s,i,r){const l=t+1,c=o.GetBinLowEdge(l),n=He(o,l),h=Math.abs(n-c);if(r.size=h,r.pos=c+h*.5-o.fXmin,e){const u=(o.fXmax-o.fXmin)*o.fNbins/(e*o.fNbins);r.pos/=u,r.size/=u,r.size*=1-A,r.pos-=e*.5,r.pos+=s}}function Pe(o,t,e,A,s,i,r){St(o.fXaxis,t.x,e==null?void 0:e.x,A==null?void 0:A.x,s==null?void 0:s.x,i,r.x),St(o.fYaxis,t.y,e==null?void 0:e.z,A==null?void 0:A.y,s==null?void 0:s.z,i,r.y),St(o.fZaxis,t.z,e==null?void 0:e.y,A==null?void 0:A.z,s==null?void 0:s.y,i,r.z)}function Ve(o){const t=o.y.size,e=o.y.pos;return o.y.size=o.z.size,o.y.pos=o.z.pos,o.z.size=t,o.z.pos=e,o}function Ye(o,t,e,A,s,i,r){return Pe(o,t,A,e,s,i,r),r}function qe(o,t,e){return e.z.pos=2*o-e.z.pos,e}function Jt(o,t){if(o.length!==t.length)return!1;const e={};for(const A of o)e[A]=(e[A]||0)+1;for(const A of t){if(!e[A])return!1;e[A]--}return!0}function Tt(o,t,e,A){let s=Array(o.length).fill(0);const i=(r,l,c)=>{const n=l.fXaxis.fNbins,h=l.fYaxis.fNbins;l.fZaxis.fNbins;const u=e.slice(-e.length+r+1).reduce((d,m)=>d*m,1);if(s[c]+=(o[r].x+o[r].y*n+o[r].z*n*h)*u,r+1<o.length){let d;l.children.content?d=l.children.content[l.getBin(o[r].x+1,o[r].y+1,o[r].z+1)]:d=l.children[A[0]][l.getBin(o[r].x+1,o[r].y+1,o[r].z+1)],c>r&&i(r+1,d,c)}};for(let r=0;r<o.length;r++)i(0,t,r);return s}function ft(o,t,e){var s;let A=Array(o.length).fill(0);for(let i=0;i<o.length;i++)if(A[i]=t.getBin(o[i].x+1,o[i].y+1,o[i].z+1),t.children)(s=t.children)!=null&&s.content?t=t.children.content[A[i]]:t=t.children[e[0]][A[i]];else return A;return A}function gt(o,t,e,A,s,i=0){var n,h,a,u;const r=["x","y","z"],l=Number.parseInt(e._typename.substring(2,3),10);let c={};if(o[0]){for(let d=0;d<l;d++){const m=r[d],b=e[`f${m.toUpperCase()}axis`],y=o[0][m];c[m]={min:b.GetBinLowEdge(y+1),max:b.GetBinCenter(y+1)*2-b.GetBinLowEdge(y+1),name:b.fName,title:b.fTitle,label:(h=(n=b.fLabels)==null?void 0:n.arr[y])==null?void 0:h.fString}}c={...c,color:A.getColorAt(i,t),name:e.fName}}if(o[1]){let d;return(a=e.children)!=null&&a.content?d=e.children.content[e.getBin(o[0].x+1,o[0].y+1,o[0].z+1)]:(u=e.children)!=null&&u[s[0]]&&(d=e.children[s[0]][e.getBin(o[0].x+1,o[0].y+1,o[0].z+1)]),[c,...gt(o.slice(1),t,d,A,s,i+1)]}else return[c]}function Ie(o,t,e,A){let s=0;const i=e.slice(1),r=[];for(let c=0;c<i.length;c++){const n=i.slice(c).reduce((h,a)=>h*a,1);r.push(n)}const l=(c,n)=>{const{fNbins:h}=n.fXaxis,{fNbins:a}=n.fYaxis,{fNbins:u}=n.fZaxis,d=o[c].x+o[c].y*h+o[c].z*h*a;if(s+=d*r[c],c+1<o.length){const m=Ge(n,o[c],A);l(c+1,m)}};return l(0,t),s}function Ge(o,t,e){const A=o.getBin(t.x+1,t.y+1,t.z+1);return o.children.content?o.children.content[A]:o.children[e[0]][A]}function Ee(o){if(!o)return;const t=s=>{let i=-1/0;for(let r=0;r<s.length;r++){const l=s[r];l>i&&(i=l)}return i},e=[];e[0]={content:t(o.fArray)},o.fArrays&&Object.keys(o==null?void 0:o.fArrays).forEach(s=>{e[0]={...e[0],[s]:t(o.fArrays[s])}});const A=(s,i=1)=>{e[i]||(e[i]={}),Object.entries(s).forEach(([r,l])=>{l.forEach(c=>{if(!c)return;const n=t(c.fArray);(!(r in e[i])||n>e[i][r])&&(e[i][r]=n),c.children&&A(c.children,i+1)})})};return o.children&&A(o.children),e}function Xe(o){if(!o)return;const t=s=>{let i=1/0;for(let r=0;r<s.length;r++){const l=s[r];l<i&&(i=l)}return i},e=[];e[0]={content:t(o.fArray.filter(s=>s!==0))},o.fArrays&&Object.keys(o==null?void 0:o.fArrays).forEach(s=>{e[0]={...e[0],[s]:t(o.fArrays[s].values.filter(i=>i!==0))}});const A=(s,i=1)=>{e[i]||(e[i]={}),Object.entries(s).forEach(([r,l])=>{l.forEach(c=>{if(!c)return;const n=t(c.fArray.filter(h=>h!==0));(!(r in e[i])||n>e[i][r])&&(e[i][r]=n),c.children&&A(c.children,i+1)})})};return o.children&&A(o.children),e}function Qe(o){if(!o)return;const t=o.fXaxis.fNbins*o.fYaxis.fNbins*o.fZaxis.fNbins;let e=[];e.push(t);const A=(s,i=1)=>{let r=0;return i>=e.length&&e.push(0),Object.entries(s).forEach((l,c)=>{l[1].forEach(n=>{n&&(r=n.fXaxis.fNbins*n.fYaxis.fNbins*n.fZaxis.fNbins,r>e[i]&&(e[i]=r),n.children&&A(n.children,i+1))})}),e};return o.children&&A(o.children),e.push(1),e}function Fe(o,t,e){new g.Color(o.color.default.min).toArray(e,0),new g.Color(o.color.default.max).toArray(e,3);let A=1;o.color.layer.forEach(s=>{const i=A*6;new g.Color(s.min).toArray(e,i),new g.Color(s.max).toArray(e,i+3),A++}),o.color.set.forEach(s=>{const i=A*6;new g.Color(s.min).toArray(e,i),new g.Color(s.max).toArray(e,i+3),A++}),t.uniforms.colorPairs={value:e},t.uniformsNeedUpdate=!0}function Se(o,t,e,A,s,i,r){const c=((h,a,u)=>(h-a)/(u-a))(e,A,s);let n=0;return o.set[i]?n=1+o.layer.length+i:o.layer[r]&&(n=1+r),n+c}function Rt(o,t,e,A,s,i,r){if(!(1/o===-1/0||o<0))return r[0]=t[o],r[1]=t[o+1],r[2]=t[o+2],r[3]=e[o],r[4]=e[o+1],r[5]=e[o+2],r;const c=Math.abs(o),n=i!==null?A[s][i]:A[s];return r[0]=n.pos[c],r[1]=n.pos[c+1],r[2]=n.pos[c+2],r[3]=n.scale[c],r[4]=n.scale[c+1],r[5]=n.scale[c+2],r}function Wt(o,t,e,A,s,i,r){const l=t.fXaxis.fNbins,c=t.fYaxis.fNbins,n=t.fZaxis.fNbins;let h=0,a=0;const u=new Float32Array((l*c*n-1)*3),d=new Float32Array((l*c*n-1)*3),m=new Float32Array(l*c*n-1),b=new Float32Array(l*c*n-1),y=new Float32Array(l*c*n-1),f=new Float32Array(6),v=new Float32Array(6),x=D=>{const H=M*3;u[H]=D[0],u[H+1]=D[1],u[H+2]=D[2],d[H]=D[3],d[H+1]=D[4],d[H+2]=D[5],m[M]=D[6],b[M]=D[7],y[M]=D[8]},C=(D,H,V,E)=>{Rt(D,u,d,o,V,E,f),Rt(H,u,d,o,V,E,v);const q=f[0]-f[3]*.5<v[0]-v[3]*.5?f[0]-f[3]*.5:v[0]-v[3]*.5,Y=f[1]-f[4]*.5<v[1]-v[4]*.5?f[1]-f[4]*.5:v[1]-v[4]*.5,N=f[2]-f[5]*.5<v[2]-v[5]*.5?f[2]-f[5]*.5:v[2]-v[5]*.5,F=f[0]+f[3]*.5>v[0]+v[3]*.5?f[0]+f[3]*.5:v[0]+v[3]*.5,j=f[1]+f[4]*.5>v[1]+v[4]*.5?f[1]+f[4]*.5:v[1]+v[4]*.5,S=f[2]+f[5]*.5>v[2]+v[5]*.5?f[2]+f[5]*.5:v[2]+v[5]*.5,Q=new Float32Array(9);return Q[0]=(q+F)*.5,Q[1]=(Y+j)*.5,Q[2]=(N+S)*.5,Q[3]=F-q,Q[4]=j-Y,Q[5]=S-N,Q};let M=0;for(let D=0;D<c;D++){for(let V=0;V<n;V++){const E=h+r;let q=new Array(l);for(let Y=0;Y<l;Y++)q[Y]=-Y-E;for(;q.length>1;){let Y=0;const N=Math.floor(q.length/2);for(let F=0;F<N;F++){const j=q[Y],S=q[Y+1],Q=C(j*3,S*3,e,A);q.splice(Y,2,M),kt(Q,i),Q[6]=1/j===-1/0||j<0?j:y[j],Q[7]=1/S===-1/0||S<0?S:y[S],Q[8]=a,x(Q),M+=1,a+=1,Y+=1}}h+=l}const H=new Array(n);for(let V=0;V<n;V++)H[V]=M-1-(n-1-V)*(l-1);for(;H.length>1;){let V=0;const E=Math.floor(H.length/2);for(let q=0;q<E;q++){const Y=H[V],N=H[V+1],F=C(Y*3,N*3,e,A);H.splice(V,2,M),kt(F,i),F[6]=y[Y],F[7]=y[N],F[8]=a,x(F),M+=1,a+=1,V+=1}}}const O=new Array(c);for(let D=0;D<c;D++)O[D]=M-1-(c-1-D)*(l*n-1);for(;O.length>1;){let D=0;const H=Math.floor(O.length/2);for(let V=0;V<H;V++){const E=O[D],q=O[D+1],Y=C(E*3,q*3,e,A);O.splice(D,2,M),kt(Y,i),Y[6]=y[E],Y[7]=y[q],Y[8]=a,x(Y),M+=1,a+=1,D+=1}}return{pos:u,scale:d,left:m,right:b}}function Te(o,t,e,A,s,i,r){const l=new Array(o.length).fill().map(n=>[]);l[l.length-1]=Array.from({length:s.length},()=>[]),l[0]=[Wt(o,t,e,null,s,i,0)];const c=(n,h,a)=>{var y;if(!n.children)return;const u=new Zt([n.fXaxis.fNbins,n.fYaxis.fNbins,n.fZaxis.fNbins]),d=n.fXaxis.fNbins*n.fYaxis.fNbins*n.fZaxis.fNbins,m=r.slice(1,h-1).reduce((f,v)=>f*v,r[1]),b=r[h];for(let f=0;f<d;f++){const v={x:u.getValueAt(0),y:u.getValueAt(1),z:u.getValueAt(2)};if((y=n==null?void 0:n.children)!=null&&y.content){const x=n.children.content[n.getBin(v.x+1,v.y+1,v.z+1)];if(!x){if(u.increment()===!1)break;continue}l[h][f+a]=Wt(o,x,h,null,s,i,(f+a)*b),c(x,h+1,(u.getIndex()+a)*m)}else n.children&&!n.children.hasOwnProperty("content")&&A.forEach(x=>{const C=s.indexOf(x),M=(f+a)*b;let O=!1;for(let H=M;H<M+r[h];H++)if(o[h][C].rendered[H]!==-1){O=!0;break}if(!O){l[h][C].push(null);return}const D=n.children[x][n.getBin(v.x+1,v.z+1,v.y+1)];D&&(l[h][C][f+a]=Wt(o,D,h,C,s,i,(f+a)*b),c(D,h+1,(u.getIndex()+a)*m))});if(u.increment()===!1)break}};return c(t,1,0),l}function kt(o,t){const e=t.elements,A=Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]),s=Math.sqrt(e[4]*e[4]+e[5]*e[5]+e[6]*e[6]),i=Math.sqrt(e[8]*e[8]+e[9]*e[9]+e[10]*e[10]);o[0]=o[0]*A+e[12],o[1]=o[1]*s+e[13],o[2]=o[2]*i+e[14],o[3]=o[3]*A,o[4]=o[4]*s,o[5]=o[5]*i}class Lt{constructor(t){p(this,"rootObj");p(this,"origin");p(this,"parentPath",[]);p(this,"path");p(this,"title");p(this,"range",[]);p(this,"isOnSet",!1);this.rootObj=t,this.origin=this.rootObj,this.title=this.origin.fTitle,this.path=this.origin.fName}setOriginToChild(t,e,A){var i,r;if(!t)return;const s=t.splice(0,1);if((i=this.origin)!=null&&i.children){if((r=this.origin.children)!=null&&r.content)this.parentPath.push({origin:this.origin,range:A,bin:s}),this.origin=this.origin.children.content[s],this.isOnSet=!1;else if(Object.keys(this.origin.children).includes(e))this.parentPath.push({origin:this.origin,range:A,bin:s}),this.origin=this.origin.children[e][s],this.isOnSet=!0;else{console.error("Bad set or index specified.");return}this.title=this.origin.fTitle,this.path=this.path+"/"+this.origin.fName,t.length>0&&this.setOriginToChild(t,e)}}getChildByPosition(t,e,A=this.origin){var i;if(!t||t.length===0)return A;const s=t.pop();return A!=null&&A.children?(i=A.children)!=null&&i.content?this.getChildByPosition(t,e,A.children.content[s]):Object.keys(A.children).includes(e)?this.getChildByPosition(t,e,A.children[e][s]):(console.error("Bad set or index specified."),null):A}setOriginToParent(t=1){if(t<=0||this.parentPath.length===0)return;const e=this.path.lastIndexOf("/");this.path=this.path.slice(0,e);const A=this.parentPath.pop();A&&(this.origin=A.origin),this.title=this.origin.fTitle,this.setOriginToParent(t-1),this.isOnSet=!1}}class We{constructor(t,e,A){p(this,"wireframe");p(this,"instGeom");p(this,"material");p(this,"totalInstances");p(this,"maxInstancesPerLayer");p(this,"instancePositions");p(this,"instanceScales");p(this,"instanceColors");p(this,"colorArray");p(this,"configSub");p(this,"stateSub");p(this,"config");p(this,"numOfavailableSets");p(this,"visibility",!0);this.config=A,this.maxInstancesPerLayer=t;const s=new g.BoxGeometry(1,1,1),i=new g.EdgesGeometry(s);this.instGeom=new g.InstancedBufferGeometry,this.instGeom.instanceCount=0,this.instGeom.frustumCulled=!1,this.instGeom.index=i.index;for(const r in i.attributes)this.instGeom.setAttribute(r,i.attributes[r]);this.material=this.createMaterial(),this.colorArray=new Float32Array(32*3),this.fillColorArray(),this.instancePositions=new Float32Array(3),this.instanceScales=new Float32Array(3),this.instanceColors=new Float32Array(1),this.instGeom.setAttribute("instancePosition",new g.InstancedBufferAttribute(this.instancePositions,3)),this.instGeom.setAttribute("instanceScale",new g.InstancedBufferAttribute(this.instanceScales,3)),this.instGeom.setAttribute("instanceColorIndex",new g.InstancedBufferAttribute(this.instanceColors,1)),this.wireframe=new g.LineSegments(this.instGeom,this.material),this.wireframe.frustumCulled=!1,this.stateSub=R().getObservable().subscribe(r=>{this.numOfavailableSets=r.sets.length})}pushVisibleInstances(t,e,A){let s=this.wireframe.parent;s&&(s.remove(this.wireframe),this.instGeom.dispose());const i=[],r=t.length-1;{const v=(Array.isArray(t[r])?t[r][A]:t[r]).rendered,x=new Uint8Array(v.length);for(let C=0;C<v.length;C++)x[C]=v[C]!==-1?1:0;i[r]=x}for(let f=r-1;f>=0;f--){const x=(Array.isArray(t[f])?t[f][A]:t[f]).rendered,C=i[f+1],M=e[f+1]||0,O=new Uint8Array(x.length);for(let D=0;D<x.length;D++){if(x[D]!==-1){O[D]=1;continue}const H=D*M,V=H+M;for(let E=H;E<V;E++)if(C[E]){O[D]=1;break}}i[f]=O}const l=(f,v)=>i[f][v]===1,c=(f,v)=>{let x=0,C=f,M=v;for(;C+1<t.length;){C++,M*=e[C];const O=t[C],D=Array.isArray(O)?O[A]:O;for(let H=M;H<M+e[C];H++)if(D.rendered[H]!==-1){x=C-f;break}}return x};let n=0;for(let f=0;f<t.length;f++){const v=t[f];if(!Array.isArray(v))for(let x=0;x<v.rendered.length;x++)l(f,x)&&n++}const h=new Float32Array(n*3),a=new Float32Array(n*3),u=new Float32Array(n);let d=0;for(let f=0;f<t.length;f++){const v=t[f],x=this.getColorIndex(f,A);if(!Array.isArray(v)){for(let C=0;C<v.rendered.length;C++)if(l(f,C)){const M=c(f,C)*.05;h[d*3]=v.pos[C*3],h[d*3+1]=v.pos[C*3+1],h[d*3+2]=v.pos[C*3+2],a[d*3]=v.scale[C*3]+M,a[d*3+1]=v.scale[C*3+1]+M,a[d*3+2]=v.scale[C*3+2]+M,u[d++]=x}}}const m=new g.BoxGeometry(1,1,1),b=new g.EdgesGeometry(m);this.instGeom=new g.InstancedBufferGeometry,this.instGeom.instanceCount=n,this.instGeom.frustumCulled=!1,this.instGeom.index=b.index;const y=b.attributes;for(const f in y)this.instGeom.setAttribute(f,y[f]);this.instancePositions=h,this.instanceScales=a,this.instanceColors=u,this.instGeom.setAttribute("instancePosition",new g.InstancedBufferAttribute(h,3)),this.instGeom.setAttribute("instanceScale",new g.InstancedBufferAttribute(a,3)),this.instGeom.setAttribute("instanceColorIndex",new g.InstancedBufferAttribute(u,1)),this.wireframe=new g.LineSegments(this.instGeom,this.material),this.wireframe.frustumCulled=!1,s&&s.add(this.wireframe)}toggleVisibility(t,e,A){this.visibility=!this.visibility,this.visibility?this.pushVisibleInstances(t,e,A):this.clearWireframe()}dispose(){this.instancePositions=[],this.instanceScales=[],this.wireframe.parent.remove(this.wireframe),this.instGeom.dispose()}clearWireframe(){this.instancePositions=new Float32Array(3),this.instanceScales=new Float32Array(3),this.instanceColors=new Float32Array(1),this.instGeom.dispose(),this.instGeom.instanceCount=0}fillColorArray(){new g.Color(this.config.color.default).toArray(this.colorArray,0);let t=1;this.config.color.layer.map(e=>new g.Color(e)).forEach(e=>{const A=t*3;e.toArray(this.colorArray,A),t++}),this.config.color.set.map(e=>new g.Color(e)).forEach(e=>{const A=t*3;e.toArray(this.colorArray,A),t++}),this.material.uniforms.colorArray={value:this.colorArray},this.material.uniformsNeedUpdate=!0}createMaterial(){return new g.ShaderMaterial({vertexShader:`
|
|
37
|
+
attribute vec3 instancePosition;
|
|
38
|
+
attribute vec3 instanceScale;
|
|
39
|
+
attribute float instanceColorIndex;
|
|
40
|
+
|
|
41
|
+
uniform vec3 colorArray[32]; // must match maxColors in JS
|
|
42
|
+
|
|
43
|
+
varying vec3 vColor;
|
|
44
|
+
|
|
45
|
+
void main() {
|
|
46
|
+
vec3 transformed = position * instanceScale + instancePosition;
|
|
47
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(transformed, 1.0);
|
|
48
|
+
|
|
49
|
+
int idx = int(instanceColorIndex);
|
|
50
|
+
vColor = colorArray[idx];
|
|
51
|
+
}
|
|
52
|
+
`,fragmentShader:`
|
|
53
|
+
varying vec3 vColor;
|
|
54
|
+
void main() {
|
|
55
|
+
gl_FragColor = vec4(vColor, 1.0);
|
|
56
|
+
}
|
|
57
|
+
`,transparent:!1})}getColorIndex(t,e){return this.config.color.set[e]?this.config.color.layer.length+1:this.config.color.layer[t]?t+1:0}getColorAt(t,e){return this.config.color.set[e]?this.config.color.set[e]:this.config.color.layer[t]?this.config.color.layer[t]:this.config.color.default}}class ke{constructor(t,e,A){p(this,"id");p(this,"functionSub");p(this,"configSub");p(this,"dispatchSub");p(this,"rootObj");p(this,"config");p(this,"limits",{position:new g.Vector3(0,0,0),scale:new g.Vector3(10,10,10)});p(this,"mouseEvents",[]);p(this,"keydownEvents",[]);p(this,"keyupEvents",[]);p(this,"keyBindings",{});p(this,"opts");var s;this.rootObj=t.obj,this.id=e,this.opts=A,this.config=it().mergeHistogramConfig((s=this==null?void 0:this.opts)==null?void 0:s.config),this.functionSub=Pt().getObservable().pipe(z.filter(i=>i.target.entity==="nested-histogram"&&(i.target.id.includes("*")||i.target.id.includes(this.id)))).subscribe(i=>this.functionSubjectHandler(i)),this.configSub=it().getObservable().pipe(z.filter(i=>i.target.id.includes("*")||i.target.id.includes(this.id))).subscribe(i=>{var l;this.config=it().mergeHistogramConfig((l=this==null?void 0:this.opts)==null?void 0:l.config),this.keyBindings=de(i.config.bindings);const r=i.config.environment.histogramPads.find(c=>c.id===this.id);this.limits=r??{scale:{x:20,y:10,z:20},padding:{x:0,y:0,z:0},position:{x:0,y:0,z:-5}}}),this.dispatchSub=jt().getObservable().pipe(z.filter(i=>i.target.id==="*"||i.target.id===this.id)).subscribe(i=>this.dispatchSubjectHandler(i)),this.initDefaultFunctions()}remove(){this.functionSub.unsubscribe(),this.configSub.unsubscribe(),this.dispatchSub.unsubscribe(),window.removeEventListener("keydown",this.keyDownHandler),window.removeEventListener("keydown",this.keyUpHandler)}initDefaultFunctions(){this.keyDownHandler=this.keyDownHandler.bind(this),this.keyUpHandler=this.keyUpHandler.bind(this),this.raycastHandler=this.raycastHandler.bind(this),this.mouseClickDefault=this.mouseClickDefault.bind(this),this.mousemoveDefault=this.mousemoveDefault.bind(this),this.shiftMouseClickDefault=this.shiftMouseClickDefault.bind(this),this.mouseDBClickDefault=this.mouseDBClickDefault.bind(this),this.shiftMouseDBClickDefault=this.shiftMouseDBClickDefault.bind(this),window.addEventListener("keydown",this.keyDownHandler),window.addEventListener("keydown",this.keyUpHandler),this.addEvent("mouseclick",this.mouseClickDefault),this.addEvent("mousemove",this.mousemoveDefault),this.addEvent("shiftmouseclick",this.shiftMouseClickDefault),this.addEvent("mousedbclick",this.mouseDBClickDefault),this.addEvent("shiftmousedbclick",this.shiftMouseDBClickDefault)}functionSubjectHandler(t){if(t.flag==="add")if(t.function)this.addEvent(t.event,t.function);else switch(t.event){case"mousemove":this.addEvent(t.event,this.mousemoveDefault);break;case"mouseclick":this.addEvent(t.event,this.mouseClickDefault);break;case"shiftmouseclick":this.addEvent(t.event,this.shiftMouseClickDefault);break;case"mousedbclick":this.addEvent(t.event,this.mouseDBClickDefault);break;case"shiftmousedbclick":this.addEvent(t.event,this.shiftMouseDBClickDefault);break}else if(t.flag==="remove"&&t.function)this.removeEvent(t.event,t.function);else if(t.flag==="remove")switch(t==null?void 0:t.state){case"keydown":this.keydownEvents=[];break;case"keyup":this.keyupEvents=[];break;default:this.mouseEvents=this.mouseEvents.filter(e=>e.event!==t.event)}else t.flag==="removeAll"&&(this.keydownEvents=[],this.keyupEvents=[],this.mouseEvents=[])}addEvent(t,e){(t==null?void 0:t.state)==="keydown"?this.keydownEvents.push({key:t.key,function:e}):(t==null?void 0:t.state)==="keyup"?this.keyupEvents.push({key:t.key,function:e}):this.mouseEvents.push({event:t,function:e})}removeEvent(t,e){const A=this.mouseEvents.find(s=>s===e);A&&this.mouseEvents.splice(A,1)}mouseClickDefault(t){console.log("mouse click default")}mousemoveDefault(t){console.log("mouse move default")}shiftMouseClickDefault(t){console.log("shift mouse click")}mouseDBClickDefault(t){console.log("mouseDBClick default")}shiftMouseDBClickDefault(t){console.log("shift mouse db click default")}dispatchSubjectHandler(t){console.log("dispatch: ",t)}}class Le extends ke{constructor(e,A,s){super(e,A,s);p(this,"stateSub");p(this,"pointer");p(this,"wireframe");p(this,"BVHTree",[]);p(this,"maxInstancesPerLayer");p(this,"maxContentPerLayer");p(this,"totalInstances");p(this,"color",new g.Color);p(this,"matrixCache");p(this,"selectedSet",[]);p(this,"selectedArray","content");p(this,"availableSets",[]);p(this,"renderHistory",[]);p(this,"dirtyInstance",[]);p(this,"mesh");p(this,"instGeom");p(this,"material");p(this,"instancePositions");p(this,"instanceScales");p(this,"instanceColors");p(this,"colorArray");this.pointer=new Lt(this.rootObj),this.handleStateChange=this.handleStateChange.bind(this),this.stateSub=R().getObservable().subscribe(this.handleStateChange),this.init(),this.renderHistogram(0,this.totalInstances,0)}updateHistogram(e){const A=this.mesh.parent,s=this.mesh.raycast;this.mesh.raycast=()=>{},this.matrixCache=[],this.BVHTree=[],this.availableSets=[],this.selectedSet=[],R().next({sets:[],selectedSet:[],arrays:["content"],selectedArray:"content"}),this.wireframe.dispose(),this.instGeom.dispose(),A.remove(this.mesh),this.rootObj=e.obj,this.pointer=new Lt(this.rootObj),this.init(),this.renderHistogram(0,this.totalInstances,0),setTimeout(()=>{A.add(this.mesh),this.mesh.raycast=s},0),A.add(this.wireframe.wireframe)}remove(){super.remove(),this.matrixCache=[],this.instGeom.dispose(),this.mesh.parent&&(this.mesh.parent.remove(this.mesh),this.wireframe.dispose()),this.stateSub.unsubscribe()}init(){this.setAvailableSets(this.pointer.origin),this.setAvailableArrays(this.pointer.origin),this.maxInstancesPerLayer=Qe(this.pointer.origin),this.maxContentPerLayer=Ee(this.pointer.origin),this.minContentPerLayer=Xe(this.pointer.origin),this.totalInstances=this.maxInstancesPerLayer.reduce((e,A)=>e*A,1),this.setupInsBufGeom(),this.wireframe=new We(this.maxInstancesPerLayer,this.matrixCache,this.config.wireframe)}setupMatrixCache(){this.matrixCache=new Array(this.maxInstancesPerLayer.length-1);const e=this.availableSets.length>0;e&&(this.matrixCache[this.matrixCache.length-1]=new Array(this.availableSets.length));let A=this.maxInstancesPerLayer[0];for(let i=0;i<this.maxInstancesPerLayer.length-1-(e?1:0);i++)this.matrixCache[i]={pos:new Float32Array(A*3),scale:new Float32Array(A*3),rendered:new Float32Array(A).fill(-1)},A*=this.maxInstancesPerLayer[i+1];if(!e)return;const s=this.matrixCache[this.matrixCache.length-1];for(let i=0;i<s.length;i++)s[i]={pos:new Float32Array(A*3),scale:new Float32Array(A*3),rendered:new Float32Array(A).fill(-1)}}setupInsBufGeom(){this.setupMatrixCache();let e=this.maxInstancesPerLayer.reduce((s,i)=>s*i,1);this.selectedSet.length>1&&(e*=this.selectedSet.length);const A=new g.BoxGeometry(1,1,1);this.instGeom=new g.InstancedBufferGeometry,this.instGeom.instanceCount=0,this.instGeom.frustumCulled=!1,this.instGeom.index=A.index;for(const s in A.attributes)this.instGeom.setAttribute(s,A.attributes[s]);this.material=this.createMaterial(),this.colorArray=new Float32Array(32*6),this.material.uniforms.colorArray={value:this.colorArray},Fe(this.config,this.material,this.colorArray),this.instancePositions=new Float32Array(3),this.instanceScales=new Float32Array(3),this.instanceColors=new Float32Array(1),this.instGeom.setAttribute("instancePosition",new g.InstancedBufferAttribute(this.instancePositions,3)),this.instGeom.setAttribute("instanceScale",new g.InstancedBufferAttribute(this.instanceScales,3)),this.instGeom.setAttribute("instanceColorIndex",new g.InstancedBufferAttribute(this.instanceColors,1)),this.mesh=new g.Mesh(this.instGeom,this.material),this.mesh.raycast=this.raycastHandler,this.mesh.frustumCulled=!1,this.material.uniforms.colorArray={value:this.colorArray},this.mesh.material.uniformsNeedUpdate=!0}pushVisibleInstances(){let e=this.mesh.parent;e&&(e.remove(this.mesh),this.instGeom.dispose());let A=0;for(let h=0;h<this.matrixCache.length;h++){const a=this.matrixCache[h];if(Array.isArray(a))for(let u=0;u<a.length;u++){const d=a[u];for(let m=0;m<d.rendered.length;m++)d.rendered[m]!==-1&&A++}else for(let u=0;u<a.rendered.length;u++)a.rendered[u]!==-1&&A++}const s=new Float32Array(A*3),i=new Float32Array(A*3),r=new Float32Array(A);let l=0;for(let h=0;h<this.matrixCache.length;h++){const a=this.matrixCache[h];if(Array.isArray(a))for(let u=0;u<a.length;u++){const d=a[u];for(let m=0;m<d.rendered.length;m++)d.rendered[m]!==-1&&(s[l*3]=d.pos[m*3],s[l*3+1]=d.pos[m*3+1],s[l*3+2]=d.pos[m*3+2],i[l*3]=d.scale[m*3],i[l*3+1]=d.scale[m*3+1],i[l*3+2]=d.scale[m*3+2],r[l++]=d.rendered[m])}else for(let u=0;u<a.rendered.length;u++)a.rendered[u]!==-1&&(s[l*3]=a.pos[u*3],s[l*3+1]=a.pos[u*3+1],s[l*3+2]=a.pos[u*3+2],i[l*3]=a.scale[u*3],i[l*3+1]=a.scale[u*3+1],i[l*3+2]=a.scale[u*3+2],r[l++]=a.rendered[u])}const c=new g.BoxGeometry(1,1,1);this.instGeom=new g.InstancedBufferGeometry,this.instGeom.instanceCount=A,this.instGeom.frustumCulled=!1,this.instGeom.index=c.index;const n=c.attributes;for(const h in n)this.instGeom.setAttribute(h,n[h]);this.instancePositions=s,this.instanceScales=i,this.instanceColors=r,this.instGeom.setAttribute("instancePosition",new g.InstancedBufferAttribute(s,3)),this.instGeom.setAttribute("instanceScale",new g.InstancedBufferAttribute(i,3)),this.instGeom.setAttribute("instanceColorIndex",new g.InstancedBufferAttribute(r,1)),this.mesh=new g.Mesh(this.instGeom,this.material),this.mesh.raycast=this.raycastHandler,this.mesh.frustumCulled=!1,e&&e.add(this.mesh)}setMatrixCacheAt(e,A,s,i,r){const l=A!==null?this.matrixCache[e][A]:this.matrixCache[e];l.pos[s*3]=i.x.pos,l.pos[s*3+1]=i.y.pos,l.pos[s*3+2]=i.z.pos,l.scale[s*3]=i.x.size,l.scale[s*3+1]=i.y.size,l.scale[s*3+2]=i.z.size,l.rendered[s]=r}renderHistogram(e,A,s){if(!this.pointer||s>=this.maxInstancesPerLayer.length-1)return;this.logRender({procedure:"render",value:{startIndex:e,endIndex:A,layer:s}});const i={x:{size:0,pos:0},y:{size:0,pos:0},z:{size:0,pos:0}},r=async(l,c,n,h,a,u)=>{var N,F,j,S,Q,Kt,$t;if(n>s||!h)return;const d=new Zt([h.fXaxis.fNbins,h.fYaxis.fNbins,h.fZaxis.fNbins]);let m,b,y,f;const v=((F=(N=h.fArrays)==null?void 0:N[this.selectedArray])==null?void 0:F.outside)??!1,x=this.selectedSet.indexOf(u),C=this.availableSets.indexOf(u);if(this.config.sets.scale.maximum==="relative"){const k=(j=h.fArrays)==null?void 0:j[this.selectedArray];if(k){const T=k.values.filter(P=>P!==0);y=Math.min(...T),f=Math.max(...T),m=k.min??y,b=k.max??f}else{const T=h.fArray.filter(P=>P!==0);m=Math.min(...T),b=Math.max(...T)}}else u&&this.maxContentPerLayer[n][u]?(b=this.maxContentPerLayer[n][u],m=this.minContentPerLayer[n][u]):(b=this.maxContentPerLayer[n][this.selectedArray],m=this.minContentPerLayer[n][this.selectedArray]);m===b&&(m=b-1);const M=h._typename.substring(0,3)==="TH3",O=h._typename.substring(0,3)==="TH2",D=h._typename.substring(0,3)==="TH1",H=this.maxInstancesPerLayer.slice(n+1).reduce((k,T)=>k*T,1);d.setFromNumber(l/H);const V=this.config.padding.layer[n]??this.config.padding.default;let E=!this.config.padding.layer[n]&&D?{x:V.x,y:V.y,z:V.z}:{...V};u&&this.config.padding.sets&&D&&(E={x:this.config.padding.sets.x,y:0,z:0}),this.pointer.isOnSet&&(E={x:0,y:0,z:0});const{min:q,max:Y}=(S=this.config.scale)!=null&&S[n]?(Q=this.config.scale)==null?void 0:Q[n]:this.config.scale.default;for(let k=l;k<c;k+=H){const T={x:d.getValueAt(0),y:d.getValueAt(1),z:d.getValueAt(2)},P=qe(a.position.z,a.scale.z,Ve(Ye(h,T,E,a==null?void 0:a.scale,a==null?void 0:a.position,n,i))),tt=this.getBinContent(h,T.x,T.y,T.z,this.selectedArray);let Z=1;if((tt>=m&&tt<=b)==!v){const et=(tt-m)/(b-m);if(!v)Z=Number.isInteger(tt)&&tt===0?Z=0:(Y-q)*et+q;else{const dt=(tt-y)/(f-y);Z=Number.isInteger(tt)&&tt===0?Z=0:(Y-q)*dt+q}}else Z=0;this.color=Se(this.config.color,this.availableSets,tt,0,b,C,n);const wt=P.y.size*Z;if(Z===0)P.x.size=0,P.z.size=0,P.y.size=0;else if(M)P.x.size*=Z,P.z.size*=Z,P.y.size=wt;else if(O)P.y.pos-=(P.y.size-wt)/2,P.y.size=wt;else if(P.y.pos-=(P.y.size-wt)/2,P.y.size=wt,u){const et=this.config.TH1ZScale.set;P.z.size=et||.01}else($t=(Kt=this.config.TH1ZScale)==null?void 0:Kt.layer)!=null&&$t[n]?P.z.size=a.scale.z*this.config.TH1ZScale.layer[n]:P.z.size=a.scale.z*this.config.TH1ZScale.default;if(u?(P.z.size=.01,P.z.pos+=(x-(this.selectedSet.length-1)/2)*.1,this.setMatrixCacheAt(n,C,k/H,P,n===s&&Z!==0?this.color:-1)):(this.pointer.isOnSet&&(P.z.size=.01,P.z.pos+=(x-(this.selectedSet.length-1)/2)*.1),this.setMatrixCacheAt(n,null,k/H,P,n===s&&Z!==0?this.color:-1)),n===s){let et=k;u&&(et+=this.totalInstances*x)}else{const et=h.getBin(T.x+1,T.y+1,T.z+1);let dt;const _t={position:new g.Vector3(P.x.pos,P.y.pos,P.z.pos),scale:new g.Vector3(P.x.size,P.y.size,P.z.size)};h.children.content?(dt=h.children.content[et],r(k,c,n+1,dt,_t)):this.selectedSet.forEach(te=>{dt=h.children[te][et],r(k,c,n+1,dt,_t,te)})}if(!d.increment())break}};r(e,A,0,this.pointer.origin,this.limits).then(()=>{setTimeout(()=>{this.wireframe.pushVisibleInstances(this.matrixCache,this.maxInstancesPerLayer,this.availableSets.indexOf(this.selectedSet[0])),this.pushVisibleInstances(),this.BVHTree=Te(this.matrixCache,this.pointer.origin,0,this.selectedSet,this.availableSets,this.mesh.matrixWorld,this.maxInstancesPerLayer)},0)})}createMaterial(){return new g.ShaderMaterial({vertexShader:`
|
|
58
|
+
attribute vec3 instancePosition;
|
|
59
|
+
attribute vec3 instanceScale;
|
|
60
|
+
attribute float instanceColorIndex;
|
|
61
|
+
|
|
62
|
+
uniform vec3 colorArray[32]; // must match maxColors in JS
|
|
63
|
+
|
|
64
|
+
varying vec3 vColor;
|
|
65
|
+
|
|
66
|
+
void main() {
|
|
67
|
+
vec3 transformed = position * instanceScale + instancePosition;
|
|
68
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(transformed, 1.0);
|
|
69
|
+
|
|
70
|
+
// --- Gradient logic ---
|
|
71
|
+
float colorIndex = clamp(instanceColorIndex, 0.0, 31.9999); // stay within bounds
|
|
72
|
+
int idx0 = int(floor(colorIndex));
|
|
73
|
+
int idx1 = int(ceil(colorIndex));
|
|
74
|
+
float t = fract(colorIndex); // blend amount between the two colors
|
|
75
|
+
|
|
76
|
+
vec3 c0 = colorArray[idx0];
|
|
77
|
+
vec3 c1 = colorArray[idx1];
|
|
78
|
+
vColor = mix(c0, c1, t); // smooth blend
|
|
79
|
+
}
|
|
80
|
+
`,fragmentShader:`
|
|
81
|
+
varying vec3 vColor;
|
|
82
|
+
void main() {
|
|
83
|
+
gl_FragColor = vec4(vColor, 1.0);
|
|
84
|
+
}
|
|
85
|
+
`,transparent:!1})}mouseClickDefault(e){this.showChildHistogram(e.index),It().next({id:"*",obj:e.jsrootObj})}mousemoveDefault(e){if(((m,b)=>{if(m.length!==b.length)return!1;for(let y=0;y<m.length;y++){const f=m[y],v=b[y];if(f.x!==v.x||f.y!==v.y||f.z!==v.z)return!1}return!0})(e.index,this.dirtyInstance)){this.dirtyInstance=null;return}const s=this.pointer.parentPath.map(m=>{const b=m.range[0];return{bin:m.bin[0],...b}});e.range=e.range.map((m,b)=>{const y=e.jsrootInstance[b];return{...m,bin:y}});const i={...e,level:s.length,range:s.concat(e.range)},{range:r,level:l,content:c,error:n,set:h,triggerSource:a,instanceId:u}=i,d={coords:r,level:l,content:c,error:n,set:h,triggerSource:a,instanceId:u};Xt().next(d)}shiftMouseClickDefault(e){this.hideChildHistogram(e.index)}mouseDBClickDefault(e){e.set?this.setPointerToChild(e.index,e.set):this.setPointerToChild(e.index,this.selectedSet[0])}shiftMouseDBClickDefault(e){this.setPointerToParent()}intersectionHandler(e,A){this.mouseEvents.filter(s=>s.event===A).forEach(s=>s.function(e,this)),this.dirtyInstance=e.index}raycastHandler(e){try{const s=this.checkIntersectionBVH(e.ray)[0];if(s){const i=e._triggerSource;this.intersectionHandler(s,i)}}catch(A){console.log(A)}}handleStateChange(e){if(Jt(e.sets,this.availableSets)&&(!Jt(e.selectedSet,this.selectedSet)||this.selectedArray!==e.selectedArray)){this.selectedArray=e.selectedArray,this.selectedSet=e.selectedSet;const A=this.mesh.parent;this.instGeom.dispose(),A.remove(this.mesh),this.setupInsBufGeom(),A.add(this.mesh);const s=this.renderHistory;this.renderHistory=[],s.forEach(i=>{i.procedure==="render"?this.renderHistogram(i.value.startIndex,i.value.endIndex,i.value.layer):i.procedure==="hide"&&this.hideChildHistogram(i.value)})}else this.availableSets=e.sets,this.selectedSet=e.selectedSet}setPointerToChild(e,A){const s=this.mesh.parent;this.matrixCache=[],this.instGeom.dispose(),this.wireframe.dispose(),s.remove(this.mesh);const i=gt(e,A,this.pointer.origin,this.wireframe,this.selectedSet);this.pointer.setOriginToChild(ft(e,this.pointer.origin,this.selectedSet),A,i),this.init(),console.log("path: ",this.pointer.path),console.log("title: ",this.pointer.title),this.renderHistogram(0,this.totalInstances,0),s.add(this.mesh),s.add(this.wireframe.wireframe)}setPointerToParent(){const e=this.mesh.parent;this.matrixCache=[],this.instGeom.dispose(),this.wireframe.dispose(),e.remove(this.mesh),this.pointer.setOriginToParent(1),console.log("path: ",this.pointer.path),console.log("title: ",this.pointer.title),this.init(),this.renderHistogram(0,this.totalInstances,0),e.add(this.mesh),e.add(this.wireframe.wireframe)}showChildHistogram(e){const A=Tt(e,this.pointer.origin,this.maxInstancesPerLayer,this.selectedSet),i=this.maxInstancesPerLayer.slice(-this.maxInstancesPerLayer.length+e.length).reduce((r,l)=>r*l,1);this.renderHistogram(A.slice(-1)[0],A.slice(-1)[0]+i,e.length)}hideChildHistogram(e){if(e.length===1)return;const A=this.maxInstancesPerLayer.slice(e.length-1),s=this.maxInstancesPerLayer.slice(e.length-1,this.maxInstancesPerLayer.length-1),i=A.reduce((c,n)=>c*n,1),r=Ie(e,this.pointer.origin,this.maxInstancesPerLayer,this.selectedSet),l=Math.floor(r/i)*i;this.clearMatrixCacheRange(l,i,s,e.length-1),this.logRender({procedure:"hide",value:e}),this.renderHistogram(l,l+i,e.length-2),this.renderHistory.pop()}clearMatrixCacheRange(e,A,s,i){let r=e,l=A;const c={x:{pos:0,size:0},y:{pos:0,size:0},z:{pos:0,size:0}};for(let n=i+s.length-1;n>=i;n--){if(Array.isArray(this.matrixCache[n]))for(let h=0;h<this.matrixCache[n].length;h++)for(let a=r;a<r+l;a++)this.setMatrixCacheAt(n,h,a,c,-1);else for(let h=r;h<r+l;h++)this.setMatrixCacheAt(n,null,h,c,-1);n>i&&(r/=s[n-i],l/=s[n-i])}}setAvailableSets(e){var A;if((A=e.children)!=null&&A.content){const s=e.children.content.find(i=>i);this.setAvailableSets(s)}else if(e!=null&&e.children){const s=R().getValue();s.sets=Object.keys(e.children),s.selectedSet.length===0?(this.selectedSet.push(s.sets[0]),s.selectedSet.push(s.sets[0])):this.selectedSet.every(i=>s.sets.find(r=>r===i))||(s.selectedSet=[s.sets[0]]),R().next(s)}else{const s=R().getValue();s.sets=[],s.selectedSet=[]}}setAvailableArrays(e){const A=R().getValue();A.arrays=[],e.fArrays&&(A.arrays=Object.keys(e.fArrays)),A.arrays.unshift("content"),R().next(A)}keyDownHandler(e){const A=/^(?:Digit|Numpad)(\d+)$/,s=e.code.match(A);if(s){if(parseInt(s[1])>this.matrixCache.length)return;const i=new g.Object3D;i.scale.set(0,0,0),i.updateMatrix();let r=this.maxInstancesPerLayer.reduce((l,c)=>l*c,1);this.selectedSet.length>1&&(r*=this.selectedSet.length),this.setupMatrixCache(),this.wireframe.clearWireframe(),this.renderHistogram(0,this.totalInstances,parseInt(s[1])-1)}else e.key===this.keyBindings.hideOutlines?this.wireframe.toggleVisibility(this.matrixCache,this.maxInstancesPerLayer,this.availableSets.indexOf(this.selectedSet[0])):e.key===this.keyBindings.resetHistogram?this.resetHistogram():e.key===this.keyBindings.goToPreviousLayer&&this.setPointerToParent()}keyUpHandler(e){}resetHistogram(){this.updateHistogram({obj:this.rootObj})}logRender(e){e.procedure==="render"&&e.value.startIndex===0&&e.value.endIndex===this.totalInstances&&(this.renderHistory=[]),this.renderHistory.push(e)}getBinContent(e,A,s,i,r){var l;if(r==="content"||!e.fArrays)return e.getBinContent(A+1,s+1,i+1);{const c=e.getBin(A+1,s+1,i+1);return(l=e.fArrays)==null?void 0:l[r].values[c]}}checkIntersectionBVH(e){const A=new g.Vector3,s=(n,h,a,u)=>{var d;if(h<0||1/h===-1/0){const m=h*-1,b=u&&u!=="content"?(d=this.matrixCache[n])==null?void 0:d[this.availableSets.indexOf(u)]:this.matrixCache[n];return b?new g.Box3().setFromCenterAndSize(new g.Vector3(b.pos[m*3],b.pos[m*3+1],b.pos[m*3+2]),new g.Vector3(b.scale[m*3],b.scale[m*3+1],b.scale[m*3+2])):void 0}else{const m=u&&u!=="content"?this.BVHTree[n][this.availableSets.indexOf(u)][a]:this.BVHTree[n][a];return m?new g.Box3().setFromCenterAndSize(new g.Vector3(m.pos[h*3],m.pos[h*3+1],m.pos[h*3+2]),new g.Vector3(m.scale[h*3],m.scale[h*3+1],m.scale[h*3+2])):void 0}},i=(n,h)=>{let a=0,u=n,d=h;for(;u+1<this.matrixCache.length;){u++;const m=this.matrixCache[u];if(Array.isArray(m))this.selectedSet.forEach(b=>{const y=this.availableSets.indexOf(b);for(let f=d;f<d+this.maxInstancesPerLayer[u];f++)if(m[y].rendered[f]!==-1){a=u-n;break}});else{if(!m)return a;for(let b=d;b<d+this.maxInstancesPerLayer[u];b++)if(m.rendered[b]!==-1){a=u-n;break}}d*=this.maxInstancesPerLayer[u+1]}return a},r=(n,h,a,u)=>{const d=u&&u!=="content"?this.BVHTree[a][this.availableSets.indexOf(u)][h]:this.BVHTree[a][h],m=s(a,d.left[n],h,u),b=s(a,d.right[n],h,u),y=[];return e.intersectBox(m,A)?y.push({index:d.left[n],target:A.clone(),distance:e.origin.distanceTo(A)}):y.push(null),e.intersectBox(b,A)?y.push({index:d.right[n],target:A.clone(),distance:e.origin.distanceTo(A)}):y.push(null),y},l=(n,h,a)=>{const u=[],d=b=>{if(b.index<0||1/b.index===-1/0){u.push(b);return}const[y,f]=r(b.index,h,n,a);y&&d(y),f&&d(f)},m=a&&a!=="content"?this.BVHTree[n][this.availableSets.indexOf(a)][h]:this.BVHTree[n][h];return m&&d({index:m.left.length-1,target:null,distance:null}),u},c=(n,h,a=0,u=[],d=void 0)=>{const m=[],b=this.maxInstancesPerLayer[h+1],y=this.maxInstancesPerLayer[h]*this.maxInstancesPerLayer[h+1];return l(h,a,d).forEach(f=>{var D;const v=Math.abs(f.index)-a*this.maxInstancesPerLayer[h],x=v%n.fXaxis.fNbins,C=Math.floor(v%(n.fXaxis.fNbins*n.fYaxis.fNbins)/n.fXaxis.fNbins),M=Math.floor(v/(n.fXaxis.fNbins*n.fYaxis.fNbins)),O=[...u,{x,y:C,z:M}];if(n.children){const V=Object.entries(n.children).flatMap(([E,q])=>{const Y=n.getBin(x+1,C+1,M+1),N=q==null?void 0:q[Y];if(!N)return[];const F=a*y+(x+C*n.fXaxis.fNbins+M*(n.fXaxis.fNbins*n.fYaxis.fNbins))*b;if(!(i(h,F)>0))return[];let S=c(N,h+1,Math.abs(f.index),O,E);return E!=="content"&&(S=S.map(Q=>({...Q,set:E}))),S});if(V.length>0)m.push(...V);else{const E=a*this.maxInstancesPerLayer[h]+(x+C*n.fXaxis.fNbins+M*(n.fXaxis.fNbins*n.fYaxis.fNbins));(d&&d!=="content"?(D=this.matrixCache[h])==null?void 0:D[this.availableSets.indexOf(d)]:this.matrixCache[h]).rendered[E]!==-1&&m.push({index:O,target:f.target,distance:f.distance,set:d,instanceId:Tt(O,this.pointer.origin,this.maxInstancesPerLayer,this.selectedSet),jsrootInstance:ft(O,this.pointer.origin,this.selectedSet),range:gt(O,d,this.pointer.origin,this.wireframe,this.selectedSet),origin:this,jsrootObj:n,content:this.getBinContent(n,x,C,M,this.selectedArray),error:n.getBinError(x+1,C+1,M+1)})}}else m.push({index:O,target:f.target,distance:f.distance,set:d,instanceId:Tt(O,this.pointer.origin,this.maxInstancesPerLayer,this.selectedSet),jsrootInstance:ft(O,this.pointer.origin,this.selectedSet),range:gt(O,d,this.pointer.origin,this.wireframe,this.selectedSet),origin:this,jsrootObj:n,content:this.getBinContent(n,x,C,M,this.selectedArray),error:n.getBinError(x+1,C+1,M+1)})}),m.sort((f,v)=>f.distance-v.distance)};return c(this.pointer.origin,0)}dispatchSubjectHandler(e){console.log("dispatch: ",e);const A=e.event.index.map(r=>({x:r.x-1,y:r.y-1,z:r.z-1})),s=this.pointer.getChildByPosition(ft([...A]).slice(0,-1),e.event.set,this.selectedSet),i={index:A,set:e.event.set,jsrootInstance:ft(A,this.pointer.origin,this.selectedSet),range:gt(A,e.event.set,this.pointer.origin,this.wireframe,this.selectedSet),origin:this,jsrootObj:s,content:this.getBinContent(s,A[0].x+1,A[0].y+1,A[0].z+1,this.selectedArray),error:s.getBinError(A[0].x+1,A[0].y+1,A[0].z+1)};this.intersectionHandler(i,e.event.source)}}class Ne{constructor(t,e,A,s,i){p(this,"plane");p(this,"cinemaSub");p(this,"position");p(this,"rotation");p(this,"scale");p(this,"id");p(this,"configSub");const r=new g.PlaneGeometry(s.x,s.y),l=new g.MeshBasicMaterial({color:new g.Color().setHex(16777215),side:g.DoubleSide});this.plane||(this.plane=new g.Mesh(r,l),this.plane.position.set(e.x,e.y,e.z)),t&&this.updateTexture(t),this.id=i,this.position=e,this.rotation=A,this.scale=s,this.cinemaSub=It().getObservable().pipe(z.filter(c=>c.id===this.id||c.id==="*")).subscribe(c=>{console.log("obj: ",c);const n=c.obj;G.makeImage({format:"png",object:n,width:1200,height:600}).then(h=>{this.updateTexture(h)})}),this.configSub=it().getObservable().pipe(z.filter(c=>c.target.id.includes("*")||c.target.id.includes(this.id))).subscribe(c=>{this.position=c.config.environment.canvas.position,this.rotation=c.config.environment.canvas.rotation,this.scale=c.config.environment.canvas.scale,this.updateMesh()})}updateMesh(){this.plane.scale.set(this.scale.x,this.scale.y,this.scale.z),this.plane.position.set(this.position.x,this.position.y,this.position.z);const t=Math.PI/180;this.plane.rotation.set(this.rotation.x*t,this.rotation.y*t,this.rotation.z*t)}updateTexture(t){if(!t){console.warn("updateTexture called with null/undefined");return}const e=new g.TextureLoader;if(typeof t=="string"&&(t.startsWith("data:")||t.startsWith("http")))e.load(t,A=>{this.plane.material.map=A,this.plane.material.needsUpdate=!0},void 0,A=>console.error("Texture load failed",A));else if(t instanceof HTMLImageElement){const A=new Texture(t);A.needsUpdate=!0,this.plane.material.map=A,this.plane.material.needsUpdate=!0}else console.error("Unsupported image type passed to updateTexture:",t)}remove(){this.plane.parent&&(this.plane.parent.remove(this.plane),this.cinemaSub.unsubscribe(),this.configSub.unsubscribe())}getPlane(){return this.plane}}class je extends g.Loader{constructor(t){super(t)}load(t,e,A,s){const i=this,r=new g.FileLoader(this.manager);r.setPath(this.path),r.setRequestHeader(this.requestHeader),r.setWithCredentials(this.withCredentials),r.load(t,function(l){const c=i.parse(JSON.parse(l));e&&e(c)},A,s)}parse(t){return new Ue(t)}}class Ue{constructor(t){this.isFont=!0,this.type="Font",this.data=t}generateShapes(t,e=100){const A=[],s=Ze(t,e,this.data);for(let i=0,r=s.length;i<r;i++)A.push(...s[i].toShapes());return A}}function Ze(o,t,e){const A=Array.from(o),s=t/e.resolution,i=(e.boundingBox.yMax-e.boundingBox.yMin+e.underlineThickness)*s,r=[];let l=0,c=0;for(let n=0;n<A.length;n++){const h=A[n];if(h===`
|
|
86
|
+
`)l=0,c-=i;else{const a=Je(h,s,l,c,e);l+=a.offsetX,r.push(a.path)}}return r}function Je(o,t,e,A,s){const i=s.glyphs[o]||s.glyphs["?"];if(!i){console.error('THREE.Font: character "'+o+'" does not exists in font family '+s.familyName+".");return}const r=new g.ShapePath;let l,c,n,h,a,u,d,m;if(i.o){const b=i._cachedOutline||(i._cachedOutline=i.o.split(" "));for(let y=0,f=b.length;y<f;)switch(b[y++]){case"m":l=b[y++]*t+e,c=b[y++]*t+A,r.moveTo(l,c);break;case"l":l=b[y++]*t+e,c=b[y++]*t+A,r.lineTo(l,c);break;case"q":n=b[y++]*t+e,h=b[y++]*t+A,a=b[y++]*t+e,u=b[y++]*t+A,r.quadraticCurveTo(a,u,n,h);break;case"b":n=b[y++]*t+e,h=b[y++]*t+A,a=b[y++]*t+e,u=b[y++]*t+A,d=b[y++]*t+e,m=b[y++]*t+A,r.bezierCurveTo(a,u,d,m,n,h);break}}return{offsetX:i.ha*t,path:r}}class Re{constructor(t,e={}){this.camera=t,this.options={backgroundColor:11184810,textColor:1,titleColor:0,padding:.002,lineHeight:.002,textSize:10,width:.031,...e},this.loader=new je,this.queue=new z.Subject;let A=!1,s=null;this.queueSub=this.queue.pipe(z.concatMap(i=>A?(s=i,z.EMPTY):(A=!0,z.from(this.updateVisualization(i)).pipe(z.finalize(()=>{if(A=!1,s){const r=s;s=null,this.queue.next(r)}}))))).subscribe(),this.group=new g.Group}parseData(t){const e=[];if(t.title&&e.push({text:t.title,isTitle:!0}),t.coords&&Array.isArray(t.coords)&&t.coords.forEach(A=>{Object.entries(A).forEach(([s,i])=>{if(i&&typeof i=="object"&&!("isColor"in i)){const r=`${s} = [${i.min.toFixed(2)}, ${i.max.toFixed(2)})`;e.push({text:r,isTitle:!1})}})}),t.index&&Array.isArray(t.index)&&t.index.forEach(A=>{let s=`bin = ${t.object.bins[t.instanceId]}`;Object.entries(A).forEach(([i,r])=>{s+=`, ${i}: ${r}`}),e.push({text:s,isTitle:!1})}),t.content!==void 0){const A=Number.isInteger(t.content)?`content = ${t.content}`:`content = ${t.content.toFixed(2)}`;e.push({text:A,isTitle:!1})}if(t.error!==void 0){const A=Number.isInteger(t.error)?`error = ${t.error}`:`error = ${t.error.toFixed(2)}`;e.push({text:A,isTitle:!1})}return e}createBackgroundPanel(t){const{width:e,backgroundColor:A}=this.options,s=new g.PlaneGeometry(e,t),i=new g.MeshBasicMaterial({color:A,side:g.DoubleSide});return new g.Mesh(s,i)}async updateVisualization(t){for(t===null&&this.clear();this.group.children.length>0;){const x=this.group.children[0];x.geometry&&x.geometry.dispose(),x.material&&x.material.dispose(),this.group.remove(x)}const e=this.parseData(t);if(e.length===0)return;const{padding:A,lineHeight:s,textSize:i,textColor:r,titleColor:l,width:c}=this.options,n=e.length*s+A*2,h=this.createBackgroundPanel(n);this.group.add(h);const a=n/2-A-s/2;for(let x=0;x<e.length;x++){const C=e[x],M=a-x*s;try{const O=G.create("TLatex");O.fTitle=C.text,O.fTextAlign=12,O.fTextFont=2,O.fTitleFont=2,O.fLabelFont=2,O.fTextColor=C.isTitle?l:r,O.fTextSize=C.isTitle?i+2:i;const D=await G.build3d(O,"p",M*100,"","");D.scale.set(16e-5,16e-5,16e-5),D.position.x=-(c/2)+A,D.position.y=M,D.position.z=.001,this.group.add(D)}catch(O){console.error("Error creating text line:",O)}}const u=new g.Vector3(t.point.x,t.point.y,t.point.z);this.camera.worldToLocal(u);const d=new g.Vector3().subVectors(u,this.camera.position).normalize(),b=new g.Vector3().copy(this.camera.position).addScaledVector(d,.1),y=new g.Box3().setFromObject(this.group),f=new g.Vector3;y.getSize(f);const v=f.clone().multiplyScalar(.5);b.add(new g.Vector3(v.x,v.y,0)),this.group.position.copy(b),this.camera.add(this.group)}getGroup(){return this.group}setPosition(t,e,A){this.group.position.set(t,e,A)}setRotation(t,e,A){this.group.rotation.set(t,e,A)}clear(){for(;this.group.children.length>0;){const t=this.group.children[0];t.geometry&&t.geometry.dispose(),t.material&&t.material.dispose(),this.group.remove(t)}}dispose(){for(this.queueSub.unsubscribe();this.group.children.length>0;){const t=this.group.children[0];t.geometry&&t.geometry.dispose(),t.material&&t.material.dispose(),this.group.remove(t)}}}class Ke{constructor(t,e,A){p(this,"histogramGroup");p(this,"binInfoComponent");p(this,"id");p(this,"configSub");p(this,"rootObj");p(this,"histoSub");p(this,"dummyEl");p(this,"defaultRaycastHandler");p(this,"mouseEvents",[]);p(this,"color",new g.Color);p(this,"colorTarget",new g.Color(65535));p(this,"buildPromise");this.id=t,this.rootObj=e,this.camera=A,this.histogramGroup=new g.Group,this.dummyEl=document.getElementById("dummyDiv"+t),this.dummyEl&&document.body.removeChild(this.dummyEl),this.binInfoComponent=new Re(this.camera,{backgroundColor:3556687,textColor:0,titleColor:0}),this.dummyEl=document.createElement("div"),this.dummyEl.id="dummyDiv"+t,document.body.appendChild(this.dummyEl),this.configSub=it().getObservable().pipe(z.filter(s=>s.target.id.includes("*")||s.target.id.includes(this.id))).subscribe(s=>{this.config={...s.config};const r=this.config.environment.histogramPads.find(l=>l.id===this.id).position;this.histogramGroup.position.set(r.x,r.y,r.z)}),this.sub=Pt().getObservable().pipe(z.filter(s=>s.target.id.includes("*")||s.target.id.includes(this.id))).subscribe(s=>{if(s.flag==="add")if(s.function)this.addEvent(s.event,s.function);else switch(s.event){case"mousemove":this.addEvent(s.event,this.mousemoveDefault);break;case"mouseclick":this.addEvent(s.event,this.mouseClickDefault);break;case"shiftmouseclick":this.addEvent(s.event,this.shiftMouseClickDefault);break;case"mousedbclick":this.addEvent(s.event,this.mouseDBClickDefault);break;case"shiftmousedbclick":this.addEvent(s.event,this.shiftMouseDBClickDefault);break}else if(s.flag==="remove"&&s.function)this.removeEvent(s.event,s.function);else if(s.flag==="remove")switch(s==null?void 0:s.state){case"keydown":this.keydownEvents=[];break;case"keyup":this.keyupEvents=[];break;default:this.mouseEvents=this.mouseEvents.filter(i=>i.event!==s.event),this.mousemoveDefault({object:this.getInstancedMesh(),instanceId:null})}else s.flag==="removeAll"&&(this.keydownEvents=[],this.keyupEvents=[],this.mouseEvents=[])}),this.raycastHandler=this.raycastHandler.bind(this),this.mouseClickDefault=this.mouseClickDefault.bind(this),this.mousemoveDefault=this.mousemoveDefault.bind(this),this.shiftMouseClickDefault=this.shiftMouseClickDefault.bind(this),this.mouseDBClickDefault=this.mouseDBClickDefault.bind(this),this.shiftMouseDBClickDefault=this.shiftMouseDBClickDefault.bind(this),this.addEvent("mouseclick",this.mouseClickDefault),this.addEvent("mousemove",this.mousemoveDefault),this.addEvent("shiftmouseclick",this.shiftMouseClickDefault),this.addEvent("mousedbclick",this.mouseDBClickDefault),this.addEvent("shiftmousedbclick",this.shiftMouseDBClickDefault),this.buildPromise=this.renderWithBuild3d()}updateHistogram(t){this.rootObj=t,this.histogramGroup.clear(),this.buildPromise=this.renderWithBuild3d()}renderWithBuild3d(){return G.build3d(this.rootObj).then(t=>{var r;const e=(r=this.config.environment.histogramPads.find(l=>l.id===this.id))==null?void 0:r.scale,A=new g.Box3().setFromObject(t),s=new g.Vector3;A.getSize(s),t.scale.set(e.x/s.x,e.z/s.y,e.y/s.z),t.rotateX(-Math.PI/2),t.translateZ(-(e.y/2)),this.histogramGroup.add(t);const i=this.getInstancedMesh();i&&(this.defaultRaycastHandler=i.raycast.bind(i),i.raycast=this.raycastHandler.bind(this))}).catch(t=>{const e=this.config.environment.histogramPads.find(A=>A.id===this.id);throw console.log("JSROOT was not able to build object: ",t,e),{message:t,scale:e==null?void 0:e.scale,position:e==null?void 0:e.position}})}raycastHandler(t,e){this.defaultRaycastHandler(t,e),setTimeout(()=>{const A=e.filter(a=>a.instanceId!==void 0).sort((a,u)=>a.distance-u.distance)[0];if(!A){this.mouseEvents.filter(a=>a.event==="mousemove").forEach(a=>a.function({instanceId:void 0,object:this.getInstancedMesh()},this));return}const s=A.object.bins[A.instanceId],i=this.rootObj.fXaxis.fNbins+2,r=this.rootObj.fYaxis.fNbins+2,l={x:s%i,y:Math.floor(s%(i*r)/i),z:Math.floor(s/(i*r))},c=this.getRangeByPosition([l]),n=this.rootObj.fName,h={...A,index:[l],coords:[{...c,bin:s,name:n}],content:this.rootObj.getBinContent(l.x,l.y,l.z),error:this.rootObj.getBinError(l.x,l.y,l.z)};this.mouseEvents.filter(a=>a.event===t._triggerSource).forEach(a=>a.function(h,this)),this.dirtyInstance=A.instanceId},0)}addEvent(t,e){(t==null?void 0:t.state)==="keydown"?this.keydownEvents.push({key:t.key,function:e}):(t==null?void 0:t.state)==="keyup"?this.keyupEvents.push({key:t.key,function:e}):this.mouseEvents.push({event:t,function:e})}removeEvent(t,e){const A=this.mouseEvents.find(s=>s===e);A&&this.mouseEvents.splice(A,1)}mouseClickDefault(t){console.log("mouseclick default")}mousemoveDefault(t){if(t.instanceId===this.dirtyInstance)return;const e=t.object;if(this.dirtyInstance!==void 0){e.getColorAt(this.dirtyInstance,this.color);const A=.5;this.color.lerp(this.colorTarget,-A/(1-A)),e.setColorAt(this.dirtyInstance,this.color)}this.dirtyInstance=t.instanceId,e.getColorAt(this.dirtyInstance,this.color),this.color.lerp(this.colorTarget,.5),e.setColorAt(this.dirtyInstance,this.color),e.instanceColor.needsUpdate=!0,this.binInfoComponent.queue.next(t),Xt().next(t)}shiftMouseClickDefault(t){console.log("shiftMouseClickDefault")}mouseDBClickDefault(t){console.log("mouseDBClickDefault")}shiftMouseDBClickDefault(t){console.log("shiftMouseDBClickDefault")}getInstancedMesh(t=this.histogramGroup){if(!t)return null;if(t.isInstancedMesh===!0)return t;if(t.children&&t.children.length>0)for(const e of t.children){const A=this.getInstancedMesh(e);if(A)return A}return null}getRangeByPosition(t){const e=["x","y","z"],A=Number.parseInt(this.rootObj._typename.substring(2,3),10);let s={};if(t[0]){for(let i=0;i<A;i++){const r=e[i],l=this.rootObj[`f${r.toUpperCase()}axis`],c=t[0][r];s[r]={min:l.GetBinLowEdge(c),max:l.GetBinCenter(c)*2-l.GetBinLowEdge(c),name:l.fName,title:l.fTitle}}s={...s,color:new g.Color(0)}}return s}remove(){this.histogramGroup.parent.remove(this.histogramGroup),this.dummyEl=document.getElementById("dummyDiv"+this.id),this.dummyEl&&document.body.removeChild(this.dummyEl),this.configSub.unsubscribe(),this.sub.unsubscribe()}getHistogramMesh(){return this.histogramGroup}}B.CanvasClass=Ne,B.HistogramJsrootClass=Ke,B.HistogramPointerClass=Lt,B.MobileController=ze,B.NdmvrRaycaster=Oe,B.THnPainter=Le,B.binInfoSubjectGet=Xt,B.brokerManagerGet=Nt,B.canvasSubjectGet=It,B.configSubjectGet=it,B.dispatchSubjectGet=jt,B.fetchTFile=Me,B.functionSubjectGet=Pt,B.getCameraComponent=ye,B.histogramSubjectGet=ge,B.httpRequest=ne,B.initNdmvrAframe=ie,B.inputDeviceSubjectGet=Mt,B.stateSubjectGet=R,Object.defineProperty(B,Symbol.toStringTag,{value:"Module"})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.skyColor{filter:hue-rotate(240deg) saturate(100%) brightness(100%) drop-shadow(0px 0px 20px white)}.baseColor{filter:hue-rotate(24deg) saturate(68%) brightness(100%) drop-shadow(0px 0px 20px white)}.grayColor{filter:hue-rotate(0deg) saturate(0%) brightness(100%) drop-shadow(0px 0px 20px white)}img{width:50px;height:50px;cursor:pointer;transform:rotate(90deg)}.mainUI{border:0px solid pink;position:absolute;top:0;width:99%;height:99%;z-index:9999;pointer-events:none}.regionUI{border:0px solid yellow;position:absolute;display:flex;flex-direction:column;pointer-events:none}.buttonUI{border:0px solid lime;display:flex;flex-direction:column;justify-content:center;pointer-events:auto;filter:drop-shadow(0px 0px 20px white)}.joystick{width:100px;height:100px}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ndmspc/ndmvr-core",
|
|
3
|
+
"private": false,
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"description": "NDMVR Core Library",
|
|
6
|
+
"author": "",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"bugs": {
|
|
9
|
+
"url": "https://gitlab.com/ndmspc/ndmvr-core/issues"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://ndmspc.gitlab.io/ndmvr-core",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://gitlab.com/ndmspc/ndmvr-core.git"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "dist/index.js",
|
|
18
|
+
"module": "dist/index.js",
|
|
19
|
+
"exports": {
|
|
20
|
+
"import": "./dist/index.es.js",
|
|
21
|
+
"require": "./dist/index.cjs"
|
|
22
|
+
},
|
|
23
|
+
"directories": {
|
|
24
|
+
"doc": "docs"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"ignore": [
|
|
31
|
+
"!build/",
|
|
32
|
+
"src/",
|
|
33
|
+
"test/"
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"dev": "vite",
|
|
38
|
+
"build": "vite build",
|
|
39
|
+
"preview": "vite preview",
|
|
40
|
+
"prepack": "npmignore --auto"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@eslint/js": "^9.36.0",
|
|
44
|
+
"eslint": "^9.36.0",
|
|
45
|
+
"globals": "^16.4.0",
|
|
46
|
+
"npmignore": "^0.3.1",
|
|
47
|
+
"standard": "^17.1.2",
|
|
48
|
+
"three": "^0.173.0",
|
|
49
|
+
"jsroot": "github:root-project/jsroot#30c16c1c5b73eb71fe741bf6ecc27c603f7658be",
|
|
50
|
+
"aframe": "^1.7.0",
|
|
51
|
+
"vite": "6.0.8"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"rxjs": "^7.8.1"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"three": "~0.173.0",
|
|
58
|
+
"jsroot": "github:root-project/jsroot#30c16c1c5b73eb71fe741bf6ecc27c603f7658be"
|
|
59
|
+
}
|
|
60
|
+
}
|