首页 > 解决方案 > ARKit hitTest(_:options:) 选择放置的 3d 对象不起作用

问题描述

我正在尝试选择一个已放置在检测到的平面上的对象,以便对其执行各种任务,例如通过手势旋转。

为了搜索放置的对象并避免获得无关性质的 hitTestResults(例如,选择平面或 ARWorldMap 本身),我尝试将 hitTest(_:options:) 与 SCNHitTestOption.categoryBitMask 一起使用。然而,hitTest 似乎返回所有类型的结果,而不仅仅是所选 categoryBitMask = 5 的对象,即使根据我的理解 categoryBitMask 是“仅搜索与指定位掩码匹配的对象的选项”。我该如何解决这个问题,有没有更好的方法在 ARKit 中选择放置的 3D 模型?下面是我必须旋转 3d 模型的功能。

enum BodyType: Int {
    case model = 5
}

@objc func panned(recognizer :UIPanGestureRecognizer) {
    guard let recognizerView = recognizer.view as? ARSCNView else {return}

    let touch = recognizer.location(in: recognizerView)
    let translation = recognizer.translation(in: recognizerView)

    let hitTestResult = self.sceneView.hitTest(touch, options: [SCNHitTestOption.categoryBitMask: BodyType.model.rawValue])
    guard let modelNodeHit = hitTestResult.first?.node.parent else{return}
    if recognizer.state == .changed {
            self.newAngleY = Float(translation.x) * (Float) (Double.pi) / 180
            self.newAngleY += self.currentAngleY
            modelNodeHit.eulerAngles.y = self.newAngleY
    }else if recognizer.state == .ended {
        self.currentAngleY = self.newAngleY
    }
}

标签: swiftscenekitarkitscnnodearscnview

解决方案


有没有更好的方法在 ARKit 中选择放置的 3D 模型

不,你是对的。SCNSceneRenderer.hitTest(_:, options:)在搜索 SceneKit 内容和ARSCNView.hitTest(_:types:)搜索 ARKit 识别的真实对象时使用。

这里似乎有问题的categoryBitMask是,嗯,一个位掩码。5 的二进制表示101。SceneKit 然后将每个位与对象上的位进行比较,如果其中任何一个匹配,它将在结果中包含该对象。
因此,当所有其他对象的默认类别为 时1,它都会包含在结果中,因为101001有一个匹配位。

您可以使用的是OptionSet协议。

struct BodyType: OptionSet {
  let rawValue: Int

  static let `default` = BodyType(rawValue: 1)
  static let userInteraction = BodyType(rawValue: 4)

  static let model: BodyType = [.default, .userInteraction]
}

您的模型可以model选择,但在您的命中测试中您只使用.userInteraction.


推荐阅读