Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UAs must retain expando XRAnchor attributes in future XRFrame.trackedAnchors sets #35

Open
thetuvix opened this issue Mar 18, 2020 · 3 comments

Comments

@thetuvix
Copy link
Contributor

Given this approach of XRAnchor only representing explicit app-created freespace anchors, having a list of tracked anchors seems harmless to me.

XRFrame.trackedAnchors does feel lower value than is implied by the code in the anchors explainer, as there is no per-anchor ID or other data beyond the anchorSpace to tie a given XRAnchor back to any set of app content. The app itself will need to remember for each anchored scene object it creates which anchor that object is attached to... at which point the app could just loop over its own list of those anchors and poll for isLost or such.

Note that the for loop over trackedAnchors at the bottom stops after getting each XRAnchor's pose - it's not clear what the next line of code would be for the app to make productive use of that pose, unless it was already maintaining an equivalent trackedAnchors map from scene node to anchor itself:

let previousFrameAnchors = Set();

function onXRFrame(timestamp, frame) {
  frame.session.requestAnimationFrame(onXRFrame);

  const trackedAnchors = frame.trackedAnchors;

  for(const anchor of previousFrameAnchors) {
    if(!trackedAnchors.has(anchor)) {
      // Handle anchor tracking loss - `anchor` was present
      // in the present frame but is no longer tracked.
    }
  }

  for(const anchor of trackedAnchors) {
    // Query most recent pose of the anchor relative to some reference space:
    const pose = xrFrame.getPose(anchor.anchorSpace, referenceSpace);
  }

  previousFrameAnchors = trackedAnchors;
}

The primary way I could see an app productively using trackedAnchors is if it set its own additional attribute on each XRAnchor to store the list of its root scene objects whose poses need to be updated each frame:

  for(const anchor of trackedAnchors) {
    // Query most recent pose of the anchor relative to some reference space:
    const pose = xrFrame.getPose(anchor.anchorSpace, referenceSpace);

    for(const sceneNode of anchor.attachedSceneNodes) {
      // Adjust the pose of each scene node attached to this anchor.
      sceneNode.setTransform(pose.transform);
  }

This seems like a reasonable pattern, although it would rely on a promise that the UA will return the same XRAnchor instance on subsequent frames when XRFrame.trackedAnchors is enumerated, rather than returning a new equivalent XRAnchor instance that lost that extra data.

I'll file a new issue around specifying that the UA must retain any extra data on an XRAnchor when it's enumerated moving forward.

Originally posted by @thetuvix in #11 (comment)

@raviramachandra
Copy link

I am thinking instead of custom extra data such as attachedSceneNodes either a UUID or opaque unique handle per anchor would make UA's management of anchors easier.

@bialpio
Copy link
Contributor

bialpio commented Mar 19, 2020

The main value of the trackedAnchors set is to actually enable the application to perform some cleanup when it notices that an anchor is no longer tracked:

  for(const anchor of previousFrameAnchors) {
    if(!trackedAnchors.has(anchor)) {
      // Handle anchor tracking loss - `anchor` was present
      // in the present frame but is no longer tracked.
    }
  }

I'll file a new issue around specifying that the UA must retain any extra data on an XRAnchor when it's enumerated moving forward.

Yes, I had this behavior in mind when designing the API, although it may not be explicitly stated anywhere in the spec. The snippet pasted above is implying that the anchor object is persistent for as long as it's present in trackedAnchors set or as long as app has outstanding reference to it, whichever is longer (if it weren't persistent and we returned different instances, the !trackedAnchors.has(anchor) would always be false). Since we're returning the same objects and it's JavaScript, application could attach new data to those objects (although I've been told it might not be a common / best practice). Let me find a way to be a bit more explicit about it - my approach was that new instances of XRAnchor objects are only created as a result of successful calls to createAnchor(), the trackedAnchors is just regurgitating whatever was already created.

As for UUID, it was discussed in #18 - please take a look and reopen the issue if you disagree with the resolution.

@bialpio
Copy link
Contributor

bialpio commented Mar 19, 2020

I thought about it for a bit and it occurred to me that the way the specification draft is written, it is already explicit that the anchor objects are the same ones - the only objects that can appear in trackedAnchors set are the ones that have been created via one of the createAnchor() calls - the objects get placed in set of tracked anchors on a session, and later get added to trackedAnchors on a frame (alternative view is that there are only 2 places where the spec refers to create new anchor object algorithm). Given that, I'm not sure if any special phrasing is needed to ensure that UAs must maintain app-attached attributes - I don't think we mention it anywhere in the WebXR spec but we already half-expect that the application will store for example session mode on an XRSession object for convenience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants