plane tracking and objects
1. Begin by opening up Xcode, pressing Create a new Xcode project, and selecting "Augmented Reality App." In the option menu that appears, most of the information should be filled out for you—just give your project a name like plane_tracking, and make sure to select Personal Team under the Team dropdown menu. We'll be using Apple's SceneKit (under Content Technology), which makes incorporating 3D animated objects/scenes/effects less tedious.
Your screen should look something like Figure 1. Press next and save the project in a folder somewhere.
Figure 1: Project options
2. The two main files here are AppDelegate.swift and ViewController.swift. AppDelegate is kind of the "controller" for app, checking system states/interruptions such as active/inactive state or notifications. We won't have to worry about this file in this project.
ViewController.swift is where we create the meat of our project. By default, the scene will render an airplane, whose texture is rendered in the function viewDidLoad(). This function is called after the viewWillAppear() function, which sets up the view controller (e.g. stuff related to orientation, tracking mode, etc.).
Starting from the very beginning, we set our viewWillAppear() function to allow horizontal plane tracking:
Now, in viewDidLoad, simply create and set the scene:
Most of this should have already been in the existing functions.
3. Now we'll create the plane object that the app will be overlaying on the scene as the phone pans. Create a new Swift file called Plane.swift.
Here, we use the SCNNode class, which stands for a SceneKit node. This is just an object that we can attach geometry and other displayable elements to. The ARPlaneAnchor gives us the information of the plane that we're detecting, and a SCNPlane is the most basic of planes, a flat 2D plane with fixed size.
4. When the AppDelegate gets a call to renderer (which we'll implement later), the Plane class is supposed to create a new new plane that is ready to display. To do so, we implement the plane class's init() function:
This sets a material and dimensions for the plane, then add the node to the Plane object.
5. As we move around, however, we have to make sure to update the plane, which includes updating the dimensions of the plane as the anchor reports different dimensions. The function below simply updates the material dimensions to scale per the object's self-reported geometry.
Now, as we move around, the anchors will change. Every time a new anchor is added, indicating a new plane, we must poll the dimensions and position of the anchor, using updatePlaneMaterialDimensions as needed to render the plane.
6. Now, back in ViewController, there should be a commented out renderer() method. We actually have to create three different versions of this method, one for each of adding a new anchor, updating an anchor, and removing an anchor. As we move, more and more anchors will be added and rendered. To keep track, we'll use a dictionary object with a UUID. Define var planes = [UUID: Plane]() at the top of ViewController.
Now our add anchor function should look something like this:
Updating and removing are self-explanatory:
And that's it for plane detection! Try running it on your phone. In Xcode, under Product > Destination, you should see the name of your connected device. Select it, then press Command-R to sideload the app to your device and run it from there.