ARKit –与真实世界对象的碰撞 [英] ARKit – Collision with Real world objects
问题描述
我需要使用ARKit检测虚拟对象何时与现实世界对象接触.
I need to detect when the virtual objects gets in contact with the real world object using ARKit.
有什么办法可以找到它吗?
Is there any way to find it out?
推荐答案
首先,您需要创建一个符合 OptionSet
协议并具有位集类型属性的碰撞类别结构:
At first you need to create a collision category struct that conforms to OptionSet
protocol and has properties with bitset types:
import ARKit
struct Category: OptionSet {
let rawValue: Int
static let sphereCategory = Category(rawValue: 1 << 0)
static let targetCategory = Category(rawValue: 1 << 1)
}
然后在生命周期方法内为 SCNPhysicsContactDelegate
协议设置一个 physics委托
:
Then set a physics delegate
to SCNPhysicsContactDelegate
protocol inside lifecycle method:
class ViewController: UIViewController, SCNPhysicsContactDelegate {
@IBOutlet var sceneView: ARSCNView!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
sceneView.scene.physicsWorld.contactDelegate = self
let config = ARWorldTrackingConfiguration()
config.planeDetection = [.horizontal]
sceneView.session.run(config)
}
}
SCNPhysicsContactDelegate
包含3个可选的physicsWorld()方法(稍后将使用第1个方法):
SCNPhysicsContactDelegate
contains 3 optional physicsWorld() methods (we'll use 1st later):
public protocol SCNPhysicsContactDelegate: NSObjectProtocol {
optional func physicsWorld(_ world: SCNPhysicsWorld,
didBegin contact: SCNPhysicsContact)
optional func physicsWorld(_ world: SCNPhysicsWorld,
didUpdate contact: SCNPhysicsContact)
optional func physicsWorld(_ world: SCNPhysicsWorld,
didEnd contact: SCNPhysicsContact)
}
在此之后,为球体对撞机定义 categoryBitMask
和 collisionBitMask
:
After this define categoryBitMask
and collisionBitMask
for sphere collider:
fileprivate func createSphere() -> SCNNode {
var sphere = SCNNode()
sphere.geometry = SCNSphere(radius: 0.1)
sphere.physicsBody = SCNPhysicsBody(type: .dynamic, shape: nil)
sphere.physicsBody?.isAffectedByGravity = true
sphere.physicsBody?.categoryBitMask = Category.sphereCategory.rawValue
sphere.physicsBody?.collisionBitMask = Category.targetCategory.rawValue
return sphere
}
...并为现实世界中检测到的平面以相反顺序定义位掩码:
...and define bit-masks in reversed order for real world detected plane:
fileprivate func visualizeDetectedPlane() -> SCNNode {
var plane = SCNNode()
plane.geometry = SCNPlane(width: 0.7, height: 0.7)
plane.physicsBody = SCNPhysicsBody(type: .dynamic, shape: nil)
plane.physicsBody?.isAffectedByGravity = false
plane.physicsBody?.categoryBitMask = Category.targetCategory.rawValue
plane.physicsBody?.collisionBitMask = Category.sphereCategory.rawValue
return plane
}
仅当将SCNPlanes添加到实际检测到的平面并将SCNSphere附加到SCNScene时,才可以使用
physicsWorld(_:didBegin:)
实例方法来检测碰撞:
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
if contact.nodeA.physicsBody?.categoryBitMask ==
Category.targetCategory.rawValue ||
contact.nodeB.physicsBody?.categoryBitMask ==
Category.targetCategory.rawValue {
print("BOOM!")
}
}
这篇关于ARKit –与真实世界对象的碰撞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!