Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move object from Anchor to Anchor?

My use case is:

  1. tap on the screen and save the "point" as starting anchor
  2. tap on the screen second time and save the "point" as end anchor
  3. push the button that will move the object from starting to end anchor

I've built my own node that is using ObjectAnimator similar like in the solar system example. My only problem is that I do not know how to determine start and end point for the the evaluator. My first thought was to take the x,y,z from Pose of start and end anchor

Vector3 start = new Vector3(startAnchor.getPose().tx(), startAnchor.getPose().ty(), startAnchor.getPose().tz());
Vector3 end = new Vector3(endAnchor.getPose().tx(), endAnchor.getPose().ty(), endAnchor.getPose().tz());

movingAnimation.setObjectValues(startingPoint, endPoint);
movingAnimation.setPropertyName("localPosition");
movingAnimation.setEvaluator(new Vector3Evaluator());

but when I do that animation is done from completely different places.

I haven't found any reference to built-in tools for such operation. I'm using Sceneform.

So the question is: How to make a fluent animation (a simple slide is enough) from anchor A to anchor B?

like image 837
Fixus Avatar asked Jul 14 '18 10:07

Fixus


1 Answers

I did this in the HelloSceneform sample. I created the first AnchorNode and added the "andy" node as a child. On the next tap, I created the endPosition AnchorNode and started the animation to move to that position.

The thing to remember is that if you are using the positions of objects with a different parent, you want to use worldPosition vs. localPosition.

  private void onPlaneTap(HitResult hitResult, Plane plane, MotionEvent motionEvent) {
      if (andyRenderable == null) {
        return;
      }
      // Create the Anchor.
      Anchor anchor = hitResult.createAnchor();

      // Create the starting position.
      if (startNode == null) {
        startNode = new AnchorNode(anchor);
        startNode.setParent(arFragment.getArSceneView().getScene());

        // Create the transformable andy and add it to the anchor.
        andy = new Node();
        andy.setParent(startNode);
        andy.setRenderable(andyRenderable);
      } else {
        // Create the end position and start the animation.
        endNode = new AnchorNode(anchor);
        endNode.setParent(arFragment.getArSceneView().getScene());
        startWalking();
      }
  }

  private void startWalking() {
    objectAnimation = new ObjectAnimator();
    objectAnimation.setAutoCancel(true);
    objectAnimation.setTarget(andy);

    // All the positions should be world positions
    // The first position is the start, and the second is the end.
    objectAnimation.setObjectValues(andy.getWorldPosition(), endNode.getWorldPosition());

    // Use setWorldPosition to position andy.
    objectAnimation.setPropertyName("worldPosition");

    // The Vector3Evaluator is used to evaluator 2 vector3 and return the next
    // vector3.  The default is to use lerp. 
    objectAnimation.setEvaluator(new Vector3Evaluator());
    // This makes the animation linear (smooth and uniform).
    objectAnimation.setInterpolator(new LinearInterpolator());
    // Duration in ms of the animation.
    objectAnimation.setDuration(500);
    objectAnimation.start();
  }
like image 76
Clayton Wilkinson Avatar answered Oct 28 '22 13:10

Clayton Wilkinson