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.
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
}
}
No, you are right. Use
SCNSceneRenderer.hitTest(_:, options:)
when searching for SceneKit content andARSCNView.hitTest(_:types:)
when searching for real objects recognised by ARKit.What seems wrong here is that
categoryBitMask
is, well, a bitmask. 5 has a binary representation of101
. 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, because101
and001
have a matching bit.What you can use is the
OptionSet
protocol.Your model gets the
model
option, but in your hit-testing you only use.userInteraction
.