@zeainc/zea-ux
Version:
1 lines • 141 kB
JavaScript
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@zeainc/zea-engine")):"function"==typeof define&&define.amd?define(["exports","@zeainc/zea-engine"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).zeaUx={},e.zeaEngine)}(this,(function(e,t){"use strict";var a={name:"@zeainc/zea-ux",version:"4.9.0",description:"Zea UX",homepage:"https://github.com/ZeaInc/zea-ux#readme",author:"Zea Inc.",license:"MIT",repository:{type:"git",url:"git+ssh://git@github.com/ZeaInc/zea-ux.git"},bugs:{url:"https://github.com/ZeaInc/zea-ux/issues"},main:"dist/index.cjs.js",module:"dist/index.esm.js",browser:"dist/index.umd.js",umd:"dist/index.umd.js",exports:{".":{import:"./dist/index.esm.js",require:"./dist/index.cjs.js",types:"./dist/zea-ux.d.ts"}},types:"dist/zea-ux.d.ts",files:["dist/"],keywords:["Zea","UX"],scripts:{"build:tsc":"npx tsc","build:tsc:watch":"npx tsc --watch","clean:build":"rm -Rf dist/ buildcache","build:rollup":"rollup -c","build:rollup:watch":"rollup -w -c",build:"npm-run-all clean:build build:rollup",dev:"npm-run-all --parallel build:rollup:watch start:watch",start:"es-dev-server --app-index testing-e2e/index.html --open","start:watch":"es-dev-server --app-index testing-e2e/index.html --open --watch",release:"standard-version",dist:"yarn publish --access=public",docs:"adg --config adg.config.json","docs-w":"adg -w --config=adg.config.json","docs:serve":"docsify serve docs/",lint:"eslint src/",prepare:"yarn run build",test:"jest",generate:"plop","test:coverage":"jest --coverage","test:debug":"node --inspect ./node_modules/jest/bin/jest.js --runInBand --watch","test:watch":"jest --watch","test:e2e":"percy exec cypress run --browser chrome --headless","test:e2e:watch":"percy exec cypress open","to-cleanup":"rm -Rf dist/ node_modules/ yarn.lock","to-link-packages":"yarn link @zeainc/zea-engine"},devDependencies:{"@babel/preset-env":"^7.12.7","@percy/cypress":"^2.3.1","@rollup/plugin-commonjs":"^21.0.1","@rollup/plugin-json":"^4.1.0","@rollup/plugin-node-resolve":"^13.0.6","@rollup/plugin-terser":"0.4.4","@rollup/plugin-typescript":"^12.1.1","@zeainc/zea-collab":"^6.3.4","@zeainc/zea-engine":"4.17.0",canvas:"^2.6.1",copyfiles:"^2.4.1",cypress:"^5.6.0","docsify-cli":"^4.4.2",documentation:"^13.1.0","es-dev-server":"^1.60.1",eslint:"^7.14.0","eslint-config-google":"^0.14.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.2.0",husky:"^4.3.0","husky-run":"^0.0.0",jest:"^26.6.3","npm-run-all":"^4.1.5",plop:"^2.7.4",prettier:"^2.2.1",rollup:"^2.34.1","rollup-plugin-dts":"^4.2.3","standard-version":"^9.0.0","ts-node":"^10.4.0",tslib:"^2.3.1",typedoc:"^0.23.21","typedoc-plugin-markdown":"^3.13.6",typescript:"^5.6.3"},dependencies:{"dom-to-image":"^2.6.0",global:"^4.4.0","license-checker":"^25.0.1"},husky:{hooks:{"disabled=pre-commit":"npm test","disabled=pre-push":"npm test"}}};function i(e){return e instanceof t.ZeaMouseEvent||t.ZeaTouchEvent?e.pointerRay:e instanceof t.XRControllerEvent?e.controller.pointerRay:(console.warn("unhandled pointer event"),new t.Ray)}class s extends t.TreeItem{gizmoRay;activeController;captured=!1;colorParam=new t.ColorParameter("Color",new t.Color);highlightColorParam=new t.ColorParameter("HighlightColor",new t.Color(1,1,1));grabPos;holdPos;holdDist;value;delta;releasePos;constructor(e){super(e),this.addParameter(this.colorParam),this.addParameter(this.highlightColorParam)}highlight(){this.emit("highlight")}unhighlight(){this.emit("unhighlight")}getManipulationPlane(){const e=this.globalXfoParam.value;return new t.Ray(e.tr,e.ori.getZaxis())}onPointerEnter(e){this.highlight()}onPointerLeave(e){this.unhighlight()}onPointerDown(e){e.setCapture(this),e.stopPropagation(),this.captured=!0,e instanceof t.ZeaTouchEvent&&this.highlight(),e instanceof t.ZeaMouseEvent||e instanceof t.ZeaTouchEvent?this.handlePointerDown(e):e instanceof t.XRControllerEvent&&this.onXRControllerButtonDown(e)}onPointerMove(e){this.captured&&(e.stopPropagation(),e instanceof t.ZeaMouseEvent||e instanceof t.ZeaTouchEvent?this.handlePointerMove(e):e instanceof t.XRPoseEvent&&this.onXRPoseChanged(e)),e.preventDefault()}onPointerUp(e){e.stopPropagation(),this.captured&&(e.releaseCapture(),this.captured=!1,e instanceof t.ZeaTouchEvent&&this.unhighlight(),e instanceof t.ZeaMouseEvent||e instanceof t.ZeaTouchEvent?this.handlePointerUp(e):e instanceof t.XRControllerEvent&&this.onVRControllerButtonUp(e))}onPointerClick(e){e.stopPropagation()}onPointerDoubleClick(e){e.stopPropagation()}onWheel(e){}handlePointerDown(e){this.gizmoRay=this.getManipulationPlane();const t=i(e),a=t.intersectRayPlane(this.gizmoRay);this.grabPos=t.pointAtDist(a),this.onDragStart(e)}handlePointerMove(e){const t=i(e),a=t.intersectRayPlane(this.gizmoRay);this.holdPos=t.pointAtDist(a),this.onDrag(e)}handlePointerUp(e){const t=e.pointerRay;if(t){const e=t.intersectRayPlane(this.gizmoRay);this.releasePos=t.pointAtDist(e)}this.onDragEnd(e)}onXRControllerButtonDown(e){this.activeController=e.controller;const t=this.activeController.getTipXfo().clone(),a=this.getManipulationPlane(),i=t.tr.subtract(a.start),s=t.tr.subtract(a.dir.scale(i.dot(a.dir)));this.grabPos=s,this.onDragStart(e)}onXRPoseChanged(e){if(this.activeController){const t=this.activeController.getTipXfo(),a=this.getManipulationPlane(),i=t.tr.subtract(a.start),s=t.tr.subtract(a.dir.scale(i.dot(a.dir)));this.holdPos=s,this.onDrag(e)}}onVRControllerButtonUp(e){this.activeController==e.controller&&(this.activeController.getTipXfo(),this.onDragEnd(e),this.activeController=void 0)}onDragStart(e){console.warn("@Handle#onDragStart - Implement me!",e)}onDrag(e){console.warn("@Handle#onDrag - Implement me!",e)}onDragEnd(e){console.warn("@Handle#onDragEnd - Implement me!",e)}setTargetParam(e){console.warn("setTargetParam not implemented")}}class n extends s{grabDist;constructor(e){super(e)}handlePointerDown(e){this.gizmoRay=this.getManipulationPlane();const t=i(e).intersectRayVector(this.gizmoRay);this.grabDist=Array.isArray(t)?t[1]:t;const a=this.gizmoRay.pointAtDist(this.grabDist);this.grabPos=a,this.onDragStart(e)}handlePointerMove(e){const t=i(e).intersectRayVector(this.gizmoRay),a=Array.isArray(t)?t[1]:t;this.holdPos=this.gizmoRay.pointAtDist(a),this.holdDist=a,this.value=a,this.delta=a-this.grabDist,this.onDrag(e)}handlePointerUp(e){const t=i(e);if(t){const e=t.intersectRayVector(this.gizmoRay),a=Array.isArray(e)?e[1]:e,i=this.gizmoRay.pointAtDist(a);this.releasePos=i}this.onDragEnd(e)}onXRControllerButtonDown(e){this.gizmoRay=this.getManipulationPlane(),this.activeController=e.controller;const t=this.activeController.getTipXfo();this.grabDist=t.tr.subtract(this.gizmoRay.start).dot(this.gizmoRay.dir),this.grabPos=this.gizmoRay.start.add(this.gizmoRay.dir.scale(this.grabDist)),this.onDragStart(e)}onXRPoseChanged(e){const t=this.activeController.getTipXfo().tr.subtract(this.gizmoRay.start).dot(this.gizmoRay.dir);this.holdPos=this.gizmoRay.start.add(this.gizmoRay.dir.scale(t)),this.value=t,this.delta=t-this.grabDist,this.onDrag(e)}onVRControllerButtonUp(e){this.activeController==e.controller&&(this.onDragEnd(),this.activeController=void 0)}}const o=e=>{e.undo();for(let t=e.secondaryChanges.length-1;t>=0;t--)o(e.secondaryChanges[t])},r=e=>{e.redo();for(let t=0;t<e.secondaryChanges.length;t++)r(e.secondaryChanges[t])};class l extends t.EventEmitter{__undoStack=[];__redoStack=[];__currChange=null;constructor(){super(),this.currChangeUpdated=this.currChangeUpdated.bind(this)}flush(){for(const e of this.__undoStack)e.destroy();this.__undoStack=[];for(const e of this.__redoStack)e.destroy();this.__redoStack=[],this.__currChange&&(this.__currChange.off("updated",this.currChangeUpdated),this.__currChange=null)}addChange(e){this.__currChange&&this.__currChange.off&&this.__currChange.off("updated",this.currChangeUpdated),this.__undoStack.push(e),this.__currChange=e,this.__currChange.on&&this.__currChange.on("updated",this.currChangeUpdated);for(const e of this.__redoStack)e.destroy();this.__redoStack=[],this.emit("changeAdded",{change:e})}getCurrentChange(){return this.__currChange}currChangeUpdated(e){this.emit("changeUpdated",e)}undo(e=!0){if(this.__undoStack.length>0){this.__currChange&&(this.__currChange.off("updated",this.currChangeUpdated),this.__currChange=null);const t=this.__undoStack.pop();o(t),e&&(this.__redoStack.push(t),this.emit("changeUndone",{change:t}))}}cancel(){if(this.__currChange){this.__currChange.off("updated",this.currChangeUpdated),this.__currChange=null;const e=this.__undoStack.pop();o(e)}}redo(){if(this.__redoStack.length>0){const e=this.__redoStack.pop();r(e),this.__undoStack.push(e),this.emit("changeRedone",{change:e})}}constructChange(e){return t.Registry.constructClass(e)}static isChangeClassRegistered(e){try{t.Registry.getClassName(Object.getPrototypeOf(e).constructor);return!0}catch(e){return!1}}static getChangeClassName(e){return t.Registry.getClassName(Object.getPrototypeOf(e).constructor)}static registerChange(e,a){t.Registry.register(e,a)}static getInstance(){return h||(h=new l),h}}let h;class c extends t.EventEmitter{name;secondaryChanges=[];suppressPrimaryChange=!1;closed=!1;constructor(e){super(),this.name=e||l.getChangeClassName(this)}addSecondaryChange(e){const t=this.secondaryChanges.length;return this.secondaryChanges.push(e),e.setPrimaryChange(this),t}setPrimaryChange(e){}undo(){}redo(){}update(e){throw new Error("Implement me")}toJSON(e){return{name:this.name,className:this.getClassName(),secondaryChanges:this.secondaryChanges.map((t=>t.toJSON(e)))}}fromJSON(e,t){this.name=e.name,e.secondaryChanges.forEach((e=>{const a=l.getInstance().constructChange(e.className);a.fromJSON(e,t),this.addSecondaryChange(a)}))}destroy(){}}l.registerChange("Change",c);class d extends c{param;nextValue;prevValue;supressed=!1;constructor(e,t){super(e?e.getName()+" Changed":"ParameterValueChange"),e&&(this.prevValue=e.value,this.param=e,null!=t&&(this.nextValue=t,this.param.value=this.nextValue))}undo(){this.param&&!this.suppressPrimaryChange&&(this.param.value=this.prevValue)}redo(){this.param&&!this.suppressPrimaryChange&&(this.param.value=this.nextValue)}update(e){this.param&&(this.nextValue=e.value,this.supressed||(this.param.value=this.nextValue),this.emit("updated",e))}toJSON(e){const t=super.toJSON(e);return t.paramPath=this.param.getPath(),null!=this.nextValue&&(this.nextValue.toJSON?t.value=this.nextValue.toJSON():t.value=this.nextValue),t}fromJSON(e,a){super.fromJSON(e,a);const i=a.appData.scene.getRoot().resolvePath(e.paramPath,1);i&&i instanceof t.Parameter?(this.param=i,this.prevValue=this.param.value,this.prevValue.clone?this.nextValue=this.prevValue.clone():this.nextValue=this.prevValue,null!=e.value&&(this.nextValue.fromJSON?this.nextValue.fromJSON(e.value):this.nextValue=e.value),this.supressed||(this.param.value=this.nextValue)):console.warn("resolvePath is unable to resolve",e.paramPath)}}l.registerChange("ParameterValueChange",d);class m extends t.Material{baseColorParam=new t.MaterialColorParam("BaseColor",new t.Color(1,1,.5));maintainScreenSizeParam=new t.NumberParameter("MaintainScreenSize",0);overlayParam=new t.NumberParameter("Overlay",0,[0,1]);constructor(e){super(e),this.__shaderName="HandleShader",this.addParameter(this.baseColorParam),this.addParameter(this.maintainScreenSizeParam),this.addParameter(this.overlayParam)}}t.Registry.register("HandleMaterial",m);class u extends t.GLShader{constructor(e){super(e),this.setShaderStage("VERTEX_SHADER",'\nprecision highp float;\n\nattribute vec3 positions;\n#ifdef ENABLE_TEXTURES\nattribute vec2 texCoords;\n#endif\n\n<%include file="GLSLUtils.glsl"/>\n<%include file="stack-gl/transpose.glsl"/>\n<%include file="drawItemId.glsl"/>\n<%include file="drawItemTexture.glsl"/>\n<%include file="modelMatrix.glsl"/>\n<%include file="materialparams.glsl"/>\n\nuniform mat4 viewMatrix;\nuniform mat4 projectionMatrix;\nuniform lowp int isOrthographic;\nuniform vec4 viewportFrustum;\n\n\n/* VS Outputs */\nvarying float v_drawItemId;\nvarying vec4 v_geomItemData;\nvarying vec3 v_viewPos;\n#ifdef ENABLE_TEXTURES\nvarying vec2 v_textureCoord;\n#endif\n\nvoid main(void) {\n int drawItemId = getDrawItemId();\n v_drawItemId = float(drawItemId);\n v_geomItemData = getInstanceData(drawItemId);\n\n //////////////////////////////////////////////\n // Material\n vec2 materialCoords = v_geomItemData.zw;\n vec4 materialValue1 = getMaterialValue(materialCoords, 1);\n int maintainScreenSize = int(materialValue1.x + 0.5);\n float overlay = materialValue1.y;\n\n //////////////////////////////////////////////\n // Matrix\n \n mat4 modelMatrix = getModelMatrix(drawItemId);\n if (maintainScreenSize != 0) {\n // Remove the scale from the model matrix.\n vec3 row0 = normalize(vec3(modelMatrix[0][0], modelMatrix[0][1], modelMatrix[0][2]));\n vec3 row1 = normalize(vec3(modelMatrix[1][0], modelMatrix[1][1], modelMatrix[1][2]));\n vec3 row2 = normalize(vec3(modelMatrix[2][0], modelMatrix[2][1], modelMatrix[2][2]));\n modelMatrix = mat4(\n row0.x, row0.y, row0.z, 0.0,\n row1.x, row1.y, row1.z, 0.0,\n row2.x, row2.y, row2.z, 0.0,\n modelMatrix[3][0], modelMatrix[3][1], modelMatrix[3][2], 1.0\n );\n }\n mat4 modelViewMatrix = viewMatrix * modelMatrix;\n if (maintainScreenSize != 0) {\n if (isOrthographic > 0){\n // At a distance of 1, we should match the orthographic and perspective sizes.\n // Calculate the size of the handle in perpective projection at 1 meter.\n // With a 24mm camera, the Fov is 46.4 degrees, or 0.8098327729253689 radians.\n // (0.81 / 2.0) * focalDist * 2.0\n // The frustum height at 1m is 0.81.\n float sc = viewportFrustum.y / 0.8098327;\n mat4 scmat = mat4(\n sc, 0.0, 0.0, 0.0,\n 0.0, sc, 0.0, 0.0,\n 0.0, 0.0, sc, 0.0,\n 0.0, 0.0, 0.0, 1.0\n );\n modelViewMatrix = modelViewMatrix * scmat;\n } else {\n float dist = modelViewMatrix[3][2];\n float sc = abs(dist); // Note: items in front of the camera will have a negative value here.\n mat4 scmat = mat4(\n sc, 0.0, 0.0, 0.0,\n 0.0, sc, 0.0, 0.0,\n 0.0, 0.0, sc, 0.0,\n 0.0, 0.0, 0.0, 1.0\n );\n modelViewMatrix = modelViewMatrix * scmat;\n }\n }\n\n vec4 viewPos = modelViewMatrix * vec4(positions, 1.0);\n gl_Position = projectionMatrix * viewPos;\n\n if(overlay > 0.0){\n gl_Position.z = mix(gl_Position.z, -gl_Position.w, overlay);\n }\n\n v_viewPos = viewPos.xyz;\n v_textureCoord = texCoords;\n v_textureCoord.y = 1.0 - v_textureCoord.y;// Flip y\n}\n'),this.setShaderStage("FRAGMENT_SHADER",'\nprecision highp float;\n\n<%include file="GLSLUtils.glsl"/>\n<%include file="math/constants.glsl"/>\n<%include file="drawItemTexture.glsl"/>\n<%include file="stack-gl/gamma.glsl"/>\n<%include file="materialparams.glsl"/>\n\n\n#if defined(DRAW_COLOR)\n\nuniform color BaseColor;\n\n#ifdef ENABLE_TEXTURES\nuniform sampler2D BaseColorTex;\nuniform int BaseColorTexType;\n#endif\n\n#elif defined(DRAW_GEOMDATA)\n\nuniform lowp int isOrthographic;\nimport \'surfaceGeomData.glsl\'\n\n#elif defined(DRAW_HIGHLIGHT)\n\n#ifdef ENABLE_FLOAT_TEXTURES\nvec4 getHighlightColor(int id) {\n return fetchTexel(instancesTexture, instancesTextureSize, (id * pixelsPerItem) + 4);\n}\n#else // ENABLE_FLOAT_TEXTURES\n\nuniform vec4 highlightColor;\n\nvec4 getHighlightColor() {\n return highlightColor;\n}\n\n#endif // ENABLE_FLOAT_TEXTURES\n\n#endif // DRAW_HIGHLIGHT\n\n/* VS Outputs */\nvarying float v_drawItemId;\nvarying vec4 v_geomItemData;\nvarying vec3 v_viewPos;\n#ifdef ENABLE_TEXTURES\nvarying vec2 v_textureCoord;\n#endif\n\n\n#ifdef ENABLE_ES3\n out vec4 fragColor;\n#endif\nvoid main(void) {\n#ifndef ENABLE_ES3\n vec4 fragColor;\n#endif\n\n int drawItemId = int(v_drawItemId + 0.5);\n\n //////////////////////////////////////////////\n // Color\n#if defined(DRAW_COLOR)\n\n vec2 materialCoords = v_geomItemData.zw;\n vec4 baseColor = toLinear(getMaterialValue(materialCoords, 0));\n\n fragColor = baseColor;\n\n#ifdef ENABLE_INLINE_GAMMACORRECTION\n fragColor.rgb = toGamma(fragColor.rgb);\n#endif\n\n //////////////////////////////////////////////\n // GeomData\n#elif defined(DRAW_GEOMDATA)\n\n fragColor = setFragColor_geomData(v_viewPos, floatGeomBuffer, passId, v_drawItemId, isOrthographic);\n //////////////////////////////////////////////\n // Highlight\n#elif defined(DRAW_HIGHLIGHT)\n \n fragColor = getHighlightColor(drawItemId);\n\n#endif // DRAW_HIGHLIGHT\n\n\n#ifndef ENABLE_ES3\n gl_FragColor = fragColor;\n#endif\n}\n')}static getPackedMaterialData(e){const t=new Float32Array(8),a=e.getParameter("BaseColor").value;return t[0]=a.r,t[1]=a.g,t[2]=a.b,t[3]=a.a,t[4]=e.getParameter("MaintainScreenSize").value,t[5]=e.getParameter("Overlay").value,t}static isOverlay(){return!0}static getMaterialTemplate(){return g}}const g=new m("HandleShader_template");t.Registry.register("HandleShader",u);const p=(e,t)=>{e.update();const a=e.positions;for(let e=0;e<a.getCount();e++){const i=a.getValue(e),s=t.transformVec3(i);a.setValue(e,s)}};class f extends c{supressed=!1;treeItems=[];baseXfo;localXfos=[];prevValues=[];newValues=[];constructor(e,t){if(super("SelectionXfoChange"),!e||!t)return;this.treeItems=e,this.baseXfo=t;const a=t.inverse();this.treeItems.forEach((e=>{this.localXfos.push(a.multiply(e.globalXfoParam.value)),this.prevValues.push(e.globalXfoParam.value),this.newValues.push(e.globalXfoParam.value)}))}setDeltaXfo(e){const t=this.baseXfo.clone();t.tr=e.tr.add(t.tr),t.ori=e.ori.multiply(t.ori),t.sc=e.sc.multiply(t.sc),this.prevValues.forEach(((e,a)=>{const i=t.multiply(this.localXfos[a]);this.newValues[a]=i,this.treeItems[a].globalXfoParam.value=this.newValues[a].clone()})),this.emit("updated",{newValues:[...this.newValues]})}setDone(){this.emit("done")}undo(){this.treeItems.forEach(((e,t)=>{e.globalXfoParam.value=this.prevValues[t]}))}redo(){this.treeItems.forEach(((e,t)=>{e.globalXfoParam.value=this.newValues[t]}))}update(e){this.newValues=e.newValues,this.supressed||this.treeItems.forEach(((e,t)=>{e.globalXfoParam.value=this.newValues[t]})),this.emit("updated",e)}toJSON(e){const t=super.toJSON(e);return t.treeItems=[],t.prevValues=[],t.newValues=[],t.baseXfo=this.baseXfo.toJSON(),t.supressed=this.supressed,this.treeItems.forEach(((e,a)=>{t.treeItems[a]=this.treeItems[a].getPath(),t.prevValues[a]=this.prevValues[a].toJSON(),t.newValues[a]=this.newValues[a].toJSON()})),t}fromJSON(e,a){super.fromJSON(e,a),this.baseXfo||(this.baseXfo=new t.Xfo),this.baseXfo.fromJSON(e.baseXfo);const i=this.baseXfo.inverse();e.treeItems.forEach(((s,n)=>{this.treeItems[n]=a.appData.scene.getRoot().resolvePath(s),this.localXfos.push(i.multiply(this.treeItems[n].globalXfoParam.value)),this.prevValues[n]||(this.prevValues[n]=new t.Xfo),this.prevValues[n].fromJSON(e.prevValues[n]),this.newValues[n]||(this.newValues[n]=new t.Xfo),this.newValues[n].fromJSON(e.newValues[n])}))}}l.registerChange("SelectionXfoChange",f);class v extends c{__selectionManager;__prevSelection;__newSelection;constructor(e,t,a){super("SelectionChange"),e&&t&&a&&(this.__selectionManager=e,this.__prevSelection=t,this.__newSelection=a)}undo(){this.__selectionManager.setSelection(this.__prevSelection,!1)}redo(){this.__selectionManager.setSelection(this.__newSelection,!1)}toJSON(e){const t=super.toJSON(e),a=[];for(const e of this.__newSelection)a.push(e.getPath());return t.itemPaths=a,t}fromJSON(e,t){super.fromJSON(e,t),this.__selectionManager=t.appData.selectionManager,this.__prevSelection=new Set(this.__selectionManager.getSelection());const a=t.appData.scene.getRoot(),i=new Set;for(const t of e.itemPaths)i.add(a.resolvePath(t,1));this.__newSelection=i,this.__selectionManager.setSelection(this.__newSelection,!1)}}l.registerChange("SelectionChange",v);class P extends c{selection;state;constructor(e,t){super("Selection Visibility Change"),e&&"boolean"==typeof t&&(this.selection=e,this.state=t,this._changeItemsVisibility(this.state))}undo(){this._changeItemsVisibility(!this.state)}redo(){this._changeItemsVisibility(this.state)}_changeItemsVisibility(e){for(const t of this.selection)t.getParameter("Visible").value=e}}l.registerChange("ToggleSelectionVisibility",P);class I extends c{treeItem;owner;prevSelection;selectionManager;treeItemIndex;constructor(e,t,a){e?(super(e.getName()+" Added"),this.treeItem=e,this.owner=t,this.selectionManager=a,this.prevSelection=new Set(this.selectionManager.getSelection()),this.treeItemIndex=this.owner.getChildIndex(this.owner.addChild(this.treeItem)),this.selectionManager.setSelection(new Set([this.treeItem]),!1)):super()}undo(){if(this.treeItem instanceof t.Operator){this.treeItem.detach()}else this.treeItem instanceof t.TreeItem&&this.treeItem.traverse((e=>{if(e instanceof t.Operator){e.detach()}}),!1);this.owner.removeChild(this.treeItemIndex),this.selectionManager&&this.selectionManager.setSelection(this.prevSelection,!1)}redo(){if(this.treeItem instanceof t.Operator){this.treeItem.reattach()}else this.treeItem instanceof t.TreeItem&&this.treeItem.traverse((e=>{if(e instanceof t.Operator){e.reattach()}}),!1);this.owner.addChild(this.treeItem),this.selectionManager&&this.selectionManager.setSelection(new Set([this.treeItem]),!1)}toJSON(e){const t=super.toJSON(e);return t.treeItem=this.treeItem.toJSON(e),t.treeItemPath=this.treeItem.getPath(),t.treeItemIndex=this.treeItemIndex,t}fromJSON(e,a){super.fromJSON(e,a);const i=t.Registry.constructClass(e.treeItem.type);i?(this.name=e.name,this.treeItem=i,this.treeItem.fromJSON(e.treeItem,a),this.treeItemIndex=this.owner.getChildIndex(this.owner.addChild(this.treeItem))):console.warn("resolvePath is unable to construct",e.treeItem)}destroy(){}}l.registerChange("TreeItemAddChange",I);class C extends c{treeItem;oldOwner;oldOwnerIndex;newOwner;constructor(e,t){e?(super(e.getName()+" Moved"),this.treeItem=e,this.oldOwner=this.treeItem.getOwner(),this.oldOwnerIndex=this.oldOwner.getChildIndex(this.treeItem),this.newOwner=t,this.newOwner.addChild(this.treeItem,!0)):super()}undo(){this.oldOwner.insertChild(this.treeItem,this.oldOwnerIndex,!0)}redo(){this.newOwner.addChild(this.treeItem,!0)}toJSON(e){const t=super.toJSON(e);return t.treeItemPath=this.treeItem.getPath(),t.newOwnerPath=this.newOwner.getPath(),t}fromJSON(e,t){if(!t||!t.scene)return;super.fromJSON(e,t);const a=t.scene.getRoot().resolvePath(e.treeItemPath,1);if(!a)return void console.warn("resolvePath is unable to resolve",e.treeItemPath);const i=t.scene.getRoot().resolvePath(e.newOwnerPath,1);i?(this.name=e.name,this.treeItem=a,this.newOwner=i,this.oldOwner=this.treeItem.getOwner(),this.oldOwnerIndex=this.oldOwner.getChildIndex(this.treeItem),this.newOwner.addChild(this.treeItem,!0)):console.warn("resolvePath is unable to resolve",e.newOwnerPath)}}l.registerChange("TreeItemMoveChange",C);class w extends c{items=[];itemOwners=[];itemPaths=[];itemIndices=[];constructor(e,t){if(super(),e){this.items=e;const a=new Set(t?.selectionManager?.getSelection()),i=[];this.items.forEach((e=>{const t=e.getOwner(),s=t.getChildIndex(e);i.push(e.getName()),this.itemOwners.push(t),this.itemPaths.push(e.getPath()),this.itemIndices.push(s),a.has(e)&&a.delete(e),e.traverse((e=>{a.has(e)&&a.delete(e)}),!1),t.removeChild(s)})),t?.selectionManager&&t.selectionManager.setSelection(a,!0,this),this.name=i+" Deleted"}}undo(){this.items.forEach(((e,t)=>{this.itemOwners[t].insertChild(e,this.itemIndices[t],!1,!1)}))}redo(){this.items.forEach(((e,t)=>{this.itemOwners[t].removeChild(this.itemIndices[t])}))}toJSON(e){const t=super.toJSON(e);return t.itemPaths=this.itemPaths,t.itemIndices=this.itemIndices,t}fromJSON(e,t){super.fromJSON(e,t);const a=t.appData.scene.getRoot();e.itemPaths.forEach((e=>{const t=a.resolvePath(e,1);if(!t)return void console.warn("resolvePath is unable to resolve",e);const i=t.getOwner(),s=i.getChildIndex(t);this.itemOwners.push(i),this.itemPaths.push(t.getPath()),this.itemIndices.push(s),i.removeChild(s)}))}}l.registerChange("TreeItemsRemoveChange",w);class b extends n{handleMat;baseXfo;change;param;selectionGroup;constructor(e,a=.1,i=.003,s=new t.Color){super(e),this.colorParam.value=s,this.handleMat=new m("handle"),this.handleMat.baseColorParam.value=s,this.handleMat.maintainScreenSizeParam.value=1,this.handleMat.overlayParam.value=.9;const n=new t.Cylinder(i,a,64);n.baseZAtZeroParam.value=!0;const o=new t.Cone(8*i,16*i,64,!0),r=new t.GeomItem("handle",n,this.handleMat),l=new t.GeomItem("tip",o,this.handleMat),h=new t.Xfo;h.tr.set(0,0,a),p(o,h),this.colorParam.on("valueChanged",(()=>{this.handleMat.baseColorParam.value=this.colorParam.value})),this.addChild(r),this.addChild(l)}highlight(){super.highlight(),this.handleMat.baseColorParam.value=this.highlightColorParam.value}unhighlight(){super.unhighlight(),this.handleMat.baseColorParam.value=this.colorParam.value}setSelectionGroup(e){this.selectionGroup=e}setTargetParam(e){this.param=e}getTargetParam(){return this.param?this.param:this.globalXfoParam}onDragStart(e){const t=this.getTargetParam();if(this.baseXfo=t.value,this.selectionGroup){const e=this.selectionGroup.getItems();this.change=new f(Array.from(e),this.globalXfoParam.value),l.getInstance().addChange(this.change)}else this.change=new d(t),l.getInstance().addChange(this.change)}onDrag(e){const a=this.holdPos.subtract(this.grabPos);if(this.change instanceof f){const e=new t.Xfo(a);this.change.setDeltaXfo(e)}else{const e=this.baseXfo.clone();e.tr.addInPlace(a),this.change.update({value:e})}}onDragEnd(e){this.change instanceof f&&this.change.setDone(),this.change=null}}class y extends s{param;radiusParam;baseXfo;handleXfo;snapIncrementAngle=22.5;enableAngleSnapping=!1;handleToTargetXfo;vec0;change;handleMat;handle;selectionGroup;constructor(e,a,i,s=.5*Math.PI,n=new t.Color(1,1,0)){super(e),this.radiusParam=new t.NumberParameter("Radius",a),this.colorParam.value=n,this.addParameter(this.radiusParam),this.handleMat=new m("handle"),this.handleMat.baseColorParam.value=n,this.handleMat.maintainScreenSizeParam.value=1,this.handleMat.overlayParam.value=.9;const o=new t.Torus(i,a,64,s);this.handle=new t.GeomItem("handle",o,this.handleMat),this.radiusParam.on("valueChanged",(()=>{a=this.radiusParam.value,o.outerRadiusParam.value=a,o.innerRadiusParam.value=.02*a})),this.colorParam.on("valueChanged",(()=>{this.handleMat.baseColorParam.value=this.colorParam.value})),this.addChild(this.handle)}highlight(){super.highlight(),this.handleMat.baseColorParam.value=this.highlightColorParam.value}unhighlight(){super.unhighlight(),this.handleMat.baseColorParam.value=this.colorParam.value}setSelectionGroup(e){this.selectionGroup=e}setTargetParam(e){this.param=e}getTargetParam(){return this.param?this.param:this.globalXfoParam}onDragStart(e){if(this.highlight(),this.baseXfo=this.globalXfoParam.value.clone(),this.vec0=this.grabPos.subtract(this.baseXfo.tr),this.vec0.normalizeInPlace(),this.selectionGroup){const e=this.selectionGroup.getItems();this.change=new f(Array.from(e),this.baseXfo),l.getInstance().addChange(this.change)}else{const e=this.baseXfo.inverse(),t=this.getTargetParam();this.handleToTargetXfo=e.multiply(t.value),this.change=new d(t),l.getInstance().addChange(this.change)}}onDrag(e){const a=this.holdPos.subtract(this.baseXfo.tr);a.normalizeInPlace();let i=this.vec0.angleTo(a);if(this.vec0.cross(a).dot(this.baseXfo.ori.getZaxis())<0&&(i=-i),e instanceof t.ZeaMouseEvent&&e.shiftKey||this.enableAngleSnapping){const e=t.MathFunctions.degToRad(this.snapIncrementAngle);i=Math.floor(i/e)*e}const s=new t.Xfo;if(s.ori.setFromAxisAndAngle(this.baseXfo.ori.getZaxis(),i),this.change instanceof f)this.change.setDeltaXfo(s);else{const e=this.baseXfo.clone();e.ori=s.ori.multiply(e.ori);const t=e.multiply(this.handleToTargetXfo);this.change.update({value:t})}}onDragEnd(e){this.change instanceof f&&this.change.setDone(),this.change=null}}class X extends s{param;fullXfoManipulationInVR;grabOffset;baseXfo;change;selectionGroup;constructor(e){super(e),this.fullXfoManipulationInVR=!0}setSelectionGroup(e){this.selectionGroup=e}setTargetParam(e){this.param=e}getTargetParam(){return this.param?this.param:this.globalXfoParam}onDragStart(e){this.grabPos=this.grabPos;const t=this.getTargetParam();if(this.baseXfo=t.value,this.selectionGroup){const e=this.selectionGroup.getItems();this.change=new f(Array.from(e),this.globalXfoParam.value),l.getInstance().addChange(this.change)}else this.change=new d(t),l.getInstance().addChange(this.change)}onDrag(e){const a=this.holdPos.subtract(this.grabPos);if(this.change instanceof f){const e=new t.Xfo(a);this.change.setDeltaXfo(e)}else{const e=this.baseXfo.clone();e.tr.addInPlace(a),this.change.update({value:e})}}onDragEnd(e){this.change instanceof f&&this.change.setDone(),this.change=null}onXRControllerButtonDown(e){if(this.fullXfoManipulationInVR){this.activeController=e.controller;const t=this.activeController.getTipXfo(),a=this.globalXfoParam.value;this.grabOffset=t.inverse().multiply(a)}else super.onXRControllerButtonDown(e)}onXRPoseChanged(e){if(this.fullXfoManipulationInVR){const e=this.activeController.getTipXfo().multiply(this.grabOffset);if(this.change)this.change.update({value:e});else{this.getTargetParam().value=e}}else super.onXRPoseChanged(e)}onVRControllerButtonUp(e){this.fullXfoManipulationInVR?this.change=null:super.onVRControllerButtonUp(e)}}class M extends X{sizeParam;handle;handleMat;constructor(e,a,i,s=new t.Color){super(e),this.sizeParam=new t.NumberParameter("Size",a),this.addParameter(this.sizeParam),this.colorParam.value=s,this.handleMat=new m("handle"),this.handleMat.baseColorParam.value=s,this.handleMat.maintainScreenSizeParam.value=1,this.handleMat.overlayParam.value=.9;const n=new t.Cuboid(a,a,.02*a),o=new t.Xfo;o.tr=i,p(n,o),this.handle=new t.GeomItem("handle",n,this.handleMat),this.sizeParam.on("valueChanged",(()=>{a=this.sizeParam.value,n.sizeXParam.value=a,n.sizeYParam.value=a,n.sizeZParam.value=.02*a})),this.colorParam.on("valueChanged",(()=>{this.handleMat.baseColorParam.value=this.colorParam.value})),this.addChild(this.handle)}highlight(){super.highlight(),this.handleMat.baseColorParam.value=this.highlightColorParam.value}unhighlight(){super.unhighlight(),this.handleMat.baseColorParam.value=this.colorParam.value}}class S extends t.TreeItem{param;highlightColorParam=new t.ColorParameter("HighlightColor",new t.Color(1,1,1));constructor(e=.1,a=.001){super("XfoHandle"),this.highlightColorParam.on("valueChanged",(()=>{const e=this.highlightColorParam.value;this.traverse((t=>{t instanceof s&&(t.highlightColorParam.value=e)}))})),this.addParameter(this.highlightColorParam);const i=new t.TreeItem("Translate");this.addChild(i);const n=new t.Color(1,.1,.1),o=new t.Color("#32CD32"),r=new t.Color("#1E90FF");n.a=1,o.a=1,r.a=1;{const s=new b("linearX",e,a,n),o=new t.Xfo;o.ori.setFromAxisAndAngle(new t.Vec3(0,1,0),.5*Math.PI),s.localXfoParam.value=o,i.addChild(s)}{const s=new b("linearY",e,a,o),n=new t.Xfo;n.ori.setFromAxisAndAngle(new t.Vec3(1,0,0),-.5*Math.PI),s.localXfoParam.value=n,i.addChild(s)}{const t=new b("linearZ",e,a,r);i.addChild(t)}const l=.25*e;{const e=new M("planarXY",l,new t.Vec3(.85*l,.85*l,0),r),a=new t.Xfo;e.localXfoParam.value=a,i.addChild(e)}{const e=new M("planarYZ",l,new t.Vec3(-.85*l,.85*l,0),n),a=new t.Xfo;a.ori.setFromAxisAndAngle(new t.Vec3(0,1,0),.5*Math.PI),e.localXfoParam.value=a,i.addChild(e)}{const e=new M("planarXZ",l,new t.Vec3(.85*l,.85*l,0),o),a=new t.Xfo;a.ori.setFromAxisAndAngle(new t.Vec3(1,0,0),.5*Math.PI),e.localXfoParam.value=a,i.addChild(e)}const h=new t.TreeItem("Rotate");this.addChild(h);{const i=new y("rotationX",.75*e,a,.5*Math.PI,n),s=new t.Xfo;s.ori.setFromEulerAngles(new t.EulerAngles(-.5*Math.PI,-.5*Math.PI,0)),i.localXfoParam.value=s,h.addChild(i)}{const i=new y("rotationY",.75*e,a,.5*Math.PI,o),s=new t.Xfo;s.ori.setFromAxisAndAngle(new t.Vec3(1,0,0),-.5*Math.PI),i.localXfoParam.value=s,h.addChild(i)}{const i=new y("rotationZ",.75*e,a,.5*Math.PI,r),s=new t.Xfo;s.ori.setFromAxisAndAngle(new t.Vec3(0,0,1),.5*Math.PI),i.localXfoParam.value=s,h.addChild(i)}}showHandles(e){e?this.setVisible(!0):this.setVisible(!1)}setTargetParam(e){this.param=e,this.traverse((t=>{(t instanceof b||t instanceof M||t instanceof y)&&t.setTargetParam(e)}))}setSelectionGroup(e){this.traverse((t=>{(t instanceof b||t instanceof M||t instanceof y)&&t.setSelectionGroup(e)}))}}class T extends t.Operator{currGroupXfo;xfoModeInput=new t.NumberOperatorInput("InitialXfoMode");xfoOutput=new t.XfoOperatorOutput("GroupGlobalXfo");constructor(e,a){super(),this.addInput(this.xfoModeInput).setParam(e),this.addOutput(this.xfoOutput).setParam(a),this.currGroupXfo=new t.Xfo}addItem(e){const a=new t.XfoOperatorInput("MemberGlobalXfo"+this.getNumInputs());a.setParam(e.globalXfoParam),this.addInput(a),this.setDirty()}removeItem(e){const t=e.globalXfoParam;for(let e=1;e<this.getNumInputs();e++){const a=this.getInputByIndex(e);if(a.getParam()==t)return this.removeInput(a),void this.setDirty()}throw new Error("Item not found in SelectionGroupXfoOperator")}backPropagateValue(e){const t=this.currGroupXfo.inverse(),a=e.multiply(t);a.ori.normalizeInPlace(),this.currGroupXfo=a.multiply(this.currGroupXfo);for(let e=1;e<this.getNumInputs();e++){const t=this.getInputByIndex(e),i=t.getValue(),s=a.multiply(i);t.setValue(s)}}evaluate(){if(this.currGroupXfo=new t.Xfo,1==this.getNumInputs())return void this.xfoOutput.setClean(this.currGroupXfo);const e=this.xfoModeInput.param.value;if(e!=t.KinematicGroup.INITIAL_XFO_MODES.manual){if(e==t.KinematicGroup.INITIAL_XFO_MODES.first){const e=this.getInputByIndex(1).getValue();this.currGroupXfo.tr=e.tr.clone(),this.currGroupXfo.ori=e.ori.clone()}else if(e==t.KinematicGroup.INITIAL_XFO_MODES.average){this.currGroupXfo.ori.set(0,0,0,0);let e=0;for(let t=1;t<this.getNumInputs();t++){const a=this.getInputByIndex(t).getValue();this.currGroupXfo.tr.addInPlace(a.tr),0==e&&this.currGroupXfo.ori.addInPlace(a.ori),e++}this.currGroupXfo.tr.scaleInPlace(1/e)}else{if(e!=t.KinematicGroup.INITIAL_XFO_MODES.globalOri)throw new Error("Invalid KinematicGroup.INITIAL_XFO_MODES.");{let e=0;for(let t=1;t<this.getNumInputs();t++){const a=this.getInputByIndex(t).getValue();this.currGroupXfo.tr.addInPlace(a.tr),e++}this.currGroupXfo.tr.scaleInPlace(1/e)}}this.currGroupXfo.ori.normalizeInPlace(),this.xfoOutput.setClean(this.currGroupXfo)}else this.currGroupXfo=this.xfoOutput.getParam().value.clone()}}const x={disabled:0,manual:1,first:2,average:3,globalOri:4};class A extends t.SelectionSet{initialXfoModeParam=new t.MultiChoiceParameter("InitialXfoMode",x.average,["manual","first","average","global"]);selectionGroupXfoOp;constructor(e){super();const a=e.selectionOutlineColor?e.selectionOutlineColor:new t.Color(3/255,227/255,172/255,.1);this.highlightColorParam.value=a,this.itemsParam.setFilterFn((e=>e instanceof t.BaseItem)),this.addParameter(this.initialXfoModeParam),this.selectionGroupXfoOp=new T(this.initialXfoModeParam,this.globalXfoParam)}static get INITIAL_XFO_MODES(){return x}clone(e){const t=new A;return t.copyFrom(this,e),t}bindItem(e,t){const a=this.highlightColorParam.value;a.a=this.highlightFillParam.value,e.addHighlight("selected"+this.getId(),a,!0),this.selectionGroupXfoOp.addItem(e)}unbindItem(e,t){e.removeHighlight("selected"+this.getId(),!0),this.selectionGroupXfoOp.removeItem(e)}}class D extends t.EventEmitter{appData;leadSelection=void 0;selectionGroup;xfoHandle;xfoHandleVisible;renderer;pickFilter;pickCB;constructor(e,a={}){super(),this.appData=e,this.selectionGroup=new A(a),!0===a.enableXfoHandles&&(this.xfoHandle=new S,this.xfoHandle.setSelectionGroup(this.selectionGroup),this.xfoHandle.setVisible(!1),this.xfoHandle.highlightColorParam.value=new t.Color(1,1,0),this.xfoHandleVisible=!0,this.selectionGroup.addChild(this.xfoHandle)),this.appData.renderer&&this.setRenderer(this.appData.renderer)}setRenderer(e){this.renderer!=e?(this.renderer=e,this.renderer.addTreeItem(this.selectionGroup)):console.warn("Renderer already set on SelectionManager")}setXfoMode(e){this.xfoHandle&&(this.selectionGroup.initialXfoModeParam.value=e)}showHandles(e){this.xfoHandleVisible=e}updateHandleVisibility(){if(!this.xfoHandle)return;const e=this.selectionGroup.getItems(),t=Array.from(e).length>0;this.xfoHandle.setVisible(t&&this.xfoHandleVisible),this.renderer.requestRedraw()}getSelection(){return this.selectionGroup.getItems()}setSelection(e,t=!0,a){const i=new Set(this.selectionGroup.getItems()),s=new Set(i);for(const t of e)i.has(t)||(t.setSelected(!0),i.add(t));for(const t of i)e.has(t)||(t.setSelected(!1),i.delete(t));if(this.selectionGroup.setItems(i),i.size>0?this.setLeadSelection(i.values().next().value):this.setLeadSelection(),this.updateHandleVisibility(),t){const e=new v(this,s,i);a?a.addSecondaryChange(e):l.getInstance().addChange(e)}this.emit("selectionChanged",{prevSelection:s,selection:i})}setLeadSelection(e){this.leadSelection!=e&&(this.leadSelection=e,this.emit("leadSelectionChanged",{treeItem:e}))}toggleItemSelection(e,t=!0,a=!0,i){const s=new Set(this.selectionGroup.getItems()),n=new Set(s);if(t&&(1!=s.size||!s.has(e))){let t=!0;if(s.has(e)){let a=1;e.traverse((e=>{s.has(e)&&a++})),t=a!=s.size}t&&(Array.from(s).forEach((e=>{e.setSelected(!1)})),s.clear())}let o;if(s.has(e)?(e.setSelected(!1),s.delete(e),o=!1):(e.setSelected(!0),s.add(e),o=!0),this.selectionGroup.setItems(s),o&&1===s.size?this.setLeadSelection(e):o||(1===s.size?this.setLeadSelection(s.values().next().value):0===s.size&&this.setLeadSelection()),a){const e=new v(this,n,s);i?i.addSecondaryChange(e):l.getInstance().addChange(e)}this.updateHandleVisibility(),this.emit("selectionChanged",{prevSelection:n,selection:s})}clearSelection(e=!0,t){const a=new Set(this.selectionGroup.getItems());if(0==a.size)return;let i;e&&(i=new Set(a));for(const e of a)e.setSelected(!1);if(a.clear(),this.selectionGroup.setItems(a),this.setLeadSelection(),this.updateHandleVisibility(),e){const e=new v(this,i,a);t?t.addSecondaryChange(e):l.getInstance().addChange(e)}this.emit("selectionChanged",{selection:a,prevSelection:i})}selectItems(e,t=!0,a=!0,i){const s=new Set(this.selectionGroup.getItems()),n=new Set(s);t&&s.clear();for(const t of e)s.has(t)||(t.setSelected(!0),s.add(t));if(this.selectionGroup.setItems(s),1===s.size?this.setLeadSelection(s.values().next().value):0===s.size&&this.setLeadSelection(),this.updateHandleVisibility(),a){const e=new v(this,n,s);i?i.addSecondaryChange(e):l.getInstance().addChange(e)}this.emit("selectionChanged",{prevSelection:n,selection:s})}deselectItems(e,t=!0,a){const i=new Set(this.selectionGroup.getItems()),s=new Set(i);for(const t of e)i.has(t)&&(t.setSelected(!1),i.delete(t));if(this.selectionGroup.setItems(i),1===i.size?this.setLeadSelection(i.values().next().value):0===i.size&&this.setLeadSelection(),this.updateHandleVisibility(),t){const e=new v(this,s,i);a?a.addSecondaryChange(e):l.getInstance().addChange(e)}this.emit("selectionChanged",{prevSelection:s,selection:i})}startPickingMode(e,t){this.pickCB=e,this.pickFilter=t}pickingModeActive(){return!!this.pickCB&&!!this.pickFilter}endPickingMode(){this.pickCB=void 0}pick(e){if(this.pickCB)if(Array.isArray(e))e.forEach((e=>{const t=this.pickFilter?this.pickFilter(e):e;t&&this.pickCB(t)}));else{const t=this.pickFilter?this.pickFilter(e):e;t&&this.pickCB(t)}}}class R extends t.BaseTool{appData;dragging;selectionManager;selectionRectXfo;rectItem;pointerDownPos;selectionRect;selectionRectMat;selectionFilterFn=null;constructor(e){super(),e||console.error("App data not provided to tool"),this.appData=e,this.dragging=!1,e.selectionManager||console.error("`SelectionTool` requires `SelectionManager` to be provided in the `appData` object"),this.selectionManager=e.selectionManager,this.selectionRect=new t.Rect(1,1),this.selectionRectMat=new t.ScreenSpaceMaterial("marker"),this.selectionRectMat.baseColorParam.value=new t.Color("#03E3AC"),this.selectionRectXfo=new t.Xfo,this.selectionRectXfo.sc.set(0,0,0),this.rectItem=new t.GeomItem("selectionRect",this.selectionRect,this.selectionRectMat),this.rectItem.visibleParam.value=!1,this.rectItem.pickableParam.value=!1,this.appData.renderer.addTreeItem(this.rectItem)}activateTool(){super.activateTool()}deactivateTool(){super.deactivateTool(),this.selectionRectXfo.sc.set(0,0,0),this.rectItem.globalXfoParam.value=this.selectionRectXfo,this.rectItem.visibleParam.value=!1}setSelectionManager(e){this.selectionManager=e}setSelectionFilter(e){this.selectionFilterFn=e}resizeRect(e,a){const i=e.getWidth(),s=e.getHeight(),n=new t.Vec2(1/i*2,1/s*2),o=a.multiply(n);this.selectionRectXfo.sc.set(Math.abs(o.x),Math.abs(o.y),1);const r=this.pointerDownPos.subtract(a.scale(.5)).multiply(n).subtract(new t.Vec2(1,1));this.selectionRectXfo.tr.x=r.x,this.selectionRectXfo.tr.y=-r.y,this.rectItem.globalXfoParam.value=this.selectionRectXfo}onPointerDoublePress(e){}onPointerDown(e){this.dragging?(this.selectionRectXfo.sc.set(0,0,0),this.rectItem.globalXfoParam.value=this.selectionRectXfo,this.rectItem.visibleParam.value=!1,this.pointerDownPos=void 0,this.dragging=!1,e.stopPropagation()):(e instanceof t.ZeaTouchEvent||e instanceof t.ZeaMouseEvent&&0==e.button)&&(this.pointerDownPos=e.pointerPos.scale(window.devicePixelRatio),this.dragging=!1,e.stopPropagation())}onPointerMove(e){if(e instanceof t.ZeaMouseEvent||e instanceof t.ZeaTouchEvent)if(this.pointerDownPos){const t=e.pointerPos.scale(window.devicePixelRatio),a=this.pointerDownPos.subtract(t);a.length()>4&&(this.dragging=!0,this.rectItem.visibleParam.value=!0,this.resizeRect(e.viewport,a)),e.stopPropagation()}else this.selectionManager.pickingModeActive()&&(e.intersectionData?this.selectionManager.pickFilter(e.intersectionData.geomItem):this.selectionManager.pickFilter(null));else console.warn("not handling VR")}onPointerUp(e){if((e instanceof t.ZeaMouseEvent||e instanceof t.ZeaTouchEvent)&&this.pointerDownPos){if(this.dragging){this.dragging=!1,this.rectItem.visibleParam.value=!1;const a=e.pointerPos.scale(window.devicePixelRatio),i=new t.Vec2(Math.min(this.pointerDownPos.x,a.x),Math.min(this.pointerDownPos.y,a.y)),n=new t.Vec2(Math.max(this.pointerDownPos.x,a.x),Math.max(this.pointerDownPos.y,a.y)),o=e.viewport;let r=Array.from(o.getGeomItemsInRect(i,n));if(r=r.filter((e=>e!=this.rectItem&&!(e.parent instanceof s))),this.selectionFilterFn){const e=[];r.forEach((t=>{const a=this.selectionFilterFn(t);a&&e.push(a)})),r=e}if(!this.selectionManager)throw"Please set the Selection Manager on the Selection Tool before using it.";if(this.selectionManager.pickingModeActive())this.selectionManager.pick(r);else{const t=new Set(r);e.shiftKey?this.selectionManager.deselectItems(t):this.selectionManager.selectItems(t,!e.ctrlKey),this.selectionRectXfo.sc.set(0,0,0),this.rectItem.globalXfoParam.value=this.selectionRectXfo}}else{const t=e.viewport,a=e.pointerPos,i=t.getGeomDataAtPos(a,void 0);if(null==i||i.geomItem.getOwner()instanceof s)this.selectionManager.clearSelection();else{let t=i.geomItem;if(this.selectionFilterFn&&(t=this.selectionFilterFn(t)),t)if(this.selectionManager.pickingModeActive())this.selectionManager.pick(t);else if(e.shiftKey){const e=new Set;e.add(t),this.selectionManager.deselectItems(e)}else this.selectionManager.toggleItemSelection(t,!e.ctrlKey)}}this.pointerDownPos=void 0,e.stopPropagation()}}onXRControllerButtonDown(e){if(1==e.button){if(!this.selectionManager)throw"Please set the Selection Manager on the Selection Tool before using it.";const t=e.controller.getGeomItemAtTip();null==t||t.geomItem.getOwner()instanceof s||(this.selectionManager.toggleItemSelection(t.geomItem),e.stopPropagation())}}}const V=new t.Lines;V.setNumVertices(2),V.setNumSegments(1),V.setSegmentVertexIndices(0,0,1);const E=V.getVertexAttribute("positions");E.setValue(0,new t.Vec3(0,0,0)),E.setValue(1,new t.Vec3(0,0,1)),V.setBoundingBoxDirty();const O=new t.LinesMaterial("line");O.baseColorParam.value=new t.Color(.2,1,.2);class k extends t.BaseTool{appData;vrViewport;prevCursor;pointerController;pointerThickness=.002;pointerColor=new t.Color(1,.2,.2);geom;material;defaultRaycastDist=0;raycastDist=20;bindControllerId;pointerGeomItems=[];constructor(e){super(),this.appData=e,this.appData.renderer.getXRViewport().then((e=>{e instanceof t.VRViewport&&(this.vrViewport=e)}))}activateTool(){super.activateTool(),this.displayPointers()}deactivateTool(){super.deactivateTool(),this.removePointers()}displayPointers(){this.appData&&this.appData.renderer&&(this.prevCursor=this.appData.renderer.getGLCanvas().style.cursor,this.appData.renderer.getGLCanvas().style.cursor="crosshair"),this.pointerThickness>0?(!this.geom||this.geom instanceof t.Cylinder)&&(this.geom=new t.Cylinder(this.pointerThickness,1,6,2,!0,!0),this.material=new t.FlatSurfaceMaterial("line"),this.material.overlayParam.value=.5):(this.geom=V,this.material=new t.LinesMaterial("line"),this.material.overlayParam.value=.5),this.material.baseColorParam.value=this.pointerColor;const e=e=>{if(this.pointerGeomItems[e.id])return;this.defaultRaycastDist=e.raycastDist,e.raycastDist=this.raycastDist;const a=new t.GeomItem("PointerRay",this.geom,this.material);a.pickableParam.value=!1;const i=new t.Xfo;i.sc.set(1,1,this.raycastDist/e.getTipXfo().sc.z),a.localXfoParam.value=i,e.tipItem.addChild(a,!1),this.pointerGeomItems[e.id]=a,this.appData.session&&this.appData.session.pub("poseChanged",{interfaceType:"VR",showPointer:{controllerId:e.id,thickness:this.pointerThickness,xfo:i,color:this.pointerColor}})};if(this.pointerController)e(this.pointerController);else if(this.vrViewport){for(const t of this.vrViewport.controllers)e(t);this.bindControllerId=this.vrViewport.on("controllerAdded",(t=>e(t.controller)))}}removePointers(){this.appData&&this.appData.renderer&&(this.appData.renderer.getGLCanvas().style.cursor=this.prevCursor);const e=e=>{this.pointerGeomItems[e.id]&&(e.tipItem.removeChildByHandle(this.pointerGeomItems[e.id]),e.raycastDist=this.defaultRaycastDist,this.pointerGeomItems[e.id]=null)};if(this.pointerController)e(this.pointerController);else if(this.vrViewport){for(const t of this.vrViewport.controllers)e(t);this.vrViewport.removeListenerById("controllerAdded",this.bindControllerId)}}setPointerLength(e,t){const a=this.pointerGeomItems[t.id];if(a){const i=a.localXfoParam.value;i.sc.set(1,1,e/t.getTipXfo().sc.z),a.localXfoParam.value=i,this.appData.session&&this.appData.session.pub("poseChanged",{interfaceType:"VR",updatePointer:{controllerId:t.id,xfo:i}})}}checkPointerIntersection(e){const t=e.getGeomItemAtTip();t?this.setPointerLength(t.dist,e):this.setPointerLength(this.raycastDist,e)}onPointerMove(e){e instanceof t.XRPoseEvent&&(this.pointerController?this.checkPointerIntersection(this.pointerController):e.controllers.forEach((e=>{this.pointerGeomItems[e.id]&&this.checkPointerIntersection(e)})),e.stopPropagation())}}const G=function(){return{escape:function(e){return e.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")},parseExtension:e,mimeType:function(t){const a=e(t).toLowerCase();return function(){const e="application/font-woff",t="image/jpeg";return{woff:e,woff2:e,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:t,jpeg:t,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}()[a]||""},dataAsUrl:function(e,t){return"data:"+t+";base64,"+e},isDataUrl:function(e){return-1!==e.search(/^(data:)/)},canvasToBlob:function(e){return e.toBlob?new Promise((function(t){e.toBlob(t)})):function(e){return new Promise((function(t){const a=window.atob(e.toDataURL().split(",")[1]),i=a.length,s=new Uint8Array(i);for(let e=0;e<i;e++)s[e]=a.charCodeAt(e);t(new Blob([s],{type:"image/png"}))}))}(e)},resolveUrl:function(e,t){const a=document.implementation.createHTMLDocument(),i=a.createElement("base");a.head.appendChild(i);const s=a.createElement("a");return a.body.appendChild(s),i.href=t,s.href=e,s.href},getAndEncode:function(e){const t=3e4;U.impl.options.cacheBust&&(e+=(/\?/.test(e)?"&":"?")+(new Date).getTime());return new Promise((function(a){const i=new XMLHttpRequest;let s;if(i.onreadystatechange=n,i.ontimeout=o,i.responseType="blob",i.timeout=t,i.open("GET",e,!0),i.send(),U.impl.options.imagePlaceholder){const e=U.impl.options.imagePlaceholder.split(/,/);e&&e[1]&&(s=e[1])}function n(){if(4!==i.readyState)return;if(200!==i.status)return void(s?a(s):r("cannot fetch resource: "+e+", status: "+i.status));const t=new FileReader;t.onloadend=function(){if("string"==typeof t.result){const e=t.result.split(/,/)[1];a(e)}else console.warn("encoder.result is not of string type")},t.readAsDataURL(i.response)}function o(){s?a(s):r("timeout of "+t+"ms occured while fetching resource: "+e)}function r(e){console.error(e),a("")}}))},uid:function(){let e=0;return function(){return"u"+t()+e++;function t(){return("0000"+(Math.random()*Math.pow(36,4)|0).toString(36)).slice(-4)}}}(),delay:function(e){return function(t){return new Promise((function(a){setTimeout((function(){a(t)}),e)}))}},asArray:function(e){const t=[],a=e.length;for(let i=0;i<a;i++)t.push(e[i]);return t},escapeXhtml:function(e){return e.replace(/#/g,"%23").replace(/\n/g,"%0A")},makeImage:function(e){return new Promise((function(t,a){const i=new Image;i.onload=function(){t(i)},i.onerror=a,i.src=e}))},width:function(e){const a=t(e,"border-left-width"),i=t(e,"border-right-width");return e.scrollWidth+a+i},height:function(e){const a=t(e,"border-top-width"),i=t(e,"border-bottom-width");return e.scrollHeight+a+i}};function e(e){const t=/\.([^\.\/]*?)$/g.exec(e);return t?t[1]:""}function t(e,t){const a=window.getComputedStyle(e).getPropertyValue(t);return parseFloat(a.replace("px",""))}}(),_=function(){const e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:function(e,s,n){return o()?Promise.resolve(e):Promise.resolve(e).then(a).then((function(t){let a=Promise.resolve(e);return t.forEach((function(e){a=a.then((function(t){return i(t,e,s,n)}))})),a}));function o(){return!t(e)}},shouldProcess:t,impl:{readUrls:a,inline:i}};function t(t){return-1!==t.search(e)}function a(t){const a=[];let i;for(;