Reputation: 43
I want to connect two TransformableNode on the Sceneform at ArFragment with some visible line but without using OpenGL functions. Is it possible to draw a line between two anchors (or nodes) in Sceneform in ARCore Java in Android? If it possible then how I can do this?
Upvotes: 3
Views: 5680
Reputation: 689
Other way for drawing a line by cylinder.
private void addLineBetweenPoints(Scene scene, Vector3 from, Vector3 to) {
// prepare an anchor position
Quaternion camQ = scene.getCamera().getWorldRotation();
float[] f1 = new float[]{to.x, to.y, to.z};
float[] f2 = new float[]{camQ.x, camQ.y, camQ.z, camQ.w};
Pose anchorPose = new Pose(f1, f2);
// make an ARCore Anchor
Anchor anchor = mCallback.getSession().createAnchor(anchorPose);
// Node that is automatically positioned in world space based on the ARCore Anchor.
AnchorNode anchorNode = new AnchorNode(anchor);
anchorNode.setParent(scene);
// Compute a line's length
float lineLength = Vector3.subtract(from, to).length();
// Prepare a color
Color colorOrange = new Color(android.graphics.Color.parseColor("#ffa71c"));
// 1. make a material by the color
MaterialFactory.makeOpaqueWithColor(getContext(), colorOrange)
.thenAccept(material -> {
// 2. make a model by the material
ModelRenderable model = ShapeFactory.makeCylinder(0.0025f, lineLength,
new Vector3(0f, lineLength / 2, 0f), material);
model.setShadowReceiver(false);
model.setShadowCaster(false);
// 3. make node
Node node = new Node();
node.setRenderable(model);
node.setParent(anchorNode);
// 4. set rotation
final Vector3 difference = Vector3.subtract(to, from);
final Vector3 directionFromTopToBottom = difference.normalized();
final Quaternion rotationFromAToB =
Quaternion.lookRotation(directionFromTopToBottom, Vector3.up());
node.setWorldRotation(Quaternion.multiply(rotationFromAToB,
Quaternion.axisAngle(new Vector3(1.0f, 0.0f, 0.0f), 90)));
});
}
Upvotes: 8
Reputation: 1300
Yes there is a way to do this:
private void addLineBetweenHits(HitResult hitResult, Plane plane, MotionEvent motionEvent) {
int val = motionEvent.getActionMasked();
float axisVal = motionEvent.getAxisValue(MotionEvent.AXIS_X, motionEvent.getPointerId(motionEvent.getPointerCount() - 1));
Log.e("Values:", String.valueOf(val) + String.valueOf(axisVal));
Anchor anchor = hitResult.createAnchor();
AnchorNode anchorNode = new AnchorNode(anchor);
if (lastAnchorNode != null) {
anchorNode.setParent(arFragment.getArSceneView().getScene());
Vector3 point1, point2;
point1 = lastAnchorNode.getWorldPosition();
point2 = anchorNode.getWorldPosition();
/*
First, 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.makeOpaqueWithColor(getApplicationContext(), new Color(0, 255, 244))
.thenAccept(
material -> {
/* Then, create a rectangular prism, using ShapeFactory.makeCube() and use the difference vector
to extend to the necessary length. */
ModelRenderable model = ShapeFactory.makeCube(
new Vector3(.01f, .01f, difference.length()),
Vector3.zero(), material);
/* Last, 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 node = new Node();
node.setParent(anchorNode);
node.setRenderable(model);
node.setWorldPosition(Vector3.add(point1, point2).scaled(.5f));
node.setWorldRotation(rotationFromAToB);
}
);
lastAnchorNode = anchorNode;
}
}
Upvotes: 9