ARKit –与真实世界对象的碰撞 [英] ARKit – Collision with Real world objects

查看:62
本文介绍了ARKit –与真实世界对象的碰撞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆