{"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;;;;AAIA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,sBAAsB,0BAA0B,GAAG;AACvF,WAAW;AACX;AACA;AACA;;AAEA;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;;AAEA;AACA;AACA;AACA,6DAA6D;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;;AAET;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;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,qCAAqC;AACrC,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA,+DAA+D,QAAQ;AACvE,qDAAqD,QAAQ;;AAE7D;AACA,wEAAwE,QAAQ;;AAEhF;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;;;;;;;;;;;;ACv5BD;;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 */\r\n\r\nAFRAME.registerComponent('ar-anchors', {\r\n\r\n getSource: function () {\r\n var whichar;\r\n if (!this.source) {\r\n whichar = this.el.sceneEl.components['ar'];\r\n if (whichar) {\r\n this.source = whichar.getSource();\r\n }\r\n }\r\n return this.source;\r\n },\r\n\r\n getAnchors: function () {\r\n var source = this.getSource();\r\n if (!source || !source.getAnchors) return undefined;\r\n return source.getAnchors();\r\n }\r\n});\r\n","/* global AFRAME */\r\n\r\nAFRAME.registerComponent('ar-camera', {\r\n schema: {\r\n enabled: {default:true}\r\n },\r\n\r\n init: function () {\r\n var lookControls = this.el.getAttribute('look-controls');\r\n this.wasLookControlsEnabled = lookControls ? lookControls.enabled : false;\r\n },\r\n\r\n update: function (oldData) {\r\n if (!oldData || oldData.enabled !== this.data.enabled) {\r\n // Value changed, so react accordingly.\r\n if (this.data.enabled) {\r\n // Save camera look-controls enabled, and turn off for AR.\r\n var lookControls = this.el.getAttribute('look-controls');\r\n this.wasLookControlsEnabled = lookControls ? lookControls.enabled : false;\r\n if (this.wasLookControlsEnabled) {\r\n this.el.setAttribute('look-controls', 'enabled', false);\r\n }\r\n } else {\r\n // Restore camera look-controls enabled.\r\n if (this.wasLookControlsEnabled) {\r\n this.el.setAttribute('look-controls', 'enabled', true);\r\n }\r\n }\r\n }\r\n },\r\n \r\n tick: function (t, dt) {\r\n if (!this.data.enabled) { return; }\r\n \r\n var whichar = this.checkWhichAR();\r\n if (!whichar) { return; }\r\n \r\n // Apply the pose position via setAttribute,\r\n // so that other A-Frame components can see the values.\r\n var pos = whichar.getPosition();\r\n if (pos) { this.el.setAttribute('position', pos); }\r\n\r\n // Apply the pose rotation via setAttribute,\r\n // so that other A-Frame components can see the values.\r\n var rot = whichar.getRotation();\r\n if (rot) { this.el.setAttribute('rotation', rot); }\r\n\r\n // Apply the projection matrix, if we're not in VR.\r\n if (!this.el.sceneEl.is('vr-mode')) {\r\n var matrix = whichar.getProjectionMatrix();\r\n if (matrix) { this.el.components.camera.camera.projectionMatrix = matrix; }\r\n } \r\n },\r\n \r\n checkWhichAR: function () {\r\n if (!this.whichar) {\r\n var whichar = this.el.sceneEl.components['ar'].getSource();\r\n if (!whichar || !whichar.arDisplay) { return; }\r\n this.whichar = whichar;\r\n }\r\n return this.whichar;\r\n } \r\n});\r\n","/* global AFRAME, THREE */\r\n\r\nAFRAME.registerComponent('ar-images', {\r\n\r\n getSource: function () {\r\n var whichar;\r\n if (!this.source) {\r\n whichar = this.el.sceneEl.components['ar'];\r\n if (whichar) {\r\n this.source = whichar.getSource();\r\n }\r\n }\r\n return this.source;\r\n },\r\n\r\n addImage: function (name, url, physicalWidth) {\r\n var source = this.getSource();\r\n if (!source || !source.addImage) return undefined;\r\n return source.addImage(name, url, physicalWidth);\r\n },\r\n\r\n removeImage: function (name) {\r\n var source = this.getSource();\r\n if (!source || !source.removeImage) return undefined;\r\n return source.removeImage(name);\r\n },\r\n\r\n});\r\n","/* global AFRAME, THREE */\r\n\r\nAFRAME.registerComponent('ar-planes', {\r\n\r\n getPlaneSource: function () {\r\n var whichar;\r\n if (!this.planeSource) {\r\n whichar = this.el.sceneEl.components['ar'];\r\n if (whichar) {\r\n this.planeSource = whichar.getSource();\r\n }\r\n }\r\n return this.planeSource;\r\n },\r\n\r\n getPlanes: function () {\r\n var planeSource = this.getPlaneSource();\r\n if (!planeSource || !planeSource.getPlanes) return undefined;\r\n return planeSource.getPlanes();\r\n },\r\n\r\n init: function () {\r\n // Remember planes when we see them.\r\n this.planes = {};\r\n this.anchorsAdded = [];\r\n this.anchorsAddedDetail = {type:'added', anchors: this.anchorsAdded};\r\n this.anchorsUpdated = [];\r\n this.anchorsUpdatedDetail = {type:'updated', anchors: this.anchorsUpdated};\r\n this.anchorsRemoved = [];\r\n this.anchorsRemovedDetail = {type:'removed', anchors: this.anchorsRemoved};\r\n },\r\n\r\n tick: (function (t, dt) {\r\n // Create the temporary variables we will reuse, if needed.\r\n var tempScale = new THREE.Vector3(1, 1, 1);\r\n var tempMat4 = new THREE.Matrix4();\r\n var tempPosition = new THREE.Vector3();\r\n var tempQuaternion = new THREE.Quaternion();\r\n\r\n // The actual function, which we return.\r\n return function (t, dt) {\r\n // Get the list of planes.\r\n var planes = this.getPlanes();\r\n if (!planes) { return; }\r\n\r\n // Ideally we would have either events, or separate lists for added / updated / removed.\r\n var addedThese = [];\r\n var updatedThese = [];\r\n var removedThese = [];\r\n\r\n // Because we don't have an indication of added / updated / removed,\r\n // try to keep track ourselves.\r\n var seenThese = {};\r\n var i;\r\n\r\n // Iterate over the available planes.\r\n for (i=0; planes && i 0) {\r\n // Reuse the same event detail to avoid making garbage.\r\n // TODO: Reuse same CustomEvent?\r\n this.anchorsAddedDetail.anchors = addedThese;\r\n this.el.emit('anchorsadded', this.anchorsAddedDetail);\r\n }\r\n\r\n // Replace the old list.\r\n this.anchorsUpdated = updatedThese;\r\n // Emit event if list isn't empty.\r\n if (updatedThese.length > 0) {\r\n // Reuse the same event detail to avoid making garbage.\r\n // TODO: Reuse same CustomEvent?\r\n this.anchorsUpdatedDetail.anchors = updatedThese;\r\n this.el.emit('anchorsupdated', this.anchorsUpdatedDetail);\r\n }\r\n\r\n // Replace the old list.\r\n this.anchorsRemoved = removedThese;\r\n // Emit event if list isn't empty.\r\n if (removedThese.length > 0) {\r\n // Reuse the same event detail to avoid making garbage.\r\n // TODO: Reuse same CustomEvent?\r\n this.anchorsRemovedDetail.anchors = removedThese;\r\n this.el.emit('anchorsremoved', this.anchorsRemovedDetail);\r\n }\r\n }; \r\n })()\r\n});\r\n","/* global AFRAME */\r\n\r\n// ar-raycaster modifies raycaster to append AR hit, if any.\r\n// But note that current AR hit API does not support orientation as input.\r\nAFRAME.registerComponent('ar-raycaster', { \r\n dependencies: ['raycaster'],\r\n \r\n schema: {\r\n x: {default: 0.5},\r\n y: {default: 0.5},\r\n el: {type: 'selector'}\r\n },\r\n \r\n init: function () {\r\n // HACK: monkey-patch raycaster to append AR hit result\r\n this.raycaster = this.el.components['raycaster'].raycaster;\r\n this.raycasterIntersectObjects = this.raycaster.intersectObjects.bind(this.raycaster);\r\n this.raycaster.intersectObjects = this.intersectObjects.bind(this);\r\n },\r\n \r\n update: function (oldData) {\r\n if (!this.data.el) {\r\n // If not given some other element, return hit against the scene.\r\n // HACK: But that means we need its object3D to have an el.\r\n if (!this.el.sceneEl.object3D.el) {\r\n this.el.sceneEl.object3D.el = this.el.sceneEl;\r\n }\r\n }\r\n },\r\n \r\n intersectObjects: function (objects, recursive, rawIntersections) {\r\n // it appears that intersectObjects is now returning in rawIntersections\r\n var results = this.raycasterIntersectObjects(objects, recursive, rawIntersections);\r\n // Tack on AR hit result, if any.\r\n var hitARResults = this.hitAR();\r\n if (hitARResults && hitARResults.length) {\r\n if (rawIntersections) {\r\n hitARResults.forEach((hit) => rawIntersections.push(hit));\r\n results = rawIntersections;\r\n } else {\r\n hitARResults.forEach((hit) => results.push(hit));\r\n }\r\n }\r\n return results;\r\n }, \r\n \r\n hitAR: function () {\r\n var whichar = this.checkWhichAR();\r\n if (!whichar || !whichar.arDisplay) { return []; }\r\n var x = this.data.x;\r\n var y = this.data.y;\r\n if (arguments.length >= 2) {\r\n x = arguments[0];\r\n y = arguments[1];\r\n }\r\n return whichar.hitAR(x, y, this.data.el, this.el);\r\n },\r\n\r\n checkWhichAR: function () {\r\n if (!this.whichar) {\r\n var whichar = this.el.sceneEl.components['ar'];\r\n if (whichar) { whichar = whichar.getSource ? whichar.getSource() : undefined; }\r\n if (!whichar || !whichar.arDisplay) { return; }\r\n this.whichar = whichar;\r\n }\r\n return this.whichar;\r\n } \r\n});\r\n\r\n","/* global AFRAME */\r\n\r\nAFRAME.registerComponent('ar', {\r\n schema: {\r\n takeOverCamera: {default: true},\r\n cameraUserHeight: {default: false},\r\n worldSensing: {default: true},\r\n hideUI: {default: false}\r\n },\r\n dependencies: ['webxr-ar', 'mozilla-xr-ar', 'ar-planes', 'ar-anchors'],\r\n getSource: function () {\r\n var whichar;\r\n if (!this.source) {\r\n var self = this;\r\n self.dependencies.forEach(function(sys) {\r\n whichar = self.el.sceneEl.components[sys];\r\n if (whichar && whichar.arDisplay) {\r\n self.source = whichar;\r\n }\r\n });\t\r\n }\r\n return this.source;\r\n },\r\n getPlanes: function () {\r\n return this.source ? this.source.getPlanes() : undefined;\r\n },\r\n getAnchors: function () {\r\n return this.source ? this.source.getAnchors() : undefined;\r\n },\r\n addImage: function (name, url, physicalWidth) {\r\n return this.source.addImage(name, url, physicalWidth);\r\n },\r\n removeImage: function (name) {\r\n return this.source.removeImage(name);\r\n },\r\n init: function () {\r\n var options = {\r\n takeOverCamera: this.data.takeOverCamera,\r\n cameraUserHeight: this.data.cameraUserHeight,\r\n worldSensing: this.data.worldSensing\r\n };\r\n\r\n var self = this;\r\n this.dependencies.forEach(function(sys) {\r\n self.el.setAttribute(sys, options);\r\n });\r\n\r\n if (this.data.hideUI) {\r\n this.el.sceneEl.setAttribute('vr-mode-ui', {enabled: false});\r\n }\r\n\r\n // Ensure passthrough is visible, make sure A-Frame styles don't interfere.\r\n document.head.insertAdjacentHTML('beforeend', \r\n '');\r\n }\r\n});\r\n","require('./webxr-ar');\r\n//require('./three-ar');\r\nrequire('./mozilla-xr-ar');\r\nrequire('./ar-planes');\r\nrequire('./ar-anchors');\r\nrequire('./ar-images');\r\nrequire('./ar');\r\nrequire('./ar-camera');\r\nrequire('./ar-raycaster');\r\n\r\n","/* global AFRAME, THREE */\r\n\r\nfunction convertVertices(vertices) {\r\n var verticesLength = vertices.length;\r\n var newVertices = new Float32Array(verticesLength * 3);\r\n var i = 0;\r\n var j = 0;\r\n var vertex;\r\n for (i = 0; i < verticesLength; i++) {\r\n vertex = vertices[i];\r\n newVertices[j] = vertex.x;\r\n newVertices[j + 1] = vertex.y;\r\n newVertices[j + 2] = vertex.z;\r\n j += 3;\r\n }\r\n return newVertices;\r\n}\r\n\r\n\r\nfunction encode(buffer) {\r\nvar base64 = ''\r\nvar encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\r\n\r\nvar bytes = buffer; // assume it's a typedArrayBuffer \r\n \r\nif (buffer instanceof ArrayBuffer) {\r\nbytes = new Uint8Array(arrayBuffer)\r\n} else if (buffer instanceof ImageData) {\r\nbytes = buffer.data\r\n}\r\n\r\nvar byteLength = buffer.length\r\nvar byteRemainder = byteLength % 3\r\nvar mainLength = byteLength - byteRemainder\r\n\r\nvar a, b, c, d\r\nvar chunk\r\n\r\n// Main loop deals with bytes in chunks of 3\r\nfor (var i = 0; i < mainLength; i = i + 3) {\r\n// Combine the three bytes into a single integer\r\nchunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]\r\n\r\n// Use bitmasks to extract 6-bit segments from the triplet\r\na = (chunk & 16515072) >> 18 // 16515072 = (2^6 - 1) << 18\r\nb = (chunk & 258048) >> 12 // 258048 = (2^6 - 1) << 12\r\nc = (chunk & 4032) >> 6 // 4032 = (2^6 - 1) << 6\r\nd = chunk & 63 // 63 = 2^6 - 1\r\n\r\n// Convert the raw binary segments to the appropriate ASCII encoding\r\nbase64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]\r\n}\r\n\r\n// Deal with the remaining bytes and padding\r\nif (byteRemainder == 1) {\r\nchunk = bytes[mainLength]\r\n\r\na = (chunk & 252) >> 2 // 252 = (2^6 - 1) << 2\r\n\r\n// Set the 4 least significant bits to zero\r\nb = (chunk & 3) << 4 // 3 = 2^2 - 1\r\n\r\nbase64 += encodings[a] + encodings[b] + '=='\r\n} else if (byteRemainder == 2) {\r\nchunk = (bytes[mainLength] << 8) | bytes[mainLength + 1]\r\n\r\na = (chunk & 64512) >> 10 // 64512 = (2^6 - 1) << 10\r\nb = (chunk & 1008) >> 4 // 1008 = (2^6 - 1) << 4\r\n\r\n// Set the 2 least significant bits to zero\r\nc = (chunk & 15) << 2 // 15 = 2^4 - 1\r\n\r\nbase64 += encodings[a] + encodings[b] + encodings[c] + '='\r\n}\r\n\r\nreturn base64\r\n}\r\n\r\n\r\n\r\nAFRAME.registerComponent('mozilla-xr-ar', {\r\n schema: {\r\n takeOverCamera: {default: true},\r\n cameraUserHeight: {default: false},\r\n worldSensing: {default: true}\r\n },\r\n\r\n init: function () {\r\n this.onInit = this.onInit.bind(this);\r\n this.onWatch = this.onWatch.bind(this);\r\n\r\n this.forceResize = this.forceResize.bind(this);\r\n\r\n this.poseMatrix = new THREE.Matrix4();\r\n this.posePosition = new THREE.Vector3();\r\n this.poseQuaternion = new THREE.Quaternion();\r\n this.poseEuler = new THREE.Euler(0, 0, 0, 'YXZ');\r\n this.poseRotation = new THREE.Vector3();\r\n this.projectionMatrix = new THREE.Matrix4();\r\n this.viewMatrix = new THREE.Matrix4();\r\n\r\n this.onceSceneLoaded = this.onceSceneLoaded.bind(this);\r\n if (this.el.sceneEl.hasLoaded) {\r\n setTimeout(this.onceSceneLoaded);\r\n } else {\r\n this.el.sceneEl.addEventListener('loaded', this.onceSceneLoaded);\r\n }\r\n\r\n // Add planes handling, so we can do synchronous hit test.\r\n // From google-ar/WebARonARKit; also see webxr-polyfill/ARKitWrapper.js\r\n\r\n this.planes_ = new Map();\r\n this.anchors_ = new Map();\r\n },\r\n\r\n // For WebXR Viewer, we are currently directly hooking the callback\r\n // used to provide frame data, so we don't need to do anything in tick!\r\n\r\n takeOverCamera: function (camera) {\r\n this.arCamera = camera;\r\n camera.el.setAttribute('ar-camera', 'enabled', true);\r\n },\r\n\r\n onceSceneLoaded: function () {\r\n // Check if the low-level WebXR Viewer interfaces are there.\r\n if (!window.webkit || !window.webkit.messageHandlers) { return; }\r\n if (!window.webkit.messageHandlers.initAR) { return; }\r\n\r\n // If we are the new version 2.0, don't use this!\r\n if (navigator.userAgent.indexOf('Mobile WebXRViewer/v1.') < 0) {\r\n/*\r\n // FIXME: sure but we do need a wakelock, and camera position is wrong with the new version\r\n // sigh, we do still need the wakelock killer\r\n var scene = this.el.sceneEl;\r\n scene.addEventListener('enter-vr', function (data) {\r\n // Kill broken wakelock, but wait a tick for it to be created!\r\n setTimeout(function () { if (scene.wakelock) { scene.wakelock.release(); }});\r\n });\r\n*/\r\n return;\r\n }\r\n\r\n window['arkitCallback' + 0] = this.onInit;\r\n window['arkitCallback' + 1] = this.onWatch;\r\n\r\n // Compose data to use with initAR.\r\n var data = {\r\n options: {\r\n ui: {\r\n browser: true,\r\n points: true,\r\n focus: false,\r\n rec: true,\r\n rec_time: true,\r\n mic: false,\r\n build: false,\r\n plane: true,\r\n warnings: true,\r\n anchors: false,\r\n debug: true,\r\n statistics: false\r\n }\r\n },\r\n callback: 'arkitCallback0' // this.onInit as window callback\r\n };\r\n\r\n // Need these because WebXR Viewer...\r\n //if (window['setNativeTime']) {\r\n // console.log('window handler already defined for ', 'setNativeTime');\r\n //} else\r\n window['setNativeTime'] = function (data) {\r\n window.nativeTime = data.nativeTime;\r\n };\r\n [\r\n 'arkitStartRecording',\r\n 'arkitStopRecording',\r\n 'arkitDidMoveBackground',\r\n 'arkitWillEnterForeground',\r\n 'arkitInterrupted',\r\n 'arkitInterruptionEnded',\r\n 'arkitShowDebug',\r\n // elsewhere... 'arkitWindowResize',\r\n 'onError',\r\n 'arTrackingChanged',\r\n 'ios_did_receive_memory_warning',\r\n 'onComputerVisionData',\r\n // above... 'setNativeTime',\r\n 'userGrantedComputerVisionData',\r\n 'userGrantedWorldSensingData', // Needed for world sensing.\r\n ].forEach(function (eventName) {\r\n //if (window[eventName]) {\r\n // console.log('window handler already defined for ', eventName);\r\n //} else\r\n window[eventName] = function (data) {\r\n console.log(eventName + ':', data);\r\n };\r\n });\r\n\r\n var self = this;\r\n\r\n self.el.addEventListener('exit-vr', function (data) {\r\n // tell WebXR Viewer to stop\r\n // FIXME: well, no, that's too much, camera tracking stops.\r\n window.webkit.messageHandlers.stopAR.postMessage({});\r\n // release ar-camera\r\n if (self.data.takeOverCamera && self.arCamera) {\r\n self.arCamera.el.setAttribute('ar-camera', 'enabled', false);\r\n }\r\n // turn AR button back on\r\n setTimeout(function () {\r\n var vrmodeui = self.el.sceneEl.components['vr-mode-ui'];\r\n vrmodeui.enterAREl.classList.remove('a-hidden');\r\n });\r\n });\r\n\r\n // act like Chrome WebXR by forcibly showing AR button and making it work\r\n var vrmodeui = this.el.sceneEl.components['vr-mode-ui'];\r\n var newarbutton = vrmodeui.enterAREl.cloneNode(true);\r\n vrmodeui.enterAREl.parentNode.replaceChild(newarbutton, vrmodeui.enterAREl);\r\n vrmodeui.enterAREl = newarbutton;\r\n vrmodeui.enterAREl.classList.remove('a-hidden');\r\n vrmodeui.enterAREl.onclick = function() {\r\n var scene = AFRAME.scenes[0];\r\n\r\n // Note we're in AR mode (the way WebXR handling does).\r\n scene.addState('ar-mode');\r\n\r\n // Kill the Cardboard display that gets in our way.\r\n scene.components['vr-mode-ui'].orientationModalEl.style='display:none!important';\r\n\r\n // Fake VR mode from enterVRSuccess.\r\n scene.addState('vr-mode');\r\n scene.emit('enter-vr', {target: scene});\r\n\r\n // Call initAR.\r\n window.webkit.messageHandlers.initAR.postMessage(data);\r\n \r\n // Kill broken wakelock!\r\n scene.wakelock.release();\r\n\r\n // Take over the scene camera, if so directed.\r\n // But wait a tick, because otherwise injected camera will not be present.\r\n if (self.data.takeOverCamera) {\r\n setTimeout(function () { self.takeOverCamera(scene.camera); });\r\n }\r\n\r\n let sz = new THREE.Vector2();\r\n let pixelRatio = scene.renderer.getPixelRatio();\r\n scene.renderer.getSize(sz);\r\n console.log(\"pixelRatio \", pixelRatio, \" size \", sz);\r\n\r\n // Ugly hack to get around WebXR Viewer resizing issue.\r\n scene.canvas.style.position = \"absolute !important\";\r\n scene.canvas.style.width = \"100% !important\";\r\n scene.canvas.style.height = \"100% !important\";\r\n\r\n // Force resize after we have access to data (?!)\r\n window.userGrantedWorldSensingData = function(data) {\r\n console.log('userGrantedWorldSensingData:', data);\r\n setTimeout(function () {\r\n self.forceResize(\r\n screen.width * window.devicePixelRatio,\r\n screen.height * window.devicePixelRatio);\r\n }, 100); // 1000 seems to be long enough initially\r\n };\r\n };\r\n },\r\n\r\n forceResize: function (sx, sy) {\r\n var sc = this.el.sceneEl, self = this;\r\n console.log('forceResize ', sx, sy,\r\n ' was ', \r\n sc.canvas.width, sc.canvas.height, \r\n screen.width, screen.height,\r\n window.devicePixelRatio, sc.renderer.getPixelRatio());\r\n\r\n var pixelRatio = sc.renderer.getPixelRatio();\r\n var maxSize = sc.maxCanvasSize;\r\n if (sx * pixelRatio > maxSize.width ||\r\n sy * pixelRatio > maxSize.height) {\r\n\r\n console.log('applying maxSize constraints ', maxSize);\r\n\r\n aspectRatio = sx / sy;\r\n\r\n if ((sx * pixelRatio) > maxSize.width && maxSize.width !== -1) {\r\n sx = Math.round(maxSize.width / pixelRatio);\r\n sy = Math.round(maxSize.width / aspectRatio / pixelRatio);\r\n }\r\n\r\n if ((sy * pixelRatio) > maxSize.height && maxSize.height !== -1) {\r\n sy = Math.round(maxSize.height / pixelRatio);\r\n sx = Math.round(maxSize.height * aspectRatio / pixelRatio);\r\n }\r\n\r\n console.log('applied maxSize constraints ', sx, sy, maxSize);\r\n }\r\n\r\n sx = sx || this.forceResizeX; this.forceResizeX = sx;\r\n sy = sy || this.forceResizeY; this.forceResizeY = sy;\r\n sc.canvas.setAttribute('width', sx);\r\n sc.canvas.setAttribute('height', sy);\r\n sc.camera.aspect = sx / sy;\r\n sc.camera.projectionMatrix.copy(self.projectionMatrix);\r\n sc.renderer.setSize(sx, sy, false);\r\n sc.emit('rendererresize', null, false);\r\n },\r\n\r\n checkForARDisplay: function () {\r\n // Check if the low-level WebXR Viewer interfaces are there.\r\n if (!window.webkit || !window.webkit.messageHandlers) { return; }\r\n if (!window.webkit.messageHandlers.watchAR) { return; }\r\n\r\n // If we are the new version 2.0, don't use this!\r\n if (navigator.userAgent.indexOf('Mobile WebXRViewer/v1.') < 0) { return; }\r\n\r\n // Mozilla WebXR Viewer detected.\r\n var self = this;\r\n self.arDisplay = true;\r\n\r\n\r\n // Compose data to use with watchAR.\r\n var data = {\r\n options: {\r\n location: true,\r\n camera: true,\r\n objects: true,\r\n light_intensity: true,\r\n worldSensing: this.data.worldSensing\r\n },\r\n callback: 'arkitCallback1' // this.onWatch as window callback\r\n };\r\n\r\n // Add resize handling.\r\n window['arkitWindowResize'] = function (data) {\r\n console.log('arkitWindowResize' + ':', data);\r\n\r\n // we're faking being in vr-mode anyway so resize will exit.\r\n //window.emit('resize', {target: window});\r\n\r\n // on iOS, AFRAME waits 100ms... \r\n setTimeout(function () {\r\n self.forceResize(\r\n data.width * window.devicePixelRatio,\r\n data.height * window.devicePixelRatio);\r\n }, 150); // 250 seems to be long enough\r\n };\r\n\r\n // Start watching AR.\r\n window.webkit.messageHandlers.watchAR.postMessage(data);\r\n },\r\n\r\n onInit: function (deviceId) {\r\n this.checkForARDisplay();\r\n },\r\n\r\n onWatch: function (data) {\r\n this.frameData = data;\r\n this.handleFrame(data);\r\n },\r\n\r\n handleFrame: function (data) {\r\n // Decompose to get camera pose.\r\n this.poseMatrix.fromArray(data.camera_transform);\r\n this.poseMatrix.decompose(this.posePosition, this.poseQuaternion, this.poseRotation); // poseRotation is really scale, we redo below\r\n this.poseEuler.setFromQuaternion(this.poseQuaternion);\r\n this.poseRotation.set(\r\n THREE.Math.RAD2DEG * this.poseEuler.x,\r\n THREE.Math.RAD2DEG * this.poseEuler.y,\r\n THREE.Math.RAD2DEG * this.poseEuler.z);\r\n\r\n this.projectionMatrix.fromArray(data.projection_camera);\r\n this.viewMatrix.fromArray(data.camera_view);\r\n\r\n // If we control a camera, and should apply user height, do it.\r\n if (this.arCamera && this.data.cameraUserHeight) {\r\n this.posePosition.y += this.arCamera.el.components.camera.data.userHeight;\r\n }\r\n\r\n // For A-Painter, detect bogus pose and fire poseFound / poseLost.\r\n var poseValid = this.posePosition.x || this.posePosition.y || this.posePosition.z || this.poseQuaternion.x || this.poseQuaternion.y || this.poseQuaternion.z;\r\n if (poseValid) {\r\n if (this.poseLost !== false) {\r\n this.poseLost = false;\r\n this.el.emit('poseFound');\r\n }\r\n } else {\r\n if (this.poseLost !== true) {\r\n this.poseLost = true;\r\n this.el.emit('poseLost', false);\r\n }\r\n }\r\n\r\n // Add planes handling, so we can do synchronous hit test.\r\n // From google-ar/WebARonARKit; also see webxr-polyfill/ARKitWrapper.js\r\n\r\n var i;\r\n var element;\r\n\r\n // WebXR Viewer returns geometry.vertices as an array of {x: number, y: number, y: number}\r\n // https://github.com/mozilla-mobile/webxr-ios/blob/c77b12c235e3960e2cd51538e086a38c83d8ec7c/XRViewer/ARKController/ARKController.m#L845\r\n // We transform this to a flatten array of number, like WebARonARCore.\r\n\r\n if(data.newObjects && data.newObjects.length){\r\n for (i = 0; i < data.newObjects.length; i++) {\r\n element = data.newObjects[i];\r\n if(element.plane_center){\r\n this.planes_.set(element.uuid, {\r\n id: element.uuid,\r\n center: element.plane_center,\r\n extent: [element.plane_extent.x, element.plane_extent.z],\r\n modelMatrix: element.transform,\r\n alignment: element.plane_alignment,\r\n vertices: convertVertices(element.geometry.vertices)\r\n });\r\n }else{\r\n var anchorData = {\r\n id: element.uuid,\r\n modelMatrix: element.transform\r\n };\r\n if (element.type === 'image') {\r\n anchorData.name = element.uuid;\r\n }\r\n this.anchors_.set(element.uuid, anchorData);\r\n }\r\n }\r\n }\r\n\r\n if(data.removedObjects && data.removedObjects.length){\r\n for (i = 0; i < data.removedObjects.length; i++) {\r\n element = data.removedObjects[i];\r\n if(this.planes_.get(element)){\r\n this.planes_.delete(element);\r\n }else{\r\n this.anchors_.delete(element);\r\n }\r\n }\r\n }\r\n\r\n if(data.objects && data.objects.length){\r\n for (i = 0; i < data.objects.length; i++) {\r\n element = data.objects[i];\r\n if(element.plane_center){\r\n var plane = this.planes_.get(element.uuid);\r\n if(!plane){\r\n this.planes_.set(element.uuid, {\r\n id: element.uuid,\r\n center: element.plane_center,\r\n extent: [element.plane_extent.x, element.plane_extent.z],\r\n modelMatrix: element.transform,\r\n alignment: element.plane_alignment,\r\n vertices: convertVertices(element.geometry.vertices)\r\n });\r\n } else {\r\n plane.center = element.plane_center;\r\n plane.extent = [element.plane_extent.x, element.plane_extent.z];\r\n plane.modelMatrix = element.transform;\r\n plane.alignment = element.plane_alignment;\r\n plane.vertices = convertVertices(element.geometry.vertices);\r\n }\r\n }else{\r\n var anchor = this.anchors_.get(element.uuid);\r\n if(!anchor){\r\n this.anchors_.set(element.uuid, {\r\n id: element.uuid,\r\n modelMatrix: element.transform\r\n });\r\n }else{\r\n anchor.modelMatrix = element.transform;\r\n }\r\n }\r\n }\r\n }\r\n },\r\n\r\n getPosition: function () {\r\n if (!this.arDisplay) { return null; }\r\n return this.posePosition;\r\n },\r\n\r\n getOrientation: function () {\r\n if (!this.arDisplay) { return null; }\r\n return this.poseQuaternion;\r\n },\r\n\r\n getRotation: function () {\r\n if (!this.arDisplay) { return null; }\r\n return this.poseRotation;\r\n },\r\n\r\n getProjectionMatrix: function () {\r\n if (!this.arDisplay) { return null; }\r\n return this.projectionMatrix;\r\n },\r\n\r\n // Link to new ARKit image marker and anchor support.\r\n\r\n addImage: function (name, url, physicalWidth) {\r\n if (!this.arDisplay) { return null; }\r\n/*\r\nNSDictionary *imageAnchorInfoDictionary = [message body];\r\nNSString *createDetectionImageCallback = [[message body] objectForKey:WEB_AR_CALLBACK_OPTION];\r\n// callback\r\n\r\nCGFloat physicalWidth = [referenceImageDictionary[@\"physicalWidth\"] doubleValue];\r\nNSString* b64String = referenceImageDictionary[@\"buffer\"];\r\nsize_t width = (size_t) [referenceImageDictionary[@\"imageWidth\"] intValue];\r\nsize_t height = (size_t) [referenceImageDictionary[@\"imageHeight\"] intValue];\r\n...\r\nresult.name = referenceImageDictionary[@\"uid\"];\r\n*/\r\n // NOTE: looks like WebXR Viewer won't load from URL,\r\n // so we need to convert from img element\r\n var aCanvas = document.createElement('canvas');\r\n var aContext = aCanvas.getContext('2d');\r\n var aImg; // Don't use element; chance of changed width/height.\r\n if (!aImg) {\r\n aImg = document.createElement('img');\r\n aImg.crossOrigin = 'anonymous';\r\n aImg.src = url;\r\n document.body.appendChild(aImg);\r\n }\r\n\r\n // The image needs to be loaded...\r\n if (!aImg.complete || !aImg.naturalHeight) {\r\n console.log('!!! addImage: !aImg.complete || !aImg.naturalHeight, aborting');\r\n return;\r\n } \r\n \r\n // The image needs to be have nonzero size...\r\n if (!aImg.width || !aImg.height) {\r\n console.log('!!! addImage: !aImg.width || !aImg.height, aborting');\r\n return;\r\n } \r\n\r\n aCanvas.width = aImg.width;\r\n aCanvas.height = aImg.height;\r\n aContext.drawImage(aImg, 0, 0);\r\n var aImageData = aContext.getImageData(0, 0, aImg.width, aImg.height);\r\n var b64ImageData = encode(aImageData.data);\r\n if (!b64ImageData) {\r\n console.log('!!! addImage: !b64ImageData, aborting');\r\n return;\r\n }\r\n\r\n // NOTE: also, WebXR Viewer doesn't pass back which image/name,\r\n // so we need a per-image/name callback\r\n window.callbackForCreateImageAnchorCounter = (window.callbackForCreateImageAnchorCounter || 0) + 1;\r\n var callbackName = 'callbackForCreateImageAnchor_' + window.callbackForCreateImageAnchorCounter;\r\n var imageName = name;\r\n //console.log('creating ', callbackName, ' for ', imageName);\r\n window[callbackName] = function (data) {\r\n //console.log(callbackName);\r\n //console.log(data);\r\n //var name = callbackName.substring(29);\r\n if (data.created !== undefined) {\r\n if (!data.created) {\r\n // we failed to create the image, for whatever reason.\r\n console.log('addImage: !created; ', data.error);\r\n delete window[callbackName];\r\n } else {\r\n //console.log('addImage: created, activating ', imageName);\r\n window.webkit.messageHandlers.activateDetectionImage.postMessage({\r\n callback: callbackName,\r\n uid: imageName\r\n });\r\n }\r\n } else\r\n if (data.activated !== undefined) {\r\n if (!data.activated) {\r\n // we failed to activate the image, for whatever reason.\r\n console.log('addImage: !activated; ', data.error);\r\n } else {\r\n //console.log('addImage: activated ', imageName);\r\n }\r\n delete window[callbackName];\r\n }\r\n };\r\n\r\n window.webkit.messageHandlers.createImageAnchor.postMessage({\r\n callback: callbackName,\r\n uid: name,\r\n buffer: b64ImageData,\r\n imageWidth: aImg.width,\r\n imageHeight: aImg.height,\r\n physicalWidth: physicalWidth // in meters\r\n });\r\n },\r\n\r\n removeImage: function (name) {\r\n if (!this.arDisplay) { return null; }\r\n/*\r\nNSDictionary *imageAnchorInfoDictionary = [message body];\r\nNSString *imageName = imageAnchorInfoDictionary[WEB_AR_DETECTION_IMAGE_NAME_OPTION];\r\n// detectionImageName\r\nNSString *deactivateDetectionImageCallback = [[message body] objectForKey:WEB_AR_CALLBACK_OPTION];\r\n// callback\r\n*/\r\n window.callbackForRemoveImageAnchorCounter = (window.callbackForRemoveImageAnchorCounter || 0) + 1;\r\n var callbackName = 'callbackForRemoveImageAnchor_' + window.callbackForRemoveImageAnchorCounter;\r\n var imageName = name;\r\n //console.log('creating ', callbackName, ' for ', imageName);\r\n window[callbackName] = function (data) {\r\n //console.log(callbackName);\r\n //console.log(data);\r\n\r\n if (data.deactivated !== undefined) {\r\n if (!data.deactivated) {\r\n console.log('!!! ' + callbackName + ': !deactivated', data.error);\r\n delete window[callbackName];\r\n } else {\r\n //console.log(callbackName + ': deactivated, destroying', imageName);\r\n }\r\n window.webkit.messageHandlers.destroyDetectionImage.postMessage({\r\n callback: callbackName,\r\n uid: imageName\r\n });\r\n }\r\n if (data.destroyed !== undefined) {\r\n if (!data.destroyed) {\r\n console.log('!!! ' + callbackName + ': !destroyed, ', data.error);\r\n } else {\r\n //console.log(callbackName + ': destroyed', imageName);\r\n }\r\n delete window[callbackName];\r\n }\r\n };\r\n\r\n window.webkit.messageHandlers.deactivateDetectionImage.postMessage({\r\n callback: callbackName,\r\n uid: imageName\r\n });\r\n },\r\n\r\n getAnchors: function () {\r\n return Array.from(this.anchors_.values());\r\n },\r\n\r\n // Use planes to do synchronous hit test.\r\n // From google-ar/WebARonARKit; also see webxr-polyfill/ARKitWrapper.js\r\n\r\n getPlanes: function () {\r\n return Array.from(this.planes_.values());\r\n },\r\n\r\n hitTestNoAnchor: (function () {\r\n // Temporary variables, only within closure scope.\r\n\r\n /**\r\n * The result of a raycast into the AR world encoded as a transform matrix.\r\n * This structure has a single property - modelMatrix - which encodes the\r\n * translation of the intersection of the hit in the form of a 4x4 matrix.\r\n * @constructor\r\n */\r\n function VRHit() {\r\n this.modelMatrix = new Float32Array(16);\r\n return this;\r\n };\r\n\r\n /**\r\n * Cached vec3, mat4, and quat structures needed for the hit testing to\r\n * avoid generating garbage.\r\n * @type {Object}\r\n */\r\n var hitVars = {\r\n rayStart: new THREE.Vector3(), //vec3.create(),\r\n rayEnd: new THREE.Vector3(), //vec3.create(),\r\n cameraPosition: new THREE.Vector3(), //vec3.create(),\r\n cameraQuaternion: new THREE.Quaternion(), //quat.create(),\t\r\n //modelViewMatrix: new THREE.Matrix4(), //mat4.create(),\r\n //projectionMatrix: new THREE.Matrix4(), //mat4.create(),\r\n projViewMatrix: new THREE.Matrix4(), //mat4.create(),\r\n worldRayStart: new THREE.Vector3(), //vec3.create(),\r\n worldRayEnd: new THREE.Vector3(), //vec3.create(),\r\n worldRayDir: new THREE.Vector3(), //vec3.create(),\r\n planeMatrix: new THREE.Matrix4(), //mat4.create(),\r\n planeMatrixInverse: new THREE.Matrix4(), //mat4.create(),\r\n planeExtent: new THREE.Vector3(), //vec3.create(),\r\n planePosition: new THREE.Vector3(), //vec3.create(),\r\n planeCenter: new THREE.Vector3(), //vec3.create(),\r\n planeNormal: new THREE.Vector3(), //vec3.create(),\r\n planeIntersection: new THREE.Vector3(), //vec3.create(),\r\n planeIntersectionLocal: new THREE.Vector3(), //vec3.create(),\r\n planeHit: new THREE.Matrix4(), //mat4.create()\r\n planeQuaternion: new THREE.Quaternion() // quat.create()\r\n };\r\n \r\n /**\r\n * Tests whether the given ray intersects the given plane.\r\n *\r\n * @param {!vec3} planeNormal The normal of the plane.\r\n * @param {!vec3} planePosition Any point on the plane.\r\n * @param {!vec3} rayOrigin The origin of the ray.\r\n * @param {!vec3} rayDirection The direction of the ray (normalized).\r\n * @return {number} The t-value of the intersection (-1 for none).\r\n */\r\n var rayIntersectsPlane = (function() {\r\n var rayToPlane = new THREE.Vector3();\r\n return function(planeNormal, planePosition, rayOrigin, rayDirection) {\r\n // assuming vectors are all normalized\r\n var denom = planeNormal.dot(rayDirection);\r\n rayToPlane.subVectors(planePosition, rayOrigin);\r\n return rayToPlane.dot(planeNormal) / denom;\r\n };\r\n })();\r\n \r\n /**\r\n * Sorts based on the distance from the VRHits to the camera.\r\n *\r\n * @param {!VRHit} a The first hit to compare.\r\n * @param {!VRHit} b The second hit item to compare.\r\n * @returns {number} -1 if a is closer than b, otherwise 1.\r\n */\r\n var sortFunction = function(a, b) {\r\n // Get the matrix of hit a.\r\n hitVars.planeMatrix.fromArray(a.modelMatrix);\r\n // Get the translation component of a's matrix.\r\n hitVars.planeIntersection.setFromMatrixPosition(hitVars.planeMatrix);\r\n // Get the distance from the intersection point to the camera.\r\n var distA = hitVars.planeIntersection.distanceTo(hitVars.cameraPosition);\r\n \r\n // Get the matrix of hit b.\r\n hitVars.planeMatrix.fromArray(b.modelMatrix);\r\n // Get the translation component of b's matrix.\r\n hitVars.planeIntersection.setFromMatrixPosition(hitVars.planeMatrix);\r\n // Get the distance from the intersection point to the camera.\r\n var distB = hitVars.planeIntersection.distanceTo(hitVars.cameraPosition);\r\n \r\n // Return comparison of distance from camera to a and b.\r\n return distA < distB ? -1 : 1;\r\n };\r\n \r\n return function(x, y) {\r\n // Coordinates must be in normalized screen space.\r\n if (x < 0 || x > 1 || y < 0 || y > 1) {\r\n throw new Error(\r\n \"hitTest - x and y values must be normalized [0,1]!\")\r\n ;\r\n }\r\n \r\n var hits = [];\r\n // If there are no anchors detected, there will be no hits.\r\n var planes = this.getPlanes();\r\n if (!planes || planes.length === 0) {\r\n return hits;\r\n }\r\n\r\n // Create a ray in screen space for the hit test ([-1, 1] with y flip).\r\n hitVars.rayStart.set(2 * x - 1, 2 * (1 - y) - 1, 0);\r\n hitVars.rayEnd.set(2 * x - 1, 2 * (1 - y) - 1, 1);\r\n\r\n // Set the projection matrix.\r\n //hitVars.projectionMatrix.fromArray(this.projectionMatrix);\r\n \r\n // Set the model view matrix.\r\n //hitVars.modelViewMatrix.fromArray(this.viewMatrix);\r\n \r\n // Combine the projection and model view matrices.\r\n hitVars.planeMatrix.multiplyMatrices(\r\n this.projectionMatrix, //hitVars.projectionMatrix,\r\n this.viewMatrix //hitVars.modelViewMatrix\r\n );\r\n // Invert the combined matrix because we need to go from screen -> world.\r\n hitVars.projViewMatrix.getInverse(hitVars.planeMatrix);\r\n \r\n // Transform the screen-space ray start and end to world-space.\r\n hitVars.worldRayStart.copy(hitVars.rayStart)\r\n .applyMatrix4(hitVars.projViewMatrix);\r\n hitVars.worldRayEnd.copy(hitVars.rayEnd)\r\n .applyMatrix4(hitVars.projViewMatrix);\r\n \r\n // Subtract start from end to get the ray direction and then normalize.\r\n hitVars.worldRayDir.subVectors(\r\n hitVars.worldRayEnd,\r\n hitVars.worldRayStart\r\n ).normalize();\r\n\r\n // Go through all the anchors and test for intersections with the ray.\r\n for (var i = 0; i < planes.length; i++) {\r\n var plane = planes[i];\r\n // Get the anchor transform.\r\n hitVars.planeMatrix.fromArray(plane.modelMatrix);\r\n \r\n // Get the position of the anchor in world-space.\r\n hitVars.planeCenter.set(plane.center.x, plane.center.y, plane.center.z);\r\n hitVars.planePosition.copy(hitVars.planeCenter)\r\n .applyMatrix4(hitVars.planeMatrix)\r\n\r\n hitVars.planeAlignment = plane.alignment\r\n \r\n // Get the plane normal.\r\n if (hitVars.planeAlignment === 0) {\r\n hitVars.planeNormal.set(0, 1, 0);\r\n } else {\r\n hitVars.planeNormal.set(hitVars.planeMatrix[4], hitVars.planeMatrix[5], hitVars.planeMatrix[6]);\r\n }\r\n \r\n // Check if the ray intersects the plane.\r\n var t = rayIntersectsPlane(\r\n hitVars.planeNormal,\r\n hitVars.planePosition,\r\n hitVars.worldRayStart,\r\n hitVars.worldRayDir\r\n );\r\n\r\n // if t < 0, there is no intersection.\r\n if (t < 0) {\r\n continue;\r\n }\r\n \r\n // Calculate the actual intersection point.\r\n hitVars.planeIntersectionLocal.copy(hitVars.worldRayDir).multiplyScalar(t);\r\n hitVars.planeIntersection.addVectors(\r\n hitVars.worldRayStart,\r\n hitVars.planeIntersectionLocal\r\n );\r\n // Get the plane extents (extents are in plane local space).\r\n hitVars.planeExtent.set(plane.extent[0], 0, plane.extent[1]);\r\n /*\r\n ///////////////////////////////////////////////\r\n // Test by converting extents to world-space.\r\n // TODO: get this working to avoid matrix inversion in method below.\r\n \r\n // Get the rotation component of the anchor transform.\r\n mat4.getRotation(hitVars.planeQuaternion, hitVars.planeMatrix);\r\n \r\n // Convert the extent into world space.\r\n vec3.transformQuat(\r\n hitVars.planeExtent, hitVars.planeExtent, hitVars.planeQuaternion);\r\n \r\n // Check if intersection is outside of the extent of the anchor.\r\n if (Math.abs(hitVars.planeIntersection[0] - hitVars.planePosition[0]) > hitVars.planeExtent[0] / 2) {\r\n continue;\r\n }\r\n if (Math.abs(hitVars.planeIntersection[2] - hitVars.planePosition[2]) > hitVars.planeExtent[2] / 2) {\r\n continue;\r\n }\r\n ////////////////////////////////////////////////\r\n */\r\n \r\n ////////////////////////////////////////////////\r\n // Test by converting intersection into plane-space.\r\n hitVars.planeMatrixInverse.getInverse(hitVars.planeMatrix);\r\n hitVars.planeIntersectionLocal.copy(hitVars.planeIntersection)\r\n .applyMatrix4(hitVars.planeMatrixInverse);\r\n \r\n // Check if intersection is outside of the extent of the anchor.\r\n // Tolerance is added to match the behavior of the native hitTest call.\r\n var tolerance = 0.0075;\r\n if (\r\n Math.abs(hitVars.planeIntersectionLocal.x) >\r\n hitVars.planeExtent.x / 2 + tolerance\r\n ) {\r\n continue;\r\n }\r\n if (\r\n Math.abs(hitVars.planeIntersectionLocal.z) >\r\n hitVars.planeExtent.z / 2 + tolerance\r\n ) {\r\n continue;\r\n }\r\n \r\n ////////////////////////////////////////////////\r\n \r\n // The intersection is valid - create a matrix from hit position.\r\n hitVars.planeQuaternion.setFromRotationMatrix(hitVars.planeMatrix);\r\n hitVars.planeHit.makeRotationFromQuaternion(hitVars.planeQuaternion).setPosition(hitVars.planeIntersection);\r\n var hit = new VRHit();\r\n for (var j = 0; j < 16; j++) {\r\n hit.modelMatrix[j] = hitVars.planeHit.elements[j];\r\n }\r\n hit.i = i;\r\n hits.push(hit);\r\n }\r\n \r\n\r\n // Sort the hits by distance.\r\n hits.sort(sortFunction);\r\n return hits;\r\n };\r\n })(),\r\n\r\n hitAR: (function () {\r\n // Temporary variables, only within closure scope.\r\n var transform = new THREE.Matrix4();\r\n var hitpoint = new THREE.Vector3();\r\n var hitquat = new THREE.Quaternion();\r\n var hitscale = new THREE.Vector3();\r\n var worldpos = new THREE.Vector3();\r\n\r\n // The desired function, which this returns.\r\n return function (x, y, el, raycasterEl) {\r\n if (!this.arDisplay) { return []; }\r\n\r\n var hit = this.hitTestNoAnchor(x, y);\r\n\r\n // Process AR hits.\r\n var hitsToReturn = [];\r\n for (var i = 0; hit && i < hit.length; i++) {\r\n transform.fromArray(hit[i].modelMatrix);\r\n transform.decompose(hitpoint, hitquat, hitscale);\r\n raycasterEl.object3D.getWorldPosition(worldpos);\r\n\r\n hitsToReturn.push({\r\n distance: hitpoint.distanceTo(worldpos),\r\n point: hitpoint.clone(), // Vector3\r\n object: (el && el.object3D) || this.el.sceneEl.object3D\r\n/*\r\n // We don't have any of these properties...\r\n face: undefined, // Face3\r\n faceIndex: undefined,\r\n index: undefined,\r\n uv: undefined // Vector2\r\n*/\r\n });\r\n }\r\n return hitsToReturn;\r\n } \r\n })()\r\n});\r\n","/* global AFRAME, THREE, VRFrameData */\r\n\r\nAFRAME.registerComponent('webxr-ar', {\r\n schema: {\r\n takeOverCamera: {default: true},\r\n cameraUserHeight: {default: false},\r\n worldSensing: {default: false} // currently unused\r\n },\r\n\r\n init: function () {\r\n this.posePosition = new THREE.Vector3();\r\n this.poseQuaternion = new THREE.Quaternion();\r\n this.poseEuler = new THREE.Euler(0, 0, 0, 'YXZ');\r\n this.poseRotation = new THREE.Vector3();\r\n this.projectionMatrix = new THREE.Matrix4();\r\n\r\n this.onceSceneLoaded = this.onceSceneLoaded.bind(this);\r\n if (this.el.sceneEl.hasLoaded) {\r\n setTimeout(this.onceSceneLoaded);\r\n } else {\r\n this.el.sceneEl.addEventListener('loaded', this.onceSceneLoaded);\r\n }\r\n\r\n // Add planes handling, so we can do synchronous hit test.\r\n\r\n this.rawPlanes_ = null;\r\n this.planes_ = new Map();\r\n this.anchors_ = new Map();\r\n },\r\n\r\n convertPolygonToVertices: function(polygon) {\r\n return newVertices;\r\n },\r\n\r\n convertedPlane: function(rawPlane, pose) {\r\n var mins = [0, 0];\r\n var maxs = [0, 0];\r\n var verticesLength = rawPlane.polygon.length;\r\n var newVertices = new Float32Array(verticesLength * 3);\r\n var i = 0;\r\n var j = 0;\r\n var vertex;\r\n for (i = 0; i < verticesLength; i++) {\r\n vertex = rawPlane.polygon[i];\r\n newVertices[j] = vertex.x;\r\n newVertices[j + 1] = vertex.y;\r\n newVertices[j + 2] = vertex.z;\r\n j += 3;\r\n if (i == 0) {\r\n mins[0] = maxs[0] = vertex.x;\r\n mins[1] = maxs[1] = vertex.z;\r\n } else {\r\n if (mins[0] > vertex.x) { mins[0] = vertex.x; }\r\n if (maxs[0] < vertex.x) { maxs[0] = vertex.x; }\r\n if (mins[1] > vertex.z) { mins[1] = vertex.z; }\r\n if (maxs[1] < vertex.z) { maxs[1] = vertex.z; }\r\n }\r\n }\r\n var position = pose.transform.position;\r\n rawPlane.position.set(position.x, position.y, position.z);\r\n var converted = {\r\n id: rawPlane.id,\r\n center: rawPlane.position,\r\n extent: [maxs[0] - mins[0], maxs[1] - mins[1]],\r\n modelMatrix: pose.transform.matrix,\r\n alignment: rawPlane.orientation != 'Horizontal' ? 1 : 0,\r\n vertices: newVertices\r\n };\r\n return converted;\r\n },\r\n\r\n rawPlaneRemoved: function(rawPlane) {\r\n // remove the converted plane\r\n this.planes_.delete(rawPlane.id);\r\n },\r\n\r\n rawPlaneUpdated: function(rawPlane, pose) {\r\n // convert the updated plane\r\n this.planes_.set(rawPlane.id, this.convertedPlane(rawPlane, pose));\r\n },\r\n\r\n rawPlaneNotUpdated: function(rawPlane, pose) {\r\n // FIXME: check is broken so update anyway\r\n this.rawPlaneUpdated(rawPlane, pose);\r\n // do nothing\r\n },\r\n\r\n rawPlaneCreated: function(rawPlane, pose) {\r\n // assign and attach an id... for now, use Math.random()\r\n rawPlane.id = Math.random().toString().substring(2);\r\n rawPlane.position = new THREE.Vector3();\r\n // convert the plane\r\n this.planes_[rawPlane.id] = this.convertedPlane(rawPlane, pose);\r\n },\r\n\r\n tick: function (t, dt) {\r\n let frame = this.el.sceneEl.frame;\r\n if (!this.arDisplay\r\n || !frame\r\n || !frame.worldInformation) { return; }\r\n\r\n // use the planes information\r\n let world = frame.worldInformation;\r\n\r\n // check for removed planes\r\n this.rawPlanes_ && this.rawPlanes_.forEach(plane => {\r\n if(!world.detectedPlanes || !world.detectedPlanes.has(plane)) {\r\n // Handle removed plane - `plane` was present in previous frame but is no longer tracked.\r\n this.rawPlaneRemoved(plane);\r\n }\r\n });\r\n\r\n // check for changed planes\r\n let timestamp = this.el.sceneEl.time;\r\n world.detectedPlanes && world.detectedPlanes.forEach(plane => {\r\n let planePose = frame.getPose(plane.planeSpace, this.refSpace);\r\n if (this.rawPlanes_.has(plane)) {\r\n if(plane.lastChangedTime == timestamp) {\r\n // Handle previously seen plane that was updated in current frame.\r\n this.rawPlaneUpdated(plane, planePose);\r\n } else {\r\n // Handle previously seen plane that was not updated in current frame.\r\n // Depending on the application, this could be a no-op.\r\n this.rawPlaneNotUpdated(plane, planePose);\r\n }\r\n } else {\r\n // Handle new plane.\r\n this.rawPlaneCreated(plane, planePose);\r\n }\r\n });\r\n \r\n this.rawPlanes_ = world.detectedPlanes;\r\n },\r\n\r\n takeOverCamera: function (camera) {\r\n this.arCamera = camera;\r\n camera.isARPerspectiveCamera = true; // HACK - is this necessary?\r\n camera.vrDisplay = this.arDisplay; // HACK - is this necessary?\r\n camera.el.setAttribute('ar-camera', 'enabled', true);\r\n },\r\n\r\n onceSceneLoaded: function () {\r\n var self = this;\r\n window.addEventListener('ardisplayconnect', function () {\r\n if (!self.arDisplay) { self.checkForARDisplay(); }\r\n });\r\n\r\n // Check now for AR display.\r\n this.checkForARDisplay();\r\n },\r\n\r\n checkForARDisplay: function () {\r\n // check to see if webxr ar mode is supported\r\n if (!navigator.xr || !navigator.xr.isSessionSupported) { return; }\r\n\r\n var self = this;\r\n self.arDisplay = {type: 'webxr-ar'};\r\n\r\n navigator.xr.isSessionSupported('immersive-ar').then(function(supported) {\r\n if (supported) {\r\n let ourRequiredFeatures = ['local-floor'];\r\n let ourOptionalFeatures = [];\r\n (self.data.worldSensing ? ourRequiredFeatures : ourOptionalFeatures).push('hit-test');\r\n let existingFeatures = self.el.sceneEl.getAttribute('webxr');\r\n if (!existingFeatures) {\r\n // here, we assume we can set as map and not String (?) \r\n self.el.sceneEl.setAttribute('webxr', { \r\n requiredFeatures: ourRequiredFeatures.join(','), \r\n optionalFeatures: ourOptionalFeatures.join(',') \r\n });\r\n } else {\r\n // here, we assume we get and set as map and not String (?)\r\n // remove existing optional features from our optional\r\n existingFeatures.optionalFeatures.forEach(function (feature) {\r\n ourOptionalFeatures = ourOptionalFeatures.filter(function(value, index, arr){ return value != feature;});\r\n });\r\n // remove existing required features from our required\r\n existingFeatures.requiredFeatures.forEach(function (feature) {\r\n ourRequiredFeatures = ourRequiredFeatures.filter(function(value, index, arr){ return value != feature;});\r\n });\r\n // remove our required features from existing optional\r\n ourRequiredFeatures.forEach(function (feature) {\r\n existingFeatures.optionalFeatures = existingFeatures.optionalFeatures.filter(function(value, index, arr){ return value != feature;});\r\n });\r\n // add our required and optional features to the existing\r\n existingFeatures.requiredFeatures = existingFeatures.requiredFeatures.concat(ourRequiredFeatures);\r\n existingFeatures.optionalFeatures = existingFeatures.optionalFeatures.concat(ourOptionalFeatures);\r\n\r\n self.el.sceneEl.setAttribute('webxr', existingFeatures);\r\n }\r\n\r\n self.el.sceneEl.setAttribute('vr-mode-ui', \"enabled\", \"true\");\r\n // auto-entering AR doesn't work.\r\n\r\n self.xrHitTestSource = null;\r\n self.viewerSpace = null;\r\n self.refSpace = null;\r\n\r\n self.el.sceneEl.renderer.xr.addEventListener('sessionend', (ev) => {\r\n self.viewerSpace = null;\r\n self.refSpace = null;\r\n self.xrHitTestSource = null;\r\n });\r\n self.el.sceneEl.renderer.xr.addEventListener('sessionstart', (ev) => {\r\n let session = self.el.sceneEl.renderer.xr.getSession();\r\n let el = self.el.sceneEl.canvas;\r\n\r\n session.addEventListener('selectstart', function (e) {\r\n // dispatch touchstart\r\n var pageX = e.inputSource.gamepad.axes[0];\r\n var pageY = e.inputSource.gamepad.axes[1];\r\n setTimeout(() => {\r\n var event = new TouchEvent('touchstart', {\r\n view: window,\r\n bubbles: true,\r\n cancelable: true\r\n });\r\n event.targetTouches = [{ pageX: pageX, pageY: pageY }];\r\n el.dispatchEvent(event);\r\n });\r\n });\r\n\r\n session.addEventListener('selectend', function (e) {\r\n // dispatch touchend\r\n var pageX = e.inputSource.gamepad.axes[0];\r\n var pageY = e.inputSource.gamepad.axes[1];\r\n setTimeout(() => {\r\n var event = new TouchEvent('touchend', {\r\n view: window,\r\n bubbles: true,\r\n cancelable: true\r\n });\r\n event.targetTouches = [{ pageX: pageX, pageY: pageY }];\r\n el.dispatchEvent(event);\r\n });\r\n });\r\n\r\n session.addEventListener('select', function (e) {\r\n // dispatch click\r\n var pageX = e.inputSource.gamepad.axes[0];\r\n var pageY = e.inputSource.gamepad.axes[1];\r\n setTimeout(() => {\r\n var event = new MouseEvent('click', { \r\n clientX: pageX, \r\n clientY: pageY, \r\n bubbles: true,\r\n cancelable: true\r\n });\r\n el.dispatchEvent(event);\r\n });\r\n });\r\n\r\n session.requestReferenceSpace('viewer').then((space) => {\r\n self.viewerSpace = space;\r\n if (self.data.worldSensing) {\r\n session.requestHitTestSource({space: self.viewerSpace})\r\n .then((hitTestSource) => {\r\n self.xrHitTestSource = hitTestSource;\r\n })\r\n }\r\n });\r\n\r\n session.requestReferenceSpace('local-floor').then((space) => {\r\n self.refSpace = space;\r\n });\r\n\r\n // Ask for planes, if we should.\r\n if (self.data.worldSensing) {\r\n session.updateWorldTrackingState({planeDetectionState : {enabled : true}});\r\n }\r\n });\r\n }\r\n });\r\n },\r\n\r\n getPosition: function () {\r\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\r\n return this.posePosition;\r\n },\r\n\r\n getOrientation: function () {\r\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\r\n return this.poseQuaternion;\r\n },\r\n\r\n getRotation: function () {\r\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\r\n return this.poseRotation;\r\n },\r\n\r\n getProjectionMatrix: function () {\r\n if (!this.arDisplay || !this.arDisplay.getFrameData) { return null; }\r\n return this.projectionMatrix;\r\n },\r\n\r\n hitAR: (function () { \r\n // Temporary variables, only within closure scope.\r\n var transform = new THREE.Matrix4();\r\n var hitpoint = new THREE.Vector3();\r\n var hitquat = new THREE.Quaternion();\r\n var hitscale = new THREE.Vector3();\r\n var worldpos = new THREE.Vector3();\r\n \r\n // The desired function, which this returns.\r\n return function (x, y, el, raycasterEl) {\r\n if (!this.arDisplay) { return []; }\r\n var hitsToReturn = [];\r\n\r\n if (this.el.sceneEl.is('ar-mode')) {\r\n if (!this.viewerSpace) return;\r\n\r\n let frame = this.el.sceneEl.frame;\r\n let xrViewerPose = frame.getViewerPose(this.refSpace);\r\n\r\n if (this.xrHitTestSource && xrViewerPose) {\r\n let hitTestResults = frame.getHitTestResults(this.xrHitTestSource);\r\n\r\n // Process AR hits.\r\n var hitsToReturn = [];\r\n for (var i = 0; hitTestResults && i < hitTestResults.length; i++) {\r\n let pose = hitTestResults[i].getPose(this.refSpace);\r\n transform.fromArray(pose.transform.matrix);\r\n hitpoint.setFromMatrixPosition(transform); //transform.decompose(hitpoint, hitquat, hitscale);\r\n raycasterEl.object3D.getWorldPosition(worldpos);\r\n\r\n hitsToReturn.push({\r\n distance: hitpoint.distanceTo(worldpos),\r\n point: hitpoint.clone(), // Vector3\r\n object: (el && el.object3D) || this.el.sceneEl.object3D\r\n/*\r\n // We don't have any of these properties...\r\n face: undefined, // Face3\r\n faceIndex: undefined,\r\n index: undefined,\r\n uv: undefined // Vector2\r\n*/\r\n });\r\n }\r\n }\r\n }\r\n\r\n return hitsToReturn;\r\n }\r\n })(),\r\n\r\n // Link to image marker and anchor support.\r\n\r\n addImage: function (name, url, physicalWidth) {\r\n if (!this.arDisplay) { return null; }\r\n\r\n return null;\r\n },\r\n\r\n removeImage: function (name) {\r\n if (!this.arDisplay) { return null; }\r\n\r\n return null;\r\n },\r\n\r\n getAnchors: function () {\r\n return Array.from(this.anchors_.values());\r\n },\r\n\r\n // Use planes to do synchronous hit test.\r\n\r\n getPlanes: function () {\r\n return Array.from(this.planes_.values());\r\n }\r\n});\r\n"],"sourceRoot":""}