【问题标题】:Using SceneKit for hitTesting not returning a hit with SCNNode使用 SceneKit 进行 hitTesting 不返回 SCNNode 的命中
【发布时间】:2017-04-18 17:58:03
【问题描述】:

XCode 中的文档明确指出,当计划测试 3D 线段时,可以使用 SCNRender、SCNView 或 SCNNode 本身在 SceneKit 中对几何体进行 hitTesting。我有一个使用 SCNScene 的节点,它的节点没有渲染器或视图,因此我计划使用 SCNNode hitTesting。我创建了一个 SCNScene,将一个 SCNNode 放入其中并测试通过的简单光线,但我总是得到一个空的 hitList,我不明白为什么:

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
    }
}

我尝试过传递各种形式的选项,但没有任何改变。

  1. SCNHitTestFirstFoundOnlyKey:是或否不会改变任何事情
  2. SCNHitTestSortResultsKey:是或否不会改变任何事情
  3. SCNHitTestClipToZRangeKey:对 SCNNode 无效
  4. SCNHitTestBackFaceCullingKey:是或否不会改变任何事情
  5. SCNHitTestBoundingBoxOnlyKey:是或否不会改变任何事情
  6. SCNHitTestRootNodeKey: 场景或 boxNode 的 rootNOde 没有改变 任何东西
  7. SCNHitTestIgnoreHiddenNodesKey: yes 或 no 不会改变任何东西

我做错了什么?

【问题讨论】:

    标签: swift scenekit scnnode


    【解决方案1】:

    我找到了答案,要么是 bug,要么是功能:使用 SCNScene 及其节点 SCNNode 进行 3D hitTesting,特别是方法:“hitTestWithSegmentFromPoint(toPoint:options:)” 除非场景不返回命中包含在 SCNView 中。看来它不能在屏幕外使用。我的猜测是你为什么会出现这种情况,尽管我可以想象这与在显卡上执行一些相当昂贵的计算有关。

    我已经使用 GameView SCNScene 启动项目对此进行了测试。关键线是 self.gameView!.scene = scene

    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.
        }
    
    }
    

    【讨论】:

    • 要么是 SceneKit 无法按您预期的方式工作的错误,要么是文档没有说明预期的问题。 File a report,无论哪种方式,我们都会找到答案。
    • 2020年也一样。节点不仅需要在SCNView中,还需要等待SceneKit的后台进程完成添加。答案中的实际代码对我不起作用,除非添加和测试之间存在时间间隔(但这可能是因为我使用的是更复杂的模型)。
    【解决方案2】:

    我也遇到了 hitTestWithSegmentFromPoint 的问题。

    我在 viewDidLoad() 中调用它,它返回了一个 0 元素数组,尽管我确信有命中。

    在 viewDidAppear() (或更高版本)中调用它解决了我的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-27
      • 2018-10-14
      • 2015-07-31
      • 2016-03-25
      • 2017-06-28
      • 1970-01-01
      • 2018-03-28
      • 2021-05-20
      相关资源
      最近更新 更多