Wednesday, September 27, 2017

WEDDING SETTEE BACK FIT-ON USING AR KIT

Create a New Project

Once everything is installed and ready to go, it is time to open up Xcode. Click on the icon with the blueprint and hammer and you will be faced with the "Welcome" screen. First, we need to start a new project. In order to do that we need to click on the "Create a new Xcode project" button.
Xcode will load up its main page and bring up a template selection page. Templates simplify the process of getting started by allowing the user to start with a framework for a project closely resembling the type they want. On a very basic skeleton frame, of course.
Select the Augmented Reality App icon and click the "Next" button.









The project options panel will appear. Here we will name the project and link it to our developer account. Make sure SceneKit is currently selected under Content Technology. When you have everything looking like you want, click the "Next" button.









Now we need a place to store our project. Create a folder in the folder selection window and click the "Create" button.
Once everything loads up you should see something along the lines of this:









Modify the 3D Model

Create a model with .scn file






Add Our 3D Model to the Current Project

So the default template project comes with a 3D model which we need to replace with the one we just created. Looking through our Project Navigator, find a folder called art.scnassets. This is the spot we are looking for.
Select "ship.scn" and hit the "Delete" key.
Now that the model is in your project you can open up the ViewController.swift file created by the template and swap out the spaceship for your model. Find this line of code:
let scene = SCNScene(named: "art.scnassets/settee.scn")!

When running the app with this change you will not be able to see the model because it is much too large, and not positioned in front of the camera. An easy way to check the size of a model is to cut & paste the spaceship model from the default scn file in to the dae file using the SceneKit editor in Xcode. This will tell you the relative sizes, and in this case the object is around 100 times too large.

Select the object model in the SceneKit editor view by clicking it, and then on the right-hand side pane select the Node inspector. This is the tab with the cube icon. Here we can set the x, y, and z scale to 0.01, reducing the size of the tree by 99%. You can also set the scale in code, as well as position and rotation.



You may notice that in the default position, the object is not visible. This is because it’s origin is at position 0, 0, 0, and it’s invisible because the camera is actually inside of the object at this location. If you start up the AR app on a device and walk around a bit, when you turn around you’ll see the object. But let’s just move it out some using some code. What we’ll do is change the position to be 1 unit in front of the camera in it’s default location. In order to do this we’ll need to find the object as a node within the scene. Going back to the SceneKit editor (select the DAE file within Xcode), we can click on the object model itself, and then again in the Node inspector there should be a name. This is the name of the mesh selected, in this case sette_lp_11. If you’re using a different model the name may be different, or empty. Fortunately we can just type in our own name as needed.

Now that we know the name of the node, we can access it within our code.
let scene = SCNScene(named: "art.scnassets/sette.dae")!
let treeNode = scene.rootNode.childNode(withName: "sette_lp_11", recursively: true)

The second line above does a search of the child nodes of the scene object created from the DAE file we imported, and returns a node with the name specified. Since 3D models can have deeply nested nodes, it’s often useful to recursively search through the nested heirarchy to find the mesh object, so we opt to search recursively, even though it is not neccessary for this particular model.
From here, we can simply reposition the node by moving it forward a bit. The means going in a negative direction in the z axis, as the default camera faces down the negative Z. Or in other words it’s looking at the point (0, 0, -Inf).
So to make the object visible, let’s move it back 1 unit in the z direction. The easiest way to do this is just set the new z to -1 on the position object.
let scene = SCNScene(named: "art.scnassets/sette.dae")!
let treeNode = scene.rootNode.childNode(withName: "sette_lp_11", recursively: true)
treeNode?.position.z = -1

This will work, but in practice what is more common is to create a new position object from scratch and assign that as the new position. This is based on taste, but it’s a common approach to avoid mutating positions of 3D objects, and instead to replace them. To do this we need to construct a SCNVector3 object with the position (0,0,-1). This code has the exact same effect, but is a better practice:
let scene = SCNScene(named: "art.scnassets/sette.dae")!
let treeNode = scene.rootNode.childNode(withName: "sette_lp_11", recursively: true)
treeNode?.position = SCNVector3Make(0, 0, -1)

In order to modify the treeNode later, let’s keep an instance reference to it. Outside of any functions, but inside the ViewController class add an optional reference to treeNode:
class ViewController: UIViewController, ARSCNViewDelegate {
  var treeNode: SCNNode?
  ...
}

In the next step we’re going to want a reference to the treeNode again, so rather than doing the lookup every time, it is useful to cache the reference to the treeNode. To do this, I’ll modify the childNode call we just added inside of viewDidLoad so that it sets this to an instance variable treeNode as opposed to just the local treeNode variable:
let scene = SCNScene(named: "art.scnassets/sette.dae")!
self.treeNode = scene.rootNode.childNode(withName: "sette_lp_11", recursively: true)
self.treeNode?.position = SCNVector3Make(0, 0, -1)

Although AR is not supported in the simulator, SceneKit is, and this is just a SceneKit model. So if you run the simulator you’ll find you can now see the object model with a black background.