SceneKit Rotation Using Quaternions

Viewed 294

I have developed a scene that displays a rotating sphere. I have been using the SCNAction.rotate() method which uses simple angles to rotate with. However, in order to use the new sceneView.snapshot() method, I need to rotate the sphere without an animation method which would require the use of the sphereNode.rotate() method instead. This method requires a SCNQuaternion and an SCNVector 3.

In my old code, I used the following for the rotation

sphereNode.rotation = SCNVector4(x: 0.0, y: 1.0, z: 0.0, w: 0.0)
sphereNode.runAction(SCNAction.rotate(by: 1.1*CGFloat(Double.pi), around: SCNVector3(x: 0.0, y: 1.0, z: 0.0), duration: 0.0))

Now I must use

sphereNode.rotate(by: SCNQuaternion, aroundTarget: SCNVector3)

I should add that I am open to other alternatives to rotating the sphere upon setup without an animation. The rotate() function is the only one I have found so far that will rotate the sphere before the image is captured.

How can I achieve the same rotation as before using this method? Below is my full code

var sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))


extension SCNMaterial {
    convenience init(color: UIColor) {
        self.init()
        diffuse.contents = color
    }
    convenience init(image: UIImage) {
        self.init()
        diffuse.contents = image
    }
}

func addBloom() -> [CIFilter]? {
    let bloomFilter = CIFilter(name:"CIBloom")!
    bloomFilter.setValue(0.2, forKey: "inputIntensity")
    bloomFilter.setValue(35, forKey: "inputRadius")

    return [bloomFilter]
}


func sceneSetup(completion: () -> ()) {
    let scene = SCNScene()
    sceneView.backgroundColor = UIColor(red: 0.09, green: 0.09, blue: 0.09, alpha: 1.00)
        
    let sphere = SCNSphere(radius: 1)
    sphere.segmentCount = 100
    let mat = SCNMaterial(image: UIImage(named: "desaturated.png")!)
    sphere.materials = [mat]
    sphere.firstMaterial?.diffuse.wrapS = SCNWrapMode.clamp
    sphere.firstMaterial?.diffuse.wrapT = SCNWrapMode.clamp
    let sphereNode = SCNNode(geometry: sphere)
    sphereNode.filters = addBloom()
    scene.rootNode.addChildNode(sphereNode)
    
    sceneView.scene = scene
    
    let ambientLightNode = SCNNode()
    ambientLightNode.light = SCNLight()
    ambientLightNode.light!.type = SCNLight.LightType.ambient
    ambientLightNode.light!.color = UIColor(white: 0.8, alpha: 1.0)
    scene.rootNode.addChildNode(ambientLightNode)
    
    let omniLightNode = SCNNode()
    omniLightNode.light = SCNLight()
    omniLightNode.light!.type = SCNLight.LightType.omni
    omniLightNode.light!.color = UIColor(white: 0.99, alpha: 1.0)
    omniLightNode.position = SCNVector3Make(0, 0, 50)
    scene.rootNode.addChildNode(omniLightNode)
    
    sphereNode.rotation = SCNVector4(x: 0.0, y: 1.0, z: 0.0, w: 0.0)
    
    sphereNode.runAction(SCNAction.rotate(by: 1.1*CGFloat(Double.pi), around: SCNVector3(x: 0.0, y: 1.0, z: 0.0), duration: 0.0))
     
    completion()    
}

This code resulted in this output (keep in mind the mapped texture is a half gradient / half transparent image which gives the sphere this effect)

enter image description here

0 Answers
Related