diff --git a/dist-footer.js b/dist-footer.js
new file mode 100644
index 0000000..303b13a
--- /dev/null
+++ b/dist-footer.js
@@ -0,0 +1,22 @@
+
+XRDisplay = window.XRDisplay
+XRSession = window.XRSession
+XRSessionCreateParameters = window.XRSessionCreateParameters
+Reality = window.Reality
+XRPointCloud = window.XRPointCloud
+XRLightEstimate = window.XRLightEstimate
+XRAnchor = window.XRAnchor;
+XRPlaneAnchor = window.XRPlaneAnchor;
+XRFaceAnchor = window.XRFaceAnchor;
+XRImageAnchor = window.XRImageAnchor;
+XRAnchorOffset = window.XRAnchorOffset;
+XRStageBounds = window.XRStageBounds;
+XRStageBoundsPoint = window.XRStageBoundsPoint;
+XRPresentationFrame = window.XRPresentationFrame;
+XRView = window.XRView;
+XRViewport = window.XRViewport;
+XRCoordinateSystem = window.XRCoordinateSystem;
+XRViewPose = window.XRViewPose;
+XRLayer = window.XRLayer;
+XRWebGLLayer = window.XRWebGLLayer;
+XRVideoFrame = window.XRVideoFrame;
diff --git a/dist-header.js b/dist-header.js
new file mode 100644
index 0000000..431400f
--- /dev/null
+++ b/dist-header.js
@@ -0,0 +1,25 @@
+/* if there is a navigator.xr, clear it out */
+if(typeof navigator.xr != 'undefined') {
+ if(typeof XRDisplay != 'undefined') { XRDisplay = null }
+ if(typeof XRSession != 'undefined') { XRSession = null }
+ if(typeof XRSessionCreateParameters != 'undefined') { XRSessionCreateParameters = null }
+ if(typeof Reality != 'undefined') { Reality = null }
+ if(typeof XRPointCloud != 'undefined') { XRPointCloud = null }
+ if(typeof XRLightEstimate != 'undefined') { XRLightEstimate = null }
+ if(typeof XRAnchor != 'undefined') { XRAnchor = null }
+ if(typeof XRPlaneAnchor != 'undefined') { XRPlaneAnchor = null }
+ if(typeof XRFaceAnchor != 'undefined') { XRFaceAnchor = null }
+ if(typeof XRImageAnchor != 'undefined') { XRImageAnchor = null }
+ if(typeof XRAnchorOffset != 'undefined') { XRAnchorOffset = null }
+ if(typeof XRStageBounds != 'undefined') { XRStageBounds = null }
+ if(typeof XRStageBoundsPoint != 'undefined') { XRStageBoundsPoint = null }
+ if(typeof XRPresentationFrame != 'undefined') { XRPresentationFrame = null }
+ if(typeof XRView != 'undefined') { XRView = null }
+ if(typeof XRViewport != 'undefined') { XRViewport = null }
+ if(typeof XRCoordinateSystem != 'undefined') { XRCoordinateSystem = null }
+ if(typeof XRViewPose != 'undefined') { XRViewPose = null }
+ if(typeof XRLayer != 'undefined') { XRLayer = null }
+ if(typeof XRWebGLLayer != 'undefined') { XRWebGLLayer = null }
+ if(typeof XRVideoFrame != 'undefined') { XRVideoFrame = null }
+ //navigator.xr = null;
+}
\ No newline at end of file
diff --git a/examples/ar_anchors/index.html b/examples/ar_anchors/index.html
index 33ceca0..a12fabc 100644
--- a/examples/ar_anchors/index.html
+++ b/examples/ar_anchors/index.html
@@ -35,8 +35,11 @@
+
+
diff --git a/examples/ar_simplest/index.html b/examples/ar_simplest/index.html
index e26679d..ac4d18a 100644
--- a/examples/ar_simplest/index.html
+++ b/examples/ar_simplest/index.html
@@ -28,8 +28,11 @@
+
+
diff --git a/examples/boombox/index.html b/examples/boombox/index.html
index ef4ef86..f160df4 100644
--- a/examples/boombox/index.html
+++ b/examples/boombox/index.html
@@ -28,8 +28,11 @@
+
+
diff --git a/examples/face_tracking/index.html b/examples/face_tracking/index.html
index e1cfc4a..d14b217 100644
--- a/examples/face_tracking/index.html
+++ b/examples/face_tracking/index.html
@@ -26,8 +26,11 @@
-
-
+
+
diff --git a/examples/hit_test/index.html b/examples/hit_test/index.html
index 50a6ffa..710c5c1 100644
--- a/examples/hit_test/index.html
+++ b/examples/hit_test/index.html
@@ -30,8 +30,11 @@
+
+
diff --git a/examples/image_detection/index.html b/examples/image_detection/index.html
index c46efa6..4c44e82 100644
--- a/examples/image_detection/index.html
+++ b/examples/image_detection/index.html
@@ -39,9 +39,11 @@
-
-
-
+
+
@@ -89,7 +91,7 @@
this.duckyCreated = false
this.imageDetectionCreationRequested = false
- this.imageActivateDection = false;
+ this.imageActivateDetection = false;
this.imageActivated = false;
loadGLTF('./DuckyMesh.glb').then(gltf => {
@@ -123,20 +125,20 @@
this.resetButton.innerText = 'Reset'
this.el.appendChild(this.resetButton)
this.resetButton.addEventListener('click', ev => {
- this.imageActivateDection = true;
+ this.imageActivateDetection = true;
this.removeAnchoredNode(this.ducky)
})
// ready to go!
- this.imageActivateDection = true;
+ this.imageActivateDetection = true;
}).catch(error => {
console.error(`error creating ducky: ${error}`)
})
}
- if (!this.imageActivated && this.imageActivateDection) {
+ if (!this.imageActivated && this.imageActivateDetection) {
this.imageActivated = true;
- this.imageActivateDection = false;
+ this.imageActivateDetection = false;
this.session.activateDetectionImage(hubsImageName).then(imageAnchorTransform => {
this.imageActivated = false;
diff --git a/examples/light/index.html b/examples/light/index.html
index 9626655..508ea16 100644
--- a/examples/light/index.html
+++ b/examples/light/index.html
@@ -30,8 +30,11 @@
+
+
diff --git a/examples/opencv-aruco/index.html b/examples/opencv-aruco/index.html
index 009723b..63746c1 100644
--- a/examples/opencv-aruco/index.html
+++ b/examples/opencv-aruco/index.html
@@ -44,8 +44,11 @@
+
+
diff --git a/examples/opencv-face/index.html b/examples/opencv-face/index.html
index 6d63357..ae559c3 100644
--- a/examples/opencv-face/index.html
+++ b/examples/opencv-face/index.html
@@ -57,8 +57,11 @@
+
+
diff --git a/examples/peoples/index.html b/examples/peoples/index.html
index 2780b71..387b847 100644
--- a/examples/peoples/index.html
+++ b/examples/peoples/index.html
@@ -44,8 +44,11 @@
+
+
diff --git a/examples/persistence/index.html b/examples/persistence/index.html
new file mode 100644
index 0000000..f9b29c7
--- /dev/null
+++ b/examples/persistence/index.html
@@ -0,0 +1,242 @@
+
+
+
+ Hit test example
+
+
+
+
+
+
+
+
+
+
+
+
+
Hit Test with Persistence
+
(click to dismiss)
+
Find anchors by searching on tap events.
+
+
+
+
diff --git a/examples/persistence/screenshot.jpeg b/examples/persistence/screenshot.jpeg
new file mode 100644
index 0000000..23ba81c
Binary files /dev/null and b/examples/persistence/screenshot.jpeg differ
diff --git a/examples/reticle/index.html b/examples/reticle/index.html
index 502e39f..d338904 100644
--- a/examples/reticle/index.html
+++ b/examples/reticle/index.html
@@ -30,8 +30,11 @@
+
+
diff --git a/examples/sensing/index.html b/examples/sensing/index.html
index b8b2574..24ab61d 100644
--- a/examples/sensing/index.html
+++ b/examples/sensing/index.html
@@ -25,8 +25,11 @@
-
-
+
+
@@ -89,6 +92,8 @@
this.listenerSetup = true
this.session.addEventListener(XRSession.NEW_WORLD_ANCHOR, this._handleNewWorldAnchor.bind(this))
this.session.addEventListener(XRSession.UPDATE_WORLD_ANCHOR, this._handleUpdateWorldAnchor.bind(this))
+ this.session.addEventListener(XRSession.REMOVE_WORLD_ANCHOR, this._handleRemoveWorldAnchor.bind(this))
+
}
}
diff --git a/examples/simplecv/index.html b/examples/simplecv/index.html
index 947fdd8..33f6c0b 100644
--- a/examples/simplecv/index.html
+++ b/examples/simplecv/index.html
@@ -47,8 +47,11 @@
+
+
diff --git a/examples/vr_simplest/index.html b/examples/vr_simplest/index.html
index ac64e54..2edec0c 100644
--- a/examples/vr_simplest/index.html
+++ b/examples/vr_simplest/index.html
@@ -36,8 +36,11 @@
+
+
diff --git a/index.html b/index.html
index 1ced9bf..4504fcb 100644
--- a/index.html
+++ b/index.html
@@ -296,6 +296,14 @@
+
+ Map Sharing and Persistence
+ source
+ Small test app to see if ARKit Map Sharing is working.
+
+
+
+
diff --git a/package.json b/package.json
index b8af6c8..7e5c670 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,9 @@
"babel-loader": "^7.1.1",
"babel-preset-env": "^1.6.0",
"http-server": "^0.10.0",
- "webpack": "^3.5.5"
+ "webpack": "^3.5.5",
+ "wrapper-webpack-plugin": "^1.0.0"
+ },
+ "dependencies": {
}
}
diff --git a/polyfill/Reality.js b/polyfill/Reality.js
index a8bcd5c..e0bff3d 100644
--- a/polyfill/Reality.js
+++ b/polyfill/Reality.js
@@ -28,14 +28,14 @@ export default class Reality extends EventHandlerBase {
Called when at least one active XRSession is using this Reality
*/
_start(parameters){
- throw new Error('Exending classes should implement _start')
+ throw new Error('Extending classes should implement _start')
}
/*
Called when no more active XRSessions are using this Reality
*/
_stop(){
- throw new Error('Exending classes should implement _stop')
+ throw new Error('Extending classes should implement _stop')
}
/*
@@ -63,7 +63,7 @@ export default class Reality extends EventHandlerBase {
*/
_addAnchor(anchor, display){
// returns DOMString anchor UID
- throw new Error('Exending classes should implement _addAnchor')
+ throw new Error('Extending classes should implement _addAnchor')
}
/*
@@ -72,15 +72,15 @@ export default class Reality extends EventHandlerBase {
normalized screen x and y are in range 0..1, with 0,0 at top left and 1,1 at bottom right
*/
_findAnchor(normalizedScreenX, normalizedScreenY, display){
- throw new Error('Exending classes should implement _findAnchor')
+ throw new Error('Extending classes should implement _findAnchor')
}
_createImageAnchor(uid, buffer, width, height, physicalWidthInMeters) {
- throw new Error('Exending classes should implement _createImageAnchor')
+ throw new Error('Extending classes should implement _createImageAnchor')
}
activateDetectionImage(uid, display) {
- throw new Error('Exending classes should implement _activateDetectionImage')
+ throw new Error('Extending classes should implement _activateDetectionImage')
}
/*
@@ -88,7 +88,7 @@ export default class Reality extends EventHandlerBase {
returns a Promise that resolves either to an AnchorOffset or null if the floor level is unknown
*/
_findFloorAnchor(display, uid=null){
- throw new Error('Exending classes should implement _findFloorAnchor')
+ throw new Error('Extending classes should implement _findFloorAnchor')
}
_getAnchor(uid){
@@ -97,17 +97,28 @@ export default class Reality extends EventHandlerBase {
_removeAnchor(uid){
// returns void
- throw new Error('Exending classes should implement _removeAnchor')
+ throw new Error('Extending classes should implement _removeAnchor')
}
_hitTestNoAnchor(normalizedScreenX, normalizedScreenY, display){
- throw new Error('Exending classes should implement _hitTestNoAnchor')
+ throw new Error('Extending classes should implement _hitTestNoAnchor')
}
_getLightAmbientIntensity(){
- throw new Error('Exending classes should implement _getLightAmbientIntensity')
+ throw new Error('Extending classes should implement _getLightAmbientIntensity')
}
+ _getWorldMap() {
+ throw new Error('Extending classes should implement _getWorldMap')
+ }
+
+ _setWorldMap(worldMap) {
+ throw new Error('Extending classes should implement _setWorldMap')
+ }
+
+ _getWorldMappingStatus() {
+ throw new Error('Extending classes should implement _getWorldMappingStatus')
+ }
// attribute EventHandler onchange;
}
diff --git a/polyfill/XRDisplay.js b/polyfill/XRDisplay.js
index 81f729a..e7bb5b9 100644
--- a/polyfill/XRDisplay.js
+++ b/polyfill/XRDisplay.js
@@ -101,6 +101,8 @@ export default class XRDisplay extends EventHandlerBase {
//attribute EventHandler ondeactivate;
}
+XRDisplay.VIDEO_FRAME = 'videoFrame'
+XRDisplay.TRACKING_CHANGED = 'tracking-changed'
XRDisplay.NEW_WORLD_ANCHOR = 'world-anchor'
XRDisplay.UPDATE_WORLD_ANCHOR = 'update-world-anchor'
XRDisplay.REMOVE_WORLD_ANCHOR = 'remove-world-anchor'
diff --git a/polyfill/XRPolyfill.js b/polyfill/XRPolyfill.js
index 5ed242e..65f7214 100644
--- a/polyfill/XRPolyfill.js
+++ b/polyfill/XRPolyfill.js
@@ -1,24 +1,24 @@
-import XRDisplay from './XRDisplay.js'
-import XRSession from './XRSession.js'
-import XRSessionCreateParameters from './XRSessionCreateParameters.js'
-import Reality from './Reality.js'
-import XRPointCloud from './XRPointCloud.js'
-import XRLightEstimate from './XRLightEstimate.js'
-import XRAnchor from './XRAnchor.js'
-import XRPlaneAnchor from './XRPlaneAnchor.js'
-import XRFaceAnchor from './XRFaceAnchor.js'
-import XRImageAnchor from './XRImageAnchor.js'
-import XRAnchorOffset from './XRAnchorOffset.js'
-import XRStageBounds from './XRStageBounds.js'
-import XRStageBoundsPoint from './XRStageBoundsPoint.js'
-import XRPresentationFrame from './XRPresentationFrame.js'
-import XRView from './XRView.js'
-import XRViewport from './XRViewport.js'
-import XRCoordinateSystem from './XRCoordinateSystem.js'
-import XRViewPose from './XRViewPose.js'
-import XRLayer from './XRLayer.js'
-import XRWebGLLayer from './XRWebGLLayer.js'
-import XRVideoFrame from './XRVideoFrame.js'
+import _XRDisplay from './XRDisplay.js'
+import _XRSession from './XRSession.js'
+import _XRSessionCreateParameters from './XRSessionCreateParameters.js'
+import _Reality from './Reality.js'
+import _XRPointCloud from './XRPointCloud.js'
+import _XRLightEstimate from './XRLightEstimate.js'
+import _XRAnchor from './XRAnchor.js'
+import _XRPlaneAnchor from './XRPlaneAnchor.js'
+import _XRFaceAnchor from './XRFaceAnchor.js'
+import _XRImageAnchor from './XRImageAnchor.js'
+import _XRAnchorOffset from './XRAnchorOffset.js'
+import _XRStageBounds from './XRStageBounds.js'
+import _XRStageBoundsPoint from './XRStageBoundsPoint.js'
+import _XRPresentationFrame from './XRPresentationFrame.js'
+import _XRView from './XRView.js'
+import _XRViewport from './XRViewport.js'
+import _XRCoordinateSystem from './XRCoordinateSystem.js'
+import _XRViewPose from './XRViewPose.js'
+import _XRLayer from './XRLayer.js'
+import _XRWebGLLayer from './XRWebGLLayer.js'
+import _XRVideoFrame from './XRVideoFrame.js'
import EventHandlerBase from './fill/EventHandlerBase.js'
import FlatDisplay from './display/FlatDisplay.js'
@@ -35,27 +35,49 @@ so you can safely include this script in any page.
class XRPolyfill extends EventHandlerBase {
constructor(){
super()
- window.XRDisplay = XRDisplay
- window.XRSession = XRSession
- window.XRSessionCreateParameters = XRSessionCreateParameters
- window.Reality = Reality
- window.XRPointCloud = XRPointCloud
- window.XRLightEstimate = XRLightEstimate
- window.XRAnchor = XRAnchor
- window.XRPlaneAnchor = XRPlaneAnchor
- window.XRFaceAnchor = XRFaceAnchor
- window.XRImageAnchor = XRImageAnchor
- window.XRAnchorOffset = XRAnchorOffset
- window.XRStageBounds = XRStageBounds
- window.XRStageBoundsPoint = XRStageBoundsPoint
- window.XRPresentationFrame = XRPresentationFrame
- window.XRView = XRView
- window.XRViewport = XRViewport
- window.XRCoordinateSystem = XRCoordinateSystem
- window.XRViewPose = XRViewPose
- window.XRLayer = XRLayer
- window.XRWebGLLayer = XRWebGLLayer
- window.XRVideoFrame = XRVideoFrame
+ window.XRDisplay = _XRDisplay
+ window.XRSession = _XRSession
+ window.XRSessionCreateParameters = _XRSessionCreateParameters
+ window.Reality = _Reality
+ window.XRPointCloud = _XRPointCloud
+ window.XRLightEstimate = _XRLightEstimate
+ window.XRAnchor = _XRAnchor
+ window.XRPlaneAnchor = _XRPlaneAnchor
+ window.XRFaceAnchor = _XRFaceAnchor
+ window.XRImageAnchor = _XRImageAnchor
+ window.XRAnchorOffset = _XRAnchorOffset
+ window.XRStageBounds = _XRStageBounds
+ window.XRStageBoundsPoint = _XRStageBoundsPoint
+ window.XRPresentationFrame = _XRPresentationFrame
+ window.XRView = _XRView
+ window.XRViewport = _XRViewport
+ window.XRCoordinateSystem = _XRCoordinateSystem
+ window.XRViewPose = _XRViewPose
+ window.XRLayer = _XRLayer
+ window.XRWebGLLayer = _XRWebGLLayer
+ window.XRVideoFrame = _XRVideoFrame
+
+ XRDisplay = window.XRDisplay
+ XRSession = window.XRSession
+ XRSessionCreateParameters = window.XRSessionCreateParameters
+ Reality = window.Reality
+ XRPointCloud = window.XRPointCloud
+ XRLightEstimate = window.XRLightEstimate
+ XRAnchor = window.XRAnchor;
+ XRPlaneAnchor = window.XRPlaneAnchor;
+ XRFaceAnchor = window.XRFaceAnchor;
+ XRImageAnchor = window.XRImageAnchor;
+ XRAnchorOffset = window.XRAnchorOffset;
+ XRStageBounds = window.XRStageBounds;
+ XRStageBoundsPoint = window.XRStageBoundsPoint;
+ XRPresentationFrame = window.XRPresentationFrame;
+ XRView = window.XRView;
+ XRViewport = window.XRViewport;
+ XRCoordinateSystem = window.XRCoordinateSystem;
+ XRViewPose = window.XRViewPose;
+ XRLayer = window.XRLayer;
+ XRWebGLLayer = window.XRWebGLLayer;
+ XRVideoFrame = window.XRVideoFrame;
this._getVRDisplaysFinished = false;
@@ -125,4 +147,6 @@ class XRPolyfill extends EventHandlerBase {
}
/* Install XRPolyfill if window.XR does not exist */
-if(typeof navigator.XR === 'undefined') navigator.XR = new XRPolyfill()
+if(typeof navigator.XR === 'undefined') {
+ navigator.XR = new XRPolyfill()
+}
diff --git a/polyfill/XRPresentationFrame.js b/polyfill/XRPresentationFrame.js
index f74ae84..9a5a315 100644
--- a/polyfill/XRPresentationFrame.js
+++ b/polyfill/XRPresentationFrame.js
@@ -56,13 +56,13 @@ export default class XRPresentationFrame {
/*
Create an anchor at a specific position defined by XRAnchor.coordinates
*/
- addAnchor(coordinateSystem, position=[0,0,0], orientation=[0,0,0,1]){
+ addAnchor(coordinateSystem, position=[0,0,0], orientation=[0,0,0,1],uid=null){
//DOMString? addAnchor(XRCoordinateSystem, position, orientation);
let poseMatrix = MatrixMath.mat4_fromRotationTranslation(new Float32Array(16), orientation, position)
MatrixMath.mat4_multiply(poseMatrix, coordinateSystem.getTransformTo(this._session._display._trackerCoordinateSystem), poseMatrix)
let anchorCoordinateSystem = new XRCoordinateSystem(this._session._display, XRCoordinateSystem.TRACKER)
anchorCoordinateSystem._relativeMatrix = poseMatrix
- return this._session.reality._addAnchor(new XRAnchor(anchorCoordinateSystem), this._session.display)
+ return this._session.reality._addAnchor(new XRAnchor(anchorCoordinateSystem, uid), this._session.display)
}
// normalized screen x and y are in range 0..1, with 0,0 at top left and 1,1 at bottom right
diff --git a/polyfill/XRSession.js b/polyfill/XRSession.js
index c3df0b4..dc331c0 100644
--- a/polyfill/XRSession.js
+++ b/polyfill/XRSession.js
@@ -28,6 +28,7 @@ export default class XRSession extends EventHandlerBase {
this._tempMatrix = MatrixMath.mat4_generateIdentity()
this._tempMatrix2 = MatrixMath.mat4_generateIdentity()
+ this._display.addEventListener(XRDisplay.TRACKING_CHANGED, this._handleTrackingChanged.bind(this))
this._display.addEventListener(XRDisplay.NEW_WORLD_ANCHOR, this._handleNewWorldAnchor.bind(this))
this._display.addEventListener(XRDisplay.REMOVE_WORLD_ANCHOR, this._handleRemoveWorldAnchor.bind(this))
this._display.addEventListener(XRDisplay.UPDATE_WORLD_ANCHOR, this._handleUpdateWorldAnchor.bind(this))
@@ -106,7 +107,8 @@ export default class XRSession extends EventHandlerBase {
// new anchor each minute
if (this._frameAnchors.length == 0 || (this._frameAnchors[0].timestamp + 60000) < frame.timestamp) {
const headCoordinateSystem = frame.getCoordinateSystem(XRCoordinateSystem.EYE_LEVEL)
- const anchorUID = frame.addAnchor(headCoordinateSystem, [0,-1,0])
+ const anchorUID = frame.addAnchor(headCoordinateSystem, [0,-1,0], [0,0,0,1],
+ 'cameraAnchor-' + new Date().getTime() + '-' + Math.floor((Math.random() * Number.MAX_SAFE_INTEGER)));
const anchor = frame.getAnchor(anchorUID)
anchor.timestamp = frame.timestamp;
this._frameAnchors.unshift(anchor)
@@ -245,19 +247,23 @@ export default class XRSession extends EventHandlerBase {
let xrAnchor = event.detail
//console.log(`New world anchor: ${JSON.stringify(xrAnchor)}`)
- try {
- this.dispatchEvent(
- new CustomEvent(
- XRSession.NEW_WORLD_ANCHOR,
- {
- source: this,
- detail: xrAnchor
- }
+ if (!xrAnchor.uid.startsWith('cameraAnchor-')) {
+ try {
+ this.dispatchEvent(
+ new CustomEvent(
+ XRSession.NEW_WORLD_ANCHOR,
+ {
+ source: this,
+ detail: xrAnchor
+ }
+ )
)
- )
- } catch(e) {
- console.error('NEW_WORLD_ANCHOR event error', e)
- }
+ } catch(e) {
+ console.error('NEW_WORLD_ANCHOR event error', e)
+ }
+ } else {
+ console.log('not passing NEW_WORLD_ANCHOR event to app for ', xrAnchor.uid)
+ }
}
_handleUpdateWorldAnchor(event) {
@@ -297,6 +303,34 @@ export default class XRSession extends EventHandlerBase {
console.error('REMOVE_WORLD_ANCHOR event error', e)
}
}
+
+ _handleTrackingChanged(event) {
+ try {
+ this.dispatchEvent(
+ new CustomEvent(
+ XRSession.TRACKING_CHANGED,
+ {
+ source: this,
+ detail: event.detail
+ }
+ )
+ )
+ } catch(e) {
+ console.error('TRACKING_CHANGED event error', e)
+ }
+ }
+
+ getWorldMap() {
+ return this.reality._getWorldMap()
+ }
+
+ setWorldMap(worldMap) {
+ return this.reality._setWorldMap(worldMap)
+ }
+
+ getWorldMappingStatus() {
+ return this.reality._getWorldMappingStatus()
+ }
/*
attribute EventHandler onblur;
attribute EventHandler onfocus;
@@ -314,6 +348,8 @@ XRSession.AUGMENTATION = 'augmentation'
XRSession.TYPES = [XRSession.REALITY, XRSession.AUGMENTATION]
+XRSession.TRACKING_CHANGED = 'tracking-changed'
+
XRSession.NEW_WORLD_ANCHOR = 'world-anchor'
XRSession.UPDATE_WORLD_ANCHOR = 'update-world-anchor'
XRSession.REMOVE_WORLD_ANCHOR = 'remove-world-anchor'
\ No newline at end of file
diff --git a/polyfill/display/FlatDisplay.js b/polyfill/display/FlatDisplay.js
index dbd1290..42dce54 100644
--- a/polyfill/display/FlatDisplay.js
+++ b/polyfill/display/FlatDisplay.js
@@ -314,6 +314,20 @@ export default class FlatDisplay extends XRDisplay {
// #define WEB_AR_TRACKING_STATE_LIMITED_MOTION @"ar_tracking_limited_excessive_motion"
// #define WEB_AR_TRACKING_STATE_LIMITED_FEATURES @"ar_tracking_limited_insufficient_features"
// #define WEB_AR_TRACKING_STATE_NOT_AVAILABLE @"ar_tracking_not_available"
+ // #define WEB_AR_TRACKING_STATE_RELOCALIZING @"ar_tracking_relocalizing"
+ try {
+ this.dispatchEvent(
+ new CustomEvent(
+ XRDisplay.TRACKING_CHANGED,
+ {
+ source: this,
+ detail: ev.detail
+ }
+ )
+ );
+ } catch (e) {
+ console.error('trackingChanged callback error', e);
+ }
}
@@ -322,13 +336,13 @@ export default class FlatDisplay extends XRDisplay {
try {
this.dispatchEvent(
new CustomEvent(
- "videoFrame",
- {
- source: this,
- detail: ev.detail
- }
- )
- )
+ XRDisplay.VIDEO_FRAME,
+ {
+ source: this,
+ detail: ev.detail
+ }
+ )
+ )
} catch(e) {
console.error('computer vision callback error', e)
}
diff --git a/polyfill/platform/ARKitWrapper.js b/polyfill/platform/ARKitWrapper.js
index 2289212..efdebd8 100644
--- a/polyfill/platform/ARKitWrapper.js
+++ b/polyfill/platform/ARKitWrapper.js
@@ -88,6 +88,7 @@ export default class ARKitWrapper extends EventHandlerBase {
this._timeOffsetComputed = false;
this.timestamp = 0;
+ this.worldMappingStatus = ARKitWrapper.WEB_AR_WORLDMAPPING_NOT_AVAILABLE;
this._globalCallbacksMap = {} // Used to map a window.arkitCallback method name to an ARKitWrapper.on* method name
// Set up the window.arkitCallback methods that the ARKit bridge depends on
@@ -684,6 +685,43 @@ export default class ARKitWrapper extends EventHandlerBase {
})
}
+ /***
+ * getWorldMap requests a worldmap from the platform
+ * @returns {Promise} a promise that will be resolved when the worldMap has been retrieved, or an error otherwise
+ */
+ getWorldMap() {
+ return new Promise((resolve, reject) => {
+ if (!this._isInitialized){
+ reject(new Error('ARKit is not initialized'));
+ return;
+ }
+
+ window.webkit.messageHandlers.getWorldMap.postMessage({
+ callback: this._createPromiseCallback('getWorldMap', resolve)
+ })
+ })
+ }
+
+ /***
+ * setWorldMap requests a worldmap for the platform be set
+ * @returns {Promise} a promise that will be resolved when the worldMap has been set, or an error otherwise
+ */
+ setWorldMap(worldMap) {
+ return new Promise((resolve, reject) => {
+ if (!this._isInitialized){
+ reject(new Error('ARKit is not initialized'));
+ return;
+ }
+
+ window.webkit.messageHandlers.setWorldMap.postMessage({
+ worldMap: worldMap.worldMap,
+ callback: this._createPromiseCallback('setWorldMap', resolve)
+ })
+ })
+ }
+
+
+
/*
RACE CONDITION: call stop, then watch: stop does not set isWatching false until it gets a message back from the app,
so watch will return and not issue a watch command. May want to set isWatching false immediately?
@@ -858,7 +896,7 @@ export default class ARKitWrapper extends EventHandlerBase {
this.lightIntensity = data.light_intensity;
this.viewMatrix_ = data.camera_view;
this.projectionMatrix_ = data.projection_camera;
-
+ this.worldMappingStatus = data.worldMappingStatus;
if(data.newObjects.length){
for (let i = 0; i < data.newObjects.length; i++) {
const element = data.newObjects[i];
@@ -906,7 +944,7 @@ export default class ARKitWrapper extends EventHandlerBase {
} else {
plane.center = element.plane_center;
plane.extent[0] = element.plane_extent.x
- plane.extent[1] = element.plane_extent.y
+ plane.extent[1] = element.plane_extent.z
plane.modelMatrix = element.transform;
plane.alignment = element.plane_alignment
}
@@ -1286,6 +1324,12 @@ ARKitWrapper.ORIENTATION_RIGHT = 6 // 0th row on right, 0th column at
ARKitWrapper.ORIENTATION_RIGHT_MIRRORED = 7 // 0th row on right, 0th column on bottom
ARKitWrapper.ORIENTATION_LEFT = 8 // 0th row on left, 0th column at bottom - 90 deg CCW
+// world mapping status
+ARKitWrapper.WEB_AR_WORLDMAPPING_NOT_AVAILABLE = "ar_worldmapping_not_available"
+ARKitWrapper.WEB_AR_WORLDMAPPING_LIMITED = "ar_worldmapping_limited"
+ARKitWrapper.WEB_AR_WORLDMAPPING_EXTENDING = "ar_worldmapping_extending"
+ARKitWrapper.WEB_AR_WORLDMAPPING_MAPPED = "ar_worldmapping_mapped"
+
// hit test types
ARKitWrapper.HIT_TEST_TYPE_FEATURE_POINT = 1
ARKitWrapper.HIT_TEST_TYPE_ESTIMATED_HORIZONTAL_PLANE = 2
diff --git a/polyfill/reality/CameraReality.js b/polyfill/reality/CameraReality.js
index ac95c24..f70b83e 100644
--- a/polyfill/reality/CameraReality.js
+++ b/polyfill/reality/CameraReality.js
@@ -697,6 +697,54 @@ export default class CameraReality extends Reality {
}
}
+ _getWorldMappingStatus(){
+ if(this._arKitWrapper !== null){
+ return this._arKitWrapper.worldMappingStatus;
+ }else{
+ // No platform support for ligth estimation
+ return null;
+ }
+ }
+
+ /**
+ * retrieves a worldMap from the platform, if possible
+ * @returns a promise when the worldMap has been retrieved
+ * @private
+ */
+ _getWorldMap() {
+ return new Promise((resolve, reject) => {
+ if (this._arKitWrapper) {
+ this._arKitWrapper.getWorldMap().then(ARKitWorldMap => {
+ if (ARKitWorldMap.saved === true) {
+ resolve(ARKitWorldMap.worldMap)
+ } else if (ARKitWorldMap.error !== null) {
+ reject(ARKitWorldMap.error)
+ } else {
+ reject(null)
+ }
+ })
+ } else {
+ reject('ARKit not supported')
+ }
+ })
+ }
+
+ /**
+ * sets a worldMap for the platform, if possible
+ * @param worldMap a platform specific worldmap
+ * @returns a promise when the worldMap has been set
+ * @private
+ */
+ _setWorldMap(worldMap) {
+ if (this._arKitWrapper) {
+ return this._arKitWrapper.setWorldMap(worldMap)
+ } else {
+ return new Promise((resolve, reject) => {
+ reject(new Error('setWorldMap not supported'));
+ })
+ }
+ }
+
_getTimeStamp(timestamp) {
if(this._arKitWrapper !== null){
return this._arKitWrapper.timestamp;
diff --git a/webpack.config.js b/webpack.config.js
index 1e4da39..5d8a48e 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,25 +1,37 @@
const path = require('path');
+const fs = require('fs');
+
+WrapperPlugin = require('wrapper-webpack-plugin');
+
+const headerDoc = fs.readFileSync('./dist-header.js', 'utf8');
+const footerDoc = fs.readFileSync('./dist-footer.js', 'utf8');
var xrPolyfill = {
- entry: './polyfill/XRPolyfill.js',
- output: {
- filename: 'webxr-polyfill.js',
- path: path.resolve(__dirname, 'dist')
- },
+ entry: './polyfill/XRPolyfill.js',
+ output: {
+ filename: 'webxr-polyfill.js',
+ path: path.resolve(__dirname, 'dist')
+ },
+ plugins: [
+ new WrapperPlugin({
+ header: headerDoc,
+ footer: footerDoc
+ })
+ ],
module: {
- rules: [
+ rules: [
{
- test: /\.js$/,
- include: [
- path.resolve(__dirname, "polyfill"),
- ],
- use: {
- loader: 'babel-loader',
- options: {
- presets: ['env']
+ test: /\.js$/,
+ include: [
+ path.resolve(__dirname, "polyfill"),
+ ],
+ use: {
+ loader: 'babel-loader',
+ options: {
+ presets: ['env']
+ }
}
}
- }
]
},
resolve: {
@@ -36,17 +48,17 @@ var xrVideoWorker = {
module: {
rules: [
{
- test: /\.js$/,
- include: [
- path.resolve(__dirname, "polyfill"),
- ],
- use: {
- loader: 'babel-loader',
- options: {
- presets: ['env']
+ test: /\.js$/,
+ include: [
+ path.resolve(__dirname, "polyfill"),
+ ],
+ use: {
+ loader: 'babel-loader',
+ options: {
+ presets: ['env']
+ }
}
}
- }
]
},
resolve: {