SCNNode有一个hitTestWithSegment方法用以检测两点连线通过的Node,使用方法如下:
let scene = SCNScene()
sceneView.delegate = self
let boxGeometry = SCNBox(width: 1.0, height: 1.0, length: 1.0, chamferRadius: 0.0)
let boxNode = SCNNode(geometry: boxGeometry)
boxNode.position=SCNVector3(x: 0, y: 0, z: 0)
scene.rootNode.addChildNode(boxNode)
sceneView.scene = scene
let hitList = sceneView.scene.rootNode.hitTestWithSegment(from: SCNVector3(x:-10,y:0,z:0), to: SCNVector3(x:10,y:0,z:0), options:[SCNHitTestOption.backFaceCulling.rawValue:false, SCNHitTestOption.sortResults.rawValue:true, SCNHitTestOption.ignoreHiddenNodes.rawValue:false])
if hitList.count > 0 {
print("Hit found: \n\n\( hitList[0] )")
} else {
print("No hit")
}
但是如果我们调整一下代码顺序:
let scene = SCNScene()
sceneView.delegate = self
sceneView.scene = scene
let boxGeometry = SCNBox(width: 1.0, height: 1.0, length: 1.0, chamferRadius: 0.0)
let boxNode = SCNNode(geometry: boxGeometry)
boxNode.position=SCNVector3(x: 0, y: 0, z: 0)
sceneView.scene.rootNode.addChildNode(boxNode)
let hitList = sceneView.scene.rootNode.hitTestWithSegment(from: SCNVector3(x:-10,y:0,z:0), to: SCNVector3(x:10,y:0,z:0), options:[SCNHitTestOption.backFaceCulling.rawValue:false, SCNHitTestOption.sortResults.rawValue:true, SCNHitTestOption.ignoreHiddenNodes.rawValue:false])
if hitList.count > 0 {
print("Hit found: \n\n\( hitList[0] )")
} else {
print("No hit")
}
将得不到预期的结果,不知道这是bug还是有其他我没理解的地方。
实际使用中多是用第二种写法,这时我们不能在直接使用
sceneView.scene.rootNode.hitTestWithSegment
我们需要使用SCNSceneRenderer
extension UIViewController: ARSCNViewDelegate{
public func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
let hitList = renderer.scene?.rootNode.hitTestWithSegment(from: SCNVector3(x:-10,y:0,z:0), to: SCNVector3(x:10,y:0,z:0), options:[SCNHitTestOption.backFaceCulling.rawValue:false, SCNHitTestOption.sortResults.rawValue:true, SCNHitTestOption.ignoreHiddenNodes.rawValue:false])
if (hitList?.count)! > 0 {
print("Hit found: \n\n\( hitList![0] )")
} else {
print("No hit")
}
}
}