Search code examples
androidandroid-studioaugmented-realityarcoresceneform

How to tilt a Node(or TransformableNode)object downwards in Sceneform(Ar Core)?


I am bit confused how to tilt an image downwards with the help of TransformableNode in google ARCore Sceneform API. I am using google Sceneform example. I am successfully able to place contents in Screen.

Please take a look at below image how it is currently image

However, I want to tilt the facebook icon downwards like earth, which is in the table. I have tried using Node and TransformableNode as stated here, but failed to do so. Can anyone tell me how to do so? Here what I have tried so far.

public class AugmentedImageNodee extends AnchorNode {

  private static final String TAG = "AugmentedImageNode";

  // The augmented image represented by this node.
  private AugmentedImage image;

  // Models of the 4 corners.  We use completable futures here to simplify
  // the error handling and asynchronous loading.  The loading is started with the
  // first construction of an instance, and then used when the image is set.
//  private static CompletableFuture<ModelRenderable> ulCorner;
  private static CompletableFuture<ViewRenderable> ulCorner;
  private static CompletableFuture<ModelRenderable> urCorner;
  private static CompletableFuture<ModelRenderable> lrCorner;
  private static CompletableFuture<ModelRenderable> llCorner;
  private ArFragment arFragment;

  public AugmentedImageNodee(Context context, ArFragment arFragment) {
    this.arFragment =arFragment;
    // Upon construction, start loading the models for the corners of the frame.
    if (ulCorner == null) {

      /*=================================================================================*/
      /*below is my only layout fb object for rendering, rest are google's one*/
      /*=================================================================================*/

      ulCorner = ViewRenderable.builder()
              .setView(context,R.layout.fb_layout)
              .build();


      urCorner =
          ModelRenderable.builder()
              .setSource(context, Uri.parse("models/frame_upper_right.sfb"))
              .build();
      llCorner =
          ModelRenderable.builder()
              .setSource(context, Uri.parse("models/frame_lower_left.sfb"))
              .build();
      lrCorner =
          ModelRenderable.builder()
              .setSource(context, Uri.parse("models/frame_lower_right.sfb"))
              .build();
    }
  }

  /**
   * Called when the AugmentedImage is detected and should be rendered. A Sceneform node tree is
   * created based on an Anchor created from the image. The corners are then positioned based on the
   * extents of the image. There is no need to worry about world coordinates since everything is
   * relative to the center of the image, which is the parent node of the corners.
   */
  @SuppressWarnings({"AndroidApiChecker", "FutureReturnValueIgnored"})
  public void setImage(AugmentedImage image) {
    this.image = image;

    // If any of the models are not loaded, then recurse when all are loaded.
    if (!ulCorner.isDone() || !urCorner.isDone() || !llCorner.isDone() || !lrCorner.isDone()) {
      CompletableFuture.allOf(ulCorner, urCorner, llCorner, lrCorner)
          .thenAccept((Void aVoid) -> setImage(image))
          .exceptionally(
              throwable -> {
                Log.e(TAG, "Exception loading", throwable);
                return null;
              });
    }

    // Set the anchor based on the center of the image.
    setAnchor(image.createAnchor(image.getCenterPose()));

    /*=================================================================================*/
    /*My node for placing the fb*/
    /*=================================================================================*/

    // Make the 4 corner nodes.
    Vector3 localPosition = new Vector3();
    TransformableNode cornerNode;

    // Upper left corner.
    localPosition.set(-0.5f * image.getExtentX(), 0.0f, -0.5f * image.getExtentZ());
    cornerNode = new TransformableNode(arFragment.getTransformationSystem());

//    cornerNode.setLocalRotation(Quaternion.axisAngle(new Vector3(0f,
//            0f, 0f ), 180));
    cornerNode.setParent(this);
    cornerNode.setLocalPosition(localPosition);
    cornerNode.setRenderable(ulCorner.getNow(null));

    /*=================================================================================*/
    /*=================================================================================*/



    // Upper right corner.
    localPosition.set(0.5f * image.getExtentX(), 0.0f, -0.5f * image.getExtentZ());
    cornerNode = new TransformableNode(arFragment.getTransformationSystem());
    cornerNode.setParent(this);
    cornerNode.setLocalPosition(localPosition);
    cornerNode.setRenderable(urCorner.getNow(null));

    // Lower right corner.
    localPosition.set(0.5f * image.getExtentX(), 0.0f, 0.5f * image.getExtentZ());
    cornerNode = new TransformableNode(arFragment.getTransformationSystem());
    cornerNode.setParent(this);
    cornerNode.setLocalPosition(localPosition);
    cornerNode.setRenderable(lrCorner.getNow(null));

    // Lower left corner.
    localPosition.set(-0.5f * image.getExtentX(), 0.0f, 0.5f * image.getExtentZ());
    cornerNode = new TransformableNode(arFragment.getTransformationSystem());
    cornerNode.setParent(this);
    cornerNode.setLocalPosition(localPosition);
    cornerNode.setRenderable(llCorner.getNow(null));
  }

  public AugmentedImage getImage() {
    return image;
  }
}

Solution

  • Similar to set position cornerNode.setLocalPosition(localPosition); you can set rotation cornerNode.setLocalRotation(new Quaternion(90f, 0f, 0f, -90f));