Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 使用SceneKit进行命中测试,但不使用SCNNode返回命中_Swift_Scenekit_Scnnode - Fatal编程技术网

Swift 使用SceneKit进行命中测试,但不使用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,

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

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
    }
}
我尝试过通过各种形式的选项,但没有任何改变

  • SCNHitTestFirstFoundOnlyKey:是或否不会改变任何事情
  • 是或否不会改变任何事情
  • SCNHitTestClipToZRangeKey:对于SCNNode无效
  • SCNHitestBackfaceCullingKey:是或否不会改变任何东西
  • SCNHitTestBoundingBoxOnlyKey:是或否不会改变任何东西
  • SCNHITTSROOTNODEKEY:场景或boxNode的根节点不会更改 任何事
  • SCNHITTESTIGNORHIDDENNODESKEY:是或否不会改变任何事情

  • 我做错了什么?

    我找到了答案,这要么是一个错误,要么是一个功能:使用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的后台进程完成添加。答案中的实际代码不适合我,除非在添加和测试之间有时间间隔(但这可能是因为我使用的是更复杂的模型)。