Обнаружение столкновения SCNNode не распознается в ARSCNView - PullRequest
0 голосов
/ 31 мая 2018

У меня проблемы с обнаружением коллизий в AR / SCNKit.Я нашел это: Как настроить обнаружение коллизий SceneKit , хотя это полезно, но мой код по-прежнему не работает.

Основная цель - обнаружить, когда два узла сцены соприкасаются, одинball, другой - это scnbox, выполняющий роль scnplane.

ViewController.swift

class ViewController: UIViewController, ARSCNViewDelegate, SCNPhysicsContactDelegate{

    override func viewDidLoad() {
        super.viewDidLoad()
        let scene = SCNScene()
        sceneView.scene = scene
        sceneView.scene.physicsWorld.contactDelegate = self
    }

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        guard let planeAnchor = anchor as? ARPlaneAnchor else { return }

        let width = CGFloat(planeAnchor.extent.x)
        let length = CGFloat(planeAnchor.extent.z)
        let planeHeight = CGFloat(0.01)

        let plane = SCNBox(width: width, height:planeHeight, length:length, chamferRadius: 0)

        plane.materials.first?.diffuse.contents = UIColor.orange
        let planeNode = SCNNode(geometry: plane)

        let x = CGFloat(planeAnchor.center.x)
        let y = CGFloat(planeAnchor.center.y)
        let z = CGFloat(planeAnchor.center.z)
        planeNode.position = SCNVector3(x,y,z)

        planeNode.physicsBody = SCNPhysicsBody(type:.kinematic, shape: SCNPhysicsShape(geometry:plane, options:nil))
        planeNode.physicsBody?.categoryBitMask = Int(CategoryMask.plane.rawValue)
        planeNode.physicsBody?.collisionBitMask = Int(CategoryMask.ball.rawValue) | Int(CategoryMask.plane.rawValue)
    }

    func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
        print("-> didBeginContact")
    }

    func physicsWorld(_ world: SCNPhysicsWorld, didUpdate contact: SCNPhysicsContact) {
        print("-> didUpdateContact")
    }

    func physicsWorld(_ world: SCNPhysicsWorld, didEnd contact: SCNPhysicsContact) {
        print("-> didEndContact")
    }

Ball.swift

class Ball {
    init(x: Float, y: Float, z:Float){

    let sphereNode = SCNNode()
    let sphere = SCNSphere(radius: 0.05)
    sphereNode.addChildNode(SCNNode(geometry: sphere))

    sphereNode.position = SCNVector3(x, y, z)
    self.node = sphereNode

    self.node.physicsBody = SCNPhysicsBody(type: .dynamic, shape: SCNPhysicsShape(geometry:sphere, options:nil))
    self.node.physicsBody?.categoryBitMask = Int(CategoryMask.ball.rawValue)
    self.node.physicsBody?.collisionBitMask = Int(CategoryMask.ball.rawValue) | Int(CategoryMask.plane.rawValue)
    self.node.physicsBody?.friction = 1
    self.node.physicsBody?.mass = 2.0
}

Constants.swift

enum CategoryMask: UInt32 {
    case ball = 0b01 // 1
    case plane = 0b11 // 2
}

Я ожидаю, что physicsWorld позвонят, когда самолет и мяч столкнутся, но этого не происходит.Любое понимание очень ценится.

...