Panoramas in Swift Playgrounds

Panoramas in Swift Playgrounds

IMG_0631.jpg

Over the Black Friday sales I bought myself the 360Fly HD Camera to start experimenting with creating my own Virtual Reality content. One of my students asked if it would be possible to embed 360 degree photos into Swift Playgrounds.

I took a picture of my un-kept background (don’t judge holidays haven’t started yet!) and I researched how I could use a panoramic image as a texture.

Using SceneKit and CoreMotion (which are used for creating 3D scenes and ARKit Apps) I created a Sphere and placed it within the Scene. Once I had the Sphere I applied the Texture to both the inside and outside of the surfaces and then used the camera to place the user inside the middle of the Sphere. It’s not a perfect solution, but it serves its purpose. Some possible extensions to this Playground could include using the gyroscope sensor to control the movement (rather than gestures). This would make it feel more like Virtual Reality.

Swift_Playgrounds_Panorama_Daniel_Budd.jpeg

I have posted the code below, but it is also available through the Swift Teacher’s subscription and GitHub.


import PlaygroundSupport
import UIKit
import SceneKit
import CoreMotion

class ViewController: UIViewController{
    
    let motionManager = CMMotionManager()
    let cameraNode = SCNNode()
    let sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: 800, height: 600))
    let scene = SCNScene()
    
    override func viewDidLoad(){
        super.viewDidLoad()
        
        view.frame = CGRect(x: 0, y: -200, width: 800, height: 1200)
        view.backgroundColor = .black
        
        sceneView.backgroundColor = .clear
        sceneView.scene = scene
        sceneView.center = view.center
        sceneView.allowsCameraControl = true
        sceneView.autoenablesDefaultLighting = true
        sceneView.showsStatistics = true
        
        view.addSubview(sceneView)
        
        //Create a node containing a sphere, using the panoramic image as a texture
        let sphere = SCNSphere(radius: 60.0)
        
        sphere.firstMaterial!.isDoubleSided = true
        
        let image = #imageLiteral(resourceName: "IMG_0690.JPG")
        sphere.firstMaterial!.diffuse.contents = image
        
        let sphereNode = SCNNode(geometry: sphere)
        sphereNode.position = SCNVector3Make(0,0,0)
        scene.rootNode.addChildNode(sphereNode)
        
        //Create a camera node which will be the view of the user
        cameraNode.camera = SCNCamera()
        cameraNode.position = SCNVector3Make(5,-10,20) //adjust to fit your image
        scene.rootNode.addChildNode(cameraNode)
    }
}
PlaygroundPage.current.liveView = ViewController()
Coding Club Cheatsheets for Swift

Coding Club Cheatsheets for Swift

Pulling live data from USGS to Swift Playgrounds

Pulling live data from USGS to Swift Playgrounds