ARKit:两个对象不相互接触,但调用了didBegin()函数

时间:2018-01-13 16:22:53

标签: objective-c 3d arkit

在场景中,两个3d对象没有相互接触,但调用了函数func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {}

我使用addItem()在场景中添加节点

func addItem(hitTestResult: ARHitTestResult) {
        if let selectedItem = self.selectedItem {
            let scene = SCNScene(named: "art.scnassets/\(selectedItem).scn")
            let node = (scene?.rootNode.childNode(withName: selectedItem, recursively: false))!

            let transform = hitTestResult.worldTransform
            let thirdColumn = transform.columns.3
            node.position = SCNVector3(thirdColumn.x, thirdColumn.y, thirdColumn.z)


             node.physicsBody = SCNPhysicsBody(type:.dynamic, shape: SCNPhysicsShape(node: node, options: nil))


            node.physicsBody?.isAffectedByGravity = false


            node.physicsBody?.categoryBitMask = BitMaskCategory(rawValue: selectedItem)!.maskValue


            node.physicsBody?.contactTestBitMask = BitMaskCategory.mug.maskValue


            self.sceneView.scene.rootNode.addChildNode(node)
        }
    }


enum BitMaskCategory: String {

    case mug, banana, cup, vase

    var maskValue : Int {
        switch self {
        case .mug: return 1
        case .banana: return 2
        case .cup: return 3
        case .vase: return 4

        }
    }
}

当我点击屏幕并在场景中添加两个节点(杯子和杯子)时,这两个节点开始彼此远离。他们互相排斥,即使他们没有相互接触。

感谢。

1 个答案:

答案 0 :(得分:1)

调试碰撞的最佳方法&物理联系人的使用方法是:

 sceneView.debugOptions = .showPhysicsShapes

在上面的代码中,您为物理形状选择了nil:

 node.physicsBody = SCNPhysicsBody(type:.dynamic, shape: SCNPhysicsShape(node: node, options: nil))

此选项允许scenekit近似形状...当使用在第三方3d建模软件中创建的导入dae模型时,通常效果不佳。

我通常将基本的原始物理形状(如球体或框)应用于复杂的dae模型,而不是使用nil选项。

额外理解

如果你的模型有凹形部分,比如说管......它不需要是动态的。您可以使用以下代码确保管道允许物体穿过内管段。

tubeNode.physicsBody = SCNPhysicsBody(type: .static, shape: SCNPhysicsShape(geometry: geometry, options: [SCNPhysicsShape.Option.type: SCNPhysicsShape.ShapeType.concavePolyhedron]))

这是结果......因为你可以看到绿线代表physicsBody。像球这样的物体现在可以穿过管子的中心。

enter image description here

如果对象需要动态,凹面不可用...下面的代码可以在动态主体上将选项设置为convexHull。

 tubeNode.physicsBody = SCNPhysicsBody(type: .dynamic, shape: SCNPhysicsShape(geometry: geometry, options: [SCNPhysicsShape.Option.type: SCNPhysicsShape.ShapeType.convexHull]))

enter image description here

因此,落在上方的球将位于管的顶部而不会通过管的中心。