This section applies only to the Augmented Reality SDK v4 +. Are you still using an older version? Previous versions of the SDKs will not receive updates anymore. If you need help transitioning to the newer version, you can get support through our support channel.
In version 3 of the Augmented Reality SDK, we’ve introduced a new feature that allows the user to fix or attach the AR content to the screen instead of the real-world object.
In a regular Augmented Reality experience, the content is attached to the reference object from the real world when your app is augmenting the scene. While tracking the real-world object, the user can move around and interact with the Augmented Reality experience from different viewpoints.
This article shows how to use the off-tracking rendering feature of the Augmented Reality SDK. With this feature, you can indicate that an AR item’s contents are still drawn on the screen even if the reference object is not being tracked.
In order to get familiar with this functionality, we recommend following the example described below (for iOS and for Android), which is also available open-source from our examples project in Github (for iOS and Android). The example consists of a view that renders a regular AR scene and a button to attach AR contents to the screen by freezing them when we press the button. After scanning the reference image, the AR content is loaded. Clicking on the attach icon forces the content to stay fixed on the screen in the last rendered pose.
Fix content on iOS
In order to manage the attachment of a particular AR experience, we need to keep a reference to the corresponding AR item. We add the following attributes to the AR_ProgrammaticallyViewController class to control the state of the contents (attached or not attached):
1
2
3
|
CraftARItemAR *myItem;
bool _isTrackingEnabled;
bool _isAttached;
|
When the reference image is recognized, we receive all the information of the AR item (together with its contents). This is the right moment to create the reference to that object. In this example, we modify didGetSearchResults in order to do that. The following is a snippet assuming that the contents associated with the AR item are local to the app and consist of an image file named “AR_programmatically_content.png”.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
- (void) didGetSearchResults:(NSArray *)results {
bool haveARItems = NO;
if ([results count] >= 1) {
[mSDK stopFinder];
// Found one result, launch its content on a webView:
CraftARSearchResult *result = [results objectAtIndex:0];
// Each result has one item
CraftARItem* item = result.item;
if ([item isKindOfClass:[CraftARItemAR class]]) {
myItem = (CraftARItemAR*)item;
// Local content creation
CraftARTrackingContentImage *image = [[CraftARTrackingContentImage alloc]
initWithImageNamed:@"AR_programmatically_content" ofType:@"png"];
image.wrapMode = CRAFTAR_TRACKING_WRAP_ASPECT_FIT;
[myItem addContent:image];
NSError *err = [mTracking addARItem:myItem];
if (err) {
NSLog(@"Error adding AR item: %@", err.localizedDescription);
}
haveARItems = YES;
}
if (haveARItems) {
self._scanOverlay.hidden = YES;
[mTracking startTracking];
} else {
[mSDK startFinder];
}
}
}
|
Finally, we add the behavior to our attach button. This button has been added to the storyboard and connected to the following method called attachContents, which is an IBAction of the viewController.
1
2
3
4
5
6
7
8
9
10
11
|
- (IBAction)attachContents:(id)sender {
if (!_isAttached && _isTrackingEnabled) {
myItem.drawOffTracking = YES;
_isTrackingEnabled = false;
[mTracking stopTracking];
} else {
myItem.drawOffTracking = NO;
_isTrackingEnabled = true;
[mTracking startTracking];
}
}
|
Fix content on Android
In order to manage the attachment of a particular AR experience, we need to keep a reference to the corresponding AR item. We add the following attributes to the ARProgrammaticallyActivity.java class to control the state of the contents (attached or not attached):
1
2
3
|
private CraftARItemAR myARItem;
private boolean isAttached = false;
private boolean isTrackingEnabled = false;
|
When the reference image is recognized, we receive all the information of the AR item (together with its contents). This is the right moment to create the reference to that object. We can modify searchCompleted in order to do that. The following is a snippet assuming that the contents associated with the AR item are local to the app and consist of an image file named “AR_programmatically_content.png”.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
@Override
public void searchCompleted(ArrayList results) {
if(results.size()!=0){
CraftARResult result = results.get(0);
/**
* Get the item for this result and check if it is an AR item
*/
CraftARItem item = result.getItem();
if (item.isAR()) {
// Stop Finding
mCraftARSDK.stopFinder();
// Cast the found item to an AR item
myARItem = (CraftARItemAR)item;
// Add content to the tracking SDK and start AR experience
try {
// We create a CraftARContentImage programmatically from a resource stored in the SD card.
String imageUrl = getApplicationContext().getExternalFilesDir(null)
+ "/ar_programmatically_content.png";
CraftARContentImage myImage = new CraftARContentImage(imageUrl);
myImage.setWrapMode(CraftARContent.ContentWrapMode.WRAP_MODE_SCALE_FILL);
// Add the content to the AR item
myARItem.addContent(myImage);
// Add the item to the tracking and start tracking.
mTracking.addItem(myARItem);
mTracking.startTracking();
mScanningLayout.setVisibility(View.GONE);
} catch (CraftARSDKException e) {
e.printStackTrace();
}
}
}
}
|
Finally, we add the behavior for our Attached button. This button has been added to the layout and the ARProgrammaticallyActivity.java activity has been set as the onClick listener.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@Override
public void onClick(View v) {
if (!isAttached && isTrackingEnabled) {
myARItem.setDrawOffTracking(true);
mTracking.stopTracking();
isAttached = true;
} else if (myARItem != null){
myARItem.setDrawOffTracking(false);
isAttached = false;
mTracking.startTracking();
isTrackingEnabled = true;
}
}
|