@lumiscaphe/viewer 4.1.17 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/index.cjs +2 -2
- package/dist/lib/index.d.ts +19 -2
- package/dist/lib/index.js +193 -192
- package/package.json +5 -5
package/dist/lib/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
(function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(".ls-viewer-container{display:block;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none;width:100%;height:100%}.ls-viewer-container-image,.ls-viewer-container-video{cursor:default;pointer-events:none}.ls-viewer-container-vrcube{cursor:pointer;cursor:grab}.ls-viewer-container-vrcube-grabbing{cursor:move;cursor:grabbing}.ls-viewer-container-vrobject{cursor:move;cursor:grab}.ls-viewer-container-vrobject-grabbing{cursor:move;cursor:grabbing}.ls-viewer-container-loading{cursor:progress}.ls-viewer-canvas{position:absolute;opacity:0;transition:opacity .5s}.ls-viewer-video{position:absolute}")),document.head.appendChild(e)}}catch(r){console.error("vite-plugin-css-injected-by-js",r)}})();
|
|
2
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const k=require("debounce-promise"),h=require("twgl.js"),U=require("regression");function N(l){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(l){for(const e in l)if(e!=="default"){const i=Object.getOwnPropertyDescriptor(l,e);Object.defineProperty(t,e,i.get?i:{enumerable:!0,get:()=>l[e]})}}return t.default=l,Object.freeze(t)}const P=N(h);class y{constructor(t,e){this.width=t,this.height=e}get aspect(){return this.width/this.height}}class w{constructor(t,e,i,s){this.top=t,this.left=e,this.width=i,this.height=s}static contains(t,e){return e.x>=0&&e.x<t.width&&e.y>=0&&e.y<t.height}static fit(t,e,i){const s=t.aspect,r=e.aspect;let n=0,a=0;switch(i){case"contain":n=r<s?e.width:e.height*s,a=r<s?e.width/s:e.height;break;case"cover":default:n=r<s?e.height*s:e.width,a=r<s?e.height:e.width/s;break;case"fill":n=e.width,a=e.height;break}const o=(e.height-a)/2,d=(e.width-n)/2;return new w(o,d,n,a)}static project(t,e,i,s){const r=w.fit(t,e,i),n=r.width/t.width,a=r.height/t.height;return{x:Math.round(r.left+s.x*n),y:Math.round(r.top+s.y*a)}}static unproject(t,e,i,s){const r=w.fit(t,e,i),n=r.width/t.width,a=r.height/t.height;return{x:Math.round((s.x-r.left)/n),y:Math.round((s.y-r.top)/a)}}static getStandardAspectRatio(t,e){if(t===0||e===0)return 0;const i=t/e;if(t<e){const n=Math.abs(.75-i),a=Math.abs(9/16-i);return n<a?3/4:9/16}const s=Math.abs(4/3-i),r=Math.abs(16/9-i);return s<r?4/3:16/9}static getStandardResolution(t,e){if(t===0||e===0)return new y(0,0);const i=w.getStandardAspectRatio(t,e);if(t<e){const r=w.getStandardQuality(Math.max(e*i,t));return new y(Math.round(r),Math.round(r/i))}const s=w.getStandardQuality(Math.max(t/i,e));return new y(Math.round(s*i),Math.round(s))}static getStandardQuality(t){return t<=240?240:t<=360?360:t<=480?480:t<=720?720:1080}}class B{constructor(t){this.element=document.createElement("canvas"),this.element.classList.add("ls-viewer-canvas"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.context=this.element.getContext("2d"),this.backCanvas=document.createElement("canvas"),this.backContext=this.backCanvas.getContext("2d"),this.fit=t,this.pixelRatio=1}destroy(){this.requestAnimationId&&(cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0)}show(t){t?this.element.style.display="block":this.element.style.opacity="1"}hide(t){t?this.element.style.display="none":this.element.style.opacity="0"}get resolution(){return new y(this.element.width/this.pixelRatio,this.element.height/this.pixelRatio)}resize(t,e,i){this.element.width=t*i,this.element.height=e*i,this.element.style.width=`${t}px`,this.element.style.height=`${e}px`,this.backCanvas.width=t*i,this.backCanvas.height=e*i,this.pixelRatio=i}draw(t,e,i){if(!t)return;this.requestAnimationId&&(cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0);const s=w.fit(new y(t.width,t.height),new y(this.element.width,this.element.height),this.fit);e?(this.backContext.drawImage(this.element,0,0),this.context.globalAlpha=0,this.fadeLoop(t,i||0)):(this.context.globalAlpha=1,this.context.drawImage(t,s.left,s.top,s.width,s.height)),this.image=t}fadeLoop(t,e){if(this.context.globalAlpha>=1){cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0;return}const i=Math.min(this.context.globalAlpha+e,1),s=w.fit(new y(t.width,t.height),new y(this.element.width,this.element.height),this.fit);this.context.clearRect(0,0,this.element.width,this.element.height),this.context.globalAlpha=1,this.context.drawImage(this.backCanvas,0,0),this.context.globalAlpha=i,this.context.drawImage(t,s.left,s.top,s.width,s.height),this.requestAnimationId=requestAnimationFrame(()=>{this.fadeLoop(t,e)})}}class X{constructor(){this.element=document.createElement("canvas"),this.element.classList.add("ls-viewer-canvas"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.context=P.getContext(this.element,{preserveDrawingBuffer:!0}),this.context&&this.context.isContextLost()&&(this.context=void 0),P.setDefaults({textureColor:[1,1,1,1]})}show(){this.element.style.opacity="1"}hide(){this.element.style.opacity="0"}resize(t,e,i){this.element.width=t*i,this.element.height=e*i,this.element.style.width=`${t}px`,this.element.style.height=`${e}px`}}class g{static accelerate(t,e){const i=e||1.5;return Math.abs(t)**i*(t>0?1:-1)}static clamp(t,e,i){return Math.max(Math.min(t,i),e)}static degreesToRadians(t){return t*(Math.PI/180)}static radiansToDegrees(t){return t*(180/Math.PI)}static mod(t,e){return t-e*Math.floor(t/e)}static perspectiveWithFovX(t,e,i,s,r){const n=Math.tan(t/2),a=n/e;return this.perspectiveWithLeft(-n,n,-a,a,i,s,r)}static perspectiveWithFovY(t,e,i,s,r){const n=i*Math.tan(t/2),a=n*e;return this.perspectiveWithLeft(-a,a,-n,n,i,s,r)}static perspectiveWithLeft(t,e,i,s,r,n,a){a=a||new Float32Array(16);const o=e+t,d=e-t,u=s+i,p=s-i,c=n-r;return a[0]=2*r/d,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=2*r/p,a[6]=0,a[7]=0,a[8]=o/d,a[9]=u/p,a[10]=-n/c,a[11]=-1,a[12]=0,a[13]=0,a[14]=-n*r/c,a[15]=0,a}}const F=class F{static initCubeFace(t,e,i){let s=[0,0,0];const r=h.v3.subtract(e,t),n=h.v3.mulScalar([0,1,0],h.v3.length(r)),a=h.v3.mulScalar(h.v3.normalize(h.v3.cross(r,n)),h.v3.length(r)),o=h.v3.mulScalar(h.v3.normalize(h.v3.cross(n,a)),h.v3.length(r));switch(i){case"front":e=h.v3.add(t,o),s=h.v3.normalize(n);break;case"right":e=h.v3.add(t,a),s=h.v3.normalize(n);break;case"back":e=h.v3.subtract(t,o),s=h.v3.normalize(n);break;case"left":e=h.v3.subtract(t,a),s=h.v3.normalize(n);break;case"up":e=h.v3.add(t,n),s=h.v3.normalize(h.v3.mulScalar(o,-1));break;case"down":e=h.v3.subtract(t,n),s=h.v3.normalize(o);break}return new F(e,t,s)}constructor(t,e,i){this.target=h.v3.copy(t),this.eye=h.v3.copy(e),this.up=h.v3.copy(i)}get viewVector(){return h.v3.subtract(this.target,this.eye)}get rightVector(){return h.v3.normalize(h.v3.cross(this.viewVector,this.up))}get viewMatrix(){return h.m4.inverse(h.m4.lookAt(this.eye,this.target,this.up))}clone(){return new F(h.v3.copy(this.target),h.v3.copy(this.eye),h.v3.copy(this.up))}};F.default=new F([0,0,0],[2,2,2],[0,1,0]);let I=F;class Y{constructor(t){this.target=t.target;const e=h.v3.normalize(h.v3.subtract(t.eye,t.target)),i=h.v3.dot(e,[1,0,0]),s=h.v3.dot(e,[0,1,0]),r=h.v3.dot(e,[0,0,1]);this.longitude=Math.atan2(i,r),this.latitude=Math.atan2(s,Math.sqrt(i*i+r*r)),h.v3.dot(t.up,[0,1,0])<0&&(this.longitude=Math.PI+this.longitude,this.latitude=Math.PI-this.latitude),this.distance=h.v3.length(h.v3.subtract(t.target,t.eye))}get vector(){const t=Math.cos(this.latitude)*this.distance,e=Math.sin(this.latitude)*this.distance,i=Math.cos(this.longitude)*t,s=Math.sin(this.longitude)*t;return[i,e,s]}pointOfView(t){const e=h.m4.rotationY(this.longitude),i=h.m4.rotationX(-this.latitude),s=h.m4.rotationZ(0),r=h.m4.multiply(e,h.m4.multiply(i,s));let n=[0,0,-1];n=h.m4.transformPoint(r,n);let a=[0,1,0];a=h.m4.transformPoint(r,a);const o=h.v3.subtract(t,h.v3.mulScalar(n,this.distance));return new I(t,o,a)}}class W{constructor(){}async animation(t){return t.scene}async database(t){throw new Error("Unavailable")}async image(t){return t.scene}async video(t){return t.scene}async vrCube(t){return t.scene}async vrObject(t){return t.scene}}class V{constructor(t){this.xmlDoc=t}get id(){return this.xmlDoc.getElementsByTagName("Database")[0]?.getAttribute("id")}getCameraId(t,e){return e?this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`)?.getAttribute("id"):this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`)?.getAttribute("id")}getCameraById(t,e){let i;return t&&e?i=this.xmlDoc.querySelector(`RootCameraGroup Group[id="${e}"] Camera[id="${t}"]`):i=this.xmlDoc.querySelector(`RootCameraGroup Camera[id="${t}"]`),i?this.mapElementToCamera(i):null}getCameraByName(t,e){let i;return e&&t?i=this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`):i=this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`),i?this.mapElementToCamera(i):null}getCameraGroupId(t){return this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`)?.getAttribute("id")}getCameraGroupById(t){const e=this.xmlDoc.querySelector(`RootCameraGroup Group[id="${t}"]`);return e?this.mapElementToCameraGroup(e):null}getCameraGroupByName(t){const e=this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`);return e?this.mapElementToCameraGroup(e):null}mapElementToCamera(t){return{id:t.getAttribute("id"),name:t.getAttribute("name"),pointOfView:new I([parseFloat(t.querySelector("PointOfView Target").getAttribute("x")),parseFloat(t.querySelector("PointOfView Target").getAttribute("y")),parseFloat(t.querySelector("PointOfView Target").getAttribute("z"))],[parseFloat(t.querySelector("PointOfView Eye").getAttribute("x")),parseFloat(t.querySelector("PointOfView Eye").getAttribute("y")),parseFloat(t.querySelector("PointOfView Eye").getAttribute("z"))],[parseFloat(t.querySelector("PointOfView Up").getAttribute("x")),parseFloat(t.querySelector("PointOfView Up").getAttribute("y")),parseFloat(t.querySelector("PointOfView Up").getAttribute("z"))])}}mapElementToCameraGroup(t){return{id:t.getAttribute("id"),name:t.getAttribute("name"),cameras:[...t.querySelectorAll("Camera")].map(e=>this.mapElementToCamera(e))}}}const v=class v{constructor(t){this.server=t}static buildQuery(t){return Object.entries(t).filter(([e,i])=>i!=null).map(([e,i])=>`${e}=${i}`).join("&")}static sceneParameters(t){const e=t.scene,i=e.length>1?e.find(n=>n.accessory):null,s=e.length>1?e.find(n=>n.decor):null,r=e.find(n=>n!==i&&n!==s);return{databaseId:r.database,configuration:r?.configuration,animations:r?.animations?.join("/"),accessoryDatabaseId:i?.database,decorDatabaseId:s?.database,decorDeltaAltitude:s?.translation?.y}}static renderParameters(t){const{parameters:e,view:i}=t;return{background:i.background,width:e.width,height:e.height,softwareAntialiasing:e.antialiasing,superSampling:e.superSampling}}static encoderParameters(t){const{encoder:e}=t;return{imageFormat:e.format,imageQuality:e.quality}}static async fetch(t){return fetch(t).then(e=>e.text()).then(e=>{const s=e.replace(/&/g,"&").match(this.xmlRegex);return s?s.map(r=>r.replace(this.xmlRegex,"$1")):Promise.reject()})}async animation(t){const e={...v.sceneParameters(t),animation:t.view.animation,bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],frames:t.view.frames,loop:!!t.view.loop,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return v.fetch(`${this.server}/ImagesFromAnimation?${i}`)}async database(t){return fetch(`${this.server}/Database?databaseId=${t}`).then(e=>e.text()).then(e=>{const i=new DOMParser().parseFromString(e,"application/xml");return new V(i)})}async image(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return Promise.resolve(`${this.server}/ImageFromBookmark?${i}`)}async video(t){const e={...v.sceneParameters(t),animation:t.view.animation,bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],duration:t.view.duration,frames:t.view.frames,loop:!!t.view.loop,reverse:!!t.view.reverse,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return Promise.resolve(`${this.server}/ImagesFromAnimation?${i}`)}async vrCube(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],...v.renderParameters(t),...v.encoderParameters(t)};e.width=Math.max(e.width,e.height),e.height=Math.max(e.width,e.height);const i=v.buildQuery(e);return v.fetch(`${this.server}/CubeFromBookmark?${i}`)}async vrObject(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return v.fetch(`${this.server}/ImagesFromBookmarkSet?${i}`)}};v.xmlRegex=/directUrl="([^"]*)"/g;let S=v;class m{constructor(t){this.server=t}static scene(t){return t.scene.map(e=>{const{accessory:i,decor:s,...r}=e;return r})}static renderParameters(t){return{...t.parameters,superSampling:t.parameters.superSampling.toString()}}static encoder(t){switch(t.encoder.format){case"jpeg":return{jpeg:{quality:t.encoder.quality}};case"png":return{png:{compression:t.encoder.compression}};case"webp":return{webp:{quality:t.encoder.quality}}}return{jpeg:{quality:80}}}static async fetchFrame(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i.url)}static async fetchFrameArray(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i.map(s=>s.url))}static async fetchHotspots(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json())}static async fetchHotspotsArray(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json())}static async fetchPick(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i[0])}async database(t){return fetch(`${this.server}/Database?databaseId=${t}`).then(e=>e.text()).then(e=>{const i=new DOMParser().parseFromString(e,"application/xml");return new V(i)})}async image(t){const e={scene:m.scene(t),mode:{image:{camera:t.view.camera}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrame(`${this.server}/Snapshot`,e)}async vrCube(t){const e={scene:m.scene(t),mode:{vrCube:{camera:t.view.camera}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return e.renderParameters.width=Math.max(e.renderParameters.width,e.renderParameters.height),e.renderParameters.height=Math.max(e.renderParameters.width,e.renderParameters.height),m.fetchFrameArray(`${this.server}/Snapshot`,e)}async vrObject(t){let e;t.view.cameraGroup?e={images:{cameraGroup:t.view.cameraGroup}}:t.view.frames?e={vrObject:{camera:t.view.camera,frames:t.view.frames}}:e={vrObject:{camera:t.view.camera,panFrames:t.view.panFrames||1,panFrom:t.view.panFrom||0,panTo:t.view.panTo||0,panLoop:t.view.panLoop||!1,tiltFrames:t.view.tiltFrames||1,tiltFrom:t.view.tiltFrom||0,tiltTo:t.view.tiltTo||0,tiltLoop:t.view.tiltLoop||!1}};const i={scene:m.scene(t),mode:e,renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrameArray(`${this.server}/Snapshot`,i)}async animation(t){const e={scene:m.scene(t),mode:{animation:{id:t.view.animation,camera:t.view.camera,fps:t.view.fps}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrameArray(`${this.server}/Snapshot`,e)}async imageHotspots(t,e){const i={scene:m.scene(t),mode:{image:{camera:t.view.camera}},renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return await m.fetchHotspots(`${this.server}/Hotspot`,i)}async imagePick(t,e){const i={scene:m.scene(t),camera:t.view.camera,renderParameters:m.renderParameters(t),positions:[e]};return await m.fetchPick(`${this.server}/Pick`,i)}async vrCubeHotspots(t,e){const i={scene:m.scene(t),mode:{vrCube:{camera:t.view.camera}},renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return i.renderParameters.width=Math.max(i.renderParameters.width,i.renderParameters.height),i.renderParameters.height=Math.max(i.renderParameters.width,i.renderParameters.height),await m.fetchHotspotsArray(`${this.server}/Hotspot`,i)}async vrObjectHotspots(t,e){let i;t.view.cameraGroup?i={images:{cameraGroup:t.view.cameraGroup}}:t.view.frames?i={vrObject:{camera:t.view.camera,frames:t.view.frames}}:i={vrObject:{camera:t.view.camera,panFrames:t.view.panFrames||1,panFrom:t.view.panFrom||0,panTo:t.view.panTo||0,panLoop:t.view.panLoop||!1,tiltFrames:t.view.tiltFrames||1,tiltFrom:t.view.tiltFrom||0,tiltTo:t.view.tiltTo||0,tiltLoop:t.view.tiltLoop||!1}};const s={scene:m.scene(t),mode:i,renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return await m.fetchHotspotsArray(`${this.server}/Hotspot`,s)}hotspotsBody(t){return{positions:t.every(e=>typeof e!="string")?t:void 0,tags:t.every(e=>typeof e=="string")?t:void 0}}}class C{constructor(t,e,i){switch(e){case"static":this.webrender=new W;break;case"v1":this.webrender=new S(t),this.webrenderV2=new m(t);break;case"v2":this.webrender=new m(t),this.webrenderV2=new m(t);break;default:this.webrender=new S(t),this.webrenderV2=new m(t);break}this.delegate=i,this.loadingId=0,this.loaded=0,this.total=0,this.databases=[],this.onLoadStart=i&&i.onLoadStart?i.onLoadStart:()=>{},this.onLoadProgress=i&&i.onLoadProgress?i.onLoadProgress:()=>{},this.onLoadEnd=i&&i.onLoadEnd?i.onLoadEnd:()=>{}}get progress(){return this.total?this.loaded/this.total:0}async loadImageSnapshot(t){this.loadingId+=1,this.loaded=0,this.total=1,this.onLoadStart(this.progress);const{loadingId:e}=this;return this.webrender.image(t).then(i=>this.loadImage(i,e)).then(i=>(this.onLoadEnd(this.progress),i))}async loadVideoSnapshot(t,e){this.loadingId+=1,this.loaded=0,this.total=1,this.onLoadStart(this.progress);const{loadingId:i}=this;return this.webrender.video(e).then(s=>this.loadVideo(t,s,!!e.view.loop,i)).then(()=>(this.onLoadEnd(this.progress),t))}async loadVRCubeSnapshot(t){this.loadingId+=1,this.loaded=0,this.total=0,this.onLoadStart(this.progress);const{loadingId:e}=this;return this.webrender.vrCube(t).then(i=>{this.total=i.length;const s=i.map(r=>this.loadImage(r,e));return Promise.all(s)}).then(i=>(this.onLoadEnd(this.progress),i))}async loadVRObjectSnapshot(t,e){this.loadingId+=1,this.loaded=0,this.total=0,this.onLoadStart(this.progress);const{loadingId:i}=this;return t.view.animation?t.encoder?.format==="mp4"?this.webrender.video(t).then(s=>this.loadVideoFrames(s,t.view.frames,30,i)):this.webrender.animation(t).then(s=>this.loadImageFrames(s,t.view.loop,e,i)):this.webrender.vrObject(t).then(s=>this.loadImageFrames(s,t.view.loop,e,i))}async loadImage(t,e){const i=new Image;i.crossOrigin=location.protocol==="file:"&&!C.isValidHttpUrl(t)?null:"anonymous";const s=new Promise((r,n)=>{i.addEventListener("load",()=>{e===this.loadingId&&(this.loaded+=1,this.onLoadProgress(this.progress),r(i))},{once:!0}),i.addEventListener("error",a=>{e===this.loadingId&&n(`${a.type} : ${t}`)},{once:!0})});return i.src=t,s}loadImageFrames(t,e,i,s){this.total=t.length;const r=new Array(t.length),n=i||0;for(let a=0,o=t.length;a<o;a+=1){const d=Math.ceil(a/2)*(a%2===0?1:-1),u=e?g.mod(n+d,o):a;r[u]=this.loadImage(t[u],s)}return Promise.all(r).then(()=>this.onLoadEnd(this.progress)).catch(()=>{}),r}async loadVideo(t,e,i,s){t.loop=i;const r=new Promise((n,a)=>{t.addEventListener("canplaythrough",()=>{s===this.loadingId&&(this.loaded+=1,this.onLoadProgress(this.progress),n())},{once:!0}),t.addEventListener("error",o=>{s===this.loadingId&&a(`${o.type} : ${e}`)},{once:!0})});return t.src=e,t.load(),r}async loadVideoFrame(t,e,i,s,r){let n=0;return new Promise((a,o)=>{const d=()=>{if(r!==this.loadingId)return;if(n!==s){n+=1;return}t.removeEventListener("seeked",d);const u=document.createElement("canvas");u.width=t.videoWidth,u.height=t.videoHeight,u.getContext("2d").drawImage(t,0,0);const c=new Image;c.src=u.toDataURL(),a(c),this.loaded+=1,this.onLoadProgress(this.progress),s!==i-1&&(t.currentTime+=1/e)};t.addEventListener("seeked",d),t.addEventListener("error",u=>{r===this.loadingId&&o(u)},{once:!0})})}loadVideoFrames(t,e,i,s){this.total=e;const r=new Array(e),n=document.createElement("video");for(let a=0,o=e;a<o;a+=1)r[a]=this.loadVideoFrame(n,i,e,a,s);return n.addEventListener("canplaythrough",()=>{s===this.loadingId&&(n.currentTime=1/i/2)},{once:!0}),n.src=t,n.load(),Promise.all(r).then(()=>this.onLoadEnd(this.progress)).catch(()=>{}),r}async loadImageHotspots(t,e){return this.webrenderV2?await this.webrenderV2.imageHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadVRCubeHotspots(t,e){return this.webrenderV2?await this.webrenderV2.vrCubeHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadVRObjectHotspots(t,e){return this.webrenderV2?await this.webrenderV2.vrObjectHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadImagePick(t,e){return this.webrenderV2?await this.webrenderV2.imagePick(await this.convert(t),e):Promise.reject(new Error("Picking only available with api V2"))}async loadVRObjectPick(t,e,i,s){return this.webrenderV2?await this.webrenderV2.imagePick(await this.vrObjectFrameSnapshot(t,i,s),e):Promise.reject(new Error("Picking only available with api V2"))}async loadVRCubePick(t,e,i){return this.webrenderV2?await this.webrenderV2.imagePick(await this.vrCubeFrameSnapshot(t,i),e):Promise.reject(new Error("Picking only available with api V2"))}async convert(t){if(!this.webrenderV2||this.webrender instanceof m||!t.view.camera)return t;const e=t.scene.find(o=>!o.decor&&!o.accessory);if(!e)return t;let i=this.databases.find(o=>o.id===e.database);(!i||!i.xmlDoc)&&(i=await this.webrender.database(e.database),this.databases.push(i));const s=t.view.camera?.split("/"),r=s.length===2?s[0]:void 0,n=s.length===2?s[1]:s[0],a=i.getCameraId(n,r);if(a)return{...t,view:{...t.view,camera:a}};{const o=i.getCameraGroupId(n);return o?{...t,view:{...t.view,cameraGroup:o}}:t}}async vrObjectFrameSnapshot(t,e,i){if(!this.webrenderV2)return t;const s=t.scene.find(n=>!n.decor&&!n.accessory);if(!s)return t;let r=this.databases.find(n=>n.id===s.database);if(r||(r=await this.webrender.database(s.database),this.databases.push(r)),this.webrender instanceof S){if(!t.view.camera)return t;const n=r.getCameraGroupId(t.view.camera);if(!n)return t;const a=r.getCameraGroupById(n);if(!a)return t;const o=a.cameras[e];return o?{...t,view:{...t.view,camera:o.id}}:t}else if(this.webrender instanceof m)if(t.view.camera){const n=r.getCameraById(t.view.camera);if(!n)return t;const a=new Y(n.pointOfView),o=2*Math.PI/i;a.longitude+=e*o%(2*Math.PI);const d=a.pointOfView(n.pointOfView.target);return{...t,view:{...t.view,camera:{id:n.id,pov:{target:{x:d.target[0],y:d.target[1],z:d.target[2]},eye:{x:d.eye[0],y:d.eye[1],z:d.eye[2]},up:{x:d.up[0],y:d.up[1],z:d.up[2]}}}}}}else if(t.view.cameraGroup){const n=r.getCameraGroupById(t.view.cameraGroup);if(!n)return t;const a=n.cameras[e];return a?{...t,view:{...t.view,camera:a.id}}:t}else return t;else return t}async vrCubeFrameSnapshot(t,e){const i=t.scene.find(o=>!o.decor&&!o.accessory);if(!i)return t;let s=this.databases.find(o=>o.id===i.database);if(s||(s=await this.webrender.database(i.database),this.databases.push(s)),!t.view.camera)return t;let r;if(this.webrender instanceof S){const o=t.view.camera.split("/"),d=o.length===2?o[0]:void 0,u=o.length===2?o[1]:o[0];r=s.getCameraId(u,d)}else this.webrender instanceof m&&(r=t.view.camera);if(!r)return t;const n=s.getCameraById(r);if(!n)return t;const a=I.initCubeFace(n.pointOfView.eye,n.pointOfView.target,e);return{...t,view:{...t.view,camera:{id:n.id,pov:{target:{x:a.target[0],y:a.target[1],z:a.target[2]},eye:{x:a.eye[0],y:a.eye[1],z:a.eye[2]},up:{x:a.up[0],y:a.up[1],z:a.up[2]}},lens:{fov:90}}},parameters:{...t.parameters,width:Math.max(t.parameters.width,t.parameters.height),height:Math.max(t.parameters.width,t.parameters.height)}}}onLoadStart(t){this.delegate&&this.delegate.onLoadStart(t)}onLoadProgress(t){this.delegate&&this.delegate.onLoadProgress(t)}onLoadEnd(t){this.delegate&&this.delegate.onLoadEnd(t)}static isValidHttpUrl(t){let e;try{e=new URL(t)}catch{return!1}return e.protocol==="http:"||e.protocol==="https:"}}class J{constructor(){this.element=document.createElement("video"),this.element.classList.add("ls-viewer-video"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.element.setAttribute("muted",""),this.element.setAttribute("playsinline",""),this.element.setAttribute("preload","auto")}show(){this.element.style.opacity="1"}hide(){this.element.style.opacity="0"}resize(t,e,i,s){const r=w.fit(i,new y(t,e),s);this.element.style.top=`${r.top}px`,this.element.style.left=`${r.left}px`,this.element.style.width=`${r.width}px`,this.element.style.height=`${r.height}px`,(i.width!==this.element.width||i.height!==this.element.height)&&(this.element.width=i.width,this.element.height=i.height)}}class j{constructor(t,e,i){this.container=t,this.canvas=e,this.loader=i,this.hotspotList=[]}destroy(){}show(){this.canvas.show(!1),this.container.classList.add("ls-viewer-container-image")}hide(){this.canvas.hide(!1),this.container.classList.remove("ls-viewer-container-image")}async load(t,e,i,s){let r=Promise.resolve();const n=JSON.stringify(t);n===this.snapshotHash&&this.image?r=r.then(()=>this.canvas.draw(this.image,s,.05)):r=r.then(()=>this.loader.loadImageSnapshot(t).then(o=>{this.canvas.draw(o,s,.05),this.image=o}));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadImageHotspots(t,e).then(o=>{this.hotspotList=o})):this.hotspotList=[]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=new y(t.parameters.width,t.parameters.height),s=w.unproject(i,this.canvas.resolution,this.canvas.fit,e);return this.loader.loadImagePick(t,s)}hotspots(t){return this.hotspotList.map(e=>({...e,position2D:w.project(t,this.canvas.resolution,this.canvas.fit,e.position2D)})).map(e=>({...e,visibility:w.contains(this.canvas.resolution,e.position2D)?e.visibility:"OutOfFrustum"}))}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}onMouseDown(t){}onMouseMove(t){}onMouseUp(t){}onMouseEnter(t){}onTouchStart(t){}onTouchMove(t){}onTouchEnd(t){}onDeviceOrientation(t){}}class E{constructor(t,e){this.x=t,this.y=e}clone(){return new E(this.x,this.y)}}class f{static pointFromMouseEvent(t){return new E(t.screenX,t.screenY)}static pointFromTouchEvent(t){const e=t.targetTouches[0]||t.changedTouches[0];return new E(e.screenX,e.screenY)}}class D{constructor(...t){t.length===3?({0:this.u,1:this.v,2:this.o}=t,this.w=h.v3.cross(this.u,this.v)):t.length===4?{0:this.u,1:this.v,2:this.w,3:this.o}=t:(this.u=[1,0,0],this.v=[0,1,0],this.w=[0,0,1],this.o=[0,0,0])}get localToGlobalMatrix(){const t=[this.u[0],this.u[1],this.u[2],0],e=[this.v[0],this.v[1],this.v[2],0],i=[this.w[0],this.w[1],this.w[2],0],s=[this.o[0],this.o[1],this.o[2],1];return[...t,...e,...i,...s]}get globalToLocalMatrix(){return h.m4.inverse(this.localToGlobalMatrix)}}class Z{constructor(t,e,i){this.x=t,this.y=e,this.time=i}}class q{constructor(t){this.points=[],this.onMotion=t,this.lastPoint=new E(0,0),this.velocity=new E(0,0),this.loop=this.loop.bind(this)}destroy(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}track(t){const e=Date.now();this.points=this.points.filter(i=>e-i.time<=100),this.points.push(new Z(t.x,t.y,e)),this.lastPoint=t}start(){if(this.points.length===0)return;const t=this.points[0],e=this.points[this.points.length-1],i=e.x-t.x,s=e.y-t.y,r=e.time-t.time;this.velocity=new E(r===0?0:i/(r/15),r===0?0:s/(r/15)),this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0),this.animationFrameId=requestAnimationFrame(this.loop)}stop(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0),this.points=[]}loop(){if(Math.abs(this.velocity.x)<1&&Math.abs(this.velocity.y)<1){this.animationFrameId=void 0,this.points=[];return}this.lastPoint.x+=this.velocity.x,this.lastPoint.y+=this.velocity.y,this.velocity.x*=.9,this.velocity.y*=.9,this.onMotion(this.lastPoint.clone()),this.animationFrameId=requestAnimationFrame(this.loop)}}class Q{constructor(t,e,i){this.isStarted=!1,this.pov=t,this.fov=g.degreesToRadians(e),this.orientationMatrix=h.m4.identity(),this.inertia=new q(this.motion.bind(this)),this.onMotion=i,this.initPov=this.pov,this.initFov=this.fov,this.initOrientation=g.degreesToRadians(window.orientation)||0,this.startPov=new I([0,0,1],[0,0,0],[0,1,0]),this.startSize={width:0,height:0},this.previousPoint=new E(0,0)}destroy(){this.inertia.destroy()}get orientedPov(){const t=h.v3.normalize(h.v3.cross(this.pov.up,this.pov.target)),e=new D(t,[0,1,0],this.pov.eye),i=h.m4.identity();h.m4.multiply(i,e.localToGlobalMatrix,i),h.m4.multiply(i,this.orientationMatrix,i),h.m4.multiply(i,e.globalToLocalMatrix,i);const s=h.m4.transformDirection(i,this.pov.target),r=this.pov.eye,n=h.m4.transformDirection(i,this.pov.up);return new I(s,r,n)}reset(){this.pov=this.initPov.clone(),this.fov=this.initFov}start(t,e){this.isStarted=!0,this.startPov=this.pov,this.startSize=e,this.previousPoint=t,this.inertia.stop()}motion(t){this.isStarted&&this.inertia.track(t);const e={x:t.x-this.previousPoint.x,y:t.y-this.previousPoint.y},i=g.accelerate(e.x,1.3)/this.startSize.width*.2*Math.PI*1.5,s=g.accelerate(e.y,1.3)/this.startSize.height*.2*Math.PI,r=h.m4.multiply(h.m4.rotationY(i),h.m4.rotationX(-s)),n=h.v3.normalize(h.v3.cross(this.pov.up,this.pov.target)),a=new D(n,[0,1,0],this.pov.eye),o=h.m4.identity();h.m4.multiply(o,a.localToGlobalMatrix,o),h.m4.multiply(o,r,o),h.m4.multiply(o,a.globalToLocalMatrix,o);const d=h.m4.transformPoint(o,this.pov.target),u=h.m4.transformDirection(o,this.pov.up);h.v3.cross(u,[0,0,1])[0]>=0&&(this.pov.target=d,this.pov.up=u),this.previousPoint=t,this.onMotion()}end(t,e){this.isStarted=!1,e&&(this.inertia.track(t),this.inertia.start())}orientation(t,e,i){const s=g.degreesToRadians(window.orientation)||0,r=g.degreesToRadians(t),n=g.degreesToRadians(-e),a=g.degreesToRadians(-i),o=h.m4.rotationX(g.degreesToRadians(90));h.m4.rotateZ(o,this.initOrientation,o),h.m4.rotateZ(o,r,o),h.m4.rotateX(o,n,o),h.m4.rotateY(o,a,o),h.m4.rotateZ(o,-s,o),this.orientationMatrix=o,this.onMotion()}}var _=`precision mediump float;
|
|
2
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const k=require("debounce-promise"),h=require("twgl.js"),U=require("regression");function N(l){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(l){for(const e in l)if(e!=="default"){const i=Object.getOwnPropertyDescriptor(l,e);Object.defineProperty(t,e,i.get?i:{enumerable:!0,get:()=>l[e]})}}return t.default=l,Object.freeze(t)}const P=N(h);class y{constructor(t,e){this.width=t,this.height=e}get aspect(){return this.width/this.height}}class w{constructor(t,e,i,s){this.top=t,this.left=e,this.width=i,this.height=s}static contains(t,e){return e.x>=0&&e.x<t.width&&e.y>=0&&e.y<t.height}static fit(t,e,i){const s=t.aspect,r=e.aspect;let n=0,a=0;switch(i){case"contain":n=r<s?e.width:e.height*s,a=r<s?e.width/s:e.height;break;case"cover":default:n=r<s?e.height*s:e.width,a=r<s?e.height:e.width/s;break;case"fill":n=e.width,a=e.height;break}const o=(e.height-a)/2,u=(e.width-n)/2;return new w(o,u,n,a)}static project(t,e,i,s){const r=w.fit(t,e,i),n=r.width/t.width,a=r.height/t.height;return{x:Math.round(r.left+s.x*n),y:Math.round(r.top+s.y*a)}}static unproject(t,e,i,s){const r=w.fit(t,e,i),n=r.width/t.width,a=r.height/t.height;return{x:Math.round((s.x-r.left)/n),y:Math.round((s.y-r.top)/a)}}static getStandardAspectRatio(t,e){if(t===0||e===0)return 0;const i=t/e;if(t<e){const n=Math.abs(.75-i),a=Math.abs(9/16-i);return n<a?3/4:9/16}const s=Math.abs(4/3-i),r=Math.abs(16/9-i);return s<r?4/3:16/9}static getStandardResolution(t,e){if(t===0||e===0)return new y(0,0);const i=w.getStandardAspectRatio(t,e);if(t<e){const r=w.getStandardQuality(Math.max(e*i,t));return new y(Math.round(r),Math.round(r/i))}const s=w.getStandardQuality(Math.max(t/i,e));return new y(Math.round(s*i),Math.round(s))}static getStandardQuality(t){return t<=720?720:1080}}class B{constructor(t){this.element=document.createElement("canvas"),this.element.classList.add("ls-viewer-canvas"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.context=this.element.getContext("2d"),this.backCanvas=document.createElement("canvas"),this.backContext=this.backCanvas.getContext("2d"),this.fit=t,this.pixelRatio=1}destroy(){this.requestAnimationId&&(cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0)}show(t){t?this.element.style.display="block":this.element.style.opacity="1"}hide(t){t?this.element.style.display="none":this.element.style.opacity="0"}get resolution(){return new y(this.element.width/this.pixelRatio,this.element.height/this.pixelRatio)}resize(t,e,i){this.element.width=t*i,this.element.height=e*i,this.element.style.width=`${t}px`,this.element.style.height=`${e}px`,this.backCanvas.width=t*i,this.backCanvas.height=e*i,this.pixelRatio=i}draw(t,e,i){if(!t)return;this.requestAnimationId&&(cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0);const s=w.fit(new y(t.width,t.height),new y(this.element.width,this.element.height),this.fit);e?(this.backContext.drawImage(this.element,0,0),this.context.globalAlpha=0,this.fadeLoop(t,i||0)):(this.context.globalAlpha=1,this.context.drawImage(t,s.left,s.top,s.width,s.height)),this.image=t}fadeLoop(t,e){if(this.context.globalAlpha>=1){cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0;return}const i=Math.min(this.context.globalAlpha+e,1),s=w.fit(new y(t.width,t.height),new y(this.element.width,this.element.height),this.fit);this.context.clearRect(0,0,this.element.width,this.element.height),this.context.globalAlpha=1,this.context.drawImage(this.backCanvas,0,0),this.context.globalAlpha=i,this.context.drawImage(t,s.left,s.top,s.width,s.height),this.requestAnimationId=requestAnimationFrame(()=>{this.fadeLoop(t,e)})}}class X{constructor(){this.element=document.createElement("canvas"),this.element.classList.add("ls-viewer-canvas"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.context=P.getContext(this.element,{preserveDrawingBuffer:!0}),this.context&&this.context.isContextLost()&&(this.context=void 0),P.setDefaults({textureColor:[1,1,1,1]})}show(){this.element.style.opacity="1"}hide(){this.element.style.opacity="0"}resize(t,e,i){this.element.width=t*i,this.element.height=e*i,this.element.style.width=`${t}px`,this.element.style.height=`${e}px`}}class g{static accelerate(t,e){const i=e||1.5;return Math.abs(t)**i*(t>0?1:-1)}static clamp(t,e,i){return Math.max(Math.min(t,i),e)}static degreesToRadians(t){return t*(Math.PI/180)}static radiansToDegrees(t){return t*(180/Math.PI)}static mod(t,e){return t-e*Math.floor(t/e)}static perspectiveWithFovX(t,e,i,s,r){const n=Math.tan(t/2),a=n/e;return this.perspectiveWithLeft(-n,n,-a,a,i,s,r)}static perspectiveWithFovY(t,e,i,s,r){const n=i*Math.tan(t/2),a=n*e;return this.perspectiveWithLeft(-a,a,-n,n,i,s,r)}static perspectiveWithLeft(t,e,i,s,r,n,a){a=a||new Float32Array(16);const o=e+t,u=e-t,d=s+i,p=s-i,c=n-r;return a[0]=2*r/u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=2*r/p,a[6]=0,a[7]=0,a[8]=o/u,a[9]=d/p,a[10]=-n/c,a[11]=-1,a[12]=0,a[13]=0,a[14]=-n*r/c,a[15]=0,a}}const F=class F{static initCubeFace(t,e,i){let s=[0,0,0];const r=h.v3.subtract(e,t),n=h.v3.mulScalar([0,1,0],h.v3.length(r)),a=h.v3.mulScalar(h.v3.normalize(h.v3.cross(r,n)),h.v3.length(r)),o=h.v3.mulScalar(h.v3.normalize(h.v3.cross(n,a)),h.v3.length(r));switch(i){case"front":e=h.v3.add(t,o),s=h.v3.normalize(n);break;case"right":e=h.v3.add(t,a),s=h.v3.normalize(n);break;case"back":e=h.v3.subtract(t,o),s=h.v3.normalize(n);break;case"left":e=h.v3.subtract(t,a),s=h.v3.normalize(n);break;case"up":e=h.v3.add(t,n),s=h.v3.normalize(h.v3.mulScalar(o,-1));break;case"down":e=h.v3.subtract(t,n),s=h.v3.normalize(o);break}return new F(e,t,s)}constructor(t,e,i){this.target=h.v3.copy(t),this.eye=h.v3.copy(e),this.up=h.v3.copy(i)}get viewVector(){return h.v3.subtract(this.target,this.eye)}get rightVector(){return h.v3.normalize(h.v3.cross(this.viewVector,this.up))}get viewMatrix(){return h.m4.inverse(h.m4.lookAt(this.eye,this.target,this.up))}clone(){return new F(h.v3.copy(this.target),h.v3.copy(this.eye),h.v3.copy(this.up))}};F.default=new F([0,0,0],[2,2,2],[0,1,0]);let I=F;class Y{constructor(t){this.target=t.target;const e=h.v3.normalize(h.v3.subtract(t.eye,t.target)),i=h.v3.dot(e,[1,0,0]),s=h.v3.dot(e,[0,1,0]),r=h.v3.dot(e,[0,0,1]);this.longitude=Math.atan2(i,r),this.latitude=Math.atan2(s,Math.sqrt(i*i+r*r)),h.v3.dot(t.up,[0,1,0])<0&&(this.longitude=Math.PI+this.longitude,this.latitude=Math.PI-this.latitude),this.distance=h.v3.length(h.v3.subtract(t.target,t.eye))}get vector(){const t=Math.cos(this.latitude)*this.distance,e=Math.sin(this.latitude)*this.distance,i=Math.cos(this.longitude)*t,s=Math.sin(this.longitude)*t;return[i,e,s]}pointOfView(t){const e=h.m4.rotationY(this.longitude),i=h.m4.rotationX(-this.latitude),s=h.m4.rotationZ(0),r=h.m4.multiply(e,h.m4.multiply(i,s));let n=[0,0,-1];n=h.m4.transformPoint(r,n);let a=[0,1,0];a=h.m4.transformPoint(r,a);const o=h.v3.subtract(t,h.v3.mulScalar(n,this.distance));return new I(t,o,a)}}class W{constructor(){}async animation(t){return t.scene}async database(t){throw new Error("Unavailable")}async image(t){return t.scene}async video(t){return t.scene}async vrCube(t){return t.scene}async vrObject(t){return t.scene}}class V{constructor(t){this.xmlDoc=t}get id(){return this.xmlDoc.getElementsByTagName("Database")[0]?.getAttribute("id")}getCameraId(t,e){return e?this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`)?.getAttribute("id"):this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`)?.getAttribute("id")}getCameraById(t,e){let i;return t&&e?i=this.xmlDoc.querySelector(`RootCameraGroup Group[id="${e}"] Camera[id="${t}"]`):i=this.xmlDoc.querySelector(`RootCameraGroup Camera[id="${t}"]`),i?this.mapElementToCamera(i):null}getCameraByName(t,e){let i;return e&&t?i=this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`):i=this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`),i?this.mapElementToCamera(i):null}getCameraGroupId(t){return this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`)?.getAttribute("id")}getCameraGroupById(t){const e=this.xmlDoc.querySelector(`RootCameraGroup Group[id="${t}"]`);return e?this.mapElementToCameraGroup(e):null}getCameraGroupByName(t){const e=this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`);return e?this.mapElementToCameraGroup(e):null}mapElementToCamera(t){return{id:t.getAttribute("id"),name:t.getAttribute("name"),pointOfView:new I([parseFloat(t.querySelector("PointOfView Target").getAttribute("x")),parseFloat(t.querySelector("PointOfView Target").getAttribute("y")),parseFloat(t.querySelector("PointOfView Target").getAttribute("z"))],[parseFloat(t.querySelector("PointOfView Eye").getAttribute("x")),parseFloat(t.querySelector("PointOfView Eye").getAttribute("y")),parseFloat(t.querySelector("PointOfView Eye").getAttribute("z"))],[parseFloat(t.querySelector("PointOfView Up").getAttribute("x")),parseFloat(t.querySelector("PointOfView Up").getAttribute("y")),parseFloat(t.querySelector("PointOfView Up").getAttribute("z"))])}}mapElementToCameraGroup(t){return{id:t.getAttribute("id"),name:t.getAttribute("name"),cameras:[...t.querySelectorAll("Camera")].map(e=>this.mapElementToCamera(e))}}}const v=class v{constructor(t){this.server=t}static buildQuery(t){return Object.entries(t).filter(([e,i])=>i!=null).map(([e,i])=>`${e}=${i}`).join("&")}static sceneParameters(t){const e=t.scene,i=e.length>1?e.find(n=>n.accessory):null,s=e.length>1?e.find(n=>n.decor):null,r=e.find(n=>n!==i&&n!==s);return{databaseId:r.database,configuration:r?.configuration,animations:r?.animations?.join("/"),accessoryDatabaseId:i?.database,decorDatabaseId:s?.database,decorDeltaAltitude:s?.translation?.y}}static renderParameters(t){const{parameters:e,view:i}=t;return{background:i.background,width:e.width,height:e.height,softwareAntialiasing:e.antialiasing,superSampling:e.superSampling}}static encoderParameters(t){const{encoder:e}=t;return{imageFormat:e.format,imageQuality:e.quality}}static async fetch(t){return fetch(t).then(e=>e.text()).then(e=>{const s=e.replace(/&/g,"&").match(this.xmlRegex);return s?s.map(r=>r.replace(this.xmlRegex,"$1")):Promise.reject()})}async animation(t){const e={...v.sceneParameters(t),animation:t.view.animation,bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],frames:t.view.frames,loop:!!t.view.loop,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return v.fetch(`${this.server}/ImagesFromAnimation?${i}`)}async database(t){return fetch(`${this.server}/Database?databaseId=${t}`).then(e=>e.text()).then(e=>{const i=new DOMParser().parseFromString(e,"application/xml");return new V(i)})}async image(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return Promise.resolve(`${this.server}/ImageFromBookmark?${i}`)}async video(t){const e={...v.sceneParameters(t),animation:t.view.animation,bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],duration:t.view.duration,frames:t.view.frames,loop:!!t.view.loop,reverse:!!t.view.reverse,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return Promise.resolve(`${this.server}/ImagesFromAnimation?${i}`)}async vrCube(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],...v.renderParameters(t),...v.encoderParameters(t)};e.width=Math.max(e.width,e.height),e.height=Math.max(e.width,e.height);const i=v.buildQuery(e);return v.fetch(`${this.server}/CubeFromBookmark?${i}`)}async vrObject(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return v.fetch(`${this.server}/ImagesFromBookmarkSet?${i}`)}};v.xmlRegex=/directUrl="([^"]*)"/g;let S=v;class m{constructor(t){this.server=t}static scene(t){return t.scene.map(e=>{const{accessory:i,decor:s,...r}=e;return r})}static renderParameters(t){return{...t.parameters,superSampling:t.parameters.superSampling.toString()}}static encoder(t){switch(t.encoder.format){case"jpeg":return{jpeg:{quality:t.encoder.quality}};case"png":return{png:{compression:t.encoder.compression}};case"webp":return{webp:{quality:t.encoder.quality}}}return{jpeg:{quality:80}}}static async fetchFrame(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i.url)}static async fetchFrameArray(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i.map(s=>s.url))}static async fetchHotspots(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json())}static async fetchHotspotsArray(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json())}static async fetchPick(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i[0])}async database(t){return fetch(`${this.server}/Database?databaseId=${t}`).then(e=>e.text()).then(e=>{const i=new DOMParser().parseFromString(e,"application/xml");return new V(i)})}async image(t){const e={scene:m.scene(t),mode:{image:{camera:t.view.camera}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrame(`${this.server}/Snapshot`,e)}async vrCube(t){const e={scene:m.scene(t),mode:{vrCube:{camera:t.view.camera}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return e.renderParameters.width=Math.max(e.renderParameters.width,e.renderParameters.height),e.renderParameters.height=Math.max(e.renderParameters.width,e.renderParameters.height),m.fetchFrameArray(`${this.server}/Snapshot`,e)}async vrObject(t){let e;t.view.cameraGroup?e={images:{cameraGroup:t.view.cameraGroup}}:t.view.frames?e={vrObject:{camera:t.view.camera,frames:t.view.frames}}:e={vrObject:{camera:t.view.camera,panFrames:t.view.panFrames||1,panFrom:t.view.panFrom||0,panTo:t.view.panTo||0,panLoop:t.view.panLoop||!1,tiltFrames:t.view.tiltFrames||1,tiltFrom:t.view.tiltFrom||0,tiltTo:t.view.tiltTo||0,tiltLoop:t.view.tiltLoop||!1}};const i={scene:m.scene(t),mode:e,renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrameArray(`${this.server}/Snapshot`,i)}async animation(t){const e={scene:m.scene(t),mode:{animation:{id:t.view.animation,camera:t.view.camera,fps:t.view.fps}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrameArray(`${this.server}/Snapshot`,e)}async imageHotspots(t,e){const i={scene:m.scene(t),mode:{image:{camera:t.view.camera}},renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return await m.fetchHotspots(`${this.server}/Hotspot`,i)}async imagePick(t,e){const i={scene:m.scene(t),camera:t.view.camera,renderParameters:m.renderParameters(t),positions:[e]};return await m.fetchPick(`${this.server}/Pick`,i)}async vrCubeHotspots(t,e){const i={scene:m.scene(t),mode:{vrCube:{camera:t.view.camera}},renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return i.renderParameters.width=Math.max(i.renderParameters.width,i.renderParameters.height),i.renderParameters.height=Math.max(i.renderParameters.width,i.renderParameters.height),await m.fetchHotspotsArray(`${this.server}/Hotspot`,i)}async vrObjectHotspots(t,e){let i;t.view.cameraGroup?i={images:{cameraGroup:t.view.cameraGroup}}:t.view.frames?i={vrObject:{camera:t.view.camera,frames:t.view.frames}}:i={vrObject:{camera:t.view.camera,panFrames:t.view.panFrames||1,panFrom:t.view.panFrom||0,panTo:t.view.panTo||0,panLoop:t.view.panLoop||!1,tiltFrames:t.view.tiltFrames||1,tiltFrom:t.view.tiltFrom||0,tiltTo:t.view.tiltTo||0,tiltLoop:t.view.tiltLoop||!1}};const s={scene:m.scene(t),mode:i,renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return await m.fetchHotspotsArray(`${this.server}/Hotspot`,s)}hotspotsBody(t){return{positions:t.every(e=>typeof e!="string")?t:void 0,tags:t.every(e=>typeof e=="string")?t:void 0}}}class C{constructor(t,e,i){switch(e){case"static":this.webrender=new W;break;case"v1":this.webrender=new S(t),this.webrenderV2=new m(t);break;case"v2":this.webrender=new m(t),this.webrenderV2=new m(t);break;default:this.webrender=new S(t),this.webrenderV2=new m(t);break}this.delegate=i,this.loadingId=0,this.loaded=0,this.total=0,this.databases=[],this.onLoadStart=i&&i.onLoadStart?i.onLoadStart:()=>{},this.onLoadProgress=i&&i.onLoadProgress?i.onLoadProgress:()=>{},this.onLoadEnd=i&&i.onLoadEnd?i.onLoadEnd:()=>{}}get progress(){return this.total?this.loaded/this.total:0}async loadImageSnapshot(t){this.loadingId+=1,this.loaded=0,this.total=1,this.onLoadStart(this.progress);const{loadingId:e}=this;return this.webrender.image(t).then(i=>this.loadImage(i,e)).then(i=>(this.onLoadEnd(this.progress),i))}async loadVideoSnapshot(t,e){this.loadingId+=1,this.loaded=0,this.total=1,this.onLoadStart(this.progress);const{loadingId:i}=this;return this.webrender.video(e).then(s=>this.loadVideo(t,s,!!e.view.loop,i)).then(()=>(this.onLoadEnd(this.progress),t))}async loadVRCubeSnapshot(t){this.loadingId+=1,this.loaded=0,this.total=0,this.onLoadStart(this.progress);const{loadingId:e}=this;return this.webrender.vrCube(t).then(i=>{this.total=i.length;const s=i.map(r=>this.loadImage(r,e));return Promise.all(s)}).then(i=>(this.onLoadEnd(this.progress),i))}async loadVRObjectSnapshot(t,e){this.loadingId+=1,this.loaded=0,this.total=0,this.onLoadStart(this.progress);const{loadingId:i}=this;return t.view.animation?t.encoder?.format==="mp4"?this.webrender.video(t).then(s=>this.loadVideoFrames(s,t.view.frames,30,i)):this.webrender.animation(t).then(s=>this.loadImageFrames(s,t.view.loop,e,i)):this.webrender.vrObject(t).then(s=>this.loadImageFrames(s,t.view.loop,e,i))}async loadImage(t,e){const i=new Image;i.crossOrigin=location.protocol==="file:"&&!C.isValidHttpUrl(t)?null:"anonymous";const s=new Promise((r,n)=>{i.addEventListener("load",()=>{e===this.loadingId&&(this.loaded+=1,this.onLoadProgress(this.progress),r(i))},{once:!0}),i.addEventListener("error",a=>{e===this.loadingId&&n(`${a.type} : ${t}`)},{once:!0})});return i.src=t,s}loadImageFrames(t,e,i,s){this.total=t.length;const r=new Array(t.length),n=i||0;for(let a=0,o=t.length;a<o;a+=1){const u=Math.ceil(a/2)*(a%2===0?1:-1),d=e?g.mod(n+u,o):a;r[d]=this.loadImage(t[d],s)}return Promise.all(r).then(()=>this.onLoadEnd(this.progress)).catch(()=>{}),r}async loadVideo(t,e,i,s){t.loop=i;const r=new Promise((n,a)=>{t.addEventListener("canplaythrough",()=>{s===this.loadingId&&(this.loaded+=1,this.onLoadProgress(this.progress),n())},{once:!0}),t.addEventListener("error",o=>{s===this.loadingId&&a(`${o.type} : ${e}`)},{once:!0})});return t.src=e,t.load(),r}async loadVideoFrame(t,e,i,s,r){let n=0;return new Promise((a,o)=>{const u=()=>{if(r!==this.loadingId)return;if(n!==s){n+=1;return}t.removeEventListener("seeked",u);const d=document.createElement("canvas");d.width=t.videoWidth,d.height=t.videoHeight,d.getContext("2d").drawImage(t,0,0);const c=new Image;c.src=d.toDataURL(),a(c),this.loaded+=1,this.onLoadProgress(this.progress),s!==i-1&&(t.currentTime+=1/e)};t.addEventListener("seeked",u),t.addEventListener("error",d=>{r===this.loadingId&&o(d)},{once:!0})})}loadVideoFrames(t,e,i,s){this.total=e;const r=new Array(e),n=document.createElement("video");for(let a=0,o=e;a<o;a+=1)r[a]=this.loadVideoFrame(n,i,e,a,s);return n.addEventListener("canplaythrough",()=>{s===this.loadingId&&(n.currentTime=1/i/2)},{once:!0}),n.src=t,n.load(),Promise.all(r).then(()=>this.onLoadEnd(this.progress)).catch(()=>{}),r}async loadImageHotspots(t,e){return this.webrenderV2?await this.webrenderV2.imageHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadVRCubeHotspots(t,e){return this.webrenderV2?await this.webrenderV2.vrCubeHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadVRObjectHotspots(t,e){return this.webrenderV2?await this.webrenderV2.vrObjectHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadImagePick(t,e){return this.webrenderV2?await this.webrenderV2.imagePick(await this.convert(t),e):Promise.reject(new Error("Picking only available with api V2"))}async loadVRObjectPick(t,e,i,s){return this.webrenderV2?await this.webrenderV2.imagePick(await this.vrObjectFrameSnapshot(t,i,s),e):Promise.reject(new Error("Picking only available with api V2"))}async loadVRCubePick(t,e,i){return this.webrenderV2?await this.webrenderV2.imagePick(await this.vrCubeFrameSnapshot(t,i),e):Promise.reject(new Error("Picking only available with api V2"))}async convert(t){if(!this.webrenderV2||this.webrender instanceof m||!t.view.camera)return t;const e=t.scene.find(o=>!o.decor&&!o.accessory);if(!e)return t;let i=this.databases.find(o=>o.id===e.database);(!i||!i.xmlDoc)&&(i=await this.webrender.database(e.database),this.databases.push(i));const s=t.view.camera.split("/"),r=s.length===2?s[0]:void 0,n=s.length===2?s[1]:s[0],a=i.getCameraId(n,r);if(a)return{...t,view:{...t.view,camera:a}};{const o=i.getCameraGroupId(n);return o?{...t,view:{...t.view,cameraGroup:o}}:t}}async vrObjectFrameSnapshot(t,e,i){if(!this.webrenderV2)return t;const s=t.scene.find(n=>!n.decor&&!n.accessory);if(!s)return t;let r=this.databases.find(n=>n.id===s.database);if(r||(r=await this.webrender.database(s.database),this.databases.push(r)),this.webrender instanceof S){if(!t.view.camera)return t;const n=r.getCameraGroupId(t.view.camera);if(!n)return t;const a=r.getCameraGroupById(n);if(!a)return t;const o=a.cameras[e];return o?{...t,view:{...t.view,camera:o.id}}:t}else if(this.webrender instanceof m){const n=typeof t.view.camera=="string"?t.view.camera:t.view.camera?.id;if(n){const a=r.getCameraById(n);if(!a)return t;const o=new Y(a.pointOfView),u=2*Math.PI/i;o.longitude+=e*u%(2*Math.PI);const d=o.pointOfView(a.pointOfView.target);return{...t,view:{...t.view,camera:{id:a.id,pov:{target:{x:d.target[0],y:d.target[1],z:d.target[2]},eye:{x:d.eye[0],y:d.eye[1],z:d.eye[2]},up:{x:d.up[0],y:d.up[1],z:d.up[2]}}}}}}else if(t.view.cameraGroup){const a=r.getCameraGroupById(t.view.cameraGroup);if(!a)return t;const o=a.cameras[e];return o?{...t,view:{...t.view,camera:o.id}}:t}else return t}else return t}async vrCubeFrameSnapshot(t,e){const i=t.scene.find(o=>!o.decor&&!o.accessory);if(!i)return t;let s=this.databases.find(o=>o.id===i.database);if(s||(s=await this.webrender.database(i.database),this.databases.push(s)),!t.view.camera)return t;let r;if(this.webrender instanceof S){const o=t.view.camera.split("/"),u=o.length===2?o[0]:void 0,d=o.length===2?o[1]:o[0];r=s.getCameraId(d,u)}else this.webrender instanceof m&&(r=typeof t.view.camera=="string"?t.view.camera:t.view.camera.id);if(!r)return t;const n=s.getCameraById(r);if(!n)return t;const a=I.initCubeFace(n.pointOfView.eye,n.pointOfView.target,e);return{...t,view:{...t.view,camera:{id:n.id,pov:{target:{x:a.target[0],y:a.target[1],z:a.target[2]},eye:{x:a.eye[0],y:a.eye[1],z:a.eye[2]},up:{x:a.up[0],y:a.up[1],z:a.up[2]}},lens:{fov:90}}},parameters:{...t.parameters,width:Math.max(t.parameters.width,t.parameters.height),height:Math.max(t.parameters.width,t.parameters.height)}}}onLoadStart(t){this.delegate&&this.delegate.onLoadStart(t)}onLoadProgress(t){this.delegate&&this.delegate.onLoadProgress(t)}onLoadEnd(t){this.delegate&&this.delegate.onLoadEnd(t)}static isValidHttpUrl(t){let e;try{e=new URL(t)}catch{return!1}return e.protocol==="http:"||e.protocol==="https:"}}class J{constructor(){this.element=document.createElement("video"),this.element.classList.add("ls-viewer-video"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.element.setAttribute("muted",""),this.element.setAttribute("playsinline",""),this.element.setAttribute("preload","auto")}show(){this.element.style.opacity="1"}hide(){this.element.style.opacity="0"}resize(t,e,i,s){const r=w.fit(i,new y(t,e),s);this.element.style.top=`${r.top}px`,this.element.style.left=`${r.left}px`,this.element.style.width=`${r.width}px`,this.element.style.height=`${r.height}px`,(i.width!==this.element.width||i.height!==this.element.height)&&(this.element.width=i.width,this.element.height=i.height)}}class j{constructor(t,e,i){this.container=t,this.canvas=e,this.loader=i,this.hotspotList=[]}destroy(){}show(){this.canvas.show(!1),this.container.classList.add("ls-viewer-container-image")}hide(){this.canvas.hide(!1),this.container.classList.remove("ls-viewer-container-image")}async load(t,e,i,s){let r=Promise.resolve();const n=JSON.stringify(t);n===this.snapshotHash&&this.image?r=r.then(()=>this.canvas.draw(this.image,s,.05)):r=r.then(()=>this.loader.loadImageSnapshot(t).then(o=>{this.canvas.draw(o,s,.05),this.image=o}));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadImageHotspots(t,e).then(o=>{this.hotspotList=o})):this.hotspotList=[]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=new y(t.parameters.width,t.parameters.height),s=w.unproject(i,this.canvas.resolution,this.canvas.fit,e);return this.loader.loadImagePick(t,s)}hotspots(t){return this.hotspotList.map(e=>({...e,position2D:w.project(t,this.canvas.resolution,this.canvas.fit,e.position2D)})).map(e=>({...e,visibility:w.contains(this.canvas.resolution,e.position2D)?e.visibility:"OutOfFrustum"}))}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}onMouseDown(t){}onMouseMove(t){}onMouseUp(t){}onMouseEnter(t){}onTouchStart(t){}onTouchMove(t){}onTouchEnd(t){}onDeviceOrientation(t){}}class E{constructor(t,e){this.x=t,this.y=e}clone(){return new E(this.x,this.y)}}class f{static pointFromMouseEvent(t){return new E(t.screenX,t.screenY)}static pointFromTouchEvent(t){const e=t.targetTouches[0]||t.changedTouches[0];return new E(e.screenX,e.screenY)}}class D{constructor(...t){t.length===3?({0:this.u,1:this.v,2:this.o}=t,this.w=h.v3.cross(this.u,this.v)):t.length===4?{0:this.u,1:this.v,2:this.w,3:this.o}=t:(this.u=[1,0,0],this.v=[0,1,0],this.w=[0,0,1],this.o=[0,0,0])}get localToGlobalMatrix(){const t=[this.u[0],this.u[1],this.u[2],0],e=[this.v[0],this.v[1],this.v[2],0],i=[this.w[0],this.w[1],this.w[2],0],s=[this.o[0],this.o[1],this.o[2],1];return[...t,...e,...i,...s]}get globalToLocalMatrix(){return h.m4.inverse(this.localToGlobalMatrix)}}class Z{constructor(t,e,i){this.x=t,this.y=e,this.time=i}}class q{constructor(t){this.points=[],this.onMotion=t,this.lastPoint=new E(0,0),this.velocity=new E(0,0),this.loop=this.loop.bind(this)}destroy(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}track(t){const e=Date.now();this.points=this.points.filter(i=>e-i.time<=100),this.points.push(new Z(t.x,t.y,e)),this.lastPoint=t}start(){if(this.points.length===0)return;const t=this.points[0],e=this.points[this.points.length-1],i=e.x-t.x,s=e.y-t.y,r=e.time-t.time;this.velocity=new E(r===0?0:i/(r/15),r===0?0:s/(r/15)),this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0),this.animationFrameId=requestAnimationFrame(this.loop)}stop(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0),this.points=[]}loop(){if(Math.abs(this.velocity.x)<1&&Math.abs(this.velocity.y)<1){this.animationFrameId=void 0,this.points=[];return}this.lastPoint.x+=this.velocity.x,this.lastPoint.y+=this.velocity.y,this.velocity.x*=.9,this.velocity.y*=.9,this.onMotion(this.lastPoint.clone()),this.animationFrameId=requestAnimationFrame(this.loop)}}class Q{constructor(t,e,i){this.isStarted=!1,this.pov=t,this.fov=g.degreesToRadians(e),this.orientationMatrix=h.m4.identity(),this.inertia=new q(this.motion.bind(this)),this.onMotion=i,this.initPov=this.pov,this.initFov=this.fov,this.initOrientation=g.degreesToRadians(window.orientation)||0,this.startPov=new I([0,0,1],[0,0,0],[0,1,0]),this.startSize={width:0,height:0},this.previousPoint=new E(0,0)}destroy(){this.inertia.destroy()}get orientedPov(){const t=h.v3.normalize(h.v3.cross(this.pov.up,this.pov.target)),e=new D(t,[0,1,0],this.pov.eye),i=h.m4.identity();h.m4.multiply(i,e.localToGlobalMatrix,i),h.m4.multiply(i,this.orientationMatrix,i),h.m4.multiply(i,e.globalToLocalMatrix,i);const s=h.m4.transformDirection(i,this.pov.target),r=this.pov.eye,n=h.m4.transformDirection(i,this.pov.up);return new I(s,r,n)}reset(){this.pov=this.initPov.clone(),this.fov=this.initFov}start(t,e){this.isStarted=!0,this.startPov=this.pov,this.startSize=e,this.previousPoint=t,this.inertia.stop()}motion(t){this.isStarted&&this.inertia.track(t);const e={x:t.x-this.previousPoint.x,y:t.y-this.previousPoint.y},i=g.accelerate(e.x,1.3)/this.startSize.width*.2*Math.PI*1.5,s=g.accelerate(e.y,1.3)/this.startSize.height*.2*Math.PI,r=h.m4.multiply(h.m4.rotationY(i),h.m4.rotationX(-s)),n=h.v3.normalize(h.v3.cross(this.pov.up,this.pov.target)),a=new D(n,[0,1,0],this.pov.eye),o=h.m4.identity();h.m4.multiply(o,a.localToGlobalMatrix,o),h.m4.multiply(o,r,o),h.m4.multiply(o,a.globalToLocalMatrix,o);const u=h.m4.transformPoint(o,this.pov.target),d=h.m4.transformDirection(o,this.pov.up);h.v3.cross(d,[0,0,1])[0]>=0&&(this.pov.target=u,this.pov.up=d),this.previousPoint=t,this.onMotion()}end(t,e){this.isStarted=!1,e&&(this.inertia.track(t),this.inertia.start())}orientation(t,e,i){const s=g.degreesToRadians(window.orientation)||0,r=g.degreesToRadians(t),n=g.degreesToRadians(-e),a=g.degreesToRadians(-i),o=h.m4.rotationX(g.degreesToRadians(90));h.m4.rotateZ(o,this.initOrientation,o),h.m4.rotateZ(o,r,o),h.m4.rotateX(o,n,o),h.m4.rotateY(o,a,o),h.m4.rotateZ(o,-s,o),this.orientationMatrix=o,this.onMotion()}}var _=`precision mediump float;
|
|
3
3
|
|
|
4
4
|
uniform float u_mix;
|
|
5
5
|
uniform samplerCube u_texture;
|
|
@@ -22,4 +22,4 @@ void main() {
|
|
|
22
22
|
gl_Position = position;
|
|
23
23
|
}`;class H{constructor(t,e,i,s){this.container=t,this.canvas=e,this.loader=i,this.images=[],this.hotspotsList=[[]];const r=new I([0,0,1],[0,0,0],[0,1,0]),n=60,a=h.m4.rotationX(g.degreesToRadians(15));h.m4.transformDirection(a,r.target,r.target),h.m4.transformDirection(a,r.up,r.up),this.interaction=new Q(r,n,()=>{this.animationFrameId=requestAnimationFrame(this.render),this.onInteraction({pov:this.interaction.pov.clone(),fov:this.interaction.fov})}),this.onInteraction=s,this.gl=this.canvas.context,this.programInfo=P.createProgramInfo(this.gl,[`${K}
|
|
24
24
|
`,`${_}
|
|
25
|
-
`]),this.quad=P.primitives.createXYQuadBufferInfo(this.gl),this.uniforms={u_mvpi:h.m4.identity(),u_mix:0,u_texture_back:P.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,minMag:this.gl.LINEAR,width:1,height:1}),u_texture:P.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,minMag:this.gl.LINEAR,width:1,height:1})},this.render=this.render.bind(this)}destroy(){this.interaction.destroy(),this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}show(){this.canvas.show(),this.container.classList.add("ls-viewer-container-vrcube")}hide(){this.canvas.hide(),this.container.classList.remove("ls-viewer-container-vrcube")}get pov(){return this.interaction.pov}set pov(t){this.interaction.pov.eye.every((e,i)=>e===t.eye[i])&&this.interaction.pov.target.every((e,i)=>e===t.target[i])&&this.interaction.pov.up.every((e,i)=>e===t.up[i])||(this.interaction.pov=t.clone(),this.animationFrameId=requestAnimationFrame(this.render))}get fov(){return g.radiansToDegrees(this.interaction.fov)}set fov(t){this.interaction.fov!==t&&(this.interaction.fov=g.degreesToRadians(t),this.animationFrameId=requestAnimationFrame(this.render))}async load(t,e,i,s){let r=Promise.resolve();{const o=this.gl.getExtension("WEBGL_debug_renderer_info");o&&navigator.platform==="MacIntel"&&navigator.userAgent.includes("Chrome")&&this.gl.getParameter(o.UNMASKED_RENDERER_WEBGL).includes("OpenGL")&&(t.parameters.width=Math.min(t.parameters.width,1812),t.parameters.height=Math.min(t.parameters.height,1812))}const n=JSON.stringify(t);n===this.snapshotHash?r=r.then(()=>(this.animationFrameId=requestAnimationFrame(this.render),Promise.resolve())):(this.images=[],this.animationFrameId=requestAnimationFrame(this.render),r=r.then(()=>this.loader.loadVRCubeSnapshot(t).then(o=>{this.images=o,P.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,min:this.gl.LINEAR_MIPMAP_LINEAR,minMag:this.gl.LINEAR,cubeFaceOrder:[this.gl.TEXTURE_CUBE_MAP_POSITIVE_Z,this.gl.TEXTURE_CUBE_MAP_POSITIVE_X,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_X,this.gl.TEXTURE_CUBE_MAP_POSITIVE_Y,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y],src:o},(d,u)=>{d||(i&&this.interaction.reset(),this.uniforms.u_mix=s?0:1,this.uniforms.u_texture_back=this.uniforms.u_texture,this.uniforms.u_texture=u,this.animationFrameId=requestAnimationFrame(this.render))})})));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadVRCubeHotspots(t,e).then(o=>{this.hotspotsList=o})):this.hotspotsList=[[]]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=this.canvas.element.clientWidth,s=this.canvas.element.clientHeight,r=e.x,n=s-e.y,a=2*r/i-1,o=2*n/s-1,d=[a,o,0],u=this.modelViewProjectionMatrix,p=h.m4.inverse(u),c=h.v3.normalize(h.m4.transformPoint(p,d)),A=Math.max(Math.abs(c[0]),Math.abs(c[1]),Math.abs(c[2]));let L="";Math.abs(c[0])===A?L=c[0]>0?"XPOS":"XNEG":Math.abs(c[1])===A?L=c[1]>0?"YPOS":"YNEG":L=c[2]>0?"ZPOS":"ZNEG";let b=0,x=0,M="";switch(L){case"XPOS":b=(-c[2]/Math.abs(c[0])+1)/2,x=(-c[1]/Math.abs(c[0])+1)/2,M="right";break;case"XNEG":b=(c[2]/Math.abs(c[0])+1)/2,x=(-c[1]/Math.abs(c[0])+1)/2,M="left";break;case"YPOS":b=(c[0]/Math.abs(c[1])+1)/2,x=(c[2]/Math.abs(c[1])+1)/2,M="up";break;case"YNEG":b=(c[0]/Math.abs(c[1])+1)/2,x=(-c[2]/Math.abs(c[1])+1)/2,M="down";break;case"ZPOS":b=(c[0]/Math.abs(c[2])+1)/2,x=(-c[1]/Math.abs(c[2])+1)/2,M="front";break;case"ZNEG":b=(-c[0]/Math.abs(c[2])+1)/2,x=(-c[1]/Math.abs(c[2])+1)/2,M="back";break}const T={x:Math.round(b*Math.max(t.parameters.width,t.parameters.height)),y:Math.round(x*Math.max(t.parameters.width,t.parameters.height))};return this.loader.loadVRCubePick(t,T,M)}hotspots(){const t=[];if(this.hotspotsList.length===0)return[];const e=this.hotspotsList[0]?.length??0,i=this.modelViewProjectionMatrix;for(let s=0;s<e;s++){const r=this.hotspotsList.findIndex($=>$[s].visibility!=="OutOfFrustum");if(r===-1)continue;const n={...this.hotspotsList[r][s]},a=n.position2D.x/this.images[0].width,o=n.position2D.y/this.images[0].height;let d=0,u=0,p=0;switch(r){case 0:this.pov.target[2]<0&&(n.visibility="OutOfFrustum"),d=2*a-1,u=1-2*o,p=1;break;case 1:this.pov.target[0]>0&&(n.visibility="OutOfFrustum"),d=1,u=1-2*o,p=1-2*a;break;case 2:this.pov.target[2]>0&&(n.visibility="OutOfFrustum"),d=1-2*a,u=1-2*o,p=-1;break;case 3:this.pov.target[0]<0&&(n.visibility="OutOfFrustum"),d=-1,u=1-2*o,p=2*a-1;break;case 4:this.pov.target[1]<0&&(n.visibility="OutOfFrustum"),d=2*a-1,u=1,p=2*o-1;break;case 5:this.pov.target[1]>0&&(n.visibility="OutOfFrustum"),d=2*a-1,u=-1,p=1-2*o;break}const c=h.v3.normalize([d,u,p]),A=h.m4.transformPoint(i,c),L=this.canvas.element.clientWidth,b=this.canvas.element.clientHeight,x=.5*L*(A[0]+1),M=.5*b*(A[1]+1),T={x:Math.round(x),y:Math.round(b-M)},R=new y(L,b),z=w.contains(R,T)?n.visibility:"OutOfFrustum";t.push({...n,position2D:T,visibility:z})}return t}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}get modelViewProjectionMatrix(){const t=this.canvas.element.clientWidth,e=this.canvas.element.clientHeight,i=t>e?t/e:e/t,s=w.getStandardAspectRatio(t,e),r=this.interaction.fov*(s/i),n=h.m4.setAxis(h.m4.identity(),[-1,0,0],0),a=t>e?g.perspectiveWithFovY(r,t/e,.5,100):g.perspectiveWithFovX(r,t/e,.5,100),o=this.interaction.orientedPov,d=h.m4.inverse(h.m4.lookAt(o.eye,o.target,o.up));return h.m4.multiply(h.m4.multiply(a,d),n)}render(){this.gl.viewport(0,0,this.gl.canvas.width,this.gl.canvas.height),this.uniforms.u_mvpi=h.m4.inverse(this.modelViewProjectionMatrix),this.gl.useProgram(this.programInfo.program),P.setBuffersAndAttributes(this.gl,this.programInfo,this.quad),P.setUniforms(this.programInfo,this.uniforms),P.drawBufferInfo(this.gl,this.quad),this.uniforms.u_mix<1&&(this.uniforms.u_mix=Math.min(this.uniforms.u_mix+.05,1),this.animationFrameId=requestAnimationFrame(this.render))}onMouseDown(t){this.container.classList.add("ls-viewer-container-vrcube-grabbing"),this.interaction.start(f.pointFromMouseEvent(t),{width:this.gl.canvas.width,height:this.gl.canvas.height})}onMouseMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromMouseEvent(t)),t.preventDefault())}onMouseUp(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!0))}onMouseEnter(t){this.interaction.isStarted&&t.buttons===0&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!1))}onTouchStart(t){this.container.classList.add("ls-viewer-container-vrcube-grabbing"),this.interaction.start(f.pointFromTouchEvent(t),{width:this.gl.canvas.width,height:this.gl.canvas.height})}onTouchMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromTouchEvent(t)),t.preventDefault())}onTouchEnd(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromTouchEvent(t),!0))}onDeviceOrientation(t){this.interaction.orientation(t.alpha,t.beta,t.gamma)}}class tt{constructor(t,e,i,s,r){this.isStarted=!1,this.position=t,this.frames=e,this.rows=i,this.loop=s,this.onMotion=r,this.inertia=new q(this.motion.bind(this)),this.initPosition={...this.position},this.startPosition={x:0,y:0},this.startPoint=new E(0,0),this.startSize={width:0,height:0},this.lastPoints=[],this.lastPointsNumber=20}destroy(){this.inertia.destroy()}reset(){this.position={...this.initPosition}}get positionIndex(){return this.frames*this.position.y+this.position.x}set positionIndex(t){if(this.positionIndex===t)return;const e=this.loop?g.mod(t,this.frames*this.rows):Math.max(0,Math.min(t,this.frames*this.rows));this.position.x=g.mod(e,this.frames),this.position.y=Math.floor(e/this.frames)}start(t,e){this.isStarted=!0,this.startPosition={...this.position},this.startPoint=t,this.startSize=e,this.lastPoints=[],this.inertia.stop()}motion(t){this.isStarted&&this.inertia.track(t),this.lastPoints.push({x:t.x,y:t.y}),this.lastPoints.splice(0,this.lastPoints.length-this.lastPointsNumber);const e=U.linear(this.lastPoints.map(s=>[s.x,s.y])),i=25;if(Math.abs(e.equation[0])<1){const s=g.accelerate(t.x-this.startPoint.x,1.3)/this.startSize.width*(this.frames/4);let r=this.startPosition.x-Math.round(s);r=this.loop?g.mod(r,this.frames):Math.max(0,Math.min(r,this.frames-1)),r!==this.position.x&&(this.position.x=r,this.onMotion());const n=Math.min(...this.lastPoints.map(o=>o.x));Math.max(...this.lastPoints.map(o=>o.x))-n>i&&(this.startPoint.y=t.y,this.startPosition.y=this.position.y)}else{const s=g.accelerate(t.y-this.startPoint.y,1.7)/this.startSize.height*(this.rows/4);let r=this.startPosition.y+Math.round(s);r=Math.max(0,Math.min(r,this.rows-1)),r!==this.position.y&&(this.position.y=r,this.onMotion());const n=Math.min(...this.lastPoints.map(o=>o.y));Math.max(...this.lastPoints.map(o=>o.y))-n>i&&(this.startPoint.x=t.x,this.startPosition.x=this.position.x)}}end(t,e){this.isStarted=!1,e&&(this.inertia.track(t),this.inertia.start())}}class O{constructor(t,e,i,s){this.container=t,this.canvas=e,this.loader=i,this.images=[],this.frames=24,this.hotspotsList=[[]],this.interaction=new tt({x:0,y:0},1,1,!1,()=>{this.canvas.draw(this.image,!0,.5),this.onInteraction({position:this.interaction.positionIndex})}),this.onInteraction=s}destroy(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}show(){this.canvas.show(!1),this.container.classList.add("ls-viewer-container-vrobject")}hide(){this.canvas.hide(!1),this.container.classList.remove("ls-viewer-container-vrobject")}async goto(t){return new Promise(e=>{let i=this.interaction.positionIndex;const s=()=>{if(this.interaction.positionIndex===t)e();else{let r=i>t?-1:1;this.interaction.loop&&this.interaction.frames-i+t<Math.abs(t-i)&&(r*=-1),i+=.5*r,this.position=Math.floor(i),this.animationFrameId=requestAnimationFrame(s)}};this.animationFrameId=requestAnimationFrame(s)})}get position(){return this.interaction.positionIndex}set position(t){this.interaction.positionIndex=t,this.canvas.draw(this.image,!0,.5)}get image(){return this.images[this.interaction.positionIndex]}async load(t,e,i,s){let r=Promise.resolve();i&&this.interaction.reset();const n=JSON.stringify(t);n===this.snapshotHash&&this.image?r=r.then(()=>this.canvas.draw(this.image,s,.05)):(this.images=[],r=r.then(()=>this.loader.loadVRObjectSnapshot(t,this.interaction.positionIndex).then(o=>{const d=o.length;return this.images=new Array(d),this.interaction.frames=t.view.frames??t.view.panFrames??this.frames,this.interaction.rows=d/this.interaction.frames,this.interaction.loop=!!t.view.loop,i&&this.interaction.reset(),o.forEach((u,p)=>{u.then(c=>{this.images[p]=c,c===this.image&&this.canvas.draw(this.image,s,.05)}).catch(()=>{})}),o[this.interaction.positionIndex].then(()=>Promise.resolve())})));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadVRObjectHotspots(t,e).then(o=>{this.hotspotsList=o})):this.hotspotsList=[[]]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=new y(t.parameters.width,t.parameters.height),s=w.unproject(i,this.canvas.resolution,this.canvas.fit,e);return this.loader.loadVRObjectPick(t,s,this.position,this.frames)}hotspots(t){return(this.hotspotsList[this.interaction.positionIndex]||[]).map(i=>({...i,position2D:w.project(t,this.canvas.resolution,this.canvas.fit,i.position2D)})).map(i=>({...i,visibility:w.contains(this.canvas.resolution,i.position2D)?i.visibility:"OutOfFrustum"}))}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}onMouseDown(t){this.container.classList.add("ls-viewer-container-vrobject-grabbing"),this.interaction.start(f.pointFromMouseEvent(t),{width:this.canvas.element.width,height:this.canvas.element.height})}onMouseMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromMouseEvent(t)),t.preventDefault())}onMouseUp(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!0))}onMouseEnter(t){this.interaction.isStarted&&t.buttons===0&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!1))}onTouchStart(t){this.container.classList.add("ls-viewer-container-vrobject-grabbing"),this.interaction.start(f.pointFromTouchEvent(t),{width:this.canvas.element.width,height:this.canvas.element.height})}onTouchMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromTouchEvent(t)),t.preventDefault())}onTouchEnd(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromTouchEvent(t),!0))}onDeviceOrientation(t){}}class G{constructor(t,e,i){this.container=t,this.loader=i,this.video=e}destroy(){}show(){this.video.show(),this.container.classList.add("ls-viewer-container-video")}hide(){this.video.hide(),this.container.classList.remove("ls-viewer-container-video")}async load(t){const e=JSON.stringify(t);return e===this.hash?(this.video.element.load(),Promise.resolve()):(this.hash=e,this.loader.loadVideoSnapshot(this.video.element,t))}async pick(t,e){return Promise.reject()}hotspots(t){return[]}snapshot(t,e){return"data:image/gif;base64,R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="}async play(){return new Promise((t,e)=>{this.video.element.addEventListener("ended",()=>{t()},{once:!0}),this.video.element.play().catch(e),this.show()})}onMouseDown(t){}onMouseMove(t){}onMouseUp(t){}onMouseEnter(t){}onTouchStart(t){}onTouchMove(t){}onTouchEnd(t){}onDeviceOrientation(t){}}class et{constructor(t,e){this.checkResize=this.checkResize.bind(this),this.onDeviceOrientation=this.onDeviceOrientation.bind(this),this.onResize=this.onResize.bind(this),this.onMouseDown=this.onMouseDown.bind(this),this.onMouseMove=this.onMouseMove.bind(this),this.onMouseUp=this.onMouseUp.bind(this),this.onMouseEnter=this.onMouseEnter.bind(this),this.onTouchStart=this.onTouchStart.bind(this),this.onTouchMove=this.onTouchMove.bind(this),this.onTouchEnd=this.onTouchEnd.bind(this),this.onLoadStart=this.onLoadStart.bind(this),this.onLoadProgress=this.onLoadProgress.bind(this),this.onLoadEnd=this.onLoadEnd.bind(this),this.onLoadError=this.onLoadError.bind(this),this.onHotspotsChange=this.onHotspotsChange.bind(this),this.onVrcubeInteraction=this.onVrcubeInteraction.bind(this),this.onVrobjectInteraction=this.onVrobjectInteraction.bind(this),this.options={server:"localhost",api:"v1",autores:!0,fit:"cover",image:{},video:{},vrcube:{},vrobject:{},events:{},...e},this.options.events={onLoadStart:()=>{},onLoadProgress:()=>{},onLoadEnd:()=>{},onLoadError:()=>{},onInteraction:()=>{},onVrcubeInteraction:()=>{},onVrobjectInteraction:()=>{},onHotspotsChange:()=>{},...e.events},this.options.events.onLoadError=k(this.options.events.onLoadError,10),this.container=t,this.container.classList.add("ls-viewer-container"),this.containerWidth=0,this.containerHeight=0,this.canvas2D=new B(this.options.fit),this.container.prepend(this.canvas2D.element),this.canvas3D=new X,this.container.prepend(this.canvas3D.element),this.video=new J,this.container.prepend(this.video.element),this.loader=new C(this.options.server,this.options.api,this),this.resolution=new y(0,0),this.parameters={width:0,height:0,antialiasing:!1,superSampling:2},this.encoder={format:"jpeg",quality:80},this.hotspots=[],this.widgetImage=new j(t,this.canvas2D,this.loader),this.widgetVideo=new G(t,this.video,this.loader),this.widgetVRObject=new O(t,this.canvas2D,this.loader,this.onVrobjectInteraction),this.canvas3D.context&&(this.widgetVRCube=new H(t,this.canvas3D,this.loader,this.onVrcubeInteraction)),this.widget=this.widgetImage,this.isDestroyed=!1,this.container.addEventListener("mousedown",this.onMouseDown),this.container.addEventListener("mouseenter",this.onMouseEnter),this.container.addEventListener("touchstart",this.onTouchStart),document.addEventListener("mousemove",this.onMouseMove,{passive:!1}),document.addEventListener("mouseup",this.onMouseUp),document.addEventListener("touchmove",this.onTouchMove,{passive:!1}),document.addEventListener("touchend",this.onTouchEnd),this.loadWidget=k(this.loadWidget,10),this.onResize=k(this.onResize,250),requestAnimationFrame(this.checkResize)}destroy(){this.canvas2D.destroy(),this.container.removeEventListener("mousedown",this.onMouseDown),this.container.removeEventListener("mouseenter",this.onMouseEnter),this.container.removeEventListener("touchstart",this.onTouchStart),document.removeEventListener("mousemove",this.onMouseMove),document.removeEventListener("mouseup",this.onMouseUp),document.removeEventListener("touchmove",this.onTouchMove),document.removeEventListener("touchend",this.onTouchEnd),this.isDestroyed=!0}async load(t,e){let i=Promise.resolve();return e?.animation&&(i=i.then(()=>this.loadAnimation(e.animation))),this.view&&e?.fromPosition!==void 0&&this.viewWidget instanceof O&&(this.view.mode,i=i.then(()=>this.viewWidget.goto(e.fromPosition))),e?.animation&&(i=i.then(()=>this.widgetVideo.play())),i=i.then(()=>(this.scene=Array.isArray(t)?[...t]:[t],this.loadWidget(!1,!(e&&e.animation)))),i.catch(s=>{this.onLoadError(s)}),i}async setEncoder(t){this.encoder={...t};let e=Promise.resolve();return e=e.then(()=>this.loadWidget(!1,!0)),e.catch(i=>{this.onLoadError(i)}),e}setParameters(t){t.width&&t.height&&(this.resolution=new y(t.width,t.height)),this.parameters={...t},this.parameters.width=this.resolution.width,this.parameters.height=this.resolution.height;let e=Promise.resolve();return e=e.then(()=>this.loadWidget(!1,!0)),e.catch(i=>{this.onLoadError(i)}),e}setHotspots(t){this.hotspots=t,this.loadWidget(!1,!1)}async setView(t,e){let i=Promise.resolve();return e?.animation&&(i=i.then(()=>this.loadAnimation(e.animation))),this.view&&e?.fromPosition!==void 0&&this.viewWidget instanceof O&&(i=i.then(()=>this.viewWidget.goto(e.fromPosition))),e?.animation&&(i=i.then(()=>this.widgetVideo.play())),i=i.then(()=>{let s=!0;return this.view={...t},this.view&&this.viewWidget instanceof O&&e?.toPosition!==void 0&&(s=!1,this.viewWidget.position=e.toPosition),this.loadWidget(s,!(e&&e.animation))}),i.catch(s=>{this.onLoadError(s)}),i}setVrcube(t){this.widgetVRCube&&Object.assign(this.widgetVRCube,t)}setVrobject(t){Object.assign(this.widgetVRObject,t)}async loadAnimation(t){const e={scene:this.scene,view:{animation:t.name,camera:t.camera,duration:t.duration,loop:t.loop,reverse:t.reverse},parameters:this.parameters,encoder:{format:"mp4"}};return e.view?.background||(e.view.background="product"),this.widgetVideo.load(e).then(()=>Promise.resolve())}async playAnimation(t){return this.loadAnimation(t).then(()=>this.widgetVideo.play()).catch(e=>{this.onLoadError(e)})}stopAnimation(){this.widgetVideo.hide()}async pick(t){if(!this.scene)throw new Error("No scene set");if(!this.view)throw new Error("No view set");if(!this.view.camera&&!this.view.cameraGroup)throw new Error("No camera set");const e={scene:this.scene,view:this.view,parameters:this.parameters,encoder:this.encoder};return await this.viewWidget.pick(e,t)}async pickHotspot(t){const e=await this.pick(t),i=Object.values(e.point),s=h.v3.normalize(Object.values(e.normal)),r=h.v3.add(i,h.v3.mulScalar(s,.01));return e.point={x:r[0],y:r[1],z:r[2]},e}snapshot(t,e){return this.viewWidget.snapshot(t,e)}async loadWidget(t,e){if(!this.scene||!this.view||!this.parameters.width||!this.parameters.height)return Promise.resolve();const i=this.viewWidget;if(!i)return Promise.reject(new Error("Unknown view mode"));const s={scene:this.scene,view:this.view,parameters:this.parameters,encoder:this.encoder};return s.view.background||(s.view.background="product"),i.load(s,this.hotspots,t,e).then(()=>{this.widget.hide(),this.widget=i,this.widget.show(),this.widgetVideo.hide(),this.onHotspotsChange()})}get viewWidget(){switch(this.view?.mode){case"image":return this.widgetImage;case"video":return this.widgetVideo;case"vrcube":return this.widgetVRCube??this.widgetImage;case"vrobject":return this.widgetVRObject;default:return this.widgetImage}}checkResize(){if(this.isDestroyed)return;const t=this.container.clientWidth,e=this.container.clientHeight;(t!==this.containerWidth||e!==this.containerHeight)&&(this.containerWidth=t,this.containerHeight=e,this.onResize()),this.isDestroyed||requestAnimationFrame(this.checkResize)}onMouseDown(t){this.widget.onMouseDown(t)}onMouseEnter(t){this.widget.onMouseEnter(t)}onMouseMove(t){this.widget.onMouseMove(t)}onMouseUp(t){this.widget.onMouseUp(t)}onTouchStart(t){this.widget.onTouchStart(t)}onTouchMove(t){this.widget.onTouchMove(t)}onTouchEnd(t){this.widget.onTouchEnd(t)}onDeviceOrientation(t){this.widget.onDeviceOrientation(t)}onResize(){const t=this.container.clientWidth,e=this.container.clientHeight;this.options.autores&&(this.resolution=w.getStandardResolution(t*window.devicePixelRatio,e*window.devicePixelRatio),this.parameters.width=this.resolution.width,this.parameters.height=this.resolution.height),this.canvas2D.resize(t,e,window.devicePixelRatio),this.canvas3D.resize(t,e,window.devicePixelRatio),this.video.resize(t,e,this.resolution,this.options.fit),this.loadWidget(!1,!1).then(()=>{this.onHotspotsChange()}).catch(i=>{this.onLoadError(i)})}onVrcubeInteraction(...t){this.onHotspotsChange(),this.options.events.onInteraction(...t),this.options.events.onVrcubeInteraction(...t)}onVrobjectInteraction(t){this.onHotspotsChange(),this.options.events.onInteraction(t.position),this.options.events.onVrobjectInteraction(t.position)}onHotspotsChange(){const t=this.widget.hotspots(this.resolution);t.length&&this.options.events.onHotspotsChange(t)}onLoadStart(...t){this.container.classList.add("ls-viewer-container-loading"),this.options.events.onLoadStart(...t)}onLoadProgress(...t){this.options.events.onLoadProgress(...t)}onLoadEnd(...t){this.container.classList.remove("ls-viewer-container-loading"),this.options.events.onLoadEnd(...t)}onLoadError(...t){this.container.classList.remove("ls-viewer-container-loading"),this.options.events.onLoadError(...t)}}exports.WRAPIv2=void 0;(l=>{(t=>{t.Visible="Visible",t.Occluded="Occluded",t.Clipped="Clipped",t.OutOfFrustum="OutOfFrustum"})(l.HotspotVisibility||(l.HotspotVisibility={})),(t=>{t.VeryLow="veryLow",t.Low="low",t.Medium="medium",t.Fine="fine",t.Ultra="ultra"})(l.SunShadowQualityMode||(l.SunShadowQualityMode={})),(t=>{t.None="none",t.Weak="weak",t.Normal="normal",t.Fine="fine",t.UltraFine="ultraFine",t.Max="max"})(l.SunShadowSmoothnessMode||(l.SunShadowSmoothnessMode={})),(t=>{t.Manual="manual",t.TimeAndLoc="timeAndLoc",t.ExtractedFromEnv="extractedFromEnv"})(l.SunUseCaseMode||(l.SunUseCaseMode={})),(t=>{t.ShowOnly="showOnly",t.HideOnly="hideOnly"})(l.SurfacesFilterMode||(l.SurfacesFilterMode={}))})(exports.WRAPIv2||(exports.WRAPIv2={}));exports.Viewer=et;exports.WidgetImage=j;exports.WidgetVRCube=H;exports.WidgetVRObject=O;exports.WidgetVideo=G;
|
|
25
|
+
`]),this.quad=P.primitives.createXYQuadBufferInfo(this.gl),this.uniforms={u_mvpi:h.m4.identity(),u_mix:0,u_texture_back:P.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,minMag:this.gl.LINEAR,width:1,height:1}),u_texture:P.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,minMag:this.gl.LINEAR,width:1,height:1})},this.render=this.render.bind(this)}destroy(){this.interaction.destroy(),this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}show(){this.canvas.show(),this.container.classList.add("ls-viewer-container-vrcube")}hide(){this.canvas.hide(),this.container.classList.remove("ls-viewer-container-vrcube")}get pov(){return this.interaction.pov}set pov(t){this.interaction.pov.eye.every((e,i)=>e===t.eye[i])&&this.interaction.pov.target.every((e,i)=>e===t.target[i])&&this.interaction.pov.up.every((e,i)=>e===t.up[i])||(this.interaction.pov=t.clone(),this.animationFrameId=requestAnimationFrame(this.render))}get fov(){return g.radiansToDegrees(this.interaction.fov)}set fov(t){this.interaction.fov!==t&&(this.interaction.fov=g.degreesToRadians(t),this.animationFrameId=requestAnimationFrame(this.render))}async load(t,e,i,s){let r=Promise.resolve();{const o=this.gl.getExtension("WEBGL_debug_renderer_info");o&&navigator.platform==="MacIntel"&&navigator.userAgent.includes("Chrome")&&this.gl.getParameter(o.UNMASKED_RENDERER_WEBGL).includes("OpenGL")&&(t.parameters.width=Math.min(t.parameters.width,1812),t.parameters.height=Math.min(t.parameters.height,1812))}const n=JSON.stringify(t);n===this.snapshotHash?r=r.then(()=>(this.animationFrameId=requestAnimationFrame(this.render),Promise.resolve())):(this.images=[],this.animationFrameId=requestAnimationFrame(this.render),r=r.then(()=>this.loader.loadVRCubeSnapshot(t).then(o=>{this.images=o,P.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,min:this.gl.LINEAR_MIPMAP_LINEAR,minMag:this.gl.LINEAR,cubeFaceOrder:[this.gl.TEXTURE_CUBE_MAP_POSITIVE_Z,this.gl.TEXTURE_CUBE_MAP_POSITIVE_X,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_X,this.gl.TEXTURE_CUBE_MAP_POSITIVE_Y,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y],src:o},(u,d)=>{u||(i&&this.interaction.reset(),this.uniforms.u_mix=s?0:1,this.uniforms.u_texture_back=this.uniforms.u_texture,this.uniforms.u_texture=d,this.animationFrameId=requestAnimationFrame(this.render))})})));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadVRCubeHotspots(t,e).then(o=>{this.hotspotsList=o})):this.hotspotsList=[[]]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=this.canvas.element.clientWidth,s=this.canvas.element.clientHeight,r=e.x,n=s-e.y,a=2*r/i-1,o=2*n/s-1,u=[a,o,0],d=this.modelViewProjectionMatrix,p=h.m4.inverse(d),c=h.v3.normalize(h.m4.transformPoint(p,u)),A=Math.max(Math.abs(c[0]),Math.abs(c[1]),Math.abs(c[2]));let L="";Math.abs(c[0])===A?L=c[0]>0?"XPOS":"XNEG":Math.abs(c[1])===A?L=c[1]>0?"YPOS":"YNEG":L=c[2]>0?"ZPOS":"ZNEG";let b=0,x=0,M="";switch(L){case"XPOS":b=(-c[2]/Math.abs(c[0])+1)/2,x=(-c[1]/Math.abs(c[0])+1)/2,M="right";break;case"XNEG":b=(c[2]/Math.abs(c[0])+1)/2,x=(-c[1]/Math.abs(c[0])+1)/2,M="left";break;case"YPOS":b=(c[0]/Math.abs(c[1])+1)/2,x=(c[2]/Math.abs(c[1])+1)/2,M="up";break;case"YNEG":b=(c[0]/Math.abs(c[1])+1)/2,x=(-c[2]/Math.abs(c[1])+1)/2,M="down";break;case"ZPOS":b=(c[0]/Math.abs(c[2])+1)/2,x=(-c[1]/Math.abs(c[2])+1)/2,M="front";break;case"ZNEG":b=(-c[0]/Math.abs(c[2])+1)/2,x=(-c[1]/Math.abs(c[2])+1)/2,M="back";break}const T={x:Math.round(b*Math.max(t.parameters.width,t.parameters.height)),y:Math.round(x*Math.max(t.parameters.width,t.parameters.height))};return this.loader.loadVRCubePick(t,T,M)}hotspots(){const t=[];if(this.hotspotsList.length===0)return[];const e=this.hotspotsList[0]?.length??0,i=this.modelViewProjectionMatrix;for(let s=0;s<e;s++){const r=this.hotspotsList.findIndex($=>$[s].visibility!=="OutOfFrustum");if(r===-1)continue;const n={...this.hotspotsList[r][s]},a=n.position2D.x/this.images[0].width,o=n.position2D.y/this.images[0].height;let u=0,d=0,p=0;switch(r){case 0:this.pov.target[2]<0&&(n.visibility="OutOfFrustum"),u=2*a-1,d=1-2*o,p=1;break;case 1:this.pov.target[0]>0&&(n.visibility="OutOfFrustum"),u=1,d=1-2*o,p=1-2*a;break;case 2:this.pov.target[2]>0&&(n.visibility="OutOfFrustum"),u=1-2*a,d=1-2*o,p=-1;break;case 3:this.pov.target[0]<0&&(n.visibility="OutOfFrustum"),u=-1,d=1-2*o,p=2*a-1;break;case 4:this.pov.target[1]<0&&(n.visibility="OutOfFrustum"),u=2*a-1,d=1,p=2*o-1;break;case 5:this.pov.target[1]>0&&(n.visibility="OutOfFrustum"),u=2*a-1,d=-1,p=1-2*o;break}const c=h.v3.normalize([u,d,p]),A=h.m4.transformPoint(i,c),L=this.canvas.element.clientWidth,b=this.canvas.element.clientHeight,x=.5*L*(A[0]+1),M=.5*b*(A[1]+1),T={x:Math.round(x),y:Math.round(b-M)},R=new y(L,b),z=w.contains(R,T)?n.visibility:"OutOfFrustum";t.push({...n,position2D:T,visibility:z})}return t}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}get modelViewProjectionMatrix(){const t=this.canvas.element.clientWidth,e=this.canvas.element.clientHeight,i=t>e?t/e:e/t,s=w.getStandardAspectRatio(t,e),r=this.interaction.fov*(s/i),n=h.m4.setAxis(h.m4.identity(),[-1,0,0],0),a=t>e?g.perspectiveWithFovY(r,t/e,.5,100):g.perspectiveWithFovX(r,t/e,.5,100),o=this.interaction.orientedPov,u=h.m4.inverse(h.m4.lookAt(o.eye,o.target,o.up));return h.m4.multiply(h.m4.multiply(a,u),n)}render(){this.gl.viewport(0,0,this.gl.canvas.width,this.gl.canvas.height),this.uniforms.u_mvpi=h.m4.inverse(this.modelViewProjectionMatrix),this.gl.useProgram(this.programInfo.program),P.setBuffersAndAttributes(this.gl,this.programInfo,this.quad),P.setUniforms(this.programInfo,this.uniforms),P.drawBufferInfo(this.gl,this.quad),this.uniforms.u_mix<1&&(this.uniforms.u_mix=Math.min(this.uniforms.u_mix+.05,1),this.animationFrameId=requestAnimationFrame(this.render))}onMouseDown(t){this.container.classList.add("ls-viewer-container-vrcube-grabbing"),this.interaction.start(f.pointFromMouseEvent(t),{width:this.gl.canvas.width,height:this.gl.canvas.height})}onMouseMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromMouseEvent(t)),t.preventDefault())}onMouseUp(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!0))}onMouseEnter(t){this.interaction.isStarted&&t.buttons===0&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!1))}onTouchStart(t){this.container.classList.add("ls-viewer-container-vrcube-grabbing"),this.interaction.start(f.pointFromTouchEvent(t),{width:this.gl.canvas.width,height:this.gl.canvas.height})}onTouchMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromTouchEvent(t)),t.preventDefault())}onTouchEnd(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromTouchEvent(t),!0))}onDeviceOrientation(t){this.interaction.orientation(t.alpha,t.beta,t.gamma)}}class tt{constructor(t,e,i,s,r){this.isStarted=!1,this.position=t,this.frames=e,this.rows=i,this.loop=s,this.onMotion=r,this.inertia=new q(this.motion.bind(this)),this.initPosition={...this.position},this.startPosition={x:0,y:0},this.startPoint=new E(0,0),this.startSize={width:0,height:0},this.lastPoints=[],this.lastPointsNumber=20}destroy(){this.inertia.destroy()}reset(){this.position={...this.initPosition}}get positionIndex(){return this.frames*this.position.y+this.position.x}set positionIndex(t){if(this.positionIndex===t)return;const e=this.loop?g.mod(t,this.frames*this.rows):Math.max(0,Math.min(t,this.frames*this.rows));this.position.x=g.mod(e,this.frames),this.position.y=Math.floor(e/this.frames)}start(t,e){this.isStarted=!0,this.startPosition={...this.position},this.startPoint=t,this.startSize=e,this.lastPoints=[],this.inertia.stop()}motion(t){this.isStarted&&this.inertia.track(t),this.lastPoints.push({x:t.x,y:t.y}),this.lastPoints.splice(0,this.lastPoints.length-this.lastPointsNumber);const e=U.linear(this.lastPoints.map(s=>[s.x,s.y])),i=25;if(Math.abs(e.equation[0])<1){const s=g.accelerate(t.x-this.startPoint.x,1.3)/this.startSize.width*(this.frames/4);let r=this.startPosition.x-Math.round(s);r=this.loop?g.mod(r,this.frames):Math.max(0,Math.min(r,this.frames-1)),r!==this.position.x&&(this.position.x=r,this.onMotion());const n=Math.min(...this.lastPoints.map(o=>o.x));Math.max(...this.lastPoints.map(o=>o.x))-n>i&&(this.startPoint.y=t.y,this.startPosition.y=this.position.y)}else{const s=g.accelerate(t.y-this.startPoint.y,1.7)/this.startSize.height*(this.rows/4);let r=this.startPosition.y+Math.round(s);r=Math.max(0,Math.min(r,this.rows-1)),r!==this.position.y&&(this.position.y=r,this.onMotion());const n=Math.min(...this.lastPoints.map(o=>o.y));Math.max(...this.lastPoints.map(o=>o.y))-n>i&&(this.startPoint.x=t.x,this.startPosition.x=this.position.x)}}end(t,e){this.isStarted=!1,e&&(this.inertia.track(t),this.inertia.start())}}class O{constructor(t,e,i,s){this.container=t,this.canvas=e,this.loader=i,this.images=[],this.frames=24,this.hotspotsList=[[]],this.interaction=new tt({x:0,y:0},1,1,!1,()=>{this.canvas.draw(this.image,!0,.5),this.onInteraction({position:this.interaction.positionIndex})}),this.onInteraction=s}destroy(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}show(){this.canvas.show(!1),this.container.classList.add("ls-viewer-container-vrobject")}hide(){this.canvas.hide(!1),this.container.classList.remove("ls-viewer-container-vrobject")}async goto(t){return new Promise(e=>{let i=this.interaction.positionIndex;const s=()=>{if(this.interaction.positionIndex===t)e();else{let r=i>t?-1:1;this.interaction.loop&&this.interaction.frames-i+t<Math.abs(t-i)&&(r*=-1),i+=.5*r,this.position=Math.floor(i),this.animationFrameId=requestAnimationFrame(s)}};this.animationFrameId=requestAnimationFrame(s)})}get position(){return this.interaction.positionIndex}set position(t){this.interaction.positionIndex=t,this.canvas.draw(this.image,!0,.5)}get image(){return this.images[this.interaction.positionIndex]}async load(t,e,i,s){let r=Promise.resolve();i&&this.interaction.reset();const n=JSON.stringify(t);n===this.snapshotHash&&this.image?r=r.then(()=>this.canvas.draw(this.image,s,.05)):(this.images=[],r=r.then(()=>this.loader.loadVRObjectSnapshot(t,this.interaction.positionIndex).then(o=>{const u=o.length;return this.images=new Array(u),this.interaction.frames=t.view.frames??t.view.panFrames??this.frames,this.interaction.rows=u/this.interaction.frames,this.interaction.loop=!!t.view.loop,i&&this.interaction.reset(),o.forEach((d,p)=>{d.then(c=>{this.images[p]=c,c===this.image&&this.canvas.draw(this.image,s,.05)}).catch(()=>{})}),o[this.interaction.positionIndex].then(()=>Promise.resolve())})));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadVRObjectHotspots(t,e).then(o=>{this.hotspotsList=o})):this.hotspotsList=[[]]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=new y(t.parameters.width,t.parameters.height),s=w.unproject(i,this.canvas.resolution,this.canvas.fit,e);return this.loader.loadVRObjectPick(t,s,this.position,this.frames)}hotspots(t){return(this.hotspotsList[this.interaction.positionIndex]||[]).map(i=>({...i,position2D:w.project(t,this.canvas.resolution,this.canvas.fit,i.position2D)})).map(i=>({...i,visibility:w.contains(this.canvas.resolution,i.position2D)?i.visibility:"OutOfFrustum"}))}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}onMouseDown(t){this.container.classList.add("ls-viewer-container-vrobject-grabbing"),this.interaction.start(f.pointFromMouseEvent(t),{width:this.canvas.element.width,height:this.canvas.element.height})}onMouseMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromMouseEvent(t)),t.preventDefault())}onMouseUp(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!0))}onMouseEnter(t){this.interaction.isStarted&&t.buttons===0&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!1))}onTouchStart(t){this.container.classList.add("ls-viewer-container-vrobject-grabbing"),this.interaction.start(f.pointFromTouchEvent(t),{width:this.canvas.element.width,height:this.canvas.element.height})}onTouchMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromTouchEvent(t)),t.preventDefault())}onTouchEnd(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromTouchEvent(t),!0))}onDeviceOrientation(t){}}class G{constructor(t,e,i){this.container=t,this.loader=i,this.video=e}destroy(){}show(){this.video.show(),this.container.classList.add("ls-viewer-container-video")}hide(){this.video.hide(),this.container.classList.remove("ls-viewer-container-video")}async load(t){const e=JSON.stringify(t);return e===this.hash?(this.video.element.load(),Promise.resolve()):(this.hash=e,this.loader.loadVideoSnapshot(this.video.element,t))}async pick(t,e){return Promise.reject()}hotspots(t){return[]}snapshot(t,e){return"data:image/gif;base64,R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="}async play(){return new Promise((t,e)=>{this.video.element.addEventListener("ended",()=>{t()},{once:!0}),this.video.element.play().catch(e),this.show()})}onMouseDown(t){}onMouseMove(t){}onMouseUp(t){}onMouseEnter(t){}onTouchStart(t){}onTouchMove(t){}onTouchEnd(t){}onDeviceOrientation(t){}}class et{constructor(t,e){this.checkResize=this.checkResize.bind(this),this.onDeviceOrientation=this.onDeviceOrientation.bind(this),this.onResize=this.onResize.bind(this),this.onMouseDown=this.onMouseDown.bind(this),this.onMouseMove=this.onMouseMove.bind(this),this.onMouseUp=this.onMouseUp.bind(this),this.onMouseEnter=this.onMouseEnter.bind(this),this.onTouchStart=this.onTouchStart.bind(this),this.onTouchMove=this.onTouchMove.bind(this),this.onTouchEnd=this.onTouchEnd.bind(this),this.onLoadStart=this.onLoadStart.bind(this),this.onLoadProgress=this.onLoadProgress.bind(this),this.onLoadEnd=this.onLoadEnd.bind(this),this.onLoadError=this.onLoadError.bind(this),this.onHotspotsChange=this.onHotspotsChange.bind(this),this.onVrcubeInteraction=this.onVrcubeInteraction.bind(this),this.onVrobjectInteraction=this.onVrobjectInteraction.bind(this),this.options={server:"localhost",api:"v1",autores:!0,fit:"cover",image:{},video:{},vrcube:{},vrobject:{},events:{},...e},this.options.events={onLoadStart:()=>{},onLoadProgress:()=>{},onLoadEnd:()=>{},onLoadError:()=>{},onInteraction:()=>{},onVrcubeInteraction:()=>{},onVrobjectInteraction:()=>{},onHotspotsChange:()=>{},...e.events},this.options.events.onLoadError=k(this.options.events.onLoadError,10),this.container=t,this.container.classList.add("ls-viewer-container"),this.containerWidth=0,this.containerHeight=0,this.canvas2D=new B(this.options.fit),this.container.prepend(this.canvas2D.element),this.canvas3D=new X,this.container.prepend(this.canvas3D.element),this.video=new J,this.container.prepend(this.video.element),this.loader=new C(this.options.server,this.options.api,this),this.resolution=new y(0,0),this.parameters={width:0,height:0,antialiasing:!1,superSampling:2},this.encoder={format:"jpeg",quality:80},this.hotspots=[],this.widgetImage=new j(t,this.canvas2D,this.loader),this.widgetVideo=new G(t,this.video,this.loader),this.widgetVRObject=new O(t,this.canvas2D,this.loader,this.onVrobjectInteraction),this.canvas3D.context&&(this.widgetVRCube=new H(t,this.canvas3D,this.loader,this.onVrcubeInteraction)),this.widget=this.widgetImage,this.isDestroyed=!1,this.container.addEventListener("mousedown",this.onMouseDown),this.container.addEventListener("mouseenter",this.onMouseEnter),this.container.addEventListener("touchstart",this.onTouchStart),document.addEventListener("mousemove",this.onMouseMove,{passive:!1}),document.addEventListener("mouseup",this.onMouseUp),document.addEventListener("touchmove",this.onTouchMove,{passive:!1}),document.addEventListener("touchend",this.onTouchEnd),this.loadWidget=k(this.loadWidget,10),this.onResize=k(this.onResize,250),requestAnimationFrame(this.checkResize)}destroy(){this.canvas2D.destroy(),this.container.removeEventListener("mousedown",this.onMouseDown),this.container.removeEventListener("mouseenter",this.onMouseEnter),this.container.removeEventListener("touchstart",this.onTouchStart),document.removeEventListener("mousemove",this.onMouseMove),document.removeEventListener("mouseup",this.onMouseUp),document.removeEventListener("touchmove",this.onTouchMove),document.removeEventListener("touchend",this.onTouchEnd),this.isDestroyed=!0}async load(t,e){let i=Promise.resolve();return e?.animation&&(i=i.then(()=>this.loadAnimation(e.animation))),this.view&&e?.fromPosition!==void 0&&this.viewWidget instanceof O&&(this.view.mode,i=i.then(()=>this.viewWidget.goto(e.fromPosition))),e?.animation&&(i=i.then(()=>this.widgetVideo.play())),i=i.then(()=>(this.scene=Array.isArray(t)?[...t]:[t],this.loadWidget(!1,!(e&&e.animation)))),i.catch(s=>{this.onLoadError(s)}),i}async setEncoder(t){this.encoder={...t};let e=Promise.resolve();return e=e.then(()=>this.loadWidget(!1,!0)),e.catch(i=>{this.onLoadError(i)}),e}setParameters(t){t.width&&t.height&&(this.resolution=new y(t.width,t.height)),this.parameters={...t},this.parameters.width=this.resolution.width,this.parameters.height=this.resolution.height;let e=Promise.resolve();return e=e.then(()=>this.loadWidget(!1,!0)),e.catch(i=>{this.onLoadError(i)}),e}setHotspots(t){this.hotspots=t,this.loadWidget(!1,!1)}async setView(t,e){let i=Promise.resolve();return e?.animation&&(i=i.then(()=>this.loadAnimation(e.animation))),this.view&&e?.fromPosition!==void 0&&this.viewWidget instanceof O&&(i=i.then(()=>this.viewWidget.goto(e.fromPosition))),e?.animation&&(i=i.then(()=>this.widgetVideo.play())),i=i.then(()=>{let s=!0;return this.view={...t},this.view&&this.viewWidget instanceof O&&e?.toPosition!==void 0&&(s=!1,this.viewWidget.position=e.toPosition),this.loadWidget(s,!(e&&e.animation))}),i.catch(s=>{this.onLoadError(s)}),i}setVrcube(t){this.widgetVRCube&&Object.assign(this.widgetVRCube,t)}setVrobject(t){Object.assign(this.widgetVRObject,t)}async loadAnimation(t){const e={scene:this.scene,view:{animation:t.name,camera:t.camera,duration:t.duration,loop:t.loop,reverse:t.reverse},parameters:this.parameters,encoder:{format:"mp4"}};return e.view?.background||(e.view.background="product"),this.widgetVideo.load(e).then(()=>Promise.resolve())}async playAnimation(t){return this.loadAnimation(t).then(()=>this.widgetVideo.play()).catch(e=>{this.onLoadError(e)})}stopAnimation(){this.widgetVideo.hide()}async pick(t){if(!this.scene)throw new Error("No scene set");if(!this.view)throw new Error("No view set");if(!this.view.camera&&!this.view.cameraGroup)throw new Error("No camera set");const e={scene:this.scene,view:this.view,parameters:this.parameters,encoder:this.encoder};return await this.viewWidget.pick(e,t)}async pickHotspot(t){const e=await this.pick(t),i=Object.values(e.point),s=h.v3.normalize(Object.values(e.normal)),r=h.v3.add(i,h.v3.mulScalar(s,.01));return e.point={x:r[0],y:r[1],z:r[2]},e}snapshot(t,e){return this.viewWidget.snapshot(t,e)}async loadWidget(t,e){if(!this.scene||!this.view||!this.parameters.width||!this.parameters.height)return Promise.resolve();const i=this.viewWidget;if(!i)return Promise.reject(new Error("Unknown view mode"));const s={scene:this.scene,view:this.view,parameters:this.parameters,encoder:this.encoder};return s.view.background||(s.view.background="product"),i.load(s,this.hotspots,t,e).then(()=>{this.widget.hide(),this.widget=i,this.widget.show(),this.widgetVideo.hide(),this.onHotspotsChange()})}get viewWidget(){switch(this.view?.mode){case"image":return this.widgetImage;case"video":return this.widgetVideo;case"vrcube":return this.widgetVRCube??this.widgetImage;case"vrobject":return this.widgetVRObject;default:return this.widgetImage}}checkResize(){if(this.isDestroyed)return;const t=this.container.clientWidth,e=this.container.clientHeight;(t!==this.containerWidth||e!==this.containerHeight)&&(this.containerWidth=t,this.containerHeight=e,this.onResize()),this.isDestroyed||requestAnimationFrame(this.checkResize)}onMouseDown(t){this.widget.onMouseDown(t)}onMouseEnter(t){this.widget.onMouseEnter(t)}onMouseMove(t){this.widget.onMouseMove(t)}onMouseUp(t){this.widget.onMouseUp(t)}onTouchStart(t){this.widget.onTouchStart(t)}onTouchMove(t){this.widget.onTouchMove(t)}onTouchEnd(t){this.widget.onTouchEnd(t)}onDeviceOrientation(t){this.widget.onDeviceOrientation(t)}onResize(){const t=this.container.clientWidth,e=this.container.clientHeight;this.options.autores&&(this.resolution=w.getStandardResolution(t*window.devicePixelRatio,e*window.devicePixelRatio),this.parameters.width=this.resolution.width,this.parameters.height=this.resolution.height),this.canvas2D.resize(t,e,window.devicePixelRatio),this.canvas3D.resize(t,e,window.devicePixelRatio),this.video.resize(t,e,this.resolution,this.options.fit),this.loadWidget(!1,!1).then(()=>{this.onHotspotsChange()}).catch(i=>{this.onLoadError(i)})}onVrcubeInteraction(...t){this.onHotspotsChange(),this.options.events.onInteraction(...t),this.options.events.onVrcubeInteraction(...t)}onVrobjectInteraction(t){this.onHotspotsChange(),this.options.events.onInteraction(t.position),this.options.events.onVrobjectInteraction(t.position)}onHotspotsChange(){const t=this.widget.hotspots(this.resolution);t.length&&this.options.events.onHotspotsChange(t)}onLoadStart(...t){this.container.classList.add("ls-viewer-container-loading"),this.options.events.onLoadStart(...t)}onLoadProgress(...t){this.options.events.onLoadProgress(...t)}onLoadEnd(...t){this.container.classList.remove("ls-viewer-container-loading"),this.options.events.onLoadEnd(...t)}onLoadError(...t){this.container.classList.remove("ls-viewer-container-loading"),this.options.events.onLoadError(...t)}}exports.WRAPIv2=void 0;(l=>{(t=>{t.Visible="Visible",t.Occluded="Occluded",t.Clipped="Clipped",t.OutOfFrustum="OutOfFrustum"})(l.HotspotVisibility||(l.HotspotVisibility={})),(t=>{t.VeryLow="veryLow",t.Low="low",t.Medium="medium",t.Fine="fine",t.Ultra="ultra"})(l.SunShadowQualityMode||(l.SunShadowQualityMode={})),(t=>{t.None="none",t.Weak="weak",t.Normal="normal",t.Fine="fine",t.UltraFine="ultraFine",t.Max="max"})(l.SunShadowSmoothnessMode||(l.SunShadowSmoothnessMode={})),(t=>{t.Manual="manual",t.TimeAndLoc="timeAndLoc",t.ExtractedFromEnv="extractedFromEnv"})(l.SunUseCaseMode||(l.SunUseCaseMode={})),(t=>{t.ShowOnly="showOnly",t.HideOnly="hideOnly"})(l.SurfacesFilterMode||(l.SurfacesFilterMode={}))})(exports.WRAPIv2||(exports.WRAPIv2={}));exports.Viewer=et;exports.WidgetImage=j;exports.WidgetVRCube=H;exports.WidgetVRObject=O;exports.WidgetVideo=G;
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -169,12 +169,12 @@ declare class Video {
|
|
|
169
169
|
|
|
170
170
|
export declare interface View {
|
|
171
171
|
mode: string;
|
|
172
|
-
camera?: string |
|
|
172
|
+
camera?: string | WRAPIv2.CameraObj;
|
|
173
173
|
background?: string;
|
|
174
174
|
animation?: string;
|
|
175
175
|
frames?: number;
|
|
176
176
|
loop?: boolean;
|
|
177
|
-
cameraGroup?:
|
|
177
|
+
cameraGroup?: string;
|
|
178
178
|
panFrom?: number;
|
|
179
179
|
panTo?: number;
|
|
180
180
|
panFrames?: number;
|
|
@@ -522,6 +522,7 @@ export declare namespace WRAPIv2 {
|
|
|
522
522
|
export type AnimationArray = Animation[];
|
|
523
523
|
export type Camera = Guid | CameraObj;
|
|
524
524
|
export type CameraGroup = Guid;
|
|
525
|
+
export type ClippingPlaneArray = ClippingPlane[];
|
|
525
526
|
export type Color = string;
|
|
526
527
|
export type ColoredBackground = {
|
|
527
528
|
color: Color;
|
|
@@ -529,6 +530,7 @@ export declare namespace WRAPIv2 {
|
|
|
529
530
|
startColor: Color;
|
|
530
531
|
endColor: Color;
|
|
531
532
|
};
|
|
533
|
+
export type CullfacePolicy = 'always' | 'never' | 'product' | 'surface';
|
|
532
534
|
export type Guid = string;
|
|
533
535
|
export type LabelArray = (Label | ImageLabel | TextLabel)[];
|
|
534
536
|
export type LabelTransformArray = LabelTransform[];
|
|
@@ -559,6 +561,20 @@ export declare namespace WRAPIv2 {
|
|
|
559
561
|
pov?: Pov;
|
|
560
562
|
sensor?: Guid | Sensor;
|
|
561
563
|
}
|
|
564
|
+
export interface ClippingPlane {
|
|
565
|
+
enabled?: boolean;
|
|
566
|
+
position?: Vector3D;
|
|
567
|
+
normal?: Vector3D;
|
|
568
|
+
sliceEnabled?: boolean;
|
|
569
|
+
sliceColor?: Color;
|
|
570
|
+
sliceThickness?: number;
|
|
571
|
+
}
|
|
572
|
+
export interface ClippingPlanes {
|
|
573
|
+
enabled?: boolean;
|
|
574
|
+
cullfacePolicy?: CullfacePolicy;
|
|
575
|
+
excludedSurfacesTags?: string[];
|
|
576
|
+
planes?: ClippingPlaneArray;
|
|
577
|
+
}
|
|
562
578
|
export interface DepthPolicy {
|
|
563
579
|
mode?: DepthPolicyMode;
|
|
564
580
|
zMin?: number;
|
|
@@ -687,6 +703,7 @@ export declare namespace WRAPIv2 {
|
|
|
687
703
|
mode?: RenderMode;
|
|
688
704
|
antialiasing?: boolean;
|
|
689
705
|
background?: boolean;
|
|
706
|
+
clippingPlanes?: ClippingPlanes;
|
|
690
707
|
compositing?: boolean;
|
|
691
708
|
enhancedTransparency?: boolean;
|
|
692
709
|
grid?: boolean;
|
package/dist/lib/index.js
CHANGED
|
@@ -20,34 +20,34 @@ class p {
|
|
|
20
20
|
}
|
|
21
21
|
static fit(t, e, i) {
|
|
22
22
|
const s = t.aspect, r = e.aspect;
|
|
23
|
-
let
|
|
23
|
+
let a = 0, n = 0;
|
|
24
24
|
switch (i) {
|
|
25
25
|
case "contain":
|
|
26
|
-
|
|
26
|
+
a = r < s ? e.width : e.height * s, n = r < s ? e.width / s : e.height;
|
|
27
27
|
break;
|
|
28
28
|
case "cover":
|
|
29
29
|
default:
|
|
30
|
-
|
|
30
|
+
a = r < s ? e.height * s : e.width, n = r < s ? e.height : e.width / s;
|
|
31
31
|
break;
|
|
32
32
|
case "fill":
|
|
33
|
-
|
|
33
|
+
a = e.width, n = e.height;
|
|
34
34
|
break;
|
|
35
35
|
}
|
|
36
|
-
const o = (e.height -
|
|
37
|
-
return new p(o,
|
|
36
|
+
const o = (e.height - n) / 2, u = (e.width - a) / 2;
|
|
37
|
+
return new p(o, u, a, n);
|
|
38
38
|
}
|
|
39
39
|
static project(t, e, i, s) {
|
|
40
|
-
const r = p.fit(t, e, i),
|
|
40
|
+
const r = p.fit(t, e, i), a = r.width / t.width, n = r.height / t.height;
|
|
41
41
|
return {
|
|
42
|
-
x: Math.round(r.left + s.x *
|
|
43
|
-
y: Math.round(r.top + s.y *
|
|
42
|
+
x: Math.round(r.left + s.x * a),
|
|
43
|
+
y: Math.round(r.top + s.y * n)
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
46
|
static unproject(t, e, i, s) {
|
|
47
|
-
const r = p.fit(t, e, i),
|
|
47
|
+
const r = p.fit(t, e, i), a = r.width / t.width, n = r.height / t.height;
|
|
48
48
|
return {
|
|
49
|
-
x: Math.round((s.x - r.left) /
|
|
50
|
-
y: Math.round((s.y - r.top) /
|
|
49
|
+
x: Math.round((s.x - r.left) / a),
|
|
50
|
+
y: Math.round((s.y - r.top) / n)
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
53
|
static getStandardAspectRatio(t, e) {
|
|
@@ -55,8 +55,8 @@ class p {
|
|
|
55
55
|
return 0;
|
|
56
56
|
const i = t / e;
|
|
57
57
|
if (t < e) {
|
|
58
|
-
const
|
|
59
|
-
return
|
|
58
|
+
const a = Math.abs(0.75 - i), n = Math.abs(9 / 16 - i);
|
|
59
|
+
return a < n ? 3 / 4 : 9 / 16;
|
|
60
60
|
}
|
|
61
61
|
const s = Math.abs(4 / 3 - i), r = Math.abs(16 / 9 - i);
|
|
62
62
|
return s < r ? 4 / 3 : 16 / 9;
|
|
@@ -73,7 +73,7 @@ class p {
|
|
|
73
73
|
return new b(Math.round(s * i), Math.round(s));
|
|
74
74
|
}
|
|
75
75
|
static getStandardQuality(t) {
|
|
76
|
-
return t <=
|
|
76
|
+
return t <= 720 ? 720 : 1080;
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
class U {
|
|
@@ -145,41 +145,41 @@ class w {
|
|
|
145
145
|
return t - e * Math.floor(t / e);
|
|
146
146
|
}
|
|
147
147
|
static perspectiveWithFovX(t, e, i, s, r) {
|
|
148
|
-
const
|
|
149
|
-
return this.perspectiveWithLeft(-
|
|
148
|
+
const a = Math.tan(t / 2), n = a / e;
|
|
149
|
+
return this.perspectiveWithLeft(-a, a, -n, n, i, s, r);
|
|
150
150
|
}
|
|
151
151
|
static perspectiveWithFovY(t, e, i, s, r) {
|
|
152
|
-
const
|
|
153
|
-
return this.perspectiveWithLeft(-
|
|
152
|
+
const a = i * Math.tan(t / 2), n = a * e;
|
|
153
|
+
return this.perspectiveWithLeft(-n, n, -a, a, i, s, r);
|
|
154
154
|
}
|
|
155
|
-
static perspectiveWithLeft(t, e, i, s, r,
|
|
156
|
-
|
|
157
|
-
const o = e + t,
|
|
158
|
-
return
|
|
155
|
+
static perspectiveWithLeft(t, e, i, s, r, a, n) {
|
|
156
|
+
n = n || new Float32Array(16);
|
|
157
|
+
const o = e + t, u = e - t, m = s + i, f = s - i, d = a - r;
|
|
158
|
+
return n[0] = 2 * r / u, n[1] = 0, n[2] = 0, n[3] = 0, n[4] = 0, n[5] = 2 * r / f, n[6] = 0, n[7] = 0, n[8] = o / u, n[9] = m / f, n[10] = -a / d, n[11] = -1, n[12] = 0, n[13] = 0, n[14] = -a * r / d, n[15] = 0, n;
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
const A = class A {
|
|
162
162
|
static initCubeFace(t, e, i) {
|
|
163
163
|
let s = [0, 0, 0];
|
|
164
|
-
const r = h.subtract(e, t),
|
|
164
|
+
const r = h.subtract(e, t), a = h.mulScalar([0, 1, 0], h.length(r)), n = h.mulScalar(h.normalize(h.cross(r, a)), h.length(r)), o = h.mulScalar(h.normalize(h.cross(a, n)), h.length(r));
|
|
165
165
|
switch (i) {
|
|
166
166
|
case "front":
|
|
167
|
-
e = h.add(t, o), s = h.normalize(
|
|
167
|
+
e = h.add(t, o), s = h.normalize(a);
|
|
168
168
|
break;
|
|
169
169
|
case "right":
|
|
170
|
-
e = h.add(t,
|
|
170
|
+
e = h.add(t, n), s = h.normalize(a);
|
|
171
171
|
break;
|
|
172
172
|
case "back":
|
|
173
|
-
e = h.subtract(t, o), s = h.normalize(
|
|
173
|
+
e = h.subtract(t, o), s = h.normalize(a);
|
|
174
174
|
break;
|
|
175
175
|
case "left":
|
|
176
|
-
e = h.subtract(t,
|
|
176
|
+
e = h.subtract(t, n), s = h.normalize(a);
|
|
177
177
|
break;
|
|
178
178
|
case "up":
|
|
179
|
-
e = h.add(t,
|
|
179
|
+
e = h.add(t, a), s = h.normalize(h.mulScalar(o, -1));
|
|
180
180
|
break;
|
|
181
181
|
case "down":
|
|
182
|
-
e = h.subtract(t,
|
|
182
|
+
e = h.subtract(t, a), s = h.normalize(o);
|
|
183
183
|
break;
|
|
184
184
|
}
|
|
185
185
|
return new A(e, t, s);
|
|
@@ -214,12 +214,12 @@ class B {
|
|
|
214
214
|
}
|
|
215
215
|
pointOfView(t) {
|
|
216
216
|
const e = c.rotationY(this.longitude), i = c.rotationX(-this.latitude), s = c.rotationZ(0), r = c.multiply(e, c.multiply(i, s));
|
|
217
|
-
let
|
|
218
|
-
n = c.transformPoint(r, n);
|
|
219
|
-
let a = [0, 1, 0];
|
|
217
|
+
let a = [0, 0, -1];
|
|
220
218
|
a = c.transformPoint(r, a);
|
|
221
|
-
|
|
222
|
-
|
|
219
|
+
let n = [0, 1, 0];
|
|
220
|
+
n = c.transformPoint(r, n);
|
|
221
|
+
const o = h.subtract(t, h.mulScalar(a, this.distance));
|
|
222
|
+
return new L(t, o, n);
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
225
|
class X {
|
|
@@ -315,7 +315,7 @@ const g = class g {
|
|
|
315
315
|
return Object.entries(t).filter(([e, i]) => i != null).map(([e, i]) => `${e}=${i}`).join("&");
|
|
316
316
|
}
|
|
317
317
|
static sceneParameters(t) {
|
|
318
|
-
const e = t.scene, i = e.length > 1 ? e.find((
|
|
318
|
+
const e = t.scene, i = e.length > 1 ? e.find((a) => a.accessory) : null, s = e.length > 1 ? e.find((a) => a.decor) : null, r = e.find((a) => a !== i && a !== s);
|
|
319
319
|
return {
|
|
320
320
|
databaseId: r.database,
|
|
321
321
|
configuration: r?.configuration,
|
|
@@ -416,7 +416,7 @@ const g = class g {
|
|
|
416
416
|
};
|
|
417
417
|
g.xmlRegex = /directUrl="([^"]*)"/g;
|
|
418
418
|
let S = g;
|
|
419
|
-
class
|
|
419
|
+
class l {
|
|
420
420
|
constructor(t) {
|
|
421
421
|
this.server = t;
|
|
422
422
|
}
|
|
@@ -482,29 +482,29 @@ class m {
|
|
|
482
482
|
}
|
|
483
483
|
async image(t) {
|
|
484
484
|
const e = {
|
|
485
|
-
scene:
|
|
485
|
+
scene: l.scene(t),
|
|
486
486
|
mode: {
|
|
487
487
|
image: {
|
|
488
488
|
camera: t.view.camera
|
|
489
489
|
}
|
|
490
490
|
},
|
|
491
|
-
renderParameters:
|
|
492
|
-
encoder:
|
|
491
|
+
renderParameters: l.renderParameters(t),
|
|
492
|
+
encoder: l.encoder(t)
|
|
493
493
|
};
|
|
494
|
-
return
|
|
494
|
+
return l.fetchFrame(`${this.server}/Snapshot`, e);
|
|
495
495
|
}
|
|
496
496
|
async vrCube(t) {
|
|
497
497
|
const e = {
|
|
498
|
-
scene:
|
|
498
|
+
scene: l.scene(t),
|
|
499
499
|
mode: {
|
|
500
500
|
vrCube: {
|
|
501
501
|
camera: t.view.camera
|
|
502
502
|
}
|
|
503
503
|
},
|
|
504
|
-
renderParameters:
|
|
505
|
-
encoder:
|
|
504
|
+
renderParameters: l.renderParameters(t),
|
|
505
|
+
encoder: l.encoder(t)
|
|
506
506
|
};
|
|
507
|
-
return e.renderParameters.width = Math.max(e.renderParameters.width, e.renderParameters.height), e.renderParameters.height = Math.max(e.renderParameters.width, e.renderParameters.height),
|
|
507
|
+
return e.renderParameters.width = Math.max(e.renderParameters.width, e.renderParameters.height), e.renderParameters.height = Math.max(e.renderParameters.width, e.renderParameters.height), l.fetchFrameArray(`${this.server}/Snapshot`, e);
|
|
508
508
|
}
|
|
509
509
|
async vrObject(t) {
|
|
510
510
|
let e;
|
|
@@ -531,16 +531,16 @@ class m {
|
|
|
531
531
|
}
|
|
532
532
|
};
|
|
533
533
|
const i = {
|
|
534
|
-
scene:
|
|
534
|
+
scene: l.scene(t),
|
|
535
535
|
mode: e,
|
|
536
|
-
renderParameters:
|
|
537
|
-
encoder:
|
|
536
|
+
renderParameters: l.renderParameters(t),
|
|
537
|
+
encoder: l.encoder(t)
|
|
538
538
|
};
|
|
539
|
-
return
|
|
539
|
+
return l.fetchFrameArray(`${this.server}/Snapshot`, i);
|
|
540
540
|
}
|
|
541
541
|
async animation(t) {
|
|
542
542
|
const e = {
|
|
543
|
-
scene:
|
|
543
|
+
scene: l.scene(t),
|
|
544
544
|
mode: {
|
|
545
545
|
animation: {
|
|
546
546
|
id: t.view.animation,
|
|
@@ -548,45 +548,45 @@ class m {
|
|
|
548
548
|
fps: t.view.fps
|
|
549
549
|
}
|
|
550
550
|
},
|
|
551
|
-
renderParameters:
|
|
552
|
-
encoder:
|
|
551
|
+
renderParameters: l.renderParameters(t),
|
|
552
|
+
encoder: l.encoder(t)
|
|
553
553
|
};
|
|
554
|
-
return
|
|
554
|
+
return l.fetchFrameArray(`${this.server}/Snapshot`, e);
|
|
555
555
|
}
|
|
556
556
|
async imageHotspots(t, e) {
|
|
557
557
|
const i = {
|
|
558
|
-
scene:
|
|
558
|
+
scene: l.scene(t),
|
|
559
559
|
mode: {
|
|
560
560
|
image: {
|
|
561
561
|
camera: t.view.camera
|
|
562
562
|
}
|
|
563
563
|
},
|
|
564
|
-
renderParameters:
|
|
564
|
+
renderParameters: l.renderParameters(t),
|
|
565
565
|
...this.hotspotsBody(e)
|
|
566
566
|
};
|
|
567
|
-
return await
|
|
567
|
+
return await l.fetchHotspots(`${this.server}/Hotspot`, i);
|
|
568
568
|
}
|
|
569
569
|
async imagePick(t, e) {
|
|
570
570
|
const i = {
|
|
571
|
-
scene:
|
|
571
|
+
scene: l.scene(t),
|
|
572
572
|
camera: t.view.camera,
|
|
573
|
-
renderParameters:
|
|
573
|
+
renderParameters: l.renderParameters(t),
|
|
574
574
|
positions: [e]
|
|
575
575
|
};
|
|
576
|
-
return await
|
|
576
|
+
return await l.fetchPick(`${this.server}/Pick`, i);
|
|
577
577
|
}
|
|
578
578
|
async vrCubeHotspots(t, e) {
|
|
579
579
|
const i = {
|
|
580
|
-
scene:
|
|
580
|
+
scene: l.scene(t),
|
|
581
581
|
mode: {
|
|
582
582
|
vrCube: {
|
|
583
583
|
camera: t.view.camera
|
|
584
584
|
}
|
|
585
585
|
},
|
|
586
|
-
renderParameters:
|
|
586
|
+
renderParameters: l.renderParameters(t),
|
|
587
587
|
...this.hotspotsBody(e)
|
|
588
588
|
};
|
|
589
|
-
return i.renderParameters.width = Math.max(i.renderParameters.width, i.renderParameters.height), i.renderParameters.height = Math.max(i.renderParameters.width, i.renderParameters.height), await
|
|
589
|
+
return i.renderParameters.width = Math.max(i.renderParameters.width, i.renderParameters.height), i.renderParameters.height = Math.max(i.renderParameters.width, i.renderParameters.height), await l.fetchHotspotsArray(`${this.server}/Hotspot`, i);
|
|
590
590
|
}
|
|
591
591
|
async vrObjectHotspots(t, e) {
|
|
592
592
|
let i;
|
|
@@ -613,12 +613,12 @@ class m {
|
|
|
613
613
|
}
|
|
614
614
|
};
|
|
615
615
|
const s = {
|
|
616
|
-
scene:
|
|
616
|
+
scene: l.scene(t),
|
|
617
617
|
mode: i,
|
|
618
|
-
renderParameters:
|
|
618
|
+
renderParameters: l.renderParameters(t),
|
|
619
619
|
...this.hotspotsBody(e)
|
|
620
620
|
};
|
|
621
|
-
return await
|
|
621
|
+
return await l.fetchHotspotsArray(`${this.server}/Hotspot`, s);
|
|
622
622
|
}
|
|
623
623
|
hotspotsBody(t) {
|
|
624
624
|
return {
|
|
@@ -634,13 +634,13 @@ class D {
|
|
|
634
634
|
this.webrender = new X();
|
|
635
635
|
break;
|
|
636
636
|
case "v1":
|
|
637
|
-
this.webrender = new S(t), this.webrenderV2 = new
|
|
637
|
+
this.webrender = new S(t), this.webrenderV2 = new l(t);
|
|
638
638
|
break;
|
|
639
639
|
case "v2":
|
|
640
|
-
this.webrender = new
|
|
640
|
+
this.webrender = new l(t), this.webrenderV2 = new l(t);
|
|
641
641
|
break;
|
|
642
642
|
default:
|
|
643
|
-
this.webrender = new S(t), this.webrenderV2 = new
|
|
643
|
+
this.webrender = new S(t), this.webrenderV2 = new l(t);
|
|
644
644
|
break;
|
|
645
645
|
}
|
|
646
646
|
this.delegate = i, this.loadingId = 0, this.loaded = 0, this.total = 0, this.databases = [], this.onLoadStart = i && i.onLoadStart ? i.onLoadStart : () => {
|
|
@@ -678,7 +678,7 @@ class D {
|
|
|
678
678
|
async loadImage(t, e) {
|
|
679
679
|
const i = new Image();
|
|
680
680
|
i.crossOrigin = location.protocol === "file:" && !D.isValidHttpUrl(t) ? null : "anonymous";
|
|
681
|
-
const s = new Promise((r,
|
|
681
|
+
const s = new Promise((r, a) => {
|
|
682
682
|
i.addEventListener(
|
|
683
683
|
"load",
|
|
684
684
|
() => {
|
|
@@ -687,8 +687,8 @@ class D {
|
|
|
687
687
|
{ once: !0 }
|
|
688
688
|
), i.addEventListener(
|
|
689
689
|
"error",
|
|
690
|
-
(
|
|
691
|
-
e === this.loadingId &&
|
|
690
|
+
(n) => {
|
|
691
|
+
e === this.loadingId && a(`${n.type} : ${t}`);
|
|
692
692
|
},
|
|
693
693
|
{ once: !0 }
|
|
694
694
|
);
|
|
@@ -697,27 +697,27 @@ class D {
|
|
|
697
697
|
}
|
|
698
698
|
loadImageFrames(t, e, i, s) {
|
|
699
699
|
this.total = t.length;
|
|
700
|
-
const r = new Array(t.length),
|
|
701
|
-
for (let
|
|
702
|
-
const
|
|
703
|
-
r[
|
|
700
|
+
const r = new Array(t.length), a = i || 0;
|
|
701
|
+
for (let n = 0, o = t.length; n < o; n += 1) {
|
|
702
|
+
const u = Math.ceil(n / 2) * (n % 2 === 0 ? 1 : -1), m = e ? w.mod(a + u, o) : n;
|
|
703
|
+
r[m] = this.loadImage(t[m], s);
|
|
704
704
|
}
|
|
705
705
|
return Promise.all(r).then(() => this.onLoadEnd(this.progress)).catch(() => {
|
|
706
706
|
}), r;
|
|
707
707
|
}
|
|
708
708
|
async loadVideo(t, e, i, s) {
|
|
709
709
|
t.loop = i;
|
|
710
|
-
const r = new Promise((
|
|
710
|
+
const r = new Promise((a, n) => {
|
|
711
711
|
t.addEventListener(
|
|
712
712
|
"canplaythrough",
|
|
713
713
|
() => {
|
|
714
|
-
s === this.loadingId && (this.loaded += 1, this.onLoadProgress(this.progress),
|
|
714
|
+
s === this.loadingId && (this.loaded += 1, this.onLoadProgress(this.progress), a());
|
|
715
715
|
},
|
|
716
716
|
{ once: !0 }
|
|
717
717
|
), t.addEventListener(
|
|
718
718
|
"error",
|
|
719
719
|
(o) => {
|
|
720
|
-
s === this.loadingId &&
|
|
720
|
+
s === this.loadingId && n(`${o.type} : ${e}`);
|
|
721
721
|
},
|
|
722
722
|
{ once: !0 }
|
|
723
723
|
);
|
|
@@ -725,24 +725,24 @@ class D {
|
|
|
725
725
|
return t.src = e, t.load(), r;
|
|
726
726
|
}
|
|
727
727
|
async loadVideoFrame(t, e, i, s, r) {
|
|
728
|
-
let
|
|
729
|
-
return new Promise((
|
|
730
|
-
const
|
|
728
|
+
let a = 0;
|
|
729
|
+
return new Promise((n, o) => {
|
|
730
|
+
const u = () => {
|
|
731
731
|
if (r !== this.loadingId) return;
|
|
732
|
-
if (
|
|
733
|
-
|
|
732
|
+
if (a !== s) {
|
|
733
|
+
a += 1;
|
|
734
734
|
return;
|
|
735
735
|
}
|
|
736
|
-
t.removeEventListener("seeked",
|
|
737
|
-
const
|
|
738
|
-
|
|
736
|
+
t.removeEventListener("seeked", u);
|
|
737
|
+
const m = document.createElement("canvas");
|
|
738
|
+
m.width = t.videoWidth, m.height = t.videoHeight, m.getContext("2d").drawImage(t, 0, 0);
|
|
739
739
|
const d = new Image();
|
|
740
|
-
d.src =
|
|
740
|
+
d.src = m.toDataURL(), n(d), this.loaded += 1, this.onLoadProgress(this.progress), s !== i - 1 && (t.currentTime += 1 / e);
|
|
741
741
|
};
|
|
742
|
-
t.addEventListener("seeked",
|
|
742
|
+
t.addEventListener("seeked", u), t.addEventListener(
|
|
743
743
|
"error",
|
|
744
|
-
(
|
|
745
|
-
r === this.loadingId && o(
|
|
744
|
+
(m) => {
|
|
745
|
+
r === this.loadingId && o(m);
|
|
746
746
|
},
|
|
747
747
|
{ once: !0 }
|
|
748
748
|
);
|
|
@@ -750,16 +750,16 @@ class D {
|
|
|
750
750
|
}
|
|
751
751
|
loadVideoFrames(t, e, i, s) {
|
|
752
752
|
this.total = e;
|
|
753
|
-
const r = new Array(e),
|
|
754
|
-
for (let
|
|
755
|
-
r[
|
|
756
|
-
return
|
|
753
|
+
const r = new Array(e), a = document.createElement("video");
|
|
754
|
+
for (let n = 0, o = e; n < o; n += 1)
|
|
755
|
+
r[n] = this.loadVideoFrame(a, i, e, n, s);
|
|
756
|
+
return a.addEventListener(
|
|
757
757
|
"canplaythrough",
|
|
758
758
|
() => {
|
|
759
|
-
s === this.loadingId && (
|
|
759
|
+
s === this.loadingId && (a.currentTime = 1 / i / 2);
|
|
760
760
|
},
|
|
761
761
|
{ once: !0 }
|
|
762
|
-
),
|
|
762
|
+
), a.src = t, a.load(), Promise.all(r).then(() => this.onLoadEnd(this.progress)).catch(() => {
|
|
763
763
|
}), r;
|
|
764
764
|
}
|
|
765
765
|
async loadImageHotspots(t, e) {
|
|
@@ -781,47 +781,48 @@ class D {
|
|
|
781
781
|
return this.webrenderV2 ? await this.webrenderV2.imagePick(await this.vrCubeFrameSnapshot(t, i), e) : Promise.reject(new Error("Picking only available with api V2"));
|
|
782
782
|
}
|
|
783
783
|
async convert(t) {
|
|
784
|
-
if (!this.webrenderV2 || this.webrender instanceof
|
|
784
|
+
if (!this.webrenderV2 || this.webrender instanceof l || !t.view.camera)
|
|
785
785
|
return t;
|
|
786
786
|
const e = t.scene.find((o) => !o.decor && !o.accessory);
|
|
787
787
|
if (!e)
|
|
788
788
|
return t;
|
|
789
789
|
let i = this.databases.find((o) => o.id === e.database);
|
|
790
790
|
(!i || !i.xmlDoc) && (i = await this.webrender.database(e.database), this.databases.push(i));
|
|
791
|
-
const s = t.view.camera
|
|
792
|
-
if (
|
|
793
|
-
return { ...t, view: { ...t.view, camera:
|
|
791
|
+
const s = t.view.camera.split("/"), r = s.length === 2 ? s[0] : void 0, a = s.length === 2 ? s[1] : s[0], n = i.getCameraId(a, r);
|
|
792
|
+
if (n)
|
|
793
|
+
return { ...t, view: { ...t.view, camera: n } };
|
|
794
794
|
{
|
|
795
|
-
const o = i.getCameraGroupId(
|
|
795
|
+
const o = i.getCameraGroupId(a);
|
|
796
796
|
return o ? { ...t, view: { ...t.view, cameraGroup: o } } : t;
|
|
797
797
|
}
|
|
798
798
|
}
|
|
799
799
|
async vrObjectFrameSnapshot(t, e, i) {
|
|
800
800
|
if (!this.webrenderV2)
|
|
801
801
|
return t;
|
|
802
|
-
const s = t.scene.find((
|
|
802
|
+
const s = t.scene.find((a) => !a.decor && !a.accessory);
|
|
803
803
|
if (!s)
|
|
804
804
|
return t;
|
|
805
|
-
let r = this.databases.find((
|
|
805
|
+
let r = this.databases.find((a) => a.id === s.database);
|
|
806
806
|
if (r || (r = await this.webrender.database(s.database), this.databases.push(r)), this.webrender instanceof S) {
|
|
807
807
|
if (!t.view.camera)
|
|
808
808
|
return t;
|
|
809
|
-
const
|
|
810
|
-
if (!n)
|
|
811
|
-
return t;
|
|
812
|
-
const a = r.getCameraGroupById(n);
|
|
809
|
+
const a = r.getCameraGroupId(t.view.camera);
|
|
813
810
|
if (!a)
|
|
814
811
|
return t;
|
|
815
|
-
const
|
|
812
|
+
const n = r.getCameraGroupById(a);
|
|
813
|
+
if (!n)
|
|
814
|
+
return t;
|
|
815
|
+
const o = n.cameras[e];
|
|
816
816
|
return o ? { ...t, view: { ...t.view, camera: o.id } } : t;
|
|
817
|
-
} else if (this.webrender instanceof
|
|
818
|
-
|
|
819
|
-
|
|
817
|
+
} else if (this.webrender instanceof l) {
|
|
818
|
+
const a = typeof t.view.camera == "string" ? t.view.camera : t.view.camera?.id;
|
|
819
|
+
if (a) {
|
|
820
|
+
const n = r.getCameraById(a);
|
|
820
821
|
if (!n)
|
|
821
822
|
return t;
|
|
822
|
-
const
|
|
823
|
-
|
|
824
|
-
const
|
|
823
|
+
const o = new B(n.pointOfView), u = 2 * Math.PI / i;
|
|
824
|
+
o.longitude += e * u % (2 * Math.PI);
|
|
825
|
+
const m = o.pointOfView(n.pointOfView.target);
|
|
825
826
|
return {
|
|
826
827
|
...t,
|
|
827
828
|
view: {
|
|
@@ -830,19 +831,19 @@ class D {
|
|
|
830
831
|
id: n.id,
|
|
831
832
|
pov: {
|
|
832
833
|
target: {
|
|
833
|
-
x:
|
|
834
|
-
y:
|
|
835
|
-
z:
|
|
834
|
+
x: m.target[0],
|
|
835
|
+
y: m.target[1],
|
|
836
|
+
z: m.target[2]
|
|
836
837
|
},
|
|
837
838
|
eye: {
|
|
838
|
-
x:
|
|
839
|
-
y:
|
|
840
|
-
z:
|
|
839
|
+
x: m.eye[0],
|
|
840
|
+
y: m.eye[1],
|
|
841
|
+
z: m.eye[2]
|
|
841
842
|
},
|
|
842
843
|
up: {
|
|
843
|
-
x:
|
|
844
|
-
y:
|
|
845
|
-
z:
|
|
844
|
+
x: m.up[0],
|
|
845
|
+
y: m.up[1],
|
|
846
|
+
z: m.up[2]
|
|
846
847
|
}
|
|
847
848
|
}
|
|
848
849
|
}
|
|
@@ -852,11 +853,11 @@ class D {
|
|
|
852
853
|
const n = r.getCameraGroupById(t.view.cameraGroup);
|
|
853
854
|
if (!n)
|
|
854
855
|
return t;
|
|
855
|
-
const
|
|
856
|
-
return
|
|
856
|
+
const o = n.cameras[e];
|
|
857
|
+
return o ? { ...t, view: { ...t.view, camera: o.id } } : t;
|
|
857
858
|
} else
|
|
858
859
|
return t;
|
|
859
|
-
else
|
|
860
|
+
} else
|
|
860
861
|
return t;
|
|
861
862
|
}
|
|
862
863
|
async vrCubeFrameSnapshot(t, e) {
|
|
@@ -868,36 +869,36 @@ class D {
|
|
|
868
869
|
return t;
|
|
869
870
|
let r;
|
|
870
871
|
if (this.webrender instanceof S) {
|
|
871
|
-
const o = t.view.camera.split("/"),
|
|
872
|
-
r = s.getCameraId(
|
|
873
|
-
} else this.webrender instanceof
|
|
872
|
+
const o = t.view.camera.split("/"), u = o.length === 2 ? o[0] : void 0, m = o.length === 2 ? o[1] : o[0];
|
|
873
|
+
r = s.getCameraId(m, u);
|
|
874
|
+
} else this.webrender instanceof l && (r = typeof t.view.camera == "string" ? t.view.camera : t.view.camera.id);
|
|
874
875
|
if (!r)
|
|
875
876
|
return t;
|
|
876
|
-
const
|
|
877
|
-
if (!
|
|
877
|
+
const a = s.getCameraById(r);
|
|
878
|
+
if (!a)
|
|
878
879
|
return t;
|
|
879
|
-
const
|
|
880
|
+
const n = L.initCubeFace(a.pointOfView.eye, a.pointOfView.target, e);
|
|
880
881
|
return {
|
|
881
882
|
...t,
|
|
882
883
|
view: {
|
|
883
884
|
...t.view,
|
|
884
885
|
camera: {
|
|
885
|
-
id:
|
|
886
|
+
id: a.id,
|
|
886
887
|
pov: {
|
|
887
888
|
target: {
|
|
888
|
-
x:
|
|
889
|
-
y:
|
|
890
|
-
z:
|
|
889
|
+
x: n.target[0],
|
|
890
|
+
y: n.target[1],
|
|
891
|
+
z: n.target[2]
|
|
891
892
|
},
|
|
892
893
|
eye: {
|
|
893
|
-
x:
|
|
894
|
-
y:
|
|
895
|
-
z:
|
|
894
|
+
x: n.eye[0],
|
|
895
|
+
y: n.eye[1],
|
|
896
|
+
z: n.eye[2]
|
|
896
897
|
},
|
|
897
898
|
up: {
|
|
898
|
-
x:
|
|
899
|
-
y:
|
|
900
|
-
z:
|
|
899
|
+
x: n.up[0],
|
|
900
|
+
y: n.up[1],
|
|
901
|
+
z: n.up[2]
|
|
901
902
|
}
|
|
902
903
|
},
|
|
903
904
|
lens: {
|
|
@@ -960,18 +961,18 @@ class J {
|
|
|
960
961
|
}
|
|
961
962
|
async load(t, e, i, s) {
|
|
962
963
|
let r = Promise.resolve();
|
|
963
|
-
const
|
|
964
|
-
|
|
964
|
+
const a = JSON.stringify(t);
|
|
965
|
+
a === this.snapshotHash && this.image ? r = r.then(() => this.canvas.draw(this.image, s, 0.05)) : r = r.then(
|
|
965
966
|
() => this.loader.loadImageSnapshot(t).then((o) => {
|
|
966
967
|
this.canvas.draw(o, s, 0.05), this.image = o;
|
|
967
968
|
})
|
|
968
969
|
);
|
|
969
|
-
const
|
|
970
|
-
return (
|
|
970
|
+
const n = JSON.stringify(e);
|
|
971
|
+
return (a !== this.snapshotHash || n !== this.hotspotsHash) && (e.length ? r = r.then(
|
|
971
972
|
() => this.loader.loadImageHotspots(t, e).then((o) => {
|
|
972
973
|
this.hotspotList = o;
|
|
973
974
|
})
|
|
974
|
-
) : this.hotspotList = []), this.hotspotsHash =
|
|
975
|
+
) : this.hotspotList = []), this.hotspotsHash = n, this.snapshotHash = a, r;
|
|
975
976
|
}
|
|
976
977
|
async pick(t, e) {
|
|
977
978
|
const i = new b(t.parameters.width, t.parameters.height), s = p.unproject(i, this.canvas.resolution, this.canvas.fit, e);
|
|
@@ -1072,8 +1073,8 @@ class Q {
|
|
|
1072
1073
|
get orientedPov() {
|
|
1073
1074
|
const t = h.normalize(h.cross(this.pov.up, this.pov.target)), e = new V(t, [0, 1, 0], this.pov.eye), i = c.identity();
|
|
1074
1075
|
c.multiply(i, e.localToGlobalMatrix, i), c.multiply(i, this.orientationMatrix, i), c.multiply(i, e.globalToLocalMatrix, i);
|
|
1075
|
-
const s = c.transformDirection(i, this.pov.target), r = this.pov.eye,
|
|
1076
|
-
return new L(s, r,
|
|
1076
|
+
const s = c.transformDirection(i, this.pov.target), r = this.pov.eye, a = c.transformDirection(i, this.pov.up);
|
|
1077
|
+
return new L(s, r, a);
|
|
1077
1078
|
}
|
|
1078
1079
|
reset() {
|
|
1079
1080
|
this.pov = this.initPov.clone(), this.fov = this.initFov;
|
|
@@ -1086,17 +1087,17 @@ class Q {
|
|
|
1086
1087
|
const e = {
|
|
1087
1088
|
x: t.x - this.previousPoint.x,
|
|
1088
1089
|
y: t.y - this.previousPoint.y
|
|
1089
|
-
}, i = w.accelerate(e.x, 1.3) / this.startSize.width * 0.2 * Math.PI * 1.5, s = w.accelerate(e.y, 1.3) / this.startSize.height * 0.2 * Math.PI, r = c.multiply(c.rotationY(i), c.rotationX(-s)),
|
|
1090
|
-
c.multiply(o,
|
|
1091
|
-
const
|
|
1092
|
-
h.cross(
|
|
1090
|
+
}, i = w.accelerate(e.x, 1.3) / this.startSize.width * 0.2 * Math.PI * 1.5, s = w.accelerate(e.y, 1.3) / this.startSize.height * 0.2 * Math.PI, r = c.multiply(c.rotationY(i), c.rotationX(-s)), a = h.normalize(h.cross(this.pov.up, this.pov.target)), n = new V(a, [0, 1, 0], this.pov.eye), o = c.identity();
|
|
1091
|
+
c.multiply(o, n.localToGlobalMatrix, o), c.multiply(o, r, o), c.multiply(o, n.globalToLocalMatrix, o);
|
|
1092
|
+
const u = c.transformPoint(o, this.pov.target), m = c.transformDirection(o, this.pov.up);
|
|
1093
|
+
h.cross(m, [0, 0, 1])[0] >= 0 && (this.pov.target = u, this.pov.up = m), this.previousPoint = t, this.onMotion();
|
|
1093
1094
|
}
|
|
1094
1095
|
end(t, e) {
|
|
1095
1096
|
this.isStarted = !1, e && (this.inertia.track(t), this.inertia.start());
|
|
1096
1097
|
}
|
|
1097
1098
|
orientation(t, e, i) {
|
|
1098
|
-
const s = w.degreesToRadians(window.orientation) || 0, r = w.degreesToRadians(t),
|
|
1099
|
-
c.rotateZ(o, this.initOrientation, o), c.rotateZ(o, r, o), c.rotateX(o,
|
|
1099
|
+
const s = w.degreesToRadians(window.orientation) || 0, r = w.degreesToRadians(t), a = w.degreesToRadians(-e), n = w.degreesToRadians(-i), o = c.rotationX(w.degreesToRadians(90));
|
|
1100
|
+
c.rotateZ(o, this.initOrientation, o), c.rotateZ(o, r, o), c.rotateX(o, a, o), c.rotateY(o, n, o), c.rotateZ(o, -s, o), this.orientationMatrix = o, this.onMotion();
|
|
1100
1101
|
}
|
|
1101
1102
|
}
|
|
1102
1103
|
var W = `precision mediump float;
|
|
@@ -1124,8 +1125,8 @@ void main() {
|
|
|
1124
1125
|
class K {
|
|
1125
1126
|
constructor(t, e, i, s) {
|
|
1126
1127
|
this.container = t, this.canvas = e, this.loader = i, this.images = [], this.hotspotsList = [[]];
|
|
1127
|
-
const r = new L([0, 0, 1], [0, 0, 0], [0, 1, 0]),
|
|
1128
|
-
c.transformDirection(
|
|
1128
|
+
const r = new L([0, 0, 1], [0, 0, 0], [0, 1, 0]), a = 60, n = c.rotationX(w.degreesToRadians(15));
|
|
1129
|
+
c.transformDirection(n, r.target, r.target), c.transformDirection(n, r.up, r.up), this.interaction = new Q(r, a, () => {
|
|
1129
1130
|
this.animationFrameId = requestAnimationFrame(this.render), this.onInteraction({
|
|
1130
1131
|
pov: this.interaction.pov.clone(),
|
|
1131
1132
|
fov: this.interaction.fov
|
|
@@ -1176,8 +1177,8 @@ class K {
|
|
|
1176
1177
|
const o = this.gl.getExtension("WEBGL_debug_renderer_info");
|
|
1177
1178
|
o && navigator.platform === "MacIntel" && navigator.userAgent.includes("Chrome") && this.gl.getParameter(o.UNMASKED_RENDERER_WEBGL).includes("OpenGL") && (t.parameters.width = Math.min(t.parameters.width, 1812), t.parameters.height = Math.min(t.parameters.height, 1812));
|
|
1178
1179
|
}
|
|
1179
|
-
const
|
|
1180
|
-
|
|
1180
|
+
const a = JSON.stringify(t);
|
|
1181
|
+
a === this.snapshotHash ? r = r.then(() => (this.animationFrameId = requestAnimationFrame(this.render), Promise.resolve())) : (this.images = [], this.animationFrameId = requestAnimationFrame(this.render), r = r.then(
|
|
1181
1182
|
() => this.loader.loadVRCubeSnapshot(t).then((o) => {
|
|
1182
1183
|
this.images = o, P.createTexture(
|
|
1183
1184
|
this.gl,
|
|
@@ -1196,21 +1197,21 @@ class K {
|
|
|
1196
1197
|
],
|
|
1197
1198
|
src: o
|
|
1198
1199
|
},
|
|
1199
|
-
(
|
|
1200
|
-
|
|
1200
|
+
(u, m) => {
|
|
1201
|
+
u || (i && this.interaction.reset(), this.uniforms.u_mix = s ? 0 : 1, this.uniforms.u_texture_back = this.uniforms.u_texture, this.uniforms.u_texture = m, this.animationFrameId = requestAnimationFrame(this.render));
|
|
1201
1202
|
}
|
|
1202
1203
|
);
|
|
1203
1204
|
})
|
|
1204
1205
|
));
|
|
1205
|
-
const
|
|
1206
|
-
return (
|
|
1206
|
+
const n = JSON.stringify(e);
|
|
1207
|
+
return (a !== this.snapshotHash || n !== this.hotspotsHash) && (e.length ? r = r.then(
|
|
1207
1208
|
() => this.loader.loadVRCubeHotspots(t, e).then((o) => {
|
|
1208
1209
|
this.hotspotsList = o;
|
|
1209
1210
|
})
|
|
1210
|
-
) : this.hotspotsList = [[]]), this.hotspotsHash =
|
|
1211
|
+
) : this.hotspotsList = [[]]), this.hotspotsHash = n, this.snapshotHash = a, r;
|
|
1211
1212
|
}
|
|
1212
1213
|
async pick(t, e) {
|
|
1213
|
-
const i = this.canvas.element.clientWidth, s = this.canvas.element.clientHeight, r = e.x,
|
|
1214
|
+
const i = this.canvas.element.clientWidth, s = this.canvas.element.clientHeight, r = e.x, a = s - e.y, n = 2 * r / i - 1, o = 2 * a / s - 1, u = [n, o, 0], m = this.modelViewProjectionMatrix, f = c.inverse(m), d = h.normalize(c.transformPoint(f, u)), T = Math.max(Math.abs(d[0]), Math.abs(d[1]), Math.abs(d[2]));
|
|
1214
1215
|
let F = "";
|
|
1215
1216
|
Math.abs(d[0]) === T ? F = d[0] > 0 ? "XPOS" : "XNEG" : Math.abs(d[1]) === T ? F = d[1] > 0 ? "YPOS" : "YNEG" : F = d[2] > 0 ? "ZPOS" : "ZNEG";
|
|
1216
1217
|
let x = 0, M = 0, E = "";
|
|
@@ -1249,33 +1250,33 @@ class K {
|
|
|
1249
1250
|
const r = this.hotspotsList.findIndex((R) => R[s].visibility !== "OutOfFrustum");
|
|
1250
1251
|
if (r === -1)
|
|
1251
1252
|
continue;
|
|
1252
|
-
const
|
|
1253
|
-
let
|
|
1253
|
+
const a = { ...this.hotspotsList[r][s] }, n = a.position2D.x / this.images[0].width, o = a.position2D.y / this.images[0].height;
|
|
1254
|
+
let u = 0, m = 0, f = 0;
|
|
1254
1255
|
switch (r) {
|
|
1255
1256
|
case 0:
|
|
1256
|
-
this.pov.target[2] < 0 && (
|
|
1257
|
+
this.pov.target[2] < 0 && (a.visibility = "OutOfFrustum"), u = 2 * n - 1, m = 1 - 2 * o, f = 1;
|
|
1257
1258
|
break;
|
|
1258
1259
|
case 1:
|
|
1259
|
-
this.pov.target[0] > 0 && (
|
|
1260
|
+
this.pov.target[0] > 0 && (a.visibility = "OutOfFrustum"), u = 1, m = 1 - 2 * o, f = 1 - 2 * n;
|
|
1260
1261
|
break;
|
|
1261
1262
|
case 2:
|
|
1262
|
-
this.pov.target[2] > 0 && (
|
|
1263
|
+
this.pov.target[2] > 0 && (a.visibility = "OutOfFrustum"), u = 1 - 2 * n, m = 1 - 2 * o, f = -1;
|
|
1263
1264
|
break;
|
|
1264
1265
|
case 3:
|
|
1265
|
-
this.pov.target[0] < 0 && (
|
|
1266
|
+
this.pov.target[0] < 0 && (a.visibility = "OutOfFrustum"), u = -1, m = 1 - 2 * o, f = 2 * n - 1;
|
|
1266
1267
|
break;
|
|
1267
1268
|
case 4:
|
|
1268
|
-
this.pov.target[1] < 0 && (
|
|
1269
|
+
this.pov.target[1] < 0 && (a.visibility = "OutOfFrustum"), u = 2 * n - 1, m = 1, f = 2 * o - 1;
|
|
1269
1270
|
break;
|
|
1270
1271
|
case 5:
|
|
1271
|
-
this.pov.target[1] > 0 && (
|
|
1272
|
+
this.pov.target[1] > 0 && (a.visibility = "OutOfFrustum"), u = 2 * n - 1, m = -1, f = 1 - 2 * o;
|
|
1272
1273
|
break;
|
|
1273
1274
|
}
|
|
1274
|
-
const d = h.normalize([
|
|
1275
|
+
const d = h.normalize([u, m, f]), T = c.transformPoint(i, d), F = this.canvas.element.clientWidth, x = this.canvas.element.clientHeight, M = 0.5 * F * (T[0] + 1), E = 0.5 * x * (T[1] + 1), O = {
|
|
1275
1276
|
x: Math.round(M),
|
|
1276
1277
|
y: Math.round(x - E)
|
|
1277
|
-
}, G = new b(F, x), z = p.contains(G, O) ?
|
|
1278
|
-
t.push({ ...
|
|
1278
|
+
}, G = new b(F, x), z = p.contains(G, O) ? a.visibility : "OutOfFrustum";
|
|
1279
|
+
t.push({ ...a, position2D: O, visibility: z });
|
|
1279
1280
|
}
|
|
1280
1281
|
return t;
|
|
1281
1282
|
}
|
|
@@ -1283,8 +1284,8 @@ class K {
|
|
|
1283
1284
|
return this.canvas.element.toDataURL(t, e);
|
|
1284
1285
|
}
|
|
1285
1286
|
get modelViewProjectionMatrix() {
|
|
1286
|
-
const t = this.canvas.element.clientWidth, e = this.canvas.element.clientHeight, i = t > e ? t / e : e / t, s = p.getStandardAspectRatio(t, e), r = this.interaction.fov * (s / i),
|
|
1287
|
-
return c.multiply(c.multiply(
|
|
1287
|
+
const t = this.canvas.element.clientWidth, e = this.canvas.element.clientHeight, i = t > e ? t / e : e / t, s = p.getStandardAspectRatio(t, e), r = this.interaction.fov * (s / i), a = c.setAxis(c.identity(), [-1, 0, 0], 0), n = t > e ? w.perspectiveWithFovY(r, t / e, 0.5, 100) : w.perspectiveWithFovX(r, t / e, 0.5, 100), o = this.interaction.orientedPov, u = c.inverse(c.lookAt(o.eye, o.target, o.up));
|
|
1288
|
+
return c.multiply(c.multiply(n, u), a);
|
|
1288
1289
|
}
|
|
1289
1290
|
render() {
|
|
1290
1291
|
this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height), this.uniforms.u_mvpi = c.inverse(this.modelViewProjectionMatrix), this.gl.useProgram(this.programInfo.program), P.setBuffersAndAttributes(this.gl, this.programInfo, this.quad), P.setUniforms(this.programInfo, this.uniforms), P.drawBufferInfo(this.gl, this.quad), this.uniforms.u_mix < 1 && (this.uniforms.u_mix = Math.min(this.uniforms.u_mix + 0.05, 1), this.animationFrameId = requestAnimationFrame(this.render));
|
|
@@ -1349,14 +1350,14 @@ class tt {
|
|
|
1349
1350
|
const s = w.accelerate(t.x - this.startPoint.x, 1.3) / this.startSize.width * (this.frames / 4);
|
|
1350
1351
|
let r = this.startPosition.x - Math.round(s);
|
|
1351
1352
|
r = this.loop ? w.mod(r, this.frames) : Math.max(0, Math.min(r, this.frames - 1)), r !== this.position.x && (this.position.x = r, this.onMotion());
|
|
1352
|
-
const
|
|
1353
|
-
Math.max(...this.lastPoints.map((o) => o.x)) -
|
|
1353
|
+
const a = Math.min(...this.lastPoints.map((o) => o.x));
|
|
1354
|
+
Math.max(...this.lastPoints.map((o) => o.x)) - a > i && (this.startPoint.y = t.y, this.startPosition.y = this.position.y);
|
|
1354
1355
|
} else {
|
|
1355
1356
|
const s = w.accelerate(t.y - this.startPoint.y, 1.7) / this.startSize.height * (this.rows / 4);
|
|
1356
1357
|
let r = this.startPosition.y + Math.round(s);
|
|
1357
1358
|
r = Math.max(0, Math.min(r, this.rows - 1)), r !== this.position.y && (this.position.y = r, this.onMotion());
|
|
1358
|
-
const
|
|
1359
|
-
Math.max(...this.lastPoints.map((o) => o.y)) -
|
|
1359
|
+
const a = Math.min(...this.lastPoints.map((o) => o.y));
|
|
1360
|
+
Math.max(...this.lastPoints.map((o) => o.y)) - a > i && (this.startPoint.x = t.x, this.startPosition.x = this.position.x);
|
|
1360
1361
|
}
|
|
1361
1362
|
}
|
|
1362
1363
|
end(t, e) {
|
|
@@ -1406,24 +1407,24 @@ class k {
|
|
|
1406
1407
|
async load(t, e, i, s) {
|
|
1407
1408
|
let r = Promise.resolve();
|
|
1408
1409
|
i && this.interaction.reset();
|
|
1409
|
-
const
|
|
1410
|
-
|
|
1410
|
+
const a = JSON.stringify(t);
|
|
1411
|
+
a === this.snapshotHash && this.image ? r = r.then(() => this.canvas.draw(this.image, s, 0.05)) : (this.images = [], r = r.then(
|
|
1411
1412
|
() => this.loader.loadVRObjectSnapshot(t, this.interaction.positionIndex).then((o) => {
|
|
1412
|
-
const
|
|
1413
|
-
return this.images = new Array(
|
|
1414
|
-
|
|
1413
|
+
const u = o.length;
|
|
1414
|
+
return this.images = new Array(u), this.interaction.frames = t.view.frames ?? t.view.panFrames ?? this.frames, this.interaction.rows = u / this.interaction.frames, this.interaction.loop = !!t.view.loop, i && this.interaction.reset(), o.forEach((m, f) => {
|
|
1415
|
+
m.then((d) => {
|
|
1415
1416
|
this.images[f] = d, d === this.image && this.canvas.draw(this.image, s, 0.05);
|
|
1416
1417
|
}).catch(() => {
|
|
1417
1418
|
});
|
|
1418
1419
|
}), o[this.interaction.positionIndex].then(() => Promise.resolve());
|
|
1419
1420
|
})
|
|
1420
1421
|
));
|
|
1421
|
-
const
|
|
1422
|
-
return (
|
|
1422
|
+
const n = JSON.stringify(e);
|
|
1423
|
+
return (a !== this.snapshotHash || n !== this.hotspotsHash) && (e.length ? r = r.then(
|
|
1423
1424
|
() => this.loader.loadVRObjectHotspots(t, e).then((o) => {
|
|
1424
1425
|
this.hotspotsList = o;
|
|
1425
1426
|
})
|
|
1426
|
-
) : this.hotspotsList = [[]]), this.hotspotsHash =
|
|
1427
|
+
) : this.hotspotsList = [[]]), this.hotspotsHash = n, this.snapshotHash = a, r;
|
|
1427
1428
|
}
|
|
1428
1429
|
async pick(t, e) {
|
|
1429
1430
|
const i = new b(t.parameters.width, t.parameters.height), s = p.unproject(i, this.canvas.resolution, this.canvas.fit, e);
|
|
@@ -1518,7 +1519,7 @@ class et {
|
|
|
1518
1519
|
onDeviceOrientation(t) {
|
|
1519
1520
|
}
|
|
1520
1521
|
}
|
|
1521
|
-
class
|
|
1522
|
+
class at {
|
|
1522
1523
|
constructor(t, e) {
|
|
1523
1524
|
this.checkResize = this.checkResize.bind(this), this.onDeviceOrientation = this.onDeviceOrientation.bind(this), this.onResize = this.onResize.bind(this), this.onMouseDown = this.onMouseDown.bind(this), this.onMouseMove = this.onMouseMove.bind(this), this.onMouseUp = this.onMouseUp.bind(this), this.onMouseEnter = this.onMouseEnter.bind(this), this.onTouchStart = this.onTouchStart.bind(this), this.onTouchMove = this.onTouchMove.bind(this), this.onTouchEnd = this.onTouchEnd.bind(this), this.onLoadStart = this.onLoadStart.bind(this), this.onLoadProgress = this.onLoadProgress.bind(this), this.onLoadEnd = this.onLoadEnd.bind(this), this.onLoadError = this.onLoadError.bind(this), this.onHotspotsChange = this.onHotspotsChange.bind(this), this.onVrcubeInteraction = this.onVrcubeInteraction.bind(this), this.onVrobjectInteraction = this.onVrobjectInteraction.bind(this), this.options = {
|
|
1524
1525
|
server: "localhost",
|
|
@@ -1753,7 +1754,7 @@ var j;
|
|
|
1753
1754
|
})(v.SurfacesFilterMode || (v.SurfacesFilterMode = {}));
|
|
1754
1755
|
})(j || (j = {}));
|
|
1755
1756
|
export {
|
|
1756
|
-
|
|
1757
|
+
at as Viewer,
|
|
1757
1758
|
j as WRAPIv2,
|
|
1758
1759
|
J as WidgetImage,
|
|
1759
1760
|
K as WidgetVRCube,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lumiscaphe/viewer",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "Lumiscaphe 3D Viewer",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/lib/index.cjs",
|
|
@@ -21,18 +21,18 @@
|
|
|
21
21
|
"twgl.js": "~7.0.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@types/debounce-promise": "~3.1.
|
|
24
|
+
"@types/debounce-promise": "~3.1.0",
|
|
25
25
|
"@types/node": "~24.0.0",
|
|
26
26
|
"@types/regression": "~2.0.0",
|
|
27
27
|
"eslint": "~9.39.0",
|
|
28
28
|
"husky": "~9.1.0",
|
|
29
|
-
"prettier": "~3.
|
|
29
|
+
"prettier": "~3.8.0",
|
|
30
30
|
"typescript": "~5.9.0",
|
|
31
|
-
"typescript-eslint": "~8.
|
|
31
|
+
"typescript-eslint": "~8.60.0",
|
|
32
32
|
"vite": "~7.3.0",
|
|
33
33
|
"vite-plugin-css-injected-by-js": "~3.5.0",
|
|
34
34
|
"vite-plugin-dts": "~4.5.0",
|
|
35
35
|
"vite-plugin-eslint": "~1.8.0",
|
|
36
|
-
"vite-plugin-glsl": "~1.
|
|
36
|
+
"vite-plugin-glsl": "~1.6.0"
|
|
37
37
|
}
|
|
38
38
|
}
|