Sceneform-android-sdk: WorldPosition for the AnchorNode is different while hosting and resolving. Why is this the case?

Created on 30 Jun 2018  路  11Comments  路  Source: google-ar/sceneform-android-sdk

I have hosted a cloudAnchor with multiple nodes attached to it. I am saving the worldPosition of the child nodes and use them to resolve and position the child nodes. But I could see that the positioning is messed up. So I checked the worldPosition for the anchorNode which is the parent to the child nodes and I could see that the worldPosition, while it was hosted and resolved, didn't match.

Most helpful comment

You can record the position of the child nodes relative to the anchorNode (the parent node).

  private void storePositions() {
    List<Pair<String, Vector3>> positions = new ArrayList<>();
    for(Node node: anchorNode.getChildren()) {
      Vector3 p = node.getLocalPosition();
      positions.add(new Pair<>(node.getName(), p));
    }
    firebaseManager.storeRelativePositions(Long.parseLong(roomCodeText.getText().toString()), positions);
  }

Then on the resolving side, apply the positions by name, or create a new child node:

  private void updateLocalPositions(List<Pair<String, Vector3>> positions) {

    for(Pair<String,Vector3> pos : positions) {
      String name = pos.first;
      Vector3 lp = pos.second;
      if (anchorNode != null) {
        Node n = anchorNode.findByName(name);
        if (n != null) {
          n.setLocalPosition(lp);
        } else {
          // make a new node.
          n = makeChildNode(name);
          n.setParent(anchorNode);
          n.setLocalPosition(lp);
        }
      }
    }
  }

All 11 comments

the world position is based on the session so it shouldn't be consistent

So how do I place the child nodes relative to the AnchorNode using cloudAnchors?

What I do is this: Let Q1 be the rotation quaternion of the hosted anchor, and Q2 be the quaternion of the resolved anchor, and let O1 be the location of the hosted anchor and O2 be the location of the resolved anchor. Then for every vertex v_old in hosted anchor coordinate space I transform by: v_new = (Q2 * Q1^-1)*(v_old - O1) + O2

By Location and Rotation you mean the world location and world rotation right and not local loaction and rotation?

And should i do the same for the other child nodes which are attached to the AnchorNode?

You might want to try to save the localRotation and position of the nodes relative to the anchorNode. This should make everything relative to the anchor versus the world coordinate system.

@claywilkinson I am sorry I didn't understand what you said. Can you please explain?

@rohitagarwal3011 Yes worldRotation/location. and do it for all the child nodes

Okay @15kingben . Thanks for the help . I will implment it and get back to you incase of any issues.

You can record the position of the child nodes relative to the anchorNode (the parent node).

  private void storePositions() {
    List<Pair<String, Vector3>> positions = new ArrayList<>();
    for(Node node: anchorNode.getChildren()) {
      Vector3 p = node.getLocalPosition();
      positions.add(new Pair<>(node.getName(), p));
    }
    firebaseManager.storeRelativePositions(Long.parseLong(roomCodeText.getText().toString()), positions);
  }

Then on the resolving side, apply the positions by name, or create a new child node:

  private void updateLocalPositions(List<Pair<String, Vector3>> positions) {

    for(Pair<String,Vector3> pos : positions) {
      String name = pos.first;
      Vector3 lp = pos.second;
      if (anchorNode != null) {
        Node n = anchorNode.findByName(name);
        if (n != null) {
          n.setLocalPosition(lp);
        } else {
          // make a new node.
          n = makeChildNode(name);
          n.setParent(anchorNode);
          n.setLocalPosition(lp);
        }
      }
    }
  }

@claywilkinson Thanks a ton. It worked like a charm!!

Was this page helpful?
0 / 5 - 0 ratings