ARKit hitTest (_: options :) для выбора размещенных 3d-объектов не работает - PullRequest
0 голосов
/ 27 ноября 2018

Я пытаюсь выбрать объект, который был помещен на обнаруженную плоскость, чтобы выполнить на нем различные задачи, такие как вращение с помощью жестов.

Чтобы найти размещенные объекты и избежать попадания hitTestResults неактуальной природы (например, выбор плоскости или сама ARWorldMap), я пытаюсь использовать hitTest (_: options :) с SCNHitTestOption.categoryBitMask.Однако кажется, что hitTest возвращает результаты всех типов, а не только объекты с выбранной categoryBitMask = 5, хотя, насколько я понимаю, categoryBitMask - это «опция для поиска только объектов, соответствующих указанной битовой маске».Как мне решить эту проблему, и есть ли лучший способ выбрать размещенные 3D-модели в ARKit?Ниже приведена функция поворота 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
    }
}

1 Ответ

0 голосов
/ 28 ноября 2018

есть ли лучший способ выбрать размещенные 3D-модели в ARKit

Нет, вы правы.Используйте SCNSceneRenderer.hitTest(_:, options:) при поиске содержимого SceneKit и ARSCNView.hitTest(_:types:) при поиске реальных объектов, распознаваемых ARKit.

Что здесь не так, так это то, что categoryBitMask, ну, в общем, битовая маска.5 имеет двоичное представление 101.Затем SceneKit сравнивает каждый бит с битами ваших объектов и, если любой из них совпадает, он включает объект в результаты.
Поэтому, когда каждый другой объект имеет категорию по умолчанию 1, онвключен в результат, потому что 101 и 001 имеют соответствующий бит.

Можно использовать протокол 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.

...