@@ -18,7 +18,10 @@ class ViewController: UIViewController, ARSCNViewDelegate {
18
18
fileprivate var mainNode : SCNNode !
19
19
fileprivate weak var logoView : LogoPartsView ?
20
20
fileprivate var requestLock = false
21
+ fileprivate var checkingFrame : ARFrame ?
21
22
fileprivate var timer = Timer ( )
23
+ fileprivate var offers = [ Offer] ( )
24
+ fileprivate var showedMerchants : [ OffersMerchants ] = [ ]
22
25
23
26
override func viewDidLoad( ) {
24
27
super. viewDidLoad ( )
@@ -34,13 +37,13 @@ class ViewController: UIViewController, ARSCNViewDelegate {
34
37
super. viewDidAppear ( animated)
35
38
setupSession ( )
36
39
// @TODO: Temporary test deals icons
37
- DispatchQueue . main. asyncAfter ( deadline: . now( ) + 0.5 ) {
38
- self . add ( . dealfree, position: SCNVector3 ( - 1 , 0 , - 3.8 ) )
39
- self . add ( . deal10, position: SCNVector3 ( 0 , 0 , - 4 ) )
40
- self . add ( . deal20, position: SCNVector3 ( 1 , 0 , - 3.8 ) )
41
- self . add ( . deal30, position: SCNVector3 ( 3 , 0 , - 3 ) )
42
- self . add ( . deal40, position: SCNVector3 ( 5 , 0 , 0 ) )
43
- }
40
+ // DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
41
+ // self.add(.dealfree, position: SCNVector3(-1, 0, -3.8))
42
+ // self.add(.deal10, position: SCNVector3(0, 0, -4))
43
+ // self.add(.deal20, position: SCNVector3(1, 0, -3.8))
44
+ // self.add(.deal30, position: SCNVector3(3, 0, -3))
45
+ // self.add(.deal40, position: SCNVector3(5, 0, 0))
46
+ // }
44
47
guard let logoView = logoView else { return }
45
48
view. bringSubview ( toFront: logoView)
46
49
logoView. open ( completion: { [ weak logoView] ( success) in
@@ -52,6 +55,31 @@ class ViewController: UIViewController, ARSCNViewDelegate {
52
55
super. viewWillDisappear ( animated)
53
56
session. pause ( )
54
57
}
58
+
59
+ override func touchesBegan( _ touches: Set < UITouch > , with event: UIEvent ? ) {
60
+ super. touchesBegan ( touches, with: event)
61
+ var hitTestOptions = [ SCNHitTestOption: Any] ( )
62
+ hitTestOptions [ SCNHitTestOption . boundingBoxOnly] = true
63
+ let results : [ SCNHitTestResult ] = sceneView. hitTest ( touches. first!. location ( in: sceneView) , options: hitTestOptions)
64
+ for result in results {
65
+ var node = result. node
66
+ var object1 : VirtualObject ?
67
+ while node. parent != nil {
68
+ if let parent = node. parent as? VirtualObject {
69
+ object1 = parent
70
+ break
71
+ }
72
+ node = node. parent!
73
+ }
74
+ guard let object = object1 else { continue }
75
+ let wrapperNode = VirtualObject . convert ( object)
76
+ DispatchQueue . main. async {
77
+ object. removeFromParentNode ( )
78
+ self . setNewVirtualObjectPosition ( object. position, wrapperNode)
79
+ self . mainNode. addChildNode ( wrapperNode)
80
+ }
81
+ }
82
+ }
55
83
}
56
84
57
85
@@ -77,7 +105,29 @@ extension ViewController: ARSessionDelegate {
77
105
// Send out request and cache the image
78
106
let networkClient = NetworkClient ( )
79
107
networkClient. postMerchantIcon ( image, success: { ( merchants) in
80
- print ( " \( merchants) " )
108
+ for merchant in merchants {
109
+ print ( merchant. name)
110
+ guard let offerMerchant = OffersMerchants ( rawValue: merchant. name) else { continue }
111
+ if self . showedMerchants. contains ( offerMerchant) {
112
+ continue
113
+ }
114
+ self . showedMerchants. append ( offerMerchant)
115
+ let offers = OffersManager . shared. offersForMerchant ( merchant. name)
116
+ if self . offers. contains ( where: { $0. merchants. contains ( merchant. name) } ) {
117
+ // Don't do anything since we already check this merchant
118
+ continue
119
+ }
120
+ self . offers. append ( contentsOf: offers)
121
+ // Need to add popup to merchant
122
+ let angles = frame. camera. eulerAngles
123
+ let position = SCNVector3 . positionFromTransform ( frame. camera. transform)
124
+ let defaultDistance : Float = 4
125
+ let z1 = position. z - sin( angles. y + Float. pi/ 2 ) * defaultDistance
126
+ let x1 = position. x + cos( angles. y + Float. pi/ 2 ) * defaultDistance
127
+ DispatchQueue . main. async {
128
+ self . add ( . dealfree, position: SCNVector3 ( x1, - 1.3 , z1) )
129
+ }
130
+ }
81
131
self . requestLock = false
82
132
session. delegate = self
83
133
} , failure: { ( error) in
@@ -96,13 +146,7 @@ fileprivate extension ViewController {
96
146
/// Adds SCNNode to the current scene.
97
147
func add( _ deal: Deals , position: SCNVector3 ) {
98
148
DispatchQueue . global ( ) . async {
99
- let scene = SCNScene ( named: " art.scnassets/ " + deal. rawValue) !
100
- let wrapperNode = SCNNode ( )
101
- for child in scene. rootNode. childNodes {
102
- child. geometry? . firstMaterial? . lightingModel = . physicallyBased
103
- child. movabilityHint = . movable
104
- wrapperNode. addChildNode ( child)
105
- }
149
+ let wrapperNode = VirtualObject ( deal)
106
150
DispatchQueue . main. async {
107
151
self . setNewVirtualObjectPosition ( position, wrapperNode)
108
152
self . mainNode. addChildNode ( wrapperNode)
@@ -131,7 +175,7 @@ fileprivate extension ViewController {
131
175
132
176
func setupSession( ) {
133
177
let configuration = ARWorldTrackingSessionConfiguration ( )
134
- // configuration.planeDetection = .horizontal
178
+ // configuration.planeDetection = .horizontal
135
179
session. run ( configuration, options: [ . resetTracking, . removeExistingAnchors] )
136
180
}
137
181
@@ -173,10 +217,9 @@ fileprivate extension ViewController {
173
217
}
174
218
}
175
219
176
- enum Deals : String {
177
- case dealfree = " dealfree.scn "
178
- case deal10 = " deal10.scn "
179
- case deal20 = " deal20.scn "
180
- case deal30 = " deal30.scn "
181
- case deal40 = " deal40.scn "
220
+ enum OffersMerchants : String {
221
+ case walmart = " Walmart "
222
+ case bath = " Bath and Body Works "
223
+ case target = " Target "
182
224
}
225
+
0 commit comments