检索增强对象的边界

时间:2018-08-09 08:19:16

标签: android arcore sceneform

我正在尝试将ViewRenderable锚定到ModelRenderable上,以使其显示在Renderable的右上角,并使用以下代码片段将其放置。

    //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
    )

但是,viewRenderable并没有真正显示出预期的效果。而是在ModelRenderable的右上角显示了一些浮动。有什么方法可以获取ModelRenderable的实际边界,以便可以更好地放置它?我希望最终结果类似于下图。

enter image description here

我现在拥有的是这张图片:

enter image description here

我的代码:

//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()
}

1 个答案:

答案 0 :(得分:0)

我不确定您已经拥有了什么,但这是一种在顶部和右侧的 ViewRenderable 上放置文本的解决方案。 >

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);
                        });

我让_XXXXX包含您应使用代码进行更改的所有内容。

结果应该像这样 enter image description here

编辑。确定代码,这是您应该做的:

需要初始化视图的位置(我认为您的“关闭按钮”应该是共享按钮)

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
}
}