1

I am trying to add simple 3D objects to sceneView. Adding object to the view is rather straightforward and went smoothly. However when I tried to add body for collision purposes (boxNode.physicsBody = boxBody), the cube completely disappeared and I cannot find the cube anymore.

Did I miss something? I have attached my code below. Rest of the project is generated by the project setting selecting "AR app"

import UIKit
import SceneKit
import ARKit

class ViewController: UIViewController, ARSCNViewDelegate, ARCoachingOverlayViewDelegate {

    @IBOutlet var sceneView: ARSCNView!
    
    let coachingOverlay = ARCoachingOverlayView()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Set the view's delegate
        sceneView.delegate = self
        
        // Show statistics such as fps and timing information
        sceneView.showsStatistics = true
        
        
        let box = SCNBox(width: 0.05, height: 0.05, length: 0.05, chamferRadius: 0)
        let boxNode = SCNNode(geometry: box)
        let boxBody = SCNPhysicsBody(type: .dynamic, shape: nil)

        box.firstMaterial?.diffuse.contents = UIColor.red
        boxNode.position = SCNVector3(0.1,0,0)
//        boxBody.mass = 1
////        boxBody.categoryBitMask = CollisionBitmask.box.rawValue
        boxNode.physicsBody = boxBody
//        boxNode.rotation = SCNVector4Make(1, 1, 1, 1)
//        boxNode.name = "box"
        sceneView.scene.rootNode.addChildNode(boxNode)
        let scene = SCNScene()
        sceneView.scene = scene
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        // Create a session configuration
        let configuration = ARWorldTrackingConfiguration()

        // Run the view's session
        sceneView.session.run(configuration)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        // Pause the view's session
        sceneView.session.pause()
    }

    // MARK: - ARSCNViewDelegate
    
/*
    // Override to create and configure nodes for anchors added to the view's session.
    func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
        let node = SCNNode()
     
        return node
    }
*/
    
    func session(_ session: ARSession, didFailWithError error: Error) {
        // Present an error message to the user
        
    }
    
    func sessionWasInterrupted(_ session: ARSession) {
        // Inform the user that the session has been interrupted, for example, by presenting an overlay
        
    }
    
    func sessionInterruptionEnded(_ session: ARSession) {
        // Reset tracking and/or remove existing anchors if consistent tracking is required
        
    }
    
}
Pranav Kasetti
  • 8,770
  • 2
  • 50
  • 71
tonywang
  • 181
  • 2
  • 13

2 Answers2

2

Use isAffectedByGravity instance property to get rid of object's gravity:

var isAffectedByGravity: Bool { get set }

You need false value (by default it's true):

let sphere = SCNSphere(radius: 1)
let node = SCNNode(geometry: sphere)
let physicsBody = SCNPhysicsBody(type: .dynamic, shape: nil)

node.physicsBody = physicsBody
physicsBody.isAffectedByGravity = false
sceneView.scene.rootNode.addChildNode(node)
Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
1

Your object will likely just fall indefinitely, unless there's an SCNFloor or something below it with the mode of kinematic.

Try adding something to log the location of your SCNNode, on a tap or every second and you'll see where it is at that moment; it likely has a very negative y coordinate.

maxxfrazer
  • 1,173
  • 6
  • 15