Building an AR Experience using API
Introduction#
This tutorial will showcase a sample app that delivers immersive AR experiences. It maps the floor plan of a room and augments 3D models for a 6DoF experience.
This tutorial serves as a learning guide for understanding how to use and consume API endpoints on the Appearition platform. To do this, we will show you how the various functions of the sample app are serviced by the platform.
The main module that will be used to service this sample app is AR Target Image and Media. It defines a specific set if endpoints and schemas which will be described in this tutorial for use in the sample app.
Note
You will be able to explore and test the API endpoints for the AR Target Image and Media module in the portal using Swagger. You can find more information about this at Swagger – Discover and Test
Note
This tutorial focuses on the RESTful Web API of the Appearition platform. We also provide an SDK for various frameworks to make it easier to consume the platform services.
Overview of the sample app#
The sample app is made up of three main components:
- Room Mapper – A smart phone app which will scan the floor of a room and save a digital representation of it. For this to work, there needs to be an anchor point in the room. We will use a simple image marker on a wall for this and save it as a “Target Image”.
- Room Editor – A desktop tool that will read the digital floor plan and render it on screen. You will be able to select a 3D model from a library and place it anywhere on the floor.
- Room Visualizer - A second smart phone app which will look for the “*Target Images” on a wall and augment the 3D models in the room for you to walk around and view.
The data model#
A room is represented on the platform as a record of the AR Target Image and Media module. For the mapping and visualization to work, we will need an anchor point in the room. For this, we will use an image marker placed on one of the walls. This will be used to trigger the AR Experience in Room Visualizer app.
The captured digital floor plan will be formatted as a JSON object and stored as media against the record on the AR Target Image and Media module.
The library of 3D models will be managed on the Appearition platform in a dedicated channel. The Room Editor will be able to pull that library down and present it to the user for selection.
Rooms in a building => “AR Target Image and Media” module records inside a “Channel”
Each room resides within a building. A building will be represented as a channel within the Appearition platform. Channels are managed by administrators via the portal. In the interest of containing the scope of the sample app, certain functions and processes will be predefined and assumed. Buildings and rooms will be centrally managed and configured via the portal. As such, each component will show a list to the user and freely allow selection.
Security#
Given the scope of this sample app, user restrictions will be relaxed. There will be no authentication on any of the sample components. As such, buildings and rooms are available to all users without restriction.
Note
Changes to the sample app can be made to tighten up access and have strict access controls. The Appearition platform provides a number of fixed roles that can be assigned to users which could be applied to the various components of the sample app.
In Detail#
The following sections provide a closer insight into each of the three main components. Wireframe representations of actual functionality are provided in some cases to indicate screen flow. For each component, the required API endpoints are shown and discussed.
Room Mapper#
This tool will be built as a mobile app that uses the camera on the device to capture and record the layout of a room and create a digital representation of the floor plan than can be transmitted and stored on the Appearition Platform.
Show a list of buildings (i.e. List Channels)#
When a user launches this app, they will be presented with a list of buildings choose from. A building is represented as a channel on Appearition Platform.
The image below is a wireframe depicting the list of buildings on the sample app that the user must choose from.
As this screen represents a list of channels from the platform, you will need to invoke this API endpoint:
/{tenant}/api/Channel/List/{id}
Here is a sample curl command for making the request:
curl -X GET --header 'Accept: application/json'
--header 'Authentication-Token: <your anonymous token>'
--header 'API-Version: 1'
'https://apiusa.appearition.com/devtrial/api/Channel/List/0'
All requests to the platform are made using JSON, hence the Accept: application/json header. The exception is when uploading binary data where a multi-part form data POST is required.
All API endpoints need an authentication-token header. For the purposes of this sample app, you will need to register the sample app on the platform and generate an anonymous token. You can read more about application registration and tokens here.
All API endpoints need the API-Version header. You can read more about api versioning here.
Adding new buildings#
There is no API for creating channels. This must be done on the portal by a user who has Admin privileges.
Below is a screen shot of creating a channel in the portal. From your home screen, you can navigate to your channel list screen. From there it is quite simple to create a channel.
Show a list of rooms (i.e. List AR Experiences)#
Once a building/channel is selected, the user is then presented with a list of rooms to choose from. Rooms are stored as records in the AR Target Image and Media module on the Appearition Platform.
The image below is a wireframe depicting the list of rooms on the sample app that the user must choose from.
As this screen represents a list of “AR Target Image and Media” records from the platform, you will need to invoke this API endpoint:
/{tenant}/api/ArTarget/List/{id}
Here is a sample curl command for making the request:
curl -X GET --header 'Accept: application/json'
--header 'Authentication-Token: <your anonymous token>'
--header 'API-Version: 1'
'https://apiusa.appearition.com/devtrial/api/ArTarget/List/1'
The {id} part of the URI represents the channel id on the platform. The idea would have been retreived as part of the previous “Channell/List” API call. You can also view the channel id in the portal via the “Channel List” screen. It appears in the pop up panel when you select a channel.
Adding rooms#
At first, a building (i.e. channel) will not have any rooms. Since rooms are represented as records in the “AR Target Image and Media” module, you can use the portal to add a room.
Below are screen shots showing you the simple wizard for for adding a new AR Experience record. There are two major parts: Target Image and Media.
- Target Image is any JPG or PNG file which can be used as the anchor point of the room.
- Media can hold numerous entries. The first will be the mapped floor plan which will be stored as a JSONDATA entry. Later, in the Room Editor component, any 3D models placed in the room will appear as entries in Media.
You start by selecting the channel and clicing on the “AR Experience” module.
Note
In the portal the “AR Target Image and Media” module is relabelled to “AR Experience”. This is a configuration feature of the platform where modules can be labelled to something that gives more contextual relevance to users.
On the screen, you add a record by following the steps on the pop up wizard:
The module also exposes an API for creating records.
POST /{tenant}/api/ArTarget/Create/{id}
{id} is the channel id where you are creating the record. You can also leave it empty (i.e. set it to zero) because the request body will require you supply it also.
In the request body you need to supply two fields: name and productId
{
"productId": 0,
"name": "string"
}
name is text to label the room
productId is the channel id.
Note
The original version of the Appearition platform referred to channels as “Products”. As such, you will find many API endpoints where the schema refers to a “productId” field instead of “channelId”. Please treat these two terms as equal.
Sample curl request:
curl -X POST --header 'Content-Type: application/json'
--header 'Accept: application/json'
--header 'Authentication-Token: <your anonymous token>'
--header 'API-Version: 1'
-d '{
"productId": 1,
"name": "My Room"
}'
'https://apiusa.appearition.com/devtrial/api/ArTarget/Create/0'
The response schema is this:
{
"Data": {
"arTargetId": 0,
"assetId": "string",
"productId": 0,
"name": "string",
"isPublished": true,
"targetImages": [
{
"arImageId": 0,
"fileName": "string",
"url": "string",
"checksum": "string"
}
],
"mediaFiles": [
{
"arMediaId": 0,
"fileName": "string",
"url": "string",
"checksum": "string",
"mediaType": "string",
"mimeType": "string",
"isPrivate": true,
"resolution": 0,
"language": "string",
"isTracking": true,
"isAutoPlay": true,
"isPreDownload": true,
"isInteractive": true,
"animationName": "string",
"scaleX": 0,
"scaleY": 0,
"scaleZ": 0,
"translationX": 0,
"translationY": 0,
"translationZ": 0,
"rotationX": 0,
"rotationY": 0,
"rotationZ": 0,
"text": "string",
"custom": "string"
}
]
},
"IsSuccess": true,
"Errors": [
"string"
]
}
Please refer to the Swagger feature on the portal for more information and to execute and test this endpoint. You will find more API endpoints for updating, publishing, unpublishing and deleting records.
Read more about Swagger here.
Scanning and mapping floor plan#
When a room is selected, the user will be directed to scan and map the room.
The floor scanning and mapping function uses Simultaneous Localization and Mapping (SLAM) technology on ARCore and ARKit. However, it will not be further discussed in this tutorial because it relates to app specific logic that is beyond the scope of this tutorial. Instead we will continue to focus on understanding the API endpoints.
Saving the mapped floor plan (i.e. Saving the AR Experience changes)#
Once a room has been scanned and mapped, the user will be prompted to save. On the platform, this translates to an API call to create a new media entry on the existing AR Target Image and Media module record (i.e. the selected room). The media will be a JSON serialised representation of the scanned floor plan.
The API endpoint for creating media :
POST /{tenant}/api/ArTarget/CreateMedia/{id}?arTargetId={arTargetId}
{id} is the channel id
{arTargetId} is the selected “AR Target Image and Media” record which represents the room.
Note
Requests can also be made with this format:
POST /{tenant}/api/ArTarget/{arTargetId}/CreateMedia
The {arTargetId} is a unique id across the entire tenant. As such the channel id is not required.
Sample curl request:
curl -X POST --header 'Content-Type: application/json'
--header 'Accept: application/json'
--header 'Authentication-Token: <your anonymous token>'
--header 'API-Version: 1'
-d '{ "arMediaId": 0, "fileName": "string", "url": "string", "checksum": "string", "mediaType": "string", "mimeType": "string", "isPrivate": true, "resolution": 0, "language": "string", "isTracking": true, "isAutoPlay": true, "isPreDownload": true, "isInteractive": true, "animationName": "string", "scaleX": 0, "scaleY": 0, "scaleZ": 0, "translationX": 0, "translationY": 0, "translationZ": 0, "rotationX": 0, "rotationY": 0, "rotationZ": 0, "text": "string", "custom": "string" }'
'https://apiusa.appearition.com/swinburne/ api/ArTarget/CreateMedia/0?arTargetId=1'
The body of the request must be a JSON message with a specific schema:
{
"arMediaId": 0,
"fileName": "string",
"url": "string",
"checksum": "string",
"mediaType": "string",
"mimeType": "string",
"isPrivate": true,
"resolution": 0,
"language": "string",
"isTracking": true,
"isAutoPlay": true,
"isPreDownload": true,
"isInteractive": true,
"animationName": "string",
"scaleX": 0,
"scaleY": 0,
"scaleZ": 0,
"translationX": 0,
"translationY": 0,
"translationZ": 0,
"rotationX": 0,
"rotationY": 0,
"rotationZ": 0,
"text": "string",
"custom": "string"
}
Please refer to the Swagger feature on the portal for more information and to execute and test this endpoint. You will find more API endpoints for linking and unlinking media entries.
Read more about Swagger here.
Room Editor#
This will be built as a desktop application which will present the captured floor plan and allow placement of 3D objects anywhere on the floor.
The initial screen flow will be the same as the Room Mapper. The user is presented with a list of buildings to choose from (i.e. Channels/List). Once chosen, the user is then asked to select a room (i.e. ArTarget/List).
Please refer to the Room Mapper section above for invoking the relevant API endpoints for these two screens.
Loading the floor plan#
Once a room has been selected, the floor plan will be displayed. The wireframe image below depicts what this might look like.
The floor plan is saved as a media entry on the “AR Target Image and Media” module record. This occured in the Room Mapper component (refer to section above).
Each media entry is list in the mediaFiles collection of the “AR Target Image and Media” module record. You must invoke this API endpoint:
GET /{tenant}/api/ArTarget/Get/{id}?arTargetId={arTargetId}
{id} is the channel id
{arTargetId} is the selected “AR Target Image and Media” record which represents the room.
Note
The {arTargetId} is a unique id across the entire tenant. As such the channel id is not required so you may set it to zero.
Sample curl request:
curl -X GET --header 'Accept: application/json'
--header 'Authentication-Token: <your anonymous token>'
--header 'API-Version: 1'
'https://apiusa.appearition.com/devtrial/api/ArTarget/Get/0?arTargetId=1'
The response schema is this:
{
"Data": {
"arTargetId": 0,
"assetId": "string",
"productId": 0,
"name": "string",
"isPublished": true,
"targetImages": [
{
"arImageId": 0,
"fileName": "string",
"url": "string",
"checksum": "string"
}
],
"mediaFiles": [
{
"arMediaId": 0,
"fileName": "string",
"url": "string",
"checksum": "string",
"mediaType": "string",
"mimeType": "string",
"isPrivate": true,
"resolution": 0,
"language": "string",
"isTracking": true,
"isAutoPlay": true,
"isPreDownload": true,
"isInteractive": true,
"animationName": "string",
"scaleX": 0,
"scaleY": 0,
"scaleZ": 0,
"translationX": 0,
"translationY": 0,
"translationZ": 0,
"rotationX": 0,
"rotationY": 0,
"rotationZ": 0,
"text": "string",
"custom": "string"
}
]
},
"IsSuccess": true,
"Errors": [
"string"
]
}
Loading the library of 3D models#
Supporting the room editor will be a list of 3D models that can be placed in the room. These will be managed on the Appearition platform via a dedicated channel named MEDIA.
Note
Media entries can be shared across different “AR Target Image and Media” records within the same channel. Via the portal you cannot share media entries across your channels. However via the relevant API endpoints, you can share media entries across your channels.
The API endpoint to retrieve a list of media within a channel is:
GET /{tenant}/api/Media/List/{id}
{id} is the id of the channel which holds media.
Sample curl request:
curl -X GET --header 'Accept: application/json'
--header 'Authentication-Token: <your anonymous token>'
--header 'API-Version: 1'
'https://apiusa.appearition.com/devtrial/api/Media/List/3'
The return schema is a collection of media with summary details:
{
"Data": [
{
"arMediaId": 0,
"fileName": "string",
"url": "string",
"checksum": "string",
"mediaType": "string",
"mimeType": "string",
"isPrivate": true,
"resolution": 0
}
],
"IsSuccess": true,
"Errors": [
"string"
]
}
Please refer to the Swagger feature on the portal for more information and to execute and test this endpoint.
Read more about Swagger here.
Uploading new 3D model files#
The “AR Target Image and Media” module exposes an endpoint for uploading new media files. If you wanted to extend the scope of the Room Editor, you could allow a user to select a 3D object from their local file system and attach it as a new Media to the room record.
The API endpoint for uploading new media files is:
POST /{tenant}/api/ArTarget/UploadMedia/{id}?arTargetId={arTargetId}
{id} is the channel id
{arTargetId} is the selected “AR Target Image and Media” record which represents the room.
The API endpoint for this is a multi-part form data POST.
Note
Requests can also be made with this URI: POST /{tenant}/api/ArTarget/{arTargetId}/UploadMedia
The {arTargetId} is a unique identifier across the entire tenant. As such channel id is not necessary.
Sample URI:
POST /devtrial/api/ArTarget/3/UploadMedia
Sample request headers:
Authentication-Token: <your anonymous token>
Accept: application/json
mediaType: JSONDATA
Content-Type: multipart/form-data;
boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
mediaType is a required field and JSONDATA is a custom type configured on the portal.
Sample request body. Notice that it has a multi-part form data where “[[ file content]]” would be replaced with the file binary.
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data;
name="MyFile";
filename="myFile.json"
Content-Type: application/json
------WebKitFormBoundary7MA4YWxkTrZu0gW—
[[ file content ]]
Saving Editor Changes#
Placement of 3D models in the Room Editor will need to be saved back to the Appearition platform so they can be picked up and used in the Room Visualizer component.
Saving requires several Web API calls.
Firstly, the media entry which holds the digital floor plan needs to be updated. The floor plan JSON will contain the instructions on which 3d model to place and where.
The 1st API call
The API endpoint for saving changes to a media entry is:
POST /{tenant}/api/ArTarget/UpdateMediaSettings/{id}?arTargetId={arTargetId}&arMediaId={arMediaId}
{arTargetId} is the selected “AR Target Image and Media” record which represents the room.
{arMediaId} is the id of the specific “media” entry on the “AR Target Image and Media” record which holds the digital floor plan.
Note
The above endpoint is presented in Swagger on the portal. However, to invoke the endpoint, you can also use this URI:
POST {tenant}/api/artarget/{arTargetId}/media/{arMediaId}/settings/update
This endpoint requires the “media” schema to be sent as JSON in the body of the request.
Sample curl request:
{
"arMediaId": 0,
"language": "string",
"isTracking": true,
"isAutoPlay": true,
"isPreDownload": true,
"isInteractive": true,
"animationName": "string",
"scaleX": 0,
"scaleY": 0,
"scaleZ": 0,
"translationX": 0,
"translationY": 0,
"translationZ": 0,
"rotationX": 0,
"rotationY": 0,
"rotationZ": 0,
"text": "string",
"custom": "string"
}
The 2nd API call
Next you need to link the 3D models which the user has selected from the library and placed on the floor plan.
The API endpoint to link existing media to an “AR Target Image and Media” record is:
POST /{tenant}/api/ArTarget/LinkMedia/{id}?arTargetId={arTargetId}&arMediaId={arMediaId}
{arTargetId} is the selected “AR Target Image and Media” record which represents the room.
{arMediaId} is the id of the specific “media” entry which you want to link to the “AR Target Image and Media” record. The server will check if it is already linked and if so will return a message.
Note
The above endpoint is presented in Swagger on the portal. However, to invoke the endpoint, you can also use this URI:
POST {tenant}/api/artarget/{arTargetId}/media/{arMediaId}/link
Although this is a POST, there no data required in the body of the request.
Sample curl request:
curl -X POST --header 'Accept: application/json'
--header 'Authentication-Token: <your anonymous token>'
--header 'API-Version: 1'
'https://apiusa.appearition.com/devtrial/api/ArTarget/LinkMedia/0?arTargetId=1&arMediaId=2'
Note
The {arTargetId} is a unique id across the entire tenant. As such the channel id is not required so you may set it to zero.
The 3rd API endpoint
The final step is to unlink any 3D model media from the “AR Target Image and Media” record which have been removed from the floor plan.
The API endpoint to unlink media is:
POST /{tenant}/api/ArTarget/UnlinkMedia/{id}?arTargetId={arTargetId}&arMediaId={arMediaId}
{arTargetId} is the selected “AR Target Image and Media” record which represents the room.
{arMediaId} is the id of the specific “media” entry you want to unlink from the “AR Target Image and Media” record.
Note
The above endpoint is presented in Swagger on the portal. However, to invoke the endpoint, you can also use this URI:
POST {tenant}/api/artarget/{arTargetId}/media/{arMediaId}/unlink
Although this is a POST, there no data required in the body of the request.
Sample curl request:
curl -X POST --header 'Accept: application/json'
--header 'Authentication-Token: <your anonymous token>'
--header 'API-Version: 1'
'https://apiusa.appearition.com/devtrial/api/ArTarget/UnlinkMedia/0?arTargetId=1&arMediaId=2'
Note
The {arTargetId} is a unique id across the entire tenant. As such the channel id is not required so you may set it to zero.
Room Visualizer#
This component will be built as a second mobile app which will augment the placed 3D models in the mapped out room.
The first process of this tool will be to scan the room anchor image. Given each room has a unique image marker, the tool will be able to find the corresponding “AR Target Image and Media” record from the Appearition Platform, and then load the floor plan media content linked to that record.
Loading the “AR Target Image and Media” records#
When the app loads, a call to the Appearition platform will need to be made to retrieve all the published “AR Target Image and Media” module records. Each record represents one room with a unique image marker.
The API endpoint required to load published records is:
GET /{tenant}/api/Asset/ListByChannel/{id}
{id} represents the id of the channel. Set it to zero so that all published experiences across all of your channels are sent down.
Sample Request:
curl -X GET --header 'Accept: application/json'
--header 'Authentication-Token: <your anonymous token>'
--header 'API-Version: 1'
'https://apiusa.appearition.com/devtrial/api/Asset/ListByChannel/0'
The return schema for this request is:
{
"Data": {
"assets": [
{
"assetId": "string",
"productId": 0,
"name": "string",
"mediaGridWidth": 0,
"mediaFiles": [
{
"fileName": "string",
"url": "string",
"checksum": "string",
"mediaType": "string",
"mimeType": "string",
"isPrivate": true,
"resolution": 0,
"language": "string",
"isTracking": true,
"isAutoPlay": true,
"isPreDownload": true,
"isInteractive": true,
"animationName": "string",
"mediaGridOffset": 0,
"scaleX": 0,
"scaleY": 0,
"scaleZ": 0,
"translationX": 0,
"translationY": 0,
"translationZ": 0,
"rotationX": 0,
"rotationY": 0,
"rotationZ": 0,
"lastModified": "string",
"text": "string",
"custom": "string"
}
],
"targetImages": [
{
"arImageId": 0,
"fileName": "string",
"url": "string",
"checksum": "string"
}
]
}
]
},
"IsSuccess": true,
"Errors": [
"string"
]
}