SceneKit - positioning SCNCamera and permitting object rotation

704 Views Asked by At

I am close to completing my first project in SceneKit but I'm struggling with the last few steps. It is probably easiest to explain my progress by sharing a short screen capture video of the Xcode Simulator displaying my current scene.

As you can see by the screen capture my project is composed of three elements (this is all done in code, I do not import any external assets):

  1. outside box (defined via six SCNBox objects per corner)
  2. inside sun (defined via a SCNTube object for the circle and UIBezierPath objects per "ray")
  3. position of camera

Based on feedback I have committed the code to GitHub.

Right now the camera is allowed to rotate as seen in the screen capture but the centre of rotation of the camera and of the objects doesn't align so it appears to spin off-axis.

Here's where I want to get to:

  1. correct camera position so that the combined box & sun is positioned directly in front of the camera, filling the screen
  2. maintain the sun's position as being fixed (already done I guess)
  3. allow the box to rotate freely in x, y & z around the sun based on touch input - so the user can "flick" the box and watch it flip and spin around the sun

The code structure is straight forward:

class GameViewController: UIViewController {

var gameView: SCNView!
var gameScene: SCNScene!
var cameraNode: SCNNode!
var targetCreationTime: TimeInterval = 0

override func viewDidLoad() {
    super.viewDidLoad()
    initView()
    initScene()   // createSun() and createCube() called here
    initCamera()
}

And with respect to the camera position:

   func initCamera() {
        let camera = SCNCamera()
        cameraNode = SCNNode()
        cameraNode.camera = camera
        cameraNode.position = SCNVector3(x: 0, y: 0, z: 0)
        cameraNode.rotation = SCNVector4Make(1, 0, 0, .pi/2)
    }

But what I've found is that despite playing around with the random cameraNode.position and cameraNode.rotation values the camera view doesn't seem to change.

My questions - any help will be greatly appreciated:

  1. advice on repositioning the camera (what am I doing wrong?!) - once it's in the right place I can easily set "gameView.allowsCameraControl = false"
  2. advice on how to enable the box to spin about its axis around the sun (while the sun remains fixed)
  3. stretch goal! Any kind of general "check out this tutorial" type info on materials and lighting, and embedding this view into a SwiftUI view

Thanks!

2

There are 2 best solutions below

1
On

Use this answer in post for your camera: 57586437, remove camera rotation and take camera control off. Rotate your box with a simple (I'd do an x,y,z independent spin just to verify it) spin so that you'll know if your pivot point is correct. It should be ok by default and spin in place right in front of the camera, but depends on how you built your cube.

If you added the sun and stuff as a subnode of your box, then you're probably in decent shape and the pieces will rotate together.

If you want to do camera rotations similar to cameraControl, then you'll need to add a gesture recognizer and then you can start experimenting with it.

Hope that helps!

0
On

I decided to stop fighting the point of rotation and instead reposition the elements around this.

One interesting thing, which I’ve mentioned at the start of the createBox() func.

// originally debugCube & debugNode were used for debugging the pivot point of the box
// but I found have this large node helped to balance out the centre of mass
// set to fully transparent and added to boxNode as final step after all other transformations

If you comment out the lines 19-26 plus 117 you will completely remove debugNode. And funnily enough when you do that the box stops spinning correctly. But you add it back in and everything is fixed. I’m guessing it’s adding “mass” to the overall node and helping lock the point of rotation to the correct position. So in the end I just made it transparent!

The final (version 1.0) code is posted on GitHub at github.com/LedenMcLeden/logo