0
1
00:00:00,810 --> 00:00:01,170
All right.
1

2
00:00:01,200 --> 00:00:09,000
So in previous lessons, we managed to get our code to recognize the Pokémon card, and to be able to render
2

3
00:00:09,090 --> 00:00:15,040
a 3D model of the Eevee Pokémon on top of the card so that it's standing on the card.
3

4
00:00:15,060 --> 00:00:21,750
Now, in this lesson, it's mostly a challenge for you because I want to be able to have, say, two card side
4

5
00:00:21,750 --> 00:00:28,170
by side. Say, you know, my Pokémon is battling somebody else's Pokémon, and I want it such that when two
5

6
00:00:28,170 --> 00:00:34,200
players when they're both revealing their Pokémons, the 3D models should appear on top of each
6

7
00:00:34,200 --> 00:00:41,340
card. So the card that I'm gonna be working with is the Offish card. And the first thing we need to do
7

8
00:00:41,430 --> 00:00:45,630
is we need to add the Oddish card image to our project.
8

9
00:00:45,690 --> 00:00:50,850
So if you have your own Pokémon cards and you want to work with a different model, that's perfectly fine,
9

10
00:00:50,910 --> 00:00:55,500
or if you want to use another card that you have lying around, a playing card, a business card, that's
10

11
00:00:55,590 --> 00:00:56,430
also fine.
11

12
00:00:56,580 --> 00:00:59,900
But you need to add that into your project.
12

13
00:00:59,890 --> 00:01:06,660
Now, if you want to work along with me, then just head over to this website here and print out the Oddish
13

14
00:01:06,690 --> 00:01:11,340
card so that you can follow along with the tutorial as well.
14

15
00:01:11,340 --> 00:01:17,190
So here I've saved an image of the Oddish card and I'm simply going to rename it,
15

16
00:01:20,090 --> 00:01:29,390
oddish-card, and I'm going to drag this into my project under my assets.
16

17
00:01:29,390 --> 00:01:35,450
So notice that we've got our Pokémon cards folder already, and all I need to do is open my downloads
17

18
00:01:35,450 --> 00:01:40,550
folder and drag my Oddish card into my Pokemon cards
18

19
00:01:40,550 --> 00:01:45,580
group. So, again, we get a warning
19

20
00:01:45,660 --> 00:01:49,590
and that's because we haven't provided a physical dimension to it.
20

21
00:01:49,740 --> 00:01:51,060
So let's tap that in,
21

22
00:01:51,060 --> 00:01:53,510
0.065, hit Enter,
22

23
00:01:53,520 --> 00:01:56,710
so the height gets calculated automatically.
23

24
00:01:56,700 --> 00:02:02,640
Now, while I'm here, I'm going to switch out my Eevee card as well, just so that it's a little bit more
24

25
00:02:02,640 --> 00:02:08,970
clear and it works a little better, just because it has much higher resolution and a better clarity than
25

26
00:02:08,970 --> 00:02:15,030
what I can get from taking a photo of it. And I'm just going to drag that new card back in and delete
26

27
00:02:15,030 --> 00:02:16,470
the old one as well.
27

28
00:02:16,560 --> 00:02:21,430
And, of course, update my dimensions, 0.065. 
28

29
00:02:21,540 --> 00:02:28,410
So that means if you have images that are high resolution that already digital, then perfect, upload those.
29

30
00:02:28,860 --> 00:02:35,460
If you don't and you want a particular card to be recognized, then using the camera or using a scanner
30

31
00:02:35,730 --> 00:02:37,810
will work just as well.
31

32
00:02:37,830 --> 00:02:46,530
So, now that we have both cards incorporated to our Pokémon cards set, the next challenge is to incorporate
32

33
00:02:46,680 --> 00:02:49,060
the Oddish 3D model.
33

34
00:02:49,110 --> 00:02:51,230
So we're going to do exactly the same.
34

35
00:02:51,270 --> 00:03:00,390
You're going to download it from Roestudios and you can just command F to find Oddish, and download
35

36
00:03:00,450 --> 00:03:08,220
the file, use the Oddish model, and convert it to usdz and include it into your project.
36

37
00:03:08,220 --> 00:03:12,690
So pause the video and give that a go. All right.
37

38
00:03:12,720 --> 00:03:16,470
So this should be incredibly easy as we did it before.
38

39
00:03:16,560 --> 00:03:22,310
So we're just going to agree to the Terms and Conditions, we're going to unzip the Oddish folder.
39

40
00:03:22,710 --> 00:03:29,370
And here we have all of those different types and different file formats, but we're going to use the
40

41
00:03:29,370 --> 00:03:34,930
one that is just called Oddish.obj as we did before.
41

42
00:03:35,310 --> 00:03:44,820
And then we're going to pull up Terminal and I'm going to use Xcode command line, run, usdz_converter,
42

43
00:03:44,820 --> 00:03:52,410
and then I have a space, and then I drag in the file I want to convert, and then after a space,
43

44
00:03:52,470 --> 00:04:00,740
I add the location that I want to place my converted file. And that's just going to be called
44

45
00:04:00,960 --> 00:04:06,720
Oddish.usdz in my downloads folder. And there you have it.
45

46
00:04:06,770 --> 00:04:10,180
There's our new Oddish model.
46

47
00:04:10,500 --> 00:04:18,870
So, now that we have that model, we can drag it into our art.scnassets folder, and we can now convert
47

48
00:04:18,870 --> 00:04:22,620
it to a SceneKit scene format.
48

49
00:04:22,620 --> 00:04:24,610
And it does that for a little while.
49

50
00:04:24,630 --> 00:04:28,080
And now we have oddish.scn. And there you go,
50

51
00:04:28,110 --> 00:04:31,650
There's little Oddish. As we did previously,
51

52
00:04:31,650 --> 00:04:39,240
we're going to simplify our nodes by flattening them into one, just so that we don't have the eyes and
52

53
00:04:39,240 --> 00:04:41,550
the mouth and the body all separate,
53

54
00:04:41,550 --> 00:04:46,310
and we're going to rename this node to oddish.
54

55
00:04:46,830 --> 00:04:49,430
And at the moment, again, it's a little bit too big,
55

56
00:04:49,440 --> 00:04:52,850
so we're going to scale it down by the same scale format,
56

57
00:04:52,860 --> 00:04:58,470
So 0.05 on the height, width, and the depth.
57

58
00:04:58,710 --> 00:05:06,070
And now, this audition is about the same size as our Eevee which is the perfect size for rendering onto
58

59
00:05:06,090 --> 00:05:08,040
the card.
59

60
00:05:08,040 --> 00:05:08,370
All right.
60

61
00:05:08,370 --> 00:05:18,450
So now that we've got two 3D models and both Pokémon cards into our project, the next step is to figure
61

62
00:05:18,450 --> 00:05:27,150
out how can we know whether if the Oddish card was detected, or whether if the Eevee card was detected,
62

63
00:05:27,160 --> 00:05:29,550
how can we differentiate that.
63

64
00:05:29,580 --> 00:05:35,330
Well, you can see the anchor here is the item that triggered this function.
64

65
00:05:35,340 --> 00:05:43,200
So it's the thing that got detected using the mode of detection that we chose here which is image tracking,
65

66
00:05:43,200 --> 00:05:48,540
so the anchor is then the image that was recognized and detected.
66

67
00:05:48,750 --> 00:05:57,390
If we make sure that the image anchor is indeed an ARImageAnchor, then we should be able to tap into some
67

68
00:05:57,390 --> 00:05:58,760
its properties.
68

69
00:05:58,770 --> 00:06:06,090
Now, what kind of properties does it have? If you hold on option and you click on ARImageAnchor, then
69

70
00:06:06,180 --> 00:06:10,000
you can see this brief description about what it is.
70

71
00:06:10,140 --> 00:06:16,770
But if you want to read more, we can click on Open Developer Documentation and this takes us to the
71

72
00:06:16,830 --> 00:06:18,870
ARImageAnchor Docs.
72

73
00:06:18,900 --> 00:06:25,480
Now, it says that when you run a world-tracking AR session and specify ARReferenceImageObjects,
73

74
00:06:25,500 --> 00:06:30,930
now you might be wondering, we're not running a world tracking AR session actually, we're running
74

75
00:06:30,960 --> 00:06:33,750
a ARImageTrackingConfiguration.
75

76
00:06:33,900 --> 00:06:42,320
But if you actually change this to ARWorldTrackingConfiguration, this image tracking also works.
76

77
00:06:42,390 --> 00:06:46,030
So you can now detect planes as well as images.
77

78
00:06:46,140 --> 00:06:54,030
All you have to do is change this configuration. Instead of tracking images, you change it to 
78

79
00:06:54,060 --> 00:06:57,040
detectionImages, and it'll work exactly the same.
79

80
00:06:57,060 --> 00:07:04,030
But now, you're able to detect planes in the world tracking as well as images., so you can do both.
80

81
00:07:04,080 --> 00:07:10,530
But if you only need one, then try to keep it to imageTracking so that it's less resource-intensive.
81

82
00:07:12,250 --> 00:07:19,110
So an ARImageAnchor contains ARReferenceImage objects.
82

83
00:07:19,150 --> 00:07:27,310
So if we look inside the ARReferenceImage object, you could see that it has a number of properties, for example,
83

84
00:07:27,370 --> 00:07:36,450
the name property which is a descriptive name for the image which was recognized in the ARSession,
84

85
00:07:36,460 --> 00:07:48,340
so that means that if we print the imageAnchor.referenceImage.name, then we can figure out which
85

86
00:07:48,340 --> 00:07:52,870
card was detected when this function was called.
86

87
00:07:56,160 --> 00:08:05,160
So, now if I flip over this card, which is Eevee, you can see that in my debug console, I've got the 
87

88
00:08:05,190 --> 00:08:12,960
Eevee-card which, remember, is the name of that card over here. And that is what it's printing here.
88

89
00:08:12,960 --> 00:08:22,680
Now, if I turn over the Oddish card, then you can see I've got the Oddish card being printed over here,
89

90
00:08:23,130 --> 00:08:26,520
and that refers to this one being detected.
90

91
00:08:26,640 --> 00:08:33,930
So at the moment, an Eevee is being rendered on both cards, and we're only getting one card recognized
91

92
00:08:34,020 --> 00:08:35,610
at one time.
92

93
00:08:35,610 --> 00:08:38,940
So let's try and change that.
93

94
00:08:39,240 --> 00:08:45,360
Let's head back to our ViewController and we can be pretty certain that we can access the image that
94

95
00:08:45,360 --> 00:08:50,780
was detected through using the imageAnchor.referenceImage.name.
95

96
00:08:50,820 --> 00:08:53,910
So let's go ahead and delete this print statement.
96

97
00:08:54,210 --> 00:09:01,150
Now, if you scroll up to our viewWillAppear, you can see that at one point, we set the maximum number
97

98
00:09:01,150 --> 00:09:04,010
of tracked images in our configuration to 1.
98

99
00:09:04,140 --> 00:09:10,560
And that's why at any moment in time, we're only tracking one image and we're only able to render our
99

100
00:09:10,560 --> 00:09:12,510
3D model onto one image.
100

101
00:09:12,900 --> 00:09:20,280
So let's raise that number to two so that we can simultaneously track and render for two images.
101

102
00:09:20,280 --> 00:09:28,600
Now, down here, when we render our pokeScene, at the moment, it only renders eeveee.scn.
102

103
00:09:28,620 --> 00:09:35,820
But we want to be able to render the oddish.scn, as well as eevee, depending on which card and which
103

104
00:09:35,850 --> 00:09:37,630
images were detected.
104

105
00:09:37,650 --> 00:09:45,620
So as a challenge, can you modify this code so that when the orange card is detected,
105

106
00:09:45,630 --> 00:09:51,630
so we only have Oddish on the table, then we should only see the Oddish model rendered.
106

107
00:09:51,780 --> 00:09:57,810
But when we have Eevee on the table as well, then we should be able to see both models rendered onto
107

108
00:09:57,810 --> 00:09:58,990
the correct card.
108

109
00:09:59,190 --> 00:10:05,070
So pause the video and see if you can complete this challenge.
109

110
00:10:05,120 --> 00:10:05,480
All right.
110

111
00:10:05,510 --> 00:10:06,560
So how did that go?
111

112
00:10:07,250 --> 00:10:20,500
Let's say that if imageAnchor.referenceImage.name == "eevee-card,"
112

113
00:10:20,580 --> 00:10:26,700
and remember, this is the name that we had printed in our debug console and it also refers to the name
113

114
00:10:26,700 --> 00:10:28,910
of the card over here.
114

115
00:10:29,220 --> 00:10:32,210
And, again, make sure you don't have any typos there.
115

116
00:10:32,280 --> 00:10:39,270
So if the card that was recognized was the eevee-card, then, in that case, we should be rendering a
116

117
00:10:39,270 --> 00:10:42,060
pokeScene with the eevee.scn.
117

118
00:10:42,270 --> 00:10:53,250
And we should be rendering that onto the card. Now at the same time, if the imageAnchor.referenceImage.name
118

119
00:10:53,250 --> 00:10:57,780
was "oddish-card,"
119

120
00:10:57,810 --> 00:11:00,600
so the app saw the oddish-card,
120

121
00:11:00,630 --> 00:11:06,160
then we should be rendering the oddish.scn file or the Oddish scene,
121

122
00:11:06,450 --> 00:11:16,290
and we should be adding that node to our planeNode. So, now let's just briefly review our code. This delegate
122

123
00:11:16,290 --> 00:11:25,380
method gets triggered whenever any of the images in the group that's Pokémon cards gets detected, and
123

124
00:11:25,380 --> 00:11:33,120
that is because we added all of those groups over here, so that our AR app starts tracking all of those
124

125
00:11:33,120 --> 00:11:34,110
cuts.
125

126
00:11:34,590 --> 00:11:41,090
And when one of them or both of them gets detected, then we add a plane to that
126

127
00:11:41,100 --> 00:11:44,390
imageAnchor at the position of the image.
127

128
00:11:44,490 --> 00:11:51,440
So that's when we end up with that see-through white panel that's flushed with the card.
128

129
00:11:51,450 --> 00:11:58,930
Now, if there's two cards that get detected, then they both get a white panel or a plane added to it.
129

130
00:12:00,470 --> 00:12:07,180
If the image that was detected is the eevee-card, then we create a scene using eevee.scn,
130

131
00:12:07,290 --> 00:12:10,510
and we add it onto the plane.
131

132
00:12:10,510 --> 00:12:14,580
Now, if the image that was detected was the oddish-card,
132

133
00:12:14,580 --> 00:12:25,230
then we add our oddish scene to the plane. And because we've set our maximumNumberOfTrackedImages to 2,
133

134
00:12:25,530 --> 00:12:34,170
then we can now simultaneously track movements and location for two images.
134

135
00:12:34,170 --> 00:12:40,640
So this should now fulfill all our requirements. And let's run our app to see if it does indeed work.
135

136
00:12:42,750 --> 00:12:43,020
Okay.
136

137
00:12:43,050 --> 00:12:48,690
So here's our app running. And let's just flip over one of these cards.
137

138
00:12:48,720 --> 00:12:50,090
There's Eevee
138

139
00:12:50,590 --> 00:12:54,870
and there's all Oddish. And I can move them around,
139

140
00:12:54,870 --> 00:12:56,640
I can rotate them.
140

141
00:12:56,730 --> 00:13:00,150
I can lift them up off the ground.
141

142
00:13:00,150 --> 00:13:09,570
I can move them around. And at the same time, I can have both of these guys on the screen and moving, so
142

143
00:13:09,570 --> 00:13:13,610
they could be attacking each other or something like that.
143

144
00:13:15,230 --> 00:13:22,100
So, I hope you had fun building this project along with me, and I hope this project has inspired you to create
144

145
00:13:22,100 --> 00:13:31,340
some awesome things using ARKit and SceneKit. Now, I look forward to hearing all about the amazing
145

146
00:13:31,340 --> 00:13:33,960
incredible things that you guys are building.
146

147
00:13:34,010 --> 00:13:38,310
So be sure to hit up the team at robots@londonappbrewery. com
147

148
00:13:38,390 --> 00:13:45,980
if you build something fantastic and you want to be entered into the Monthly Student App Selection that
148

149
00:13:45,980 --> 00:13:50,270
will go out in the newsletter to all of our students worldwide.
149

150
00:13:50,300 --> 00:13:59,300
So in the next module, we're going to be looking at how we can stop playing video when we track and recognize
150

151
00:13:59,420 --> 00:14:01,580
images in AR.
151

152
00:14:01,610 --> 00:14:08,450
So we're going to be building the interactive Harry Potter style newspapers where everything on the
152

153
00:14:08,450 --> 00:14:10,640
page comes alive.
153

154
00:14:10,640 --> 00:14:13,970
So for all of that and more, I'll see you on the next module.
