@onirix/ar-engine-sdk 1.6.1 → 1.6.3
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/CHANGELOG.md +12 -0
- package/README.md +1 -0
- package/dist/onirix_native_sdk.js +1 -1
- package/dist/ox-sdk.esm.js +3 -3
- package/dist/worker-a.js +1 -1
- package/dist/worker-b.js +1 -1
- package/package.json +1 -1
package/dist/ox-sdk.esm.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const TrackingMode={Image:1,QRCode:2,Surface:3,Spatial:4},SurfaceMode={WebXR:1,SLAM:2,Gyroscope:3},Events={OnDetected:1,OnPose:2,OnLost:3,OnResize:4,OnTouch:5,OnHitTestResult:6,OnKeyFrame:7,OnStatusChange:8,OnSessionEnd:9,OnFrame:10},DefaultConfig={useVocabulary:!1,forceCompatWorldTracking:!1,forceRotationOnlyTracking:!1,debug:!1,cameraAccess:!1};
|
|
4
4
|
|
|
5
|
-
class InternalError extends Error{constructor(r){super(r),this.name="INTERNAL_ERROR";}}class LicenseError extends Error{constructor(r){super(r),this.name="LICENSE_ERROR";}}class CameraError extends Error{constructor(r){super(r),this.name="CAMERA_ERROR";}}class SensorsError extends Error{constructor(r){super(r),this.name="SENSORS_ERROR";}}
|
|
5
|
+
class InternalError extends Error{constructor(r){super(r),this.name="INTERNAL_ERROR";}}class LicenseError extends Error{constructor(r){super(r),this.name="LICENSE_ERROR";}}class CameraError extends Error{constructor(r){super(r),this.name="CAMERA_ERROR";}}class SensorsError extends Error{constructor(r){super(r),this.name="SENSORS_ERROR";}}class ReconstructionPendingError extends Error{constructor(r){super(r),this.name="RECONSTRUCTION_PENDING_ERROR";}}
|
|
6
6
|
|
|
7
7
|
const BROWSER_ALIASES_MAP={"Amazon Silk":"amazon_silk","Android Browser":"android",Bada:"bada",BlackBerry:"blackberry",Chrome:"chrome",Chromium:"chromium",Electron:"electron",Epiphany:"epiphany",Firefox:"firefox",Focus:"focus",Generic:"generic","Google Search":"google_search",Googlebot:"googlebot","Internet Explorer":"ie","K-Meleon":"k_meleon",Maxthon:"maxthon","Microsoft Edge":"edge","MZ Browser":"mz","NAVER Whale Browser":"naver",Opera:"opera","Opera Coast":"opera_coast",PhantomJS:"phantomjs",Puffin:"puffin",QupZilla:"qupzilla",QQ:"qq",QQLite:"qqlite",Safari:"safari",Sailfish:"sailfish","Samsung Internet for Android":"samsung_internet",SeaMonkey:"seamonkey",Sleipnir:"sleipnir",Swing:"swing",Tizen:"tizen","UC Browser":"uc",Vivaldi:"vivaldi","WebOS Browser":"webos",WeChat:"wechat","Yandex Browser":"yandex",Roku:"roku"};const BROWSER_MAP={amazon_silk:"Amazon Silk",android:"Android Browser",bada:"Bada",blackberry:"BlackBerry",chrome:"Chrome",chromium:"Chromium",electron:"Electron",epiphany:"Epiphany",firefox:"Firefox",focus:"Focus",generic:"Generic",googlebot:"Googlebot",google_search:"Google Search",ie:"Internet Explorer",k_meleon:"K-Meleon",maxthon:"Maxthon",edge:"Microsoft Edge",mz:"MZ Browser",naver:"NAVER Whale Browser",opera:"Opera",opera_coast:"Opera Coast",phantomjs:"PhantomJS",puffin:"Puffin",qupzilla:"QupZilla",qq:"QQ Browser",qqlite:"QQ Browser Lite",safari:"Safari",sailfish:"Sailfish",samsung_internet:"Samsung Internet for Android",seamonkey:"SeaMonkey",sleipnir:"Sleipnir",swing:"Swing",tizen:"Tizen",uc:"UC Browser",vivaldi:"Vivaldi",webos:"WebOS Browser",wechat:"WeChat",yandex:"Yandex Browser"};const PLATFORMS_MAP={tablet:"tablet",mobile:"mobile",desktop:"desktop",tv:"tv"};const OS_MAP={WindowsPhone:"Windows Phone",Windows:"Windows",MacOS:"macOS",iOS:"iOS",Android:"Android",WebOS:"WebOS",BlackBerry:"BlackBerry",Bada:"Bada",Tizen:"Tizen",Linux:"Linux",ChromeOS:"Chrome OS",PlayStation4:"PlayStation 4",Roku:"Roku"};const ENGINE_MAP={EdgeHTML:"EdgeHTML",Blink:"Blink",Trident:"Trident",Presto:"Presto",Gecko:"Gecko",WebKit:"WebKit"};
|
|
8
8
|
|
|
@@ -38,7 +38,7 @@ class Quaternion{constructor(t=0,s=0,i=0,h=1){this.x=t,this.y=s,this.z=i,this.w=
|
|
|
38
38
|
|
|
39
39
|
const mat4RotationZ90CCW=(new Matrix4).set(0,1,0,0,-1,0,0,0,0,0,1,0,0,0,0,1),mat4RotationZ90CW=(new Matrix4).set(0,-1,0,0,1,0,0,0,0,0,1,0,0,0,0,1),mat4RotationX90CW=(new Matrix4).set(1,0,0,0,0,0,1,0,0,-1,0,0,0,0,0,1),mat3RotationX90CCW=(new Matrix3).set(1,0,0,0,0,1,0,-1,0),mat3RotationZ90CW=(new Matrix3).set(0,-1,0,1,0,0,0,0,1);
|
|
40
40
|
|
|
41
|
-
class NativeManager{constructor(t,i,e,a){this.uiManager=t,this.deviceManager=i,this.workerManager=e,this.indexedDBManager=a;}async init(t,i){try{let e;try{e=await getFileFromIndexedDB("SDK_1.6.
|
|
41
|
+
class NativeManager{constructor(t,i,e,a){this.uiManager=t,this.deviceManager=i,this.workerManager=e,this.indexedDBManager=a;}async init(t,i){try{let e;try{e=await getFileFromIndexedDB("SDK_1.6.3");}catch(t){let i=await fetch(new URL("./onirix_native_sdk.js",import.meta.url).href);e=await i.text(),await this.indexedDBManager.saveFileToIndexedDB("SDK_1.6.3",e);}let a=URL.createObjectURL(new Blob([e],{type:"text/javascript"}));const{default:r}=await import(/* webpackIgnore: true, webpackMode: "lazy" */a);let s,n,o;if(this.useVocabulary=i.useVocabulary,this.host=i.host??"https://studio.onirix.com",this.useVocabulary&&(s=await this.indexedDBManager.getFromCacheOrFetch("orb.fbow","https://sdk.onirix.com/common/orb.fbow")),i.mode===TrackingMode.Spatial){if(n=await fetch(`${this.host}/api/projects/self/targets/${i.sceneOid}/osf?token=${t}`),!n.ok)throw new ReconstructionPendingError(`Could not get Onirix Spatial File. Server responded with ${n.status}`);const e=await n.arrayBuffer();o=new Uint8Array(e),await this.workerManager.createWorkers();}this.nativeSDK=await r({preRun:e=>{i.mode==TrackingMode.Spatial?e.FS_createDataFile("/","scene.osf",o,!0,!0,!0):i.mode===TrackingMode.Image?(this.useVocabulary&&e.FS_createDataFile("/","orb.fbow",s,!0,!0,!0),e.FS_createPreloadedFile("/","classifier.otf",`${this.host}/api/projects/self/targets/otf?token=${t}`,!0,!1)):i.mode===TrackingMode.Surface&&this.useVocabulary&&e.FS_createDataFile("/","orb.fbow",s,!0,!0,!0);}}),this.buffer=this.nativeSDK._malloc(1228800),this.imageBuffer=this.nativeSDK._malloc(1228800),this.imuAccData=this.nativeSDK._malloc(32),this.imuRotData=this.nativeSDK._malloc(72),this.cameraParamsStruct=this.nativeSDK._malloc(40),this.frameLayoutStruct=this.nativeSDK._malloc(28),this.nativeSDK.HEAPU32[this.cameraParamsStruct/4+0]=640,this.nativeSDK.HEAPU32[this.cameraParamsStruct/4+1]=480,this.nativeSDK.HEAPF64[this.cameraParamsStruct/8+1]=468,this.nativeSDK.HEAPF64[this.cameraParamsStruct/8+2]=468,this.nativeSDK.HEAPF64[this.cameraParamsStruct/8+3]=320,this.nativeSDK.HEAPF64[this.cameraParamsStruct/8+4]=240,i.debug&&this.nativeSDK._OX_SetLogCallback(this.nativeSDK.addFunction((t=>{console.log(this.nativeSDK.UTF8ToString(t));}),"vi"));}catch(t){throw t instanceof ReconstructionPendingError?t:new InternalError(t)}await this.checkLicense(t);}async checkLicense(t){try{const i=this.getStringBuffer(this.host),e=this.getStringBuffer(t),a=this.getStringBuffer(window.location.hostname),r=this.getStringBuffer(this.deviceManager.platform),s=this.getStringBuffer(this.deviceManager.device),n=await new Promise(((t,n)=>{this.nativeSDK._OX_SetLicense([i],[e],[a],[r],[s],this.nativeSDK.addFunction((i=>t(i)),"vi"));}));if(this.releaseStringBuffer(i),this.releaseStringBuffer(e),this.releaseStringBuffer(a),this.releaseStringBuffer(r),this.releaseStringBuffer(s),!n)throw new LicenseError("Invalid license")}catch(t){throw new LicenseError(t)}}startImageTracking(t,i,e){if(this.onDetected=t,this.onPose=i,this.onLost=e,this.useVocabulary){const t=this.getStringBuffer("orb.fbow");this.nativeSDK._OX_Initialize(this.cameraParamsStruct,[t]),this.releaseStringBuffer(t);}else this.nativeSDK._OX_Initialize(this.cameraParamsStruct,"");let a=this.getStringBuffer("classifier.otf");this.nativeSDK._OX_LoadImageClassifier([a]),this.releaseStringBuffer(a),this.nativeSDK._OX_StartImageDetection(2,this.nativeSDK.addFunction((t=>this.onDetected(this.nativeSDK.UTF8ToString(t))),"vi"),this.nativeSDK.addFunction((t=>{const i=this.nativeSDK.HEAPF64.subarray(t/8,t/8+16);let e=(new Matrix4).fromArray(i);e.multiply(mat4RotationX90CW),e.invert(),this.uiManager.isPortrait()?(e.multiply(mat4RotationZ90CCW),this.onPose(e.toArray())):this.onPose(e.toArray());}),"vi"),this.nativeSDK.addFunction((t=>this.onLost(this.nativeSDK.UTF8ToString(t))),"vi"));}startQRCodeTracking(t,i,e){this.onDetected=t,this.onPose=i,this.onLost=e,this.nativeSDK._OX_Initialize(this.cameraParamsStruct,""),this.nativeSDK._OX_StartQRCodeDetection(2,this.nativeSDK.addFunction((t=>this.onDetected(this.nativeSDK.UTF8ToString(t))),"vi"),this.nativeSDK.addFunction((t=>{const i=this.nativeSDK.HEAPF64.subarray(t/8,t/8+16);let e=(new Matrix4).fromArray(i);e.multiply(mat4RotationX90CW),e.invert(),this.uiManager.isPortrait()?(e.multiply(mat4RotationZ90CCW),this.onPose(e.toArray())):this.onPose(e.toArray());}),"vi"),this.nativeSDK.addFunction((t=>this.onLost(this.nativeSDK.UTF8ToString(t))),"vi"));}startSLAM(t,i,e){if(this.onPose=t,this.onKeyFrame=i,this.onStatusChange=e,this.useVocabulary){const t=this.getStringBuffer("orb.fbow");this.nativeSDK._OX_Initialize(this.cameraParamsStruct,[t]),this.releaseStringBuffer(t);}else this.nativeSDK._OX_Initialize(this.cameraParamsStruct,"");this.nativeSDK._OX_StartSLAM(this.nativeSDK.addFunction((t=>{const i=this.nativeSDK.HEAPF64.subarray(t/8,t/8+16);let e=(new Matrix4).fromArray(i);e.invert(),this.uiManager.isPortrait()?(e.multiply(mat4RotationZ90CCW),this.onPose(e.toArray())):this.onPose(e.toArray());}),"vi"),null!=this.onKeyFrame?this.nativeSDK.addFunction((()=>this.onKeyFrame()),"v"):null,this.nativeSDK.addFunction(((t,i)=>{this.onStatusChange([this.nativeSDK.UTF8ToString(t),this.nativeSDK.UTF8ToString(i)]);}),"vii"));}xrRelocation(t){if(this.lastXrPose){let i=(new Matrix4).fromArray(this.lastXrPose),e=(new Matrix4).fromArray(t.elements);this.xrTransform=e.multiply(i.invert());}}slamRelocation(t){if(this.lastSlamPose){let i=(new Matrix4).fromArray(this.lastSlamPose),e=(new Matrix4).fromArray(t.elements);this.slamTransform=e.multiply(i.invert());}}startSpatialTracking(t,i,e){this.onDetected=t,e||(this.onPose=i),this.nativeSDK._OX_Initialize(this.cameraParamsStruct,""),this.nativeSDK._OX_StartSpatialTracking(this.nativeSDK.addFunction((t=>{e||(this.spatialLocated=!0),this.onDetected("");}),"vi"),this.nativeSDK.addFunction((t=>{const i=this.nativeSDK.HEAPF64.subarray(t/8,t/8+16);let a=(new Matrix4).fromArray(i);a.invert(),this.uiManager.isPortrait()&&a.multiply(e?mat4RotationZ90CW:mat4RotationZ90CCW),e?(this.xrRelocation(a),this.onDetected("")):this.onPose(a.toArray());}),"vi"),!e);let a=this.getStringBuffer("scene.osf");this.nativeSDK._OX_LoadOSF(a),this.releaseStringBuffer(a);}processFrame(t,i=null,e=480,a=640,r=0,s=0){let n=i||this.buffer;this.nativeSDK.HEAPU8.set(t,n),this.nativeSDK.HEAPU32[this.frameLayoutStruct/4+0]=a,this.nativeSDK.HEAPU32[this.frameLayoutStruct/4+1]=e,this.nativeSDK.HEAPU32[this.frameLayoutStruct/4+2]=4*a,this.nativeSDK.HEAPU32[this.frameLayoutStruct/4+3]=!1,this.nativeSDK.HEAPU32[this.frameLayoutStruct/4+4]=5,this.nativeSDK.HEAPU32[this.frameLayoutStruct/4+5]=s,this.nativeSDK.HEAPU32[this.frameLayoutStruct/4+6]=r,this.nativeSDK._OX_ProcessFrame(n,this.frameLayoutStruct);}loadExtractionData(t,i=-1){return this.siftBuffer&&this.netvladBuffer?(this.nativeSDK.HEAPF32.set(t.extraction,this.siftBuffer/4),this.nativeSDK.HEAPF32.set(t.descriptor,this.netvladBuffer/4),this.nativeSDK._OX_LoadExtractionData(this.siftBuffer,this.netvladBuffer,i)):0}getCandidateData(t){let i=this.nativeSDK._OX_GetCandidateData(t),e=[];for(let t=0;t<55e4;t++)e.push(this.nativeSDK.HEAPF32[i/4+t]);return new Float32Array(e)}loadMatch(t){this.matchBuffer&&(this.nativeSDK.HEAPF32.set(t,this.matchBuffer/4),this.nativeSDK._OX_LoadMatch(this.matchBuffer));}spatialLocate(){this.nativeSDK._OX_SpatialLocate();}loadKeyframePose(t){this.nativeSDK._OX_LoadKfPose(t);}numSLAMKeyframes(){return this.nativeSDK._OX_GetSLAMNumKfs()}getSLAMKeyframe(t){let i=this.nativeSDK._OX_GetSLAMKf(t),e=[];for(let t=0;t<1228800;t++)e.push(this.nativeSDK.HEAPU8[i+t]);return new Uint8Array(e)}stopImageTracking(){this.nativeSDK._OX_StopImageDetection();}stopQRCodeTracking(){this.nativeSDK._OX_StopQRCodeDetection();}stopSLAM(){this.nativeSDK._OX_StopSLAM();}stopSLAM(){this.nativeSDK._OX_StopSLAM();}addImage(t,i){this.nativeSDK.HEAPU8.set(i,this.imageBuffer),this.nativeSDK.HEAPU32[this.frameLayoutStruct/4+0]=640,this.nativeSDK.HEAPU32[this.frameLayoutStruct/4+1]=480,this.nativeSDK.HEAPU32[this.frameLayoutStruct/4+2]=2560,this.nativeSDK.HEAPU32[this.frameLayoutStruct/4+3]=!1,this.nativeSDK.HEAPU32[this.frameLayoutStruct/4+4]=5,this.nativeSDK.HEAPU32[this.frameLayoutStruct/4+5]=0,this.nativeSDK.HEAPU32[this.frameLayoutStruct/4+6]=0;const e=this.getStringBuffer(t);this.nativeSDK._OX_AddImage([e],this.imageBuffer,this.frameLayoutStruct),this.releaseStringBuffer(e);}destroy(){this.nativeSDK._OX_Destroy();}extractionType(){return this.nativeSDK._OX_ExtractionType()}getStringBuffer(t){const i=this.nativeSDK.lengthBytesUTF8(t)+1;let e=this.nativeSDK._malloc(i);return this.nativeSDK.stringToUTF8(t,e,i),e}releaseStringBuffer(t){this.nativeSDK._free(t);}getSLAMMap(){const t=this.nativeSDK.UTF8ToString(this.nativeSDK._OX_GetSLAMMap());let i;try{i=JSON.parse(t);}catch(i){console.error(`Could not parse ${t}`);}return i}getSLAMTrackingPoints(){const t=this.nativeSDK.UTF8ToString(this.nativeSDK._OX_GetSLAMTrackingPoints());let i;try{i=JSON.parse(t);}catch(i){console.error(`Could not parse ${t}`);}return i}raycast(t,i,e,a,r,s){const n=this.nativeSDK.UTF8ToString(this.nativeSDK._OX_Raycast(t,i,e,a,r,s));let o;try{o=JSON.parse(n);}catch(t){console.error(`Could not parse ${n}`);}return o}}
|
|
42
42
|
|
|
43
43
|
class UIManager{constructor(){this.onFocus=this.onFocus.bind(this);}createRenderCanvas(){this.renderCanvas=document.createElement("canvas"),this.renderCanvas.id="renderer",this.renderCanvas.style.position="absolute",document.body.prepend(this.renderCanvas),this.addTouchListeners();}setRenderCanvas(e){this.renderCanvas=e,this.addTouchListeners();}addTouchListeners(){this.renderCanvas.addEventListener("click",(e=>{this.onCanvasTouch(e);})),this.renderCanvas.addEventListener("touchstart",(e=>{this.onCanvasTouchStart(e);})),this.renderCanvas.addEventListener("touchmove",(e=>{this.onCanvasTouchMove(e);})),this.renderCanvas.addEventListener("touchend",(e=>{this.onCanvasTouchEnd(e);}));}removeRenderCanvas(){this.renderCanvas&&(this.renderCanvas.remove(),this.renderCanvas=null);}createVideoElement(e){let t=document.createElement("video");t.setAttribute("playsinline","true"),t.setAttribute("autoplay","true"),t.setAttribute("muted",""),this.videoCanvas=document.createElement("canvas"),this.videoCanvas.width=640,this.videoCanvas.height=480,this.videoContext=this.videoCanvas.getContext("2d"),t.srcObject=e,document.body.appendChild(t),this.videoElement=t;const i=this.videoElement.srcObject.getVideoTracks()[0].getSettings();this.videoSizeHorizontal=[Math.max(i.width,i.height),Math.min(i.width,i.height)],this.videoSizeVertical=[Math.min(i.width,i.height),Math.max(i.width,i.height)],window.addEventListener("focus",this.onFocus);}onFocus(){this.videoElement.play();}removeVideoElement(){this.videoElement&&(window.removeEventListener("focus",this.onFocus),this.videoElement.remove(),this.videoElement=null);}fitVideoToScreen(){this.videoSize=window.innerWidth>window.innerHeight?this.videoSizeHorizontal:this.videoSizeVertical;let e=[],t=[];this.videoSize[0]/this.videoSize[1]>window.innerWidth/window.innerHeight?(t=[Math.floor(this.videoSize[0]*(window.innerHeight/this.videoSize[1])),window.innerHeight],e=[-(t[0]-window.innerWidth)/2,0]):(t=[window.innerWidth,Math.floor(this.videoSize[1]*(window.innerWidth/this.videoSize[0]))],e=[0,-(t[1]-window.innerHeight)/2]),document.body.style.setProperty("overflow","hidden"),this.videoElement.width=t[0],this.videoElement.height=t[1],this.videoElement.style.setProperty("position","absolute"),this.videoElement.style.setProperty("z-index","-1"),this.videoElement.style.setProperty("width",`${t[0]}px`),this.videoElement.style.setProperty("height",`${t[1]}px`),this.videoElement.style.setProperty("left",`${e[0]}px`),this.videoElement.style.setProperty("top",`${e[1]}px`),this.videoElement.style.setProperty("touch-action","none"),this.renderCanvas.width=t[0],this.renderCanvas.height=t[1],this.renderCanvas.style.setProperty("position","absolute","important"),this.renderCanvas.style.setProperty("width",`${t[0]}px`,"important"),this.renderCanvas.style.setProperty("height",`${t[1]}px`,"important"),this.renderCanvas.style.setProperty("left",`${e[0]}px`,"important"),this.renderCanvas.style.setProperty("top",`${e[1]}px`,"important"),this.renderCanvas.style.setProperty("touch-action","none","important");}async displayPermissionsDialog(e){return new Promise(((t,i)=>{let o,s,n,r;o=document.createElement("div"),o.id="ox-permissions-dialog",o.style.setProperty("position","fixed"),o.style.setProperty("z-index","999999"),o.style.setProperty("max-width","360px"),o.style.setProperty("width","calc(100% - 140px"),o.style.setProperty("left","50vw"),o.style.setProperty("top","50vh"),o.style.setProperty("transform","translate(-50%, -50%)"),o.style.setProperty("background-color","#FFFFFF"),o.style.setProperty("border-radius","10px"),o.style.setProperty("font-family","'Open Sans', Arial, sans-serif"),o.style.setProperty("text-align","center"),o.style.setProperty("padding","30px"),document.body.appendChild(o),s=document.createElement("h1"),s.id="ox-permissions-dialog-title",s.innerText="Access to motion sensors required",s.style.setProperty("font-size","20px"),o.appendChild(s),n=document.createElement("span"),n.id="ox-permissions-dialog-message",n.innerText="This augmented reality experience requires access to your phone motion sensors. The browser may ask you for permissions.",n.style.setProperty("display","block"),n.style.setProperty("padding","10px 0"),o.appendChild(n),r=document.createElement("button"),r.id="ox-permissions-dialog-ok-button",r.innerText="Okay!",r.style.setProperty("display","block"),r.style.setProperty("margin","auto"),r.style.setProperty("background","#000000"),r.style.setProperty("color","#FFFFFF"),r.style.setProperty("border","none"),r.style.setProperty("border-radius","12px"),r.style.setProperty("padding","20px 0"),r.style.setProperty("width","100%"),r.style.setProperty("font-size","18px"),r.style.setProperty("font-weight","bold"),r.style.setProperty("margin-top","20px"),r.style.setProperty("background-image","linear-gradient(to left, #f6414b, #ee0979)"),o.appendChild(r),r.addEventListener("click",(async s=>{s.stopPropagation(),o.remove();try{await e(),t();}catch(e){i(e);}}));}))}getVideoData(){let e;if(this.videoElement){if(this.isPortrait()){let e=320,i=240,o=480,s=640;var t=Math.PI/2;this.videoContext.translate(e,i),this.videoContext.rotate(t),this.videoContext.drawImage(this.videoElement,-i,-e,o,s),this.videoContext.rotate(-t),this.videoContext.translate(-e,-i);}else this.videoContext.drawImage(this.videoElement,0,0,640,480);e=this.videoContext.getImageData(0,0,640,480).data;}return e}getVideoElement(){return this.videoElement}getCameraParameters(){return {fov:radToDeg(2*Math.atan(this.videoSize[1]/936)),aspect:this.videoSize[0]/this.videoSize[1]}}isPortrait(){return window.innerWidth<window.innerHeight}setTouchListener(e){this.onTouch=e;}setTouchStartListener(e){this.onTouchStart=e;}setTouchMoveListener(e){this.onTouchMove=e;}setTouchEndListener(e){this.onTouchEnd=e;}getNormalizedTouchCoords(e){const t=new Vector2,i=this.renderCanvas.getBoundingClientRect();return null!=e.clientX?(t.x=(e.clientX-i.left)/i.width*2-1,t.y=-(e.clientY-i.top)/i.height*2+1):e.touches[0]?(t.x=e.touches[0].clientX/window.innerWidth*2-1,t.y=-e.touches[0].clientY/window.innerHeight*2+1):(t.x=e.changedTouches[0].clientX/window.innerWidth*2-1,t.y=-e.changedTouches[0].clientY/window.innerHeight*2+1),t}onCanvasTouch(e){const t=this.getNormalizedTouchCoords(e);this.onTouch&&this.onTouch(t);}onCanvasTouchStart(e){const t=this.getNormalizedTouchCoords(e);this.onTouchStart&&this.onTouchStart(t);}onCanvasTouchMove(e){const t=this.getNormalizedTouchCoords(e);this.onTouchMove&&this.onTouchMove(t);}onCanvasTouchEnd(e){const t=this.getNormalizedTouchCoords(e);this.onTouchEnd&&this.onTouchEnd(t);}}
|
|
44
44
|
|
|
@@ -48,7 +48,7 @@ class IMUManager{constructor(e,t){this.uiManager=e,this.deviceManager=t,this.sta
|
|
|
48
48
|
|
|
49
49
|
class WorkerExtractionData{constructor(r,t,e,s,a,i,o=5){this.data=r,this.width=t,this.height=e,this.rotate=s,this.flip=a,this.colorSpace=o,this.dtype=i;}}class WorkerMatchingData{constructor(r,t,e,s){this.idx=r,this.from=t,this.to=e,this.dtype=s;}}class WorkerManager{constructor(){this.workers={},this.callbacks={};}workerExists(r){return void 0!==this.workers[r]&&void 0!==this.callbacks[r]}createExtractionWorker(r,t){this.workerExists(r)||(this.workers[r]=new Worker(new URL("worker-a.js",import.meta.url),{type:"module"}),this.callbacks[r]=t,this.workers[r].addEventListener("message",(t=>{this.callbacks[r](t.data);})));}createMatchingWorker(r,t){this.workerExists(r)||(this.workers[r]=new Worker(new URL("worker-b.js",import.meta.url),{type:"module"}),this.callbacks[r]=t,this.workers[r].addEventListener("message",(t=>{this.callbacks[r](t.data);})));}replaceCallback(r,t){this.workerExists(r)&&(this.callbacks[r]=t);}sendDataToWorker(r,t){this.workers[r].postMessage(t);}async createWorkers(){return Promise.all([new Promise(((r,t)=>{this.createExtractionWorker("extraction",(t=>{"ready"===t&&r();}));})),new Promise(((r,t)=>{this.createMatchingWorker("matching",(t=>{"ready"===t&&r();}));}))])}}
|
|
50
50
|
|
|
51
|
-
class WebXRManager{constructor(t,e,i,a){this.uiManager=t,this.nativeManager=e,this.deviceManager=i,this.workerManager=a;}async isWebXRSupported(){let t=!1;return navigator.xr&&(t=await navigator.xr.isSessionSupported("immersive-ar")),t}async init(t,e,i){this.onPose=e,this.onSessionEnd=i;await this.uiManager.displayPermissionsDialog((async()=>{const e=["hit-test"],i=["dom-overlay"];t&&i.push("camera-access");try{const t=await navigator.xr.requestSession("immersive-ar",{requiredFeatures:e,optionalFeatures:i,domOverlay:{root:document.body}});await this.onXRSessionStarted(t);}catch(t){throw new SensorsError(`error while initializing webXR API: ${t}`)}}));}start(){this.started=!0,this.usingSpatial&&(this.relocating=!1,this.workerManager.replaceCallback("extraction",(t=>{if(!1===t)return void(this.relocating=!1);let e=this.nativeManager.loadExtractionData(t);this.candidates=Array.from(Array(e).keys()).reverse(),this.siftData=t.extraction,this.matchKeyframes();})),this.workerManager.replaceCallback("matching",(t=>{this.nativeManager.loadMatch(t),this.matchKeyframes();})));}matchKeyframes(){if(this.candidates.length>0){let t=this.candidates.pop();this.workerManager.sendDataToWorker("matching",new WorkerMatchingData(t,this.siftData,this.nativeManager.getCandidateData(t),this.nativeManager.extractionType()));}else this.nativeManager.spatialLocate(),this.relocating=!1;}async destroy(){this.xrSession&&(await this.xrSession.end(),this.xrSession=null,this.xrLastPose=null);}async onXRSessionStarted(t){let e=this.uiManager.renderCanvas.getContext("webgl2");e||(e=this.uiManager.renderCanvas.getContext("webgl")),e.getContextAttributes().xrCompatible||await e.makeXRCompatible(),this.xrContext=e,this.framebuffer=this.xrContext.createFramebuffer(),this.xrLayer=new XRWebGLLayer(t,this.xrContext),this.usingSpatial&&(this.glBinding=new XRWebGLBinding(t,this.xrContext)
|
|
51
|
+
class WebXRManager{constructor(t,e,i,a){this.uiManager=t,this.nativeManager=e,this.deviceManager=i,this.workerManager=a;}async isWebXRSupported(){let t=!1;return navigator.xr&&(t=await navigator.xr.isSessionSupported("immersive-ar")),t}async init(t,e,i){this.onPose=e,this.onSessionEnd=i;await this.uiManager.displayPermissionsDialog((async()=>{const e=["hit-test"],i=["dom-overlay"];t&&i.push("camera-access");try{const t=await navigator.xr.requestSession("immersive-ar",{requiredFeatures:e,optionalFeatures:i,domOverlay:{root:document.body}});await this.onXRSessionStarted(t);}catch(t){throw new SensorsError(`error while initializing webXR API: ${t}`)}}));}start(){this.started=!0,this.usingSpatial&&(this.relocating=!1,this.workerManager.replaceCallback("extraction",(t=>{if(!1===t)return void(this.relocating=!1);let e=this.nativeManager.loadExtractionData(t);this.candidates=Array.from(Array(e).keys()).reverse(),this.siftData=t.extraction,this.matchKeyframes();})),this.workerManager.replaceCallback("matching",(t=>{this.nativeManager.loadMatch(t),this.matchKeyframes();})));}matchKeyframes(){if(this.candidates.length>0){let t=this.candidates.pop();this.workerManager.sendDataToWorker("matching",new WorkerMatchingData(t,this.siftData,this.nativeManager.getCandidateData(t),this.nativeManager.extractionType()));}else this.nativeManager.spatialLocate(),this.relocating=!1;}async destroy(){this.xrSession&&(await this.xrSession.end(),this.xrSession=null,this.xrLastPose=null);}async onXRSessionStarted(t){let e=this.uiManager.renderCanvas.getContext("webgl2");e||(e=this.uiManager.renderCanvas.getContext("webgl")),e.getContextAttributes().xrCompatible||await e.makeXRCompatible(),this.xrContext=e,this.framebuffer=this.xrContext.createFramebuffer(),this.xrLayer=new XRWebGLLayer(t,this.xrContext);let i=this.xrLayer.framebufferWidth,a=this.xrLayer.framebufferHeight;this.usingSpatial&&(this.glBinding=new XRWebGLBinding(t,this.xrContext),this.nativeManager.xrbuffer=this.nativeManager.nativeSDK._malloc(i*a*4),this.nativeManager.siftBuffer=this.nativeManager.nativeSDK._malloc(22e5),this.nativeManager.matchBuffer=this.nativeManager.nativeSDK._malloc(14e3),this.nativeManager.netvladBuffer=this.nativeManager.nativeSDK._malloc(32768)),t.updateRenderState({baseLayer:this.xrLayer}),this.xrLocalRefSpace=await t.requestReferenceSpace("local"),this.xrViewerRefSpace=await t.requestReferenceSpace("viewer"),this.xrHitTestSource=await t.requestHitTestSource({space:this.xrViewerRefSpace}),t.requestAnimationFrame(this.onXRFrame.bind(this)),window.navigator.userAgent.includes("WebXRViewer")?(window.addEventListener("click",(t=>{this.onTouch&&this.onTouch(this.getNormalizedTouchCoords(t));})),window.addEventListener("touchstart",(t=>{this.onTouchStart&&this.onTouchStart(this.getNormalizedTouchCoords(t));})),window.addEventListener("touchend",(t=>{this.onTouchEnd&&this.onTouchEnd(this.getNormalizedTouchCoords(t));}))):(t.addEventListener("select",(t=>{this.onTouch&&this.onTouch(this.getXRInputCoords(t));})),t.addEventListener("selectstart",(t=>{this.onTouchStart&&this.onTouchStart(this.getXRInputCoords(t));})),t.addEventListener("selectend",(t=>{this.onTouchEnd&&this.onTouchEnd(this.getXRInputCoords(t));}))),window.addEventListener("touchmove",(t=>{this.onTouchMove&&this.onTouchMove(this.getNormalizedTouchCoords(t));})),t.addEventListener("end",(()=>{this.onSessionEnd&&this.onSessionEnd();})),this.xrSession=t;}hasRelocated(){return this.usingSpatial&&this.nativeManager.xrTransform}needsRelocation(){return this.usingSpatial&&!this.hasRelocated()&&(null==this.lastRelocationTry||this.msSinceRelocation()>2500)}startRelocationTimer(){this.lastRelocationTry=new Date;}msSinceRelocation(){let t=new Date;return this.lastRelocationTry?t-this.lastRelocationTry:0}onXRFrame(t,e){let i=e.session;i.requestAnimationFrame(this.onXRFrame.bind(this));const a=e.getViewerPose(this.xrLocalRefSpace);if(a){if(this.needsRelocation())for(const t of a.views)if(t.camera){const e=t.camera.width,i=t.camera.height;var r=new Uint8ClampedArray(e*i*4);let s=this.glBinding.getCameraImage(t.camera);const n=this.xrContext;let o,h;n.bindTexture(n.TEXTURE_2D,s),n.bindFramebuffer(n.FRAMEBUFFER,this.framebuffer),n.framebufferTexture2D(n.FRAMEBUFFER,n.COLOR_ATTACHMENT0,n.TEXTURE_2D,s,0),n.readPixels(0,0,t.camera.width,t.camera.height,n.RGBA,n.UNSIGNED_BYTE,r),this.uiManager.isPortrait()?(o=1,h=3):(o=2,h=0),this.relocating||(this.relocating=!0,this.extractionFrame=r,this.extractionWidth=e,this.extractionHeight=i,this.workerManager.sendDataToWorker("extraction",new WorkerExtractionData(r,e,i,h,o,this.nativeManager.extractionType())),this.nativeManager.lastXrPose=(new Matrix4).fromArray(a.transform.matrix).toArray()),this.startRelocationTimer();}this.xrContext.bindFramebuffer(this.xrContext.FRAMEBUFFER,i.renderState.baseLayer.framebuffer);const t=a.views[0];let s=(new Matrix4).fromArray(t.transform.matrix);if(this.deviceManager.os===DeviceManager.OS.Android&&this.started&&this.lastPose&&!this.jumpPose){2*Math.acos(Math.abs((new Quaternion).setFromRotationMatrix(s).dot((new Quaternion).setFromRotationMatrix(this.lastPose))))>1&&(this.jumpPose=s);}if(this.jumpPose){const t=this.jumpPose.clone().invert().multiply(s);s=this.lastPose.clone().multiply(t);}else this.lastPose=s;this.hasRelocated()&&(s=(new Matrix4).fromArray(this.nativeManager.xrTransform.elements).multiply(s)),this.usingSpatial&&!this.hasRelocated()||this.onPose(s.toArray());const n=null==this.xrLastPose||this.lastViewportWidth!=window.innerWidth||this.lastViewportHeight!=window.innerHeight;if(this.xrLastPose=a,this.lastViewportWidth=window.innerWidth,this.lastViewportHeight=window.innerHeight,n&&this.onResize&&this.onResize(),this.onHitTestResult){const t=e.getHitTestResults(this.xrHitTestSource);if(t.length>0){const e=t[0].getPose(this.xrLocalRefSpace),i=(new Matrix4).fromArray(e.transform.matrix),a=i.extractPosition(),r=((new Quaternion).setFromRotationMatrix(i),s.extractPosition()),n=Math.atan2(r.x-a.x,r.z-a.z),o={position:a,rotation:(new Quaternion).setFromEuler(new Euler(0,n,0))};this.onHitTestResult(o);}}}this.onFrame&&this.onFrame(e);}fitCanvasToXRViewport(){if(this.xrLastPose){const t=this.xrLastPose.views[0],e=this.xrLayer.getViewport(t);if((e.width>e.height&&window.innerWidth>window.innerHeight||e.width<=e.height&&window.innerWidth<=window.innerHeight)&&e.width*e.height>window.innerWidth*window.innerHeight)this.uiManager.renderCanvas.width=e.width,this.uiManager.renderCanvas.height=e.height;else {this.uiManager.renderCanvas.width=window.innerWidth;const t=parseInt(getComputedStyle(document.documentElement).getPropertyValue("--sat"),10)||0,e=parseInt(getComputedStyle(document.documentElement).getPropertyValue("--sab"),10)||0,i=window.innerHeight+t+e;this.uiManager.renderCanvas.height=i;}}}getCameraParameters(){let t=60,e=9/16;if(this.xrSession&&this.xrLastPose){const i=this.xrLastPose.views[0].projectionMatrix;e=this.uiManager.renderCanvas.width/this.uiManager.renderCanvas.height,t=radToDeg(2*Math.atan(1/i[5]));}return {fov:t,aspect:e}}getXRLayer(){return this.xrLayer}getXRInputCoords(t){const e=t.inputSource.gamepad.axes;return new Vector2(e[0],-e[1])}getNormalizedTouchCoords(t){const e=new Vector2;return e.x=t.touches[0].clientX/window.innerWidth*2-1,e.y=-t.touches[0].clientY/window.innerHeight*2+1,e}setResizeListener(t){this.onResize=t;}setTouchListener(t){this.onTouch=t;}setTouchStartListener(t){this.onTouchStart=t;}setTouchMoveListener(t){this.onTouchMove=t;}setTouchEndListener(t){this.onTouchEnd=t;}setSessionEndListener(t){this.onSessionEnd=t;}setHitTestListener(t){this.onHitTestResult=t;}setFrameListener(t){this.onFrame=t;}}
|
|
52
52
|
|
|
53
53
|
class EventManager{constructor(){this.eventListeners={},this.eventListenerCount=0;}stop(){this.eventListeners={},this.eventListenerCount=0;}addEventListener(e,t){this.eventListeners[e]||(this.eventListeners[e]=[]);const n=this.eventListenerCount++;return this.eventListeners[e].push({id:n,func:t}),n}triggerEvent(e,t){this.eventListeners[e]&&this.eventListeners[e].map((e=>e.func(t)));}removeEventListener(e){for(let t of Object.keys(this.eventListeners))for(let n=0;n<t.length;n++)if(t[n].id===e){t.splice(n,1);break}}}
|
|
54
54
|
|