/
Plane.swift
executable file
·92 lines (71 loc) · 2.46 KB
/
Plane.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
/*
See LICENSE folder for this sample’s licensing information.
Abstract:
SceneKit node wrapper for plane geometry detected in AR.
*/
import Foundation
import ARKit
class Plane: SCNNode {
var anchor: ARPlaneAnchor
var occlusionNode: SCNNode?
let occlusionPlaneVerticalOffset: Float = -0.01 // The occlusion plane should be placed 1 cm below the actual
// plane to avoid z-fighting etc.
var debugVisualization: PlaneDebugVisualization?
var focusSquare: FocusSquare?
init(_ anchor: ARPlaneAnchor, _ showDebugVisualization: Bool) {
self.anchor = anchor
super.init()
self.showDebugVisualization(showDebugVisualization)
createOcclusionNode()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func update(_ anchor: ARPlaneAnchor) {
self.anchor = anchor
debugVisualization?.update(anchor)
updateOcclusionNode()
}
func showDebugVisualization(_ show: Bool) {
if show {
if debugVisualization == nil {
DispatchQueue.global().async {
self.debugVisualization = PlaneDebugVisualization(anchor: self.anchor)
DispatchQueue.main.async {
self.addChildNode(self.debugVisualization!)
}
}
}
} else {
debugVisualization?.removeFromParentNode()
debugVisualization = nil
}
}
func updateOcclusionSetting() {
if occlusionNode == nil {
createOcclusionNode()
}
}
// MARK: Private
private func createOcclusionNode() {
// Make the occlusion geometry slightly smaller than the plane.
let occlusionPlane = SCNPlane(width: CGFloat(anchor.extent.x - 0.05), height: CGFloat(anchor.extent.z - 0.05))
let material = SCNMaterial()
material.colorBufferWriteMask = []
material.isDoubleSided = true
occlusionPlane.materials = [material]
occlusionNode = SCNNode()
occlusionNode!.geometry = occlusionPlane
occlusionNode!.transform = SCNMatrix4MakeRotation(-Float.pi / 2.0, 1, 0, 0)
occlusionNode!.position = SCNVector3Make(anchor.center.x, occlusionPlaneVerticalOffset, anchor.center.z)
self.addChildNode(occlusionNode!)
}
private func updateOcclusionNode() {
guard let occlusionNode = occlusionNode, let occlusionPlane = occlusionNode.geometry as? SCNPlane else {
return
}
occlusionPlane.width = CGFloat(anchor.extent.x - 0.05)
occlusionPlane.height = CGFloat(anchor.extent.z - 0.05)
occlusionNode.position = SCNVector3Make(anchor.center.x, occlusionPlaneVerticalOffset, anchor.center.z)
}
}