Kudan

Search results for "{{ search.query }}"

No results found for "{{search.query}}". 
View All Results

Marker to Markerless

This tutorial takes you through to transfer a node that has been added to an image trackable to ArbiTrack.

Advanced Tutorial

This tutorial assumes you have gone through both Marker Basics and ArbiTrack Basics. If you have not, it is strongly recommended that you do so before you head any further.

This tutorial uses the Lego Marker and Kudan Cow assets from the Marker Basics tutorial. If you don't already have them, head over to Marker Basics and click the download link.

Create an image trackable

First things first, you'll need to create an image trackable using the Lego Marker image, then create an image node with the Kudan Cow image and add it to the image trackable.

You'll also need to add an extra line of code here to make sure our image node has a unique name. We'll use this name to find it in the tracker later.

imageNode.setName("Cow");

Register the Activity as an ArbiTrack delegate

One of the things we need to know is when ArbiTrack starts. Fortunately, we have a delegate for that. Add the following code at the end of your setup method:

// Initialise ArbiTrack
ARArbiTrack arbiTrack = ARArbiTrack.getInstance();
 
//Add the activity as an ArbiTrack delegate
arbiManager.addListener(this);

This will call a delegate method - arbiTrackStarted - when ArbiTrack has started and positioned its world.

Setup the Target Node

We'll be using the target node a little differently here. In the ArbiTrack Basics tutorial, we created a node and used it as a target. In this tutorial, we want ArbiTrack to start tracking at the same position as the image trackable. Therefore, we must use the trackable's world as ArbiTrack's target node. Add the following code to your setup method:

// Use the image trackable's world as the target node.
// This causes ArbiTrack to start tracking at the trackable's position.
arbiTrack.setTargetNode(imageTrackable.getWorld());

Implement ArbiTrack's delegate method

The next thing we need to do is tell ArbiTrack what it needs to do when it starts. To do this, we will implement the arbiTrackStarted delegate method in our Activity. It looks like this:

// Delegate method called once ArbiTrack has started
@Override
public void arbiTrackStarted()
{
}

To switch between marker and markerless tracking, we'll need to get the image node that appears when the marker is detected and transfer it to ArbiTrack's world. We also need to make sure that the image is in the right position and orientation, otherwise it will look like it jumps around when it changes between tracking types, and we don't want that.

Add the following code to your arbiTrackStarted method:

bool firstRun = true;
@Override
public void arbiTrackStarted()
{
  Log.d("K","ArbiTrack started");

  if (firstRun) 
  {
    ARImageTrackable legoTrackable = ARImageTracker.getInstance().findTrackable("Lego Marker");
    
    ARImageNode cowNode = (ARImageNode) legoTrackable.getWorld().findChildByName("Cow");

    ARArbiTrack arbiTrack = ARArbiTrack.getInstance();

    Quaternion cowFullOrientation = cowNode.getWorld().getWorldOrientation().mult(cowNode.getWorldOrientation());

    cowNode.setOrientation(arbiTrack.getWorld().getOrientation().inverse().mult(cowFullOrientation));

    cowNode.remove();
    
    arbiTrack.getWorld().addChild(cowNode);
    
    firstRun = false;
  }
}

The 'firstRun' bool is necessary due to a bug in V1.5 of the framework that causes the method to be called earlier than it should. We are working to fix it, but in the meantime, use that as a workaround to prevent it being called during initialisation.

Now, when ArbiTrack starts, it will reparent the image node so that it is tracked markerlessly. We still need to tell ArbiTrack when to start, though.

Start ArbiTrack

To tell ArbiTrack when to start, we'll use the same method as the one in the ArbiTrack Basics](doc:arbitrack-basics-1) tutorial to respond to touch input. However, instead of simply starting ArbiTrack in onSingleTapUp, we will call the following method:

public void toggleArbiTrack(View view)
{
  Log.d("D","Button Pressed");

  ARImageTrackable legoTrackable = ARImageTracker.getInstance().findTrackable("Lego Marker");

  ARArbiTrack arbiTrack = ARArbiTrack.getInstance();

  if (!arbiTrack.getIsTracking())
  {
    // If the marker is not currently detected, exit the method and don't switch to arbitrack
    if (!legoTrackable.getDetected())
    {
      return;
    }

    arbiTrack.start();
  }

  else
  {
    ARImageNode cowNode = (ARImageNode)arbiTrack.getWorld().findChildByName("Cow");

    arbiTrack.stop();

    cowNode.setOrientation(Quaternion.IDENTITY);

    cowNode.remove();

    legoTrackable.getWorld().addChild(cowNode);
  }
}

In this method, when we tap the screen, if ArbiTrack isn't already running and the marker is being

In this method, we need to know whether or not ArbiTrack is running when we tap, because we only want ArbiTrack to start if it hasn't already started. In addition, we want to know whether or not our trackable is being detected, because we can't go from marker tracking to markerless tracking if we aren't tracking a marker.

This means that when we tap the screen, if ArbiTrack isn't already running and the marker is being detected, it will start markerless tracking, which in turn will trigger the arbiTrackStarted method and transfer over our image node.

You might be wondering why we implement the arbiTrackStarted method at all, since we could just run that same code when we tap the screen. The reason for this is that when ArbiTrack first starts, it doesn't actually get data from the Gyroscope right away. Because of this, its world's transform does not get updated for a couple of frames. If we tried to transfer the image node at this point, it would rotate and jump across the screen.

The arbiTrackStarted method is only called when ArbiTrack has started and has values, so we can be sure that when this method is called, it's world has been updated it is safe to transfer our content across.

If you build and run your app, you'll find that you are able to detect a marker and, when you tap the screen, it will switch to markerless tracking. You can tap again to switch back to marker tracking. You can add some form of text or implement the touch control as a button if you want more visual feedback when the tracking method changes.

Marker to Markerless

This tutorial takes you through to transfer a node that has been added to an image trackable to ArbiTrack.