Use a tracker coordinate system instead of stage. Update examples so they function but next they need to use the (not yet implemented) floor anchors.

This commit is contained in:
Trevor F. Smith 2017-10-04 16:08:47 -07:00
Родитель a86bafcab0
Коммит 34e88a32ef
16 изменённых файлов: 95 добавлений и 116 удалений

Просмотреть файл

@ -57,9 +57,8 @@ The scene, camera, and renderer objects below are representative APIs that have
// Set up for the next frame // Set up for the next frame
session.requestFrame(frame => { handleFrame(frame) }) session.requestFrame(frame => { handleFrame(frame) })
// Get the pose for the world coordinate system // Get the pose for the HMD or handset tracker coordinate system
let stageCoordinateSystem = frame.getCoordinateSystem(XRCoordinateSystem.STAGE) let trackerCoordinateSystem = frame.getCoordinateSystem(XRCoordinateSystem.TRACKER)
let stagePose = frame.getViewPose(stageCoordinateSystem)
// Get the pose for the head // Get the pose for the head
let headCoordinateSystem = frame.getCoordinateSystem(XRCoordinateSystem.HEAD_MODEL) let headCoordinateSystem = frame.getCoordinateSystem(XRCoordinateSystem.HEAD_MODEL)
@ -126,11 +125,11 @@ You now have a couple of anchored nodes save in `anchoredNodes`, so during each
const anchor = frame.getAnchor(anchoredNode.anchorOffset.anchorUID) const anchor = frame.getAnchor(anchoredNode.anchorOffset.anchorUID)
// Get the offset coordinates relative to the anchor // Get the offset coordinates relative to the anchor
let offsetCoordinates = anchoredNode.anchorOffset.getTransformedCoordinates(anchor) let offsetCoordinates = anchoredNode.anchorOffset.getTransformedCoordinates(anchor)
// Now use the offset coordinates, possibly by converting to the stage coordinate system. // Now use the offset coordinates, possibly by converting to the tracker coordinate system.
if(offsetCoordinates.coordinateSystem.type === XRCoordinateSystem.STAGE){ if(offsetCoordinates.coordinateSystem.type === XRCoordinateSystem.TRACKER){
anchoredNode.node.matrix = offsetCoordinates.poseMatrix anchoredNode.node.matrix = offsetCoordinates.poseMatrix
} else { } else {
anchoredNode.node.matrix = offsetCoordinates.getTransformedCoordinates(stageCoordinateSystem).poseMatrix anchoredNode.node.matrix = offsetCoordinates.getTransformedCoordinates(trackerCoordinateSystem).poseMatrix
} }
} }

Просмотреть файл

@ -58,11 +58,11 @@
} }
// Called during construction // Called during construction
initializeStageGroup(){ initializeScene(){
this.stageGroup.add(new THREE.AmbientLight('#FFF', 0.2)) this.scene.add(new THREE.AmbientLight('#FFF', 0.2))
let directionalLight = new THREE.DirectionalLight('#FFF', 0.6) let directionalLight = new THREE.DirectionalLight('#FFF', 0.6)
directionalLight.position.set(0, 10, 0) directionalLight.position.set(0, 10, 0)
this.stageGroup.add(directionalLight) this.scene.add(directionalLight)
} }
createSceneGraphNode(){ createSceneGraphNode(){
@ -83,8 +83,9 @@
} }
// Called once per frame // Called once per frame
updateStageGroup(frame, stageCoordinateSystem, stagePose){ updateScene(frame){
let headCoordinateSystem = frame.getCoordinateSystem(XRCoordinateSystem.HEAD_MODEL) const headCoordinateSystem = frame.getCoordinateSystem(XRCoordinateSystem.HEAD_MODEL)
const trackerCoordinateSystem = frame.getCoordinateSystem(XRCoordinateSystem.TRACKER)
// Create anchors for newly anchored nodes // Create anchors for newly anchored nodes
for(let anchorToAdd of this.anchorsToAdd){ for(let anchorToAdd of this.anchorsToAdd){
@ -102,7 +103,7 @@
anchorUID: anchorUID, anchorUID: anchorUID,
node: anchorToAdd.node node: anchorToAdd.node
}) })
this.stageGroup.add(anchorToAdd.node) this.scene.add(anchorToAdd.node)
} }
this.anchorsToAdd = [] this.anchorsToAdd = []
@ -113,7 +114,7 @@
console.error('Unknown anchor ID', anchoredNode.anchorId) console.error('Unknown anchor ID', anchoredNode.anchorId)
} else { } else {
anchoredNode.node.matrixAutoUpdate = false anchoredNode.node.matrixAutoUpdate = false
anchoredNode.node.matrix.fromArray(anchor.coordinates.getTransformedCoordinates(stageCoordinateSystem).poseMatrix) anchoredNode.node.matrix.fromArray(anchor.coordinates.getTransformedCoordinates(trackerCoordinateSystem).poseMatrix)
anchoredNode.node.updateMatrixWorld(true) anchoredNode.node.updateMatrixWorld(true)
} }
} }

Просмотреть файл

@ -36,45 +36,45 @@
<div id="target" /> <div id="target" />
<script> <script>
/* /*
ARSimplestExample shows how to populate the stage group that is rendered on the stage ARSimplestExample shows how to populate the content scene
*/ */
class ARSimplestExample extends XRExampleBase { class ARSimplestExample extends XRExampleBase {
constructor(domElement){ constructor(domElement){
super(domElement, false) super(domElement, false)
} }
// Called during construction to allow the app to populate this.stageGroup (a THREE.Group) // Called during construction to allow the app to populate the THREE.Scene
initializeStageGroup(){ initializeScene(){
// Add a teapot at about eye level // Add a teapot at about eye level
var geometry = new THREE.TeapotBufferGeometry(0.1) const geometry = new THREE.TeapotBufferGeometry(0.1)
let materialColor = new THREE.Color() const materialColor = new THREE.Color()
materialColor.setRGB(1.0, 1.0, 1.0) materialColor.setRGB(1.0, 1.0, 1.0)
let material = new THREE.MeshLambertMaterial({ const material = new THREE.MeshLambertMaterial({
color: materialColor, color: materialColor,
side: THREE.DoubleSide side: THREE.DoubleSide
}) })
let mesh = new THREE.Mesh(geometry, material) const mesh = new THREE.Mesh(geometry, material)
mesh.position.set(0, 1.4, -1) mesh.position.set(0, 1.4, -1)
this.stageGroup.add(mesh) this.scene.add(mesh)
// Add a box at the stage origin // Add a box at the scene origin
let box = new THREE.Mesh( const box = new THREE.Mesh(
new THREE.BoxBufferGeometry(0.1, 0.1, 0.1), new THREE.BoxBufferGeometry(0.1, 0.1, 0.1),
new THREE.MeshPhongMaterial({ color: '#DDFFDD' }) new THREE.MeshPhongMaterial({ color: '#DDFFDD' })
) )
box.position.set(0, 0, 0) box.position.set(0, 0, 0)
this.stageGroup.add(box) this.scene.add(box)
this.stageGroup.add(new THREE.AmbientLight('#FFF', 0.2)) this.scene.add(new THREE.AmbientLight('#FFF', 0.2))
let directionalLight = new THREE.DirectionalLight('#FFF', 0.6) const directionalLight = new THREE.DirectionalLight('#FFF', 0.6)
directionalLight.position.set(0, 10, 0) directionalLight.position.set(0, 10, 0)
this.stageGroup.add(directionalLight) this.scene.add(directionalLight)
} }
// Called once per frame, before render to give the app a chance to update this.stageGroup (a THREE.Group) // Called once per frame, before render to give the app a chance to update the this.scene
updateStageGroup(frame, stageCoordinateSystem, stagePose){ updateScene(frame){
// Uncomment the next line to spin the teapot // Uncomment the next line to spin the teapot
//this.stageGroup.children[0].rotation.y += 0.01 //this.scene.children[0].rotation.y += 0.01
} }
} }

Просмотреть файл

@ -26,14 +26,12 @@ class XRExampleBase {
// Create a simple THREE test scene for the layer // Create a simple THREE test scene for the layer
this.scene = new THREE.Scene() // The scene will be rotated and oriented around the camera using the head pose this.scene = new THREE.Scene() // The scene will be rotated and oriented around the camera using the head pose
this.stageGroup = new THREE.Group() // The group that stays on the "stage", which is at foot level relative to the head
this.scene.add(this.stageGroup)
this.camera = new THREE.PerspectiveCamera(70, 1024, 1024, 0.1, 1000) // These values will be overwritten by the projection matrix from ARKit or ARCore this.camera = new THREE.PerspectiveCamera(70, 1024, 1024, 0.1, 1000) // These values will be overwritten by the projection matrix from ARKit or ARCore
this.renderer = null // Set in this.handleNewSession this.renderer = null // Set in this.handleNewSession
// Give extending classes the opportunity to initially populate the stage group // Give extending classes the opportunity to initially populate the scene
this.initializeStageGroup(this.stageGroup) this.initializeScene()
if(typeof navigator.XR === 'undefined'){ if(typeof navigator.XR === 'undefined'){
this.showMessage('No WebXR API found, usually because the WebXR polyfill has not loaded') this.showMessage('No WebXR API found, usually because the WebXR polyfill has not loaded')
@ -154,46 +152,27 @@ class XRExampleBase {
handleLayerBlur(ev){} handleLayerBlur(ev){}
/* /*
Extending classes should override this to set up the stageGroup during class construction Extending classes should override this to set up the scene during class construction
*/ */
initializeStageGroup(){} initializeScene(){}
/* /*
Extending classes that need to update the layer during each frame should override this method Extending classes that need to update the layer during each frame should override this method
*/ */
updateStageGroup(frame, stageCoordinateSystem, stagePose){} updateScene(frame){}
handleFrame(frame){ handleFrame(frame){
const nextFrameRequest = this.session.requestFrame(frame => { this.handleFrame(frame) }) const nextFrameRequest = this.session.requestFrame(frame => { this.handleFrame(frame) })
let stageCoordinateSystem = frame.getCoordinateSystem(XRCoordinateSystem.STAGE)
if(stageCoordinateSystem === null){
this.showMessage('Could not get a usable stage coordinate system')
this.session.cancelFrame(nextFrameRequest)
this.session.endSession()
// Production apps could render a 'waiting' message and keep checking for an acceptable coordinate system
return
}
// Get the two poses we care about: the foot level stage and head pose which is updated by ARKit, ARCore, or orientation events
let stagePose = frame.getViewPose(stageCoordinateSystem)
let headPose = frame.getViewPose(frame.getCoordinateSystem(XRCoordinateSystem.HEAD_MODEL)) let headPose = frame.getViewPose(frame.getCoordinateSystem(XRCoordinateSystem.HEAD_MODEL))
// Let the extending class update the stageGroup before each render // Let the extending class update the scene before each render
this.updateStageGroup(frame, stageCoordinateSystem, stagePose) this.updateScene(frame)
// Update the stage group relative to the current head pose
this.stageGroup.matrixAutoUpdate = false
this.stageGroup.matrix.fromArray(stagePose.poseModelMatrix)
this.stageGroup.updateMatrixWorld(true)
// Prep THREE.js for the render of each XRView // Prep THREE.js for the render of each XRView
//this.renderer.resetGLState()
this.scene.matrixAutoUpdate = false
this.renderer.autoClear = false this.renderer.autoClear = false
this.renderer.setSize(this.session.baseLayer.framebufferWidth, this.session.baseLayer.framebufferHeight, false) this.renderer.setSize(this.session.baseLayer.framebufferWidth, this.session.baseLayer.framebufferHeight, false)
this.renderer.clear() this.renderer.clear()
this.scene.matrixAutoUpdate = false
//this.session.baseLayer.context.bindFramebuffer(this.session.baseLayer.context.FRAMEBUFFER, this.session.baseLayer.framebuffer)
// Render each view into this.session.baseLayer.context // Render each view into this.session.baseLayer.context
for(const view of frame.views){ for(const view of frame.views){

Просмотреть файл

@ -47,7 +47,7 @@
class HitTestExample extends XRExampleBase { class HitTestExample extends XRExampleBase {
constructor(domElement){ constructor(domElement){
super(domElement, false) super(domElement, false)
this._tapEventData = null // Will be filled in on touch start and used in updateStageGroup this._tapEventData = null // Will be filled in on touch start and used in updateScene
this.anchoredNodes = [] // { XRAnchorOffset, Three.js Object3D } this.anchoredNodes = [] // { XRAnchorOffset, Three.js Object3D }
@ -63,33 +63,33 @@
this.el.addEventListener('touchstart', this._onTouchStart.bind(this), false) this.el.addEventListener('touchstart', this._onTouchStart.bind(this), false)
} }
// Called during construction to allow the app to populate this.stageGroup (a THREE.Group) // Called during construction to allow the app to populate this.scene
initializeStageGroup(){ initializeScene(){
// Add a box at the stage origin to show where the stage group is located // Add a box at the scene origin
let box = new THREE.Mesh( let box = new THREE.Mesh(
new THREE.BoxBufferGeometry(0.1, 0.1, 0.1), new THREE.BoxBufferGeometry(0.1, 0.1, 0.1),
new THREE.MeshPhongMaterial({ color: '#DDFFDD' }) new THREE.MeshPhongMaterial({ color: '#DDFFDD' })
) )
box.position.set(0, 0, 0) box.position.set(0, 0, 0)
this.stageGroup.add(box) this.scene.add(box)
// Add a box one meter in front of stage origin to show the direction of the Z axis // Add a box one meter in front of scene origin to show the direction of the Z axis
box = new THREE.Mesh( box = new THREE.Mesh(
new THREE.BoxBufferGeometry(0.1, 0.1, 0.1), new THREE.BoxBufferGeometry(0.1, 0.1, 0.1),
new THREE.MeshPhongMaterial({ color: '#FF0000' }) new THREE.MeshPhongMaterial({ color: '#FF0000' })
) )
box.position.set(0, 0, -1) box.position.set(0, 0, -1)
this.stageGroup.add(box) this.scene.add(box)
// Add a few lights // Add a few lights
this.stageGroup.add(new THREE.AmbientLight('#FFF', 0.2)) this.scene.add(new THREE.AmbientLight('#FFF', 0.2))
let directionalLight = new THREE.DirectionalLight('#FFF', 0.6) let directionalLight = new THREE.DirectionalLight('#FFF', 0.6)
directionalLight.position.set(0, 10, 0) directionalLight.position.set(0, 10, 0)
this.stageGroup.add(directionalLight) this.scene.add(directionalLight)
} }
// Called once per frame, before render, to give the app a chance to update this.stageGroup (a THREE.Group) // Called once per frame, before render, to give the app a chance to update this.scene
updateStageGroup(frame, stageCoordinateSystem, stagePose){ updateScene(frame){
// If we have tap data, attempt a hit test for a surface // If we have tap data, attempt a hit test for a surface
if(this._tapEventData !== null){ if(this._tapEventData !== null){
const x = this._tapEventData[0] const x = this._tapEventData[0]
@ -116,13 +116,14 @@
// Add a block to the scene to indicate the position of the XRAnchorOffset // Add a block to the scene to indicate the position of the XRAnchorOffset
// Its position will be updated below along with the other anchored nodes // Its position will be updated below along with the other anchored nodes
this.stageGroup.add(anchorInfo.node) this.scene.add(anchorInfo.node)
} }
}).catch(err => { }).catch(err => {
console.error('Error in hit test', err) console.error('Error in hit test', err)
}) })
} }
const trackerCoordinateSystem = frame.getCoordinateSystem(XRCoordinateSystem.TRACKER)
// Update anchored node positions in the scene graph using updated anchor positions // Update anchored node positions in the scene graph using updated anchor positions
for(let anchoredNode of this.anchoredNodes){ for(let anchoredNode of this.anchoredNodes){
const anchor = frame.getAnchor(anchoredNode.anchorOffset.anchorUID) const anchor = frame.getAnchor(anchoredNode.anchorOffset.anchorUID)
@ -131,17 +132,17 @@
} else { } else {
anchoredNode.node.matrixAutoUpdate = false anchoredNode.node.matrixAutoUpdate = false
let offsetCoordinates = anchoredNode.anchorOffset.getTransformedCoordinates(anchor) let offsetCoordinates = anchoredNode.anchorOffset.getTransformedCoordinates(anchor)
if(offsetCoordinates.coordinateSystem.type === XRCoordinateSystem.STAGE){ if(offsetCoordinates.coordinateSystem.type === XRCoordinateSystem.TRACKER){
anchoredNode.node.matrix.fromArray(offsetCoordinates.poseMatrix) anchoredNode.node.matrix.fromArray(offsetCoordinates.poseMatrix)
} else { } else {
anchoredNode.node.matrix.fromArray(offsetCoordinates.getTransformedCoordinates(stageCoordinateSystem).poseMatrix) anchoredNode.node.matrix.fromArray(offsetCoordinates.getTransformedCoordinates(trackerCoordinateSystem).poseMatrix)
} }
anchoredNode.node.updateMatrixWorld(true) anchoredNode.node.updateMatrixWorld(true)
} }
} }
} }
// Save screen taps as normalized coordinates for use in this.updateStageGroup // Save screen taps as normalized coordinates for use in this.updateScene
_onTouchStart(ev){ _onTouchStart(ev){
if (!ev.touches || ev.touches.length === 0) { if (!ev.touches || ev.touches.length === 0) {
console.error('No touches on touch event', ev) console.error('No touches on touch event', ev)

Просмотреть файл

@ -50,7 +50,7 @@
} }
// Called during construction // Called during construction
initializeStageGroup(){ initializeScene(){
// Add a teapot at about eye level // Add a teapot at about eye level
var geometry = new THREE.TeapotBufferGeometry(0.1) var geometry = new THREE.TeapotBufferGeometry(0.1)
let materialColor = new THREE.Color() let materialColor = new THREE.Color()
@ -61,26 +61,26 @@
}) })
let mesh = new THREE.Mesh(geometry, material) let mesh = new THREE.Mesh(geometry, material)
mesh.position.set(0, 1.6, -1) mesh.position.set(0, 1.6, -1)
this.stageGroup.add(mesh) this.scene.add(mesh)
// Add a box at the stage origin // Add a box at the scene origin
let box = new THREE.Mesh( let box = new THREE.Mesh(
new THREE.BoxBufferGeometry(0.1, 0.1, 0.1), new THREE.BoxBufferGeometry(0.1, 0.1, 0.1),
new THREE.MeshPhongMaterial({ color: '#DDFFDD' }) new THREE.MeshPhongMaterial({ color: '#DDFFDD' })
) )
box.position.set(0, 0, 0) box.position.set(0, 0, 0)
this.stageGroup.add(box) this.scene.add(box)
this.stageGroup.add(new THREE.AmbientLight('#FFF', 0.2)) this.scene.add(new THREE.AmbientLight('#FFF', 0.2))
let directionalLight = new THREE.DirectionalLight('#FFF', 0.6) let directionalLight = new THREE.DirectionalLight('#FFF', 0.6)
directionalLight.position.set(0, 10, 0) directionalLight.position.set(0, 10, 0)
this.stageGroup.add(directionalLight) this.scene.add(directionalLight)
} }
// Called once per frame // Called once per frame
updateStageGroup(frame, stageCoordinateSystem, stagePose){ updateScene(frame){
// Uncomment the next line to spin the box // Uncomment the next line to spin the box
// this.stageGroup.children[0].rotation.y += 0.01 // this.scene.children[0].rotation.y += 0.01
} }
} }

Просмотреть файл

@ -7,7 +7,7 @@ The XRCoordinateSystem is a string from XRCoordinateSystem.TYPES:
- XRCoordinateSystem.HEAD_MODEL: origin is aligned with the pose of the head, as sensed by HMD or handset trackers - XRCoordinateSystem.HEAD_MODEL: origin is aligned with the pose of the head, as sensed by HMD or handset trackers
- XRCoordinateSystem.EYE_LEVEL: origin is at a fixed distance above the ground - XRCoordinateSystem.EYE_LEVEL: origin is at a fixed distance above the ground
- XRCoordinateSystem.STAGE: origin is at ground level - XRCoordinateSystem.TRACKER: The origin of this coordinate system is at floor level at or below the origin of the HMD or handset provided tracking system
- XRCoordinateSystem.GEOSPATIAL: origin is at the East, Up, South plane tangent to the planet at the latitude, longitude, and altitude represented by the `XRCoordinateSystem.cartographicCoordinates`. - XRCoordinateSystem.GEOSPATIAL: origin is at the East, Up, South plane tangent to the planet at the latitude, longitude, and altitude represented by the `XRCoordinateSystem.cartographicCoordinates`.
*/ */
@ -28,8 +28,8 @@ export default class XRCoordinateSystem {
return this._display._headPose.poseModelMatrix return this._display._headPose.poseModelMatrix
case XRCoordinateSystem.EYE_LEVEL: case XRCoordinateSystem.EYE_LEVEL:
return this._display._eyeLevelPose.poseModelMatrix return this._display._eyeLevelPose.poseModelMatrix
case XRCoordinateSystem.STAGE: case XRCoordinateSystem.TRACKER:
return this._display._stagePose.poseModelMatrix return this._display._trackerPoseModelMatrix
case XRCoordinateSystem.GEOSPATIAL: case XRCoordinateSystem.GEOSPATIAL:
throw 'This polyfill does not yet handle geospatial coordinate systems' throw 'This polyfill does not yet handle geospatial coordinate systems'
default: default:
@ -60,14 +60,14 @@ export default class XRCoordinateSystem {
} }
} }
XRCoordinateSystem.HEAD_MODEL = "headModel" XRCoordinateSystem.HEAD_MODEL = 'headModel'
XRCoordinateSystem.EYE_LEVEL = "eyeLevel" XRCoordinateSystem.EYE_LEVEL = 'eyeLevel'
XRCoordinateSystem.STAGE = "stage" XRCoordinateSystem.TRACKER = 'tracker'
XRCoordinateSystem.GEOSPATIAL = "geospatial" XRCoordinateSystem.GEOSPATIAL = 'geospatial'
XRCoordinateSystem.TYPES = [ XRCoordinateSystem.TYPES = [
XRCoordinateSystem.HEAD_MODEL, XRCoordinateSystem.HEAD_MODEL,
XRCoordinateSystem.EYE_LEVEL, XRCoordinateSystem.EYE_LEVEL,
XRCoordinateSystem.STAGE, XRCoordinateSystem.TRACKER,
XRCoordinateSystem.GEOSPATIAL XRCoordinateSystem.GEOSPATIAL
] ]

Просмотреть файл

@ -18,11 +18,16 @@ export default class XRDisplay extends EventHandlerBase {
this._headModelCoordinateSystem = new XRCoordinateSystem(this, XRCoordinateSystem.HEAD_MODEL) this._headModelCoordinateSystem = new XRCoordinateSystem(this, XRCoordinateSystem.HEAD_MODEL)
this._eyeLevelCoordinateSystem = new XRCoordinateSystem(this, XRCoordinateSystem.EYE_LEVEL) this._eyeLevelCoordinateSystem = new XRCoordinateSystem(this, XRCoordinateSystem.EYE_LEVEL)
this._stageCoordinateSystem = new XRCoordinateSystem(this, XRCoordinateSystem.STAGE) this._trackerCoordinateSystem = new XRCoordinateSystem(this, XRCoordinateSystem.TRACKER)
this._headPose = new XRViewPose([0, XRViewPose.SITTING_EYE_HEIGHT, 0]) this._headPose = new XRViewPose([0, XRViewPose.SITTING_EYE_HEIGHT, 0])
this._eyeLevelPose = new XRViewPose([0, XRViewPose.SITTING_EYE_HEIGHT, 0]) this._eyeLevelPose = new XRViewPose([0, XRViewPose.SITTING_EYE_HEIGHT, 0])
this._stagePose = new XRViewPose([0, 0, 0]) this._trackerPoseModelMatrix = new Float32Array([
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
])
var fov = 50/2; var fov = 50/2;
this._fov = new XRFieldOfView(fov, fov, fov, fov) this._fov = new XRFieldOfView(fov, fov, fov, fov)

Просмотреть файл

@ -86,8 +86,6 @@ export default class XRPresentationFrame {
return this._session._display._headPose return this._session._display._headPose
case XRCoordinateSystem.EYE_LEVEL: case XRCoordinateSystem.EYE_LEVEL:
return this._session._display._eyeLevelPose return this._session._display._eyeLevelPose
case XRCoordinateSystem.STAGE:
return this._session._display._stagePose
default: default:
return null return null
} }

Просмотреть файл

@ -75,8 +75,8 @@ export default class XRSession extends EventHandlerBase {
return this._display._headModelCoordinateSystem return this._display._headModelCoordinateSystem
case XRCoordinateSystem.EYE_LEVEL: case XRCoordinateSystem.EYE_LEVEL:
return this._display._eyeLevelCoordinateSystem return this._display._eyeLevelCoordinateSystem
case XRCoordinateSystem.STAGE: case XRCoordinateSystem.TRACKER:
return this._display._stageCoordinateSystem return this._display._trackerCoordinateSystem
case XRCoordinateSystem.GEOSPATIAL: case XRCoordinateSystem.GEOSPATIAL:
// Not supported yet // Not supported yet
default: default:

Просмотреть файл

@ -6,11 +6,11 @@ Other XR platforms sometimes refer to this concept as "room scale" or "standing
export default class XRStageBounds { export default class XRStageBounds {
get center(){ get center(){
//readonly attribute XRCoordinates center; //readonly attribute XRCoordinates center;
throw 'Not implemented' throw new Error('Not implemented')
} }
get geometry(){ get geometry(){
//readonly attribute FrozenArray<XRStageBoundsPoint>? geometry; //readonly attribute FrozenArray<XRStageBoundsPoint>? geometry;
throw 'Not implemented' throw new Error('Not implemented')
} }
} }

Просмотреть файл

@ -4,11 +4,11 @@ XRStageBoundPoints represent the offset in meters from the stage origin along th
export default class XRStageBoundsPoint { export default class XRStageBoundsPoint {
get x(){ get x(){
//readonly attribute double x; //readonly attribute double x;
throw 'Not implemented' throw new Error('Not implemented')
} }
get y(){ get y(){
//readonly attribute double z; //readonly attribute double z;
throw 'Not implemented' throw new Error('Not implemented')
} }
} }

Просмотреть файл

@ -109,7 +109,6 @@ export default class FlatDisplay extends XRDisplay {
MatrixMath.mat4_fromRotationTranslation(this._deviceWorldMatrix, this._deviceOrientation.toArray(), this._devicePosition.toArray()) MatrixMath.mat4_fromRotationTranslation(this._deviceWorldMatrix, this._deviceOrientation.toArray(), this._devicePosition.toArray())
this._headPose._setPoseModelMatrix(this._deviceWorldMatrix) this._headPose._setPoseModelMatrix(this._deviceWorldMatrix)
this._eyeLevelPose._position = this._devicePosition.toArray() this._eyeLevelPose._position = this._devicePosition.toArray()
this._stagePose._position = [0, 0, 0]
} }
_updateFromDeviceOrientationTracker(){ _updateFromDeviceOrientationTracker(){
@ -120,7 +119,6 @@ export default class FlatDisplay extends XRDisplay {
MatrixMath.mat4_fromRotationTranslation(this._deviceWorldMatrix, this._deviceOrientation.toArray(), this._devicePosition.toArray()) MatrixMath.mat4_fromRotationTranslation(this._deviceWorldMatrix, this._deviceOrientation.toArray(), this._devicePosition.toArray())
this._headPose._setPoseModelMatrix(this._deviceWorldMatrix) this._headPose._setPoseModelMatrix(this._deviceWorldMatrix)
this._eyeLevelPose._position = this._devicePosition.toArray() this._eyeLevelPose._position = this._devicePosition.toArray()
this._stagePose._position = [0, 0, 0]
} }
_handleARKitUpdate(...params){ _handleARKitUpdate(...params){
@ -129,7 +127,6 @@ export default class FlatDisplay extends XRDisplay {
this._headPose._setPoseModelMatrix(cameraTransformMatrix) this._headPose._setPoseModelMatrix(cameraTransformMatrix)
this._headPose._poseModelMatrix[13] += XRViewPose.SITTING_EYE_HEIGHT this._headPose._poseModelMatrix[13] += XRViewPose.SITTING_EYE_HEIGHT
this._eyeLevelPose._position = this._headPose._position this._eyeLevelPose._position = this._headPose._position
this._stagePose._position = [0, 0, 0]
} else { } else {
console.log('no camera transform', this._arKitWrapper.rawARData) console.log('no camera transform', this._arKitWrapper.rawARData)
} }

Просмотреть файл

@ -98,7 +98,6 @@ export default class HeadMountedDisplay extends XRDisplay {
} }
this._headPose._setPoseModelMatrix(this._deviceWorldMatrix) this._headPose._setPoseModelMatrix(this._deviceWorldMatrix)
this._eyeLevelPose.position = this._devicePosition.toArray() this._eyeLevelPose.position = this._devicePosition.toArray()
this._stagePose._position = [0, 0, 0]
} }
} }
} }

Просмотреть файл

@ -150,13 +150,13 @@ export default class CameraReality extends Reality {
console.log('unknown anchor', anchor) console.log('unknown anchor', anchor)
return return
} }
// This assumes that the anchor's coordinates are in the stage coordinate system // This assumes that the anchor's coordinates are in the tracker coordinate system
anchor.coordinates.poseMatrix = anchorInfo.transform anchor.coordinates.poseMatrix = anchorInfo.transform
} }
_addAnchor(anchor, display){ _addAnchor(anchor, display){
// Convert coordinates to the stage coordinate system so that updating from ARKit transforms is simple // Convert coordinates to the tracker coordinate system so that updating from ARKit transforms is simple
anchor.coordinates = anchor.coordinates.getTransformedCoordinates(display._stageCoordinateSystem) anchor.coordinates = anchor.coordinates.getTransformedCoordinates(display._trackerCoordinateSystem)
if(this._arKitWrapper !== null){ if(this._arKitWrapper !== null){
this._arKitWrapper.addAnchor(anchor.uid, anchor.coordinates.poseMatrix).then( this._arKitWrapper.addAnchor(anchor.uid, anchor.coordinates.poseMatrix).then(
detail => this._handleARKitAddObject(detail) detail => this._handleARKitAddObject(detail)
@ -192,7 +192,7 @@ export default class CameraReality extends Reality {
let anchor = this._getAnchor(hit.uuid) let anchor = this._getAnchor(hit.uuid)
if(anchor === null){ if(anchor === null){
let anchorCoordinates = new XRCoordinates(display, display._stageCoordinateSystem) let anchorCoordinates = new XRCoordinates(display, display._trackerCoordinateSystem)
anchorCoordinates.poseMatrix = hit.anchor_transform anchorCoordinates.poseMatrix = hit.anchor_transform
anchor = new XRAnchor(anchorCoordinates, hit.uuid) anchor = new XRAnchor(anchorCoordinates, hit.uuid)
this._anchors.set(anchor.uid, anchor) this._anchors.set(anchor.uid, anchor)
@ -220,7 +220,7 @@ export default class CameraReality extends Reality {
hits.sort((a, b) => a.distance - b.distance) hits.sort((a, b) => a.distance - b.distance)
let anchor = this._getAnchor(hits[0].uuid) let anchor = this._getAnchor(hits[0].uuid)
if(anchor === null){ if(anchor === null){
let coordinates = new XRCoordinates(display, display._stageCoordinateSystem) let coordinates = new XRCoordinates(display, display._trackerCoordinateSystem)
coordinates.poseMatrix = hits[0].modelMatrix coordinates.poseMatrix = hits[0].modelMatrix
coordinates._poseMatrix[13] += XRViewPose.SITTING_EYE_HEIGHT coordinates._poseMatrix[13] += XRViewPose.SITTING_EYE_HEIGHT
anchor = new XRAnchor(coordinates) anchor = new XRAnchor(coordinates)

Просмотреть файл

@ -9,29 +9,29 @@ import Quaternion from '../polyfill/fill/Quaternion.js'
export default class CoordinatesTest extends Test { export default class CoordinatesTest extends Test {
testTransform(){ testTransform(){
let display1 = new MockXRDisplay() let display1 = new MockXRDisplay()
let stageCoordinateSystem = new XRCoordinateSystem(display1, XRCoordinateSystem.STAGE) let trackerCoordinateSystem = new XRCoordinateSystem(display1, XRCoordinateSystem.TRACKER)
let headCoordinateSystem = new XRCoordinateSystem(display1, XRCoordinateSystem.HEAD_MODEL) let headCoordinateSystem = new XRCoordinateSystem(display1, XRCoordinateSystem.HEAD_MODEL)
let eyeLevelCoordinateSystem = new XRCoordinateSystem(display1, XRCoordinateSystem.EYE_LEVEL) let eyeLevelCoordinateSystem = new XRCoordinateSystem(display1, XRCoordinateSystem.EYE_LEVEL)
let headCoordinates = new XRCoordinates(display1, headCoordinateSystem, [0, 0, -0.5]) let headCoordinates = new XRCoordinates(display1, headCoordinateSystem, [0, 0, -0.5])
let stageCoordinates = headCoordinates.getTransformedCoordinates(stageCoordinateSystem) let trackerCoordinates = headCoordinates.getTransformedCoordinates(trackerCoordinateSystem)
this.assertFloatArraysEqual( this.assertFloatArraysEqual(
stageCoordinates.position, trackerCoordinates.position,
[headCoordinates.position[0], XRViewPose.SITTING_EYE_HEIGHT + headCoordinates.position[1], headCoordinates.position[2]] [headCoordinates.position[0], XRViewPose.SITTING_EYE_HEIGHT + headCoordinates.position[1], headCoordinates.position[2]]
) )
this.assertFloatArraysEqual(stageCoordinates.orientation, headCoordinates.orientation) this.assertFloatArraysEqual(trackerCoordinates.orientation, headCoordinates.orientation)
// Rotate the head and test the transform // Rotate the head and test the transform
let quat1 = new Quaternion() let quat1 = new Quaternion()
quat1.setFromEuler(0, -Math.PI, 0) quat1.setFromEuler(0, -Math.PI, 0)
display1._headPose._orientation = quat1.toArray() display1._headPose._orientation = quat1.toArray()
stageCoordinates = headCoordinates.getTransformedCoordinates(stageCoordinateSystem) trackerCoordinates = headCoordinates.getTransformedCoordinates(trackerCoordinateSystem)
this.assertFloatArraysEqual( this.assertFloatArraysEqual(
stageCoordinates.position, trackerCoordinates.position,
[headCoordinates.position[0], XRViewPose.SITTING_EYE_HEIGHT + headCoordinates.position[1], -1 * headCoordinates.position[2]] [headCoordinates.position[0], XRViewPose.SITTING_EYE_HEIGHT + headCoordinates.position[1], -1 * headCoordinates.position[2]]
) )
quat1.inverse() quat1.inverse()
this.assertFloatArraysEqual(quat1.toArray(), stageCoordinates.orientation) this.assertFloatArraysEqual(quat1.toArray(), trackerCoordinates.orientation)
} }
} }