Как сделать hitTest на подузлах узла в sceneView? - PullRequest
0 голосов
/ 30 апреля 2018

У меня есть ARSceneView, и я использую DetectionImages, чтобы найти плоскость, чтобы я мог добавить узлы на основе изображения, которое я обнаружил.

Моя проблема заключается в том, что все время, когда представление добавляет невидимый плоский узел над узлами, которые я добавил в качестве подузлов в "узле моего изображения", и когда я добавляю TapGestureRecognizer в sceneView, я не могу обнаружить узел, потому что он обнаруживает самолет. Иногда это работает, но когда он добавляет самолет, он не работает.

Когда самолет находится на сцене, мои узлы это

Я хочу, чтобы мои узлы были такими ...

elements 3 элемента - 0: | нет ребенка> - 1: SCNNode: 0x1c41f4100 | свет = - 2: SCNNode: 0x1c43e1000 'DetectableChildrenParent' pos (-0.009494 -0.081575 -0.360098) rot (0.997592 -0.060896 0.033189 1.335512) | 2 детей>

и мои двое детей будут только обнаруживаемыми узлами ..

но это всегда так

elements 4 элемента - 0: SCNNode: 0x1c01fcc00 pos (-0.093724 0.119850 -0.060124) rot (-0.981372 0.172364 -0.084866 0.457864) масштаб (1.000000 1.000000 1.000000) | камера = | нет ребенка> - 1: SCNNode: 0x1c01fc200 | свет = | нет ребенка> - 2: SCNNode: 0x1c01fd100 'DetectableChildrenParent' pos (-0,149971 0,050361 -0,365586) rot (0,996908 0,061535 -0,048872 1,379775) масштаб (1,000000 1,000000 1,000000) | 2 детей> - 3: SCNNode: 0x1c01f9f00 | геометрия = | нет ребенка>

и всегда обнаруживает последний узел.

Мой код для обнаружения это

@objc func addNodeToScene(withGestureRecognizer recognizer: UIGestureRecognizer) {
            let tapLocation = recognizer.location(in: self.sceneView)
            let hitTestResults = sceneView.hitTest(tapLocation)
            if let node = hitTestResults.first?.node {
                    print(node.name ?? "")
            }
    }

Как запустить тест на попадание, чтобы проверить только дочерние элементы DetectableChildrenParent?

1 Ответ

0 голосов
/ 30 апреля 2018

Предполагая, что я правильно истолковал ваш вопрос, вы ищете childNodes свойство SCNHitTestResult Node, которое относится к:

Массив дочерних узлов в иерархии графа сцены.

Поэтому я считаю, что вы можете попробовать что-то вроде этого:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    //1. Get The Current Touch Location
    guard let currentTouchLocation = touches.first?.location(in: self.augmentedRealityView),

        //2. Get The Tapped Node From An SCNHitTest
        let hitTestResultNode = self.augmentedRealityView.hitTest(currentTouchLocation, options: nil).first?.node else { return }

    //3. Loop Through The ChildNodes
    for node in hitTestResultNode.childNodes{

        //4. If The Node Has A Name Then Print It Out
        if let validName = node.name{
             print("Node\(validName) Is A Child Node Of \(hitTestResultNode)")
        }

    }

}

В качестве альтернативы, вместо того, чтобы искать 1-й результат SCNHitTest, вы можете попробовать поискать последний, например:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    //1. Get The Current Touch Location
    guard let currentTouchLocation = touches.first?.location(in: self.augmentedRealityView),

        //2. Get The Tapped Node From An SCNHitTest
        let hitTestResultNode = self.augmentedRealityView.hitTest(currentTouchLocation, options: nil).last?.node else { return }

    //3. Loop Through The ChildNodes
    for node in hitTestResultNode.childNodes{

        //4. If The Node Has A Name Then Print It Out
        if let validName = node.name{
             print("Node\(validName) Is A Child Node Of \(hitTestResultNode)")
        }

    }

}

Если вы ищете детей определенного SCNNode, вы используете следующее:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    //1. Get The Current Touch Location
    guard let currentTouchLocation = touches.first?.location(in: self.augmentedRealityView),

    //2. Get The Tapped Node From An SCNHitTest
    let hitTestResultNode = self.augmentedRealityView.hitTest(currentTouchLocation, options: nil).first?.node else { return }

    //3. If The Name Of The Nodes Is Equal To DetectableChildrenParent Then Get The Children
    if hitTestResultNode.name == "DetectableChildrenParent"{

        let childNodes = hitTestResultNode.childNodes

        print(childNodes)
    }

}

Или вы можете просто перебрать SCNHitTestResults следующим образом:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    //1. Get The Current Touch Location
    guard let currentTouchLocation = touches.first?.location(in: self.augmentedRealityView) else { return }

    //2. Get The Results Of The SCNHitTest
    let hitTestResults = self.augmentedRealityView.hitTest(currentTouchLocation, options: nil)


    //3. Loop Through Them And Handle The Result
    for result in hitTestResults{

        print(result.node)
        print(result.node.childNodes)
    }


}

Надеюсь, это поможет ...

...