iosscenekitscnnodescnscene

SceneKit - adding SCNNode on another SCNNode


I'm trying to put sphere on top of the box, but the position is strange: Ball is half hidden inside box. I tried to change box and sphere pivot, but it didn't help. Here's the code:

    let cubeGeometry = SCNBox(width: 10, height: 10, length: 10, 
    chamferRadius: 0)
    let cubeNode = SCNNode(geometry: cubeGeometry)
    //cubeNode.pivot = SCNMatrix4MakeTranslation(0, 1, 0)
    scene.rootNode.addChildNode(cubeNode)

    let ballGeometry = SCNSphere(radius: 1)
    let ballNode = SCNNode(geometry: ballGeometry)
    ballNode.pivot = SCNMatrix4MakeTranslation(0.5, 0, 0.5)
    ballNode.position = SCNVector3Make(0, 5, 0)
    cubeNode.addChildNode(ballNode)`

and the result: enter image description here

what I'm doing wrong? How to put the ball right on the top side of the box?

UPDATE: If I add Cube instead of ball, it looks good as I want


Solution

  • You need to translate on the Y-axis by cube-height/2 + sphere-radius. Thus you should have:

    ballNode.position = SCNVector3Make(0, 6, 0)
    

    Here is the screenshot:

    Ball on top of the cube

    The relevant complete code:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        // create a new scene
        let scene = SCNScene()
    
        let cubeGeometry = SCNBox(width: 10, height: 10, length: 10,
                                  chamferRadius: 0)
        cubeGeometry.firstMaterial?.diffuse.contents = UIColor.yellow
        let cubeNode = SCNNode(geometry: cubeGeometry)
        scene.rootNode.addChildNode(cubeNode)
    
        let ballGeometry = SCNSphere(radius: 1)
        ballGeometry.firstMaterial?.diffuse.contents = UIColor.green
        let ballNode = SCNNode(geometry: ballGeometry)
        ballNode.position = SCNVector3Make(0, 6, 0)
        cubeNode.addChildNode(ballNode)
    
        // retrieve the SCNView
        let scnView = self.view as! SCNView
    
        // set the scene to the view
        scnView.scene = scene
    
        // allows the user to manipulate the camera
        scnView.allowsCameraControl = true
    
        // show statistics such as fps and timing information
        scnView.showsStatistics = true
    
        // configure the view
        scnView.backgroundColor = UIColor.gray
    }
    

    Update : Why radius and not radius / 2

    See this screenshot from the Scene Editor in Xcode. The original position of cube is (0, 0, 0) and so is that of the ball; hence the ball needs to be moved by r and not r / 2; with r / 2 the lower section of the ball with height r/2 will be still inside the cube. You can just add a cube and sphere as in the scene below in the editor and that should help clarify.

    Why r and not r / 2