GuidesReferenceIssuesSupportGet API Key


Viro supports numerous mechanisms through which users can interact with both the real world and the virtual UI. These are detailed below.

AR Hit Testing

ViroViewARCore has a variety of methods used to "hit-test" against the real-world. These hit tests can be used to determine, to the best of ARCore's ability, what real-world features exist at a given point on the 2D screen. Note that since a single 2D point on the view corresponds to a 3D ray in the scene, multiple results may be returned (each at a different depth). The results may be anchors -- like planes -- or they may be feature points that have not yet been fully identified.

The easiest way to add virtual content to a hit result is to use ARHitTestResult.createAnchoredNode(). In the example below, we perform a hit test and add the 3D object of a star to the hit location.

final ViroViewARCore view = ...; //Assume this has been initialized
final ARScene scene = ...; // Assume this has been initialized

Point point = new Point((int) (view.getWidth() / 2.0), 
                        (int) (view.getHeight() / 2.0f));

view.performARHitTest(point, new ARHitTestListener() {
    public void onHitTestFinished(ARHitTestResult[] results) {
        for (ARHitTestResult result : results) {
            ARNode node = result.createAnchoredNode();
            // ARCore may fail to create an anchor
            if (node == null) {

            // Add a star model to the Node, so the user sees a star where
            // the hit test landed
            final Object3D star = loadStarModel();

Fixed to World Dragging

Normally when dragging a Node through a DragListener, the Node when dragged stays at a fixed distance from from the user, as though the user is dragging the Node across the inner surface of a sphere. This is called FIXED_DISTANCE dragging.

Viro also supports FIXED_TO_WORLD dragging in AR, where instead of keeping a dragged Node's distance from the user fixed, the dragged Node's distance is instead determined by its intersection with the nearest real-world object. This is useful for dragging a virtual object across a real-world surface, for example.

Fixed to Plane Dragging

Fixed to Plane dragging enables you to specify a plane atop which a Node can be dragged. The Node will not be able to leave this plane. You can also specify a maximum distance away from the camera that the Node can travel, to prevent users from dragging the node out to infinity. To do this, set the Node's drag type to FIXED_TO_PLANE. You define the plane along which the Node can be dragged by specifying any point on the plane, and the normal vector of the plane.

In the example below we allow a Box to only be dragged about a horizontal plane one meter below us, and we stop it from traveling more than five meters away from us.

Box box = new Box(.2f, .2f, .2f);

Node boxNode = new Node();
boxNode.setPosition(new Vector(0, 0, -1));
boxNode.setDragListener(new DragListener() {
    public void onDrag(int source, Node node, Vector worldLocation, Vector localLocation) {
        Log.i(TAG, "The box is being dragged!");

// Set FIXED_TO_PLANE dragging and define the drag plane
boxNode.setDragPlanePoint(new Vector(0, -1, 0));
boxNode.setDragPlaneNormal(new Vector(0, 1, 0));

// Do not allow the box to travel more than 5 meters away from us

Video and Still Capture

Viro supports video and still image capture, to make sharing AR experiences easy. To do this, simply grab the ViroMediaRecorder from the ViroViewARCore.