Reputation: 726
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.
What I have right now is this image:
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
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 _XXXXX
in everything that you should change with your code.
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