Swift 使用SceneKit进行命中测试,但不使用SCNNode返回命中
XCode中的文档明确指出,当计划测试3D线段时,可以使用SCNRender、SCNView或SCNNode本身在SceneKit中测试几何体。我使用SCNScene,它的节点没有渲染器或视图,因此我计划使用SCNNode测试。我创建了一个SCNScene,在其中放置了一个SCNNode,并测试了一条穿过的简单光线,但我总是得到一个空的命中列表,我不明白为什么:Swift 使用SceneKit进行命中测试,但不使用SCNNode返回命中,swift,scenekit,scnnode,Swift,Scenekit,Scnnode,XCode中的文档明确指出,当计划测试3D线段时,可以使用SCNRender、SCNView或SCNNode本身在SceneKit中测试几何体。我使用SCNScene,它的节点没有渲染器或视图,因此我计划使用SCNNode测试。我创建了一个SCNScene,在其中放置了一个SCNNode,并测试了一条穿过的简单光线,但我总是得到一个空的命中列表,我不明白为什么: import Swift import SceneKit let boxGeometry = SCNBox(width: 1.0,
import Swift
import SceneKit
let boxGeometry = SCNBox(width: 1.0, height: 1.0, length: 1.0, chamferRadius: 0)
let boxNode = SCNNode(geometry: boxGeometry)
var scene = SCNScene()
scene.rootNode.addChildNode(boxNode)
let from = SCNVector3(x: 0, y: -2, z: 0)
let to = SCNVector3(x: 0, y: 2 , z: 0)
var hits = scene.rootNode.hitTestWithSegmentFromPoint(from, toPoint: to, options:nil) // this is always empty
if hits != nil {
if hits!.count > 0 {
var hit = (hits!.first as! SCNHitTestResult).node as SCNNode
}
}
我尝试过通过各种形式的选项,但没有任何改变
我做错了什么?我找到了答案,这要么是一个错误,要么是一个功能:使用SCNScene及其节点SCNNode进行3D HitTest,特别是方法:“hitTestWithSegmentFromPoint(toPoint:options:)”不会返回命中,除非场景包含在SCNView中。它似乎不能在屏幕外使用。我的猜测是你为什么会这样,尽管我可以想象这与在图形卡上执行这些相当昂贵的计算有关 我已经使用GameView SCNScene初学者项目对此进行了测试。关键一行是self.gameView!。场景
override func awakeFromNib(){
let scene = SCNScene()
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)
// create and add a camera to the scene
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
scene.rootNode.addChildNode(cameraNode)
// place the camera
cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)
// create and add a light to the scene
let lightNode = SCNNode()
lightNode.light = SCNLight()
lightNode.light!.type = SCNLightTypeOmni
lightNode.position = SCNVector3(x: 0, y: 10, z: 10)
scene.rootNode.addChildNode(lightNode)
// create and add an ambient light to the scene
let ambientLightNode = SCNNode()
ambientLightNode.light = SCNLight()
ambientLightNode.light!.type = SCNLightTypeAmbient
ambientLightNode.light!.color = NSColor.darkGrayColor()
scene.rootNode.addChildNode(ambientLightNode)
// set the scene to the view
// uncomment this to fail
self.gameView!.scene = scene
// allows the user to manipulate the camera
self.gameView!.allowsCameraControl = true
// show statistics such as fps and timing information
self.gameView!.showsStatistics = true
// configure the view
self.gameView!.backgroundColor = NSColor.blackColor()
let hitList = scene.rootNode.hitTestWithSegmentFromPoint(SCNVector3(x:-10,y:0,z:0), toPoint: SCNVector3(x:10,y:0,z:0), options:[SCNHitTestBackFaceCullingKey:false, SCNHitTestSortResultsKey:true, SCNHitTestIgnoreHiddenNodesKey:false])
if hitList?.count > 0 {
println("Hit found: \n\n\( hitList![0] )") // assign self.gameView!.scene = scene to reach this point.
} else {
println("No hit") // uncomment self.gameView!.scene = scene to reach this point.
}
}
我还遇到了hitTestWithSegmentFromPoint的问题 我在viewDidLoad()中调用它,它返回了一个0元素数组,尽管我确信这是成功的
在ViewDidAspect()中调用它(或更高版本)解决了我的问题。要么是SceneKit没有按您预期的方式工作的一个bug,要么是文档没有说明预期的结果,这是一个大问题。不管怎样,我们都会找到答案。2020年也是如此。节点不仅需要位于SCNView中,还需要等待SceneKit的后台进程完成添加。答案中的实际代码不适合我,除非在添加和测试之间有时间间隔(但这可能是因为我使用的是更复杂的模型)。