diff --git a/dist/aframe-ar.js b/dist/aframe-ar.js index e331bd7..8b89c8d 100644 --- a/dist/aframe-ar.js +++ b/dist/aframe-ar.js @@ -880,8 +880,10 @@ AFRAME.registerComponent('mozilla-xr-ar', { sy = sy || this.forceResizeY; this.forceResizeY = sy; sc.canvas.setAttribute('width', sx); sc.canvas.setAttribute('height', sy); - sc.renderer.setPixelRatio(1); + sc.camera.aspect = sx / sy; sc.camera.projectionMatrix.copy(self.projectionMatrix); + sc.renderer.setPixelRatio(1); + sc.renderer.setSize(sx, sy, false); sc.emit('rendererresize', null, false); }, diff --git a/dist/aframe-ar.js.map b/dist/aframe-ar.js.map index 15472f9..303adcb 100644 --- a/dist/aframe-ar.js.map +++ b/dist/aframe-ar.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/ar-anchors.js","webpack:///./src/ar-camera.js","webpack:///./src/ar-images.js","webpack:///./src/ar-planes.js","webpack:///./src/ar-raycaster.js","webpack:///./src/ar.js","webpack:///./src/index.js","webpack:///./src/mozilla-xr-ar.js","webpack:///./src/webxr-ar.js"],"names":[],"mappings":";QAAA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;;;QAGA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA,0CAA0C,gCAAgC;QAC1E;QACA;;QAEA;QACA;QACA;QACA,wDAAwD,kBAAkB;QAC1E;QACA,iDAAiD,cAAc;QAC/D;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,yCAAyC,iCAAiC;QAC1E,gHAAgH,mBAAmB,EAAE;QACrI;QACA;;QAEA;QACA;QACA;QACA,2BAA2B,0BAA0B,EAAE;QACvD,iCAAiC,eAAe;QAChD;QACA;QACA;;QAEA;QACA,sDAAsD,+DAA+D;;QAErH;QACA;;;QAGA;QACA;;;;;;;;;;;;AClFA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,CAAC;;;;;;;;;;;;ACpBD;;AAEA;AACA;AACA,cAAc;AACd,GAAG;;AAEH;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA,6BAA6B,QAAQ;;AAErC;AACA,mBAAmB,QAAQ;;AAE3B;AACA;AACA;AACA,cAAc,uCAAuC;;AAErD;AACA;AACA;AACA,cAAc,uCAAuC;;AAErD;AACA;AACA;AACA,mBAAmB,4DAA4D;AAC/E,K;AACA,GAAG;;AAEH;AACA;AACA;AACA,2CAA2C,QAAQ;AACnD;AACA;AACA;AACA,G;AACA,CAAC;;;;;;;;;;;;AC9DD;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH,CAAC;;;;;;;;;;;;AC3BD;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA,iCAAiC;AACjC;AACA,iCAAiC;AACjC,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;;AAE5B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,eAAe,2BAA2B;AAC1C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;;AAEA,qBAAqB;AACrB,sCAAsC,iCAAiC;;AAEvE;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,2BAA2B,iCAAiC;AAC5D,4BAA4B,oCAAoC,E;AAChE,kCAAkC,qCAAqC;;AAEvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,M;AACA,GAAG;AACH,CAAC;;;;;;;;;;;;ACnND;;AAEA;AACA;AACA,0C;AACA;;AAEA;AACA,QAAQ,aAAa;AACrB,QAAQ,aAAa;AACrB,SAAS;AACT,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,yCAAyC,WAAW;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,oBAAoB,+DAA+D;AACnF,2CAA2C,QAAQ;AACnD;AACA;AACA;AACA,G;AACA,CAAC;;;;;;;;;;;;;ACnED;;AAEA;AACA;AACA,qBAAqB,cAAc;AACnC,uBAAuB,eAAe;AACtC,mBAAmB,cAAc;AACjC,aAAa;AACb,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,E;AACP;AACA;AACA,GAAG;AACH;AACA;AACA,GAAG;AACH;AACA;AACA,GAAG;AACH;AACA;AACA,GAAG;AACH;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA,kDAAkD,eAAe;AACjE;;AAEA;AACA;AACA,yBAAyB,0CAA0C;AACnE;AACA,CAAC;;;;;;;;;;;;ACvDD,mBAAO,CAAC,qCAAY;AACpB;AACA,mBAAO,CAAC,+CAAiB;AACzB,mBAAO,CAAC,uCAAa;AACrB,mBAAO,CAAC,yCAAc;AACtB,mBAAO,CAAC,uCAAa;AACrB,mBAAO,CAAC,yBAAM;AACd,mBAAO,CAAC,uCAAa;AACrB,mBAAO,CAAC,6CAAgB;;;;;;;;;;;;;ACRxB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,oBAAoB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA,wBAAwB;;AAExB;AACA;AACA,CAAC;AACD;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,eAAe,gBAAgB;AAC/B;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,CAAC;AACD;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;AAMA;AACA;AACA,yBAAyB,cAAc;AACvC,2BAA2B,eAAe;AAC1C,uBAAuB;AACvB,KAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA,uCAAuC;;AAEvC;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA,+DAA+D,QAAQ;AACvE,oDAAoD,QAAQ;;AAE5D;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,kCAAkC,cAAc;;AAEhD;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,oCAAoC,mCAAmC,EAAE;AACzE;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC;AACrC,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA,+DAA+D,QAAQ;AACvE,qDAAqD,QAAQ;;AAE7D;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;;AAEA;AACA;AACA;;AAEA;AACA,mCAAmC,eAAe;;AAElD;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;;AAEA;AACA;AACA,KAAK;;AAEL;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,6FAA6F;AAC7F;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA,uCAAuC;;AAEvC;AACA;;AAEA,kEAAkE;AAClE;AACA;;AAEA;AACA,qBAAqB,4BAA4B;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,qBAAqB,gCAAgC;AACrD;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA,qBAAqB,yBAAyB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,eAAe;AACf;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA,8BAA8B,aAAa;AAC3C;AACA,KAAK;;AAEL;AACA,8BAA8B,aAAa;AAC3C;AACA,KAAK;;AAEL;AACA,8BAA8B,aAAa;AAC3C;AACA,KAAK;;AAEL;AACA,8BAA8B,aAAa;AAC3C;AACA,KAAK;;AAEL;;AAEA;AACA,8BAA8B,aAAa;AAC3C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,sBAAsB;AACvC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,S;;AAEA;AACA;AACA;AACA;AACA,S;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,eAAe;AACf;AACA,WAAW;AACX;AACA;AACA;AACA,gDAAgD;AAChD,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA,8BAA8B,aAAa;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA,KAAK;;AAEL;AACA,mCAAmC;;AAEnC;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,sBAAsB,MAAM;AAC5B,sBAAsB,MAAM;AAC5B,sBAAsB,MAAM;AAC5B,sBAAsB,MAAM;AAC5B,uBAAuB,OAAO;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;;AAEV;AACA;AACA;AACA,sBAAsB,OAAO;AAC7B,sBAAsB,OAAO;AAC7B,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,4BAA4B,mBAAmB;AAC/C;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gCAAgC,QAAQ;AACxC;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kCAAkC,WAAW;;AAE7C;;AAEA;AACA;AACA,2BAA2B,uBAAuB;AAClD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,S;AACA,KAAK;AACL,CAAC;;;;;;;;;;;;ACh2BD;;AAEA;AACA;AACA,yBAAyB,cAAc;AACvC,2BAA2B,eAAe;AAC1C,uBAAuB,eAAe;AACtC,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,oBAAoB;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,yCAAyC,oBAAoB;AAC7D,yCAAyC,oBAAoB;AAC7D,yCAAyC,oBAAoB;AAC7D,yCAAyC,oBAAoB;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA,sCAAsC,QAAQ;;AAE9C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;;AAET;AACA,KAAK;;AAEL;AACA;AACA,4CAA4C;AAC5C,0CAA0C;AAC1C;AACA,KAAK;;AAEL;AACA;AACA;AACA,kCAAkC,0BAA0B;AAC5D,SAAS;;AAET;AACA;AACA,KAAK;;AAEL;AACA;AACA,gEAAgE,QAAQ;;AAExE;AACA,0BAA0B;;AAE1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uD;AACA;AACA;AACA,iBAAiB;AACjB,aAAa;AACb;AACA;AACA;AACA,iGAAiG,0BAA0B;AAC3H,iBAAiB;AACjB;AACA;AACA,iGAAiG,0BAA0B;AAC3H,iBAAiB;AACjB;AACA;AACA,6HAA6H,0BAA0B;AACvJ,iBAAiB;AACjB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB,gDAAgD,6BAA6B;AAC7E;AACA,qBAAqB;AACrB,iBAAiB;;AAEjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB,gDAAgD,6BAA6B;AAC7E;AACA,qBAAqB;AACrB,iBAAiB;;AAEjB;AACA;AACA;AACA;AACA;AACA,6D;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,qBAAqB;AACrB,iBAAiB;;AAEjB;AACA;AACA;AACA,sDAAsD,wBAAwB;AAC9E;AACA;AACA,yBAAyB;AACzB;AACA,iBAAiB;;AAEjB;AACA;AACA,iBAAiB;;AAEjB;AACA;AACA,sDAAsD,uBAAuB,gBAAgB;AAC7F;AACA,aAAa;AACb;AACA,SAAS;AACT,KAAK;;AAEL;AACA,8DAA8D,aAAa;AAC3E;AACA,KAAK;;AAEL;AACA,8DAA8D,aAAa;AAC3E;AACA,KAAK;;AAEL;AACA,8DAA8D,aAAa;AAC3E;AACA,KAAK;;AAEL;AACA,8DAA8D,aAAa;AAC3E;AACA,KAAK;;AAEL,yB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kCAAkC,WAAW;AAC7C;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,mCAAmC,6CAA6C;AAChF;AACA;AACA,kEAAkE;AAClE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;;AAEA;AACA;AACA,KAAK;;AAEL;;AAEA;AACA,8BAA8B,aAAa;;AAE3C;AACA,KAAK;;AAEL;AACA,8BAA8B,aAAa;;AAE3C;AACA,KAAK;;AAEL;AACA;AACA,KAAK;;AAEL;;AAEA;AACA;AACA;AACA,CAAC","file":"aframe-ar.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./src/index.js\");\n","/* global AFRAME, THREE */\n\nAFRAME.registerComponent('ar-anchors', {\n\n getSource: function () {\n var whichar;\n if (!this.source) {\n whichar = this.el.sceneEl.components['ar'];\n if (whichar) {\n this.source = whichar.getSource();\n }\n }\n return this.source;\n },\n\n getAnchors: function () {\n var source = this.getSource();\n if (!source || !source.getAnchors) return undefined;\n return source.getAnchors();\n }\n});\n","/* global AFRAME */\n\nAFRAME.registerComponent('ar-camera', {\n schema: {\n enabled: {default:true}\n },\n\n init: function () {\n var lookControls = this.el.getAttribute('look-controls');\n this.wasLookControlsEnabled = lookControls ? lookControls.enabled : false;\n },\n\n update: function (oldData) {\n if (!oldData || oldData.enabled !== this.data.enabled) {\n // Value changed, so react accordingly.\n if (this.data.enabled) {\n // Save camera look-controls enabled, and turn off for AR.\n var lookControls = this.el.getAttribute('look-controls');\n this.wasLookControlsEnabled = lookControls ? lookControls.enabled : false;\n if (this.wasLookControlsEnabled) {\n this.el.setAttribute('look-controls', 'enabled', false);\n }\n } else {\n // Restore camera look-controls enabled.\n if (this.wasLookControlsEnabled) {\n this.el.setAttribute('look-controls', 'enabled', true);\n }\n }\n }\n },\n \n tick: function (t, dt) {\n if (!this.data.enabled) { return; }\n \n var whichar = this.checkWhichAR();\n if (!whichar) { return; }\n \n // Apply the pose position via setAttribute,\n // so that other A-Frame components can see the values.\n var pos = whichar.getPosition();\n if (pos) { this.el.setAttribute('position', pos); }\n\n // Apply the pose rotation via setAttribute,\n // so that other A-Frame components can see the values.\n var rot = whichar.getRotation();\n if (rot) { this.el.setAttribute('rotation', rot); }\n\n // Apply the projection matrix, if we're not in VR.\n if (!this.el.sceneEl.is('vr-mode')) {\n var matrix = whichar.getProjectionMatrix();\n if (matrix) { this.el.components.camera.camera.projectionMatrix = matrix; }\n } \n },\n \n checkWhichAR: function () {\n if (!this.whichar) {\n var whichar = this.el.sceneEl.components['ar'].getSource();\n if (!whichar || !whichar.arDisplay) { return; }\n this.whichar = whichar;\n }\n return this.whichar;\n } \n});\n","/* global AFRAME, THREE */\n\nAFRAME.registerComponent('ar-images', {\n\n getSource: function () {\n var whichar;\n if (!this.source) {\n whichar = this.el.sceneEl.components['ar'];\n if (whichar) {\n this.source = whichar.getSource();\n }\n }\n return this.source;\n },\n\n addImage: function (name, url, physicalWidth) {\n var source = this.getSource();\n if (!source || !source.addImage) return undefined;\n return source.addImage(name, url, physicalWidth);\n },\n\n removeImage: function (name) {\n var source = this.getSource();\n if (!source || !source.removeImage) return undefined;\n return source.removeImage(name);\n },\n\n});\n","/* global AFRAME, THREE */\n\nAFRAME.registerComponent('ar-planes', {\n\n getPlaneSource: function () {\n var whichar;\n if (!this.planeSource) {\n whichar = this.el.sceneEl.components['ar'];\n if (whichar) {\n this.planeSource = whichar.getSource();\n }\n }\n return this.planeSource;\n },\n\n getPlanes: function () {\n var planeSource = this.getPlaneSource();\n if (!planeSource || !planeSource.getPlanes) return undefined;\n return planeSource.getPlanes();\n },\n\n init: function () {\n // Remember planes when we see them.\n this.planes = {};\n this.anchorsAdded = [];\n this.anchorsAddedDetail = {type:'added', anchors: this.anchorsAdded};\n this.anchorsUpdated = [];\n this.anchorsUpdatedDetail = {type:'updated', anchors: this.anchorsUpdated};\n this.anchorsRemoved = [];\n this.anchorsRemovedDetail = {type:'removed', anchors: this.anchorsRemoved};\n },\n\n tick: (function (t, dt) {\n // Create the temporary variables we will reuse, if needed.\n var tempScale = new THREE.Vector3(1, 1, 1);\n var tempMat4 = new THREE.Matrix4();\n var tempPosition = new THREE.Vector3();\n var tempQuaternion = new THREE.Quaternion();\n\n // The actual function, which we return.\n return function (t, dt) {\n // Get the list of planes.\n var planes = this.getPlanes();\n if (!planes) { return; }\n\n // Ideally we would have either events, or separate lists for added / updated / removed.\n var addedThese = [];\n var updatedThese = [];\n var removedThese = [];\n\n // Because we don't have an indication of added / updated / removed,\n // try to keep track ourselves.\n var seenThese = {};\n var i;\n\n // Iterate over the available planes.\n for (i=0; planes && i 0) {\n // Reuse the same event detail to avoid making garbage.\n // TODO: Reuse same CustomEvent?\n this.anchorsAddedDetail.anchors = addedThese;\n this.el.emit('anchorsadded', this.anchorsAddedDetail);\n }\n\n // Replace the old list.\n this.anchorsUpdated = updatedThese;\n // Emit event if list isn't empty.\n if (updatedThese.length > 0) {\n // Reuse the same event detail to avoid making garbage.\n // TODO: Reuse same CustomEvent?\n this.anchorsUpdatedDetail.anchors = updatedThese;\n this.el.emit('anchorsupdated', this.anchorsUpdatedDetail);\n }\n\n // Replace the old list.\n this.anchorsRemoved = removedThese;\n // Emit event if list isn't empty.\n if (removedThese.length > 0) {\n // Reuse the same event detail to avoid making garbage.\n // TODO: Reuse same CustomEvent?\n this.anchorsRemovedDetail.anchors = removedThese;\n this.el.emit('anchorsremoved', this.anchorsRemovedDetail);\n }\n }; \n })()\n});\n","/* global AFRAME */\n\n// ar-raycaster modifies raycaster to append AR hit, if any.\n// But note that current AR hit API does not support orientation as input.\nAFRAME.registerComponent('ar-raycaster', { \n dependencies: ['raycaster'],\n \n schema: {\n x: {default: 0.5},\n y: {default: 0.5},\n el: {type: 'selector'}\n },\n \n init: function () {\n // HACK: monkey-patch raycaster to append AR hit result\n this.raycaster = this.el.components['raycaster'].raycaster;\n this.raycasterIntersectObjects = this.raycaster.intersectObjects.bind(this.raycaster);\n this.raycaster.intersectObjects = this.intersectObjects.bind(this);\n },\n \n update: function (oldData) {\n if (!this.data.el) {\n // If not given some other element, return hit against the scene.\n // HACK: But that means we need its object3D to have an el.\n if (!this.el.sceneEl.object3D.el) {\n this.el.sceneEl.object3D.el = this.el.sceneEl;\n }\n }\n },\n \n intersectObjects: function (objects, recursive, rawIntersections) {\n // it appears that intersectObjects is now returning in rawIntersections\n var results = this.raycasterIntersectObjects(objects, recursive, rawIntersections);\n // Tack on AR hit result, if any.\n var hitARResults = this.hitAR();\n if (hitARResults && hitARResults.length) {\n if (rawIntersections) {\n hitARResults.forEach((hit) => rawIntersections.push(hit));\n results = rawIntersections;\n } else {\n hitARResults.forEach((hit) => results.push(hit));\n }\n }\n return results;\n }, \n \n hitAR: function () {\n var whichar = this.checkWhichAR();\n if (!whichar || !whichar.arDisplay) { return []; }\n var x = this.data.x;\n var y = this.data.y;\n if (arguments.length >= 2) {\n x = arguments[0];\n y = arguments[1];\n }\n return whichar.hitAR(x, y, this.data.el, this.el);\n },\n\n checkWhichAR: function () {\n if (!this.whichar) {\n var whichar = this.el.sceneEl.components['ar'];\n if (whichar) { whichar = whichar.getSource ? whichar.getSource() : undefined; }\n if (!whichar || !whichar.arDisplay) { return; }\n this.whichar = whichar;\n }\n return this.whichar;\n } \n});\n\n","/* global AFRAME */\n\nAFRAME.registerComponent('ar', {\n schema: {\n takeOverCamera: {default: true},\n cameraUserHeight: {default: false},\n worldSensing: {default: true},\n hideUI: {default: false}\n },\n dependencies: ['webxr-ar', 'mozilla-xr-ar', 'ar-planes', 'ar-anchors'],\n getSource: function () {\n var whichar;\n if (!this.source) {\n var self = this;\n self.dependencies.forEach(function(sys) {\n whichar = self.el.sceneEl.components[sys];\n if (whichar && whichar.arDisplay) {\n self.source = whichar;\n }\n });\t\n }\n return this.source;\n },\n getPlanes: function () {\n return this.source ? this.source.getPlanes() : undefined;\n },\n getAnchors: function () {\n return this.source ? this.source.getAnchors() : undefined;\n },\n addImage: function (name, url, physicalWidth) {\n return this.source.addImage(name, url, physicalWidth);\n },\n removeImage: function (name) {\n return this.source.removeImage(name);\n },\n init: function () {\n var options = {\n takeOverCamera: this.data.takeOverCamera,\n cameraUserHeight: this.data.cameraUserHeight,\n worldSensing: this.data.worldSensing\n };\n\n var self = this;\n this.dependencies.forEach(function(sys) {\n self.el.setAttribute(sys, options);\n });\n\n if (this.data.hideUI) {\n this.el.sceneEl.setAttribute('vr-mode-ui', {enabled: false});\n }\n\n // Ensure passthrough is visible, make sure A-Frame styles don't interfere.\n document.head.insertAdjacentHTML('beforeend', \n '');\n }\n});\n","require('./webxr-ar');\n//require('./three-ar');\nrequire('./mozilla-xr-ar');\nrequire('./ar-planes');\nrequire('./ar-anchors');\nrequire('./ar-images');\nrequire('./ar');\nrequire('./ar-camera');\nrequire('./ar-raycaster');\n\n","/* global AFRAME, THREE */\n\nfunction convertVertices(vertices) {\n var verticesLength = vertices.length;\n var newVertices = new Float32Array(verticesLength * 3);\n var i = 0;\n var j = 0;\n var vertex;\n for (i = 0; i < verticesLength; i++) {\n vertex = vertices[i];\n newVertices[j] = vertex.x;\n newVertices[j + 1] = vertex.y;\n newVertices[j + 2] = vertex.z;\n j += 3;\n }\n return newVertices;\n}\n\n\nfunction encode(buffer) {\nvar base64 = ''\nvar encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\n\nvar bytes = buffer; // assume it's a typedArrayBuffer \n \nif (buffer instanceof ArrayBuffer) {\nbytes = new Uint8Array(arrayBuffer)\n} else if (buffer instanceof ImageData) {\nbytes = buffer.data\n}\n\nvar byteLength = buffer.length\nvar byteRemainder = byteLength % 3\nvar mainLength = byteLength - byteRemainder\n\nvar a, b, c, d\nvar chunk\n\n// Main loop deals with bytes in chunks of 3\nfor (var i = 0; i < mainLength; i = i + 3) {\n// Combine the three bytes into a single integer\nchunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]\n\n// Use bitmasks to extract 6-bit segments from the triplet\na = (chunk & 16515072) >> 18 // 16515072 = (2^6 - 1) << 18\nb = (chunk & 258048) >> 12 // 258048 = (2^6 - 1) << 12\nc = (chunk & 4032) >> 6 // 4032 = (2^6 - 1) << 6\nd = chunk & 63 // 63 = 2^6 - 1\n\n// Convert the raw binary segments to the appropriate ASCII encoding\nbase64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]\n}\n\n// Deal with the remaining bytes and padding\nif (byteRemainder == 1) {\nchunk = bytes[mainLength]\n\na = (chunk & 252) >> 2 // 252 = (2^6 - 1) << 2\n\n// Set the 4 least significant bits to zero\nb = (chunk & 3) << 4 // 3 = 2^2 - 1\n\nbase64 += encodings[a] + encodings[b] + '=='\n} else if (byteRemainder == 2) {\nchunk = (bytes[mainLength] << 8) | bytes[mainLength + 1]\n\na = (chunk & 64512) >> 10 // 64512 = (2^6 - 1) << 10\nb = (chunk & 1008) >> 4 // 1008 = (2^6 - 1) << 4\n\n// Set the 2 least significant bits to zero\nc = (chunk & 15) << 2 // 15 = 2^4 - 1\n\nbase64 += encodings[a] + encodings[b] + encodings[c] + '='\n}\n\nreturn base64\n}\n\n\n\n\n\nAFRAME.registerComponent('mozilla-xr-ar', {\n schema: {\n takeOverCamera: {default: true},\n cameraUserHeight: {default: false},\n worldSensing: {default: true}\n },\n\n init: function () {\n this.onInit = this.onInit.bind(this);\n this.onWatch = this.onWatch.bind(this);\n\n this.forceResize = this.forceResize.bind(this);\n\n this.poseMatrix = new THREE.Matrix4();\n this.posePosition = new THREE.Vector3();\n this.poseQuaternion = new THREE.Quaternion();\n this.poseEuler = new THREE.Euler(0, 0, 0, 'YXZ');\n this.poseRotation = new THREE.Vector3();\n this.projectionMatrix = new THREE.Matrix4();\n this.viewMatrix = new THREE.Matrix4();\n\n this.onceSceneLoaded = this.onceSceneLoaded.bind(this);\n if (this.el.sceneEl.hasLoaded) {\n setTimeout(this.onceSceneLoaded);\n } else {\n this.el.sceneEl.addEventListener('loaded', this.onceSceneLoaded);\n }\n\n // Add planes handling, so we can do synchronous hit test.\n // From google-ar/WebARonARKit; also see webxr-polyfill/ARKitWrapper.js\n\n this.planes_ = new Map();\n this.anchors_ = new Map();\n },\n\n // For WebXR Viewer, we are currently directly hooking the callback\n // used to provide frame data, so we don't need to do anything in tick!\n\n takeOverCamera: function (camera) {\n this.arCamera = camera;\n camera.el.setAttribute('ar-camera', 'enabled', true);\n },\n\n onceSceneLoaded: function () {\n // Check if the low-level WebXR Viewer interfaces are there.\n if (!window.webkit || !window.webkit.messageHandlers) { return; }\n if (!window.webkit.messageHandlers.initAR) { return; }\n\n window['arkitCallback' + 0] = this.onInit;\n window['arkitCallback' + 1] = this.onWatch;\n\n // Compose data to use with initAR.\n var data = {\n options: {\n ui: {\n browser: true,\n points: true,\n focus: false,\n rec: true,\n rec_time: true,\n mic: false,\n build: false,\n plane: true,\n warnings: true,\n anchors: false,\n debug: true,\n statistics: false\n }\n },\n callback: 'arkitCallback0' // this.onInit as window callback\n };\n\n // Need these because WebXR Viewer...\n //if (window['setNativeTime']) {\n // console.log('window handler already defined for ', 'setNativeTime');\n //} else\n window['setNativeTime'] = function (data) {\n window.nativeTime = data.nativeTime;\n };\n [\n 'arkitStartRecording',\n 'arkitStopRecording',\n 'arkitDidMoveBackground',\n 'arkitWillEnterForeground',\n 'arkitInterrupted',\n 'arkitInterruptionEnded',\n 'arkitShowDebug',\n // elsewhere... 'arkitWindowResize',\n 'onError',\n 'arTrackingChanged',\n 'ios_did_receive_memory_warning',\n 'onComputerVisionData',\n // above... 'setNativeTime',\n 'userGrantedComputerVisionData',\n 'userGrantedWorldSensingData', // Needed for world sensing.\n ].forEach(function (eventName) {\n //if (window[eventName]) {\n // console.log('window handler already defined for ', eventName);\n //} else\n window[eventName] = function (data) {\n console.log(eventName + ':', data);\n };\n });\n\n // act like Chrome WebXR by forcibly showing AR button and making it work\n var vrmodeui = this.el.sceneEl.components['vr-mode-ui'];\n var newarbutton = vrmodeui.enterAREl.cloneNode(true);\n vrmodeui.enterAREl.parentNode.replaceChild(newarbutton, vrmodeui.enterAREl);\n vrmodeui.enterAREl = newarbutton;\n vrmodeui.enterAREl.classList.remove('a-hidden');\n var self = this;\n vrmodeui.enterAREl.onclick = function() {\n var scene = AFRAME.scenes[0];\n\n // Note we're in AR mode (the way WebXR handling does).\n scene.addState('ar-mode');\n\n // Kill the Cardboard display that gets in our way.\n scene.components['vr-mode-ui'].orientationModalEl.style='display:none!important';\n\n // Fake VR mode from enterVRSuccess.\n scene.addState('vr-mode');\n scene.emit('enter-vr', {target: scene});\n\n // Call initAR.\n window.webkit.messageHandlers.initAR.postMessage(data);\n \n // Kill broken wakelock!\n scene.wakelock.release();\n\n // Take over the scene camera, if so directed.\n // But wait a tick, because otherwise injected camera will not be present.\n if (self.data.takeOverCamera) {\n setTimeout(function () { self.takeOverCamera(scene.camera); });\n }\n\n let sz = new THREE.Vector2();\n let pixelRatio = scene.renderer.getPixelRatio();\n scene.renderer.getSize(sz);\n console.log(\"pixelRatio \", pixelRatio, \" size \", sz);\n\n // Ugly hack to get around WebXR Viewer resizing issue.\n scene.canvas.style.position = \"absolute !important\";\n scene.canvas.style.width = \"100% !important\";\n scene.canvas.style.height = \"100% !important\";\n\n // Force resize after we have access to data (?!)\n window.userGrantedWorldSensingData = function(data) {\n console.log('userGrantedWorldSensingData:', data);\n setTimeout(function () {\n self.forceResize(\n screen.width * window.devicePixelRatio,\n screen.height * window.devicePixelRatio);\n }, 100); // 1000 seems to be long enough initially\n };\n };\n },\n\n forceResize: function (sx, sy) {\n var sc = this.el.sceneEl, self = this;\n console.log('forceResize ', sx, sy,\n ' was ', \n sc.canvas.width, sc.canvas.height, \n screen.width, screen.height,\n window.devicePixelRatio, sc.renderer.getPixelRatio());\n sx = sx || this.forceResizeX; this.forceResizeX = sx;\n sy = sy || this.forceResizeY; this.forceResizeY = sy;\n sc.canvas.setAttribute('width', sx);\n sc.canvas.setAttribute('height', sy);\n sc.renderer.setPixelRatio(1);\n sc.camera.projectionMatrix.copy(self.projectionMatrix);\n sc.emit('rendererresize', null, false);\n },\n\n checkForARDisplay: function () {\n // Check if the low-level WebXR Viewer interfaces are there.\n if (!window.webkit || !window.webkit.messageHandlers) { return; }\n if (!window.webkit.messageHandlers.watchAR) { return; }\n\n // Mozilla WebXR Viewer detected.\n var self = this;\n self.arDisplay = true;\n\n\n // Compose data to use with watchAR.\n var data = {\n options: {\n location: true,\n camera: true,\n objects: true,\n light_intensity: true,\n worldSensing: this.data.worldSensing\n },\n callback: 'arkitCallback1' // this.onWatch as window callback\n };\n\n // Add resize handling.\n window['arkitWindowResize'] = function (data) {\n console.log('arkitWindowResize' + ':', data);\n\n // we're faking being in vr-mode anyway so resize will exit.\n //window.emit('resize', {target: window});\n\n // on iOS, AFRAME waits 100ms... \n setTimeout(function () {\n self.forceResize(\n data.width * window.devicePixelRatio,\n data.height * window.devicePixelRatio);\n }, 150); // 250 seems to be long enough\n };\n\n // Start watching AR.\n window.webkit.messageHandlers.watchAR.postMessage(data);\n },\n\n onInit: function (deviceId) {\n this.checkForARDisplay();\n },\n\n onWatch: function (data) {\n this.frameData = data;\n this.handleFrame(data);\n },\n\n handleFrame: function (data) {\n // Decompose to get camera pose.\n this.poseMatrix.fromArray(data.camera_transform);\n this.poseMatrix.decompose(this.posePosition, this.poseQuaternion, this.poseRotation); // poseRotation is really scale, we redo below\n this.poseEuler.setFromQuaternion(this.poseQuaternion);\n this.poseRotation.set(\n THREE.Math.RAD2DEG * this.poseEuler.x,\n THREE.Math.RAD2DEG * this.poseEuler.y,\n THREE.Math.RAD2DEG * this.poseEuler.z);\n\n this.projectionMatrix.fromArray(data.projection_camera);\n this.viewMatrix.fromArray(data.camera_view);\n\n // If we control a camera, and should apply user height, do it.\n if (this.arCamera && this.data.cameraUserHeight) {\n this.posePosition.y += this.arCamera.el.components.camera.data.userHeight;\n }\n\n // For A-Painter, detect bogus pose and fire poseFound / poseLost.\n var poseValid = this.posePosition.x || this.posePosition.y || this.posePosition.z || this.poseQuaternion.x || this.poseQuaternion.y || this.poseQuaternion.z;\n if (poseValid) {\n if (this.poseLost !== false) {\n this.poseLost = false;\n this.el.emit('poseFound');\n }\n } else {\n if (this.poseLost !== true) {\n this.poseLost = true;\n this.el.emit('poseLost', false);\n }\n }\n\n // Add planes handling, so we can do synchronous hit test.\n // From google-ar/WebARonARKit; also see webxr-polyfill/ARKitWrapper.js\n\n var i;\n var element;\n\n // WebXR Viewer returns geometry.vertices as an array of {x: number, y: number, y: number}\n // https://github.com/mozilla-mobile/webxr-ios/blob/c77b12c235e3960e2cd51538e086a38c83d8ec7c/XRViewer/ARKController/ARKController.m#L845\n // We transform this to a flatten array of number, like WebARonARCore.\n\n if(data.newObjects && data.newObjects.length){\n for (i = 0; i < data.newObjects.length; i++) {\n element = data.newObjects[i];\n if(element.plane_center){\n this.planes_.set(element.uuid, {\n id: element.uuid,\n center: element.plane_center,\n extent: [element.plane_extent.x, element.plane_extent.z],\n modelMatrix: element.transform,\n alignment: element.plane_alignment,\n vertices: convertVertices(element.geometry.vertices)\n });\n }else{\n var anchorData = {\n id: element.uuid,\n modelMatrix: element.transform\n };\n if (element.type === 'image') {\n anchorData.name = element.uuid;\n }\n this.anchors_.set(element.uuid, anchorData);\n }\n }\n }\n\n if(data.removedObjects && data.removedObjects.length){\n for (i = 0; i < data.removedObjects.length; i++) {\n element = data.removedObjects[i];\n if(this.planes_.get(element)){\n this.planes_.delete(element);\n }else{\n this.anchors_.delete(element);\n }\n }\n }\n\n if(data.objects && data.objects.length){\n for (i = 0; i < data.objects.length; i++) {\n element = data.objects[i];\n if(element.plane_center){\n var plane = this.planes_.get(element.uuid);\n if(!plane){\n this.planes_.set(element.uuid, {\n id: element.uuid,\n center: element.plane_center,\n extent: [element.plane_extent.x, element.plane_extent.z],\n modelMatrix: element.transform,\n alignment: element.plane_alignment,\n vertices: convertVertices(element.geometry.vertices)\n });\n } else {\n plane.center = element.plane_center;\n plane.extent = [element.plane_extent.x, element.plane_extent.z];\n plane.modelMatrix = element.transform;\n plane.alignment = element.plane_alignment;\n plane.vertices = convertVertices(element.geometry.vertices);\n }\n }else{\n var anchor = this.anchors_.get(element.uuid);\n if(!anchor){\n this.anchors_.set(element.uuid, {\n id: element.uuid,\n modelMatrix: element.transform\n });\n }else{\n anchor.modelMatrix = element.transform;\n }\n }\n }\n }\n },\n\n getPosition: function () {\n if (!this.arDisplay) { return null; }\n return this.posePosition;\n },\n\n getOrientation: function () {\n if (!this.arDisplay) { return null; }\n return this.poseQuaternion;\n },\n\n getRotation: function () {\n if (!this.arDisplay) { return null; }\n return this.poseRotation;\n },\n\n getProjectionMatrix: function () {\n if (!this.arDisplay) { return null; }\n return this.projectionMatrix;\n },\n\n // Link to new ARKit image marker and anchor support.\n\n addImage: function (name, url, physicalWidth) {\n if (!this.arDisplay) { return null; }\n/*\nNSDictionary *imageAnchorInfoDictionary = [message body];\nNSString *createDetectionImageCallback = [[message body] objectForKey:WEB_AR_CALLBACK_OPTION];\n// callback\n\nCGFloat physicalWidth = [referenceImageDictionary[@\"physicalWidth\"] doubleValue];\nNSString* b64String = referenceImageDictionary[@\"buffer\"];\nsize_t width = (size_t) [referenceImageDictionary[@\"imageWidth\"] intValue];\nsize_t height = (size_t) [referenceImageDictionary[@\"imageHeight\"] intValue];\n...\nresult.name = referenceImageDictionary[@\"uid\"];\n*/\n // NOTE: looks like WebXR Viewer won't load from URL,\n // so we need to convert from img element\n var aCanvas = document.createElement('canvas');\n var aContext = aCanvas.getContext('2d');\n var aImg; // Don't use element; chance of changed width/height.\n if (!aImg) {\n aImg = document.createElement('img');\n aImg.crossOrigin = 'anonymous';\n aImg.src = url;\n document.body.appendChild(aImg);\n }\n\n // The image needs to be loaded...\n if (!aImg.complete || !aImg.naturalHeight) {\n console.log('!!! addImage: !aImg.complete || !aImg.naturalHeight, aborting');\n return;\n } \n \n // The image needs to be have nonzero size...\n if (!aImg.width || !aImg.height) {\n console.log('!!! addImage: !aImg.width || !aImg.height, aborting');\n return;\n } \n\n aCanvas.width = aImg.width;\n aCanvas.height = aImg.height;\n aContext.drawImage(aImg, 0, 0);\n var aImageData = aContext.getImageData(0, 0, aImg.width, aImg.height);\n var b64ImageData = encode(aImageData.data);\n if (!b64ImageData) {\n console.log('!!! addImage: !b64ImageData, aborting');\n return;\n }\n\n // NOTE: also, WebXR Viewer doesn't pass back which image/name,\n // so we need a per-image/name callback\n window.callbackForCreateImageAnchorCounter = (window.callbackForCreateImageAnchorCounter || 0) + 1;\n var callbackName = 'callbackForCreateImageAnchor_' + window.callbackForCreateImageAnchorCounter;\n var imageName = name;\n //console.log('creating ', callbackName, ' for ', imageName);\n window[callbackName] = function (data) {\n //console.log(callbackName);\n //console.log(data);\n //var name = callbackName.substring(29);\n if (data.created !== undefined) {\n if (!data.created) {\n // we failed to create the image, for whatever reason.\n console.log('addImage: !created; ', data.error);\n delete window[callbackName];\n } else {\n //console.log('addImage: created, activating ', imageName);\n window.webkit.messageHandlers.activateDetectionImage.postMessage({\n callback: callbackName,\n uid: imageName\n });\n }\n } else\n if (data.activated !== undefined) {\n if (!data.activated) {\n // we failed to activate the image, for whatever reason.\n console.log('addImage: !activated; ', data.error);\n } else {\n //console.log('addImage: activated ', imageName);\n }\n delete window[callbackName];\n }\n };\n\n window.webkit.messageHandlers.createImageAnchor.postMessage({\n callback: callbackName,\n uid: name,\n buffer: b64ImageData,\n imageWidth: aImg.width,\n imageHeight: aImg.height,\n physicalWidth: physicalWidth // in meters\n });\n },\n\n removeImage: function (name) {\n if (!this.arDisplay) { return null; }\n/*\nNSDictionary *imageAnchorInfoDictionary = [message body];\nNSString *imageName = imageAnchorInfoDictionary[WEB_AR_DETECTION_IMAGE_NAME_OPTION];\n// detectionImageName\nNSString *deactivateDetectionImageCallback = [[message body] objectForKey:WEB_AR_CALLBACK_OPTION];\n// callback\n*/\n window.callbackForRemoveImageAnchorCounter = (window.callbackForRemoveImageAnchorCounter || 0) + 1;\n var callbackName = 'callbackForRemoveImageAnchor_' + window.callbackForRemoveImageAnchorCounter;\n var imageName = name;\n //console.log('creating ', callbackName, ' for ', imageName);\n window[callbackName] = function (data) {\n //console.log(callbackName);\n //console.log(data);\n\n if (data.deactivated !== undefined) {\n if (!data.deactivated) {\n console.log('!!! ' + callbackName + ': !deactivated', data.error);\n delete window[callbackName];\n } else {\n //console.log(callbackName + ': deactivated, destroying', imageName);\n }\n window.webkit.messageHandlers.destroyDetectionImage.postMessage({\n callback: callbackName,\n uid: imageName\n });\n }\n if (data.destroyed !== undefined) {\n if (!data.destroyed) {\n console.log('!!! ' + callbackName + ': !destroyed, ', data.error);\n } else {\n //console.log(callbackName + ': destroyed', imageName);\n }\n delete window[callbackName];\n }\n };\n\n window.webkit.messageHandlers.deactivateDetectionImage.postMessage({\n callback: callbackName,\n uid: imageName\n });\n },\n\n getAnchors: function () {\n return Array.from(this.anchors_.values());\n },\n\n // Use planes to do synchronous hit test.\n // From google-ar/WebARonARKit; also see webxr-polyfill/ARKitWrapper.js\n\n getPlanes: function () {\n return Array.from(this.planes_.values());\n },\n\n hitTestNoAnchor: (function () {\n // Temporary variables, only within closure scope.\n\n /**\n * The result of a raycast into the AR world encoded as a transform matrix.\n * This structure has a single property - modelMatrix - which encodes the\n * translation of the intersection of the hit in the form of a 4x4 matrix.\n * @constructor\n */\n function VRHit() {\n this.modelMatrix = new Float32Array(16);\n return this;\n };\n\n /**\n * Cached vec3, mat4, and quat structures needed for the hit testing to\n * avoid generating garbage.\n * @type {Object}\n */\n var hitVars = {\n rayStart: new THREE.Vector3(), //vec3.create(),\n rayEnd: new THREE.Vector3(), //vec3.create(),\n cameraPosition: new THREE.Vector3(), //vec3.create(),\n cameraQuaternion: new THREE.Quaternion(), //quat.create(),\t\n //modelViewMatrix: new THREE.Matrix4(), //mat4.create(),\n //projectionMatrix: new THREE.Matrix4(), //mat4.create(),\n projViewMatrix: new THREE.Matrix4(), //mat4.create(),\n worldRayStart: new THREE.Vector3(), //vec3.create(),\n worldRayEnd: new THREE.Vector3(), //vec3.create(),\n worldRayDir: new THREE.Vector3(), //vec3.create(),\n planeMatrix: new THREE.Matrix4(), //mat4.create(),\n planeMatrixInverse: new THREE.Matrix4(), //mat4.create(),\n planeExtent: new THREE.Vector3(), //vec3.create(),\n planePosition: new THREE.Vector3(), //vec3.create(),\n planeCenter: new THREE.Vector3(), //vec3.create(),\n planeNormal: new THREE.Vector3(), //vec3.create(),\n planeIntersection: new THREE.Vector3(), //vec3.create(),\n planeIntersectionLocal: new THREE.Vector3(), //vec3.create(),\n planeHit: new THREE.Matrix4(), //mat4.create()\n planeQuaternion: new THREE.Quaternion() // quat.create()\n };\n \n /**\n * Tests whether the given ray intersects the given plane.\n *\n * @param {!vec3} planeNormal The normal of the plane.\n * @param {!vec3} planePosition Any point on the plane.\n * @param {!vec3} rayOrigin The origin of the ray.\n * @param {!vec3} rayDirection The direction of the ray (normalized).\n * @return {number} The t-value of the intersection (-1 for none).\n */\n var rayIntersectsPlane = (function() {\n var rayToPlane = new THREE.Vector3();\n return function(planeNormal, planePosition, rayOrigin, rayDirection) {\n // assuming vectors are all normalized\n var denom = planeNormal.dot(rayDirection);\n rayToPlane.subVectors(planePosition, rayOrigin);\n return rayToPlane.dot(planeNormal) / denom;\n };\n })();\n \n /**\n * Sorts based on the distance from the VRHits to the camera.\n *\n * @param {!VRHit} a The first hit to compare.\n * @param {!VRHit} b The second hit item to compare.\n * @returns {number} -1 if a is closer than b, otherwise 1.\n */\n var sortFunction = function(a, b) {\n // Get the matrix of hit a.\n hitVars.planeMatrix.fromArray(a.modelMatrix);\n // Get the translation component of a's matrix.\n hitVars.planeIntersection.setFromMatrixPosition(hitVars.planeMatrix);\n // Get the distance from the intersection point to the camera.\n var distA = hitVars.planeIntersection.distanceTo(hitVars.cameraPosition);\n \n // Get the matrix of hit b.\n hitVars.planeMatrix.fromArray(b.modelMatrix);\n // Get the translation component of b's matrix.\n hitVars.planeIntersection.setFromMatrixPosition(hitVars.planeMatrix);\n // Get the distance from the intersection point to the camera.\n var distB = hitVars.planeIntersection.distanceTo(hitVars.cameraPosition);\n \n // Return comparison of distance from camera to a and b.\n return distA < distB ? -1 : 1;\n };\n \n return function(x, y) {\n // Coordinates must be in normalized screen space.\n if (x < 0 || x > 1 || y < 0 || y > 1) {\n throw new Error(\n \"hitTest - x and y values must be normalized [0,1]!\")\n ;\n }\n \n var hits = [];\n // If there are no anchors detected, there will be no hits.\n var planes = this.getPlanes();\n if (!planes || planes.length === 0) {\n return hits;\n }\n\n // Create a ray in screen space for the hit test ([-1, 1] with y flip).\n hitVars.rayStart.set(2 * x - 1, 2 * (1 - y) - 1, 0);\n hitVars.rayEnd.set(2 * x - 1, 2 * (1 - y) - 1, 1);\n\n // Set the projection matrix.\n //hitVars.projectionMatrix.fromArray(this.projectionMatrix);\n \n // Set the model view matrix.\n //hitVars.modelViewMatrix.fromArray(this.viewMatrix);\n \n // Combine the projection and model view matrices.\n hitVars.planeMatrix.multiplyMatrices(\n this.projectionMatrix, //hitVars.projectionMatrix,\n this.viewMatrix //hitVars.modelViewMatrix\n );\n // Invert the combined matrix because we need to go from screen -> world.\n hitVars.projViewMatrix.getInverse(hitVars.planeMatrix);\n \n // Transform the screen-space ray start and end to world-space.\n hitVars.worldRayStart.copy(hitVars.rayStart)\n .applyMatrix4(hitVars.projViewMatrix);\n hitVars.worldRayEnd.copy(hitVars.rayEnd)\n .applyMatrix4(hitVars.projViewMatrix);\n \n // Subtract start from end to get the ray direction and then normalize.\n hitVars.worldRayDir.subVectors(\n hitVars.worldRayEnd,\n hitVars.worldRayStart\n ).normalize();\n\n // Go through all the anchors and test for intersections with the ray.\n for (var i = 0; i < planes.length; i++) {\n var plane = planes[i];\n // Get the anchor transform.\n hitVars.planeMatrix.fromArray(plane.modelMatrix);\n \n // Get the position of the anchor in world-space.\n hitVars.planeCenter.set(plane.center.x, plane.center.y, plane.center.z);\n hitVars.planePosition.copy(hitVars.planeCenter)\n .applyMatrix4(hitVars.planeMatrix)\n\n hitVars.planeAlignment = plane.alignment\n \n // Get the plane normal.\n if (hitVars.planeAlignment === 0) {\n hitVars.planeNormal.set(0, 1, 0);\n } else {\n hitVars.planeNormal.set(hitVars.planeMatrix[4], hitVars.planeMatrix[5], hitVars.planeMatrix[6]);\n }\n \n // Check if the ray intersects the plane.\n var t = rayIntersectsPlane(\n hitVars.planeNormal,\n hitVars.planePosition,\n hitVars.worldRayStart,\n hitVars.worldRayDir\n );\n\n // if t < 0, there is no intersection.\n if (t < 0) {\n continue;\n }\n \n // Calculate the actual intersection point.\n hitVars.planeIntersectionLocal.copy(hitVars.worldRayDir).multiplyScalar(t);\n hitVars.planeIntersection.addVectors(\n hitVars.worldRayStart,\n hitVars.planeIntersectionLocal\n );\n // Get the plane extents (extents are in plane local space).\n hitVars.planeExtent.set(plane.extent[0], 0, plane.extent[1]);\n /*\n ///////////////////////////////////////////////\n // Test by converting extents to world-space.\n // TODO: get this working to avoid matrix inversion in method below.\n \n // Get the rotation component of the anchor transform.\n mat4.getRotation(hitVars.planeQuaternion, hitVars.planeMatrix);\n \n // Convert the extent into world space.\n vec3.transformQuat(\n hitVars.planeExtent, hitVars.planeExtent, hitVars.planeQuaternion);\n \n // Check if intersection is outside of the extent of the anchor.\n if (Math.abs(hitVars.planeIntersection[0] - hitVars.planePosition[0]) > hitVars.planeExtent[0] / 2) {\n continue;\n }\n if (Math.abs(hitVars.planeIntersection[2] - hitVars.planePosition[2]) > hitVars.planeExtent[2] / 2) {\n continue;\n }\n ////////////////////////////////////////////////\n */\n \n ////////////////////////////////////////////////\n // Test by converting intersection into plane-space.\n hitVars.planeMatrixInverse.getInverse(hitVars.planeMatrix);\n hitVars.planeIntersectionLocal.copy(hitVars.planeIntersection)\n .applyMatrix4(hitVars.planeMatrixInverse);\n \n // Check if intersection is outside of the extent of the anchor.\n // Tolerance is added to match the behavior of the native hitTest call.\n var tolerance = 0.0075;\n if (\n Math.abs(hitVars.planeIntersectionLocal.x) >\n hitVars.planeExtent.x / 2 + tolerance\n ) {\n continue;\n }\n if (\n Math.abs(hitVars.planeIntersectionLocal.z) >\n hitVars.planeExtent.z / 2 + tolerance\n ) {\n continue;\n }\n \n ////////////////////////////////////////////////\n \n // The intersection is valid - create a matrix from hit position.\n hitVars.planeQuaternion.setFromRotationMatrix(hitVars.planeMatrix);\n hitVars.planeHit.makeRotationFromQuaternion(hitVars.planeQuaternion).setPosition(hitVars.planeIntersection);\n var hit = new VRHit();\n for (var j = 0; j < 16; j++) {\n hit.modelMatrix[j] = hitVars.planeHit.elements[j];\n }\n hit.i = i;\n hits.push(hit);\n }\n \n\n // Sort the hits by distance.\n hits.sort(sortFunction);\n return hits;\n };\n })(),\n\n hitAR: (function () {\n // Temporary variables, only within closure scope.\n var transform = new THREE.Matrix4();\n var hitpoint = new THREE.Vector3();\n var hitquat = new THREE.Quaternion();\n var hitscale = new THREE.Vector3();\n var worldpos = new THREE.Vector3();\n\n // The desired function, which this returns.\n return function (x, y, el, raycasterEl) {\n if (!this.arDisplay) { return []; }\n\n var hit = this.hitTestNoAnchor(x, y);\n\n // Process AR hits.\n var hitsToReturn = [];\n for (var i = 0; hit && i < hit.length; i++) {\n transform.fromArray(hit[i].modelMatrix);\n transform.decompose(hitpoint, hitquat, hitscale);\n raycasterEl.object3D.getWorldPosition(worldpos);\n\n hitsToReturn.push({\n distance: hitpoint.distanceTo(worldpos),\n point: hitpoint.clone(), // Vector3\n object: (el && el.object3D) || this.el.sceneEl.object3D\n/*\n // We don't have any of these properties...\n face: undefined, // Face3\n faceIndex: undefined,\n index: undefined,\n uv: undefined // Vector2\n*/\n });\n }\n return hitsToReturn;\n } \n })()\n});\n","/* global AFRAME, THREE, VRFrameData */\n\nAFRAME.registerComponent('webxr-ar', {\n schema: {\n takeOverCamera: {default: true},\n cameraUserHeight: {default: false},\n worldSensing: {default: false} // currently unused\n },\n\n init: function () {\n this.posePosition = new THREE.Vector3();\n this.poseQuaternion = new THREE.Quaternion();\n this.poseEuler = new THREE.Euler(0, 0, 0, 'YXZ');\n this.poseRotation = new THREE.Vector3();\n this.projectionMatrix = new THREE.Matrix4();\n\n this.onceSceneLoaded = this.onceSceneLoaded.bind(this);\n if (this.el.sceneEl.hasLoaded) {\n setTimeout(this.onceSceneLoaded);\n } else {\n this.el.sceneEl.addEventListener('loaded', this.onceSceneLoaded);\n }\n\n // Add planes handling, so we can do synchronous hit test.\n\n this.rawPlanes_ = null;\n this.planes_ = new Map();\n this.anchors_ = new Map();\n },\n\n convertPolygonToVertices: function(polygon) {\n return newVertices;\n },\n\n convertedPlane: function(rawPlane, pose) {\n var mins = [0, 0];\n var maxs = [0, 0];\n var verticesLength = rawPlane.polygon.length;\n var newVertices = new Float32Array(verticesLength * 3);\n var i = 0;\n var j = 0;\n var vertex;\n for (i = 0; i < verticesLength; i++) {\n vertex = rawPlane.polygon[i];\n newVertices[j] = vertex.x;\n newVertices[j + 1] = vertex.y;\n newVertices[j + 2] = vertex.z;\n j += 3;\n if (i == 0) {\n mins[0] = maxs[0] = vertex.x;\n mins[1] = maxs[1] = vertex.z;\n } else {\n if (mins[0] > vertex.x) { mins[0] = vertex.x; }\n if (maxs[0] < vertex.x) { maxs[0] = vertex.x; }\n if (mins[1] > vertex.z) { mins[1] = vertex.z; }\n if (maxs[1] < vertex.z) { maxs[1] = vertex.z; }\n }\n }\n var position = pose.transform.position;\n rawPlane.position.set(position.x, position.y, position.z);\n var converted = {\n id: rawPlane.id,\n center: rawPlane.position,\n extent: [maxs[0] - mins[0], maxs[1] - mins[1]],\n modelMatrix: pose.transform.matrix,\n alignment: rawPlane.orientation != 'Horizontal' ? 1 : 0,\n vertices: newVertices\n };\n return converted;\n },\n\n rawPlaneRemoved: function(rawPlane) {\n // remove the converted plane\n this.planes_.delete(rawPlane.id);\n },\n\n rawPlaneUpdated: function(rawPlane, pose) {\n // convert the updated plane\n this.planes_.set(rawPlane.id, this.convertedPlane(rawPlane, pose));\n },\n\n rawPlaneNotUpdated: function(rawPlane, pose) {\n // FIXME: check is broken so update anyway\n this.rawPlaneUpdated(rawPlane, pose);\n // do nothing\n },\n\n rawPlaneCreated: function(rawPlane, pose) {\n // assign and attach an id... for now, use Math.random()\n rawPlane.id = Math.random().toString().substring(2);\n rawPlane.position = new THREE.Vector3();\n // convert the plane\n this.planes_[rawPlane.id] = this.convertedPlane(rawPlane, pose);\n },\n\n tick: function (t, dt) {\n let frame = this.el.sceneEl.frame;\n if (!this.arDisplay\n || !frame\n || !frame.worldInformation) { return; }\n\n // use the planes information\n let world = frame.worldInformation;\n\n // check for removed planes\n this.rawPlanes_ && this.rawPlanes_.forEach(plane => {\n if(!world.detectedPlanes || !world.detectedPlanes.has(plane)) {\n // Handle removed plane - `plane` was present in previous frame but is no longer tracked.\n this.rawPlaneRemoved(plane);\n }\n });\n\n // check for changed planes\n let timestamp = this.el.sceneEl.time;\n world.detectedPlanes && world.detectedPlanes.forEach(plane => {\n let planePose = frame.getPose(plane.planeSpace, this.refSpace);\n if (this.rawPlanes_.has(plane)) {\n if(plane.lastChangedTime == timestamp) {\n // Handle previously seen plane that was updated in current frame.\n this.rawPlaneUpdated(plane, planePose);\n } else {\n // Handle previously seen plane that was not updated in current frame.\n // Depending on the application, this could be a no-op.\n this.rawPlaneNotUpdated(plane, planePose);\n }\n } else {\n // Handle new plane.\n this.rawPlaneCreated(plane, planePose);\n }\n });\n \n this.rawPlanes_ = world.detectedPlanes;\n },\n\n takeOverCamera: function (camera) {\n this.arCamera = camera;\n camera.isARPerspectiveCamera = true; // HACK - is this necessary?\n camera.vrDisplay = this.arDisplay; // HACK - is this necessary?\n camera.el.setAttribute('ar-camera', 'enabled', true);\n },\n\n onceSceneLoaded: function () {\n var self = this;\n window.addEventListener('ardisplayconnect', function () {\n if (!self.arDisplay) { self.checkForARDisplay(); }\n });\n\n // Check now for AR display.\n this.checkForARDisplay();\n },\n\n checkForARDisplay: function () {\n // check to see if webxr ar mode is supported\n if (!navigator.xr || !navigator.xr.isSessionSupported) { return; }\n\n var self = this;\n self.arDisplay = {type: 'webxr-ar'};\n\n navigator.xr.isSessionSupported('immersive-ar').then(function(supported) {\n if (supported) {\n let ourRequiredFeatures = ['local-floor'];\n let ourOptionalFeatures = [];\n (self.data.worldSensing ? ourRequiredFeatures : ourOptionalFeatures).push('hit-test');\n let existingFeatures = self.el.sceneEl.getAttribute('webxr');\n if (!existingFeatures) {\n // here, we assume we can set as map and not String (?) \n self.el.sceneEl.setAttribute('webxr', { \n requiredFeatures: ourRequiredFeatures.join(','), \n optionalFeatures: ourOptionalFeatures.join(',') \n });\n } else {\n // here, we assume we get and set as map and not String (?)\n // remove existing optional features from our optional\n existingFeatures.optionalFeatures.forEach(function (feature) {\n ourOptionalFeatures = ourOptionalFeatures.filter(function(value, index, arr){ return value != feature;});\n });\n // remove existing required features from our required\n existingFeatures.requiredFeatures.forEach(function (feature) {\n ourRequiredFeatures = ourRequiredFeatures.filter(function(value, index, arr){ return value != feature;});\n });\n // remove our required features from existing optional\n ourRequiredFeatures.forEach(function (feature) {\n existingFeatures.optionalFeatures = existingFeatures.optionalFeatures.filter(function(value, index, arr){ return value != feature;});\n });\n // add our required and optional features to the existing\n existingFeatures.requiredFeatures = existingFeatures.requiredFeatures.concat(ourRequiredFeatures);\n existingFeatures.optionalFeatures = existingFeatures.optionalFeatures.concat(ourOptionalFeatures);\n\n self.el.sceneEl.setAttribute('webxr', existingFeatures);\n }\n\n self.el.sceneEl.setAttribute('vr-mode-ui', \"enabled\", \"true\");\n // auto-entering AR doesn't work.\n\n self.xrHitTestSource = null;\n self.viewerSpace = null;\n self.refSpace = null;\n\n self.el.sceneEl.renderer.xr.addEventListener('sessionend', (ev) => {\n self.viewerSpace = null;\n self.refSpace = null;\n self.xrHitTestSource = null;\n });\n self.el.sceneEl.renderer.xr.addEventListener('sessionstart', (ev) => {\n let session = self.el.sceneEl.renderer.xr.getSession();\n let el = self.el.sceneEl.canvas;\n\n session.addEventListener('selectstart', function (e) {\n // dispatch touchstart\n var pageX = e.inputSource.gamepad.axes[0];\n var pageY = e.inputSource.gamepad.axes[1];\n setTimeout(() => {\n var event = new TouchEvent('touchstart', {\n view: window,\n bubbles: true,\n cancelable: true\n });\n event.targetTouches = [{ pageX: pageX, pageY: pageY }];\n el.dispatchEvent(event);\n });\n });\n\n session.addEventListener('selectend', function (e) {\n // dispatch touchend\n var pageX = e.inputSource.gamepad.axes[0];\n var pageY = e.inputSource.gamepad.axes[1];\n setTimeout(() => {\n var event = new TouchEvent('touchend', {\n view: window,\n bubbles: true,\n cancelable: true\n });\n event.targetTouches = [{ pageX: pageX, pageY: pageY }];\n el.dispatchEvent(event);\n });\n });\n\n session.addEventListener('select', function (e) {\n // dispatch click\n var pageX = e.inputSource.gamepad.axes[0];\n var pageY = e.inputSource.gamepad.axes[1];\n setTimeout(() => {\n var event = new MouseEvent('click', { \n clientX: pageX, \n clientY: pageY, \n bubbles: true,\n cancelable: true\n });\n el.dispatchEvent(event);\n });\n });\n\n session.requestReferenceSpace('viewer').then((space) => {\n self.viewerSpace = space;\n if (self.data.worldSensing) {\n session.requestHitTestSource({space: self.viewerSpace})\n .then((hitTestSource) => {\n self.xrHitTestSource = hitTestSource;\n })\n }\n });\n\n session.requestReferenceSpace('local-floor').then((space) => {\n self.refSpace = space;\n });\n\n // Ask for planes, if we should.\n if (self.data.worldSensing) {\n session.updateWorldTrackingState({planeDetectionState : {enabled : true}});\n }\n });\n }\n });\n },\n\n getPosition: function () {\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\n return this.posePosition;\n },\n\n getOrientation: function () {\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\n return this.poseQuaternion;\n },\n\n getRotation: function () {\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\n return this.poseRotation;\n },\n\n getProjectionMatrix: function () {\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\n return this.projectionMatrix;\n },\n\n hitAR: (function () { \n // Temporary variables, only within closure scope.\n var transform = new THREE.Matrix4();\n var hitpoint = new THREE.Vector3();\n var hitquat = new THREE.Quaternion();\n var hitscale = new THREE.Vector3();\n var worldpos = new THREE.Vector3();\n \n // The desired function, which this returns.\n return function (x, y, el, raycasterEl) {\n if (!this.arDisplay) { return []; }\n var hitsToReturn = [];\n\n if (this.el.sceneEl.is('ar-mode')) {\n if (!this.viewerSpace) return;\n\n let frame = this.el.sceneEl.frame;\n let xrViewerPose = frame.getViewerPose(this.refSpace);\n\n if (this.xrHitTestSource && xrViewerPose) {\n let hitTestResults = frame.getHitTestResults(this.xrHitTestSource);\n\n // Process AR hits.\n var hitsToReturn = [];\n for (var i = 0; hitTestResults && i < hitTestResults.length; i++) {\n let pose = hitTestResults[i].getPose(this.refSpace);\n transform.fromArray(pose.transform.matrix);\n hitpoint.setFromMatrixPosition(transform); //transform.decompose(hitpoint, hitquat, hitscale);\n raycasterEl.object3D.getWorldPosition(worldpos);\n\n hitsToReturn.push({\n distance: hitpoint.distanceTo(worldpos),\n point: hitpoint.clone(), // Vector3\n object: (el && el.object3D) || this.el.sceneEl.object3D\n/*\n // We don't have any of these properties...\n face: undefined, // Face3\n faceIndex: undefined,\n index: undefined,\n uv: undefined // Vector2\n*/\n });\n }\n }\n }\n\n return hitsToReturn;\n }\n })(),\n\n // Link to image marker and anchor support.\n\n addImage: function (name, url, physicalWidth) {\n if (!this.arDisplay) { return null; }\n\n return null;\n },\n\n removeImage: function (name) {\n if (!this.arDisplay) { return null; }\n\n return null;\n },\n\n getAnchors: function () {\n return Array.from(this.anchors_.values());\n },\n\n // Use planes to do synchronous hit test.\n\n getPlanes: function () {\n return Array.from(this.planes_.values());\n }\n});\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/ar-anchors.js","webpack:///./src/ar-camera.js","webpack:///./src/ar-images.js","webpack:///./src/ar-planes.js","webpack:///./src/ar-raycaster.js","webpack:///./src/ar.js","webpack:///./src/index.js","webpack:///./src/mozilla-xr-ar.js","webpack:///./src/webxr-ar.js"],"names":[],"mappings":";QAAA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;;;QAGA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA,0CAA0C,gCAAgC;QAC1E;QACA;;QAEA;QACA;QACA;QACA,wDAAwD,kBAAkB;QAC1E;QACA,iDAAiD,cAAc;QAC/D;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,yCAAyC,iCAAiC;QAC1E,gHAAgH,mBAAmB,EAAE;QACrI;QACA;;QAEA;QACA;QACA;QACA,2BAA2B,0BAA0B,EAAE;QACvD,iCAAiC,eAAe;QAChD;QACA;QACA;;QAEA;QACA,sDAAsD,+DAA+D;;QAErH;QACA;;;QAGA;QACA;;;;;;;;;;;;AClFA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,CAAC;;;;;;;;;;;;ACpBD;;AAEA;AACA;AACA,cAAc;AACd,GAAG;;AAEH;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA,6BAA6B,QAAQ;;AAErC;AACA,mBAAmB,QAAQ;;AAE3B;AACA;AACA;AACA,cAAc,uCAAuC;;AAErD;AACA;AACA;AACA,cAAc,uCAAuC;;AAErD;AACA;AACA;AACA,mBAAmB,4DAA4D;AAC/E,K;AACA,GAAG;;AAEH;AACA;AACA;AACA,2CAA2C,QAAQ;AACnD;AACA;AACA;AACA,G;AACA,CAAC;;;;;;;;;;;;AC9DD;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH,CAAC;;;;;;;;;;;;AC3BD;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA,iCAAiC;AACjC;AACA,iCAAiC;AACjC,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;;AAE5B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,eAAe,2BAA2B;AAC1C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;;AAEA,qBAAqB;AACrB,sCAAsC,iCAAiC;;AAEvE;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,2BAA2B,iCAAiC;AAC5D,4BAA4B,oCAAoC,E;AAChE,kCAAkC,qCAAqC;;AAEvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,M;AACA,GAAG;AACH,CAAC;;;;;;;;;;;;ACnND;;AAEA;AACA;AACA,0C;AACA;;AAEA;AACA,QAAQ,aAAa;AACrB,QAAQ,aAAa;AACrB,SAAS;AACT,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,yCAAyC,WAAW;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,oBAAoB,+DAA+D;AACnF,2CAA2C,QAAQ;AACnD;AACA;AACA;AACA,G;AACA,CAAC;;;;;;;;;;;;;ACnED;;AAEA;AACA;AACA,qBAAqB,cAAc;AACnC,uBAAuB,eAAe;AACtC,mBAAmB,cAAc;AACjC,aAAa;AACb,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,E;AACP;AACA;AACA,GAAG;AACH;AACA;AACA,GAAG;AACH;AACA;AACA,GAAG;AACH;AACA;AACA,GAAG;AACH;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA,kDAAkD,eAAe;AACjE;;AAEA;AACA;AACA,yBAAyB,0CAA0C;AACnE;AACA,CAAC;;;;;;;;;;;;ACvDD,mBAAO,CAAC,qCAAY;AACpB;AACA,mBAAO,CAAC,+CAAiB;AACzB,mBAAO,CAAC,uCAAa;AACrB,mBAAO,CAAC,yCAAc;AACtB,mBAAO,CAAC,uCAAa;AACrB,mBAAO,CAAC,yBAAM;AACd,mBAAO,CAAC,uCAAa;AACrB,mBAAO,CAAC,6CAAgB;;;;;;;;;;;;;ACRxB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,oBAAoB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;;AAEA,wBAAwB;;AAExB;AACA;AACA,CAAC;AACD;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,eAAe,gBAAgB;AAC/B;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,CAAC;AACD;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;AAMA;AACA;AACA,yBAAyB,cAAc;AACvC,2BAA2B,eAAe;AAC1C,uBAAuB;AACvB,KAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;AACA,uCAAuC;;AAEvC;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA,+DAA+D,QAAQ;AACvE,oDAAoD,QAAQ;;AAE5D;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;;AAEA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,kCAAkC,cAAc;;AAEhD;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,oCAAoC,mCAAmC,EAAE;AACzE;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC;AACrC,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA,+DAA+D,QAAQ;AACvE,qDAAqD,QAAQ;;AAE7D;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;;AAEA;AACA;AACA;;AAEA;AACA,mCAAmC,eAAe;;AAElD;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;;AAEA;AACA;AACA,KAAK;;AAEL;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,6FAA6F;AAC7F;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA,uCAAuC;;AAEvC;AACA;;AAEA,kEAAkE;AAClE;AACA;;AAEA;AACA,qBAAqB,4BAA4B;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,qBAAqB,gCAAgC;AACrD;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA,qBAAqB,yBAAyB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,eAAe;AACf;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA,8BAA8B,aAAa;AAC3C;AACA,KAAK;;AAEL;AACA,8BAA8B,aAAa;AAC3C;AACA,KAAK;;AAEL;AACA,8BAA8B,aAAa;AAC3C;AACA,KAAK;;AAEL;AACA,8BAA8B,aAAa;AAC3C;AACA,KAAK;;AAEL;;AAEA;AACA,8BAA8B,aAAa;AAC3C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,sBAAsB;AACvC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,S;;AAEA;AACA;AACA;AACA;AACA,S;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,eAAe;AACf;AACA,WAAW;AACX;AACA;AACA;AACA,gDAAgD;AAChD,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA,8BAA8B,aAAa;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT,KAAK;;AAEL;AACA;AACA,KAAK;;AAEL;AACA,mCAAmC;;AAEnC;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,sBAAsB,MAAM;AAC5B,sBAAsB,MAAM;AAC5B,sBAAsB,MAAM;AAC5B,sBAAsB,MAAM;AAC5B,uBAAuB,OAAO;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;;AAEV;AACA;AACA;AACA,sBAAsB,OAAO;AAC7B,sBAAsB,OAAO;AAC7B,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,4BAA4B,mBAAmB;AAC/C;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gCAAgC,QAAQ;AACxC;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kCAAkC,WAAW;;AAE7C;;AAEA;AACA;AACA,2BAA2B,uBAAuB;AAClD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,S;AACA,KAAK;AACL,CAAC;;;;;;;;;;;;ACl2BD;;AAEA;AACA;AACA,yBAAyB,cAAc;AACvC,2BAA2B,eAAe;AAC1C,uBAAuB,eAAe;AACtC,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;;AAEA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,oBAAoB;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,yCAAyC,oBAAoB;AAC7D,yCAAyC,oBAAoB;AAC7D,yCAAyC,oBAAoB;AAC7D,yCAAyC,oBAAoB;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA,sCAAsC,QAAQ;;AAE9C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;;AAET;AACA,KAAK;;AAEL;AACA;AACA,4CAA4C;AAC5C,0CAA0C;AAC1C;AACA,KAAK;;AAEL;AACA;AACA;AACA,kCAAkC,0BAA0B;AAC5D,SAAS;;AAET;AACA;AACA,KAAK;;AAEL;AACA;AACA,gEAAgE,QAAQ;;AAExE;AACA,0BAA0B;;AAE1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uD;AACA;AACA;AACA,iBAAiB;AACjB,aAAa;AACb;AACA;AACA;AACA,iGAAiG,0BAA0B;AAC3H,iBAAiB;AACjB;AACA;AACA,iGAAiG,0BAA0B;AAC3H,iBAAiB;AACjB;AACA;AACA,6HAA6H,0BAA0B;AACvJ,iBAAiB;AACjB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB,gDAAgD,6BAA6B;AAC7E;AACA,qBAAqB;AACrB,iBAAiB;;AAEjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB,gDAAgD,6BAA6B;AAC7E;AACA,qBAAqB;AACrB,iBAAiB;;AAEjB;AACA;AACA;AACA;AACA;AACA,6D;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,qBAAqB;AACrB,iBAAiB;;AAEjB;AACA;AACA;AACA,sDAAsD,wBAAwB;AAC9E;AACA;AACA,yBAAyB;AACzB;AACA,iBAAiB;;AAEjB;AACA;AACA,iBAAiB;;AAEjB;AACA;AACA,sDAAsD,uBAAuB,gBAAgB;AAC7F;AACA,aAAa;AACb;AACA,SAAS;AACT,KAAK;;AAEL;AACA,8DAA8D,aAAa;AAC3E;AACA,KAAK;;AAEL;AACA,8DAA8D,aAAa;AAC3E;AACA,KAAK;;AAEL;AACA,8DAA8D,aAAa;AAC3E;AACA,KAAK;;AAEL;AACA,8DAA8D,aAAa;AAC3E;AACA,KAAK;;AAEL,yB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kCAAkC,WAAW;AAC7C;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,mCAAmC,6CAA6C;AAChF;AACA;AACA,kEAAkE;AAClE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;;AAEA;AACA;AACA,KAAK;;AAEL;;AAEA;AACA,8BAA8B,aAAa;;AAE3C;AACA,KAAK;;AAEL;AACA,8BAA8B,aAAa;;AAE3C;AACA,KAAK;;AAEL;AACA;AACA,KAAK;;AAEL;;AAEA;AACA;AACA;AACA,CAAC","file":"aframe-ar.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./src/index.js\");\n","/* global AFRAME, THREE */\n\nAFRAME.registerComponent('ar-anchors', {\n\n getSource: function () {\n var whichar;\n if (!this.source) {\n whichar = this.el.sceneEl.components['ar'];\n if (whichar) {\n this.source = whichar.getSource();\n }\n }\n return this.source;\n },\n\n getAnchors: function () {\n var source = this.getSource();\n if (!source || !source.getAnchors) return undefined;\n return source.getAnchors();\n }\n});\n","/* global AFRAME */\n\nAFRAME.registerComponent('ar-camera', {\n schema: {\n enabled: {default:true}\n },\n\n init: function () {\n var lookControls = this.el.getAttribute('look-controls');\n this.wasLookControlsEnabled = lookControls ? lookControls.enabled : false;\n },\n\n update: function (oldData) {\n if (!oldData || oldData.enabled !== this.data.enabled) {\n // Value changed, so react accordingly.\n if (this.data.enabled) {\n // Save camera look-controls enabled, and turn off for AR.\n var lookControls = this.el.getAttribute('look-controls');\n this.wasLookControlsEnabled = lookControls ? lookControls.enabled : false;\n if (this.wasLookControlsEnabled) {\n this.el.setAttribute('look-controls', 'enabled', false);\n }\n } else {\n // Restore camera look-controls enabled.\n if (this.wasLookControlsEnabled) {\n this.el.setAttribute('look-controls', 'enabled', true);\n }\n }\n }\n },\n \n tick: function (t, dt) {\n if (!this.data.enabled) { return; }\n \n var whichar = this.checkWhichAR();\n if (!whichar) { return; }\n \n // Apply the pose position via setAttribute,\n // so that other A-Frame components can see the values.\n var pos = whichar.getPosition();\n if (pos) { this.el.setAttribute('position', pos); }\n\n // Apply the pose rotation via setAttribute,\n // so that other A-Frame components can see the values.\n var rot = whichar.getRotation();\n if (rot) { this.el.setAttribute('rotation', rot); }\n\n // Apply the projection matrix, if we're not in VR.\n if (!this.el.sceneEl.is('vr-mode')) {\n var matrix = whichar.getProjectionMatrix();\n if (matrix) { this.el.components.camera.camera.projectionMatrix = matrix; }\n } \n },\n \n checkWhichAR: function () {\n if (!this.whichar) {\n var whichar = this.el.sceneEl.components['ar'].getSource();\n if (!whichar || !whichar.arDisplay) { return; }\n this.whichar = whichar;\n }\n return this.whichar;\n } \n});\n","/* global AFRAME, THREE */\n\nAFRAME.registerComponent('ar-images', {\n\n getSource: function () {\n var whichar;\n if (!this.source) {\n whichar = this.el.sceneEl.components['ar'];\n if (whichar) {\n this.source = whichar.getSource();\n }\n }\n return this.source;\n },\n\n addImage: function (name, url, physicalWidth) {\n var source = this.getSource();\n if (!source || !source.addImage) return undefined;\n return source.addImage(name, url, physicalWidth);\n },\n\n removeImage: function (name) {\n var source = this.getSource();\n if (!source || !source.removeImage) return undefined;\n return source.removeImage(name);\n },\n\n});\n","/* global AFRAME, THREE */\n\nAFRAME.registerComponent('ar-planes', {\n\n getPlaneSource: function () {\n var whichar;\n if (!this.planeSource) {\n whichar = this.el.sceneEl.components['ar'];\n if (whichar) {\n this.planeSource = whichar.getSource();\n }\n }\n return this.planeSource;\n },\n\n getPlanes: function () {\n var planeSource = this.getPlaneSource();\n if (!planeSource || !planeSource.getPlanes) return undefined;\n return planeSource.getPlanes();\n },\n\n init: function () {\n // Remember planes when we see them.\n this.planes = {};\n this.anchorsAdded = [];\n this.anchorsAddedDetail = {type:'added', anchors: this.anchorsAdded};\n this.anchorsUpdated = [];\n this.anchorsUpdatedDetail = {type:'updated', anchors: this.anchorsUpdated};\n this.anchorsRemoved = [];\n this.anchorsRemovedDetail = {type:'removed', anchors: this.anchorsRemoved};\n },\n\n tick: (function (t, dt) {\n // Create the temporary variables we will reuse, if needed.\n var tempScale = new THREE.Vector3(1, 1, 1);\n var tempMat4 = new THREE.Matrix4();\n var tempPosition = new THREE.Vector3();\n var tempQuaternion = new THREE.Quaternion();\n\n // The actual function, which we return.\n return function (t, dt) {\n // Get the list of planes.\n var planes = this.getPlanes();\n if (!planes) { return; }\n\n // Ideally we would have either events, or separate lists for added / updated / removed.\n var addedThese = [];\n var updatedThese = [];\n var removedThese = [];\n\n // Because we don't have an indication of added / updated / removed,\n // try to keep track ourselves.\n var seenThese = {};\n var i;\n\n // Iterate over the available planes.\n for (i=0; planes && i 0) {\n // Reuse the same event detail to avoid making garbage.\n // TODO: Reuse same CustomEvent?\n this.anchorsAddedDetail.anchors = addedThese;\n this.el.emit('anchorsadded', this.anchorsAddedDetail);\n }\n\n // Replace the old list.\n this.anchorsUpdated = updatedThese;\n // Emit event if list isn't empty.\n if (updatedThese.length > 0) {\n // Reuse the same event detail to avoid making garbage.\n // TODO: Reuse same CustomEvent?\n this.anchorsUpdatedDetail.anchors = updatedThese;\n this.el.emit('anchorsupdated', this.anchorsUpdatedDetail);\n }\n\n // Replace the old list.\n this.anchorsRemoved = removedThese;\n // Emit event if list isn't empty.\n if (removedThese.length > 0) {\n // Reuse the same event detail to avoid making garbage.\n // TODO: Reuse same CustomEvent?\n this.anchorsRemovedDetail.anchors = removedThese;\n this.el.emit('anchorsremoved', this.anchorsRemovedDetail);\n }\n }; \n })()\n});\n","/* global AFRAME */\n\n// ar-raycaster modifies raycaster to append AR hit, if any.\n// But note that current AR hit API does not support orientation as input.\nAFRAME.registerComponent('ar-raycaster', { \n dependencies: ['raycaster'],\n \n schema: {\n x: {default: 0.5},\n y: {default: 0.5},\n el: {type: 'selector'}\n },\n \n init: function () {\n // HACK: monkey-patch raycaster to append AR hit result\n this.raycaster = this.el.components['raycaster'].raycaster;\n this.raycasterIntersectObjects = this.raycaster.intersectObjects.bind(this.raycaster);\n this.raycaster.intersectObjects = this.intersectObjects.bind(this);\n },\n \n update: function (oldData) {\n if (!this.data.el) {\n // If not given some other element, return hit against the scene.\n // HACK: But that means we need its object3D to have an el.\n if (!this.el.sceneEl.object3D.el) {\n this.el.sceneEl.object3D.el = this.el.sceneEl;\n }\n }\n },\n \n intersectObjects: function (objects, recursive, rawIntersections) {\n // it appears that intersectObjects is now returning in rawIntersections\n var results = this.raycasterIntersectObjects(objects, recursive, rawIntersections);\n // Tack on AR hit result, if any.\n var hitARResults = this.hitAR();\n if (hitARResults && hitARResults.length) {\n if (rawIntersections) {\n hitARResults.forEach((hit) => rawIntersections.push(hit));\n results = rawIntersections;\n } else {\n hitARResults.forEach((hit) => results.push(hit));\n }\n }\n return results;\n }, \n \n hitAR: function () {\n var whichar = this.checkWhichAR();\n if (!whichar || !whichar.arDisplay) { return []; }\n var x = this.data.x;\n var y = this.data.y;\n if (arguments.length >= 2) {\n x = arguments[0];\n y = arguments[1];\n }\n return whichar.hitAR(x, y, this.data.el, this.el);\n },\n\n checkWhichAR: function () {\n if (!this.whichar) {\n var whichar = this.el.sceneEl.components['ar'];\n if (whichar) { whichar = whichar.getSource ? whichar.getSource() : undefined; }\n if (!whichar || !whichar.arDisplay) { return; }\n this.whichar = whichar;\n }\n return this.whichar;\n } \n});\n\n","/* global AFRAME */\n\nAFRAME.registerComponent('ar', {\n schema: {\n takeOverCamera: {default: true},\n cameraUserHeight: {default: false},\n worldSensing: {default: true},\n hideUI: {default: false}\n },\n dependencies: ['webxr-ar', 'mozilla-xr-ar', 'ar-planes', 'ar-anchors'],\n getSource: function () {\n var whichar;\n if (!this.source) {\n var self = this;\n self.dependencies.forEach(function(sys) {\n whichar = self.el.sceneEl.components[sys];\n if (whichar && whichar.arDisplay) {\n self.source = whichar;\n }\n });\t\n }\n return this.source;\n },\n getPlanes: function () {\n return this.source ? this.source.getPlanes() : undefined;\n },\n getAnchors: function () {\n return this.source ? this.source.getAnchors() : undefined;\n },\n addImage: function (name, url, physicalWidth) {\n return this.source.addImage(name, url, physicalWidth);\n },\n removeImage: function (name) {\n return this.source.removeImage(name);\n },\n init: function () {\n var options = {\n takeOverCamera: this.data.takeOverCamera,\n cameraUserHeight: this.data.cameraUserHeight,\n worldSensing: this.data.worldSensing\n };\n\n var self = this;\n this.dependencies.forEach(function(sys) {\n self.el.setAttribute(sys, options);\n });\n\n if (this.data.hideUI) {\n this.el.sceneEl.setAttribute('vr-mode-ui', {enabled: false});\n }\n\n // Ensure passthrough is visible, make sure A-Frame styles don't interfere.\n document.head.insertAdjacentHTML('beforeend', \n '');\n }\n});\n","require('./webxr-ar');\n//require('./three-ar');\nrequire('./mozilla-xr-ar');\nrequire('./ar-planes');\nrequire('./ar-anchors');\nrequire('./ar-images');\nrequire('./ar');\nrequire('./ar-camera');\nrequire('./ar-raycaster');\n\n","/* global AFRAME, THREE */\n\nfunction convertVertices(vertices) {\n var verticesLength = vertices.length;\n var newVertices = new Float32Array(verticesLength * 3);\n var i = 0;\n var j = 0;\n var vertex;\n for (i = 0; i < verticesLength; i++) {\n vertex = vertices[i];\n newVertices[j] = vertex.x;\n newVertices[j + 1] = vertex.y;\n newVertices[j + 2] = vertex.z;\n j += 3;\n }\n return newVertices;\n}\n\n\nfunction encode(buffer) {\nvar base64 = ''\nvar encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\n\nvar bytes = buffer; // assume it's a typedArrayBuffer \n \nif (buffer instanceof ArrayBuffer) {\nbytes = new Uint8Array(arrayBuffer)\n} else if (buffer instanceof ImageData) {\nbytes = buffer.data\n}\n\nvar byteLength = buffer.length\nvar byteRemainder = byteLength % 3\nvar mainLength = byteLength - byteRemainder\n\nvar a, b, c, d\nvar chunk\n\n// Main loop deals with bytes in chunks of 3\nfor (var i = 0; i < mainLength; i = i + 3) {\n// Combine the three bytes into a single integer\nchunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]\n\n// Use bitmasks to extract 6-bit segments from the triplet\na = (chunk & 16515072) >> 18 // 16515072 = (2^6 - 1) << 18\nb = (chunk & 258048) >> 12 // 258048 = (2^6 - 1) << 12\nc = (chunk & 4032) >> 6 // 4032 = (2^6 - 1) << 6\nd = chunk & 63 // 63 = 2^6 - 1\n\n// Convert the raw binary segments to the appropriate ASCII encoding\nbase64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]\n}\n\n// Deal with the remaining bytes and padding\nif (byteRemainder == 1) {\nchunk = bytes[mainLength]\n\na = (chunk & 252) >> 2 // 252 = (2^6 - 1) << 2\n\n// Set the 4 least significant bits to zero\nb = (chunk & 3) << 4 // 3 = 2^2 - 1\n\nbase64 += encodings[a] + encodings[b] + '=='\n} else if (byteRemainder == 2) {\nchunk = (bytes[mainLength] << 8) | bytes[mainLength + 1]\n\na = (chunk & 64512) >> 10 // 64512 = (2^6 - 1) << 10\nb = (chunk & 1008) >> 4 // 1008 = (2^6 - 1) << 4\n\n// Set the 2 least significant bits to zero\nc = (chunk & 15) << 2 // 15 = 2^4 - 1\n\nbase64 += encodings[a] + encodings[b] + encodings[c] + '='\n}\n\nreturn base64\n}\n\n\n\n\n\nAFRAME.registerComponent('mozilla-xr-ar', {\n schema: {\n takeOverCamera: {default: true},\n cameraUserHeight: {default: false},\n worldSensing: {default: true}\n },\n\n init: function () {\n this.onInit = this.onInit.bind(this);\n this.onWatch = this.onWatch.bind(this);\n\n this.forceResize = this.forceResize.bind(this);\n\n this.poseMatrix = new THREE.Matrix4();\n this.posePosition = new THREE.Vector3();\n this.poseQuaternion = new THREE.Quaternion();\n this.poseEuler = new THREE.Euler(0, 0, 0, 'YXZ');\n this.poseRotation = new THREE.Vector3();\n this.projectionMatrix = new THREE.Matrix4();\n this.viewMatrix = new THREE.Matrix4();\n\n this.onceSceneLoaded = this.onceSceneLoaded.bind(this);\n if (this.el.sceneEl.hasLoaded) {\n setTimeout(this.onceSceneLoaded);\n } else {\n this.el.sceneEl.addEventListener('loaded', this.onceSceneLoaded);\n }\n\n // Add planes handling, so we can do synchronous hit test.\n // From google-ar/WebARonARKit; also see webxr-polyfill/ARKitWrapper.js\n\n this.planes_ = new Map();\n this.anchors_ = new Map();\n },\n\n // For WebXR Viewer, we are currently directly hooking the callback\n // used to provide frame data, so we don't need to do anything in tick!\n\n takeOverCamera: function (camera) {\n this.arCamera = camera;\n camera.el.setAttribute('ar-camera', 'enabled', true);\n },\n\n onceSceneLoaded: function () {\n // Check if the low-level WebXR Viewer interfaces are there.\n if (!window.webkit || !window.webkit.messageHandlers) { return; }\n if (!window.webkit.messageHandlers.initAR) { return; }\n\n window['arkitCallback' + 0] = this.onInit;\n window['arkitCallback' + 1] = this.onWatch;\n\n // Compose data to use with initAR.\n var data = {\n options: {\n ui: {\n browser: true,\n points: true,\n focus: false,\n rec: true,\n rec_time: true,\n mic: false,\n build: false,\n plane: true,\n warnings: true,\n anchors: false,\n debug: true,\n statistics: false\n }\n },\n callback: 'arkitCallback0' // this.onInit as window callback\n };\n\n // Need these because WebXR Viewer...\n //if (window['setNativeTime']) {\n // console.log('window handler already defined for ', 'setNativeTime');\n //} else\n window['setNativeTime'] = function (data) {\n window.nativeTime = data.nativeTime;\n };\n [\n 'arkitStartRecording',\n 'arkitStopRecording',\n 'arkitDidMoveBackground',\n 'arkitWillEnterForeground',\n 'arkitInterrupted',\n 'arkitInterruptionEnded',\n 'arkitShowDebug',\n // elsewhere... 'arkitWindowResize',\n 'onError',\n 'arTrackingChanged',\n 'ios_did_receive_memory_warning',\n 'onComputerVisionData',\n // above... 'setNativeTime',\n 'userGrantedComputerVisionData',\n 'userGrantedWorldSensingData', // Needed for world sensing.\n ].forEach(function (eventName) {\n //if (window[eventName]) {\n // console.log('window handler already defined for ', eventName);\n //} else\n window[eventName] = function (data) {\n console.log(eventName + ':', data);\n };\n });\n\n // act like Chrome WebXR by forcibly showing AR button and making it work\n var vrmodeui = this.el.sceneEl.components['vr-mode-ui'];\n var newarbutton = vrmodeui.enterAREl.cloneNode(true);\n vrmodeui.enterAREl.parentNode.replaceChild(newarbutton, vrmodeui.enterAREl);\n vrmodeui.enterAREl = newarbutton;\n vrmodeui.enterAREl.classList.remove('a-hidden');\n var self = this;\n vrmodeui.enterAREl.onclick = function() {\n var scene = AFRAME.scenes[0];\n\n // Note we're in AR mode (the way WebXR handling does).\n scene.addState('ar-mode');\n\n // Kill the Cardboard display that gets in our way.\n scene.components['vr-mode-ui'].orientationModalEl.style='display:none!important';\n\n // Fake VR mode from enterVRSuccess.\n scene.addState('vr-mode');\n scene.emit('enter-vr', {target: scene});\n\n // Call initAR.\n window.webkit.messageHandlers.initAR.postMessage(data);\n \n // Kill broken wakelock!\n scene.wakelock.release();\n\n // Take over the scene camera, if so directed.\n // But wait a tick, because otherwise injected camera will not be present.\n if (self.data.takeOverCamera) {\n setTimeout(function () { self.takeOverCamera(scene.camera); });\n }\n\n let sz = new THREE.Vector2();\n let pixelRatio = scene.renderer.getPixelRatio();\n scene.renderer.getSize(sz);\n console.log(\"pixelRatio \", pixelRatio, \" size \", sz);\n\n // Ugly hack to get around WebXR Viewer resizing issue.\n scene.canvas.style.position = \"absolute !important\";\n scene.canvas.style.width = \"100% !important\";\n scene.canvas.style.height = \"100% !important\";\n\n // Force resize after we have access to data (?!)\n window.userGrantedWorldSensingData = function(data) {\n console.log('userGrantedWorldSensingData:', data);\n setTimeout(function () {\n self.forceResize(\n screen.width * window.devicePixelRatio,\n screen.height * window.devicePixelRatio);\n }, 100); // 1000 seems to be long enough initially\n };\n };\n },\n\n forceResize: function (sx, sy) {\n var sc = this.el.sceneEl, self = this;\n console.log('forceResize ', sx, sy,\n ' was ', \n sc.canvas.width, sc.canvas.height, \n screen.width, screen.height,\n window.devicePixelRatio, sc.renderer.getPixelRatio());\n sx = sx || this.forceResizeX; this.forceResizeX = sx;\n sy = sy || this.forceResizeY; this.forceResizeY = sy;\n sc.canvas.setAttribute('width', sx);\n sc.canvas.setAttribute('height', sy);\n sc.camera.aspect = sx / sy;\n sc.camera.projectionMatrix.copy(self.projectionMatrix);\n sc.renderer.setPixelRatio(1);\n sc.renderer.setSize(sx, sy, false);\n sc.emit('rendererresize', null, false);\n },\n\n checkForARDisplay: function () {\n // Check if the low-level WebXR Viewer interfaces are there.\n if (!window.webkit || !window.webkit.messageHandlers) { return; }\n if (!window.webkit.messageHandlers.watchAR) { return; }\n\n // Mozilla WebXR Viewer detected.\n var self = this;\n self.arDisplay = true;\n\n\n // Compose data to use with watchAR.\n var data = {\n options: {\n location: true,\n camera: true,\n objects: true,\n light_intensity: true,\n worldSensing: this.data.worldSensing\n },\n callback: 'arkitCallback1' // this.onWatch as window callback\n };\n\n // Add resize handling.\n window['arkitWindowResize'] = function (data) {\n console.log('arkitWindowResize' + ':', data);\n\n // we're faking being in vr-mode anyway so resize will exit.\n //window.emit('resize', {target: window});\n\n // on iOS, AFRAME waits 100ms... \n setTimeout(function () {\n self.forceResize(\n data.width * window.devicePixelRatio,\n data.height * window.devicePixelRatio);\n }, 150); // 250 seems to be long enough\n };\n\n // Start watching AR.\n window.webkit.messageHandlers.watchAR.postMessage(data);\n },\n\n onInit: function (deviceId) {\n this.checkForARDisplay();\n },\n\n onWatch: function (data) {\n this.frameData = data;\n this.handleFrame(data);\n },\n\n handleFrame: function (data) {\n // Decompose to get camera pose.\n this.poseMatrix.fromArray(data.camera_transform);\n this.poseMatrix.decompose(this.posePosition, this.poseQuaternion, this.poseRotation); // poseRotation is really scale, we redo below\n this.poseEuler.setFromQuaternion(this.poseQuaternion);\n this.poseRotation.set(\n THREE.Math.RAD2DEG * this.poseEuler.x,\n THREE.Math.RAD2DEG * this.poseEuler.y,\n THREE.Math.RAD2DEG * this.poseEuler.z);\n\n this.projectionMatrix.fromArray(data.projection_camera);\n this.viewMatrix.fromArray(data.camera_view);\n\n // If we control a camera, and should apply user height, do it.\n if (this.arCamera && this.data.cameraUserHeight) {\n this.posePosition.y += this.arCamera.el.components.camera.data.userHeight;\n }\n\n // For A-Painter, detect bogus pose and fire poseFound / poseLost.\n var poseValid = this.posePosition.x || this.posePosition.y || this.posePosition.z || this.poseQuaternion.x || this.poseQuaternion.y || this.poseQuaternion.z;\n if (poseValid) {\n if (this.poseLost !== false) {\n this.poseLost = false;\n this.el.emit('poseFound');\n }\n } else {\n if (this.poseLost !== true) {\n this.poseLost = true;\n this.el.emit('poseLost', false);\n }\n }\n\n // Add planes handling, so we can do synchronous hit test.\n // From google-ar/WebARonARKit; also see webxr-polyfill/ARKitWrapper.js\n\n var i;\n var element;\n\n // WebXR Viewer returns geometry.vertices as an array of {x: number, y: number, y: number}\n // https://github.com/mozilla-mobile/webxr-ios/blob/c77b12c235e3960e2cd51538e086a38c83d8ec7c/XRViewer/ARKController/ARKController.m#L845\n // We transform this to a flatten array of number, like WebARonARCore.\n\n if(data.newObjects && data.newObjects.length){\n for (i = 0; i < data.newObjects.length; i++) {\n element = data.newObjects[i];\n if(element.plane_center){\n this.planes_.set(element.uuid, {\n id: element.uuid,\n center: element.plane_center,\n extent: [element.plane_extent.x, element.plane_extent.z],\n modelMatrix: element.transform,\n alignment: element.plane_alignment,\n vertices: convertVertices(element.geometry.vertices)\n });\n }else{\n var anchorData = {\n id: element.uuid,\n modelMatrix: element.transform\n };\n if (element.type === 'image') {\n anchorData.name = element.uuid;\n }\n this.anchors_.set(element.uuid, anchorData);\n }\n }\n }\n\n if(data.removedObjects && data.removedObjects.length){\n for (i = 0; i < data.removedObjects.length; i++) {\n element = data.removedObjects[i];\n if(this.planes_.get(element)){\n this.planes_.delete(element);\n }else{\n this.anchors_.delete(element);\n }\n }\n }\n\n if(data.objects && data.objects.length){\n for (i = 0; i < data.objects.length; i++) {\n element = data.objects[i];\n if(element.plane_center){\n var plane = this.planes_.get(element.uuid);\n if(!plane){\n this.planes_.set(element.uuid, {\n id: element.uuid,\n center: element.plane_center,\n extent: [element.plane_extent.x, element.plane_extent.z],\n modelMatrix: element.transform,\n alignment: element.plane_alignment,\n vertices: convertVertices(element.geometry.vertices)\n });\n } else {\n plane.center = element.plane_center;\n plane.extent = [element.plane_extent.x, element.plane_extent.z];\n plane.modelMatrix = element.transform;\n plane.alignment = element.plane_alignment;\n plane.vertices = convertVertices(element.geometry.vertices);\n }\n }else{\n var anchor = this.anchors_.get(element.uuid);\n if(!anchor){\n this.anchors_.set(element.uuid, {\n id: element.uuid,\n modelMatrix: element.transform\n });\n }else{\n anchor.modelMatrix = element.transform;\n }\n }\n }\n }\n },\n\n getPosition: function () {\n if (!this.arDisplay) { return null; }\n return this.posePosition;\n },\n\n getOrientation: function () {\n if (!this.arDisplay) { return null; }\n return this.poseQuaternion;\n },\n\n getRotation: function () {\n if (!this.arDisplay) { return null; }\n return this.poseRotation;\n },\n\n getProjectionMatrix: function () {\n if (!this.arDisplay) { return null; }\n return this.projectionMatrix;\n },\n\n // Link to new ARKit image marker and anchor support.\n\n addImage: function (name, url, physicalWidth) {\n if (!this.arDisplay) { return null; }\n/*\nNSDictionary *imageAnchorInfoDictionary = [message body];\nNSString *createDetectionImageCallback = [[message body] objectForKey:WEB_AR_CALLBACK_OPTION];\n// callback\n\nCGFloat physicalWidth = [referenceImageDictionary[@\"physicalWidth\"] doubleValue];\nNSString* b64String = referenceImageDictionary[@\"buffer\"];\nsize_t width = (size_t) [referenceImageDictionary[@\"imageWidth\"] intValue];\nsize_t height = (size_t) [referenceImageDictionary[@\"imageHeight\"] intValue];\n...\nresult.name = referenceImageDictionary[@\"uid\"];\n*/\n // NOTE: looks like WebXR Viewer won't load from URL,\n // so we need to convert from img element\n var aCanvas = document.createElement('canvas');\n var aContext = aCanvas.getContext('2d');\n var aImg; // Don't use element; chance of changed width/height.\n if (!aImg) {\n aImg = document.createElement('img');\n aImg.crossOrigin = 'anonymous';\n aImg.src = url;\n document.body.appendChild(aImg);\n }\n\n // The image needs to be loaded...\n if (!aImg.complete || !aImg.naturalHeight) {\n console.log('!!! addImage: !aImg.complete || !aImg.naturalHeight, aborting');\n return;\n } \n \n // The image needs to be have nonzero size...\n if (!aImg.width || !aImg.height) {\n console.log('!!! addImage: !aImg.width || !aImg.height, aborting');\n return;\n } \n\n aCanvas.width = aImg.width;\n aCanvas.height = aImg.height;\n aContext.drawImage(aImg, 0, 0);\n var aImageData = aContext.getImageData(0, 0, aImg.width, aImg.height);\n var b64ImageData = encode(aImageData.data);\n if (!b64ImageData) {\n console.log('!!! addImage: !b64ImageData, aborting');\n return;\n }\n\n // NOTE: also, WebXR Viewer doesn't pass back which image/name,\n // so we need a per-image/name callback\n window.callbackForCreateImageAnchorCounter = (window.callbackForCreateImageAnchorCounter || 0) + 1;\n var callbackName = 'callbackForCreateImageAnchor_' + window.callbackForCreateImageAnchorCounter;\n var imageName = name;\n //console.log('creating ', callbackName, ' for ', imageName);\n window[callbackName] = function (data) {\n //console.log(callbackName);\n //console.log(data);\n //var name = callbackName.substring(29);\n if (data.created !== undefined) {\n if (!data.created) {\n // we failed to create the image, for whatever reason.\n console.log('addImage: !created; ', data.error);\n delete window[callbackName];\n } else {\n //console.log('addImage: created, activating ', imageName);\n window.webkit.messageHandlers.activateDetectionImage.postMessage({\n callback: callbackName,\n uid: imageName\n });\n }\n } else\n if (data.activated !== undefined) {\n if (!data.activated) {\n // we failed to activate the image, for whatever reason.\n console.log('addImage: !activated; ', data.error);\n } else {\n //console.log('addImage: activated ', imageName);\n }\n delete window[callbackName];\n }\n };\n\n window.webkit.messageHandlers.createImageAnchor.postMessage({\n callback: callbackName,\n uid: name,\n buffer: b64ImageData,\n imageWidth: aImg.width,\n imageHeight: aImg.height,\n physicalWidth: physicalWidth // in meters\n });\n },\n\n removeImage: function (name) {\n if (!this.arDisplay) { return null; }\n/*\nNSDictionary *imageAnchorInfoDictionary = [message body];\nNSString *imageName = imageAnchorInfoDictionary[WEB_AR_DETECTION_IMAGE_NAME_OPTION];\n// detectionImageName\nNSString *deactivateDetectionImageCallback = [[message body] objectForKey:WEB_AR_CALLBACK_OPTION];\n// callback\n*/\n window.callbackForRemoveImageAnchorCounter = (window.callbackForRemoveImageAnchorCounter || 0) + 1;\n var callbackName = 'callbackForRemoveImageAnchor_' + window.callbackForRemoveImageAnchorCounter;\n var imageName = name;\n //console.log('creating ', callbackName, ' for ', imageName);\n window[callbackName] = function (data) {\n //console.log(callbackName);\n //console.log(data);\n\n if (data.deactivated !== undefined) {\n if (!data.deactivated) {\n console.log('!!! ' + callbackName + ': !deactivated', data.error);\n delete window[callbackName];\n } else {\n //console.log(callbackName + ': deactivated, destroying', imageName);\n }\n window.webkit.messageHandlers.destroyDetectionImage.postMessage({\n callback: callbackName,\n uid: imageName\n });\n }\n if (data.destroyed !== undefined) {\n if (!data.destroyed) {\n console.log('!!! ' + callbackName + ': !destroyed, ', data.error);\n } else {\n //console.log(callbackName + ': destroyed', imageName);\n }\n delete window[callbackName];\n }\n };\n\n window.webkit.messageHandlers.deactivateDetectionImage.postMessage({\n callback: callbackName,\n uid: imageName\n });\n },\n\n getAnchors: function () {\n return Array.from(this.anchors_.values());\n },\n\n // Use planes to do synchronous hit test.\n // From google-ar/WebARonARKit; also see webxr-polyfill/ARKitWrapper.js\n\n getPlanes: function () {\n return Array.from(this.planes_.values());\n },\n\n hitTestNoAnchor: (function () {\n // Temporary variables, only within closure scope.\n\n /**\n * The result of a raycast into the AR world encoded as a transform matrix.\n * This structure has a single property - modelMatrix - which encodes the\n * translation of the intersection of the hit in the form of a 4x4 matrix.\n * @constructor\n */\n function VRHit() {\n this.modelMatrix = new Float32Array(16);\n return this;\n };\n\n /**\n * Cached vec3, mat4, and quat structures needed for the hit testing to\n * avoid generating garbage.\n * @type {Object}\n */\n var hitVars = {\n rayStart: new THREE.Vector3(), //vec3.create(),\n rayEnd: new THREE.Vector3(), //vec3.create(),\n cameraPosition: new THREE.Vector3(), //vec3.create(),\n cameraQuaternion: new THREE.Quaternion(), //quat.create(),\t\n //modelViewMatrix: new THREE.Matrix4(), //mat4.create(),\n //projectionMatrix: new THREE.Matrix4(), //mat4.create(),\n projViewMatrix: new THREE.Matrix4(), //mat4.create(),\n worldRayStart: new THREE.Vector3(), //vec3.create(),\n worldRayEnd: new THREE.Vector3(), //vec3.create(),\n worldRayDir: new THREE.Vector3(), //vec3.create(),\n planeMatrix: new THREE.Matrix4(), //mat4.create(),\n planeMatrixInverse: new THREE.Matrix4(), //mat4.create(),\n planeExtent: new THREE.Vector3(), //vec3.create(),\n planePosition: new THREE.Vector3(), //vec3.create(),\n planeCenter: new THREE.Vector3(), //vec3.create(),\n planeNormal: new THREE.Vector3(), //vec3.create(),\n planeIntersection: new THREE.Vector3(), //vec3.create(),\n planeIntersectionLocal: new THREE.Vector3(), //vec3.create(),\n planeHit: new THREE.Matrix4(), //mat4.create()\n planeQuaternion: new THREE.Quaternion() // quat.create()\n };\n \n /**\n * Tests whether the given ray intersects the given plane.\n *\n * @param {!vec3} planeNormal The normal of the plane.\n * @param {!vec3} planePosition Any point on the plane.\n * @param {!vec3} rayOrigin The origin of the ray.\n * @param {!vec3} rayDirection The direction of the ray (normalized).\n * @return {number} The t-value of the intersection (-1 for none).\n */\n var rayIntersectsPlane = (function() {\n var rayToPlane = new THREE.Vector3();\n return function(planeNormal, planePosition, rayOrigin, rayDirection) {\n // assuming vectors are all normalized\n var denom = planeNormal.dot(rayDirection);\n rayToPlane.subVectors(planePosition, rayOrigin);\n return rayToPlane.dot(planeNormal) / denom;\n };\n })();\n \n /**\n * Sorts based on the distance from the VRHits to the camera.\n *\n * @param {!VRHit} a The first hit to compare.\n * @param {!VRHit} b The second hit item to compare.\n * @returns {number} -1 if a is closer than b, otherwise 1.\n */\n var sortFunction = function(a, b) {\n // Get the matrix of hit a.\n hitVars.planeMatrix.fromArray(a.modelMatrix);\n // Get the translation component of a's matrix.\n hitVars.planeIntersection.setFromMatrixPosition(hitVars.planeMatrix);\n // Get the distance from the intersection point to the camera.\n var distA = hitVars.planeIntersection.distanceTo(hitVars.cameraPosition);\n \n // Get the matrix of hit b.\n hitVars.planeMatrix.fromArray(b.modelMatrix);\n // Get the translation component of b's matrix.\n hitVars.planeIntersection.setFromMatrixPosition(hitVars.planeMatrix);\n // Get the distance from the intersection point to the camera.\n var distB = hitVars.planeIntersection.distanceTo(hitVars.cameraPosition);\n \n // Return comparison of distance from camera to a and b.\n return distA < distB ? -1 : 1;\n };\n \n return function(x, y) {\n // Coordinates must be in normalized screen space.\n if (x < 0 || x > 1 || y < 0 || y > 1) {\n throw new Error(\n \"hitTest - x and y values must be normalized [0,1]!\")\n ;\n }\n \n var hits = [];\n // If there are no anchors detected, there will be no hits.\n var planes = this.getPlanes();\n if (!planes || planes.length === 0) {\n return hits;\n }\n\n // Create a ray in screen space for the hit test ([-1, 1] with y flip).\n hitVars.rayStart.set(2 * x - 1, 2 * (1 - y) - 1, 0);\n hitVars.rayEnd.set(2 * x - 1, 2 * (1 - y) - 1, 1);\n\n // Set the projection matrix.\n //hitVars.projectionMatrix.fromArray(this.projectionMatrix);\n \n // Set the model view matrix.\n //hitVars.modelViewMatrix.fromArray(this.viewMatrix);\n \n // Combine the projection and model view matrices.\n hitVars.planeMatrix.multiplyMatrices(\n this.projectionMatrix, //hitVars.projectionMatrix,\n this.viewMatrix //hitVars.modelViewMatrix\n );\n // Invert the combined matrix because we need to go from screen -> world.\n hitVars.projViewMatrix.getInverse(hitVars.planeMatrix);\n \n // Transform the screen-space ray start and end to world-space.\n hitVars.worldRayStart.copy(hitVars.rayStart)\n .applyMatrix4(hitVars.projViewMatrix);\n hitVars.worldRayEnd.copy(hitVars.rayEnd)\n .applyMatrix4(hitVars.projViewMatrix);\n \n // Subtract start from end to get the ray direction and then normalize.\n hitVars.worldRayDir.subVectors(\n hitVars.worldRayEnd,\n hitVars.worldRayStart\n ).normalize();\n\n // Go through all the anchors and test for intersections with the ray.\n for (var i = 0; i < planes.length; i++) {\n var plane = planes[i];\n // Get the anchor transform.\n hitVars.planeMatrix.fromArray(plane.modelMatrix);\n \n // Get the position of the anchor in world-space.\n hitVars.planeCenter.set(plane.center.x, plane.center.y, plane.center.z);\n hitVars.planePosition.copy(hitVars.planeCenter)\n .applyMatrix4(hitVars.planeMatrix)\n\n hitVars.planeAlignment = plane.alignment\n \n // Get the plane normal.\n if (hitVars.planeAlignment === 0) {\n hitVars.planeNormal.set(0, 1, 0);\n } else {\n hitVars.planeNormal.set(hitVars.planeMatrix[4], hitVars.planeMatrix[5], hitVars.planeMatrix[6]);\n }\n \n // Check if the ray intersects the plane.\n var t = rayIntersectsPlane(\n hitVars.planeNormal,\n hitVars.planePosition,\n hitVars.worldRayStart,\n hitVars.worldRayDir\n );\n\n // if t < 0, there is no intersection.\n if (t < 0) {\n continue;\n }\n \n // Calculate the actual intersection point.\n hitVars.planeIntersectionLocal.copy(hitVars.worldRayDir).multiplyScalar(t);\n hitVars.planeIntersection.addVectors(\n hitVars.worldRayStart,\n hitVars.planeIntersectionLocal\n );\n // Get the plane extents (extents are in plane local space).\n hitVars.planeExtent.set(plane.extent[0], 0, plane.extent[1]);\n /*\n ///////////////////////////////////////////////\n // Test by converting extents to world-space.\n // TODO: get this working to avoid matrix inversion in method below.\n \n // Get the rotation component of the anchor transform.\n mat4.getRotation(hitVars.planeQuaternion, hitVars.planeMatrix);\n \n // Convert the extent into world space.\n vec3.transformQuat(\n hitVars.planeExtent, hitVars.planeExtent, hitVars.planeQuaternion);\n \n // Check if intersection is outside of the extent of the anchor.\n if (Math.abs(hitVars.planeIntersection[0] - hitVars.planePosition[0]) > hitVars.planeExtent[0] / 2) {\n continue;\n }\n if (Math.abs(hitVars.planeIntersection[2] - hitVars.planePosition[2]) > hitVars.planeExtent[2] / 2) {\n continue;\n }\n ////////////////////////////////////////////////\n */\n \n ////////////////////////////////////////////////\n // Test by converting intersection into plane-space.\n hitVars.planeMatrixInverse.getInverse(hitVars.planeMatrix);\n hitVars.planeIntersectionLocal.copy(hitVars.planeIntersection)\n .applyMatrix4(hitVars.planeMatrixInverse);\n \n // Check if intersection is outside of the extent of the anchor.\n // Tolerance is added to match the behavior of the native hitTest call.\n var tolerance = 0.0075;\n if (\n Math.abs(hitVars.planeIntersectionLocal.x) >\n hitVars.planeExtent.x / 2 + tolerance\n ) {\n continue;\n }\n if (\n Math.abs(hitVars.planeIntersectionLocal.z) >\n hitVars.planeExtent.z / 2 + tolerance\n ) {\n continue;\n }\n \n ////////////////////////////////////////////////\n \n // The intersection is valid - create a matrix from hit position.\n hitVars.planeQuaternion.setFromRotationMatrix(hitVars.planeMatrix);\n hitVars.planeHit.makeRotationFromQuaternion(hitVars.planeQuaternion).setPosition(hitVars.planeIntersection);\n var hit = new VRHit();\n for (var j = 0; j < 16; j++) {\n hit.modelMatrix[j] = hitVars.planeHit.elements[j];\n }\n hit.i = i;\n hits.push(hit);\n }\n \n\n // Sort the hits by distance.\n hits.sort(sortFunction);\n return hits;\n };\n })(),\n\n hitAR: (function () {\n // Temporary variables, only within closure scope.\n var transform = new THREE.Matrix4();\n var hitpoint = new THREE.Vector3();\n var hitquat = new THREE.Quaternion();\n var hitscale = new THREE.Vector3();\n var worldpos = new THREE.Vector3();\n\n // The desired function, which this returns.\n return function (x, y, el, raycasterEl) {\n if (!this.arDisplay) { return []; }\n\n var hit = this.hitTestNoAnchor(x, y);\n\n // Process AR hits.\n var hitsToReturn = [];\n for (var i = 0; hit && i < hit.length; i++) {\n transform.fromArray(hit[i].modelMatrix);\n transform.decompose(hitpoint, hitquat, hitscale);\n raycasterEl.object3D.getWorldPosition(worldpos);\n\n hitsToReturn.push({\n distance: hitpoint.distanceTo(worldpos),\n point: hitpoint.clone(), // Vector3\n object: (el && el.object3D) || this.el.sceneEl.object3D\n/*\n // We don't have any of these properties...\n face: undefined, // Face3\n faceIndex: undefined,\n index: undefined,\n uv: undefined // Vector2\n*/\n });\n }\n return hitsToReturn;\n } \n })()\n});\n","/* global AFRAME, THREE, VRFrameData */\n\nAFRAME.registerComponent('webxr-ar', {\n schema: {\n takeOverCamera: {default: true},\n cameraUserHeight: {default: false},\n worldSensing: {default: false} // currently unused\n },\n\n init: function () {\n this.posePosition = new THREE.Vector3();\n this.poseQuaternion = new THREE.Quaternion();\n this.poseEuler = new THREE.Euler(0, 0, 0, 'YXZ');\n this.poseRotation = new THREE.Vector3();\n this.projectionMatrix = new THREE.Matrix4();\n\n this.onceSceneLoaded = this.onceSceneLoaded.bind(this);\n if (this.el.sceneEl.hasLoaded) {\n setTimeout(this.onceSceneLoaded);\n } else {\n this.el.sceneEl.addEventListener('loaded', this.onceSceneLoaded);\n }\n\n // Add planes handling, so we can do synchronous hit test.\n\n this.rawPlanes_ = null;\n this.planes_ = new Map();\n this.anchors_ = new Map();\n },\n\n convertPolygonToVertices: function(polygon) {\n return newVertices;\n },\n\n convertedPlane: function(rawPlane, pose) {\n var mins = [0, 0];\n var maxs = [0, 0];\n var verticesLength = rawPlane.polygon.length;\n var newVertices = new Float32Array(verticesLength * 3);\n var i = 0;\n var j = 0;\n var vertex;\n for (i = 0; i < verticesLength; i++) {\n vertex = rawPlane.polygon[i];\n newVertices[j] = vertex.x;\n newVertices[j + 1] = vertex.y;\n newVertices[j + 2] = vertex.z;\n j += 3;\n if (i == 0) {\n mins[0] = maxs[0] = vertex.x;\n mins[1] = maxs[1] = vertex.z;\n } else {\n if (mins[0] > vertex.x) { mins[0] = vertex.x; }\n if (maxs[0] < vertex.x) { maxs[0] = vertex.x; }\n if (mins[1] > vertex.z) { mins[1] = vertex.z; }\n if (maxs[1] < vertex.z) { maxs[1] = vertex.z; }\n }\n }\n var position = pose.transform.position;\n rawPlane.position.set(position.x, position.y, position.z);\n var converted = {\n id: rawPlane.id,\n center: rawPlane.position,\n extent: [maxs[0] - mins[0], maxs[1] - mins[1]],\n modelMatrix: pose.transform.matrix,\n alignment: rawPlane.orientation != 'Horizontal' ? 1 : 0,\n vertices: newVertices\n };\n return converted;\n },\n\n rawPlaneRemoved: function(rawPlane) {\n // remove the converted plane\n this.planes_.delete(rawPlane.id);\n },\n\n rawPlaneUpdated: function(rawPlane, pose) {\n // convert the updated plane\n this.planes_.set(rawPlane.id, this.convertedPlane(rawPlane, pose));\n },\n\n rawPlaneNotUpdated: function(rawPlane, pose) {\n // FIXME: check is broken so update anyway\n this.rawPlaneUpdated(rawPlane, pose);\n // do nothing\n },\n\n rawPlaneCreated: function(rawPlane, pose) {\n // assign and attach an id... for now, use Math.random()\n rawPlane.id = Math.random().toString().substring(2);\n rawPlane.position = new THREE.Vector3();\n // convert the plane\n this.planes_[rawPlane.id] = this.convertedPlane(rawPlane, pose);\n },\n\n tick: function (t, dt) {\n let frame = this.el.sceneEl.frame;\n if (!this.arDisplay\n || !frame\n || !frame.worldInformation) { return; }\n\n // use the planes information\n let world = frame.worldInformation;\n\n // check for removed planes\n this.rawPlanes_ && this.rawPlanes_.forEach(plane => {\n if(!world.detectedPlanes || !world.detectedPlanes.has(plane)) {\n // Handle removed plane - `plane` was present in previous frame but is no longer tracked.\n this.rawPlaneRemoved(plane);\n }\n });\n\n // check for changed planes\n let timestamp = this.el.sceneEl.time;\n world.detectedPlanes && world.detectedPlanes.forEach(plane => {\n let planePose = frame.getPose(plane.planeSpace, this.refSpace);\n if (this.rawPlanes_.has(plane)) {\n if(plane.lastChangedTime == timestamp) {\n // Handle previously seen plane that was updated in current frame.\n this.rawPlaneUpdated(plane, planePose);\n } else {\n // Handle previously seen plane that was not updated in current frame.\n // Depending on the application, this could be a no-op.\n this.rawPlaneNotUpdated(plane, planePose);\n }\n } else {\n // Handle new plane.\n this.rawPlaneCreated(plane, planePose);\n }\n });\n \n this.rawPlanes_ = world.detectedPlanes;\n },\n\n takeOverCamera: function (camera) {\n this.arCamera = camera;\n camera.isARPerspectiveCamera = true; // HACK - is this necessary?\n camera.vrDisplay = this.arDisplay; // HACK - is this necessary?\n camera.el.setAttribute('ar-camera', 'enabled', true);\n },\n\n onceSceneLoaded: function () {\n var self = this;\n window.addEventListener('ardisplayconnect', function () {\n if (!self.arDisplay) { self.checkForARDisplay(); }\n });\n\n // Check now for AR display.\n this.checkForARDisplay();\n },\n\n checkForARDisplay: function () {\n // check to see if webxr ar mode is supported\n if (!navigator.xr || !navigator.xr.isSessionSupported) { return; }\n\n var self = this;\n self.arDisplay = {type: 'webxr-ar'};\n\n navigator.xr.isSessionSupported('immersive-ar').then(function(supported) {\n if (supported) {\n let ourRequiredFeatures = ['local-floor'];\n let ourOptionalFeatures = [];\n (self.data.worldSensing ? ourRequiredFeatures : ourOptionalFeatures).push('hit-test');\n let existingFeatures = self.el.sceneEl.getAttribute('webxr');\n if (!existingFeatures) {\n // here, we assume we can set as map and not String (?) \n self.el.sceneEl.setAttribute('webxr', { \n requiredFeatures: ourRequiredFeatures.join(','), \n optionalFeatures: ourOptionalFeatures.join(',') \n });\n } else {\n // here, we assume we get and set as map and not String (?)\n // remove existing optional features from our optional\n existingFeatures.optionalFeatures.forEach(function (feature) {\n ourOptionalFeatures = ourOptionalFeatures.filter(function(value, index, arr){ return value != feature;});\n });\n // remove existing required features from our required\n existingFeatures.requiredFeatures.forEach(function (feature) {\n ourRequiredFeatures = ourRequiredFeatures.filter(function(value, index, arr){ return value != feature;});\n });\n // remove our required features from existing optional\n ourRequiredFeatures.forEach(function (feature) {\n existingFeatures.optionalFeatures = existingFeatures.optionalFeatures.filter(function(value, index, arr){ return value != feature;});\n });\n // add our required and optional features to the existing\n existingFeatures.requiredFeatures = existingFeatures.requiredFeatures.concat(ourRequiredFeatures);\n existingFeatures.optionalFeatures = existingFeatures.optionalFeatures.concat(ourOptionalFeatures);\n\n self.el.sceneEl.setAttribute('webxr', existingFeatures);\n }\n\n self.el.sceneEl.setAttribute('vr-mode-ui', \"enabled\", \"true\");\n // auto-entering AR doesn't work.\n\n self.xrHitTestSource = null;\n self.viewerSpace = null;\n self.refSpace = null;\n\n self.el.sceneEl.renderer.xr.addEventListener('sessionend', (ev) => {\n self.viewerSpace = null;\n self.refSpace = null;\n self.xrHitTestSource = null;\n });\n self.el.sceneEl.renderer.xr.addEventListener('sessionstart', (ev) => {\n let session = self.el.sceneEl.renderer.xr.getSession();\n let el = self.el.sceneEl.canvas;\n\n session.addEventListener('selectstart', function (e) {\n // dispatch touchstart\n var pageX = e.inputSource.gamepad.axes[0];\n var pageY = e.inputSource.gamepad.axes[1];\n setTimeout(() => {\n var event = new TouchEvent('touchstart', {\n view: window,\n bubbles: true,\n cancelable: true\n });\n event.targetTouches = [{ pageX: pageX, pageY: pageY }];\n el.dispatchEvent(event);\n });\n });\n\n session.addEventListener('selectend', function (e) {\n // dispatch touchend\n var pageX = e.inputSource.gamepad.axes[0];\n var pageY = e.inputSource.gamepad.axes[1];\n setTimeout(() => {\n var event = new TouchEvent('touchend', {\n view: window,\n bubbles: true,\n cancelable: true\n });\n event.targetTouches = [{ pageX: pageX, pageY: pageY }];\n el.dispatchEvent(event);\n });\n });\n\n session.addEventListener('select', function (e) {\n // dispatch click\n var pageX = e.inputSource.gamepad.axes[0];\n var pageY = e.inputSource.gamepad.axes[1];\n setTimeout(() => {\n var event = new MouseEvent('click', { \n clientX: pageX, \n clientY: pageY, \n bubbles: true,\n cancelable: true\n });\n el.dispatchEvent(event);\n });\n });\n\n session.requestReferenceSpace('viewer').then((space) => {\n self.viewerSpace = space;\n if (self.data.worldSensing) {\n session.requestHitTestSource({space: self.viewerSpace})\n .then((hitTestSource) => {\n self.xrHitTestSource = hitTestSource;\n })\n }\n });\n\n session.requestReferenceSpace('local-floor').then((space) => {\n self.refSpace = space;\n });\n\n // Ask for planes, if we should.\n if (self.data.worldSensing) {\n session.updateWorldTrackingState({planeDetectionState : {enabled : true}});\n }\n });\n }\n });\n },\n\n getPosition: function () {\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\n return this.posePosition;\n },\n\n getOrientation: function () {\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\n return this.poseQuaternion;\n },\n\n getRotation: function () {\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\n return this.poseRotation;\n },\n\n getProjectionMatrix: function () {\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\n return this.projectionMatrix;\n },\n\n hitAR: (function () { \n // Temporary variables, only within closure scope.\n var transform = new THREE.Matrix4();\n var hitpoint = new THREE.Vector3();\n var hitquat = new THREE.Quaternion();\n var hitscale = new THREE.Vector3();\n var worldpos = new THREE.Vector3();\n \n // The desired function, which this returns.\n return function (x, y, el, raycasterEl) {\n if (!this.arDisplay) { return []; }\n var hitsToReturn = [];\n\n if (this.el.sceneEl.is('ar-mode')) {\n if (!this.viewerSpace) return;\n\n let frame = this.el.sceneEl.frame;\n let xrViewerPose = frame.getViewerPose(this.refSpace);\n\n if (this.xrHitTestSource && xrViewerPose) {\n let hitTestResults = frame.getHitTestResults(this.xrHitTestSource);\n\n // Process AR hits.\n var hitsToReturn = [];\n for (var i = 0; hitTestResults && i < hitTestResults.length; i++) {\n let pose = hitTestResults[i].getPose(this.refSpace);\n transform.fromArray(pose.transform.matrix);\n hitpoint.setFromMatrixPosition(transform); //transform.decompose(hitpoint, hitquat, hitscale);\n raycasterEl.object3D.getWorldPosition(worldpos);\n\n hitsToReturn.push({\n distance: hitpoint.distanceTo(worldpos),\n point: hitpoint.clone(), // Vector3\n object: (el && el.object3D) || this.el.sceneEl.object3D\n/*\n // We don't have any of these properties...\n face: undefined, // Face3\n faceIndex: undefined,\n index: undefined,\n uv: undefined // Vector2\n*/\n });\n }\n }\n }\n\n return hitsToReturn;\n }\n })(),\n\n // Link to image marker and anchor support.\n\n addImage: function (name, url, physicalWidth) {\n if (!this.arDisplay) { return null; }\n\n return null;\n },\n\n removeImage: function (name) {\n if (!this.arDisplay) { return null; }\n\n return null;\n },\n\n getAnchors: function () {\n return Array.from(this.anchors_.values());\n },\n\n // Use planes to do synchronous hit test.\n\n getPlanes: function () {\n return Array.from(this.planes_.values());\n }\n});\n"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/aframe-ar.min.js b/dist/aframe-ar.min.js index 927f285..5c57886 100644 --- a/dist/aframe-ar.min.js +++ b/dist/aframe-ar.min.js @@ -1,2 +1,2 @@ -!function(e){var t={};function n(a){if(t[a])return t[a].exports;var i=t[a]={i:a,l:!1,exports:{}};return e[a].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,a){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:a})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var a=Object.create(null);if(n.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(a,i,function(t){return e[t]}.bind(null,i));return a},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){n(1),n(2),n(3),n(4),n(5),n(6),n(7),n(8)},function(e,t){var n,a,i;AFRAME.registerComponent("webxr-ar",{schema:{takeOverCamera:{default:!0},cameraUserHeight:{default:!1},worldSensing:{default:!1}},init:function(){this.posePosition=new THREE.Vector3,this.poseQuaternion=new THREE.Quaternion,this.poseEuler=new THREE.Euler(0,0,0,"YXZ"),this.poseRotation=new THREE.Vector3,this.projectionMatrix=new THREE.Matrix4,this.onceSceneLoaded=this.onceSceneLoaded.bind(this),this.el.sceneEl.hasLoaded?setTimeout(this.onceSceneLoaded):this.el.sceneEl.addEventListener("loaded",this.onceSceneLoaded),this.rawPlanes_=null,this.planes_=new Map,this.anchors_=new Map},convertPolygonToVertices:function(e){return newVertices},convertedPlane:function(e,t){var n,a=[0,0],i=[0,0],r=e.polygon.length,o=new Float32Array(3*r),s=0,c=0;for(s=0;sn.x&&(a[0]=n.x),i[0]n.z&&(a[1]=n.z),i[1]{a.detectedPlanes&&a.detectedPlanes.has(e)||this.rawPlaneRemoved(e)});let i=this.el.sceneEl.time;a.detectedPlanes&&a.detectedPlanes.forEach(e=>{let t=n.getPose(e.planeSpace,this.refSpace);this.rawPlanes_.has(e)?e.lastChangedTime==i?this.rawPlaneUpdated(e,t):this.rawPlaneNotUpdated(e,t):this.rawPlaneCreated(e,t)}),this.rawPlanes_=a.detectedPlanes},takeOverCamera:function(e){this.arCamera=e,e.isARPerspectiveCamera=!0,e.vrDisplay=this.arDisplay,e.el.setAttribute("ar-camera","enabled",!0)},onceSceneLoaded:function(){var e=this;window.addEventListener("ardisplayconnect",(function(){e.arDisplay||e.checkForARDisplay()})),this.checkForARDisplay()},checkForARDisplay:function(){if(navigator.xr&&navigator.xr.isSessionSupported){var e=this;e.arDisplay={type:"webxr-ar"},navigator.xr.isSessionSupported("immersive-ar").then((function(t){if(t){let t=["local-floor"],n=[];(e.data.worldSensing?t:n).push("hit-test");let a=e.el.sceneEl.getAttribute("webxr");a?(a.optionalFeatures.forEach((function(e){n=n.filter((function(t,n,a){return t!=e}))})),a.requiredFeatures.forEach((function(e){t=t.filter((function(t,n,a){return t!=e}))})),t.forEach((function(e){a.optionalFeatures=a.optionalFeatures.filter((function(t,n,a){return t!=e}))})),a.requiredFeatures=a.requiredFeatures.concat(t),a.optionalFeatures=a.optionalFeatures.concat(n),e.el.sceneEl.setAttribute("webxr",a)):e.el.sceneEl.setAttribute("webxr",{requiredFeatures:t.join(","),optionalFeatures:n.join(",")}),e.el.sceneEl.setAttribute("vr-mode-ui","enabled","true"),e.xrHitTestSource=null,e.viewerSpace=null,e.refSpace=null,e.el.sceneEl.renderer.xr.addEventListener("sessionend",t=>{e.viewerSpace=null,e.refSpace=null,e.xrHitTestSource=null}),e.el.sceneEl.renderer.xr.addEventListener("sessionstart",t=>{let n=e.el.sceneEl.renderer.xr.getSession(),a=e.el.sceneEl.canvas;n.addEventListener("selectstart",(function(e){var t=e.inputSource.gamepad.axes[0],n=e.inputSource.gamepad.axes[1];setTimeout(()=>{var e=new TouchEvent("touchstart",{view:window,bubbles:!0,cancelable:!0});e.targetTouches=[{pageX:t,pageY:n}],a.dispatchEvent(e)})})),n.addEventListener("selectend",(function(e){var t=e.inputSource.gamepad.axes[0],n=e.inputSource.gamepad.axes[1];setTimeout(()=>{var e=new TouchEvent("touchend",{view:window,bubbles:!0,cancelable:!0});e.targetTouches=[{pageX:t,pageY:n}],a.dispatchEvent(e)})})),n.addEventListener("select",(function(e){var t=e.inputSource.gamepad.axes[0],n=e.inputSource.gamepad.axes[1];setTimeout(()=>{var e=new MouseEvent("click",{clientX:t,clientY:n,bubbles:!0,cancelable:!0});a.dispatchEvent(e)})})),n.requestReferenceSpace("viewer").then(t=>{e.viewerSpace=t,e.data.worldSensing&&n.requestHitTestSource({space:e.viewerSpace}).then(t=>{e.xrHitTestSource=t})}),n.requestReferenceSpace("local-floor").then(t=>{e.refSpace=t}),e.data.worldSensing&&n.updateWorldTrackingState({planeDetectionState:{enabled:!0}})})}}))}},getPosition:function(){return this.arDisplay&&this.arDisplay.getFrameData?this.posePosition:null},getOrientation:function(){return this.arDisplay&&this.arDisplay.getFrameData?this.poseQuaternion:null},getRotation:function(){return this.arDisplay&&this.arDisplay.getFrameData?this.poseRotation:null},getProjectionMatrix:function(){return this.arDisplay&&this.arDisplay.getFrameData?this.projectionMatrix:null},hitAR:(n=new THREE.Matrix4,a=new THREE.Vector3,new THREE.Quaternion,new THREE.Vector3,i=new THREE.Vector3,function(e,t,r,o){if(!this.arDisplay)return[];var s=[];if(this.el.sceneEl.is("ar-mode")){if(!this.viewerSpace)return;let e=this.el.sceneEl.frame,t=e.getViewerPose(this.refSpace);if(this.xrHitTestSource&&t){let t=e.getHitTestResults(this.xrHitTestSource);s=[];for(var c=0;t&&c>18]+n[(258048&i)>>12]+n[(4032&i)>>6]+n[63&i];return 1==o?t+=n[(252&(i=a[s]))>>2]+n[(3&i)<<4]+"==":2==o&&(t+=n[(64512&(i=a[s]<<8|a[s+1]))>>10]+n[(1008&i)>>4]+n[(15&i)<<2]+"="),t}(r.getImageData(0,0,a.width,a.height).data);if(o){window.callbackForCreateImageAnchorCounter=(window.callbackForCreateImageAnchorCounter||0)+1;var s="callbackForCreateImageAnchor_"+window.callbackForCreateImageAnchorCounter,c=e;window[s]=function(e){void 0!==e.created?e.created?window.webkit.messageHandlers.activateDetectionImage.postMessage({callback:s,uid:c}):(console.log("addImage: !created; ",e.error),delete window[s]):void 0!==e.activated&&(e.activated||console.log("addImage: !activated; ",e.error),delete window[s])},window.webkit.messageHandlers.createImageAnchor.postMessage({callback:s,uid:e,buffer:o,imageWidth:a.width,imageHeight:a.height,physicalWidth:n})}else console.log("!!! addImage: !b64ImageData, aborting")}else console.log("!!! addImage: !aImg.width || !aImg.height, aborting");else console.log("!!! addImage: !aImg.complete || !aImg.naturalHeight, aborting")},removeImage:function(e){if(!this.arDisplay)return null;window.callbackForRemoveImageAnchorCounter=(window.callbackForRemoveImageAnchorCounter||0)+1;var t="callbackForRemoveImageAnchor_"+window.callbackForRemoveImageAnchorCounter,n=e;window[t]=function(e){void 0!==e.deactivated&&(e.deactivated||(console.log("!!! "+t+": !deactivated",e.error),delete window[t]),window.webkit.messageHandlers.destroyDetectionImage.postMessage({callback:t,uid:n})),void 0!==e.destroyed&&(e.destroyed||console.log("!!! "+t+": !destroyed, ",e.error),delete window[t])},window.webkit.messageHandlers.deactivateDetectionImage.postMessage({callback:t,uid:n})},getAnchors:function(){return Array.from(this.anchors_.values())},getPlanes:function(){return Array.from(this.planes_.values())},hitTestNoAnchor:function(){function e(){return this.modelMatrix=new Float32Array(16),this}var t,n={rayStart:new THREE.Vector3,rayEnd:new THREE.Vector3,cameraPosition:new THREE.Vector3,cameraQuaternion:new THREE.Quaternion,projViewMatrix:new THREE.Matrix4,worldRayStart:new THREE.Vector3,worldRayEnd:new THREE.Vector3,worldRayDir:new THREE.Vector3,planeMatrix:new THREE.Matrix4,planeMatrixInverse:new THREE.Matrix4,planeExtent:new THREE.Vector3,planePosition:new THREE.Vector3,planeCenter:new THREE.Vector3,planeNormal:new THREE.Vector3,planeIntersection:new THREE.Vector3,planeIntersectionLocal:new THREE.Vector3,planeHit:new THREE.Matrix4,planeQuaternion:new THREE.Quaternion},a=(t=new THREE.Vector3,function(e,n,a,i){var r=e.dot(i);return t.subVectors(n,a),t.dot(e)/r}),i=function(e,t){n.planeMatrix.fromArray(e.modelMatrix),n.planeIntersection.setFromMatrixPosition(n.planeMatrix);var a=n.planeIntersection.distanceTo(n.cameraPosition);return n.planeMatrix.fromArray(t.modelMatrix),n.planeIntersection.setFromMatrixPosition(n.planeMatrix),a1||r<0||r>1)throw new Error("hitTest - x and y values must be normalized [0,1]!");var o=[],s=this.getPlanes();if(!s||0===s.length)return o;n.rayStart.set(2*t-1,2*(1-r)-1,0),n.rayEnd.set(2*t-1,2*(1-r)-1,1),n.planeMatrix.multiplyMatrices(this.projectionMatrix,this.viewMatrix),n.projViewMatrix.getInverse(n.planeMatrix),n.worldRayStart.copy(n.rayStart).applyMatrix4(n.projViewMatrix),n.worldRayEnd.copy(n.rayEnd).applyMatrix4(n.projViewMatrix),n.worldRayDir.subVectors(n.worldRayEnd,n.worldRayStart).normalize();for(var c=0;cn.planeExtent.x/2+.0075||Math.abs(n.planeIntersectionLocal.z)>n.planeExtent.z/2+.0075)){n.planeQuaternion.setFromRotationMatrix(n.planeMatrix),n.planeHit.makeRotationFromQuaternion(n.planeQuaternion).setPosition(n.planeIntersection);for(var h=new e,u=0;u<16;u++)h.modelMatrix[u]=n.planeHit.elements[u];h.i=c,o.push(h)}}}return o.sort(i),o}}(),hitAR:(a=new THREE.Matrix4,i=new THREE.Vector3,r=new THREE.Quaternion,o=new THREE.Vector3,s=new THREE.Vector3,function(e,t,n,c){if(!this.arDisplay)return[];for(var l=this.hitTestNoAnchor(e,t),d=[],h=0;l&&h0&&(this.anchorsAddedDetail.anchors=c,this.el.emit("anchorsadded",this.anchorsAddedDetail)),this.anchorsUpdated=l,l.length>0&&(this.anchorsUpdatedDetail.anchors=l,this.el.emit("anchorsupdated",this.anchorsUpdatedDetail)),this.anchorsRemoved=d,d.length>0&&(this.anchorsRemovedDetail.anchors=d,this.el.emit("anchorsremoved",this.anchorsRemovedDetail))}})})},function(e,t){AFRAME.registerComponent("ar-anchors",{getSource:function(){var e;return this.source||(e=this.el.sceneEl.components.ar)&&(this.source=e.getSource()),this.source},getAnchors:function(){var e=this.getSource();if(e&&e.getAnchors)return e.getAnchors()}})},function(e,t){AFRAME.registerComponent("ar-images",{getSource:function(){var e;return this.source||(e=this.el.sceneEl.components.ar)&&(this.source=e.getSource()),this.source},addImage:function(e,t,n){var a=this.getSource();if(a&&a.addImage)return a.addImage(e,t,n)},removeImage:function(e){var t=this.getSource();if(t&&t.removeImage)return t.removeImage(e)}})},function(e,t){AFRAME.registerComponent("ar",{schema:{takeOverCamera:{default:!0},cameraUserHeight:{default:!1},worldSensing:{default:!0},hideUI:{default:!1}},dependencies:["webxr-ar","mozilla-xr-ar","ar-planes","ar-anchors"],getSource:function(){var e;if(!this.source){var t=this;t.dependencies.forEach((function(n){(e=t.el.sceneEl.components[n])&&e.arDisplay&&(t.source=e)}))}return this.source},getPlanes:function(){return this.source?this.source.getPlanes():void 0},getAnchors:function(){return this.source?this.source.getAnchors():void 0},addImage:function(e,t,n){return this.source.addImage(e,t,n)},removeImage:function(e){return this.source.removeImage(e)},init:function(){var e={takeOverCamera:this.data.takeOverCamera,cameraUserHeight:this.data.cameraUserHeight,worldSensing:this.data.worldSensing},t=this;this.dependencies.forEach((function(n){t.el.setAttribute(n,e)})),this.data.hideUI&&this.el.sceneEl.setAttribute("vr-mode-ui",{enabled:!1}),document.head.insertAdjacentHTML("beforeend","")}})},function(e,t){AFRAME.registerComponent("ar-camera",{schema:{enabled:{default:!0}},init:function(){var e=this.el.getAttribute("look-controls");this.wasLookControlsEnabled=!!e&&e.enabled},update:function(e){if(!e||e.enabled!==this.data.enabled)if(this.data.enabled){var t=this.el.getAttribute("look-controls");this.wasLookControlsEnabled=!!t&&t.enabled,this.wasLookControlsEnabled&&this.el.setAttribute("look-controls","enabled",!1)}else this.wasLookControlsEnabled&&this.el.setAttribute("look-controls","enabled",!0)},tick:function(e,t){if(this.data.enabled){var n=this.checkWhichAR();if(n){var a=n.getPosition();a&&this.el.setAttribute("position",a);var i=n.getRotation();if(i&&this.el.setAttribute("rotation",i),!this.el.sceneEl.is("vr-mode")){var r=n.getProjectionMatrix();r&&(this.el.components.camera.camera.projectionMatrix=r)}}}},checkWhichAR:function(){if(!this.whichar){var e=this.el.sceneEl.components.ar.getSource();if(!e||!e.arDisplay)return;this.whichar=e}return this.whichar}})},function(e,t){AFRAME.registerComponent("ar-raycaster",{dependencies:["raycaster"],schema:{x:{default:.5},y:{default:.5},el:{type:"selector"}},init:function(){this.raycaster=this.el.components.raycaster.raycaster,this.raycasterIntersectObjects=this.raycaster.intersectObjects.bind(this.raycaster),this.raycaster.intersectObjects=this.intersectObjects.bind(this)},update:function(e){this.data.el||this.el.sceneEl.object3D.el||(this.el.sceneEl.object3D.el=this.el.sceneEl)},intersectObjects:function(e,t,n){var a=this.raycasterIntersectObjects(e,t,n),i=this.hitAR();return i&&i.length&&(n?(i.forEach(e=>n.push(e)),a=n):i.forEach(e=>a.push(e))),a},hitAR:function(){var e=this.checkWhichAR();if(!e||!e.arDisplay)return[];var t=this.data.x,n=this.data.y;return arguments.length>=2&&(t=arguments[0],n=arguments[1]),e.hitAR(t,n,this.data.el,this.el)},checkWhichAR:function(){if(!this.whichar){var e=this.el.sceneEl.components.ar;if(e&&(e=e.getSource?e.getSource():void 0),!e||!e.arDisplay)return;this.whichar=e}return this.whichar}})}]); +!function(e){var t={};function n(a){if(t[a])return t[a].exports;var r=t[a]={i:a,l:!1,exports:{}};return e[a].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,a){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:a})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var a=Object.create(null);if(n.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(a,r,function(t){return e[t]}.bind(null,r));return a},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){n(1),n(2),n(3),n(4),n(5),n(6),n(7),n(8)},function(e,t){var n,a,r;AFRAME.registerComponent("webxr-ar",{schema:{takeOverCamera:{default:!0},cameraUserHeight:{default:!1},worldSensing:{default:!1}},init:function(){this.posePosition=new THREE.Vector3,this.poseQuaternion=new THREE.Quaternion,this.poseEuler=new THREE.Euler(0,0,0,"YXZ"),this.poseRotation=new THREE.Vector3,this.projectionMatrix=new THREE.Matrix4,this.onceSceneLoaded=this.onceSceneLoaded.bind(this),this.el.sceneEl.hasLoaded?setTimeout(this.onceSceneLoaded):this.el.sceneEl.addEventListener("loaded",this.onceSceneLoaded),this.rawPlanes_=null,this.planes_=new Map,this.anchors_=new Map},convertPolygonToVertices:function(e){return newVertices},convertedPlane:function(e,t){var n,a=[0,0],r=[0,0],i=e.polygon.length,o=new Float32Array(3*i),s=0,c=0;for(s=0;sn.x&&(a[0]=n.x),r[0]n.z&&(a[1]=n.z),r[1]{a.detectedPlanes&&a.detectedPlanes.has(e)||this.rawPlaneRemoved(e)});let r=this.el.sceneEl.time;a.detectedPlanes&&a.detectedPlanes.forEach(e=>{let t=n.getPose(e.planeSpace,this.refSpace);this.rawPlanes_.has(e)?e.lastChangedTime==r?this.rawPlaneUpdated(e,t):this.rawPlaneNotUpdated(e,t):this.rawPlaneCreated(e,t)}),this.rawPlanes_=a.detectedPlanes},takeOverCamera:function(e){this.arCamera=e,e.isARPerspectiveCamera=!0,e.vrDisplay=this.arDisplay,e.el.setAttribute("ar-camera","enabled",!0)},onceSceneLoaded:function(){var e=this;window.addEventListener("ardisplayconnect",(function(){e.arDisplay||e.checkForARDisplay()})),this.checkForARDisplay()},checkForARDisplay:function(){if(navigator.xr&&navigator.xr.isSessionSupported){var e=this;e.arDisplay={type:"webxr-ar"},navigator.xr.isSessionSupported("immersive-ar").then((function(t){if(t){let t=["local-floor"],n=[];(e.data.worldSensing?t:n).push("hit-test");let a=e.el.sceneEl.getAttribute("webxr");a?(a.optionalFeatures.forEach((function(e){n=n.filter((function(t,n,a){return t!=e}))})),a.requiredFeatures.forEach((function(e){t=t.filter((function(t,n,a){return t!=e}))})),t.forEach((function(e){a.optionalFeatures=a.optionalFeatures.filter((function(t,n,a){return t!=e}))})),a.requiredFeatures=a.requiredFeatures.concat(t),a.optionalFeatures=a.optionalFeatures.concat(n),e.el.sceneEl.setAttribute("webxr",a)):e.el.sceneEl.setAttribute("webxr",{requiredFeatures:t.join(","),optionalFeatures:n.join(",")}),e.el.sceneEl.setAttribute("vr-mode-ui","enabled","true"),e.xrHitTestSource=null,e.viewerSpace=null,e.refSpace=null,e.el.sceneEl.renderer.xr.addEventListener("sessionend",t=>{e.viewerSpace=null,e.refSpace=null,e.xrHitTestSource=null}),e.el.sceneEl.renderer.xr.addEventListener("sessionstart",t=>{let n=e.el.sceneEl.renderer.xr.getSession(),a=e.el.sceneEl.canvas;n.addEventListener("selectstart",(function(e){var t=e.inputSource.gamepad.axes[0],n=e.inputSource.gamepad.axes[1];setTimeout(()=>{var e=new TouchEvent("touchstart",{view:window,bubbles:!0,cancelable:!0});e.targetTouches=[{pageX:t,pageY:n}],a.dispatchEvent(e)})})),n.addEventListener("selectend",(function(e){var t=e.inputSource.gamepad.axes[0],n=e.inputSource.gamepad.axes[1];setTimeout(()=>{var e=new TouchEvent("touchend",{view:window,bubbles:!0,cancelable:!0});e.targetTouches=[{pageX:t,pageY:n}],a.dispatchEvent(e)})})),n.addEventListener("select",(function(e){var t=e.inputSource.gamepad.axes[0],n=e.inputSource.gamepad.axes[1];setTimeout(()=>{var e=new MouseEvent("click",{clientX:t,clientY:n,bubbles:!0,cancelable:!0});a.dispatchEvent(e)})})),n.requestReferenceSpace("viewer").then(t=>{e.viewerSpace=t,e.data.worldSensing&&n.requestHitTestSource({space:e.viewerSpace}).then(t=>{e.xrHitTestSource=t})}),n.requestReferenceSpace("local-floor").then(t=>{e.refSpace=t}),e.data.worldSensing&&n.updateWorldTrackingState({planeDetectionState:{enabled:!0}})})}}))}},getPosition:function(){return this.arDisplay&&this.arDisplay.getFrameData?this.posePosition:null},getOrientation:function(){return this.arDisplay&&this.arDisplay.getFrameData?this.poseQuaternion:null},getRotation:function(){return this.arDisplay&&this.arDisplay.getFrameData?this.poseRotation:null},getProjectionMatrix:function(){return this.arDisplay&&this.arDisplay.getFrameData?this.projectionMatrix:null},hitAR:(n=new THREE.Matrix4,a=new THREE.Vector3,new THREE.Quaternion,new THREE.Vector3,r=new THREE.Vector3,function(e,t,i,o){if(!this.arDisplay)return[];var s=[];if(this.el.sceneEl.is("ar-mode")){if(!this.viewerSpace)return;let e=this.el.sceneEl.frame,t=e.getViewerPose(this.refSpace);if(this.xrHitTestSource&&t){let t=e.getHitTestResults(this.xrHitTestSource);s=[];for(var c=0;t&&c>18]+n[(258048&r)>>12]+n[(4032&r)>>6]+n[63&r];return 1==o?t+=n[(252&(r=a[s]))>>2]+n[(3&r)<<4]+"==":2==o&&(t+=n[(64512&(r=a[s]<<8|a[s+1]))>>10]+n[(1008&r)>>4]+n[(15&r)<<2]+"="),t}(i.getImageData(0,0,a.width,a.height).data);if(o){window.callbackForCreateImageAnchorCounter=(window.callbackForCreateImageAnchorCounter||0)+1;var s="callbackForCreateImageAnchor_"+window.callbackForCreateImageAnchorCounter,c=e;window[s]=function(e){void 0!==e.created?e.created?window.webkit.messageHandlers.activateDetectionImage.postMessage({callback:s,uid:c}):(console.log("addImage: !created; ",e.error),delete window[s]):void 0!==e.activated&&(e.activated||console.log("addImage: !activated; ",e.error),delete window[s])},window.webkit.messageHandlers.createImageAnchor.postMessage({callback:s,uid:e,buffer:o,imageWidth:a.width,imageHeight:a.height,physicalWidth:n})}else console.log("!!! addImage: !b64ImageData, aborting")}else console.log("!!! addImage: !aImg.width || !aImg.height, aborting");else console.log("!!! addImage: !aImg.complete || !aImg.naturalHeight, aborting")},removeImage:function(e){if(!this.arDisplay)return null;window.callbackForRemoveImageAnchorCounter=(window.callbackForRemoveImageAnchorCounter||0)+1;var t="callbackForRemoveImageAnchor_"+window.callbackForRemoveImageAnchorCounter,n=e;window[t]=function(e){void 0!==e.deactivated&&(e.deactivated||(console.log("!!! "+t+": !deactivated",e.error),delete window[t]),window.webkit.messageHandlers.destroyDetectionImage.postMessage({callback:t,uid:n})),void 0!==e.destroyed&&(e.destroyed||console.log("!!! "+t+": !destroyed, ",e.error),delete window[t])},window.webkit.messageHandlers.deactivateDetectionImage.postMessage({callback:t,uid:n})},getAnchors:function(){return Array.from(this.anchors_.values())},getPlanes:function(){return Array.from(this.planes_.values())},hitTestNoAnchor:function(){function e(){return this.modelMatrix=new Float32Array(16),this}var t,n={rayStart:new THREE.Vector3,rayEnd:new THREE.Vector3,cameraPosition:new THREE.Vector3,cameraQuaternion:new THREE.Quaternion,projViewMatrix:new THREE.Matrix4,worldRayStart:new THREE.Vector3,worldRayEnd:new THREE.Vector3,worldRayDir:new THREE.Vector3,planeMatrix:new THREE.Matrix4,planeMatrixInverse:new THREE.Matrix4,planeExtent:new THREE.Vector3,planePosition:new THREE.Vector3,planeCenter:new THREE.Vector3,planeNormal:new THREE.Vector3,planeIntersection:new THREE.Vector3,planeIntersectionLocal:new THREE.Vector3,planeHit:new THREE.Matrix4,planeQuaternion:new THREE.Quaternion},a=(t=new THREE.Vector3,function(e,n,a,r){var i=e.dot(r);return t.subVectors(n,a),t.dot(e)/i}),r=function(e,t){n.planeMatrix.fromArray(e.modelMatrix),n.planeIntersection.setFromMatrixPosition(n.planeMatrix);var a=n.planeIntersection.distanceTo(n.cameraPosition);return n.planeMatrix.fromArray(t.modelMatrix),n.planeIntersection.setFromMatrixPosition(n.planeMatrix),a1||i<0||i>1)throw new Error("hitTest - x and y values must be normalized [0,1]!");var o=[],s=this.getPlanes();if(!s||0===s.length)return o;n.rayStart.set(2*t-1,2*(1-i)-1,0),n.rayEnd.set(2*t-1,2*(1-i)-1,1),n.planeMatrix.multiplyMatrices(this.projectionMatrix,this.viewMatrix),n.projViewMatrix.getInverse(n.planeMatrix),n.worldRayStart.copy(n.rayStart).applyMatrix4(n.projViewMatrix),n.worldRayEnd.copy(n.rayEnd).applyMatrix4(n.projViewMatrix),n.worldRayDir.subVectors(n.worldRayEnd,n.worldRayStart).normalize();for(var c=0;cn.planeExtent.x/2+.0075||Math.abs(n.planeIntersectionLocal.z)>n.planeExtent.z/2+.0075)){n.planeQuaternion.setFromRotationMatrix(n.planeMatrix),n.planeHit.makeRotationFromQuaternion(n.planeQuaternion).setPosition(n.planeIntersection);for(var h=new e,u=0;u<16;u++)h.modelMatrix[u]=n.planeHit.elements[u];h.i=c,o.push(h)}}}return o.sort(r),o}}(),hitAR:(a=new THREE.Matrix4,r=new THREE.Vector3,i=new THREE.Quaternion,o=new THREE.Vector3,s=new THREE.Vector3,function(e,t,n,c){if(!this.arDisplay)return[];for(var l=this.hitTestNoAnchor(e,t),d=[],h=0;l&&h0&&(this.anchorsAddedDetail.anchors=c,this.el.emit("anchorsadded",this.anchorsAddedDetail)),this.anchorsUpdated=l,l.length>0&&(this.anchorsUpdatedDetail.anchors=l,this.el.emit("anchorsupdated",this.anchorsUpdatedDetail)),this.anchorsRemoved=d,d.length>0&&(this.anchorsRemovedDetail.anchors=d,this.el.emit("anchorsremoved",this.anchorsRemovedDetail))}})})},function(e,t){AFRAME.registerComponent("ar-anchors",{getSource:function(){var e;return this.source||(e=this.el.sceneEl.components.ar)&&(this.source=e.getSource()),this.source},getAnchors:function(){var e=this.getSource();if(e&&e.getAnchors)return e.getAnchors()}})},function(e,t){AFRAME.registerComponent("ar-images",{getSource:function(){var e;return this.source||(e=this.el.sceneEl.components.ar)&&(this.source=e.getSource()),this.source},addImage:function(e,t,n){var a=this.getSource();if(a&&a.addImage)return a.addImage(e,t,n)},removeImage:function(e){var t=this.getSource();if(t&&t.removeImage)return t.removeImage(e)}})},function(e,t){AFRAME.registerComponent("ar",{schema:{takeOverCamera:{default:!0},cameraUserHeight:{default:!1},worldSensing:{default:!0},hideUI:{default:!1}},dependencies:["webxr-ar","mozilla-xr-ar","ar-planes","ar-anchors"],getSource:function(){var e;if(!this.source){var t=this;t.dependencies.forEach((function(n){(e=t.el.sceneEl.components[n])&&e.arDisplay&&(t.source=e)}))}return this.source},getPlanes:function(){return this.source?this.source.getPlanes():void 0},getAnchors:function(){return this.source?this.source.getAnchors():void 0},addImage:function(e,t,n){return this.source.addImage(e,t,n)},removeImage:function(e){return this.source.removeImage(e)},init:function(){var e={takeOverCamera:this.data.takeOverCamera,cameraUserHeight:this.data.cameraUserHeight,worldSensing:this.data.worldSensing},t=this;this.dependencies.forEach((function(n){t.el.setAttribute(n,e)})),this.data.hideUI&&this.el.sceneEl.setAttribute("vr-mode-ui",{enabled:!1}),document.head.insertAdjacentHTML("beforeend","")}})},function(e,t){AFRAME.registerComponent("ar-camera",{schema:{enabled:{default:!0}},init:function(){var e=this.el.getAttribute("look-controls");this.wasLookControlsEnabled=!!e&&e.enabled},update:function(e){if(!e||e.enabled!==this.data.enabled)if(this.data.enabled){var t=this.el.getAttribute("look-controls");this.wasLookControlsEnabled=!!t&&t.enabled,this.wasLookControlsEnabled&&this.el.setAttribute("look-controls","enabled",!1)}else this.wasLookControlsEnabled&&this.el.setAttribute("look-controls","enabled",!0)},tick:function(e,t){if(this.data.enabled){var n=this.checkWhichAR();if(n){var a=n.getPosition();a&&this.el.setAttribute("position",a);var r=n.getRotation();if(r&&this.el.setAttribute("rotation",r),!this.el.sceneEl.is("vr-mode")){var i=n.getProjectionMatrix();i&&(this.el.components.camera.camera.projectionMatrix=i)}}}},checkWhichAR:function(){if(!this.whichar){var e=this.el.sceneEl.components.ar.getSource();if(!e||!e.arDisplay)return;this.whichar=e}return this.whichar}})},function(e,t){AFRAME.registerComponent("ar-raycaster",{dependencies:["raycaster"],schema:{x:{default:.5},y:{default:.5},el:{type:"selector"}},init:function(){this.raycaster=this.el.components.raycaster.raycaster,this.raycasterIntersectObjects=this.raycaster.intersectObjects.bind(this.raycaster),this.raycaster.intersectObjects=this.intersectObjects.bind(this)},update:function(e){this.data.el||this.el.sceneEl.object3D.el||(this.el.sceneEl.object3D.el=this.el.sceneEl)},intersectObjects:function(e,t,n){var a=this.raycasterIntersectObjects(e,t,n),r=this.hitAR();return r&&r.length&&(n?(r.forEach(e=>n.push(e)),a=n):r.forEach(e=>a.push(e))),a},hitAR:function(){var e=this.checkWhichAR();if(!e||!e.arDisplay)return[];var t=this.data.x,n=this.data.y;return arguments.length>=2&&(t=arguments[0],n=arguments[1]),e.hitAR(t,n,this.data.el,this.el)},checkWhichAR:function(){if(!this.whichar){var e=this.el.sceneEl.components.ar;if(e&&(e=e.getSource?e.getSource():void 0),!e||!e.arDisplay)return;this.whichar=e}return this.whichar}})}]); //# sourceMappingURL=aframe-ar.min.js.map \ No newline at end of file diff --git a/dist/aframe-ar.min.js.map b/dist/aframe-ar.min.js.map index edb261e..5f5e628 100644 --- a/dist/aframe-ar.min.js.map +++ b/dist/aframe-ar.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/index.js","webpack:///./src/webxr-ar.js","webpack:///./src/mozilla-xr-ar.js","webpack:///./src/ar-planes.js","webpack:///./src/ar-anchors.js","webpack:///./src/ar-images.js","webpack:///./src/ar.js","webpack:///./src/ar-camera.js","webpack:///./src/ar-raycaster.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","transform","hitpoint","worldpos","AFRAME","registerComponent","schema","takeOverCamera","default","cameraUserHeight","worldSensing","init","this","posePosition","THREE","Vector3","poseQuaternion","Quaternion","poseEuler","Euler","poseRotation","projectionMatrix","Matrix4","onceSceneLoaded","el","sceneEl","hasLoaded","setTimeout","addEventListener","rawPlanes_","planes_","Map","anchors_","convertPolygonToVertices","polygon","newVertices","convertedPlane","rawPlane","pose","vertex","mins","maxs","verticesLength","length","Float32Array","j","x","y","z","position","set","id","center","extent","modelMatrix","matrix","alignment","orientation","vertices","rawPlaneRemoved","delete","rawPlaneUpdated","rawPlaneNotUpdated","rawPlaneCreated","Math","random","toString","substring","tick","dt","frame","arDisplay","worldInformation","world","forEach","plane","detectedPlanes","has","timestamp","time","planePose","getPose","planeSpace","refSpace","lastChangedTime","camera","arCamera","isARPerspectiveCamera","vrDisplay","setAttribute","self","window","checkForARDisplay","navigator","xr","isSessionSupported","type","then","supported","ourRequiredFeatures","ourOptionalFeatures","data","push","existingFeatures","getAttribute","optionalFeatures","feature","filter","index","arr","requiredFeatures","concat","join","xrHitTestSource","viewerSpace","renderer","ev","session","getSession","canvas","e","pageX","inputSource","gamepad","axes","pageY","event","TouchEvent","view","bubbles","cancelable","targetTouches","dispatchEvent","MouseEvent","clientX","clientY","requestReferenceSpace","space","requestHitTestSource","hitTestSource","updateWorldTrackingState","planeDetectionState","enabled","getPosition","getFrameData","getOrientation","getRotation","getProjectionMatrix","hitAR","raycasterEl","hitsToReturn","is","xrViewerPose","getViewerPose","hitTestResults","getHitTestResults","fromArray","setFromMatrixPosition","object3D","getWorldPosition","distance","distanceTo","point","clone","addImage","url","physicalWidth","removeImage","getAnchors","Array","from","values","getPlanes","convertVertices","hitquat","hitscale","onInit","onWatch","forceResize","poseMatrix","viewMatrix","webkit","messageHandlers","initAR","options","ui","browser","points","focus","rec","rec_time","mic","build","warnings","anchors","debug","statistics","callback","nativeTime","eventName","console","log","vrmodeui","components","newarbutton","enterAREl","cloneNode","parentNode","replaceChild","classList","remove","onclick","scene","scenes","addState","orientationModalEl","style","emit","target","postMessage","wakelock","release","sz","Vector2","pixelRatio","getPixelRatio","getSize","width","height","userGrantedWorldSensingData","screen","devicePixelRatio","sx","sy","sc","forceResizeX","forceResizeY","setPixelRatio","copy","watchAR","location","objects","light_intensity","deviceId","frameData","handleFrame","element","camera_transform","decompose","setFromQuaternion","RAD2DEG","projection_camera","camera_view","userHeight","poseLost","newObjects","plane_center","uuid","plane_extent","plane_alignment","geometry","anchorData","removedObjects","anchor","aImg","aCanvas","document","createElement","aContext","getContext","crossOrigin","src","body","appendChild","complete","naturalHeight","drawImage","b64ImageData","buffer","base64","encodings","bytes","ArrayBuffer","Uint8Array","arrayBuffer","ImageData","chunk","byteLength","byteRemainder","mainLength","encode","getImageData","callbackForCreateImageAnchorCounter","callbackName","imageName","undefined","created","activateDetectionImage","uid","error","activated","createImageAnchor","imageWidth","imageHeight","callbackForRemoveImageAnchorCounter","deactivated","destroyDetectionImage","destroyed","deactivateDetectionImage","hitTestNoAnchor","VRHit","rayToPlane","hitVars","rayStart","rayEnd","cameraPosition","cameraQuaternion","projViewMatrix","worldRayStart","worldRayEnd","worldRayDir","planeMatrix","planeMatrixInverse","planeExtent","planePosition","planeCenter","planeNormal","planeIntersection","planeIntersectionLocal","planeHit","planeQuaternion","rayIntersectsPlane","rayOrigin","rayDirection","denom","dot","subVectors","sortFunction","a","b","distA","Error","hits","planes","multiplyMatrices","getInverse","applyMatrix4","normalize","planeAlignment","multiplyScalar","addVectors","abs","setFromRotationMatrix","makeRotationFromQuaternion","setPosition","hit","elements","sort","tempScale","tempMat4","tempPosition","tempQuaternion","getPlaneSource","whichar","planeSource","getSource","anchorsAdded","anchorsAddedDetail","anchorsUpdated","anchorsUpdatedDetail","anchorsRemoved","anchorsRemovedDetail","addedThese","updatedThese","removedThese","seenThese","planespec","identifier","adding","hasTimestamp","compose","slice","utils","deepEqual","keys","source","hideUI","dependencies","sys","head","insertAdjacentHTML","lookControls","wasLookControlsEnabled","update","oldData","checkWhichAR","pos","rot","raycaster","raycasterIntersectObjects","intersectObjects","recursive","rawIntersections","results","hitARResults","arguments"],"mappings":"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","file":"aframe-ar.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","require('./webxr-ar');\n//require('./three-ar');\nrequire('./mozilla-xr-ar');\nrequire('./ar-planes');\nrequire('./ar-anchors');\nrequire('./ar-images');\nrequire('./ar');\nrequire('./ar-camera');\nrequire('./ar-raycaster');\n\n","/* global AFRAME, THREE, VRFrameData */\n\nAFRAME.registerComponent('webxr-ar', {\n schema: {\n takeOverCamera: {default: true},\n cameraUserHeight: {default: false},\n worldSensing: {default: false} // currently unused\n },\n\n init: function () {\n this.posePosition = new THREE.Vector3();\n this.poseQuaternion = new THREE.Quaternion();\n this.poseEuler = new THREE.Euler(0, 0, 0, 'YXZ');\n this.poseRotation = new THREE.Vector3();\n this.projectionMatrix = new THREE.Matrix4();\n\n this.onceSceneLoaded = this.onceSceneLoaded.bind(this);\n if (this.el.sceneEl.hasLoaded) {\n setTimeout(this.onceSceneLoaded);\n } else {\n this.el.sceneEl.addEventListener('loaded', this.onceSceneLoaded);\n }\n\n // Add planes handling, so we can do synchronous hit test.\n\n this.rawPlanes_ = null;\n this.planes_ = new Map();\n this.anchors_ = new Map();\n },\n\n convertPolygonToVertices: function(polygon) {\n return newVertices;\n },\n\n convertedPlane: function(rawPlane, pose) {\n var mins = [0, 0];\n var maxs = [0, 0];\n var verticesLength = rawPlane.polygon.length;\n var newVertices = new Float32Array(verticesLength * 3);\n var i = 0;\n var j = 0;\n var vertex;\n for (i = 0; i < verticesLength; i++) {\n vertex = rawPlane.polygon[i];\n newVertices[j] = vertex.x;\n newVertices[j + 1] = vertex.y;\n newVertices[j + 2] = vertex.z;\n j += 3;\n if (i == 0) {\n mins[0] = maxs[0] = vertex.x;\n mins[1] = maxs[1] = vertex.z;\n } else {\n if (mins[0] > vertex.x) { mins[0] = vertex.x; }\n if (maxs[0] < vertex.x) { maxs[0] = vertex.x; }\n if (mins[1] > vertex.z) { mins[1] = vertex.z; }\n if (maxs[1] < vertex.z) { maxs[1] = vertex.z; }\n }\n }\n var position = pose.transform.position;\n rawPlane.position.set(position.x, position.y, position.z);\n var converted = {\n id: rawPlane.id,\n center: rawPlane.position,\n extent: [maxs[0] - mins[0], maxs[1] - mins[1]],\n modelMatrix: pose.transform.matrix,\n alignment: rawPlane.orientation != 'Horizontal' ? 1 : 0,\n vertices: newVertices\n };\n return converted;\n },\n\n rawPlaneRemoved: function(rawPlane) {\n // remove the converted plane\n this.planes_.delete(rawPlane.id);\n },\n\n rawPlaneUpdated: function(rawPlane, pose) {\n // convert the updated plane\n this.planes_.set(rawPlane.id, this.convertedPlane(rawPlane, pose));\n },\n\n rawPlaneNotUpdated: function(rawPlane, pose) {\n // FIXME: check is broken so update anyway\n this.rawPlaneUpdated(rawPlane, pose);\n // do nothing\n },\n\n rawPlaneCreated: function(rawPlane, pose) {\n // assign and attach an id... for now, use Math.random()\n rawPlane.id = Math.random().toString().substring(2);\n rawPlane.position = new THREE.Vector3();\n // convert the plane\n this.planes_[rawPlane.id] = this.convertedPlane(rawPlane, pose);\n },\n\n tick: function (t, dt) {\n let frame = this.el.sceneEl.frame;\n if (!this.arDisplay\n || !frame\n || !frame.worldInformation) { return; }\n\n // use the planes information\n let world = frame.worldInformation;\n\n // check for removed planes\n this.rawPlanes_ && this.rawPlanes_.forEach(plane => {\n if(!world.detectedPlanes || !world.detectedPlanes.has(plane)) {\n // Handle removed plane - `plane` was present in previous frame but is no longer tracked.\n this.rawPlaneRemoved(plane);\n }\n });\n\n // check for changed planes\n let timestamp = this.el.sceneEl.time;\n world.detectedPlanes && world.detectedPlanes.forEach(plane => {\n let planePose = frame.getPose(plane.planeSpace, this.refSpace);\n if (this.rawPlanes_.has(plane)) {\n if(plane.lastChangedTime == timestamp) {\n // Handle previously seen plane that was updated in current frame.\n this.rawPlaneUpdated(plane, planePose);\n } else {\n // Handle previously seen plane that was not updated in current frame.\n // Depending on the application, this could be a no-op.\n this.rawPlaneNotUpdated(plane, planePose);\n }\n } else {\n // Handle new plane.\n this.rawPlaneCreated(plane, planePose);\n }\n });\n \n this.rawPlanes_ = world.detectedPlanes;\n },\n\n takeOverCamera: function (camera) {\n this.arCamera = camera;\n camera.isARPerspectiveCamera = true; // HACK - is this necessary?\n camera.vrDisplay = this.arDisplay; // HACK - is this necessary?\n camera.el.setAttribute('ar-camera', 'enabled', true);\n },\n\n onceSceneLoaded: function () {\n var self = this;\n window.addEventListener('ardisplayconnect', function () {\n if (!self.arDisplay) { self.checkForARDisplay(); }\n });\n\n // Check now for AR display.\n this.checkForARDisplay();\n },\n\n checkForARDisplay: function () {\n // check to see if webxr ar mode is supported\n if (!navigator.xr || !navigator.xr.isSessionSupported) { return; }\n\n var self = this;\n self.arDisplay = {type: 'webxr-ar'};\n\n navigator.xr.isSessionSupported('immersive-ar').then(function(supported) {\n if (supported) {\n let ourRequiredFeatures = ['local-floor'];\n let ourOptionalFeatures = [];\n (self.data.worldSensing ? ourRequiredFeatures : ourOptionalFeatures).push('hit-test');\n let existingFeatures = self.el.sceneEl.getAttribute('webxr');\n if (!existingFeatures) {\n // here, we assume we can set as map and not String (?) \n self.el.sceneEl.setAttribute('webxr', { \n requiredFeatures: ourRequiredFeatures.join(','), \n optionalFeatures: ourOptionalFeatures.join(',') \n });\n } else {\n // here, we assume we get and set as map and not String (?)\n // remove existing optional features from our optional\n existingFeatures.optionalFeatures.forEach(function (feature) {\n ourOptionalFeatures = ourOptionalFeatures.filter(function(value, index, arr){ return value != feature;});\n });\n // remove existing required features from our required\n existingFeatures.requiredFeatures.forEach(function (feature) {\n ourRequiredFeatures = ourRequiredFeatures.filter(function(value, index, arr){ return value != feature;});\n });\n // remove our required features from existing optional\n ourRequiredFeatures.forEach(function (feature) {\n existingFeatures.optionalFeatures = existingFeatures.optionalFeatures.filter(function(value, index, arr){ return value != feature;});\n });\n // add our required and optional features to the existing\n existingFeatures.requiredFeatures = existingFeatures.requiredFeatures.concat(ourRequiredFeatures);\n existingFeatures.optionalFeatures = existingFeatures.optionalFeatures.concat(ourOptionalFeatures);\n\n self.el.sceneEl.setAttribute('webxr', existingFeatures);\n }\n\n self.el.sceneEl.setAttribute('vr-mode-ui', \"enabled\", \"true\");\n // auto-entering AR doesn't work.\n\n self.xrHitTestSource = null;\n self.viewerSpace = null;\n self.refSpace = null;\n\n self.el.sceneEl.renderer.xr.addEventListener('sessionend', (ev) => {\n self.viewerSpace = null;\n self.refSpace = null;\n self.xrHitTestSource = null;\n });\n self.el.sceneEl.renderer.xr.addEventListener('sessionstart', (ev) => {\n let session = self.el.sceneEl.renderer.xr.getSession();\n let el = self.el.sceneEl.canvas;\n\n session.addEventListener('selectstart', function (e) {\n // dispatch touchstart\n var pageX = e.inputSource.gamepad.axes[0];\n var pageY = e.inputSource.gamepad.axes[1];\n setTimeout(() => {\n var event = new TouchEvent('touchstart', {\n view: window,\n bubbles: true,\n cancelable: true\n });\n event.targetTouches = [{ pageX: pageX, pageY: pageY }];\n el.dispatchEvent(event);\n });\n });\n\n session.addEventListener('selectend', function (e) {\n // dispatch touchend\n var pageX = e.inputSource.gamepad.axes[0];\n var pageY = e.inputSource.gamepad.axes[1];\n setTimeout(() => {\n var event = new TouchEvent('touchend', {\n view: window,\n bubbles: true,\n cancelable: true\n });\n event.targetTouches = [{ pageX: pageX, pageY: pageY }];\n el.dispatchEvent(event);\n });\n });\n\n session.addEventListener('select', function (e) {\n // dispatch click\n var pageX = e.inputSource.gamepad.axes[0];\n var pageY = e.inputSource.gamepad.axes[1];\n setTimeout(() => {\n var event = new MouseEvent('click', { \n clientX: pageX, \n clientY: pageY, \n bubbles: true,\n cancelable: true\n });\n el.dispatchEvent(event);\n });\n });\n\n session.requestReferenceSpace('viewer').then((space) => {\n self.viewerSpace = space;\n if (self.data.worldSensing) {\n session.requestHitTestSource({space: self.viewerSpace})\n .then((hitTestSource) => {\n self.xrHitTestSource = hitTestSource;\n })\n }\n });\n\n session.requestReferenceSpace('local-floor').then((space) => {\n self.refSpace = space;\n });\n\n // Ask for planes, if we should.\n if (self.data.worldSensing) {\n session.updateWorldTrackingState({planeDetectionState : {enabled : true}});\n }\n });\n }\n });\n },\n\n getPosition: function () {\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\n return this.posePosition;\n },\n\n getOrientation: function () {\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\n return this.poseQuaternion;\n },\n\n getRotation: function () {\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\n return this.poseRotation;\n },\n\n getProjectionMatrix: function () {\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\n return this.projectionMatrix;\n },\n\n hitAR: (function () { \n // Temporary variables, only within closure scope.\n var transform = new THREE.Matrix4();\n var hitpoint = new THREE.Vector3();\n var hitquat = new THREE.Quaternion();\n var hitscale = new THREE.Vector3();\n var worldpos = new THREE.Vector3();\n \n // The desired function, which this returns.\n return function (x, y, el, raycasterEl) {\n if (!this.arDisplay) { return []; }\n var hitsToReturn = [];\n\n if (this.el.sceneEl.is('ar-mode')) {\n if (!this.viewerSpace) return;\n\n let frame = this.el.sceneEl.frame;\n let xrViewerPose = frame.getViewerPose(this.refSpace);\n\n if (this.xrHitTestSource && xrViewerPose) {\n let hitTestResults = frame.getHitTestResults(this.xrHitTestSource);\n\n // Process AR hits.\n var hitsToReturn = [];\n for (var i = 0; hitTestResults && i < hitTestResults.length; i++) {\n let pose = hitTestResults[i].getPose(this.refSpace);\n transform.fromArray(pose.transform.matrix);\n hitpoint.setFromMatrixPosition(transform); //transform.decompose(hitpoint, hitquat, hitscale);\n raycasterEl.object3D.getWorldPosition(worldpos);\n\n hitsToReturn.push({\n distance: hitpoint.distanceTo(worldpos),\n point: hitpoint.clone(), // Vector3\n object: (el && el.object3D) || this.el.sceneEl.object3D\n/*\n // We don't have any of these properties...\n face: undefined, // Face3\n faceIndex: undefined,\n index: undefined,\n uv: undefined // Vector2\n*/\n });\n }\n }\n }\n\n return hitsToReturn;\n }\n })(),\n\n // Link to image marker and anchor support.\n\n addImage: function (name, url, physicalWidth) {\n if (!this.arDisplay) { return null; }\n\n return null;\n },\n\n removeImage: function (name) {\n if (!this.arDisplay) { return null; }\n\n return null;\n },\n\n getAnchors: function () {\n return Array.from(this.anchors_.values());\n },\n\n // Use planes to do synchronous hit test.\n\n getPlanes: function () {\n return Array.from(this.planes_.values());\n }\n});\n","/* global AFRAME, THREE */\n\nfunction convertVertices(vertices) {\n var verticesLength = vertices.length;\n var newVertices = new Float32Array(verticesLength * 3);\n var i = 0;\n var j = 0;\n var vertex;\n for (i = 0; i < verticesLength; i++) {\n vertex = vertices[i];\n newVertices[j] = vertex.x;\n newVertices[j + 1] = vertex.y;\n newVertices[j + 2] = vertex.z;\n j += 3;\n }\n return newVertices;\n}\n\n\nfunction encode(buffer) {\nvar base64 = ''\nvar encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\n\nvar bytes = buffer; // assume it's a typedArrayBuffer \n \nif (buffer instanceof ArrayBuffer) {\nbytes = new Uint8Array(arrayBuffer)\n} else if (buffer instanceof ImageData) {\nbytes = buffer.data\n}\n\nvar byteLength = buffer.length\nvar byteRemainder = byteLength % 3\nvar mainLength = byteLength - byteRemainder\n\nvar a, b, c, d\nvar chunk\n\n// Main loop deals with bytes in chunks of 3\nfor (var i = 0; i < mainLength; i = i + 3) {\n// Combine the three bytes into a single integer\nchunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]\n\n// Use bitmasks to extract 6-bit segments from the triplet\na = (chunk & 16515072) >> 18 // 16515072 = (2^6 - 1) << 18\nb = (chunk & 258048) >> 12 // 258048 = (2^6 - 1) << 12\nc = (chunk & 4032) >> 6 // 4032 = (2^6 - 1) << 6\nd = chunk & 63 // 63 = 2^6 - 1\n\n// Convert the raw binary segments to the appropriate ASCII encoding\nbase64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]\n}\n\n// Deal with the remaining bytes and padding\nif (byteRemainder == 1) {\nchunk = bytes[mainLength]\n\na = (chunk & 252) >> 2 // 252 = (2^6 - 1) << 2\n\n// Set the 4 least significant bits to zero\nb = (chunk & 3) << 4 // 3 = 2^2 - 1\n\nbase64 += encodings[a] + encodings[b] + '=='\n} else if (byteRemainder == 2) {\nchunk = (bytes[mainLength] << 8) | bytes[mainLength + 1]\n\na = (chunk & 64512) >> 10 // 64512 = (2^6 - 1) << 10\nb = (chunk & 1008) >> 4 // 1008 = (2^6 - 1) << 4\n\n// Set the 2 least significant bits to zero\nc = (chunk & 15) << 2 // 15 = 2^4 - 1\n\nbase64 += encodings[a] + encodings[b] + encodings[c] + '='\n}\n\nreturn base64\n}\n\n\n\n\n\nAFRAME.registerComponent('mozilla-xr-ar', {\n schema: {\n takeOverCamera: {default: true},\n cameraUserHeight: {default: false},\n worldSensing: {default: true}\n },\n\n init: function () {\n this.onInit = this.onInit.bind(this);\n this.onWatch = this.onWatch.bind(this);\n\n this.forceResize = this.forceResize.bind(this);\n\n this.poseMatrix = new THREE.Matrix4();\n this.posePosition = new THREE.Vector3();\n this.poseQuaternion = new THREE.Quaternion();\n this.poseEuler = new THREE.Euler(0, 0, 0, 'YXZ');\n this.poseRotation = new THREE.Vector3();\n this.projectionMatrix = new THREE.Matrix4();\n this.viewMatrix = new THREE.Matrix4();\n\n this.onceSceneLoaded = this.onceSceneLoaded.bind(this);\n if (this.el.sceneEl.hasLoaded) {\n setTimeout(this.onceSceneLoaded);\n } else {\n this.el.sceneEl.addEventListener('loaded', this.onceSceneLoaded);\n }\n\n // Add planes handling, so we can do synchronous hit test.\n // From google-ar/WebARonARKit; also see webxr-polyfill/ARKitWrapper.js\n\n this.planes_ = new Map();\n this.anchors_ = new Map();\n },\n\n // For WebXR Viewer, we are currently directly hooking the callback\n // used to provide frame data, so we don't need to do anything in tick!\n\n takeOverCamera: function (camera) {\n this.arCamera = camera;\n camera.el.setAttribute('ar-camera', 'enabled', true);\n },\n\n onceSceneLoaded: function () {\n // Check if the low-level WebXR Viewer interfaces are there.\n if (!window.webkit || !window.webkit.messageHandlers) { return; }\n if (!window.webkit.messageHandlers.initAR) { return; }\n\n window['arkitCallback' + 0] = this.onInit;\n window['arkitCallback' + 1] = this.onWatch;\n\n // Compose data to use with initAR.\n var data = {\n options: {\n ui: {\n browser: true,\n points: true,\n focus: false,\n rec: true,\n rec_time: true,\n mic: false,\n build: false,\n plane: true,\n warnings: true,\n anchors: false,\n debug: true,\n statistics: false\n }\n },\n callback: 'arkitCallback0' // this.onInit as window callback\n };\n\n // Need these because WebXR Viewer...\n //if (window['setNativeTime']) {\n // console.log('window handler already defined for ', 'setNativeTime');\n //} else\n window['setNativeTime'] = function (data) {\n window.nativeTime = data.nativeTime;\n };\n [\n 'arkitStartRecording',\n 'arkitStopRecording',\n 'arkitDidMoveBackground',\n 'arkitWillEnterForeground',\n 'arkitInterrupted',\n 'arkitInterruptionEnded',\n 'arkitShowDebug',\n // elsewhere... 'arkitWindowResize',\n 'onError',\n 'arTrackingChanged',\n 'ios_did_receive_memory_warning',\n 'onComputerVisionData',\n // above... 'setNativeTime',\n 'userGrantedComputerVisionData',\n 'userGrantedWorldSensingData', // Needed for world sensing.\n ].forEach(function (eventName) {\n //if (window[eventName]) {\n // console.log('window handler already defined for ', eventName);\n //} else\n window[eventName] = function (data) {\n console.log(eventName + ':', data);\n };\n });\n\n // act like Chrome WebXR by forcibly showing AR button and making it work\n var vrmodeui = this.el.sceneEl.components['vr-mode-ui'];\n var newarbutton = vrmodeui.enterAREl.cloneNode(true);\n vrmodeui.enterAREl.parentNode.replaceChild(newarbutton, vrmodeui.enterAREl);\n vrmodeui.enterAREl = newarbutton;\n vrmodeui.enterAREl.classList.remove('a-hidden');\n var self = this;\n vrmodeui.enterAREl.onclick = function() {\n var scene = AFRAME.scenes[0];\n\n // Note we're in AR mode (the way WebXR handling does).\n scene.addState('ar-mode');\n\n // Kill the Cardboard display that gets in our way.\n scene.components['vr-mode-ui'].orientationModalEl.style='display:none!important';\n\n // Fake VR mode from enterVRSuccess.\n scene.addState('vr-mode');\n scene.emit('enter-vr', {target: scene});\n\n // Call initAR.\n window.webkit.messageHandlers.initAR.postMessage(data);\n \n // Kill broken wakelock!\n scene.wakelock.release();\n\n // Take over the scene camera, if so directed.\n // But wait a tick, because otherwise injected camera will not be present.\n if (self.data.takeOverCamera) {\n setTimeout(function () { self.takeOverCamera(scene.camera); });\n }\n\n let sz = new THREE.Vector2();\n let pixelRatio = scene.renderer.getPixelRatio();\n scene.renderer.getSize(sz);\n console.log(\"pixelRatio \", pixelRatio, \" size \", sz);\n\n // Ugly hack to get around WebXR Viewer resizing issue.\n scene.canvas.style.position = \"absolute !important\";\n scene.canvas.style.width = \"100% !important\";\n scene.canvas.style.height = \"100% !important\";\n\n // Force resize after we have access to data (?!)\n window.userGrantedWorldSensingData = function(data) {\n console.log('userGrantedWorldSensingData:', data);\n setTimeout(function () {\n self.forceResize(\n screen.width * window.devicePixelRatio,\n screen.height * window.devicePixelRatio);\n }, 100); // 1000 seems to be long enough initially\n };\n };\n },\n\n forceResize: function (sx, sy) {\n var sc = this.el.sceneEl, self = this;\n console.log('forceResize ', sx, sy,\n ' was ', \n sc.canvas.width, sc.canvas.height, \n screen.width, screen.height,\n window.devicePixelRatio, sc.renderer.getPixelRatio());\n sx = sx || this.forceResizeX; this.forceResizeX = sx;\n sy = sy || this.forceResizeY; this.forceResizeY = sy;\n sc.canvas.setAttribute('width', sx);\n sc.canvas.setAttribute('height', sy);\n sc.renderer.setPixelRatio(1);\n sc.camera.projectionMatrix.copy(self.projectionMatrix);\n sc.emit('rendererresize', null, false);\n },\n\n checkForARDisplay: function () {\n // Check if the low-level WebXR Viewer interfaces are there.\n if (!window.webkit || !window.webkit.messageHandlers) { return; }\n if (!window.webkit.messageHandlers.watchAR) { return; }\n\n // Mozilla WebXR Viewer detected.\n var self = this;\n self.arDisplay = true;\n\n\n // Compose data to use with watchAR.\n var data = {\n options: {\n location: true,\n camera: true,\n objects: true,\n light_intensity: true,\n worldSensing: this.data.worldSensing\n },\n callback: 'arkitCallback1' // this.onWatch as window callback\n };\n\n // Add resize handling.\n window['arkitWindowResize'] = function (data) {\n console.log('arkitWindowResize' + ':', data);\n\n // we're faking being in vr-mode anyway so resize will exit.\n //window.emit('resize', {target: window});\n\n // on iOS, AFRAME waits 100ms... \n setTimeout(function () {\n self.forceResize(\n data.width * window.devicePixelRatio,\n data.height * window.devicePixelRatio);\n }, 150); // 250 seems to be long enough\n };\n\n // Start watching AR.\n window.webkit.messageHandlers.watchAR.postMessage(data);\n },\n\n onInit: function (deviceId) {\n this.checkForARDisplay();\n },\n\n onWatch: function (data) {\n this.frameData = data;\n this.handleFrame(data);\n },\n\n handleFrame: function (data) {\n // Decompose to get camera pose.\n this.poseMatrix.fromArray(data.camera_transform);\n this.poseMatrix.decompose(this.posePosition, this.poseQuaternion, this.poseRotation); // poseRotation is really scale, we redo below\n this.poseEuler.setFromQuaternion(this.poseQuaternion);\n this.poseRotation.set(\n THREE.Math.RAD2DEG * this.poseEuler.x,\n THREE.Math.RAD2DEG * this.poseEuler.y,\n THREE.Math.RAD2DEG * this.poseEuler.z);\n\n this.projectionMatrix.fromArray(data.projection_camera);\n this.viewMatrix.fromArray(data.camera_view);\n\n // If we control a camera, and should apply user height, do it.\n if (this.arCamera && this.data.cameraUserHeight) {\n this.posePosition.y += this.arCamera.el.components.camera.data.userHeight;\n }\n\n // For A-Painter, detect bogus pose and fire poseFound / poseLost.\n var poseValid = this.posePosition.x || this.posePosition.y || this.posePosition.z || this.poseQuaternion.x || this.poseQuaternion.y || this.poseQuaternion.z;\n if (poseValid) {\n if (this.poseLost !== false) {\n this.poseLost = false;\n this.el.emit('poseFound');\n }\n } else {\n if (this.poseLost !== true) {\n this.poseLost = true;\n this.el.emit('poseLost', false);\n }\n }\n\n // Add planes handling, so we can do synchronous hit test.\n // From google-ar/WebARonARKit; also see webxr-polyfill/ARKitWrapper.js\n\n var i;\n var element;\n\n // WebXR Viewer returns geometry.vertices as an array of {x: number, y: number, y: number}\n // https://github.com/mozilla-mobile/webxr-ios/blob/c77b12c235e3960e2cd51538e086a38c83d8ec7c/XRViewer/ARKController/ARKController.m#L845\n // We transform this to a flatten array of number, like WebARonARCore.\n\n if(data.newObjects && data.newObjects.length){\n for (i = 0; i < data.newObjects.length; i++) {\n element = data.newObjects[i];\n if(element.plane_center){\n this.planes_.set(element.uuid, {\n id: element.uuid,\n center: element.plane_center,\n extent: [element.plane_extent.x, element.plane_extent.z],\n modelMatrix: element.transform,\n alignment: element.plane_alignment,\n vertices: convertVertices(element.geometry.vertices)\n });\n }else{\n var anchorData = {\n id: element.uuid,\n modelMatrix: element.transform\n };\n if (element.type === 'image') {\n anchorData.name = element.uuid;\n }\n this.anchors_.set(element.uuid, anchorData);\n }\n }\n }\n\n if(data.removedObjects && data.removedObjects.length){\n for (i = 0; i < data.removedObjects.length; i++) {\n element = data.removedObjects[i];\n if(this.planes_.get(element)){\n this.planes_.delete(element);\n }else{\n this.anchors_.delete(element);\n }\n }\n }\n\n if(data.objects && data.objects.length){\n for (i = 0; i < data.objects.length; i++) {\n element = data.objects[i];\n if(element.plane_center){\n var plane = this.planes_.get(element.uuid);\n if(!plane){\n this.planes_.set(element.uuid, {\n id: element.uuid,\n center: element.plane_center,\n extent: [element.plane_extent.x, element.plane_extent.z],\n modelMatrix: element.transform,\n alignment: element.plane_alignment,\n vertices: convertVertices(element.geometry.vertices)\n });\n } else {\n plane.center = element.plane_center;\n plane.extent = [element.plane_extent.x, element.plane_extent.z];\n plane.modelMatrix = element.transform;\n plane.alignment = element.plane_alignment;\n plane.vertices = convertVertices(element.geometry.vertices);\n }\n }else{\n var anchor = this.anchors_.get(element.uuid);\n if(!anchor){\n this.anchors_.set(element.uuid, {\n id: element.uuid,\n modelMatrix: element.transform\n });\n }else{\n anchor.modelMatrix = element.transform;\n }\n }\n }\n }\n },\n\n getPosition: function () {\n if (!this.arDisplay) { return null; }\n return this.posePosition;\n },\n\n getOrientation: function () {\n if (!this.arDisplay) { return null; }\n return this.poseQuaternion;\n },\n\n getRotation: function () {\n if (!this.arDisplay) { return null; }\n return this.poseRotation;\n },\n\n getProjectionMatrix: function () {\n if (!this.arDisplay) { return null; }\n return this.projectionMatrix;\n },\n\n // Link to new ARKit image marker and anchor support.\n\n addImage: function (name, url, physicalWidth) {\n if (!this.arDisplay) { return null; }\n/*\nNSDictionary *imageAnchorInfoDictionary = [message body];\nNSString *createDetectionImageCallback = [[message body] objectForKey:WEB_AR_CALLBACK_OPTION];\n// callback\n\nCGFloat physicalWidth = [referenceImageDictionary[@\"physicalWidth\"] doubleValue];\nNSString* b64String = referenceImageDictionary[@\"buffer\"];\nsize_t width = (size_t) [referenceImageDictionary[@\"imageWidth\"] intValue];\nsize_t height = (size_t) [referenceImageDictionary[@\"imageHeight\"] intValue];\n...\nresult.name = referenceImageDictionary[@\"uid\"];\n*/\n // NOTE: looks like WebXR Viewer won't load from URL,\n // so we need to convert from img element\n var aCanvas = document.createElement('canvas');\n var aContext = aCanvas.getContext('2d');\n var aImg; // Don't use element; chance of changed width/height.\n if (!aImg) {\n aImg = document.createElement('img');\n aImg.crossOrigin = 'anonymous';\n aImg.src = url;\n document.body.appendChild(aImg);\n }\n\n // The image needs to be loaded...\n if (!aImg.complete || !aImg.naturalHeight) {\n console.log('!!! addImage: !aImg.complete || !aImg.naturalHeight, aborting');\n return;\n } \n \n // The image needs to be have nonzero size...\n if (!aImg.width || !aImg.height) {\n console.log('!!! addImage: !aImg.width || !aImg.height, aborting');\n return;\n } \n\n aCanvas.width = aImg.width;\n aCanvas.height = aImg.height;\n aContext.drawImage(aImg, 0, 0);\n var aImageData = aContext.getImageData(0, 0, aImg.width, aImg.height);\n var b64ImageData = encode(aImageData.data);\n if (!b64ImageData) {\n console.log('!!! addImage: !b64ImageData, aborting');\n return;\n }\n\n // NOTE: also, WebXR Viewer doesn't pass back which image/name,\n // so we need a per-image/name callback\n window.callbackForCreateImageAnchorCounter = (window.callbackForCreateImageAnchorCounter || 0) + 1;\n var callbackName = 'callbackForCreateImageAnchor_' + window.callbackForCreateImageAnchorCounter;\n var imageName = name;\n //console.log('creating ', callbackName, ' for ', imageName);\n window[callbackName] = function (data) {\n //console.log(callbackName);\n //console.log(data);\n //var name = callbackName.substring(29);\n if (data.created !== undefined) {\n if (!data.created) {\n // we failed to create the image, for whatever reason.\n console.log('addImage: !created; ', data.error);\n delete window[callbackName];\n } else {\n //console.log('addImage: created, activating ', imageName);\n window.webkit.messageHandlers.activateDetectionImage.postMessage({\n callback: callbackName,\n uid: imageName\n });\n }\n } else\n if (data.activated !== undefined) {\n if (!data.activated) {\n // we failed to activate the image, for whatever reason.\n console.log('addImage: !activated; ', data.error);\n } else {\n //console.log('addImage: activated ', imageName);\n }\n delete window[callbackName];\n }\n };\n\n window.webkit.messageHandlers.createImageAnchor.postMessage({\n callback: callbackName,\n uid: name,\n buffer: b64ImageData,\n imageWidth: aImg.width,\n imageHeight: aImg.height,\n physicalWidth: physicalWidth // in meters\n });\n },\n\n removeImage: function (name) {\n if (!this.arDisplay) { return null; }\n/*\nNSDictionary *imageAnchorInfoDictionary = [message body];\nNSString *imageName = imageAnchorInfoDictionary[WEB_AR_DETECTION_IMAGE_NAME_OPTION];\n// detectionImageName\nNSString *deactivateDetectionImageCallback = [[message body] objectForKey:WEB_AR_CALLBACK_OPTION];\n// callback\n*/\n window.callbackForRemoveImageAnchorCounter = (window.callbackForRemoveImageAnchorCounter || 0) + 1;\n var callbackName = 'callbackForRemoveImageAnchor_' + window.callbackForRemoveImageAnchorCounter;\n var imageName = name;\n //console.log('creating ', callbackName, ' for ', imageName);\n window[callbackName] = function (data) {\n //console.log(callbackName);\n //console.log(data);\n\n if (data.deactivated !== undefined) {\n if (!data.deactivated) {\n console.log('!!! ' + callbackName + ': !deactivated', data.error);\n delete window[callbackName];\n } else {\n //console.log(callbackName + ': deactivated, destroying', imageName);\n }\n window.webkit.messageHandlers.destroyDetectionImage.postMessage({\n callback: callbackName,\n uid: imageName\n });\n }\n if (data.destroyed !== undefined) {\n if (!data.destroyed) {\n console.log('!!! ' + callbackName + ': !destroyed, ', data.error);\n } else {\n //console.log(callbackName + ': destroyed', imageName);\n }\n delete window[callbackName];\n }\n };\n\n window.webkit.messageHandlers.deactivateDetectionImage.postMessage({\n callback: callbackName,\n uid: imageName\n });\n },\n\n getAnchors: function () {\n return Array.from(this.anchors_.values());\n },\n\n // Use planes to do synchronous hit test.\n // From google-ar/WebARonARKit; also see webxr-polyfill/ARKitWrapper.js\n\n getPlanes: function () {\n return Array.from(this.planes_.values());\n },\n\n hitTestNoAnchor: (function () {\n // Temporary variables, only within closure scope.\n\n /**\n * The result of a raycast into the AR world encoded as a transform matrix.\n * This structure has a single property - modelMatrix - which encodes the\n * translation of the intersection of the hit in the form of a 4x4 matrix.\n * @constructor\n */\n function VRHit() {\n this.modelMatrix = new Float32Array(16);\n return this;\n };\n\n /**\n * Cached vec3, mat4, and quat structures needed for the hit testing to\n * avoid generating garbage.\n * @type {Object}\n */\n var hitVars = {\n rayStart: new THREE.Vector3(), //vec3.create(),\n rayEnd: new THREE.Vector3(), //vec3.create(),\n cameraPosition: new THREE.Vector3(), //vec3.create(),\n cameraQuaternion: new THREE.Quaternion(), //quat.create(),\t\n //modelViewMatrix: new THREE.Matrix4(), //mat4.create(),\n //projectionMatrix: new THREE.Matrix4(), //mat4.create(),\n projViewMatrix: new THREE.Matrix4(), //mat4.create(),\n worldRayStart: new THREE.Vector3(), //vec3.create(),\n worldRayEnd: new THREE.Vector3(), //vec3.create(),\n worldRayDir: new THREE.Vector3(), //vec3.create(),\n planeMatrix: new THREE.Matrix4(), //mat4.create(),\n planeMatrixInverse: new THREE.Matrix4(), //mat4.create(),\n planeExtent: new THREE.Vector3(), //vec3.create(),\n planePosition: new THREE.Vector3(), //vec3.create(),\n planeCenter: new THREE.Vector3(), //vec3.create(),\n planeNormal: new THREE.Vector3(), //vec3.create(),\n planeIntersection: new THREE.Vector3(), //vec3.create(),\n planeIntersectionLocal: new THREE.Vector3(), //vec3.create(),\n planeHit: new THREE.Matrix4(), //mat4.create()\n planeQuaternion: new THREE.Quaternion() // quat.create()\n };\n \n /**\n * Tests whether the given ray intersects the given plane.\n *\n * @param {!vec3} planeNormal The normal of the plane.\n * @param {!vec3} planePosition Any point on the plane.\n * @param {!vec3} rayOrigin The origin of the ray.\n * @param {!vec3} rayDirection The direction of the ray (normalized).\n * @return {number} The t-value of the intersection (-1 for none).\n */\n var rayIntersectsPlane = (function() {\n var rayToPlane = new THREE.Vector3();\n return function(planeNormal, planePosition, rayOrigin, rayDirection) {\n // assuming vectors are all normalized\n var denom = planeNormal.dot(rayDirection);\n rayToPlane.subVectors(planePosition, rayOrigin);\n return rayToPlane.dot(planeNormal) / denom;\n };\n })();\n \n /**\n * Sorts based on the distance from the VRHits to the camera.\n *\n * @param {!VRHit} a The first hit to compare.\n * @param {!VRHit} b The second hit item to compare.\n * @returns {number} -1 if a is closer than b, otherwise 1.\n */\n var sortFunction = function(a, b) {\n // Get the matrix of hit a.\n hitVars.planeMatrix.fromArray(a.modelMatrix);\n // Get the translation component of a's matrix.\n hitVars.planeIntersection.setFromMatrixPosition(hitVars.planeMatrix);\n // Get the distance from the intersection point to the camera.\n var distA = hitVars.planeIntersection.distanceTo(hitVars.cameraPosition);\n \n // Get the matrix of hit b.\n hitVars.planeMatrix.fromArray(b.modelMatrix);\n // Get the translation component of b's matrix.\n hitVars.planeIntersection.setFromMatrixPosition(hitVars.planeMatrix);\n // Get the distance from the intersection point to the camera.\n var distB = hitVars.planeIntersection.distanceTo(hitVars.cameraPosition);\n \n // Return comparison of distance from camera to a and b.\n return distA < distB ? -1 : 1;\n };\n \n return function(x, y) {\n // Coordinates must be in normalized screen space.\n if (x < 0 || x > 1 || y < 0 || y > 1) {\n throw new Error(\n \"hitTest - x and y values must be normalized [0,1]!\")\n ;\n }\n \n var hits = [];\n // If there are no anchors detected, there will be no hits.\n var planes = this.getPlanes();\n if (!planes || planes.length === 0) {\n return hits;\n }\n\n // Create a ray in screen space for the hit test ([-1, 1] with y flip).\n hitVars.rayStart.set(2 * x - 1, 2 * (1 - y) - 1, 0);\n hitVars.rayEnd.set(2 * x - 1, 2 * (1 - y) - 1, 1);\n\n // Set the projection matrix.\n //hitVars.projectionMatrix.fromArray(this.projectionMatrix);\n \n // Set the model view matrix.\n //hitVars.modelViewMatrix.fromArray(this.viewMatrix);\n \n // Combine the projection and model view matrices.\n hitVars.planeMatrix.multiplyMatrices(\n this.projectionMatrix, //hitVars.projectionMatrix,\n this.viewMatrix //hitVars.modelViewMatrix\n );\n // Invert the combined matrix because we need to go from screen -> world.\n hitVars.projViewMatrix.getInverse(hitVars.planeMatrix);\n \n // Transform the screen-space ray start and end to world-space.\n hitVars.worldRayStart.copy(hitVars.rayStart)\n .applyMatrix4(hitVars.projViewMatrix);\n hitVars.worldRayEnd.copy(hitVars.rayEnd)\n .applyMatrix4(hitVars.projViewMatrix);\n \n // Subtract start from end to get the ray direction and then normalize.\n hitVars.worldRayDir.subVectors(\n hitVars.worldRayEnd,\n hitVars.worldRayStart\n ).normalize();\n\n // Go through all the anchors and test for intersections with the ray.\n for (var i = 0; i < planes.length; i++) {\n var plane = planes[i];\n // Get the anchor transform.\n hitVars.planeMatrix.fromArray(plane.modelMatrix);\n \n // Get the position of the anchor in world-space.\n hitVars.planeCenter.set(plane.center.x, plane.center.y, plane.center.z);\n hitVars.planePosition.copy(hitVars.planeCenter)\n .applyMatrix4(hitVars.planeMatrix)\n\n hitVars.planeAlignment = plane.alignment\n \n // Get the plane normal.\n if (hitVars.planeAlignment === 0) {\n hitVars.planeNormal.set(0, 1, 0);\n } else {\n hitVars.planeNormal.set(hitVars.planeMatrix[4], hitVars.planeMatrix[5], hitVars.planeMatrix[6]);\n }\n \n // Check if the ray intersects the plane.\n var t = rayIntersectsPlane(\n hitVars.planeNormal,\n hitVars.planePosition,\n hitVars.worldRayStart,\n hitVars.worldRayDir\n );\n\n // if t < 0, there is no intersection.\n if (t < 0) {\n continue;\n }\n \n // Calculate the actual intersection point.\n hitVars.planeIntersectionLocal.copy(hitVars.worldRayDir).multiplyScalar(t);\n hitVars.planeIntersection.addVectors(\n hitVars.worldRayStart,\n hitVars.planeIntersectionLocal\n );\n // Get the plane extents (extents are in plane local space).\n hitVars.planeExtent.set(plane.extent[0], 0, plane.extent[1]);\n /*\n ///////////////////////////////////////////////\n // Test by converting extents to world-space.\n // TODO: get this working to avoid matrix inversion in method below.\n \n // Get the rotation component of the anchor transform.\n mat4.getRotation(hitVars.planeQuaternion, hitVars.planeMatrix);\n \n // Convert the extent into world space.\n vec3.transformQuat(\n hitVars.planeExtent, hitVars.planeExtent, hitVars.planeQuaternion);\n \n // Check if intersection is outside of the extent of the anchor.\n if (Math.abs(hitVars.planeIntersection[0] - hitVars.planePosition[0]) > hitVars.planeExtent[0] / 2) {\n continue;\n }\n if (Math.abs(hitVars.planeIntersection[2] - hitVars.planePosition[2]) > hitVars.planeExtent[2] / 2) {\n continue;\n }\n ////////////////////////////////////////////////\n */\n \n ////////////////////////////////////////////////\n // Test by converting intersection into plane-space.\n hitVars.planeMatrixInverse.getInverse(hitVars.planeMatrix);\n hitVars.planeIntersectionLocal.copy(hitVars.planeIntersection)\n .applyMatrix4(hitVars.planeMatrixInverse);\n \n // Check if intersection is outside of the extent of the anchor.\n // Tolerance is added to match the behavior of the native hitTest call.\n var tolerance = 0.0075;\n if (\n Math.abs(hitVars.planeIntersectionLocal.x) >\n hitVars.planeExtent.x / 2 + tolerance\n ) {\n continue;\n }\n if (\n Math.abs(hitVars.planeIntersectionLocal.z) >\n hitVars.planeExtent.z / 2 + tolerance\n ) {\n continue;\n }\n \n ////////////////////////////////////////////////\n \n // The intersection is valid - create a matrix from hit position.\n hitVars.planeQuaternion.setFromRotationMatrix(hitVars.planeMatrix);\n hitVars.planeHit.makeRotationFromQuaternion(hitVars.planeQuaternion).setPosition(hitVars.planeIntersection);\n var hit = new VRHit();\n for (var j = 0; j < 16; j++) {\n hit.modelMatrix[j] = hitVars.planeHit.elements[j];\n }\n hit.i = i;\n hits.push(hit);\n }\n \n\n // Sort the hits by distance.\n hits.sort(sortFunction);\n return hits;\n };\n })(),\n\n hitAR: (function () {\n // Temporary variables, only within closure scope.\n var transform = new THREE.Matrix4();\n var hitpoint = new THREE.Vector3();\n var hitquat = new THREE.Quaternion();\n var hitscale = new THREE.Vector3();\n var worldpos = new THREE.Vector3();\n\n // The desired function, which this returns.\n return function (x, y, el, raycasterEl) {\n if (!this.arDisplay) { return []; }\n\n var hit = this.hitTestNoAnchor(x, y);\n\n // Process AR hits.\n var hitsToReturn = [];\n for (var i = 0; hit && i < hit.length; i++) {\n transform.fromArray(hit[i].modelMatrix);\n transform.decompose(hitpoint, hitquat, hitscale);\n raycasterEl.object3D.getWorldPosition(worldpos);\n\n hitsToReturn.push({\n distance: hitpoint.distanceTo(worldpos),\n point: hitpoint.clone(), // Vector3\n object: (el && el.object3D) || this.el.sceneEl.object3D\n/*\n // We don't have any of these properties...\n face: undefined, // Face3\n faceIndex: undefined,\n index: undefined,\n uv: undefined // Vector2\n*/\n });\n }\n return hitsToReturn;\n } \n })()\n});\n","/* global AFRAME, THREE */\n\nAFRAME.registerComponent('ar-planes', {\n\n getPlaneSource: function () {\n var whichar;\n if (!this.planeSource) {\n whichar = this.el.sceneEl.components['ar'];\n if (whichar) {\n this.planeSource = whichar.getSource();\n }\n }\n return this.planeSource;\n },\n\n getPlanes: function () {\n var planeSource = this.getPlaneSource();\n if (!planeSource || !planeSource.getPlanes) return undefined;\n return planeSource.getPlanes();\n },\n\n init: function () {\n // Remember planes when we see them.\n this.planes = {};\n this.anchorsAdded = [];\n this.anchorsAddedDetail = {type:'added', anchors: this.anchorsAdded};\n this.anchorsUpdated = [];\n this.anchorsUpdatedDetail = {type:'updated', anchors: this.anchorsUpdated};\n this.anchorsRemoved = [];\n this.anchorsRemovedDetail = {type:'removed', anchors: this.anchorsRemoved};\n },\n\n tick: (function (t, dt) {\n // Create the temporary variables we will reuse, if needed.\n var tempScale = new THREE.Vector3(1, 1, 1);\n var tempMat4 = new THREE.Matrix4();\n var tempPosition = new THREE.Vector3();\n var tempQuaternion = new THREE.Quaternion();\n\n // The actual function, which we return.\n return function (t, dt) {\n // Get the list of planes.\n var planes = this.getPlanes();\n if (!planes) { return; }\n\n // Ideally we would have either events, or separate lists for added / updated / removed.\n var addedThese = [];\n var updatedThese = [];\n var removedThese = [];\n\n // Because we don't have an indication of added / updated / removed,\n // try to keep track ourselves.\n var seenThese = {};\n var i;\n\n // Iterate over the available planes.\n for (i=0; planes && i 0) {\n // Reuse the same event detail to avoid making garbage.\n // TODO: Reuse same CustomEvent?\n this.anchorsAddedDetail.anchors = addedThese;\n this.el.emit('anchorsadded', this.anchorsAddedDetail);\n }\n\n // Replace the old list.\n this.anchorsUpdated = updatedThese;\n // Emit event if list isn't empty.\n if (updatedThese.length > 0) {\n // Reuse the same event detail to avoid making garbage.\n // TODO: Reuse same CustomEvent?\n this.anchorsUpdatedDetail.anchors = updatedThese;\n this.el.emit('anchorsupdated', this.anchorsUpdatedDetail);\n }\n\n // Replace the old list.\n this.anchorsRemoved = removedThese;\n // Emit event if list isn't empty.\n if (removedThese.length > 0) {\n // Reuse the same event detail to avoid making garbage.\n // TODO: Reuse same CustomEvent?\n this.anchorsRemovedDetail.anchors = removedThese;\n this.el.emit('anchorsremoved', this.anchorsRemovedDetail);\n }\n }; \n })()\n});\n","/* global AFRAME, THREE */\n\nAFRAME.registerComponent('ar-anchors', {\n\n getSource: function () {\n var whichar;\n if (!this.source) {\n whichar = this.el.sceneEl.components['ar'];\n if (whichar) {\n this.source = whichar.getSource();\n }\n }\n return this.source;\n },\n\n getAnchors: function () {\n var source = this.getSource();\n if (!source || !source.getAnchors) return undefined;\n return source.getAnchors();\n }\n});\n","/* global AFRAME, THREE */\n\nAFRAME.registerComponent('ar-images', {\n\n getSource: function () {\n var whichar;\n if (!this.source) {\n whichar = this.el.sceneEl.components['ar'];\n if (whichar) {\n this.source = whichar.getSource();\n }\n }\n return this.source;\n },\n\n addImage: function (name, url, physicalWidth) {\n var source = this.getSource();\n if (!source || !source.addImage) return undefined;\n return source.addImage(name, url, physicalWidth);\n },\n\n removeImage: function (name) {\n var source = this.getSource();\n if (!source || !source.removeImage) return undefined;\n return source.removeImage(name);\n },\n\n});\n","/* global AFRAME */\n\nAFRAME.registerComponent('ar', {\n schema: {\n takeOverCamera: {default: true},\n cameraUserHeight: {default: false},\n worldSensing: {default: true},\n hideUI: {default: false}\n },\n dependencies: ['webxr-ar', 'mozilla-xr-ar', 'ar-planes', 'ar-anchors'],\n getSource: function () {\n var whichar;\n if (!this.source) {\n var self = this;\n self.dependencies.forEach(function(sys) {\n whichar = self.el.sceneEl.components[sys];\n if (whichar && whichar.arDisplay) {\n self.source = whichar;\n }\n });\t\n }\n return this.source;\n },\n getPlanes: function () {\n return this.source ? this.source.getPlanes() : undefined;\n },\n getAnchors: function () {\n return this.source ? this.source.getAnchors() : undefined;\n },\n addImage: function (name, url, physicalWidth) {\n return this.source.addImage(name, url, physicalWidth);\n },\n removeImage: function (name) {\n return this.source.removeImage(name);\n },\n init: function () {\n var options = {\n takeOverCamera: this.data.takeOverCamera,\n cameraUserHeight: this.data.cameraUserHeight,\n worldSensing: this.data.worldSensing\n };\n\n var self = this;\n this.dependencies.forEach(function(sys) {\n self.el.setAttribute(sys, options);\n });\n\n if (this.data.hideUI) {\n this.el.sceneEl.setAttribute('vr-mode-ui', {enabled: false});\n }\n\n // Ensure passthrough is visible, make sure A-Frame styles don't interfere.\n document.head.insertAdjacentHTML('beforeend', \n '');\n }\n});\n","/* global AFRAME */\n\nAFRAME.registerComponent('ar-camera', {\n schema: {\n enabled: {default:true}\n },\n\n init: function () {\n var lookControls = this.el.getAttribute('look-controls');\n this.wasLookControlsEnabled = lookControls ? lookControls.enabled : false;\n },\n\n update: function (oldData) {\n if (!oldData || oldData.enabled !== this.data.enabled) {\n // Value changed, so react accordingly.\n if (this.data.enabled) {\n // Save camera look-controls enabled, and turn off for AR.\n var lookControls = this.el.getAttribute('look-controls');\n this.wasLookControlsEnabled = lookControls ? lookControls.enabled : false;\n if (this.wasLookControlsEnabled) {\n this.el.setAttribute('look-controls', 'enabled', false);\n }\n } else {\n // Restore camera look-controls enabled.\n if (this.wasLookControlsEnabled) {\n this.el.setAttribute('look-controls', 'enabled', true);\n }\n }\n }\n },\n \n tick: function (t, dt) {\n if (!this.data.enabled) { return; }\n \n var whichar = this.checkWhichAR();\n if (!whichar) { return; }\n \n // Apply the pose position via setAttribute,\n // so that other A-Frame components can see the values.\n var pos = whichar.getPosition();\n if (pos) { this.el.setAttribute('position', pos); }\n\n // Apply the pose rotation via setAttribute,\n // so that other A-Frame components can see the values.\n var rot = whichar.getRotation();\n if (rot) { this.el.setAttribute('rotation', rot); }\n\n // Apply the projection matrix, if we're not in VR.\n if (!this.el.sceneEl.is('vr-mode')) {\n var matrix = whichar.getProjectionMatrix();\n if (matrix) { this.el.components.camera.camera.projectionMatrix = matrix; }\n } \n },\n \n checkWhichAR: function () {\n if (!this.whichar) {\n var whichar = this.el.sceneEl.components['ar'].getSource();\n if (!whichar || !whichar.arDisplay) { return; }\n this.whichar = whichar;\n }\n return this.whichar;\n } \n});\n","/* global AFRAME */\n\n// ar-raycaster modifies raycaster to append AR hit, if any.\n// But note that current AR hit API does not support orientation as input.\nAFRAME.registerComponent('ar-raycaster', { \n dependencies: ['raycaster'],\n \n schema: {\n x: {default: 0.5},\n y: {default: 0.5},\n el: {type: 'selector'}\n },\n \n init: function () {\n // HACK: monkey-patch raycaster to append AR hit result\n this.raycaster = this.el.components['raycaster'].raycaster;\n this.raycasterIntersectObjects = this.raycaster.intersectObjects.bind(this.raycaster);\n this.raycaster.intersectObjects = this.intersectObjects.bind(this);\n },\n \n update: function (oldData) {\n if (!this.data.el) {\n // If not given some other element, return hit against the scene.\n // HACK: But that means we need its object3D to have an el.\n if (!this.el.sceneEl.object3D.el) {\n this.el.sceneEl.object3D.el = this.el.sceneEl;\n }\n }\n },\n \n intersectObjects: function (objects, recursive, rawIntersections) {\n // it appears that intersectObjects is now returning in rawIntersections\n var results = this.raycasterIntersectObjects(objects, recursive, rawIntersections);\n // Tack on AR hit result, if any.\n var hitARResults = this.hitAR();\n if (hitARResults && hitARResults.length) {\n if (rawIntersections) {\n hitARResults.forEach((hit) => rawIntersections.push(hit));\n results = rawIntersections;\n } else {\n hitARResults.forEach((hit) => results.push(hit));\n }\n }\n return results;\n }, \n \n hitAR: function () {\n var whichar = this.checkWhichAR();\n if (!whichar || !whichar.arDisplay) { return []; }\n var x = this.data.x;\n var y = this.data.y;\n if (arguments.length >= 2) {\n x = arguments[0];\n y = arguments[1];\n }\n return whichar.hitAR(x, y, this.data.el, this.el);\n },\n\n checkWhichAR: function () {\n if (!this.whichar) {\n var whichar = this.el.sceneEl.components['ar'];\n if (whichar) { whichar = whichar.getSource ? whichar.getSource() : undefined; }\n if (!whichar || !whichar.arDisplay) { return; }\n this.whichar = whichar;\n }\n return this.whichar;\n } \n});\n\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/index.js","webpack:///./src/webxr-ar.js","webpack:///./src/mozilla-xr-ar.js","webpack:///./src/ar-planes.js","webpack:///./src/ar-anchors.js","webpack:///./src/ar-images.js","webpack:///./src/ar.js","webpack:///./src/ar-camera.js","webpack:///./src/ar-raycaster.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","transform","hitpoint","worldpos","AFRAME","registerComponent","schema","takeOverCamera","default","cameraUserHeight","worldSensing","init","this","posePosition","THREE","Vector3","poseQuaternion","Quaternion","poseEuler","Euler","poseRotation","projectionMatrix","Matrix4","onceSceneLoaded","el","sceneEl","hasLoaded","setTimeout","addEventListener","rawPlanes_","planes_","Map","anchors_","convertPolygonToVertices","polygon","newVertices","convertedPlane","rawPlane","pose","vertex","mins","maxs","verticesLength","length","Float32Array","j","x","y","z","position","set","id","center","extent","modelMatrix","matrix","alignment","orientation","vertices","rawPlaneRemoved","delete","rawPlaneUpdated","rawPlaneNotUpdated","rawPlaneCreated","Math","random","toString","substring","tick","dt","frame","arDisplay","worldInformation","world","forEach","plane","detectedPlanes","has","timestamp","time","planePose","getPose","planeSpace","refSpace","lastChangedTime","camera","arCamera","isARPerspectiveCamera","vrDisplay","setAttribute","self","window","checkForARDisplay","navigator","xr","isSessionSupported","type","then","supported","ourRequiredFeatures","ourOptionalFeatures","data","push","existingFeatures","getAttribute","optionalFeatures","feature","filter","index","arr","requiredFeatures","concat","join","xrHitTestSource","viewerSpace","renderer","ev","session","getSession","canvas","e","pageX","inputSource","gamepad","axes","pageY","event","TouchEvent","view","bubbles","cancelable","targetTouches","dispatchEvent","MouseEvent","clientX","clientY","requestReferenceSpace","space","requestHitTestSource","hitTestSource","updateWorldTrackingState","planeDetectionState","enabled","getPosition","getFrameData","getOrientation","getRotation","getProjectionMatrix","hitAR","raycasterEl","hitsToReturn","is","xrViewerPose","getViewerPose","hitTestResults","getHitTestResults","fromArray","setFromMatrixPosition","object3D","getWorldPosition","distance","distanceTo","point","clone","addImage","url","physicalWidth","removeImage","getAnchors","Array","from","values","getPlanes","convertVertices","hitquat","hitscale","onInit","onWatch","forceResize","poseMatrix","viewMatrix","webkit","messageHandlers","initAR","options","ui","browser","points","focus","rec","rec_time","mic","build","warnings","anchors","debug","statistics","callback","nativeTime","eventName","console","log","vrmodeui","components","newarbutton","enterAREl","cloneNode","parentNode","replaceChild","classList","remove","onclick","scene","scenes","addState","orientationModalEl","style","emit","target","postMessage","wakelock","release","sz","Vector2","pixelRatio","getPixelRatio","getSize","width","height","userGrantedWorldSensingData","screen","devicePixelRatio","sx","sy","sc","forceResizeX","forceResizeY","aspect","copy","setPixelRatio","setSize","watchAR","location","objects","light_intensity","deviceId","frameData","handleFrame","element","camera_transform","decompose","setFromQuaternion","RAD2DEG","projection_camera","camera_view","userHeight","poseLost","newObjects","plane_center","uuid","plane_extent","plane_alignment","geometry","anchorData","removedObjects","anchor","aImg","aCanvas","document","createElement","aContext","getContext","crossOrigin","src","body","appendChild","complete","naturalHeight","drawImage","b64ImageData","buffer","base64","encodings","bytes","ArrayBuffer","Uint8Array","arrayBuffer","ImageData","chunk","byteLength","byteRemainder","mainLength","encode","getImageData","callbackForCreateImageAnchorCounter","callbackName","imageName","undefined","created","activateDetectionImage","uid","error","activated","createImageAnchor","imageWidth","imageHeight","callbackForRemoveImageAnchorCounter","deactivated","destroyDetectionImage","destroyed","deactivateDetectionImage","hitTestNoAnchor","VRHit","rayToPlane","hitVars","rayStart","rayEnd","cameraPosition","cameraQuaternion","projViewMatrix","worldRayStart","worldRayEnd","worldRayDir","planeMatrix","planeMatrixInverse","planeExtent","planePosition","planeCenter","planeNormal","planeIntersection","planeIntersectionLocal","planeHit","planeQuaternion","rayIntersectsPlane","rayOrigin","rayDirection","denom","dot","subVectors","sortFunction","a","b","distA","Error","hits","planes","multiplyMatrices","getInverse","applyMatrix4","normalize","planeAlignment","multiplyScalar","addVectors","abs","setFromRotationMatrix","makeRotationFromQuaternion","setPosition","hit","elements","sort","tempScale","tempMat4","tempPosition","tempQuaternion","getPlaneSource","whichar","planeSource","getSource","anchorsAdded","anchorsAddedDetail","anchorsUpdated","anchorsUpdatedDetail","anchorsRemoved","anchorsRemovedDetail","addedThese","updatedThese","removedThese","seenThese","planespec","identifier","adding","hasTimestamp","compose","slice","utils","deepEqual","keys","source","hideUI","dependencies","sys","head","insertAdjacentHTML","lookControls","wasLookControlsEnabled","update","oldData","checkWhichAR","pos","rot","raycaster","raycasterIntersectObjects","intersectObjects","recursive","rawIntersections","results","hitARResults","arguments"],"mappings":"aACE,IAAIA,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUC,QAGnC,IAAIC,EAASJ,EAAiBE,GAAY,CACzCG,EAAGH,EACHI,GAAG,EACHH,QAAS,IAUV,OANAI,EAAQL,GAAUM,KAAKJ,EAAOD,QAASC,EAAQA,EAAOD,QAASF,GAG/DG,EAAOE,GAAI,EAGJF,EAAOD,QAKfF,EAAoBQ,EAAIF,EAGxBN,EAAoBS,EAAIV,EAGxBC,EAAoBU,EAAI,SAASR,EAASS,EAAMC,GAC3CZ,EAAoBa,EAAEX,EAASS,IAClCG,OAAOC,eAAeb,EAASS,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEZ,EAAoBkB,EAAI,SAAShB,GACX,oBAAXiB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAeb,EAASiB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAeb,EAAS,aAAc,CAAEmB,OAAO,KAQvDrB,EAAoBsB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQrB,EAAoBqB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFA1B,EAAoBkB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOrB,EAAoBU,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRzB,EAAoB6B,EAAI,SAAS1B,GAChC,IAAIS,EAAST,GAAUA,EAAOqB,WAC7B,WAAwB,OAAOrB,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAH,EAAoBU,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRZ,EAAoBa,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG/B,EAAoBkC,EAAI,GAIjBlC,EAAoBA,EAAoBmC,EAAI,G,kBClFrD,EAAQ,GAER,EAAQ,GACR,EAAQ,GACR,EAAQ,GACR,EAAQ,GACR,EAAQ,GACR,EAAQ,GACR,EAAQ,I,cC+RG,IAECC,EACAC,EAGAC,EA3SZC,OAAOC,kBAAkB,WAAY,CACjCC,OAAQ,CACJC,eAAgB,CAACC,SAAS,GAC1BC,iBAAkB,CAACD,SAAS,GAC5BE,aAAc,CAACF,SAAS,IAG5BG,KAAM,WACFC,KAAKC,aAAe,IAAIC,MAAMC,QAC9BH,KAAKI,eAAiB,IAAIF,MAAMG,WAChCL,KAAKM,UAAY,IAAIJ,MAAMK,MAAM,EAAG,EAAG,EAAG,OAC1CP,KAAKQ,aAAe,IAAIN,MAAMC,QAC9BH,KAAKS,iBAAmB,IAAIP,MAAMQ,QAElCV,KAAKW,gBAAkBX,KAAKW,gBAAgB9B,KAAKmB,MAC7CA,KAAKY,GAAGC,QAAQC,UAChBC,WAAWf,KAAKW,iBAEhBX,KAAKY,GAAGC,QAAQG,iBAAiB,SAAUhB,KAAKW,iBAKpDX,KAAKiB,WAAa,KAClBjB,KAAKkB,QAAU,IAAIC,IACnBnB,KAAKoB,SAAW,IAAID,KAGxBE,yBAA0B,SAASC,GAC/B,OAAOC,aAGXC,eAAgB,SAASC,EAAUC,GAC/B,IAMIC,EANAC,EAAO,CAAC,EAAG,GACXC,EAAO,CAAC,EAAG,GACXC,EAAiBL,EAASH,QAAQS,OAClCR,EAAc,IAAIS,aAA8B,EAAjBF,GAC/BzE,EAAI,EACJ4E,EAAI,EAER,IAAK5E,EAAI,EAAGA,EAAIyE,EAAgBzE,IAC5BsE,EAASF,EAASH,QAAQjE,GAC1BkE,EAAYU,GAAKN,EAAOO,EACxBX,EAAYU,EAAI,GAAKN,EAAOQ,EAC5BZ,EAAYU,EAAI,GAAKN,EAAOS,EAC5BH,GAAK,EACI,GAAL5E,GACAuE,EAAK,GAAKC,EAAK,GAAKF,EAAOO,EAC3BN,EAAK,GAAKC,EAAK,GAAKF,EAAOS,IAEvBR,EAAK,GAAKD,EAAOO,IAAKN,EAAK,GAAKD,EAAOO,GACvCL,EAAK,GAAKF,EAAOO,IAAKL,EAAK,GAAKF,EAAOO,GACvCN,EAAK,GAAKD,EAAOS,IAAKR,EAAK,GAAKD,EAAOS,GACvCP,EAAK,GAAKF,EAAOS,IAAKP,EAAK,GAAKF,EAAOS,IAGnD,IAAIC,EAAWX,EAAKrC,UAAUgD,SAU9B,OATAZ,EAASY,SAASC,IAAID,EAASH,EAAGG,EAASF,EAAGE,EAASD,GACvC,CACZG,GAAId,EAASc,GACbC,OAAQf,EAASY,SACjBI,OAAQ,CAACZ,EAAK,GAAKD,EAAK,GAAIC,EAAK,GAAKD,EAAK,IAC3Cc,YAAahB,EAAKrC,UAAUsD,OAC5BC,UAAmC,cAAxBnB,EAASoB,YAA8B,EAAI,EACtDC,SAAUvB,IAKlBwB,gBAAiB,SAAStB,GAEtBzB,KAAKkB,QAAQ8B,OAAOvB,EAASc,KAGjCU,gBAAiB,SAASxB,EAAUC,GAEhC1B,KAAKkB,QAAQoB,IAAIb,EAASc,GAAIvC,KAAKwB,eAAeC,EAAUC,KAGhEwB,mBAAoB,SAASzB,EAAUC,GAEnC1B,KAAKiD,gBAAgBxB,EAAUC,IAInCyB,gBAAiB,SAAS1B,EAAUC,GAEhCD,EAASc,GAAKa,KAAKC,SAASC,WAAWC,UAAU,GACjD9B,EAASY,SAAW,IAAInC,MAAMC,QAE9BH,KAAKkB,QAAQO,EAASc,IAAMvC,KAAKwB,eAAeC,EAAUC,IAG9D8B,KAAM,SAAUjF,EAAGkF,GACf,IAAIC,EAAQ1D,KAAKY,GAAGC,QAAQ6C,MAC5B,IAAK1D,KAAK2D,YACLD,IACAA,EAAME,iBAAoB,OAG/B,IAAIC,EAAQH,EAAME,iBAGlB5D,KAAKiB,YAAcjB,KAAKiB,WAAW6C,QAAQC,IACnCF,EAAMG,gBAAmBH,EAAMG,eAAeC,IAAIF,IAElD/D,KAAK+C,gBAAgBgB,KAK7B,IAAIG,EAAYlE,KAAKY,GAAGC,QAAQsD,KAChCN,EAAMG,gBAAkBH,EAAMG,eAAeF,QAAQC,IACjD,IAAIK,EAAYV,EAAMW,QAAQN,EAAMO,WAAYtE,KAAKuE,UACjDvE,KAAKiB,WAAWgD,IAAIF,GACjBA,EAAMS,iBAAmBN,EAExBlE,KAAKiD,gBAAgBc,EAAOK,GAI5BpE,KAAKkD,mBAAmBa,EAAOK,GAInCpE,KAAKmD,gBAAgBY,EAAOK,KAIpCpE,KAAKiB,WAAa4C,EAAMG,gBAG5BrE,eAAgB,SAAU8E,GACtBzE,KAAK0E,SAAWD,EAChBA,EAAOE,uBAAwB,EAC/BF,EAAOG,UAAY5E,KAAK2D,UACxBc,EAAO7D,GAAGiE,aAAa,YAAa,WAAW,IAGnDlE,gBAAiB,WACb,IAAImE,EAAO9E,KACX+E,OAAO/D,iBAAiB,oBAAoB,WACnC8D,EAAKnB,WAAamB,EAAKE,uBAIhChF,KAAKgF,qBAGTA,kBAAmB,WAEf,GAAKC,UAAUC,IAAOD,UAAUC,GAAGC,mBAAnC,CAEI,IAAIL,EAAO9E,KACf8E,EAAKnB,UAAY,CAACyB,KAAM,YAExBH,UAAUC,GAAGC,mBAAmB,gBAAgBE,MAAK,SAASC,GAC5D,GAAIA,EAAW,CACb,IAAIC,EAAsB,CAAC,eACvBC,EAAsB,IACzBV,EAAKW,KAAK3F,aAAeyF,EAAsBC,GAAqBE,KAAK,YAC1E,IAAIC,EAAmBb,EAAKlE,GAAGC,QAAQ+E,aAAa,SAC/CD,GASDA,EAAiBE,iBAAiB/B,SAAQ,SAAUgC,GAChDN,EAAsBA,EAAoBO,QAAO,SAASzH,EAAO0H,EAAOC,GAAM,OAAO3H,GAASwH,QAGlGH,EAAiBO,iBAAiBpC,SAAQ,SAAUgC,GAChDP,EAAsBA,EAAoBQ,QAAO,SAASzH,EAAO0H,EAAOC,GAAM,OAAO3H,GAASwH,QAGlGP,EAAoBzB,SAAQ,SAAUgC,GAClCH,EAAiBE,iBAAmBF,EAAiBE,iBAAiBE,QAAO,SAASzH,EAAO0H,EAAOC,GAAM,OAAO3H,GAASwH,QAG9HH,EAAiBO,iBAAmBP,EAAiBO,iBAAiBC,OAAOZ,GAC7EI,EAAiBE,iBAAmBF,EAAiBE,iBAAiBM,OAAOX,GAE7EV,EAAKlE,GAAGC,QAAQgE,aAAa,QAASc,IAtBtCb,EAAKlE,GAAGC,QAAQgE,aAAa,QAAS,CAClCqB,iBAAkBX,EAAoBa,KAAK,KAC3CP,iBAAkBL,EAAoBY,KAAK,OAuBnDtB,EAAKlE,GAAGC,QAAQgE,aAAa,aAAc,UAAW,QAGtDC,EAAKuB,gBAAkB,KACvBvB,EAAKwB,YAAc,KACnBxB,EAAKP,SAAW,KAEhBO,EAAKlE,GAAGC,QAAQ0F,SAASrB,GAAGlE,iBAAiB,aAAewF,IACxD1B,EAAKwB,YAAc,KACnBxB,EAAKP,SAAW,KAChBO,EAAKuB,gBAAkB,OAE3BvB,EAAKlE,GAAGC,QAAQ0F,SAASrB,GAAGlE,iBAAiB,eAAiBwF,IAC1D,IAAIC,EAAU3B,EAAKlE,GAAGC,QAAQ0F,SAASrB,GAAGwB,aACtC9F,EAAKkE,EAAKlE,GAAGC,QAAQ8F,OAEzBF,EAAQzF,iBAAiB,eAAe,SAAU4F,GAE9C,IAAIC,EAAQD,EAAEE,YAAYC,QAAQC,KAAK,GACnCC,EAAQL,EAAEE,YAAYC,QAAQC,KAAK,GACvCjG,WAAW,KACP,IAAImG,EAAQ,IAAIC,WAAW,aAAc,CACrCC,KAAMrC,OACNsC,SAAS,EACTC,YAAY,IAEhBJ,EAAMK,cAAgB,CAAC,CAAEV,MAAOA,EAAOI,MAAOA,IAC9CrG,EAAG4G,cAAcN,QAIzBT,EAAQzF,iBAAiB,aAAa,SAAU4F,GAE5C,IAAIC,EAAQD,EAAEE,YAAYC,QAAQC,KAAK,GACnCC,EAAQL,EAAEE,YAAYC,QAAQC,KAAK,GACvCjG,WAAW,KACP,IAAImG,EAAQ,IAAIC,WAAW,WAAY,CACnCC,KAAMrC,OACNsC,SAAS,EACTC,YAAY,IAEhBJ,EAAMK,cAAgB,CAAC,CAAEV,MAAOA,EAAOI,MAAOA,IAC9CrG,EAAG4G,cAAcN,QAIzBT,EAAQzF,iBAAiB,UAAU,SAAU4F,GAEzC,IAAIC,EAAQD,EAAEE,YAAYC,QAAQC,KAAK,GACnCC,EAAQL,EAAEE,YAAYC,QAAQC,KAAK,GACvCjG,WAAW,KACP,IAAImG,EAAQ,IAAIO,WAAW,QAAS,CAChCC,QAASb,EACTc,QAASV,EACTI,SAAS,EACTC,YAAY,IAEhB1G,EAAG4G,cAAcN,QAIzBT,EAAQmB,sBAAsB,UAAUvC,KAAMwC,IAC1C/C,EAAKwB,YAAcuB,EACf/C,EAAKW,KAAK3F,cACV2G,EAAQqB,qBAAqB,CAACD,MAAO/C,EAAKwB,cACzCjB,KAAM0C,IACHjD,EAAKuB,gBAAkB0B,MAKnCtB,EAAQmB,sBAAsB,eAAevC,KAAMwC,IAC/C/C,EAAKP,SAAWsD,IAIhB/C,EAAKW,KAAK3F,cACV2G,EAAQuB,yBAAyB,CAACC,oBAAsB,CAACC,SAAU,aAOnFC,YAAa,WACT,OAAKnI,KAAK2D,WAAc3D,KAAK2D,UAAUyE,aAChCpI,KAAKC,aADkD,MAIlEoI,eAAgB,WACZ,OAAKrI,KAAK2D,WAAc3D,KAAK2D,UAAUyE,aAChCpI,KAAKI,eADkD,MAIlEkI,YAAa,WACT,OAAKtI,KAAK2D,WAAc3D,KAAK2D,UAAUyE,aAChCpI,KAAKQ,aADkD,MAIlE+H,oBAAqB,WACjB,OAAKvI,KAAK2D,WAAc3D,KAAK2D,UAAUyE,aAChCpI,KAAKS,iBADkD,MAIlE+H,OAEQnJ,EAAY,IAAIa,MAAMQ,QACtBpB,EAAW,IAAIY,MAAMC,QACX,IAAID,MAAMG,WACT,IAAIH,MAAMC,QACrBZ,EAAW,IAAIW,MAAMC,QAGlB,SAAU+B,EAAGC,EAAGvB,EAAI6H,GACvB,IAAKzI,KAAK2D,UAAa,MAAO,GAC9B,IAAI+E,EAAe,GAEnB,GAAI1I,KAAKY,GAAGC,QAAQ8H,GAAG,WAAY,CACjC,IAAK3I,KAAKsG,YAAa,OAEvB,IAAI5C,EAAQ1D,KAAKY,GAAGC,QAAQ6C,MACxBkF,EAAelF,EAAMmF,cAAc7I,KAAKuE,UAE5C,GAAIvE,KAAKqG,iBAAmBuC,EAAc,CACxC,IAAIE,EAAiBpF,EAAMqF,kBAAkB/I,KAAKqG,iBAG1CqC,EAAe,GACnB,IADA,IACSrL,EAAI,EAAGyL,GAAkBzL,EAAIyL,EAAe/G,OAAQ1E,IAAK,CAClE,IAAIqE,EAAOoH,EAAezL,GAAGgH,QAAQrE,KAAKuE,UACtClF,EAAU2J,UAAUtH,EAAKrC,UAAUsD,QACnCrD,EAAS2J,sBAAsB5J,GAC/BoJ,EAAYS,SAASC,iBAAiB5J,GAEtCmJ,EAAahD,KAAK,CACd0D,SAAU9J,EAAS+J,WAAW9J,GAC9B+J,MAAOhK,EAASiK,QAChBxK,OAAS6B,GAAMA,EAAGsI,UAAalJ,KAAKY,GAAGC,QAAQqI,aAa/D,OAAOR,IAMfc,SAAU,SAAU5L,EAAM6L,EAAKC,GAC3B,OAAK1J,KAAK2D,UAEH,MAGXgG,YAAa,SAAU/L,GACnB,OAAKoC,KAAK2D,UAEH,MAGXiG,WAAY,WACR,OAAOC,MAAMC,KAAK9J,KAAKoB,SAAS2I,WAKpCC,UAAW,WACP,OAAOH,MAAMC,KAAK9J,KAAKkB,QAAQ6I,c,cC5WvC,SAASE,EAAgBnH,GACrB,IAIInB,EAJAG,EAAiBgB,EAASf,OAC1BR,EAAc,IAAIS,aAA8B,EAAjBF,GAC/BzE,EAAI,EACJ4E,EAAI,EAER,IAAK5E,EAAI,EAAGA,EAAIyE,EAAgBzE,IAC5BsE,EAASmB,EAASzF,GAClBkE,EAAYU,GAAKN,EAAOO,EACxBX,EAAYU,EAAI,GAAKN,EAAOQ,EAC5BZ,EAAYU,EAAI,GAAKN,EAAOS,EAC5BH,GAAK,EAET,OAAOV,EA8yBA,IAEClC,EACAC,EACA4K,EACAC,EACA5K,EAjvBZC,OAAOC,kBAAkB,gBAAiB,CACtCC,OAAQ,CACJC,eAAgB,CAACC,SAAS,GAC1BC,iBAAkB,CAACD,SAAS,GAC5BE,aAAc,CAACF,SAAS,IAG5BG,KAAM,WACFC,KAAKoK,OAASpK,KAAKoK,OAAOvL,KAAKmB,MAC/BA,KAAKqK,QAAUrK,KAAKqK,QAAQxL,KAAKmB,MAEjCA,KAAKsK,YAActK,KAAKsK,YAAYzL,KAAKmB,MAEzCA,KAAKuK,WAAa,IAAIrK,MAAMQ,QAC5BV,KAAKC,aAAe,IAAIC,MAAMC,QAC9BH,KAAKI,eAAiB,IAAIF,MAAMG,WAChCL,KAAKM,UAAY,IAAIJ,MAAMK,MAAM,EAAG,EAAG,EAAG,OAC1CP,KAAKQ,aAAe,IAAIN,MAAMC,QAC9BH,KAAKS,iBAAmB,IAAIP,MAAMQ,QAClCV,KAAKwK,WAAa,IAAItK,MAAMQ,QAE5BV,KAAKW,gBAAkBX,KAAKW,gBAAgB9B,KAAKmB,MAC7CA,KAAKY,GAAGC,QAAQC,UAChBC,WAAWf,KAAKW,iBAEhBX,KAAKY,GAAGC,QAAQG,iBAAiB,SAAUhB,KAAKW,iBAMpDX,KAAKkB,QAAU,IAAIC,IACnBnB,KAAKoB,SAAW,IAAID,KAMxBxB,eAAgB,SAAU8E,GACtBzE,KAAK0E,SAAWD,EAChBA,EAAO7D,GAAGiE,aAAa,YAAa,WAAW,IAGnDlE,gBAAiB,WAEb,GAAKoE,OAAO0F,QAAW1F,OAAO0F,OAAOC,iBAChC3F,OAAO0F,OAAOC,gBAAgBC,OAAnC,CAEA5F,OAA0B,eAAI/E,KAAKoK,OACnCrF,OAA0B,eAAI/E,KAAKqK,QAGnC,IAAI5E,EAAO,CACPmF,QAAS,CACLC,GAAI,CACAC,SAAS,EACTC,QAAQ,EACRC,OAAO,EACPC,KAAK,EACLC,UAAU,EACVC,KAAK,EACLC,OAAO,EACPrH,OAAO,EACPsH,UAAU,EACVC,SAAS,EACTC,OAAO,EACPC,YAAY,IAGpBC,SAAU,kBAOd1G,OAAsB,cAAI,SAAUU,GAClCV,OAAO2G,WAAajG,EAAKiG,YAE3B,CACC,sBACA,qBACA,yBACA,2BACA,mBACA,yBACA,iBAEA,UACA,oBACA,iCACA,uBAEA,gCACA,+BACC5H,SAAQ,SAAU6H,GAIlB5G,OAAO4G,GAAa,SAAUlG,GAC5BmG,QAAQC,IAAIF,EAAY,IAAKlG,OAKjC,IAAIqG,EAAW9L,KAAKY,GAAGC,QAAQkL,WAAW,cACtCC,EAAcF,EAASG,UAAUC,WAAU,GAC/CJ,EAASG,UAAUE,WAAWC,aAAaJ,EAAaF,EAASG,WACjEH,EAASG,UAAYD,EACrBF,EAASG,UAAUI,UAAUC,OAAO,YACpC,IAAIxH,EAAO9E,KACX8L,EAASG,UAAUM,QAAU,WAC3B,IAAIC,EAAQhN,OAAOiN,OAAO,GAG1BD,EAAME,SAAS,WAGfF,EAAMT,WAAW,cAAcY,mBAAmBC,MAAM,yBAGxDJ,EAAME,SAAS,WACfF,EAAMK,KAAK,WAAY,CAACC,OAAQN,IAGhCzH,OAAO0F,OAAOC,gBAAgBC,OAAOoC,YAAYtH,GAGjD+G,EAAMQ,SAASC,UAIXnI,EAAKW,KAAK9F,gBACZoB,YAAW,WAAc+D,EAAKnF,eAAe6M,EAAM/H,WAGrD,IAAIyI,EAAK,IAAIhN,MAAMiN,QACfC,EAAaZ,EAAMjG,SAAS8G,gBAChCb,EAAMjG,SAAS+G,QAAQJ,GACvBtB,QAAQC,IAAI,cAAeuB,EAAY,SAAUF,GAGjDV,EAAM7F,OAAOiG,MAAMvK,SAAW,sBAC9BmK,EAAM7F,OAAOiG,MAAMW,MAAQ,kBAC3Bf,EAAM7F,OAAOiG,MAAMY,OAAS,kBAG5BzI,OAAO0I,4BAA8B,SAAShI,GAC7CmG,QAAQC,IAAI,+BAAgCpG,GAC5C1E,YAAW,WACV+D,EAAKwF,YACHoD,OAAOH,MAAQxI,OAAO4I,iBACtBD,OAAOF,OAASzI,OAAO4I,oBACvB,SAKVrD,YAAa,SAAUsD,EAAIC,GACvB,IAAIC,EAAK9N,KAAKY,GAAGC,QACjB+K,QAAQC,IAAI,eAAgB+B,EAAIC,EAC3B,QACAC,EAAGnH,OAAO4G,MAAOO,EAAGnH,OAAO6G,OAC3BE,OAAOH,MAAOG,OAAOF,OACrBzI,OAAO4I,iBAAkBG,EAAGvH,SAAS8G,iBAC1CO,EAAKA,GAAM5N,KAAK+N,aAAc/N,KAAK+N,aAAeH,EAClDC,EAAKA,GAAM7N,KAAKgO,aAAchO,KAAKgO,aAAeH,EAClDC,EAAGnH,OAAO9B,aAAa,QAAS+I,GAChCE,EAAGnH,OAAO9B,aAAa,SAAUgJ,GACjCC,EAAGrJ,OAAOwJ,OAASL,EAAKC,EACxBC,EAAGrJ,OAAOhE,iBAAiByN,KAXMlO,KAWIS,kBACrCqN,EAAGvH,SAAS4H,cAAc,GAC1BL,EAAGvH,SAAS6H,QAAQR,EAAIC,GAAI,GAC5BC,EAAGjB,KAAK,iBAAkB,MAAM,IAGpC7H,kBAAmB,WAEf,GAAKD,OAAO0F,QAAW1F,OAAO0F,OAAOC,iBAChC3F,OAAO0F,OAAOC,gBAAgB2D,QAAnC,CAGA,IAAIvJ,EAAO9E,KACX8E,EAAKnB,WAAY,EAIjB,IAAI8B,EAAO,CACPmF,QAAS,CACT0D,UAAU,EACN7J,QAAQ,EACR8J,SAAS,EACTC,iBAAiB,EACjB1O,aAAcE,KAAKyF,KAAK3F,cAE5B2L,SAAU,kBAId1G,OAA0B,kBAAI,SAAUU,GACtCmG,QAAQC,IAAI,qBAA2BpG,GAMvC1E,YAAW,WACT+D,EAAKwF,YACH7E,EAAK8H,MAAQxI,OAAO4I,iBACpBlI,EAAK+H,OAASzI,OAAO4I,oBACtB,MAIL5I,OAAO0F,OAAOC,gBAAgB2D,QAAQtB,YAAYtH,KAGtD2E,OAAQ,SAAUqE,GACdzO,KAAKgF,qBAGTqF,QAAS,SAAU5E,GACfzF,KAAK0O,UAAYjJ,EACjBzF,KAAK2O,YAAYlJ,IAGrBkJ,YAAa,SAAUlJ,GAmBnB,IAgBIpI,EACAuR,EAMJ,GAxCA5O,KAAKuK,WAAWvB,UAAUvD,EAAKoJ,kBAC/B7O,KAAKuK,WAAWuE,UAAU9O,KAAKC,aAAcD,KAAKI,eAAgBJ,KAAKQ,cACvER,KAAKM,UAAUyO,kBAAkB/O,KAAKI,gBACtCJ,KAAKQ,aAAa8B,IACdpC,MAAMkD,KAAK4L,QAAUhP,KAAKM,UAAU4B,EACpChC,MAAMkD,KAAK4L,QAAUhP,KAAKM,UAAU6B,EACpCjC,MAAMkD,KAAK4L,QAAUhP,KAAKM,UAAU8B,GAExCpC,KAAKS,iBAAiBuI,UAAUvD,EAAKwJ,mBACrCjP,KAAKwK,WAAWxB,UAAUvD,EAAKyJ,aAG3BlP,KAAK0E,UAAY1E,KAAKyF,KAAK5F,mBAC3BG,KAAKC,aAAakC,GAAKnC,KAAK0E,SAAS9D,GAAGmL,WAAWtH,OAAOgB,KAAK0J,YAInDnP,KAAKC,aAAaiC,GAAKlC,KAAKC,aAAakC,GAAKnC,KAAKC,aAAamC,GAAKpC,KAAKI,eAAe8B,GAAKlC,KAAKI,eAAe+B,GAAKnC,KAAKI,eAAegC,GAEnI,IAAlBpC,KAAKoP,WACPpP,KAAKoP,UAAW,EAChBpP,KAAKY,GAAGiM,KAAK,eAGO,IAAlB7M,KAAKoP,WACPpP,KAAKoP,UAAW,EAChBpP,KAAKY,GAAGiM,KAAK,YAAY,IAc1BpH,EAAK4J,YAAc5J,EAAK4J,WAAWtN,OACpC,IAAK1E,EAAI,EAAGA,EAAIoI,EAAK4J,WAAWtN,OAAQ1E,IAEtC,IADAuR,EAAUnJ,EAAK4J,WAAWhS,IACfiS,aACTtP,KAAKkB,QAAQoB,IAAIsM,EAAQW,KAAM,CAC7BhN,GAAIqM,EAAQW,KACZ/M,OAAQoM,EAAQU,aAChB7M,OAAQ,CAACmM,EAAQY,aAAatN,EAAG0M,EAAQY,aAAapN,GACtDM,YAAakM,EAAQvP,UACrBuD,UAAWgM,EAAQa,gBACnB3M,SAAUmH,EAAgB2E,EAAQc,SAAS5M,gBAE1C,CACH,IAAI6M,EAAa,CACfpN,GAAIqM,EAAQW,KACZ7M,YAAakM,EAAQvP,WAEF,UAAjBuP,EAAQxJ,OACVuK,EAAW/R,KAAOgR,EAAQW,MAE5BvP,KAAKoB,SAASkB,IAAIsM,EAAQW,KAAMI,GAKtC,GAAGlK,EAAKmK,gBAAkBnK,EAAKmK,eAAe7N,OAC5C,IAAK1E,EAAI,EAAGA,EAAIoI,EAAKmK,eAAe7N,OAAQ1E,IAC1CuR,EAAUnJ,EAAKmK,eAAevS,GAC3B2C,KAAKkB,QAAQhD,IAAI0Q,GAClB5O,KAAKkB,QAAQ8B,OAAO4L,GAEpB5O,KAAKoB,SAAS4B,OAAO4L,GAK3B,GAAGnJ,EAAK8I,SAAW9I,EAAK8I,QAAQxM,OAC9B,IAAK1E,EAAI,EAAGA,EAAIoI,EAAK8I,QAAQxM,OAAQ1E,IAEnC,IADAuR,EAAUnJ,EAAK8I,QAAQlR,IACZiS,aAAa,CACtB,IAAIvL,EAAQ/D,KAAKkB,QAAQhD,IAAI0Q,EAAQW,MACjCxL,GAUFA,EAAMvB,OAASoM,EAAQU,aACvBvL,EAAMtB,OAAS,CAACmM,EAAQY,aAAatN,EAAG0M,EAAQY,aAAapN,GAC7D2B,EAAMrB,YAAckM,EAAQvP,UAC5B0E,EAAMnB,UAAYgM,EAAQa,gBAC1B1L,EAAMjB,SAAWmH,EAAgB2E,EAAQc,SAAS5M,WAblD9C,KAAKkB,QAAQoB,IAAIsM,EAAQW,KAAM,CAC7BhN,GAAIqM,EAAQW,KACZ/M,OAAQoM,EAAQU,aAChB7M,OAAQ,CAACmM,EAAQY,aAAatN,EAAG0M,EAAQY,aAAapN,GACtDM,YAAakM,EAAQvP,UACrBuD,UAAWgM,EAAQa,gBACnB3M,SAAUmH,EAAgB2E,EAAQc,SAAS5M,gBAS5C,CACH,IAAI+M,EAAS7P,KAAKoB,SAASlD,IAAI0Q,EAAQW,MACnCM,EAMFA,EAAOnN,YAAckM,EAAQvP,UAL7BW,KAAKoB,SAASkB,IAAIsM,EAAQW,KAAM,CAC9BhN,GAAIqM,EAAQW,KACZ7M,YAAakM,EAAQvP,cAUnC8I,YAAa,WACT,OAAKnI,KAAK2D,UACH3D,KAAKC,aADkB,MAIlCoI,eAAgB,WACZ,OAAKrI,KAAK2D,UACH3D,KAAKI,eADkB,MAIlCkI,YAAa,WACT,OAAKtI,KAAK2D,UACH3D,KAAKQ,aADkB,MAIlC+H,oBAAqB,WACjB,OAAKvI,KAAK2D,UACH3D,KAAKS,iBADkB,MAMlC+I,SAAU,SAAU5L,EAAM6L,EAAKC,GAC3B,IAAK1J,KAAK2D,UAAa,OAAO,KAe9B,IAEImM,EAFAC,EAAUC,SAASC,cAAc,UACjCC,EAAWH,EAAQI,WAAW,MAUlC,GARKL,KACHA,EAAOE,SAASC,cAAc,QACzBG,YAAc,YACnBN,EAAKO,IAAM5G,EACXuG,SAASM,KAAKC,YAAYT,IAIvBA,EAAKU,UAAaV,EAAKW,cAM5B,GAAKX,EAAKvC,OAAUuC,EAAKtC,OAAzB,CAKAuC,EAAQxC,MAAQuC,EAAKvC,MACrBwC,EAAQvC,OAASsC,EAAKtC,OACtB0C,EAASQ,UAAUZ,EAAM,EAAG,GAC5B,IACIa,EAndZ,SAAgBC,GAChB,IAAIC,EAAY,GACZC,EAAY,mEAEZC,EAAaH,EAEbA,aAAkBI,YACtBD,EAAQ,IAAIE,WAAWC,aACZN,aAAkBO,YAC7BJ,EAAQH,EAAOnL,MAWf,IARA,IAKI2L,EALAC,EAAgBT,EAAO7O,OACvBuP,EAAgBD,EAAa,EAC7BE,EAAgBF,EAAaC,EAMxBjU,EAAI,EAAGA,EAAIkU,EAAYlU,GAAQ,EAWxCwT,GAAUC,GANG,UAHbM,EAASL,EAAM1T,IAAM,GAAO0T,EAAM1T,EAAI,IAAM,EAAK0T,EAAM1T,EAAI,MAGjC,IAMDyT,GALZ,OAARM,IAAqB,IAKcN,GAJ3B,KAARM,IAAsB,GAI4BN,EAH3C,GAARM,GA4BJ,OArBqB,GAAjBE,EAQJT,GAAUC,GALG,KAFbM,EAAQL,EAAMQ,MAEO,GAKIT,GAFZ,EAARM,IAAgB,GAEmB,KACZ,GAAjBE,IASXT,GAAUC,GANG,OAFbM,EAASL,EAAMQ,IAAe,EAAKR,EAAMQ,EAAa,MAE/B,IAMET,GALZ,KAARM,IAAmB,GAKgBN,GAF3B,GAARM,IAAmB,GAE+B,KAGhDP,EA2ZoBW,CADFtB,EAASuB,aAAa,EAAG,EAAG3B,EAAKvC,MAAOuC,EAAKtC,QACzB/H,MACrC,GAAKkL,EAAL,CAOA5L,OAAO2M,qCAAuC3M,OAAO2M,qCAAuC,GAAK,EACjG,IAAIC,EAAe,gCAAkC5M,OAAO2M,oCACxDE,EAAYhU,EAEhBmH,OAAO4M,GAAgB,SAAUlM,QAIVoM,IAAjBpM,EAAKqM,QACFrM,EAAKqM,QAMR/M,OAAO0F,OAAOC,gBAAgBqH,uBAAuBhF,YAAY,CAC/DtB,SAAUkG,EACVK,IAAKJ,KANPhG,QAAQC,IAAI,uBAAwBpG,EAAKwM,cAClClN,OAAO4M,SASKE,IAAnBpM,EAAKyM,YACFzM,EAAKyM,WAERtG,QAAQC,IAAI,yBAA0BpG,EAAKwM,cAItClN,OAAO4M,KAIlB5M,OAAO0F,OAAOC,gBAAgByH,kBAAkBpF,YAAY,CAC1DtB,SAAUkG,EACVK,IAAKpU,EACLgT,OAAQD,EACRyB,WAAYtC,EAAKvC,MACjB8E,YAAavC,EAAKtC,OAClB9D,cAAeA,SA5CfkC,QAAQC,IAAI,8CAVZD,QAAQC,IAAI,4DANZD,QAAQC,IAAI,kEAgElBlC,YAAa,SAAU/L,GACnB,IAAKoC,KAAK2D,UAAa,OAAO,KAQ9BoB,OAAOuN,qCAAuCvN,OAAOuN,qCAAuC,GAAK,EACjG,IAAIX,EAAe,gCAAkC5M,OAAOuN,oCACxDV,EAAYhU,EAEhBmH,OAAO4M,GAAgB,SAAUlM,QAINoM,IAArBpM,EAAK8M,cACF9M,EAAK8M,cACR3G,QAAQC,IAAI,OAAS8F,EAAe,iBAAkBlM,EAAKwM,cACpDlN,OAAO4M,IAIhB5M,OAAO0F,OAAOC,gBAAgB8H,sBAAsBzF,YAAY,CAC9DtB,SAAUkG,EACVK,IAAKJ,UAGcC,IAAnBpM,EAAKgN,YACFhN,EAAKgN,WACR7G,QAAQC,IAAI,OAAS8F,EAAe,iBAAkBlM,EAAKwM,cAItDlN,OAAO4M,KAIlB5M,OAAO0F,OAAOC,gBAAgBgI,yBAAyB3F,YAAY,CACjEtB,SAAUkG,EACVK,IAAKJ,KAIXhI,WAAY,WACR,OAAOC,MAAMC,KAAK9J,KAAKoB,SAAS2I,WAMpCC,UAAW,WACP,OAAOH,MAAMC,KAAK9J,KAAKkB,QAAQ6I,WAGnC4I,gBAAiB,WASb,SAASC,IAEL,OADA5S,KAAK0C,YAAc,IAAIV,aAAa,IAC7BhC,KAQP,IAiCK6S,EAjCDC,EAAU,CACbC,SAAU,IAAI7S,MAAMC,QACpB6S,OAAQ,IAAI9S,MAAMC,QAClB8S,eAAgB,IAAI/S,MAAMC,QAC1B+S,iBAAkB,IAAIhT,MAAMG,WAG5B8S,eAAgB,IAAIjT,MAAMQ,QAC1B0S,cAAe,IAAIlT,MAAMC,QACzBkT,YAAa,IAAInT,MAAMC,QACvBmT,YAAa,IAAIpT,MAAMC,QACvBoT,YAAa,IAAIrT,MAAMQ,QACvB8S,mBAAoB,IAAItT,MAAMQ,QAC9B+S,YAAa,IAAIvT,MAAMC,QACvBuT,cAAe,IAAIxT,MAAMC,QACzBwT,YAAa,IAAIzT,MAAMC,QACvByT,YAAa,IAAI1T,MAAMC,QACvB0T,kBAAmB,IAAI3T,MAAMC,QAC7B2T,uBAAwB,IAAI5T,MAAMC,QAClC4T,SAAU,IAAI7T,MAAMQ,QACpBsT,gBAAiB,IAAI9T,MAAMG,YAY3B4T,GACIpB,EAAa,IAAI3S,MAAMC,QACpB,SAASyT,EAAaF,EAAeQ,EAAWC,GAEnD,IAAIC,EAAQR,EAAYS,IAAIF,GAE5B,OADAtB,EAAWyB,WAAWZ,EAAeQ,GAC9BrB,EAAWwB,IAAIT,GAAeQ,IAWzCG,EAAe,SAASC,EAAGC,GAE3B3B,EAAQS,YAAYvK,UAAUwL,EAAE9R,aAEhCoQ,EAAQe,kBAAkB5K,sBAAsB6J,EAAQS,aAExD,IAAImB,EAAQ5B,EAAQe,kBAAkBxK,WAAWyJ,EAAQG,gBAUzD,OAPAH,EAAQS,YAAYvK,UAAUyL,EAAE/R,aAEhCoQ,EAAQe,kBAAkB5K,sBAAsB6J,EAAQS,aAKjDmB,EAHK5B,EAAQe,kBAAkBxK,WAAWyJ,EAAQG,iBAGjC,EAAI,GAGhC,OAAO,SAAS/Q,EAAGC,GAEf,GAAID,EAAI,GAAKA,EAAI,GAAKC,EAAI,GAAKA,EAAI,EAC/B,MAAM,IAAIwS,MACF,sDAIZ,IAAIC,EAAO,GAEPC,EAAS7U,KAAKgK,YAClB,IAAK6K,GAA4B,IAAlBA,EAAO9S,OAClB,OAAO6S,EAIX9B,EAAQC,SAASzQ,IAAI,EAAIJ,EAAI,EAAG,GAAK,EAAIC,GAAK,EAAG,GACjD2Q,EAAQE,OAAO1Q,IAAI,EAAIJ,EAAI,EAAG,GAAK,EAAIC,GAAK,EAAG,GAS/C2Q,EAAQS,YAAYuB,iBAChB9U,KAAKS,iBACLT,KAAKwK,YAGTsI,EAAQK,eAAe4B,WAAWjC,EAAQS,aAG1CT,EAAQM,cAAclF,KAAK4E,EAAQC,UAC9BiC,aAAalC,EAAQK,gBAC1BL,EAAQO,YAAYnF,KAAK4E,EAAQE,QAC5BgC,aAAalC,EAAQK,gBAG1BL,EAAQQ,YAAYgB,WAChBxB,EAAQO,YACRP,EAAQM,eACV6B,YAGF,IAAK,IAAI5X,EAAI,EAAGA,EAAIwX,EAAO9S,OAAQ1E,IAAK,CACpC,IAAI0G,EAAQ8Q,EAAOxX,GAEnByV,EAAQS,YAAYvK,UAAUjF,EAAMrB,aAGpCoQ,EAAQa,YAAYrR,IAAIyB,EAAMvB,OAAON,EAAG6B,EAAMvB,OAAOL,EAAG4B,EAAMvB,OAAOJ,GACrE0Q,EAAQY,cAAcxF,KAAK4E,EAAQa,aAC9BqB,aAAalC,EAAQS,aAE1BT,EAAQoC,eAAiBnR,EAAMnB,UAGA,IAA3BkQ,EAAQoC,eACRpC,EAAQc,YAAYtR,IAAI,EAAG,EAAG,GAE9BwQ,EAAQc,YAAYtR,IAAIwQ,EAAQS,YAAY,GAAIT,EAAQS,YAAY,GAAIT,EAAQS,YAAY,IAIhG,IAAIhV,EAAI0V,EACJnB,EAAQc,YACRd,EAAQY,cACRZ,EAAQM,cACRN,EAAQQ,aAIZ,KAAI/U,EAAI,GAAR,CAKAuU,EAAQgB,uBAAuB5F,KAAK4E,EAAQQ,aAAa6B,eAAe5W,GACxEuU,EAAQe,kBAAkBuB,WACtBtC,EAAQM,cACRN,EAAQgB,wBAGZhB,EAAQW,YAAYnR,IAAIyB,EAAMtB,OAAO,GAAI,EAAGsB,EAAMtB,OAAO,IAyBzDqQ,EAAQU,mBAAmBuB,WAAWjC,EAAQS,aAC9CT,EAAQgB,uBAAuB5F,KAAK4E,EAAQe,mBACvCmB,aAAalC,EAAQU,oBAK1B,KACIpQ,KAAKiS,IAAIvC,EAAQgB,uBAAuB5R,GACxC4Q,EAAQW,YAAYvR,EAAI,EAHZ,OAQZkB,KAAKiS,IAAIvC,EAAQgB,uBAAuB1R,GACxC0Q,EAAQW,YAAYrR,EAAI,EATZ,OAOhB,CAUA0Q,EAAQkB,gBAAgBsB,sBAAsBxC,EAAQS,aACtDT,EAAQiB,SAASwB,2BAA2BzC,EAAQkB,iBAAiBwB,YAAY1C,EAAQe,mBAEzF,IADD,IAAI4B,EAAM,IAAI7C,EACJ3Q,EAAI,EAAGA,EAAI,GAAIA,IACpBwT,EAAI/S,YAAYT,GAAK6Q,EAAQiB,SAAS2B,SAASzT,GAEnDwT,EAAIpY,EAAIA,EACRuX,EAAKlP,KAAK+P,KAMd,OADAb,EAAKe,KAAKpB,GACHK,GAzOC,GA6OjBpM,OAEQnJ,EAAY,IAAIa,MAAMQ,QACtBpB,EAAW,IAAIY,MAAMC,QACrB+J,EAAU,IAAIhK,MAAMG,WACpB8J,EAAW,IAAIjK,MAAMC,QACrBZ,EAAW,IAAIW,MAAMC,QAGlB,SAAU+B,EAAGC,EAAGvB,EAAI6H,GACvB,IAAKzI,KAAK2D,UAAa,MAAO,GAM9B,IAJA,IAAI8R,EAAMzV,KAAK2S,gBAAgBzQ,EAAGC,GAG9BuG,EAAe,GACVrL,EAAI,EAAGoY,GAAOpY,EAAIoY,EAAI1T,OAAQ1E,IACnCgC,EAAU2J,UAAUyM,EAAIpY,GAAGqF,aAC3BrD,EAAUyP,UAAUxP,EAAU4K,EAASC,GACvC1B,EAAYS,SAASC,iBAAiB5J,GAEtCmJ,EAAahD,KAAK,CACd0D,SAAU9J,EAAS+J,WAAW9J,GAC9B+J,MAAOhK,EAASiK,QAChBxK,OAAS6B,GAAMA,EAAGsI,UAAalJ,KAAKY,GAAGC,QAAQqI,WAUvD,OAAOR,O,cC/zBX,IAEAkN,EACAC,EACAC,EACAC,EAnCRvW,OAAOC,kBAAkB,YAAa,CAEpCuW,eAAgB,WACd,IAAIC,EAOJ,OANKjW,KAAKkW,cACRD,EAAUjW,KAAKY,GAAGC,QAAQkL,WAAe,MAEvC/L,KAAKkW,YAAcD,EAAQE,aAGxBnW,KAAKkW,aAGdlM,UAAW,WACT,IAAIkM,EAAclW,KAAKgW,iBACvB,GAAKE,GAAgBA,EAAYlM,UACjC,OAAOkM,EAAYlM,aAGrBjK,KAAM,WAEJC,KAAK6U,OAAS,GACd7U,KAAKoW,aAAe,GACpBpW,KAAKqW,mBAAqB,CAACjR,KAAK,QAASkG,QAAStL,KAAKoW,cACvDpW,KAAKsW,eAAiB,GACtBtW,KAAKuW,qBAAuB,CAACnR,KAAK,UAAWkG,QAAStL,KAAKsW,gBAC3DtW,KAAKwW,eAAiB,GACtBxW,KAAKyW,qBAAuB,CAACrR,KAAK,UAAWkG,QAAStL,KAAKwW,iBAG7DhT,MAEMoS,EAAY,IAAI1V,MAAMC,QAAQ,EAAG,EAAG,GACpC0V,EAAW,IAAI3V,MAAMQ,QACrBoV,EAAe,IAAI5V,MAAMC,QACzB4V,EAAiB,IAAI7V,MAAMG,WAGxB,SAAU9B,EAAGkF,GAElB,IAAIoR,EAAS7U,KAAKgK,YAClB,GAAK6K,EAAL,CAGA,IAOIxX,EAPAqZ,EAAa,GACbC,EAAe,GACfC,EAAe,GAIfC,EAAY,GAIhB,IAAKxZ,EAAE,EAAGwX,GAAUxX,EAAEwX,EAAO9S,OAAQ1E,IAAK,CACxC,IAIIyZ,EAJA/S,EAAQ8Q,EAAOxX,GAMfkF,QAA2BsP,IAArB9N,EAAMgT,WAA2BhT,EAAMgT,WAAahT,EAAMxB,IAAIe,WAEpEY,EAAYH,EAAMG,UAGtB2S,EAAUtU,IAAM,EAEhB,IAAIyU,GAAUhX,KAAK6U,OAAOtS,GACtB0U,OAA6BpF,IAAd3N,EACnB,GAAK8S,IAGGC,GAEI/S,IAAclE,KAAK6U,OAAOtS,GAAI2B,UAL1C,CA8CA,GAtBA4S,EAAY,CAACC,WAAYxU,QACPsP,IAAd3N,IAA2B4S,EAAU5S,UAAYA,GAGjDH,EAAMrB,aAAeqB,EAAM1E,UAC7ByX,EAAUpU,YAAcqB,EAAMrB,aAAeqB,EAAM1E,WAGnDyW,EAAa9M,UAAUjF,EAAM1B,UAC7B0T,EAAe/M,UAAUjF,EAAMlB,aAC/B+S,EAAUtT,IAAI,EAAG,EAAG,GACpBuT,EAASqB,QAAQpB,EAAcC,EAAgBH,GAC/CkB,EAAUpU,YAAcmT,EAASH,SAASyB,SAG5CL,EAAUrU,OAASsB,EAAMtB,OACrBsB,EAAMvB,SAAUsU,EAAUtU,OAASuB,EAAMvB,QACzCuB,EAAMzC,QAAWwV,EAAUhU,SAAWiB,EAAMzC,QACvCyC,EAAMjB,WAAYgU,EAAUhU,SAAWiB,EAAMjB,UAIjDkU,EAmBHN,EAAWhR,KAAKoR,QAjBhB,GAAIG,EAEFN,EAAajR,KAAKoR,OAIpB,IAAItX,OAAO4X,MAAMC,UAAUP,EAAW9W,KAAK6U,OAAOtS,IAEhD,SAKAoU,EAAajR,KAAKoR,GAUlBG,EAIFjX,KAAK6U,OAAOtS,GAAMuU,GAIlB9W,KAAK6U,OAAOtS,GAAM,CAChBwU,WAAYD,EAAUC,WACtBrU,YAAaoU,EAAUpU,YAAYyU,QACnC1U,OAAQqU,EAAUrU,OAAO0U,SAOvBL,EAAUhU,WACZ9C,KAAK6U,OAAOtS,GAAIO,SAAWgU,EAAUhU,SAASqU,WAMpD,IAAIrS,EAAO9E,KACXjC,OAAOuZ,KAAKxS,EAAK+P,QAAQ/Q,SAAQ,SAAUlF,GACpCiY,EAAUjY,KACbgY,EAAalR,KAAKZ,EAAK+P,OAAOjW,WACvBkG,EAAK+P,OAAOjW,OASvBoB,KAAKoW,aAAeM,EAEhBA,EAAW3U,OAAS,IAGtB/B,KAAKqW,mBAAmB/K,QAAUoL,EAClC1W,KAAKY,GAAGiM,KAAK,eAAgB7M,KAAKqW,qBAIpCrW,KAAKsW,eAAiBK,EAElBA,EAAa5U,OAAS,IAGxB/B,KAAKuW,qBAAqBjL,QAAUqL,EACpC3W,KAAKY,GAAGiM,KAAK,iBAAkB7M,KAAKuW,uBAItCvW,KAAKwW,eAAiBI,EAElBA,EAAa7U,OAAS,IAGxB/B,KAAKyW,qBAAqBnL,QAAUsL,EACpC5W,KAAKY,GAAGiM,KAAK,iBAAkB7M,KAAKyW,6B,cC7M5CjX,OAAOC,kBAAkB,aAAc,CAErC0W,UAAW,WACT,IAAIF,EAOJ,OANKjW,KAAKuX,SACRtB,EAAUjW,KAAKY,GAAGC,QAAQkL,WAAe,MAEvC/L,KAAKuX,OAAStB,EAAQE,aAGnBnW,KAAKuX,QAGd3N,WAAY,WACV,IAAI2N,EAASvX,KAAKmW,YAClB,GAAKoB,GAAWA,EAAO3N,WACvB,OAAO2N,EAAO3N,iB,cChBlBpK,OAAOC,kBAAkB,YAAa,CAEpC0W,UAAW,WACT,IAAIF,EAOJ,OANKjW,KAAKuX,SACRtB,EAAUjW,KAAKY,GAAGC,QAAQkL,WAAe,MAEvC/L,KAAKuX,OAAStB,EAAQE,aAGnBnW,KAAKuX,QAGd/N,SAAU,SAAU5L,EAAM6L,EAAKC,GAC7B,IAAI6N,EAASvX,KAAKmW,YAClB,GAAKoB,GAAWA,EAAO/N,SACvB,OAAO+N,EAAO/N,SAAS5L,EAAM6L,EAAKC,IAGpCC,YAAa,SAAU/L,GACrB,IAAI2Z,EAASvX,KAAKmW,YAClB,GAAKoB,GAAWA,EAAO5N,YACvB,OAAO4N,EAAO5N,YAAY/L,O,cCtB9B4B,OAAOC,kBAAkB,KAAM,CAC7BC,OAAQ,CACNC,eAAgB,CAACC,SAAS,GAC1BC,iBAAkB,CAACD,SAAS,GAC5BE,aAAc,CAACF,SAAS,GACxB4X,OAAQ,CAAC5X,SAAS,IAEpB6X,aAAc,CAAC,WAAY,gBAAiB,YAAa,cACzDtB,UAAW,WACT,IAAIF,EACJ,IAAKjW,KAAKuX,OAAQ,CAChB,IAAIzS,EAAO9E,KACX8E,EAAK2S,aAAa3T,SAAQ,SAAS4T,IACjCzB,EAAUnR,EAAKlE,GAAGC,QAAQkL,WAAW2L,KACtBzB,EAAQtS,YACrBmB,EAAKyS,OAAStB,MAIpB,OAAOjW,KAAKuX,QAEdvN,UAAW,WACT,OAAOhK,KAAKuX,OAASvX,KAAKuX,OAAOvN,iBAAc6H,GAEjDjI,WAAY,WACV,OAAO5J,KAAKuX,OAASvX,KAAKuX,OAAO3N,kBAAeiI,GAElDrI,SAAU,SAAU5L,EAAM6L,EAAKC,GAC7B,OAAO1J,KAAKuX,OAAO/N,SAAS5L,EAAM6L,EAAKC,IAEzCC,YAAa,SAAU/L,GACrB,OAAOoC,KAAKuX,OAAO5N,YAAY/L,IAEjCmC,KAAM,WACJ,IAAI6K,EAAU,CACZjL,eAAgBK,KAAKyF,KAAK9F,eAC1BE,iBAAkBG,KAAKyF,KAAK5F,iBAC5BC,aAAcE,KAAKyF,KAAK3F,cAGtBgF,EAAO9E,KACXA,KAAKyX,aAAa3T,SAAQ,SAAS4T,GAC/B5S,EAAKlE,GAAGiE,aAAa6S,EAAK9M,MAG1B5K,KAAKyF,KAAK+R,QACZxX,KAAKY,GAAGC,QAAQgE,aAAa,aAAc,CAACqD,SAAS,IAIvD8H,SAAS2H,KAAKC,mBAAmB,YAC/B,4E,cCnDNpY,OAAOC,kBAAkB,YAAa,CACpCC,OAAQ,CACNwI,QAAS,CAACtI,SAAQ,IAGpBG,KAAM,WACJ,IAAI8X,EAAe7X,KAAKY,GAAGgF,aAAa,iBACxC5F,KAAK8X,yBAAyBD,GAAeA,EAAa3P,SAG5D6P,OAAQ,SAAUC,GAChB,IAAKA,GAAWA,EAAQ9P,UAAYlI,KAAKyF,KAAKyC,QAE5C,GAAIlI,KAAKyF,KAAKyC,QAAS,CAErB,IAAI2P,EAAe7X,KAAKY,GAAGgF,aAAa,iBACxC5F,KAAK8X,yBAAyBD,GAAeA,EAAa3P,QACtDlI,KAAK8X,wBACP9X,KAAKY,GAAGiE,aAAa,gBAAiB,WAAW,QAI/C7E,KAAK8X,wBACP9X,KAAKY,GAAGiE,aAAa,gBAAiB,WAAW,IAMzDrB,KAAM,SAAUjF,EAAGkF,GACjB,GAAKzD,KAAKyF,KAAKyC,QAAf,CAEA,IAAI+N,EAAUjW,KAAKiY,eACnB,GAAKhC,EAAL,CAIA,IAAIiC,EAAMjC,EAAQ9N,cACd+P,GAAOlY,KAAKY,GAAGiE,aAAa,WAAYqT,GAI5C,IAAIC,EAAMlC,EAAQ3N,cAIlB,GAHI6P,GAAOnY,KAAKY,GAAGiE,aAAa,WAAYsT,IAGvCnY,KAAKY,GAAGC,QAAQ8H,GAAG,WAAY,CAClC,IAAIhG,EAASsT,EAAQ1N,sBACjB5F,IAAU3C,KAAKY,GAAGmL,WAAWtH,OAAOA,OAAOhE,iBAAmBkC,OAItEsV,aAAc,WACZ,IAAKjY,KAAKiW,QAAS,CACjB,IAAIA,EAAUjW,KAAKY,GAAGC,QAAQkL,WAAe,GAAEoK,YAC/C,IAAKF,IAAYA,EAAQtS,UAAa,OACtC3D,KAAKiW,QAAUA,EAEjB,OAAOjW,KAAKiW,Y,cCxDhBzW,OAAOC,kBAAkB,eAAgB,CACvCgY,aAAc,CAAC,aAEf/X,OAAQ,CACNwC,EAAG,CAACtC,QAAS,IACbuC,EAAG,CAACvC,QAAS,IACbgB,GAAI,CAACwE,KAAM,aAGbrF,KAAM,WAEJC,KAAKoY,UAAYpY,KAAKY,GAAGmL,WAAsB,UAAEqM,UACjDpY,KAAKqY,0BAA4BrY,KAAKoY,UAAUE,iBAAiBzZ,KAAKmB,KAAKoY,WAC3EpY,KAAKoY,UAAUE,iBAAmBtY,KAAKsY,iBAAiBzZ,KAAKmB,OAG/D+X,OAAQ,SAAUC,GACXhY,KAAKyF,KAAK7E,IAGRZ,KAAKY,GAAGC,QAAQqI,SAAStI,KAC5BZ,KAAKY,GAAGC,QAAQqI,SAAStI,GAAKZ,KAAKY,GAAGC,UAK5CyX,iBAAkB,SAAU/J,EAASgK,EAAWC,GAE9C,IAAIC,EAAUzY,KAAKqY,0BAA0B9J,EAASgK,EAAWC,GAE7DE,EAAe1Y,KAAKwI,QASxB,OARIkQ,GAAgBA,EAAa3W,SAC3ByW,GACFE,EAAa5U,QAAS2R,GAAQ+C,EAAiB9S,KAAK+P,IACpDgD,EAAUD,GAEVE,EAAa5U,QAAS2R,GAAQgD,EAAQ/S,KAAK+P,KAGxCgD,GAGTjQ,MAAO,WACL,IAAIyN,EAAUjW,KAAKiY,eACnB,IAAKhC,IAAYA,EAAQtS,UAAa,MAAO,GAC7C,IAAIzB,EAAIlC,KAAKyF,KAAKvD,EACdC,EAAInC,KAAKyF,KAAKtD,EAKlB,OAJIwW,UAAU5W,QAAU,IACtBG,EAAIyW,UAAU,GACdxW,EAAIwW,UAAU,IAET1C,EAAQzN,MAAMtG,EAAGC,EAAGnC,KAAKyF,KAAK7E,GAAIZ,KAAKY,KAGhDqX,aAAc,WACZ,IAAKjY,KAAKiW,QAAS,CACjB,IAAIA,EAAUjW,KAAKY,GAAGC,QAAQkL,WAAe,GAE7C,GADIkK,IAAWA,EAAUA,EAAQE,UAAYF,EAAQE,iBAActE,IAC9DoE,IAAYA,EAAQtS,UAAa,OACtC3D,KAAKiW,QAAUA,EAEjB,OAAOjW,KAAKiW","file":"aframe-ar.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","require('./webxr-ar');\n//require('./three-ar');\nrequire('./mozilla-xr-ar');\nrequire('./ar-planes');\nrequire('./ar-anchors');\nrequire('./ar-images');\nrequire('./ar');\nrequire('./ar-camera');\nrequire('./ar-raycaster');\n\n","/* global AFRAME, THREE, VRFrameData */\n\nAFRAME.registerComponent('webxr-ar', {\n schema: {\n takeOverCamera: {default: true},\n cameraUserHeight: {default: false},\n worldSensing: {default: false} // currently unused\n },\n\n init: function () {\n this.posePosition = new THREE.Vector3();\n this.poseQuaternion = new THREE.Quaternion();\n this.poseEuler = new THREE.Euler(0, 0, 0, 'YXZ');\n this.poseRotation = new THREE.Vector3();\n this.projectionMatrix = new THREE.Matrix4();\n\n this.onceSceneLoaded = this.onceSceneLoaded.bind(this);\n if (this.el.sceneEl.hasLoaded) {\n setTimeout(this.onceSceneLoaded);\n } else {\n this.el.sceneEl.addEventListener('loaded', this.onceSceneLoaded);\n }\n\n // Add planes handling, so we can do synchronous hit test.\n\n this.rawPlanes_ = null;\n this.planes_ = new Map();\n this.anchors_ = new Map();\n },\n\n convertPolygonToVertices: function(polygon) {\n return newVertices;\n },\n\n convertedPlane: function(rawPlane, pose) {\n var mins = [0, 0];\n var maxs = [0, 0];\n var verticesLength = rawPlane.polygon.length;\n var newVertices = new Float32Array(verticesLength * 3);\n var i = 0;\n var j = 0;\n var vertex;\n for (i = 0; i < verticesLength; i++) {\n vertex = rawPlane.polygon[i];\n newVertices[j] = vertex.x;\n newVertices[j + 1] = vertex.y;\n newVertices[j + 2] = vertex.z;\n j += 3;\n if (i == 0) {\n mins[0] = maxs[0] = vertex.x;\n mins[1] = maxs[1] = vertex.z;\n } else {\n if (mins[0] > vertex.x) { mins[0] = vertex.x; }\n if (maxs[0] < vertex.x) { maxs[0] = vertex.x; }\n if (mins[1] > vertex.z) { mins[1] = vertex.z; }\n if (maxs[1] < vertex.z) { maxs[1] = vertex.z; }\n }\n }\n var position = pose.transform.position;\n rawPlane.position.set(position.x, position.y, position.z);\n var converted = {\n id: rawPlane.id,\n center: rawPlane.position,\n extent: [maxs[0] - mins[0], maxs[1] - mins[1]],\n modelMatrix: pose.transform.matrix,\n alignment: rawPlane.orientation != 'Horizontal' ? 1 : 0,\n vertices: newVertices\n };\n return converted;\n },\n\n rawPlaneRemoved: function(rawPlane) {\n // remove the converted plane\n this.planes_.delete(rawPlane.id);\n },\n\n rawPlaneUpdated: function(rawPlane, pose) {\n // convert the updated plane\n this.planes_.set(rawPlane.id, this.convertedPlane(rawPlane, pose));\n },\n\n rawPlaneNotUpdated: function(rawPlane, pose) {\n // FIXME: check is broken so update anyway\n this.rawPlaneUpdated(rawPlane, pose);\n // do nothing\n },\n\n rawPlaneCreated: function(rawPlane, pose) {\n // assign and attach an id... for now, use Math.random()\n rawPlane.id = Math.random().toString().substring(2);\n rawPlane.position = new THREE.Vector3();\n // convert the plane\n this.planes_[rawPlane.id] = this.convertedPlane(rawPlane, pose);\n },\n\n tick: function (t, dt) {\n let frame = this.el.sceneEl.frame;\n if (!this.arDisplay\n || !frame\n || !frame.worldInformation) { return; }\n\n // use the planes information\n let world = frame.worldInformation;\n\n // check for removed planes\n this.rawPlanes_ && this.rawPlanes_.forEach(plane => {\n if(!world.detectedPlanes || !world.detectedPlanes.has(plane)) {\n // Handle removed plane - `plane` was present in previous frame but is no longer tracked.\n this.rawPlaneRemoved(plane);\n }\n });\n\n // check for changed planes\n let timestamp = this.el.sceneEl.time;\n world.detectedPlanes && world.detectedPlanes.forEach(plane => {\n let planePose = frame.getPose(plane.planeSpace, this.refSpace);\n if (this.rawPlanes_.has(plane)) {\n if(plane.lastChangedTime == timestamp) {\n // Handle previously seen plane that was updated in current frame.\n this.rawPlaneUpdated(plane, planePose);\n } else {\n // Handle previously seen plane that was not updated in current frame.\n // Depending on the application, this could be a no-op.\n this.rawPlaneNotUpdated(plane, planePose);\n }\n } else {\n // Handle new plane.\n this.rawPlaneCreated(plane, planePose);\n }\n });\n \n this.rawPlanes_ = world.detectedPlanes;\n },\n\n takeOverCamera: function (camera) {\n this.arCamera = camera;\n camera.isARPerspectiveCamera = true; // HACK - is this necessary?\n camera.vrDisplay = this.arDisplay; // HACK - is this necessary?\n camera.el.setAttribute('ar-camera', 'enabled', true);\n },\n\n onceSceneLoaded: function () {\n var self = this;\n window.addEventListener('ardisplayconnect', function () {\n if (!self.arDisplay) { self.checkForARDisplay(); }\n });\n\n // Check now for AR display.\n this.checkForARDisplay();\n },\n\n checkForARDisplay: function () {\n // check to see if webxr ar mode is supported\n if (!navigator.xr || !navigator.xr.isSessionSupported) { return; }\n\n var self = this;\n self.arDisplay = {type: 'webxr-ar'};\n\n navigator.xr.isSessionSupported('immersive-ar').then(function(supported) {\n if (supported) {\n let ourRequiredFeatures = ['local-floor'];\n let ourOptionalFeatures = [];\n (self.data.worldSensing ? ourRequiredFeatures : ourOptionalFeatures).push('hit-test');\n let existingFeatures = self.el.sceneEl.getAttribute('webxr');\n if (!existingFeatures) {\n // here, we assume we can set as map and not String (?) \n self.el.sceneEl.setAttribute('webxr', { \n requiredFeatures: ourRequiredFeatures.join(','), \n optionalFeatures: ourOptionalFeatures.join(',') \n });\n } else {\n // here, we assume we get and set as map and not String (?)\n // remove existing optional features from our optional\n existingFeatures.optionalFeatures.forEach(function (feature) {\n ourOptionalFeatures = ourOptionalFeatures.filter(function(value, index, arr){ return value != feature;});\n });\n // remove existing required features from our required\n existingFeatures.requiredFeatures.forEach(function (feature) {\n ourRequiredFeatures = ourRequiredFeatures.filter(function(value, index, arr){ return value != feature;});\n });\n // remove our required features from existing optional\n ourRequiredFeatures.forEach(function (feature) {\n existingFeatures.optionalFeatures = existingFeatures.optionalFeatures.filter(function(value, index, arr){ return value != feature;});\n });\n // add our required and optional features to the existing\n existingFeatures.requiredFeatures = existingFeatures.requiredFeatures.concat(ourRequiredFeatures);\n existingFeatures.optionalFeatures = existingFeatures.optionalFeatures.concat(ourOptionalFeatures);\n\n self.el.sceneEl.setAttribute('webxr', existingFeatures);\n }\n\n self.el.sceneEl.setAttribute('vr-mode-ui', \"enabled\", \"true\");\n // auto-entering AR doesn't work.\n\n self.xrHitTestSource = null;\n self.viewerSpace = null;\n self.refSpace = null;\n\n self.el.sceneEl.renderer.xr.addEventListener('sessionend', (ev) => {\n self.viewerSpace = null;\n self.refSpace = null;\n self.xrHitTestSource = null;\n });\n self.el.sceneEl.renderer.xr.addEventListener('sessionstart', (ev) => {\n let session = self.el.sceneEl.renderer.xr.getSession();\n let el = self.el.sceneEl.canvas;\n\n session.addEventListener('selectstart', function (e) {\n // dispatch touchstart\n var pageX = e.inputSource.gamepad.axes[0];\n var pageY = e.inputSource.gamepad.axes[1];\n setTimeout(() => {\n var event = new TouchEvent('touchstart', {\n view: window,\n bubbles: true,\n cancelable: true\n });\n event.targetTouches = [{ pageX: pageX, pageY: pageY }];\n el.dispatchEvent(event);\n });\n });\n\n session.addEventListener('selectend', function (e) {\n // dispatch touchend\n var pageX = e.inputSource.gamepad.axes[0];\n var pageY = e.inputSource.gamepad.axes[1];\n setTimeout(() => {\n var event = new TouchEvent('touchend', {\n view: window,\n bubbles: true,\n cancelable: true\n });\n event.targetTouches = [{ pageX: pageX, pageY: pageY }];\n el.dispatchEvent(event);\n });\n });\n\n session.addEventListener('select', function (e) {\n // dispatch click\n var pageX = e.inputSource.gamepad.axes[0];\n var pageY = e.inputSource.gamepad.axes[1];\n setTimeout(() => {\n var event = new MouseEvent('click', { \n clientX: pageX, \n clientY: pageY, \n bubbles: true,\n cancelable: true\n });\n el.dispatchEvent(event);\n });\n });\n\n session.requestReferenceSpace('viewer').then((space) => {\n self.viewerSpace = space;\n if (self.data.worldSensing) {\n session.requestHitTestSource({space: self.viewerSpace})\n .then((hitTestSource) => {\n self.xrHitTestSource = hitTestSource;\n })\n }\n });\n\n session.requestReferenceSpace('local-floor').then((space) => {\n self.refSpace = space;\n });\n\n // Ask for planes, if we should.\n if (self.data.worldSensing) {\n session.updateWorldTrackingState({planeDetectionState : {enabled : true}});\n }\n });\n }\n });\n },\n\n getPosition: function () {\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\n return this.posePosition;\n },\n\n getOrientation: function () {\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\n return this.poseQuaternion;\n },\n\n getRotation: function () {\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\n return this.poseRotation;\n },\n\n getProjectionMatrix: function () {\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\n return this.projectionMatrix;\n },\n\n hitAR: (function () { \n // Temporary variables, only within closure scope.\n var transform = new THREE.Matrix4();\n var hitpoint = new THREE.Vector3();\n var hitquat = new THREE.Quaternion();\n var hitscale = new THREE.Vector3();\n var worldpos = new THREE.Vector3();\n \n // The desired function, which this returns.\n return function (x, y, el, raycasterEl) {\n if (!this.arDisplay) { return []; }\n var hitsToReturn = [];\n\n if (this.el.sceneEl.is('ar-mode')) {\n if (!this.viewerSpace) return;\n\n let frame = this.el.sceneEl.frame;\n let xrViewerPose = frame.getViewerPose(this.refSpace);\n\n if (this.xrHitTestSource && xrViewerPose) {\n let hitTestResults = frame.getHitTestResults(this.xrHitTestSource);\n\n // Process AR hits.\n var hitsToReturn = [];\n for (var i = 0; hitTestResults && i < hitTestResults.length; i++) {\n let pose = hitTestResults[i].getPose(this.refSpace);\n transform.fromArray(pose.transform.matrix);\n hitpoint.setFromMatrixPosition(transform); //transform.decompose(hitpoint, hitquat, hitscale);\n raycasterEl.object3D.getWorldPosition(worldpos);\n\n hitsToReturn.push({\n distance: hitpoint.distanceTo(worldpos),\n point: hitpoint.clone(), // Vector3\n object: (el && el.object3D) || this.el.sceneEl.object3D\n/*\n // We don't have any of these properties...\n face: undefined, // Face3\n faceIndex: undefined,\n index: undefined,\n uv: undefined // Vector2\n*/\n });\n }\n }\n }\n\n return hitsToReturn;\n }\n })(),\n\n // Link to image marker and anchor support.\n\n addImage: function (name, url, physicalWidth) {\n if (!this.arDisplay) { return null; }\n\n return null;\n },\n\n removeImage: function (name) {\n if (!this.arDisplay) { return null; }\n\n return null;\n },\n\n getAnchors: function () {\n return Array.from(this.anchors_.values());\n },\n\n // Use planes to do synchronous hit test.\n\n getPlanes: function () {\n return Array.from(this.planes_.values());\n }\n});\n","/* global AFRAME, THREE */\n\nfunction convertVertices(vertices) {\n var verticesLength = vertices.length;\n var newVertices = new Float32Array(verticesLength * 3);\n var i = 0;\n var j = 0;\n var vertex;\n for (i = 0; i < verticesLength; i++) {\n vertex = vertices[i];\n newVertices[j] = vertex.x;\n newVertices[j + 1] = vertex.y;\n newVertices[j + 2] = vertex.z;\n j += 3;\n }\n return newVertices;\n}\n\n\nfunction encode(buffer) {\nvar base64 = ''\nvar encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\n\nvar bytes = buffer; // assume it's a typedArrayBuffer \n \nif (buffer instanceof ArrayBuffer) {\nbytes = new Uint8Array(arrayBuffer)\n} else if (buffer instanceof ImageData) {\nbytes = buffer.data\n}\n\nvar byteLength = buffer.length\nvar byteRemainder = byteLength % 3\nvar mainLength = byteLength - byteRemainder\n\nvar a, b, c, d\nvar chunk\n\n// Main loop deals with bytes in chunks of 3\nfor (var i = 0; i < mainLength; i = i + 3) {\n// Combine the three bytes into a single integer\nchunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]\n\n// Use bitmasks to extract 6-bit segments from the triplet\na = (chunk & 16515072) >> 18 // 16515072 = (2^6 - 1) << 18\nb = (chunk & 258048) >> 12 // 258048 = (2^6 - 1) << 12\nc = (chunk & 4032) >> 6 // 4032 = (2^6 - 1) << 6\nd = chunk & 63 // 63 = 2^6 - 1\n\n// Convert the raw binary segments to the appropriate ASCII encoding\nbase64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]\n}\n\n// Deal with the remaining bytes and padding\nif (byteRemainder == 1) {\nchunk = bytes[mainLength]\n\na = (chunk & 252) >> 2 // 252 = (2^6 - 1) << 2\n\n// Set the 4 least significant bits to zero\nb = (chunk & 3) << 4 // 3 = 2^2 - 1\n\nbase64 += encodings[a] + encodings[b] + '=='\n} else if (byteRemainder == 2) {\nchunk = (bytes[mainLength] << 8) | bytes[mainLength + 1]\n\na = (chunk & 64512) >> 10 // 64512 = (2^6 - 1) << 10\nb = (chunk & 1008) >> 4 // 1008 = (2^6 - 1) << 4\n\n// Set the 2 least significant bits to zero\nc = (chunk & 15) << 2 // 15 = 2^4 - 1\n\nbase64 += encodings[a] + encodings[b] + encodings[c] + '='\n}\n\nreturn base64\n}\n\n\n\n\n\nAFRAME.registerComponent('mozilla-xr-ar', {\n schema: {\n takeOverCamera: {default: true},\n cameraUserHeight: {default: false},\n worldSensing: {default: true}\n },\n\n init: function () {\n this.onInit = this.onInit.bind(this);\n this.onWatch = this.onWatch.bind(this);\n\n this.forceResize = this.forceResize.bind(this);\n\n this.poseMatrix = new THREE.Matrix4();\n this.posePosition = new THREE.Vector3();\n this.poseQuaternion = new THREE.Quaternion();\n this.poseEuler = new THREE.Euler(0, 0, 0, 'YXZ');\n this.poseRotation = new THREE.Vector3();\n this.projectionMatrix = new THREE.Matrix4();\n this.viewMatrix = new THREE.Matrix4();\n\n this.onceSceneLoaded = this.onceSceneLoaded.bind(this);\n if (this.el.sceneEl.hasLoaded) {\n setTimeout(this.onceSceneLoaded);\n } else {\n this.el.sceneEl.addEventListener('loaded', this.onceSceneLoaded);\n }\n\n // Add planes handling, so we can do synchronous hit test.\n // From google-ar/WebARonARKit; also see webxr-polyfill/ARKitWrapper.js\n\n this.planes_ = new Map();\n this.anchors_ = new Map();\n },\n\n // For WebXR Viewer, we are currently directly hooking the callback\n // used to provide frame data, so we don't need to do anything in tick!\n\n takeOverCamera: function (camera) {\n this.arCamera = camera;\n camera.el.setAttribute('ar-camera', 'enabled', true);\n },\n\n onceSceneLoaded: function () {\n // Check if the low-level WebXR Viewer interfaces are there.\n if (!window.webkit || !window.webkit.messageHandlers) { return; }\n if (!window.webkit.messageHandlers.initAR) { return; }\n\n window['arkitCallback' + 0] = this.onInit;\n window['arkitCallback' + 1] = this.onWatch;\n\n // Compose data to use with initAR.\n var data = {\n options: {\n ui: {\n browser: true,\n points: true,\n focus: false,\n rec: true,\n rec_time: true,\n mic: false,\n build: false,\n plane: true,\n warnings: true,\n anchors: false,\n debug: true,\n statistics: false\n }\n },\n callback: 'arkitCallback0' // this.onInit as window callback\n };\n\n // Need these because WebXR Viewer...\n //if (window['setNativeTime']) {\n // console.log('window handler already defined for ', 'setNativeTime');\n //} else\n window['setNativeTime'] = function (data) {\n window.nativeTime = data.nativeTime;\n };\n [\n 'arkitStartRecording',\n 'arkitStopRecording',\n 'arkitDidMoveBackground',\n 'arkitWillEnterForeground',\n 'arkitInterrupted',\n 'arkitInterruptionEnded',\n 'arkitShowDebug',\n // elsewhere... 'arkitWindowResize',\n 'onError',\n 'arTrackingChanged',\n 'ios_did_receive_memory_warning',\n 'onComputerVisionData',\n // above... 'setNativeTime',\n 'userGrantedComputerVisionData',\n 'userGrantedWorldSensingData', // Needed for world sensing.\n ].forEach(function (eventName) {\n //if (window[eventName]) {\n // console.log('window handler already defined for ', eventName);\n //} else\n window[eventName] = function (data) {\n console.log(eventName + ':', data);\n };\n });\n\n // act like Chrome WebXR by forcibly showing AR button and making it work\n var vrmodeui = this.el.sceneEl.components['vr-mode-ui'];\n var newarbutton = vrmodeui.enterAREl.cloneNode(true);\n vrmodeui.enterAREl.parentNode.replaceChild(newarbutton, vrmodeui.enterAREl);\n vrmodeui.enterAREl = newarbutton;\n vrmodeui.enterAREl.classList.remove('a-hidden');\n var self = this;\n vrmodeui.enterAREl.onclick = function() {\n var scene = AFRAME.scenes[0];\n\n // Note we're in AR mode (the way WebXR handling does).\n scene.addState('ar-mode');\n\n // Kill the Cardboard display that gets in our way.\n scene.components['vr-mode-ui'].orientationModalEl.style='display:none!important';\n\n // Fake VR mode from enterVRSuccess.\n scene.addState('vr-mode');\n scene.emit('enter-vr', {target: scene});\n\n // Call initAR.\n window.webkit.messageHandlers.initAR.postMessage(data);\n \n // Kill broken wakelock!\n scene.wakelock.release();\n\n // Take over the scene camera, if so directed.\n // But wait a tick, because otherwise injected camera will not be present.\n if (self.data.takeOverCamera) {\n setTimeout(function () { self.takeOverCamera(scene.camera); });\n }\n\n let sz = new THREE.Vector2();\n let pixelRatio = scene.renderer.getPixelRatio();\n scene.renderer.getSize(sz);\n console.log(\"pixelRatio \", pixelRatio, \" size \", sz);\n\n // Ugly hack to get around WebXR Viewer resizing issue.\n scene.canvas.style.position = \"absolute !important\";\n scene.canvas.style.width = \"100% !important\";\n scene.canvas.style.height = \"100% !important\";\n\n // Force resize after we have access to data (?!)\n window.userGrantedWorldSensingData = function(data) {\n console.log('userGrantedWorldSensingData:', data);\n setTimeout(function () {\n self.forceResize(\n screen.width * window.devicePixelRatio,\n screen.height * window.devicePixelRatio);\n }, 100); // 1000 seems to be long enough initially\n };\n };\n },\n\n forceResize: function (sx, sy) {\n var sc = this.el.sceneEl, self = this;\n console.log('forceResize ', sx, sy,\n ' was ', \n sc.canvas.width, sc.canvas.height, \n screen.width, screen.height,\n window.devicePixelRatio, sc.renderer.getPixelRatio());\n sx = sx || this.forceResizeX; this.forceResizeX = sx;\n sy = sy || this.forceResizeY; this.forceResizeY = sy;\n sc.canvas.setAttribute('width', sx);\n sc.canvas.setAttribute('height', sy);\n sc.camera.aspect = sx / sy;\n sc.camera.projectionMatrix.copy(self.projectionMatrix);\n sc.renderer.setPixelRatio(1);\n sc.renderer.setSize(sx, sy, false);\n sc.emit('rendererresize', null, false);\n },\n\n checkForARDisplay: function () {\n // Check if the low-level WebXR Viewer interfaces are there.\n if (!window.webkit || !window.webkit.messageHandlers) { return; }\n if (!window.webkit.messageHandlers.watchAR) { return; }\n\n // Mozilla WebXR Viewer detected.\n var self = this;\n self.arDisplay = true;\n\n\n // Compose data to use with watchAR.\n var data = {\n options: {\n location: true,\n camera: true,\n objects: true,\n light_intensity: true,\n worldSensing: this.data.worldSensing\n },\n callback: 'arkitCallback1' // this.onWatch as window callback\n };\n\n // Add resize handling.\n window['arkitWindowResize'] = function (data) {\n console.log('arkitWindowResize' + ':', data);\n\n // we're faking being in vr-mode anyway so resize will exit.\n //window.emit('resize', {target: window});\n\n // on iOS, AFRAME waits 100ms... \n setTimeout(function () {\n self.forceResize(\n data.width * window.devicePixelRatio,\n data.height * window.devicePixelRatio);\n }, 150); // 250 seems to be long enough\n };\n\n // Start watching AR.\n window.webkit.messageHandlers.watchAR.postMessage(data);\n },\n\n onInit: function (deviceId) {\n this.checkForARDisplay();\n },\n\n onWatch: function (data) {\n this.frameData = data;\n this.handleFrame(data);\n },\n\n handleFrame: function (data) {\n // Decompose to get camera pose.\n this.poseMatrix.fromArray(data.camera_transform);\n this.poseMatrix.decompose(this.posePosition, this.poseQuaternion, this.poseRotation); // poseRotation is really scale, we redo below\n this.poseEuler.setFromQuaternion(this.poseQuaternion);\n this.poseRotation.set(\n THREE.Math.RAD2DEG * this.poseEuler.x,\n THREE.Math.RAD2DEG * this.poseEuler.y,\n THREE.Math.RAD2DEG * this.poseEuler.z);\n\n this.projectionMatrix.fromArray(data.projection_camera);\n this.viewMatrix.fromArray(data.camera_view);\n\n // If we control a camera, and should apply user height, do it.\n if (this.arCamera && this.data.cameraUserHeight) {\n this.posePosition.y += this.arCamera.el.components.camera.data.userHeight;\n }\n\n // For A-Painter, detect bogus pose and fire poseFound / poseLost.\n var poseValid = this.posePosition.x || this.posePosition.y || this.posePosition.z || this.poseQuaternion.x || this.poseQuaternion.y || this.poseQuaternion.z;\n if (poseValid) {\n if (this.poseLost !== false) {\n this.poseLost = false;\n this.el.emit('poseFound');\n }\n } else {\n if (this.poseLost !== true) {\n this.poseLost = true;\n this.el.emit('poseLost', false);\n }\n }\n\n // Add planes handling, so we can do synchronous hit test.\n // From google-ar/WebARonARKit; also see webxr-polyfill/ARKitWrapper.js\n\n var i;\n var element;\n\n // WebXR Viewer returns geometry.vertices as an array of {x: number, y: number, y: number}\n // https://github.com/mozilla-mobile/webxr-ios/blob/c77b12c235e3960e2cd51538e086a38c83d8ec7c/XRViewer/ARKController/ARKController.m#L845\n // We transform this to a flatten array of number, like WebARonARCore.\n\n if(data.newObjects && data.newObjects.length){\n for (i = 0; i < data.newObjects.length; i++) {\n element = data.newObjects[i];\n if(element.plane_center){\n this.planes_.set(element.uuid, {\n id: element.uuid,\n center: element.plane_center,\n extent: [element.plane_extent.x, element.plane_extent.z],\n modelMatrix: element.transform,\n alignment: element.plane_alignment,\n vertices: convertVertices(element.geometry.vertices)\n });\n }else{\n var anchorData = {\n id: element.uuid,\n modelMatrix: element.transform\n };\n if (element.type === 'image') {\n anchorData.name = element.uuid;\n }\n this.anchors_.set(element.uuid, anchorData);\n }\n }\n }\n\n if(data.removedObjects && data.removedObjects.length){\n for (i = 0; i < data.removedObjects.length; i++) {\n element = data.removedObjects[i];\n if(this.planes_.get(element)){\n this.planes_.delete(element);\n }else{\n this.anchors_.delete(element);\n }\n }\n }\n\n if(data.objects && data.objects.length){\n for (i = 0; i < data.objects.length; i++) {\n element = data.objects[i];\n if(element.plane_center){\n var plane = this.planes_.get(element.uuid);\n if(!plane){\n this.planes_.set(element.uuid, {\n id: element.uuid,\n center: element.plane_center,\n extent: [element.plane_extent.x, element.plane_extent.z],\n modelMatrix: element.transform,\n alignment: element.plane_alignment,\n vertices: convertVertices(element.geometry.vertices)\n });\n } else {\n plane.center = element.plane_center;\n plane.extent = [element.plane_extent.x, element.plane_extent.z];\n plane.modelMatrix = element.transform;\n plane.alignment = element.plane_alignment;\n plane.vertices = convertVertices(element.geometry.vertices);\n }\n }else{\n var anchor = this.anchors_.get(element.uuid);\n if(!anchor){\n this.anchors_.set(element.uuid, {\n id: element.uuid,\n modelMatrix: element.transform\n });\n }else{\n anchor.modelMatrix = element.transform;\n }\n }\n }\n }\n },\n\n getPosition: function () {\n if (!this.arDisplay) { return null; }\n return this.posePosition;\n },\n\n getOrientation: function () {\n if (!this.arDisplay) { return null; }\n return this.poseQuaternion;\n },\n\n getRotation: function () {\n if (!this.arDisplay) { return null; }\n return this.poseRotation;\n },\n\n getProjectionMatrix: function () {\n if (!this.arDisplay) { return null; }\n return this.projectionMatrix;\n },\n\n // Link to new ARKit image marker and anchor support.\n\n addImage: function (name, url, physicalWidth) {\n if (!this.arDisplay) { return null; }\n/*\nNSDictionary *imageAnchorInfoDictionary = [message body];\nNSString *createDetectionImageCallback = [[message body] objectForKey:WEB_AR_CALLBACK_OPTION];\n// callback\n\nCGFloat physicalWidth = [referenceImageDictionary[@\"physicalWidth\"] doubleValue];\nNSString* b64String = referenceImageDictionary[@\"buffer\"];\nsize_t width = (size_t) [referenceImageDictionary[@\"imageWidth\"] intValue];\nsize_t height = (size_t) [referenceImageDictionary[@\"imageHeight\"] intValue];\n...\nresult.name = referenceImageDictionary[@\"uid\"];\n*/\n // NOTE: looks like WebXR Viewer won't load from URL,\n // so we need to convert from img element\n var aCanvas = document.createElement('canvas');\n var aContext = aCanvas.getContext('2d');\n var aImg; // Don't use element; chance of changed width/height.\n if (!aImg) {\n aImg = document.createElement('img');\n aImg.crossOrigin = 'anonymous';\n aImg.src = url;\n document.body.appendChild(aImg);\n }\n\n // The image needs to be loaded...\n if (!aImg.complete || !aImg.naturalHeight) {\n console.log('!!! addImage: !aImg.complete || !aImg.naturalHeight, aborting');\n return;\n } \n \n // The image needs to be have nonzero size...\n if (!aImg.width || !aImg.height) {\n console.log('!!! addImage: !aImg.width || !aImg.height, aborting');\n return;\n } \n\n aCanvas.width = aImg.width;\n aCanvas.height = aImg.height;\n aContext.drawImage(aImg, 0, 0);\n var aImageData = aContext.getImageData(0, 0, aImg.width, aImg.height);\n var b64ImageData = encode(aImageData.data);\n if (!b64ImageData) {\n console.log('!!! addImage: !b64ImageData, aborting');\n return;\n }\n\n // NOTE: also, WebXR Viewer doesn't pass back which image/name,\n // so we need a per-image/name callback\n window.callbackForCreateImageAnchorCounter = (window.callbackForCreateImageAnchorCounter || 0) + 1;\n var callbackName = 'callbackForCreateImageAnchor_' + window.callbackForCreateImageAnchorCounter;\n var imageName = name;\n //console.log('creating ', callbackName, ' for ', imageName);\n window[callbackName] = function (data) {\n //console.log(callbackName);\n //console.log(data);\n //var name = callbackName.substring(29);\n if (data.created !== undefined) {\n if (!data.created) {\n // we failed to create the image, for whatever reason.\n console.log('addImage: !created; ', data.error);\n delete window[callbackName];\n } else {\n //console.log('addImage: created, activating ', imageName);\n window.webkit.messageHandlers.activateDetectionImage.postMessage({\n callback: callbackName,\n uid: imageName\n });\n }\n } else\n if (data.activated !== undefined) {\n if (!data.activated) {\n // we failed to activate the image, for whatever reason.\n console.log('addImage: !activated; ', data.error);\n } else {\n //console.log('addImage: activated ', imageName);\n }\n delete window[callbackName];\n }\n };\n\n window.webkit.messageHandlers.createImageAnchor.postMessage({\n callback: callbackName,\n uid: name,\n buffer: b64ImageData,\n imageWidth: aImg.width,\n imageHeight: aImg.height,\n physicalWidth: physicalWidth // in meters\n });\n },\n\n removeImage: function (name) {\n if (!this.arDisplay) { return null; }\n/*\nNSDictionary *imageAnchorInfoDictionary = [message body];\nNSString *imageName = imageAnchorInfoDictionary[WEB_AR_DETECTION_IMAGE_NAME_OPTION];\n// detectionImageName\nNSString *deactivateDetectionImageCallback = [[message body] objectForKey:WEB_AR_CALLBACK_OPTION];\n// callback\n*/\n window.callbackForRemoveImageAnchorCounter = (window.callbackForRemoveImageAnchorCounter || 0) + 1;\n var callbackName = 'callbackForRemoveImageAnchor_' + window.callbackForRemoveImageAnchorCounter;\n var imageName = name;\n //console.log('creating ', callbackName, ' for ', imageName);\n window[callbackName] = function (data) {\n //console.log(callbackName);\n //console.log(data);\n\n if (data.deactivated !== undefined) {\n if (!data.deactivated) {\n console.log('!!! ' + callbackName + ': !deactivated', data.error);\n delete window[callbackName];\n } else {\n //console.log(callbackName + ': deactivated, destroying', imageName);\n }\n window.webkit.messageHandlers.destroyDetectionImage.postMessage({\n callback: callbackName,\n uid: imageName\n });\n }\n if (data.destroyed !== undefined) {\n if (!data.destroyed) {\n console.log('!!! ' + callbackName + ': !destroyed, ', data.error);\n } else {\n //console.log(callbackName + ': destroyed', imageName);\n }\n delete window[callbackName];\n }\n };\n\n window.webkit.messageHandlers.deactivateDetectionImage.postMessage({\n callback: callbackName,\n uid: imageName\n });\n },\n\n getAnchors: function () {\n return Array.from(this.anchors_.values());\n },\n\n // Use planes to do synchronous hit test.\n // From google-ar/WebARonARKit; also see webxr-polyfill/ARKitWrapper.js\n\n getPlanes: function () {\n return Array.from(this.planes_.values());\n },\n\n hitTestNoAnchor: (function () {\n // Temporary variables, only within closure scope.\n\n /**\n * The result of a raycast into the AR world encoded as a transform matrix.\n * This structure has a single property - modelMatrix - which encodes the\n * translation of the intersection of the hit in the form of a 4x4 matrix.\n * @constructor\n */\n function VRHit() {\n this.modelMatrix = new Float32Array(16);\n return this;\n };\n\n /**\n * Cached vec3, mat4, and quat structures needed for the hit testing to\n * avoid generating garbage.\n * @type {Object}\n */\n var hitVars = {\n rayStart: new THREE.Vector3(), //vec3.create(),\n rayEnd: new THREE.Vector3(), //vec3.create(),\n cameraPosition: new THREE.Vector3(), //vec3.create(),\n cameraQuaternion: new THREE.Quaternion(), //quat.create(),\t\n //modelViewMatrix: new THREE.Matrix4(), //mat4.create(),\n //projectionMatrix: new THREE.Matrix4(), //mat4.create(),\n projViewMatrix: new THREE.Matrix4(), //mat4.create(),\n worldRayStart: new THREE.Vector3(), //vec3.create(),\n worldRayEnd: new THREE.Vector3(), //vec3.create(),\n worldRayDir: new THREE.Vector3(), //vec3.create(),\n planeMatrix: new THREE.Matrix4(), //mat4.create(),\n planeMatrixInverse: new THREE.Matrix4(), //mat4.create(),\n planeExtent: new THREE.Vector3(), //vec3.create(),\n planePosition: new THREE.Vector3(), //vec3.create(),\n planeCenter: new THREE.Vector3(), //vec3.create(),\n planeNormal: new THREE.Vector3(), //vec3.create(),\n planeIntersection: new THREE.Vector3(), //vec3.create(),\n planeIntersectionLocal: new THREE.Vector3(), //vec3.create(),\n planeHit: new THREE.Matrix4(), //mat4.create()\n planeQuaternion: new THREE.Quaternion() // quat.create()\n };\n \n /**\n * Tests whether the given ray intersects the given plane.\n *\n * @param {!vec3} planeNormal The normal of the plane.\n * @param {!vec3} planePosition Any point on the plane.\n * @param {!vec3} rayOrigin The origin of the ray.\n * @param {!vec3} rayDirection The direction of the ray (normalized).\n * @return {number} The t-value of the intersection (-1 for none).\n */\n var rayIntersectsPlane = (function() {\n var rayToPlane = new THREE.Vector3();\n return function(planeNormal, planePosition, rayOrigin, rayDirection) {\n // assuming vectors are all normalized\n var denom = planeNormal.dot(rayDirection);\n rayToPlane.subVectors(planePosition, rayOrigin);\n return rayToPlane.dot(planeNormal) / denom;\n };\n })();\n \n /**\n * Sorts based on the distance from the VRHits to the camera.\n *\n * @param {!VRHit} a The first hit to compare.\n * @param {!VRHit} b The second hit item to compare.\n * @returns {number} -1 if a is closer than b, otherwise 1.\n */\n var sortFunction = function(a, b) {\n // Get the matrix of hit a.\n hitVars.planeMatrix.fromArray(a.modelMatrix);\n // Get the translation component of a's matrix.\n hitVars.planeIntersection.setFromMatrixPosition(hitVars.planeMatrix);\n // Get the distance from the intersection point to the camera.\n var distA = hitVars.planeIntersection.distanceTo(hitVars.cameraPosition);\n \n // Get the matrix of hit b.\n hitVars.planeMatrix.fromArray(b.modelMatrix);\n // Get the translation component of b's matrix.\n hitVars.planeIntersection.setFromMatrixPosition(hitVars.planeMatrix);\n // Get the distance from the intersection point to the camera.\n var distB = hitVars.planeIntersection.distanceTo(hitVars.cameraPosition);\n \n // Return comparison of distance from camera to a and b.\n return distA < distB ? -1 : 1;\n };\n \n return function(x, y) {\n // Coordinates must be in normalized screen space.\n if (x < 0 || x > 1 || y < 0 || y > 1) {\n throw new Error(\n \"hitTest - x and y values must be normalized [0,1]!\")\n ;\n }\n \n var hits = [];\n // If there are no anchors detected, there will be no hits.\n var planes = this.getPlanes();\n if (!planes || planes.length === 0) {\n return hits;\n }\n\n // Create a ray in screen space for the hit test ([-1, 1] with y flip).\n hitVars.rayStart.set(2 * x - 1, 2 * (1 - y) - 1, 0);\n hitVars.rayEnd.set(2 * x - 1, 2 * (1 - y) - 1, 1);\n\n // Set the projection matrix.\n //hitVars.projectionMatrix.fromArray(this.projectionMatrix);\n \n // Set the model view matrix.\n //hitVars.modelViewMatrix.fromArray(this.viewMatrix);\n \n // Combine the projection and model view matrices.\n hitVars.planeMatrix.multiplyMatrices(\n this.projectionMatrix, //hitVars.projectionMatrix,\n this.viewMatrix //hitVars.modelViewMatrix\n );\n // Invert the combined matrix because we need to go from screen -> world.\n hitVars.projViewMatrix.getInverse(hitVars.planeMatrix);\n \n // Transform the screen-space ray start and end to world-space.\n hitVars.worldRayStart.copy(hitVars.rayStart)\n .applyMatrix4(hitVars.projViewMatrix);\n hitVars.worldRayEnd.copy(hitVars.rayEnd)\n .applyMatrix4(hitVars.projViewMatrix);\n \n // Subtract start from end to get the ray direction and then normalize.\n hitVars.worldRayDir.subVectors(\n hitVars.worldRayEnd,\n hitVars.worldRayStart\n ).normalize();\n\n // Go through all the anchors and test for intersections with the ray.\n for (var i = 0; i < planes.length; i++) {\n var plane = planes[i];\n // Get the anchor transform.\n hitVars.planeMatrix.fromArray(plane.modelMatrix);\n \n // Get the position of the anchor in world-space.\n hitVars.planeCenter.set(plane.center.x, plane.center.y, plane.center.z);\n hitVars.planePosition.copy(hitVars.planeCenter)\n .applyMatrix4(hitVars.planeMatrix)\n\n hitVars.planeAlignment = plane.alignment\n \n // Get the plane normal.\n if (hitVars.planeAlignment === 0) {\n hitVars.planeNormal.set(0, 1, 0);\n } else {\n hitVars.planeNormal.set(hitVars.planeMatrix[4], hitVars.planeMatrix[5], hitVars.planeMatrix[6]);\n }\n \n // Check if the ray intersects the plane.\n var t = rayIntersectsPlane(\n hitVars.planeNormal,\n hitVars.planePosition,\n hitVars.worldRayStart,\n hitVars.worldRayDir\n );\n\n // if t < 0, there is no intersection.\n if (t < 0) {\n continue;\n }\n \n // Calculate the actual intersection point.\n hitVars.planeIntersectionLocal.copy(hitVars.worldRayDir).multiplyScalar(t);\n hitVars.planeIntersection.addVectors(\n hitVars.worldRayStart,\n hitVars.planeIntersectionLocal\n );\n // Get the plane extents (extents are in plane local space).\n hitVars.planeExtent.set(plane.extent[0], 0, plane.extent[1]);\n /*\n ///////////////////////////////////////////////\n // Test by converting extents to world-space.\n // TODO: get this working to avoid matrix inversion in method below.\n \n // Get the rotation component of the anchor transform.\n mat4.getRotation(hitVars.planeQuaternion, hitVars.planeMatrix);\n \n // Convert the extent into world space.\n vec3.transformQuat(\n hitVars.planeExtent, hitVars.planeExtent, hitVars.planeQuaternion);\n \n // Check if intersection is outside of the extent of the anchor.\n if (Math.abs(hitVars.planeIntersection[0] - hitVars.planePosition[0]) > hitVars.planeExtent[0] / 2) {\n continue;\n }\n if (Math.abs(hitVars.planeIntersection[2] - hitVars.planePosition[2]) > hitVars.planeExtent[2] / 2) {\n continue;\n }\n ////////////////////////////////////////////////\n */\n \n ////////////////////////////////////////////////\n // Test by converting intersection into plane-space.\n hitVars.planeMatrixInverse.getInverse(hitVars.planeMatrix);\n hitVars.planeIntersectionLocal.copy(hitVars.planeIntersection)\n .applyMatrix4(hitVars.planeMatrixInverse);\n \n // Check if intersection is outside of the extent of the anchor.\n // Tolerance is added to match the behavior of the native hitTest call.\n var tolerance = 0.0075;\n if (\n Math.abs(hitVars.planeIntersectionLocal.x) >\n hitVars.planeExtent.x / 2 + tolerance\n ) {\n continue;\n }\n if (\n Math.abs(hitVars.planeIntersectionLocal.z) >\n hitVars.planeExtent.z / 2 + tolerance\n ) {\n continue;\n }\n \n ////////////////////////////////////////////////\n \n // The intersection is valid - create a matrix from hit position.\n hitVars.planeQuaternion.setFromRotationMatrix(hitVars.planeMatrix);\n hitVars.planeHit.makeRotationFromQuaternion(hitVars.planeQuaternion).setPosition(hitVars.planeIntersection);\n var hit = new VRHit();\n for (var j = 0; j < 16; j++) {\n hit.modelMatrix[j] = hitVars.planeHit.elements[j];\n }\n hit.i = i;\n hits.push(hit);\n }\n \n\n // Sort the hits by distance.\n hits.sort(sortFunction);\n return hits;\n };\n })(),\n\n hitAR: (function () {\n // Temporary variables, only within closure scope.\n var transform = new THREE.Matrix4();\n var hitpoint = new THREE.Vector3();\n var hitquat = new THREE.Quaternion();\n var hitscale = new THREE.Vector3();\n var worldpos = new THREE.Vector3();\n\n // The desired function, which this returns.\n return function (x, y, el, raycasterEl) {\n if (!this.arDisplay) { return []; }\n\n var hit = this.hitTestNoAnchor(x, y);\n\n // Process AR hits.\n var hitsToReturn = [];\n for (var i = 0; hit && i < hit.length; i++) {\n transform.fromArray(hit[i].modelMatrix);\n transform.decompose(hitpoint, hitquat, hitscale);\n raycasterEl.object3D.getWorldPosition(worldpos);\n\n hitsToReturn.push({\n distance: hitpoint.distanceTo(worldpos),\n point: hitpoint.clone(), // Vector3\n object: (el && el.object3D) || this.el.sceneEl.object3D\n/*\n // We don't have any of these properties...\n face: undefined, // Face3\n faceIndex: undefined,\n index: undefined,\n uv: undefined // Vector2\n*/\n });\n }\n return hitsToReturn;\n } \n })()\n});\n","/* global AFRAME, THREE */\n\nAFRAME.registerComponent('ar-planes', {\n\n getPlaneSource: function () {\n var whichar;\n if (!this.planeSource) {\n whichar = this.el.sceneEl.components['ar'];\n if (whichar) {\n this.planeSource = whichar.getSource();\n }\n }\n return this.planeSource;\n },\n\n getPlanes: function () {\n var planeSource = this.getPlaneSource();\n if (!planeSource || !planeSource.getPlanes) return undefined;\n return planeSource.getPlanes();\n },\n\n init: function () {\n // Remember planes when we see them.\n this.planes = {};\n this.anchorsAdded = [];\n this.anchorsAddedDetail = {type:'added', anchors: this.anchorsAdded};\n this.anchorsUpdated = [];\n this.anchorsUpdatedDetail = {type:'updated', anchors: this.anchorsUpdated};\n this.anchorsRemoved = [];\n this.anchorsRemovedDetail = {type:'removed', anchors: this.anchorsRemoved};\n },\n\n tick: (function (t, dt) {\n // Create the temporary variables we will reuse, if needed.\n var tempScale = new THREE.Vector3(1, 1, 1);\n var tempMat4 = new THREE.Matrix4();\n var tempPosition = new THREE.Vector3();\n var tempQuaternion = new THREE.Quaternion();\n\n // The actual function, which we return.\n return function (t, dt) {\n // Get the list of planes.\n var planes = this.getPlanes();\n if (!planes) { return; }\n\n // Ideally we would have either events, or separate lists for added / updated / removed.\n var addedThese = [];\n var updatedThese = [];\n var removedThese = [];\n\n // Because we don't have an indication of added / updated / removed,\n // try to keep track ourselves.\n var seenThese = {};\n var i;\n\n // Iterate over the available planes.\n for (i=0; planes && i 0) {\n // Reuse the same event detail to avoid making garbage.\n // TODO: Reuse same CustomEvent?\n this.anchorsAddedDetail.anchors = addedThese;\n this.el.emit('anchorsadded', this.anchorsAddedDetail);\n }\n\n // Replace the old list.\n this.anchorsUpdated = updatedThese;\n // Emit event if list isn't empty.\n if (updatedThese.length > 0) {\n // Reuse the same event detail to avoid making garbage.\n // TODO: Reuse same CustomEvent?\n this.anchorsUpdatedDetail.anchors = updatedThese;\n this.el.emit('anchorsupdated', this.anchorsUpdatedDetail);\n }\n\n // Replace the old list.\n this.anchorsRemoved = removedThese;\n // Emit event if list isn't empty.\n if (removedThese.length > 0) {\n // Reuse the same event detail to avoid making garbage.\n // TODO: Reuse same CustomEvent?\n this.anchorsRemovedDetail.anchors = removedThese;\n this.el.emit('anchorsremoved', this.anchorsRemovedDetail);\n }\n }; \n })()\n});\n","/* global AFRAME, THREE */\n\nAFRAME.registerComponent('ar-anchors', {\n\n getSource: function () {\n var whichar;\n if (!this.source) {\n whichar = this.el.sceneEl.components['ar'];\n if (whichar) {\n this.source = whichar.getSource();\n }\n }\n return this.source;\n },\n\n getAnchors: function () {\n var source = this.getSource();\n if (!source || !source.getAnchors) return undefined;\n return source.getAnchors();\n }\n});\n","/* global AFRAME, THREE */\n\nAFRAME.registerComponent('ar-images', {\n\n getSource: function () {\n var whichar;\n if (!this.source) {\n whichar = this.el.sceneEl.components['ar'];\n if (whichar) {\n this.source = whichar.getSource();\n }\n }\n return this.source;\n },\n\n addImage: function (name, url, physicalWidth) {\n var source = this.getSource();\n if (!source || !source.addImage) return undefined;\n return source.addImage(name, url, physicalWidth);\n },\n\n removeImage: function (name) {\n var source = this.getSource();\n if (!source || !source.removeImage) return undefined;\n return source.removeImage(name);\n },\n\n});\n","/* global AFRAME */\n\nAFRAME.registerComponent('ar', {\n schema: {\n takeOverCamera: {default: true},\n cameraUserHeight: {default: false},\n worldSensing: {default: true},\n hideUI: {default: false}\n },\n dependencies: ['webxr-ar', 'mozilla-xr-ar', 'ar-planes', 'ar-anchors'],\n getSource: function () {\n var whichar;\n if (!this.source) {\n var self = this;\n self.dependencies.forEach(function(sys) {\n whichar = self.el.sceneEl.components[sys];\n if (whichar && whichar.arDisplay) {\n self.source = whichar;\n }\n });\t\n }\n return this.source;\n },\n getPlanes: function () {\n return this.source ? this.source.getPlanes() : undefined;\n },\n getAnchors: function () {\n return this.source ? this.source.getAnchors() : undefined;\n },\n addImage: function (name, url, physicalWidth) {\n return this.source.addImage(name, url, physicalWidth);\n },\n removeImage: function (name) {\n return this.source.removeImage(name);\n },\n init: function () {\n var options = {\n takeOverCamera: this.data.takeOverCamera,\n cameraUserHeight: this.data.cameraUserHeight,\n worldSensing: this.data.worldSensing\n };\n\n var self = this;\n this.dependencies.forEach(function(sys) {\n self.el.setAttribute(sys, options);\n });\n\n if (this.data.hideUI) {\n this.el.sceneEl.setAttribute('vr-mode-ui', {enabled: false});\n }\n\n // Ensure passthrough is visible, make sure A-Frame styles don't interfere.\n document.head.insertAdjacentHTML('beforeend', \n '');\n }\n});\n","/* global AFRAME */\n\nAFRAME.registerComponent('ar-camera', {\n schema: {\n enabled: {default:true}\n },\n\n init: function () {\n var lookControls = this.el.getAttribute('look-controls');\n this.wasLookControlsEnabled = lookControls ? lookControls.enabled : false;\n },\n\n update: function (oldData) {\n if (!oldData || oldData.enabled !== this.data.enabled) {\n // Value changed, so react accordingly.\n if (this.data.enabled) {\n // Save camera look-controls enabled, and turn off for AR.\n var lookControls = this.el.getAttribute('look-controls');\n this.wasLookControlsEnabled = lookControls ? lookControls.enabled : false;\n if (this.wasLookControlsEnabled) {\n this.el.setAttribute('look-controls', 'enabled', false);\n }\n } else {\n // Restore camera look-controls enabled.\n if (this.wasLookControlsEnabled) {\n this.el.setAttribute('look-controls', 'enabled', true);\n }\n }\n }\n },\n \n tick: function (t, dt) {\n if (!this.data.enabled) { return; }\n \n var whichar = this.checkWhichAR();\n if (!whichar) { return; }\n \n // Apply the pose position via setAttribute,\n // so that other A-Frame components can see the values.\n var pos = whichar.getPosition();\n if (pos) { this.el.setAttribute('position', pos); }\n\n // Apply the pose rotation via setAttribute,\n // so that other A-Frame components can see the values.\n var rot = whichar.getRotation();\n if (rot) { this.el.setAttribute('rotation', rot); }\n\n // Apply the projection matrix, if we're not in VR.\n if (!this.el.sceneEl.is('vr-mode')) {\n var matrix = whichar.getProjectionMatrix();\n if (matrix) { this.el.components.camera.camera.projectionMatrix = matrix; }\n } \n },\n \n checkWhichAR: function () {\n if (!this.whichar) {\n var whichar = this.el.sceneEl.components['ar'].getSource();\n if (!whichar || !whichar.arDisplay) { return; }\n this.whichar = whichar;\n }\n return this.whichar;\n } \n});\n","/* global AFRAME */\n\n// ar-raycaster modifies raycaster to append AR hit, if any.\n// But note that current AR hit API does not support orientation as input.\nAFRAME.registerComponent('ar-raycaster', { \n dependencies: ['raycaster'],\n \n schema: {\n x: {default: 0.5},\n y: {default: 0.5},\n el: {type: 'selector'}\n },\n \n init: function () {\n // HACK: monkey-patch raycaster to append AR hit result\n this.raycaster = this.el.components['raycaster'].raycaster;\n this.raycasterIntersectObjects = this.raycaster.intersectObjects.bind(this.raycaster);\n this.raycaster.intersectObjects = this.intersectObjects.bind(this);\n },\n \n update: function (oldData) {\n if (!this.data.el) {\n // If not given some other element, return hit against the scene.\n // HACK: But that means we need its object3D to have an el.\n if (!this.el.sceneEl.object3D.el) {\n this.el.sceneEl.object3D.el = this.el.sceneEl;\n }\n }\n },\n \n intersectObjects: function (objects, recursive, rawIntersections) {\n // it appears that intersectObjects is now returning in rawIntersections\n var results = this.raycasterIntersectObjects(objects, recursive, rawIntersections);\n // Tack on AR hit result, if any.\n var hitARResults = this.hitAR();\n if (hitARResults && hitARResults.length) {\n if (rawIntersections) {\n hitARResults.forEach((hit) => rawIntersections.push(hit));\n results = rawIntersections;\n } else {\n hitARResults.forEach((hit) => results.push(hit));\n }\n }\n return results;\n }, \n \n hitAR: function () {\n var whichar = this.checkWhichAR();\n if (!whichar || !whichar.arDisplay) { return []; }\n var x = this.data.x;\n var y = this.data.y;\n if (arguments.length >= 2) {\n x = arguments[0];\n y = arguments[1];\n }\n return whichar.hitAR(x, y, this.data.el, this.el);\n },\n\n checkWhichAR: function () {\n if (!this.whichar) {\n var whichar = this.el.sceneEl.components['ar'];\n if (whichar) { whichar = whichar.getSource ? whichar.getSource() : undefined; }\n if (!whichar || !whichar.arDisplay) { return; }\n this.whichar = whichar;\n }\n return this.whichar;\n } \n});\n\n"],"sourceRoot":""} \ No newline at end of file diff --git a/src/mozilla-xr-ar.js b/src/mozilla-xr-ar.js index 6f71aef..302d805 100644 --- a/src/mozilla-xr-ar.js +++ b/src/mozilla-xr-ar.js @@ -249,8 +249,10 @@ AFRAME.registerComponent('mozilla-xr-ar', { sy = sy || this.forceResizeY; this.forceResizeY = sy; sc.canvas.setAttribute('width', sx); sc.canvas.setAttribute('height', sy); - sc.renderer.setPixelRatio(1); + sc.camera.aspect = sx / sy; sc.camera.projectionMatrix.copy(self.projectionMatrix); + sc.renderer.setPixelRatio(1); + sc.renderer.setSize(sx, sy, false); sc.emit('rendererresize', null, false); },