2017-10-21 107 views
0

J'ai 4 murs, 1 plafond, 1 plancher et un mobilier. Je traîne mes meubles dans la pièce mais il traverse des murs. J'ai essayé tout ce que je sais. Encore ne peut pas résolu le problème. La détection de contact fonctionne. Mon nœud de meuble ne reste pas sur le sol si je ne lui donne pas la propriété furniture.physicsBody! .damping = 1.0. S'il vous plaît vérifier la vidéo: https://youtu.be/1iwq7gvTzA4La physique de SceneKit ne se comporte pas comme prévu

enum ABC:Int { 
    case furni = 1 
    case wall = 4 
    case floor = 6 
} 

private func setup() { 
    // create the wall geometry 
    let wallGeometry = SCNPlane(width: 2000, height: 300) 
    wallGeometry.firstMaterial!.diffuse.contents = "Wallpaper1.png" 
    wallGeometry.firstMaterial!.isDoubleSided = false 
    wallGeometry.firstMaterial!.locksAmbientWithDiffuse = true 

    let wallWithBaseboardNode = SCNNode(geometry: wallGeometry) 
    wallWithBaseboardNode.position = SCNVector3Make(0, 150, 0) 
    wallWithBaseboardNode.physicsBody = .static() 
    wallWithBaseboardNode.physicsBody!.restitution = 1.0 
    wallWithBaseboardNode.physicsBody!.contactTestBitMask = ABC.furni.rawValue 

    //front 
    _wallNode = wallWithBaseboardNode.clone() 
    _scene.rootNode.addChildNode(_wallNode) 

    //left 
    _wallNode = wallWithBaseboardNode.clone() 
    _wallNode.position = SCNVector3Make(0, 150, 0) 
    _wallNode.rotation = SCNVector4Make(0, 1, 0, .pi/2) 
    _scene.rootNode.addChildNode(_wallNode) 

    //right 
    _wallNode = wallWithBaseboardNode.clone() 
    _wallNode.position = SCNVector3Make(roomDimensions[0], 150, 0) 
    _wallNode.rotation = SCNVector4Make(0, 1, 0, -.pi/2) 
    _scene.rootNode.addChildNode(_wallNode) 

    //back 
    _wallNode = wallWithBaseboardNode.clone() 
    _wallNode.position = SCNVector3Make(0, 150, roomDimensions[1]) 
    _wallNode.rotation = SCNVector4Make(0, 1, 0, .pi/1) 
    _scene.rootNode.addChildNode(_wallNode) 

    //ceiling 
    var ceilingNode = wallWithBaseboardNode.clone() 
    ceilingNode = wallWithBaseboardNode.copy() as! SCNNode 
    ceilingNode.geometry = (ceilingNode.geometry!.copy() as! SCNGeometry) 
    ceilingNode.geometry!.firstMaterial = SCNMaterial() 
    ceilingNode.geometry!.firstMaterial!.diffuse.contents = UIColor.white 
    ceilingNode.position = SCNVector3Make(0, Float(wallGeometry.height), 0) 
    ceilingNode.scale = SCNVector3Make(10, 10, 10) 
    ceilingNode.rotation = SCNVector4Make(1, 0, 0, .pi/2) 
    _scene.rootNode.addChildNode(ceilingNode) 

    //floor 
    let floor = SCNFloor() 
    floor.reflectionFalloffEnd = 0 
    floor.reflectivity = 0 

    _floorNode = SCNNode() 
    _floorNode.geometry = floor 
    _floorNode.geometry!.firstMaterial!.diffuse.contents = "Wood3.jpg" 
    _floorNode.geometry!.firstMaterial!.locksAmbientWithDiffuse = true 
    _floorNode.geometry!.firstMaterial!.diffuse.wrapS = .repeat 
    _floorNode.geometry!.firstMaterial!.diffuse.wrapT = .repeat 
    _floorNode.geometry!.firstMaterial!.diffuse.mipFilter = .nearest 
    _floorNode.geometry!.firstMaterial!.isDoubleSided = false 

    _floorNode.physicsBody = .static() 
    _floorNode.physicsBody!.restitution = 1.0 

    //_floorNode.physicsBody!.contactTestBitMask = ABC.furni.rawValue 

    _scene.rootNode.addChildNode(_floorNode) 
} 

Et voici le code pour mon nœud de meubles

private func addFurniture() { 
    let furnitureScene = SCNScene(named: "a.dae", inDirectory: "assets.scnassets/models/", options: nil)! 
    let furniture = furnitureScene.rootNode.childNode(withName: "a", recursively: true)! 

    furniture.physicsBody = .dynamic() 
    furniture.physicsBody!.restitution = 1.0 
    furniture.physicsBody!.damping = 1.0 

    furniture.physicsBody!.contactTestBitMask = ABC.wall.rawValue 

    _scene.rootNode.addChildNode(furniture) 

    scnView.prepare(_scene, shouldAbortBlock: nil) 

    _furniture = furniture 

    scnView.debugOptions = [.showPhysicsShapes, .showPhysicsFields] 
} 
+0

connaissez-vous la différence entre contactTestBitMask et collisionBitMask ? Si oui, quel est le but de l'assignation de contactTestBitMask à vos nœuds? –

+0

@ElTomato Non, je ne suis pas vraiment sûr. Pourriez-vous me guider pour résoudre le problème? Je suis nouveau à SceneKit. Que dois-je faire pour empêcher cela de se produire? Merci. – Mamedoff

+0

De toute façon, définissez le corps physique de la propriété affectedByGravity sur false pour les parties concernées. –

Répondre

0

Si vous souhaitez déplacer le manualy de meubles (c.-à ne pas utiliser les forces), changer le type de corps. cinématique

Lorsque vous déplacez le nœud, vous pouvez exécuter contactTest(with:options:) qui vous renverra une liste de contacts si vous frappez les murs. Dans le renderer(_:willRenderScene:atTime:), vous pouvez ensuite fixer la position du mobilier pour «fixer» le décalage de la pénétration du mur contre le mur.

Vous pouvez voir ma solution d'un problème similaire ici: https://stackoverflow.com/a/46915698/1389597

Hope this helps, j'ai passé plusieurs jours à essayer de comprendre cela :)