Проблема зависания ARKit 2.0 при выполнении HitTesting - PullRequest
0 голосов
/ 25 сентября 2018

Поэтому я разрабатываю приложение, которое отображает различные виртуальные объекты, и я взаимодействую с объектом, таким как изменение цветов и дочерних узлов.

Одна проблема, которая присутствует только в ARKit 2.0, заключается в том, что когда я выполняю hitTestчтобы показать «плоскую площадь» на плоскости, которая обнаруживается, экран зависает, этой проблемы не было в ARKit 1.5.

Пример кода взят из Apple Example App (которая также зависает в 2.0):

func worldPositionFromScreenPosition(_ position: CGPoint,
                                     objectPos: SCNVector3?,
                                     infinitePlane: Bool = false) -> (position: SCNVector3?, planeAnchor: ARPlaneAnchor?, hitAPlane: Bool) {

    // -------------------------------------------------------------------------------
    // 1. Always do a hit test against exisiting plane anchors first.
    //    (If any such anchors exist & only within their extents.)

    let planeHitTestResults = sceneView.hitTest(position, types: .existingPlaneUsingExtent)
    if let result = planeHitTestResults.first {

        let planeHitTestPosition = SCNVector3.positionFromTransform(result.worldTransform)
        let planeAnchor = result.anchor

        // Return immediately - this is the best possible outcome.
        return (planeHitTestPosition, planeAnchor as? ARPlaneAnchor, true)
    }

    // -------------------------------------------------------------------------------
    // 2. Collect more information about the environment by hit testing against
    //    the feature point cloud, but do not return the result yet.

    var featureHitTestPosition: SCNVector3?
    var highQualityFeatureHitTestResult = false

    let highQualityfeatureHitTestResults = sceneView.hitTestWithFeatures(position, coneOpeningAngleInDegrees: 18, minDistance: 0.2, maxDistance: 2.0)

    if !highQualityfeatureHitTestResults.isEmpty {
        let result = highQualityfeatureHitTestResults[0]
        featureHitTestPosition = result.position
        highQualityFeatureHitTestResult = true
    }

    // -------------------------------------------------------------------------------
    // 3. If desired or necessary (no good feature hit test result): Hit test
    //    against an infinite, horizontal plane (ignoring the real world).

    if (infinitePlane && dragOnInfinitePlanesEnabled) || !highQualityFeatureHitTestResult {

        let pointOnPlane = objectPos ?? SCNVector3Zero

        let pointOnInfinitePlane = sceneView.hitTestWithInfiniteHorizontalPlane(position, pointOnPlane)
        if pointOnInfinitePlane != nil {
            return (pointOnInfinitePlane, nil, true)
        }
    }

    // -------------------------------------------------------------------------------
    // 4. If available, return the result of the hit test against high quality
    //    features if the hit tests against infinite planes were skipped or no
    //    infinite plane was hit.

    if highQualityFeatureHitTestResult {
        return (featureHitTestPosition, nil, false)
    }

    // -------------------------------------------------------------------------------
    // 5. As a last resort, perform a second, unfiltered hit test against features.
    //    If there are no features in the scene, the result returned here will be nil.

    let unfilteredFeatureHitTestResults = sceneView.hitTestWithFeatures(position)
    if !unfilteredFeatureHitTestResults.isEmpty {
        let result = unfilteredFeatureHitTestResults[0]
        return (result.position, nil, false)
    }

    return (nil, nil, false)
}

Это вызывается в методе ARSCNViewDelegate:

func renderer(_ renderer: SCNSceneRenderer, didRenderScene scene: SCNScene, atTime time: TimeInterval) {}
...