Merge pull request #23 from andyps/master
Refactor ARKitWrapper to promises
This commit is contained in:
Коммит
f267fd78db
|
@ -148,9 +148,7 @@ export default class FlatDisplay extends XRDisplay {
|
|||
location: true,
|
||||
camera: true,
|
||||
objects: true,
|
||||
debug: false,
|
||||
h_plane: false,
|
||||
hit_test_result: 'hit_test_plane'
|
||||
light_intensity: true
|
||||
})
|
||||
}, 1000)
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ export default class ARKitWrapper extends EventHandlerBase {
|
|||
|
||||
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
|
||||
let callbackNames = ['onInit', 'onWatch', 'onStop', 'onHitTest', 'onAddAnchor']
|
||||
let callbackNames = ['onInit', 'onWatch']
|
||||
for(let i=0; i < callbackNames.length; i++){
|
||||
this._generateGlobalCallback(callbackNames[i], i)
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ export default class ARKitWrapper extends EventHandlerBase {
|
|||
resolve()
|
||||
return
|
||||
}
|
||||
let callback = () => {
|
||||
const callback = () => {
|
||||
this.removeEventListener(ARKitWrapper.INIT_EVENT, callback, false)
|
||||
resolve()
|
||||
}
|
||||
|
@ -149,42 +149,69 @@ export default class ARKitWrapper extends EventHandlerBase {
|
|||
Sends a hitTest message to ARKit to get hit testing results
|
||||
x, y - screen coordinates normalized to 0..1
|
||||
types - bit mask of hit testing types
|
||||
|
||||
Returns a promise that returns an array of hit results:
|
||||
[
|
||||
{
|
||||
type: hitTestType,
|
||||
world_transform: matrix4x4 - specifies the position and orientation relative to WCS,
|
||||
local_transform: matrix4x4 - the position and orientation of the hit test result relative to the nearest anchor or feature point,
|
||||
distance: distance to the detected plane,
|
||||
anchor: {uuid, transform, ...} - the anchor representing the detected surface, if any
|
||||
},
|
||||
...
|
||||
]
|
||||
@see https://developer.apple.com/documentation/arkit/arframe/2875718-hittest
|
||||
*/
|
||||
hitTest(x, y, types = ARKitWrapper.HIT_TEST_TYPE_ALL) {
|
||||
if (!this._isInitialized) {
|
||||
return false
|
||||
}
|
||||
window.webkit.messageHandlers.hitTest.postMessage({
|
||||
x: x,
|
||||
y: y,
|
||||
type: types,
|
||||
callback: this._globalCallbacksMap.onHitTest
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this._isInitialized) {
|
||||
reject(new Error('ARKit is not initialized'));
|
||||
return;
|
||||
}
|
||||
window.webkit.messageHandlers.hitTest.postMessage({
|
||||
x: x,
|
||||
y: y,
|
||||
type: types,
|
||||
callback: this._createPromiseCallback('hitTest', resolve)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
Sends an addAnchor message to ARKit
|
||||
Returns a promise that returns:
|
||||
{
|
||||
uuid - the anchor's uuid,
|
||||
transform - anchor transformation matrix
|
||||
}
|
||||
*/
|
||||
addAnchor(uuid, transform) {
|
||||
if (!this._isInitialized) {
|
||||
return false
|
||||
}
|
||||
window.webkit.messageHandlers.addAnchor.postMessage({
|
||||
uuid: uuid,
|
||||
transform: transform,
|
||||
callback: this._globalCallbacksMap.onAddAnchor
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this._isInitialized) {
|
||||
reject(new Error('ARKit is not initialized'));
|
||||
return;
|
||||
}
|
||||
window.webkit.messageHandlers.addAnchor.postMessage({
|
||||
uuid: uuid,
|
||||
transform: transform,
|
||||
callback: this._createPromiseCallback('addAnchor', resolve)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
If this instance is currently watching, send the stopAR message to ARKit to request that it stop sending data on onWatch
|
||||
*/
|
||||
stop() {
|
||||
if (!this._isWatching) {
|
||||
return
|
||||
}
|
||||
window.webkit.messageHandlers.stopAR.postMessage({
|
||||
callback: this._globalCallbacksMap.onStop
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this._isWatching) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
window.webkit.messageHandlers.stopAR.postMessage({
|
||||
callback: this._createPromiseCallback('stop', resolve)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -318,45 +345,25 @@ export default class ARKitWrapper extends EventHandlerBase {
|
|||
*/
|
||||
_onStop() {
|
||||
this._isWatching = false
|
||||
this.dispatchEvent(new CustomEvent(ARKitWrapper.STOP_EVENT, {
|
||||
source: this
|
||||
}))
|
||||
}
|
||||
|
||||
/*
|
||||
Callback from ARKit for when it does the work initiated by sending the addAnchor message from JS
|
||||
data: {
|
||||
uuid - the anchor's uuid,
|
||||
transform - anchor transformation matrix
|
||||
}
|
||||
*/
|
||||
_onAddAnchor(data) {
|
||||
this.dispatchEvent(new CustomEvent(ARKitWrapper.ADD_ANCHOR_EVENT, {
|
||||
source: this,
|
||||
detail: data
|
||||
}))
|
||||
_createPromiseCallback(action, resolve) {
|
||||
const callbackName = this._generateCallbackUID(action);
|
||||
window[callbackName] = (data) => {
|
||||
delete window[callbackName]
|
||||
const wrapperCallbackName = '_on' + action[0].toUpperCase() +
|
||||
action.slice(1);
|
||||
if (typeof(this[wrapperCallbackName]) == 'function') {
|
||||
this[wrapperCallbackName](data);
|
||||
}
|
||||
resolve(data)
|
||||
}
|
||||
return callbackName;
|
||||
}
|
||||
|
||||
/*
|
||||
Callback from ARKit for when it does the work initiated by sending the hitTest message from JS
|
||||
ARKit returns an array of hit results
|
||||
data: [
|
||||
{
|
||||
type: hitTestType,
|
||||
world_transform: matrix4x4 - specifies the position and orientation relative to WCS,
|
||||
local_transform: matrix4x4 - the position and orientation of the hit test result relative to the nearest anchor or feature point,
|
||||
distance: distance to the detected plane,
|
||||
anchor: {uuid, transform, ...} - the anchor representing the detected surface, if any
|
||||
},
|
||||
...
|
||||
]
|
||||
@see https://developer.apple.com/documentation/arkit/arframe/2875718-hittest
|
||||
*/
|
||||
_onHitTest(data) {
|
||||
this.dispatchEvent(new CustomEvent(ARKitWrapper.HIT_TEST_EVENT, {
|
||||
source: this,
|
||||
detail: data
|
||||
}))
|
||||
_generateCallbackUID(prefix) {
|
||||
return 'arkitCallback_' + prefix + '_' + new Date().getTime() +
|
||||
'_' + Math.floor((Math.random() * Number.MAX_SAFE_INTEGER))
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -377,15 +384,12 @@ export default class ARKitWrapper extends EventHandlerBase {
|
|||
// ARKitWrapper event names:
|
||||
ARKitWrapper.INIT_EVENT = 'arkit-init'
|
||||
ARKitWrapper.WATCH_EVENT = 'arkit-watch'
|
||||
ARKitWrapper.STOP_EVENT = 'arkit-stop'
|
||||
ARKitWrapper.ADD_ANCHOR_EVENT = 'arkit-add-anchor'
|
||||
ARKitWrapper.RECORD_START_EVENT = 'arkit-record-start'
|
||||
ARKitWrapper.RECORD_STOP_EVENT = 'arkit-record-stop'
|
||||
ARKitWrapper.DID_MOVE_BACKGROUND_EVENT = 'arkit-did-move-background'
|
||||
ARKitWrapper.WILL_ENTER_FOREGROUND_EVENT = 'arkit-will-enter-foreground'
|
||||
ARKitWrapper.INTERRUPTED_EVENT = 'arkit-interrupted'
|
||||
ARKitWrapper.INTERRUPTION_ENDED_EVENT = 'arkit-interruption-ended'
|
||||
ARKitWrapper.HIT_TEST_EVENT = 'arkit-hit-test'
|
||||
ARKitWrapper.SHOW_DEBUG_EVENT = 'arkit-show-debug'
|
||||
|
||||
// hit test types
|
||||
|
|
|
@ -83,7 +83,6 @@ export default class CameraReality extends Reality {
|
|||
if(this._initialized === false){
|
||||
this._initialized = true
|
||||
this._arKitWrapper = ARKitWrapper.GetOrCreate()
|
||||
this._arKitWrapper.addEventListener(ARKitWrapper.ADD_ANCHOR_EVENT, this._handleARKitAddObject.bind(this))
|
||||
this._arKitWrapper.addEventListener(ARKitWrapper.WATCH_EVENT, this._handleARKitWatch.bind(this))
|
||||
this._arKitWrapper.waitForInit().then(() => {
|
||||
this._arKitWrapper.watch()
|
||||
|
@ -138,8 +137,8 @@ export default class CameraReality extends Reality {
|
|||
}
|
||||
}
|
||||
|
||||
_handleARKitAddObject(ev){
|
||||
this._updateAnchorFromARKitUpdate(ev.detail.uuid, ev.detail)
|
||||
_handleARKitAddObject(anchorInfo){
|
||||
this._updateAnchorFromARKitUpdate(anchorInfo.uuid, anchorInfo)
|
||||
}
|
||||
|
||||
_updateAnchorFromARKitUpdate(uuid, anchorInfo){
|
||||
|
@ -156,7 +155,9 @@ export default class CameraReality extends Reality {
|
|||
// Convert coordinates to the stage coordinate system so that updating from ARKit transforms is simple
|
||||
anchor.coordinates = anchor.coordinates.getTransformedCoordinates(display._stageCoordinateSystem)
|
||||
if(this._arKitWrapper !== null){
|
||||
this._arKitWrapper.addAnchor(anchor.uid, anchor.coordinates.poseMatrix)
|
||||
this._arKitWrapper.addAnchor(anchor.uid, anchor.coordinates.poseMatrix).then(
|
||||
detail => this._handleARKitAddObject(detail)
|
||||
)
|
||||
}
|
||||
// ARCore as implemented in the browser does not offer anchors except on a surface, so we just use untracked anchors
|
||||
this._anchors.set(anchor.uid, anchor)
|
||||
|
|
Загрузка…
Ссылка в новой задаче