ARKit by Example — Part 1: AR Cube

This first article is going to create a really simple hello world AR app using ARKit. By the end we will be able to position a 3D cube inside the augmented world and move around it with our iOS device.

To render 3D content inside ARKit, we are going to use SceneKit: https://developer.apple.com/scenekit/ This is a framework for rendering 3D graphics on an iOS device. If you are familiar with basic 3D concepts it will be pretty straightforward.

If you can’t wait until the end of the article, here is a video of the app in action. As you can see using ARKit we can place virtual objects in the real world and have them stick in place as we move the camera around.

Even though this is a very simple app, we will keep building more and more features through these series of articles, including geometry detection, 3D physics and lots more fun things.

https://youtu.be/cHuitQ0WAX0

Requirements

As of the time of writing you need to have an iOS device with an A9/A10 processor in it to support ARKit. This means an iPhone 6S or better, or an iPad 2017 or better. For the sfotware, you need to install:

  • iOS 11
  • XCode 9

Once you have those installed you are ready to go.

Creating the project

First open XCode, choose the ARKit project template:

XCode 9 - New Project Template Chooser

Fill out the project details, make sure you choose “Scene Kit” as the Content Technology option. By default is may say “Sprite Kit” which is used for 2D rendering, but we want “Scene Kit” which is used for rendering 3D content.

Run the project, if everything is working as expected on your device you should see an app that shows the live camera feed and a 3D model of an airplane that is positioned in your physical space.

Move around and see how the plane stays is the same position in the real world even as you move the camera:

The above example in the sample project is actually more advanced than we are going to create, but the whole point here is to learn how to code these project from scratch, so open up the project, and remove all the code from the viewDidLoad method (apart from the super call).

ARKit core classes

ARSCNView — a helper view that helps augment the real-time camera view with 3D content rendered by SceneKit. There are a couple of things this class does:

Renders a live video stream from your device camera in the view as a background to your 3D scene

The 3D coordinate system of ARKit matches the 3D coordinate system of SceneKit, so object rendered in this view will automatically match the augmented ARKit world view Automatically moves the virtual SceneKit 3D camera to match the 3D position tracked by ARKit, so there is no extra code needed to hook up the ARKit movement events to map to the SceneKit 3D rendering.

ARSession — every Augmented Reality session requires an ARSession instance. It is responsible for controlling the camera, gathering all of the sensor data from the device etc to build this seamless experience. The ARSCNView instance already has an ARSession instance, you just need to configure it at startup.

ARWorldTrackingSessionConfiguration — this class indicates to the ARSession that we want to use six degrees of freedom for tracking the user in the real world, roll, pitch, yaw and translation in X, Y and Z. This allows us to create AR experiences where you can not only rotate in the same spot to see augmented content, but also move around object in the 3D space. If you don’t need the translation part and the user will stay still as you project augmented content, you can use the ARSessionConfiguration class instead to initialize the ARSession instance.

For part 1 of this series we only need these classes, there are many more but this is a good starting point. Going back to our project, we can see in the viewWillAppear method that the ARSession instance is initialized, the self.sceneView refers to a ARSCNView instance.

- (void)viewWillAppear:(BOOL)animated {
  [super viewWillAppear:animated];
  // Create a session configuration
  ARWorldTrackingSessionConfiguration *configuration = [ARWorldTrackingSessionConfiguration new];
  // Run the view's session
  [self.sceneView.session runWithConfiguration:configuration];
}

Drawing the Cube

We are going to draw a 3D Cube using SceneKit. SceneKit has a couple of basic classes, SCNScene is a container for all your 3D content, you can add multiple pieces of 3D geometry to the scene, in various positions, rotations, scales etc. To add content to a scene, you first create some Geometry, geometry can be complex shapes, or simple ones like sphere, cube, plane etc. You then wrap the geometry in a scene node and add it to the scene. SceneKit will then traverse the scene graph and render the content.

To add a scene and draw a cube we would add the following code inside the viewDidLoad method:

- (void)viewDidLoad {
  [super viewDidLoad];
  // Container to hold all of the 3D geometry  
  SCNScene *scene = [SCNScene new];
  // The 3D cube geometry we want to draw
  SCNBox *boxGeometry = [SCNBox 
                          boxWithWidth:0.1 
                          height:0.1 
                          length:0.1 
                          chamferRadius:0.0];
  // The node that wraps the geometry so we can add it to the scene
  SCNNode *boxNode = [SCNNode nodeWithGeometry:boxGeometry];
  // Position the box just in front of the camera
  boxNode.position = SCNVector3Make(0, 0, -0.5);
  // rootNode is a special node, it is the starting point of all
  // the items in the 3D scene
  [scene.rootNode addChildNode: boxNode];
  // Set the scene to the view
  self.sceneView.scene = scene;
}

The coordinates in ARKit roughly correspond to meters, so in this case we are creating a 10x10x10 centimeter box. The coordinate system for ARKit and SceneKit looks like the following:

As you can see in the code code above the position the camera -0.5 units infront of the camera, since the camera faces in the negative Z direction.

When the ARSession starts up the calculated camera position is initially set as X=0, Y=0, Z=0.

If you now run the sample, you should see a small 3D cube floating in space that maintains it’s position when you move around, you should be able to walk all the way around, look under, above it. One quick tweak we will want to make is to add some default lighting in the 3D scene so that we can see the sides of the cubes, we can add some more advanced lighting later but for now we can just set the autoenablesDefaultLighting on the SCNScene instance: self.sceneView.autoenablesDefaultLighting = YES;

Next Article

In the next article we will start making our app a bit more interesting, adding some more complex objects, detecting planes in the scene and interacting with geometry in the scene, stay tuned …

results matching ""

    No results matching ""