Clinkz
Clinkz

Reputation: 726

Retrieve bounds of an augmented object

I'm attempting to anchor a ViewRenderable to a ModelRenderable so that it appears on the top right corner of the Renderable & I use the following snippet to place it.

    //Sets the button north east of the node that it is attached to
    viewRenderable.localPosition = Vector3(
            parent.right.x,
            parent.up.y,
            parent.right.z
    )

However, the viewRenderable doesn't really show up as intended. It rather shows up a few floats away from the top right corner of the ModelRenderable. Is there a way I can get the actual bounds of the ModelRenderable so that I can place it better? I want the end result something similar to the below picture.

enter image description here

What I have right now is this image:

enter image description here

My code:

//Creation of ViewRenderable
val shareButton = ViewRenderable.builder()
    .setVerticalAlignment(ViewRenderable.VerticalAlignment.TOP)
    .setHorizontalAlignment(ViewRenderable.HorizontalAlignment.RIGHT)
    .setView(view.getARFragment().context, R.layout.share)
    .build()

//Creation of ModelRenderable
val video = ModelRenderable.builder()
    .setSource(view.getARFragment().context,
        Uri.parse("chroma_key_video.sfb")).build()


//Adding Model to the scene | Extension method called on ParentNode
private fun Node.attachVideoNode(videoRenderable: ModelRenderable?) {
    //Show another anchor object
    val videoNode = Node()
    //Attach the new node with the node that this method was called on
    videoNode.setParent(this@attachVideoNode)
    //Set local position
    videoNode.localPosition = this.right //This works fine. The video is rendered next to another ModelRenderable.

    // Set the scale of the node so that the aspect ratio of the video is correct.
    val videoWidth = mediaPlayer?.videoWidth?.toFloat()
    val videoHeight = mediaPlayer?.videoHeight?.toFloat()
    videoHeight?.let {
        videoWidth?.apply {
            videoNode.localScale = Vector3(
                    (this@apply / it), 1.0f, 1.0f)
        }
    }

    // Start playing the video when the first node is placed.
    mediaPlayer?.apply {
        if (!isPlaying) {
            start()
            // Wait to set the renderable until the first frame of the  video becomes available.
            // This prevents the renderable from briefly appearing as a black quad before the video
            // plays.
            texture?.surfaceTexture
                    ?.setOnFrameAvailableListener { surfaceTexture ->
                        videoNode.renderable = videoRenderable
                        surfaceTexture.setOnFrameAvailableListener(null)
                        //Attach a share button
                        videoNode.attachShareButton()
                        ARApplication.log("The local rotation of this videoRenderable is ${videoNode.localRotation}")
                    }
        } else
            videoNode.renderable = videoRenderable
    }
}

//Attaches a share button to any node that it is called on. | Extension method called on VideoNode
private fun Node.attachShareButton() {
    //Create a new node to display the close button
    var closeButton = Node()
    closeButton.setParent(this)
    ARApplication.log("The close button has been added to the scene at world coordinates: ${closeButton.worldPosition}")

    //Set the close button as a renderable
    closeButton.renderable = view.getViewRenderable()
}

Upvotes: 1

Views: 459

Answers (1)

Canato
Canato

Reputation: 3978

I don't know exactly what you already got, but this is a solution for put a text on the ViewRenderable on the top and on the right

x x V

x O x

x x x

V - ViewRenderable O - ModelRenderable

ViewRenderable.builder()
                .setView(context, R.layout.VIEW_LAYOUT_XXXXX)
                .setHorizontalAlignment(ViewRenderable.HorizontalAlignment.RIGHT) //Here is where the magic happens
                .build()
                .thenAccept(
                        (renderable) -> {
                            YOUR_NODE_XXXXX.setRenderable(renderable);
                            TextView textView = (TextView) renderable.getView();
                            textView.setText(YOUR_TEXT_XXXXX);
                        })
                .exceptionally(
                        (throwable) -> {
                            throw new AssertionError(R.string.ERROR_MSG_XXXXX, throwable);
                        });

I let a _XXXXXin everything that you should change with your code.

Result should be like this enter image description here

EDIT. Ok looking your code now this is what you should do:

Firs you need to inicialize your view (I think your "close button" should be your share button)

private fun Node.attachShareButton() {
if(shareButton == null){ //Create a new node to display the share button
    var shareButton = Node()
    shareButton.setParent(this)
    shareButton.renderable = view.getViewRenderable()
    shareButton.setLocalPosition(new Vector3(SIZE_OF_BUTTON, SIZE_OF_BUTTON, SIZE_OF_BUTTON));
}

if (infoCard == null) {
  infoCard = new Node();
  infoCard.setParent(this);
  infoCard.setEnabled(false);
  infoCard.setLocalPosition(new Vector3(0.0f, SIZE_OF_BUTTON*0.55f, 0.0f));

  ViewRenderable.builder()
      .setView(context,  R.layout.share)
      .setHorizontalAlignment(ViewRenderable.HorizontalAlignment.RIGHT)
      .build()
      .thenAccept(
          (renderable) -> {
            infoCard.setRenderable(renderable);
          })
      .exceptionally(
          (throwable) -> {
            throw new AssertionError(R.string.ERROR_MSG_XXXXX, throwable);
          });
}

shareButton.onTap(HitTestResult hitTestResult, MotionEvent motionEvent){
    if (infoCard == null) {
        return;
    }

    infoCard.setEnabled(!infoCard.isEnabled()); //This show your card when the button is click/tap
}
}

Upvotes: 1

Related Questions