【问题标题】:Add SCNNode or UIView to the center of SCNView in order to detect other SCNNodes将 SCNNode 或 UIView 添加到 SCNView 的中心,以便检测其他 SCNNode
【发布时间】:2019-06-14 22:47:48
【问题描述】:

我正在尝试将 UIView 居中到我的 SCNView 的中心,以便检测场景中其他添加的 SCNTorus 节点。

我在我的场景视图的中心添加了一个视图,如下所示

var focusPoint: CGPoint {
    return CGPoint(
        x: sceneView.bounds.size.width / 2,
        y: sceneView.bounds.size.height - (sceneView.bounds.size.height / 1.618))
}

然后我尝试了两种方法:

1 -

    func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {

        DispatchQueue.main.async { [weak self] in

            guard let strongSelf = self else { return }

            if !strongSelf.inEditMode { return }

            for node in strongSelf.selectionRingsNodes {

                let projectedPoint = renderer.projectPoint(node.position)
                let projectedCGPoint = CGPoint(x: CGFloat(projectedPoint.x), y: CGFloat(projectedPoint.y))

                let distance = projectedCGPoint.distance(to: strongSelf.focusPoint)


                if distance < 20 {
                    print(node.name)
                }

            }
        }
    }

2 -

    func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {

        DispatchQueue.main.async { [weak self] in

            guard let strongSelf = self else { return }

            if !strongSelf.inEditMode { return }

            for node in strongSelf.selectionRingsNodes {

                let (min, max) = node.boundingBox
                let projectedMinPoint = renderer.projectPoint(min)
                let projectedMinCGPoint = CGPoint(x: CGFloat(projectedMinPoint.x), y: CGFloat(projectedMinPoint.y))

                let projectedMaxPoint = renderer.projectPoint(max)
                let projectedMaxCGPoint = CGPoint(x: CGFloat(projectedMaxPoint.x), y: CGFloat(projectedMaxPoint.y))

                let minX = CGFloat(projectedMinCGPoint.x)
                let maxX = CGFloat(projectedMaxCGPoint.x)
                let minY = CGFloat(projectedMinCGPoint.y)
                let maxY = CGFloat(projectedMaxCGPoint.y)

                let nodeRect = CGRect(x: minX, y: minY, width: maxX - minX, height: maxY - minY)

                if nodeRect.contains(strongSelf.focusPoint) {
                    print(node.name)
                }
            }
        }
    }

这两个方法返回错误的结果,距离很大,x和y也很大。

【问题讨论】:

    标签: swift scenekit arkit


    【解决方案1】:

    我终于找到了解决方案!

    原来我应该把位置转换成场景的世界坐标空间,用这个方法convertPosition(SCNVector3,to:)

    这里是完整的代码:

    func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
    
            DispatchQueue.main.async { [weak self] in
    
                guard let strongSelf = self else { return }
    
                if !strongSelf.inEditMode { return }
    
                for node in strongSelf.selectionRingsNodes {
    
                    let position = node.convertPosition(SCNVector3Zero, to: nil)
                    let projectedPoint = renderer.projectPoint(position)
                    let projectedCGPoint = CGPoint(x: CGFloat(projectedPoint.x), y: CGFloat(projectedPoint.y))
                    let distance = projectedCGPoint.distance(to: strongSelf.focusPoint)
                    if distance < 50 {
                        strongSelf.showToast(message: node.getTopMostParentNode().name!, font: .systemFont(ofSize: 30))
                    }
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-11
      • 1970-01-01
      • 2019-06-29
      • 2018-08-10
      • 2018-03-28
      • 2017-03-03
      • 2019-09-06
      • 2020-02-05
      相关资源
      最近更新 更多