Now, in the last lesson, we captured, processed, and incorporated our tracking image into our Xcode project 1
and we added it to our configuration so that it knows what are the images that it should be detecting. 2
Now, in this lesson, I want to show you how we can start recognizing those images using ARKit and how 3
to turn the image into a plane that we're going to later use to set our 3D models on. 4
So first things first, we're gonna be working within the ARSCNViewDelegate methods section, but 5
we're going to delete all of these other methods because we're not going to be using it. 6
Make sure you don't delete the last one because that's needed for the entire class. 7
Now, the method that we're gonna add in here is called renderer nodeFor anchor. And this one asked the 8
delegate to provide a SceneKit node corresponding to a newly added anchor. 9
Now, if you remember from previous lessons, the anchor is the thing that was detected. 10
So in our case, the anchor will be the image that got detected on screen, and the node is going to be 11
a 3D object that we're going to provide in response to detecting the anchor, 12
so that's basically what this method is all about. When the image gets detected, 13
this method will get called and we can look at the image that got detected. And in response, we can provide 14
a 3D object to be rendered into the screen. 15
Now, the first thing we're going to do is we're going to create that brand-new 3D object or what we call 16
a SCNNode. So this is our new node object. 17
And once everything's all said and done, then we're going to return this node as the output of this method. 18
As you can see, 19
this method is expecting a output of SCNNode and it needs to send that back onto the scene so that 20
it can render a 3D object. 21
Now, in between these two lines of code is everything that we need to do to set up our plane and also 22
render our 3D models. 23
So first things first, we're going to check to see if the anchor that we detected, 24
so if the item that was detected in the world was in fact an ARImageAnchor. 25
So we're going to do a type check. 26
So let's say let imageAnchor 27
= anchor, and that, of course, comes from here. 28
And we're going to check if the data type is an ARImageAnchor. 29
And this, of course, contains information about the position and orientation of an image detected in the 30
ARSession. 31
If a detected, say, a plane or a point or anything else, then this is not going to carry out. 32
In that case, we can use this with a "if let" to only carry out code 33
if the anchor that was detected is in fact of data type ARImageAnchor. 34
So it was in fact an image that got detected. 35
Now, if that is true, then we're going to create a new plane using that image, and the plane is going be 36
created as we did before using SCNPlane, 37
and we're going to use the method that provides a width and a height. 38
Now, this plane is going to be created from the image that was detected, 39
so from our Pokémon card. And we want the width and height of the plane in the physical world to be the 40
same as it is, 41
right? 42
So we want it to be exactly the size that our card is. 43
Now, I can either provide in hard values that I've measured using a tape measure, or I can simply say 44
look at the imageAnchor that you found and look at the referenceImage that it contains, and then get 45
its physical size, and grab the width property. 46
That means that it's going to look at the image that it detected and try to measure its actual physical 47
size and get all of its height and width properties to put in here, instead of me having to hardcode it. 48
So once we've got a dimension to our plane, then we're going to use it to create a planeNode, and this 49
is going to be the 3D object that we're going to render just on top of our card so that we can tell 50
that our card has been recognized. 51
So the planeNode is going to be an SCNNode and it's going to be created with a geometry. And the 52
geometry is, of course, this plane that we created over here. And now, we can tap into this node that we 53
created earlier on and we can add a childNode which is going to be our planeNode. 54
So, now let's hit run and let's see what we get when we tried to detect our card. 55
When you run the app, you'll be asked to grant access to the camera so that we can start an 56
ARSession. 57
And once it has, then we can reveal the face of our card which is meant to be detected and you can see 58
that we're getting this plane that's being rendered on top of it. 59
Now, the only problem with this plane is that it's being rendered vertically, whereas what we actually 60
want is for it to be lying down with the same dimension as our card. 61
So in order to do that, we have to do a few transformations. Now, the transformation we need to make is 62
to rotate this plane that we've created by 90 degrees, anticlockwise in the x axis. 63
So here are our three axis: x, y, and Z. And currently, our card looks like this. 64
So along the x axis, we're going to rotate it anticlockwise. And to do that, all we have to do is to take 65
the planeNode and tap into the eulerAngles, which is the node orientation, and notice that it's expressed 66
in radians, 67
so that requires the use of pi. And the eulerAngle that we're going to change is the x or the first 68
component. 69
And in order to rotate anticlockwise, then I'm going to make it negative. 70
And the amount that I want to rotate it by is only 90 degrees. So in radians, 71
that's expressed as pi divided by 2. Half a pi is 90 degrees in radians. 72
And you have to make sure that there's no space between the minus and the dot pi. 73
Now, you can also write pi as Float.pi or you can simply use the shorthand way which simply assumes 74
that it's a float and we're tapping into the constant of pi. 75
So, now let's hit run again and see what happens this time. 76
So, now you can see that this plane has been generated is now completely attached to the dimension of 77
the card, and it is flush with the surface of the card. 78
And this gives us a perfect place to start projecting 3D images onto, and for 3D images to be tracked. 79
Now, there's just one thing. 80
Once we've got the plane show up, it's completely white and completely opaque. And we can't really see 81
our card anymore, 82
which means I don't really know what was on the card, so it would be really nice if I can make this plane 83
a little bit more transparent. 84
So let's give that a go. Now, in order to make our plane transparent, before we set the geometry, 85
we can set another one of its properties which is its material and it's diffuse. So we can say 86
plane.firstMaterial.diffuse.contents = UIColor that is created using this method. 87
These are the grayscale and the alpha values. 88
So the grayscale, 89
I'll leave it as completely white. And the alpha, 90
I'll change that to 0.5 so that it's half as transparent as it used to be. 91
And let's try that out. 92
So, now you can see that the plane is rendered on top of my Pokémon card, but it's also transparent so 93
that I can see through it into my actual card. 94
So, now we're at the position when we are ready to start rendering our 3D Eevee on top of this playing card 95
and using that plane to track and render the 3D model, and to move the 3D model as I move this physical 96
card. 97
That is what we're going to be learning in the next lesson. 98
So for all of that and more, I'll see you there.