微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

swift – 未检测到两个节点之间的冲突ARKit

我创建了两个节点:一个球体和一个盒子:

var sphere = SCNNode(geometry: SCNSphere(radius: 0.005))
    //I get the Box node from scn file
    let BoxScene = SCNScene(named: "art.scnassets/world.scn")!
    var BoxNode: SCNNode?

我想要两个节点或physicsBody进行交互,所以我为categoryBitMask和contactTestBitMask创建了一个类别:

struct CollisionCategory: OptionSet {
    let rawValue: Int
    static let Box = CollisionCategory(rawValue: 1)
    static let sphere = CollisionCategory(rawValue: 2)
}

在这里,我将盒子节点设置为物理体:

self.BoxScene.rootNode.enumerateChildNodes { (node,_) in
    if node.name == "Box" {
        BoxNode = node
        let BoxBodyShape = SCNPhysicsShape(geometry: SCNBox(width: 0.1,height: 0.1,length: 0.1,chamferRadius: 0.1),options: nil)
        let physicsBody = SCNPhysicsBody(type: .static,shape: BoxBodyShape)
        BoxNode!.physicsBody = physicsBody
        BoxNode!.physicsBody?.categoryBitMask = CollisionCategory.Box.rawValue
        BoxNode!.physicsBody?.contactTestBitMask = CollisionCategory.sphere.rawValue
        BoxNode!.physicsBody?.collisionBitMask = BoxNode!.physicsBody!.contactTestBitMask
    }
}

在这里,我在渲染函数中设置了球体节点,您可以在视图中移动:

func setUpSphere() {
         let sphereBodySphere = SCNPhysicsShape(geometry: SCNSphere(radius: 0.005))
         let physicsBody = SCNPhysicsBody(type: .kinematic,shape: sphereBodySphere)
         sphere.physicsBody = physicsBody
         sphere.physicsBody?.categoryBitMask = CollisionCategory.sphere.rawValue
         sphere.physicsBody?.contactTestBitMask = CollisionCategory.Box.rawValue
         sphere.geometry?.firstMaterial?.diffuse.contents = UIColor.blue
         sphere.physicsBody?.collisionBitMask = sphere.physicsBody!.contactTestBitMask
         prevIoUsPoint = currentPosition 
}

///It Adds a sphere and changes his position
func renderer(_ renderer: SCNSceneRenderer,willRenderScene scene: SCNScene,atTime time: TimeInterval) {
    guard let pointOfView = sceneView.pointOfView else { return }
    let mat = pointOfView.transform
    let dir = SCNVector3(-1 * mat.m31,-1 * mat.m32,-1 * mat.m33)
    let currentPosition = pointOfView.position + (dir * 0.185)

    if buttonpressed {
        if let prevIoUsPoint = prevIoUsPoint {
            sphere.position = currentPosition
            sceneView.scene.rootNode.addChildNode(sphere)
        }
     }
}

我将协议SCNPhysicsContactDelegate添加到ViewController,
我在ViewDidLoad()中设置:

override func viewDidLoad() {
    super.viewDidLoad()
    sceneView.delegate = self
    sceneView.scene.physicsWorld.contactDelegate = self
    ///I correctly see the shapes of the sphere and the Box physics            bodies using
    sceneView.debugOptions = .showPhysicsShapes
    createBox()
    setUpSphere()
    sceneView.scene = BoxScene
    sceneView.scene.physicsWorld.contactDelegate = self
}

然后我添加了这个功能

func physicsWorld(_ world: SCNPhysicsWorld,didEnd contact: SCNPhysicsContact) {
        print("Collision!")
}

enter image description here

这就是发生的事情.

当两个节点碰撞时没有任何反应,所以我不知道这两个物体是否在接触.问题可能是关于.kinematic,.static还是关于函数render()?
我在ARKit:Tutorial 1,Tutorial 2中逐步跟踪了有关碰撞的不同教程.
我不知道它为什么不像预期的那样工作.
我的代码中有什么问题吗?

下载文件代码链接https://ufile.io/20sla

解决方法

每次渲染场景时,willRenderScene都会被称为uptown 60次.因为你每次重建物理体时都会重新发现物理引擎确定碰撞.

尝试将代码更改为仅在设置期间创建物理主体一次.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐