Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I've two objects in one SceneKit. One is the Earth and the other is the Moon. Both of them are positioned at x:0, y:0, z:0 and are overlapping. How should I change the coordinates of the Moon so it's around the Earth?

Here the code:

import UIKit
import SceneKit
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let scene = SCNScene()
        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        cameraNode.position = SCNVector3(x:0, y:0, z:10)
        scene.rootNode.addChildNode(cameraNode)
        let lightNode = SCNNode()
        lightNode.light = SCNLight()
        lightNode.light?.type = .directional
        lightNode.position = SCNVector3(x:0, y:0, z:2)
        scene.rootNode.addChildNode(lightNode)
        let stars = SCNParticleSystem(named: "StarsParticles.scnp", inDirectory: nil)!
        scene.rootNode.addParticleSystem(stars)
        let moonNode = MoonNode()
        scene.rootNode.addChildNode(moonNode)
        let sceneview = self.view as! SCNView
        sceneview.scene = scene
        let earthNode = EarthNode()
        scene.rootNode.addChildNode(earthNode)
        let sceneView = self.view as! SCNView
        sceneView.scene = scene
        sceneView.showsStatistics = false
        sceneView.backgroundColor = UIColor.black
        sceneView.allowsCameraControl = true
    override var prefersStatusBarHidden: Bool {
        return true 

You could make your view controller a SCNSceneRendererDelegate, and implement the delegate method renderer:willRenderScene which gives you a time. Based on that time, you can set something like this:

moonNode.position = SCNVector3(r * cos(Float(time), r * sin(Float(time)), 0)

where r is the radius of your Earth node - if you don't know this at compile time, just include something like this above that line:

let r = length(float3(earthNode.boundingBox.max) - float3(earthNode.boundingBox.min))

this won't quite be exact for the code I included which causes a rotation in the xy plane but it will at least give you the right order of magnitude for r. If you get an error that it can't find float3 or length, try and import simd.

Let me know if you have any issues with this, as I typed this up from memory.

More info in documentation: https://developer.apple.com/documentation/scenekit/scnscenerendererdelegate/1523483-renderer

You can easily do it using simdPivot instance property.

var simdPivot: simd_float4x4 { get set }

Here's a code for testing:

import SceneKit
class GameViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let scene = SCNScene()
        let action = SCNAction.repeatForever(SCNAction.rotate(by: .pi, 
                                                          around: SCNVector3(0,1,0), 
                                                        duration: 1))
        let earthNode = SCNNode(geometry: SCNSphere(radius: 3.57))
        earthNode.geometry?.materials.first?.diffuse.contents = UIColor.blue
        scene.rootNode.addChildNode(earthNode)
        let moonNode = SCNNode(geometry: SCNSphere(radius: 0.15))
        moonNode.geometry?.materials.first?.diffuse.contents = UIColor.yellow
        moonNode.simdPivot.columns.3.x = 5
        moonNode.runAction(action)
        scene.rootNode.addChildNode(moonNode)
        let sceneView = self.view as! SCNView
        sceneView.scene = scene
        sceneView.backgroundColor = UIColor.black
        sceneView.allowsCameraControl = true
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.