在场景中,两个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
}
}
}
当我点击屏幕并在场景中添加两个节点(杯子和杯子)时,这两个节点开始彼此远离。他们互相排斥,即使他们没有相互接触。
感谢。
答案 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。像球这样的物体现在可以穿过管子的中心。
如果对象需要动态,凹面不可用...下面的代码可以在动态主体上将选项设置为convexHull。
tubeNode.physicsBody = SCNPhysicsBody(type: .dynamic, shape: SCNPhysicsShape(geometry: geometry, options: [SCNPhysicsShape.Option.type: SCNPhysicsShape.ShapeType.convexHull]))
因此,落在上方的球将位于管的顶部而不会通过管的中心。