gpt4 book ai didi

swift - ARKit——与真实世界物体的碰撞

转载 作者:行者123 更新时间:2023-12-03 23:48:06 45 4
gpt4 key购买 nike

我需要使用 ARKit 检测虚拟对象何时与现实世界对象接触。

有什么办法可以查出来吗?

最佳答案

首先您需要创建一个符合OptionSet 协议(protocol)并具有bitset 类型属性的碰撞类别结构:

import ARKit

struct Category: OptionSet {

let rawValue: Int

static let sphereCategory = Category(rawValue: 1 << 0)
static let targetCategory = Category(rawValue: 1 << 1)
}

然后在生命周期方法中设置一个 physics delegateSCNPhysicsContactDelegate 协议(protocol):

class ViewController: UIViewController, SCNPhysicsContactDelegate {

@IBOutlet var sceneView: ARSCNView!

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

sceneView.scene = SCNScene()
sceneView.scene.physicsWorld.contactDelegate = self

let config = ARWorldTrackingConfiguration()
config.planeDetection = [.horizontal]
sceneView.session.run(config)
}
}

SCNPhysicsContactDelegate 包含 3 个可选的 physicsWorld() 方法(稍后我们将使用第一个):

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

在此之后为球体碰撞器定义 categoryBitMaskcollisionBitMask:

fileprivate func createSphere() -> SCNNode {

var sphere = SCNNode()
sphere.geometry = SCNSphere(radius: 0.1)

sphere.physicsBody = .init(type: .kinematic,
shape: .init(geometry: sphere.geometry!,
options: nil))

sphere.physicsBody?.isAffectedByGravity = true

sphere.physicsBody?.categoryBitMask = Category.sphereCategory.rawValue
sphere.physicsBody?.collisionBitMask = Category.targetCategory.rawValue
sphere.physicsBody?.contactTestBitMask = Category.targetCategory.rawValue

return sphere
}

...并以相反的顺序为真实世界检测到的平面定义位掩码:

fileprivate func visualizeDetectedPlane() -> SCNNode {

var plane = SCNNode()
plane.geometry = SCNPlane(width: 0.7, height: 0.7)

plane.physicsBody = .init(type: .kinematic,
shape: .init(geometry: plane.geometry!,
options: nil))

plane.physicsBody?.isAffectedByGravity = false

plane.physicsBody?.categoryBitMask = Category.targetCategory.rawValue
plane.physicsBody?.collisionBitMask = Category.sphereCategory.rawValue
plane.physicsBody?.contactTestBitMask = Category.sphereCategory.rawValue

return plane
}

And only when you've added your SCNPlanes to real-world detected planes and append an SCNSphere to your SCNScene, you could use physicsWorld(_:didBegin:) instance method to detect collisions:

func physicsWorld(_ world: SCNPhysicsWorld, 
didBegin contact: SCNPhysicsContact) {

if contact.nodeA.physicsBody?.categoryBitMask ==
Category.targetCategory.rawValue |
contact.nodeB.physicsBody?.categoryBitMask ==
Category.targetCategory.rawValue {

print("BOOM!")
}
}

关于swift - ARKit——与真实世界物体的碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61337942/

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com