Столкновение двух узлов не обнаружено ARKit - PullRequest
0 голосов
/ 06 февраля 2019

Я создал два узла: сферу и прямоугольник:

    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?

Я хочу, чтобы два узла или физика взаимодействовали, поэтому я создал категорию для 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: Учебник 1 , Учебник 2 .Я понятия не имею, почему это не работает, как ожидалось.Что-то не так в моем коде?

Скачать код ссылки на файл: https://ufile.io/20sla

1 Ответ

0 голосов
/ 06 февраля 2019

willRenderScene вызывается в верхней части города 60 раз в секунду каждый раз, когда происходит рендеринг сцены.Поскольку вы воссоздаете физическое тело каждый раз, когда он, вероятно, портит физический движок, определяйте столкновения.

Попробуйте изменить код, чтобы физическое тело создавалось только один раз во время установки.

...