本文介绍了ARKit hitTest(_:options :)选择放置的3d对象不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to select an object which has been placed on a detected plane in order to perform various task on it such as rotating through gestures.

为了搜索放置的对象并避免获得不相关性质的hitTestResults(例如,选择飞机或ARWorldMap本身),我试图将hitTest(_:options :)与SCNHitTestOption.categoryBitMask一起使用.但是,尽管按我的理解,categoryBitMask是仅搜索匹配指定位掩码的对象的选项",但hitTest似乎返回所有类型的结果,而不仅仅是返回具有选定categoryBitMask = 5的对象.如何解决此问题,有没有更好的方法在ARKit中选择放置的3D模型?下面是我必须旋转3D模型的功能.

In order to search for placed objects and avoid getting hitTestResults of irrelevant nature (eg. selecting the plane or the ARWorldMap itself) I am trying to use hitTest(_:options:) with SCNHitTestOption.categoryBitMask. However it seems as the hitTest returns results of all types, not just objects with the selected categoryBitMask = 5, even though from my understanding categoryBitMask is "An option to search only for objects matching a specified bitmask." How do I fix this problem, and is there a better way to select placed 3D-models in ARKit? Below is the function I have to rotate a 3d-model.

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
    }
}

推荐答案

不,您是正确的.搜索SceneKit内容时使用SCNSceneRenderer.hitTest(_:, options:),在搜索ARKit可以识别的真实对象时使用ARSCNView.hitTest(_:types:).

No, you are right. Use SCNSceneRenderer.hitTest(_:, options:) when searching for SceneKit content and ARSCNView.hitTest(_:types:) when searching for real objects recognised by ARKit.

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

What seems wrong here is that categoryBitMask is, well, a bitmask. 5 has a binary representation of 101. SceneKit then compares every bit with the bits on your objects and if any of them match, it includes the object in the results.
So when every other object has the default category of 1, it is included in the result, because 101 and 001 have a matching bit.

您可以使用的是 OptionSet 协议.

What you can use is the OptionSet protocol.

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.

Your model gets the model option, but in your hit-testing you only use .userInteraction.

这篇关于ARKit hitTest(_:options :)选择放置的3d对象不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-23 05:55