-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathGameViewController+ARSCNViewDelegate.swift
131 lines (98 loc) · 4.82 KB
/
GameViewController+ARSCNViewDelegate.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//
// GameViewController+ARSCNViewDelegate.swift
// Multiplayer_test
//
// Created by Shawn Ma on 10/1/18.
// Copyright © 2018 Shawn Ma. All rights reserved.
//
import ARKit
import os.log
extension GameViewController: ARSCNViewDelegate, ARSessionDelegate {
// MARK: - Focus Square
func updateFocusSquare(isObjectVisible: Bool) {
if isObjectVisible {
focusSquare.hide()
} else {
focusSquare.unhide()
}
if let camera = arscnView.session.currentFrame?.camera, case .normal = camera.trackingState , let result = self.arscnView.hitTest(self.screenCenter, types: [.existingPlaneUsingGeometry, .estimatedHorizontalPlane, .estimatedVerticalPlane]).first {
DispatchQueue.main.async {
self.arscnView.scene.rootNode.addChildNode(self.focusSquare)
self.focusSquare.state = .detecting(hitTestResult: result, camera: camera)
}
} else {
DispatchQueue.main.async {
self.focusSquare.state = .initializing
self.arscnView.pointOfView?.addChildNode(self.focusSquare)
}
}
}
// MARK: - AR session management
private func updateSessionInfoLabel(for frame: ARFrame, trackingState: ARCamera.TrackingState) {
// Update the UI to provide feedback on the state of the AR experience.
let message: String
//
switch trackingState {
case .normal where frame.anchors.isEmpty:
// No planes detected; provide instructions for this app's AR interactions.
message = "Move around to map the environment, or wait to join a shared session."
case .notAvailable:
message = "Tracking unavailable."
case .limited(.excessiveMotion):
message = "Tracking limited - Move the device more slowly."
case .limited(.insufficientFeatures):
message = "Tracking limited - Point the device at an area with visible surface detail, or improve lighting conditions."
case .limited(.relocalizing):
message = "Resuming session — move to where you were when the session was interrupted."
case .limited(.initializing):
message = "Initializing AR session."
default:
// when tracking is normal and planes are visible.
// (Nor when in unreachable limited-tracking states.)
message = "Tracking is normal"
}
sessionInfoLabel.text = message
sessionInfoView.isHidden = message.isEmpty
}
// MARK: - ARSCNViewDelegate
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
DispatchQueue.main.async {
self.updateFocusSquare(isObjectVisible: !self.padView.isHidden)
}
os_signpost(.begin, log: .render_loop, name: .render_loop, signpostID: .render_loop,
"Render loop started")
os_signpost(.begin, log: .render_loop, name: .logic_update, signpostID: .render_loop,
"Game logic update started")
if let gameManager = self.gameManager, gameManager.isInitialized {
GameTime.updateAtTime(time: time)
gameManager.update(timeDelta: GameTime.deltaTime)
}
os_signpost(.end, log: .render_loop, name: .logic_update, signpostID: .render_loop,
"Game logic update finished")
}
// MARK: - ARSessionDelegate
func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) {
updateSessionInfoLabel(for: session.currentFrame!, trackingState: camera.trackingState)
}
/// - Tag: CheckMappingStatus
func session(_ session: ARSession, didUpdate frame: ARFrame) {
mappingStatusLabel.text = frame.worldMappingStatus.description
updateSessionInfoLabel(for: frame, trackingState: frame.camera.trackingState)
}
// MARK: - ARSessionObserver
func sessionWasInterrupted(_ session: ARSession) {
// Inform the user that the session has been interrupted, for example, by presenting an overlay.
sessionInfoLabel.text = "Session was interrupted"
}
func sessionInterruptionEnded(_ session: ARSession) {
// Reset tracking and/or remove existing anchors if consistent tracking is required.
sessionInfoLabel.text = "Session interruption ended"
}
func session(_ session: ARSession, didFailWithError error: Error) {
// Present an error message to the user.
sessionInfoLabel.text = "Session failed: \(error.localizedDescription)"
}
func sessionShouldAttemptRelocalization(_ session: ARSession) -> Bool {
return true
}
}