How can we place multiple objects on the same Anchor ?
I am trying to implement this but the second object is floating . My use case :
When you tap, check if you are tapping on a node, using hit.getNode().getParent().getAnchor(), if your hierarchy is Anchor > AnchroNode > Node, and then for the new AnchorNode set this anchor.
Thanks for the reply. But I am still not able to place the second node on the anchor.
I have even tried storing the anchor in a private variable and using the same anchor to create an anchor node and one TransformableNode.
I have one listener on the fragment :
fragment.setOnTapArPlaneListener(
(HitResult hitResult, Plane plane, MotionEvent motionEvent) -> {
}
On first tap :
hitResult.createAnchor()ModelRenderable.builder()
.setSource(fragment.getContext(), model)
.build()
.thenAccept(renderable -> addNodeToScene(......
On second tap :
It should work logically, but the object is floating .. maybe I am missing something !
Have you tried hitresult.getHitPose() and then compare it with the stored anchor's pose? If it is equal or nearby then use that anchor.
And also, doesn't the "addNodeToScene" method already add a node and set the renderable to it?
Yes, addNodeToScene() add one node and set renderable to it. I have tried with that, using the same anchor for multiple nodes causing the problem..i.e. second node floats on air....
Can I see the code?
so to my understanding, you are creating an anchor using the hit.createAnchor() and the you render a model and set the renderable to a node using addNodeToScene() and then you again create a node using the anchor.
Did you just copy addNodeToScene from the tutorial? because in the tutorial, they pass _screencenter_ as the point where the node is to be placed, I think you missed that and because of this the object is set at (0,0,0), which is making it float in the air?
onclick arfragment :
fragment.setOnTapArPlaneListener(
(HitResult hitResult, Plane plane, MotionEvent motionEvent) -> {
if(newAnchor == null) {
newAnchor = hitResult.createAnchor();
}
appAnchorState = AppAnchorState.HOSTING;
placeObject(fragment, newAnchor, Uri.parse("sample.sfb"));
}
);
placeObject :
private void placeObject(ArFragment fragment, Anchor anchor, Uri model) {
ModelRenderable.builder()
.setSource(fragment.getContext(), model)
.build()
.thenAccept(renderable -> addNodeToScene(fragment, anchor, renderable))
.exceptionally((throwable -> {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(throwable.getMessage())
.setTitle("Error!");
AlertDialog dialog = builder.create();
dialog.show();
return null;
}));
}
addNodeToScene() is like below :
private void addNodeToScene(ArFragment fragment, Anchor anchor, Renderable renderable) {
anchorNode = new AnchorNode(anchor);
anchorNode.setParent(fragment.getArSceneView().getScene());
node = new TransformableNode(fragment.getTransformationSystem());
node.getScaleController().setMinScale(0.5f);
node.getScaleController().setMaxScale(2.8f);
anchorNode.setLocalScale(new Vector3(0.2f, 0.2f, 0.2f));
anchorNode.setWorldScale(new Vector3(0.2f, 0.2f, 0.2f));
node.setRenderable(renderable);
this.renderable = renderable;
node.setParent(anchorNode);
node.select();
node.setEnabled(true);
}
I am storing the reference of the Anchor in "newAnchor" before calling this method and from second time, using the same Anchor instead of creating one new.
I am not very sure, but I think the newAnchor is null when you are using it the 2nd time. Can you check for that? Log it or something and check if "newAnchor" has some value in it.
It is not null...not sure why the node is not placed on the anchor...
Some thoughts:
When the second object is parented to the initial anchor, that initial anchor is not going to be located where you just tapped. It will be located where you tapped when the first anchor was created. That means that the node won't be where you expect.
You could set the world position of the node to the pose of the hit result after you parent it to the anchor. However, that won't work super well with the TransformableNode.
A TransformableNode require's it's parent to be an AnchorNode, and it expects it's local position to be (0, 0, 0) relative to the anchor. Additionally, when you finish dragging the TransformableNode, the old anchor is disposed and a new anchor is created at the new location of the TransformableNode. This is probably causing newAnchor to become invalid, which could be why you aren't seeing the second object placed when you try to re-use the anchor. You can check out the code here.
Ultimately, it's expected that each TransformableNode has it's own unique anchor. If you want to create a custom TransformableNode that changes that, you can extend BaseTransformableNode and add your own custom version of a TranslationController.
There are some useful guidelines around using anchors here. In general, the closer an object is placed relative to it's anchor, the more accurate the tracking will be. However, objects that are relative to separate anchors can shift around relative to each-other.
This is really helpful info. Thank you.
how can i restrict my scene form to show one object at a time currently my code showing me many object as my taps i'm hitting :| i want to show single object on single anchor ? kindly help me ASAP
Most helpful comment
Some thoughts:
When the second object is parented to the initial anchor, that initial anchor is not going to be located where you just tapped. It will be located where you tapped when the first anchor was created. That means that the node won't be where you expect.
You could set the world position of the node to the pose of the hit result after you parent it to the anchor. However, that won't work super well with the TransformableNode.
A TransformableNode require's it's parent to be an AnchorNode, and it expects it's local position to be (0, 0, 0) relative to the anchor. Additionally, when you finish dragging the TransformableNode, the old anchor is disposed and a new anchor is created at the new location of the TransformableNode. This is probably causing newAnchor to become invalid, which could be why you aren't seeing the second object placed when you try to re-use the anchor. You can check out the code here.
Ultimately, it's expected that each TransformableNode has it's own unique anchor. If you want to create a custom TransformableNode that changes that, you can extend BaseTransformableNode and add your own custom version of a TranslationController.
There are some useful guidelines around using anchors here. In general, the closer an object is placed relative to it's anchor, the more accurate the tracking will be. However, objects that are relative to separate anchors can shift around relative to each-other.