Reputation: 43
I got 2 anchors, I'd like to render an arrow object at one anchor and the direction of the arrow head to the other. I put some code, but it didn't work properly
private void drawLine(AnchorNode node1, AnchorNode node2) {
Vector3 point1, point2;
point1 = node1.getWorldPosition();
point2 = node2.getWorldPosition();
node1.setParent(mArFragment.getArSceneView().getScene());
//find the vector extending between the two points and define a look rotation
//in terms of this Vector.
final Vector3 difference = Vector3.subtract(point1, point2);
final Vector3 directionFromTopToBottom = difference.normalized();
final Quaternion rotationFromAToB =
Quaternion.lookRotation(directionFromTopToBottom, Vector3.up());
MaterialFactory.makeTransparentWithColor(getApplicationContext(), new Color(247, 181, 0, 0.7f))
.thenAccept(
material -> {
// create a rectangular prism, using ShapeFactory.makeCube()
// use the difference vector to extend to the necessary length
ModelRenderable model = ShapeFactory.makeCube(
new Vector3(.15f, .001f, difference.length()),
Vector3.zero(), material);
// set the world rotation of the node to the rotation calculated earlier
// and set the world position to the midpoint between the given points
Node nodeForLine = new Node();
nodeForLine.setParent(node1);
nodeForLine.setRenderable(model);
nodeForLine.setWorldPosition(Vector3.add(point1, point2).scaled(.5f));
nodeForLine.setWorldRotation(rotationFromAToB);
}
); // end rendering
ModelRenderable.builder()
.setSource(this, Uri.parse("model.sfb"))
.build()
.thenAccept(modelRenderable -> {
AnchorNode anchorNode = new AnchorNode(node1.getAnchor());
TransformableNode transformableNode = new TransformableNode(mArFragment.getTransformationSystem());
transformableNode.setParent(anchorNode);
transformableNode.setRenderable(modelRenderable);
transformableNode.setWorldRotation(rotationFromAToB);
mArFragment.getArSceneView().getScene().addChild(anchorNode);
transformableNode.select();
})
.exceptionally(throwable -> {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(throwable.getMessage()).show();
return null;
});
}
You see the arrow is rendered but its direction is not correct. Current situation. See image
Upvotes: 1
Views: 1032
Reputation: 25491
I think you want the arrow on one anchor to point towards the other anchor - you can do this using 'setLookDirection' and a TransformableNode.
See below for an example:
var newAnchorNode:AnchorNode = AnchorNode(newAnchor)
var transNode = TransformableNode(arFragment.transformationSystem)
transNode.setLookDirection(Vector3(0f, 1f, 1f), Vector3.left())
transNode.renderable = selectedRenderable
transNode.setParent(newAnchorNode)
newAnchorNode.setParent(arFragment.arSceneView.scene)
See API documentation here:
This is actually for Scenefrom 1.15 and the newer version 1.16 is now open source on GitHub, but I don't think a detailed API description exists so the above is still a good place to look at this time (May 2020).
You can use your own values for the two vector3's.
The first Vector3 is the point you want your renderable to 'look at', in your case the other anchor most likely, and the second Vector3 is the orientation of the renderable in the scene - i.e. if you want it upright, facing left etc.
One thing to be aware of, AFAIK, Sceeform is still designed for landscape mode so you may need to experiment to get the orientation the way you want if it not using landscape - for example the vector3.left() in the example above is to make a renderable appear upright on a portrait display.
Upvotes: 1