Created
April 29, 2018 07:36
-
-
Save lfarah/e4fecaa696edc36c58a717686d6f8a1e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
See LICENSE folder for this sample’s licensing information. | |
Abstract: | |
Wrapper SceneKit node for virtual objects placed into the AR scene. | |
*/ | |
import Foundation | |
import SceneKit | |
import ARKit | |
class VirtualObject: SCNNode { | |
var modelName: String = "" | |
var fileExtension: String = "" | |
var thumbImage: UIImage! | |
var title: String = "" | |
var modelLoaded: Bool = false | |
var viewController: ViewController? | |
override init() { | |
super.init() | |
self.name = "Virtual object root node" | |
} | |
init(geometry: SCNGeometry?) { | |
super.init() | |
self.geometry = geometry | |
self.name = "Virtual object root node" | |
self.modelName = "modelName" | |
self.fileExtension = "fileExtension" | |
self.thumbImage = #imageLiteral(resourceName: "tom") | |
self.title = "Tom" | |
} | |
init(modelName: String, fileExtension: String, thumbImageFilename: String, title: String) { | |
super.init() | |
self.name = "Virtual object root node" | |
self.modelName = modelName | |
self.fileExtension = fileExtension | |
self.thumbImage = UIImage(named: thumbImageFilename) | |
self.title = title | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
func loadModel() { | |
guard let virtualObjectScene = SCNScene(named: "\(modelName).\(fileExtension)", inDirectory: "Models.scnassets/\(modelName)") else { | |
return | |
} | |
let wrapperNode = SCNNode() | |
for child in virtualObjectScene.rootNode.childNodes { | |
child.geometry?.firstMaterial?.lightingModel = .physicallyBased | |
child.movabilityHint = .movable | |
wrapperNode.addChildNode(child) | |
} | |
self.addChildNode(wrapperNode) | |
modelLoaded = true | |
} | |
func unloadModel() { | |
for child in self.childNodes { | |
child.removeFromParentNode() | |
} | |
modelLoaded = false | |
} | |
func translateBasedOnScreenPos(_ pos: CGPoint, instantly: Bool, infinitePlane: Bool) { | |
guard let controller = viewController else { | |
return | |
} | |
let result = controller.worldPositionFromScreenPosition(pos, objectPos: self.position, infinitePlane: infinitePlane) | |
controller.moveVirtualObjectToPosition(result.position, instantly, !result.hitAPlane) | |
} | |
} | |
extension VirtualObject { | |
static func isNodePartOfVirtualObject(_ node: SCNNode) -> Bool { | |
if node.name == "Virtual object root node" { | |
return true | |
} | |
if node.parent != nil { | |
return isNodePartOfVirtualObject(node.parent!) | |
} | |
return false | |
} | |
} | |
// MARK: - Protocols for Virtual Objects | |
protocol ReactsToScale { | |
func reactToScale() | |
} | |
extension SCNNode { | |
func reactsToScale() -> ReactsToScale? { | |
if let canReact = self as? ReactsToScale { | |
return canReact | |
} | |
if parent != nil { | |
return parent!.reactsToScale() | |
} | |
return nil | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment