Created
October 27, 2019 14:52
-
-
Save dirkolbrich/9e4dffb3026d0540d6edf6877f27d1e4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A SceneKit based Playground to test camera position and movement | |
// using a camera orbit | |
import SceneKit | |
import PlaygroundSupport | |
// setup view | |
var sceneView = SCNView(frame: CGRect(x:0 , y:0, width: 480, height: 640)) | |
var scene = SCNScene() | |
sceneView.scene = scene | |
sceneView.backgroundColor = UIColor.white | |
sceneView.autoenablesDefaultLighting = true | |
// sceneView.allowsCameraControl = true | |
sceneView.showsStatistics = true | |
// present | |
PlaygroundPage.current.liveView = sceneView | |
// add camera to the scene | |
let camera = SCNCamera() | |
camera.automaticallyAdjustsZRange = true | |
let cameraNode = SCNNode() | |
cameraNode.camera = camera | |
cameraNode.name = "camera" | |
cameraNode.position = SCNVector3(x: 0, y: 0, z: 20) | |
let cameraOrbit = SCNNode() | |
scene.rootNode.addChildNode(cameraOrbit) | |
cameraOrbit.addChildNode(cameraNode) | |
// MARK: - Spheres | |
func addSphere(x: Float, y: Float, z: Float, radius: Float, color: UIColor = UIColor.gray) { | |
let material = SCNMaterial() | |
material.diffuse.contents = color | |
let sphereGeometry = SCNSphere(radius: CGFloat(radius)) | |
sphereGeometry.firstMaterial = material | |
let sphereNode = SCNNode(geometry: sphereGeometry) | |
sphereNode.name = "dot" | |
sphereNode.position = SCNVector3(x: x, y: y, z: z) | |
scene.rootNode.addChildNode(sphereNode) | |
} | |
let spacing: Float = 2.0 | |
let radius: Float = 1.0 | |
addSphere( | |
x: 0.0, | |
y: 0.0, | |
z: 0.0, | |
radius: radius) | |
addSphere( | |
x: -2.0 * spacing, | |
y: -2.0 * spacing, | |
z: 0.0, | |
radius: radius) | |
addSphere( | |
x: 2.0 * spacing, | |
y: 2.0 * spacing, | |
z: 0.0, | |
radius: radius) | |
addSphere( | |
x: -2.0 * spacing, | |
y: 2.0 * spacing, | |
z: 0.0, | |
radius: radius) | |
addSphere( | |
x: 2.0 * spacing, | |
y: -2.0 * spacing, | |
z: 0.0, | |
radius: radius) | |
addSphere( | |
x: 0.0, | |
y: -2.0 * spacing, | |
z: -2.0 * spacing, | |
radius: radius) | |
addSphere( | |
x: 0.0, | |
y: 2.0 * spacing, | |
z: 2.0 * spacing, | |
radius: radius) | |
addSphere( | |
x: 0.0, | |
y: 2.0 * spacing, | |
z: -2.0 * spacing, | |
radius: radius) | |
addSphere( | |
x: 0.0, | |
y: -2.0 * spacing, | |
z: 2.0 * spacing, | |
radius: radius) | |
// sphere off center from square | |
addSphere( | |
x: 6.0, | |
y: 6.0, | |
z: 6.0, | |
radius: radius) | |
// MARK: - Coordinate Symbol | |
let coordinates = SCNNode() | |
scene.rootNode.addChildNode(coordinates) | |
let coordVertices: [SCNVector3] = [ | |
SCNVector3(0, 0, 0), | |
SCNVector3(5, 0, 0), | |
SCNVector3(0, 0, 5), | |
SCNVector3(-5, 0, 0), | |
SCNVector3(0, 0, -5), | |
SCNVector3(0, 5, 0) | |
] | |
let coordColors: [String: UIColor] = [ | |
"red": UIColor.red, | |
"blue": UIColor.blue, | |
"green": UIColor.green, | |
] | |
var materials: [String : SCNMaterial] { | |
var mat = [String : SCNMaterial]() | |
for (key, value) in coordColors { | |
let material = SCNMaterial() | |
material.lightingModel = SCNMaterial.LightingModel.constant | |
material.isDoubleSided = true | |
material.diffuse.contents = value | |
mat[key] = material | |
} | |
return mat | |
} | |
func buildLine(vertice1: SCNVector3, Vertice2: SCNVector3, material: SCNMaterial) -> SCNNode { | |
let geometry = SCNGeometry( | |
sources: [SCNGeometrySource(vertices: [vertice1, Vertice2])], | |
elements: [SCNGeometryElement(indices: [Int32]([0,1]), primitiveType: .line)] | |
) | |
geometry.firstMaterial = material | |
return SCNNode(geometry: geometry) | |
} | |
coordinates.addChildNode(buildLine(vertice1: coordVertices[1], Vertice2: coordVertices[3], material: materials["red"]!)) | |
coordinates.addChildNode(buildLine(vertice1: coordVertices[2], Vertice2: coordVertices[4], material: materials["blue"]!)) | |
coordinates.addChildNode(buildLine(vertice1: coordVertices[0], Vertice2: coordVertices[5], material: materials["green"]!)) | |
// MARK: - Handle Gesture | |
var lastWidthRatio: Float = 0 | |
var lastHeightRatio: Float = 0 | |
extension SCNView { | |
@objc func handlePanGesture(_ sender: UIPanGestureRecognizer) { | |
let translation = sender.translation(in: sender.view) | |
let widthRatio = Float(translation.x) / Float(sender.view!.frame.size.width) + lastWidthRatio | |
let heightRatio = Float(translation.y) / Float(sender.view!.frame.size.height) + lastHeightRatio | |
cameraOrbit.eulerAngles.y = Float(-2 * Double.pi) * widthRatio | |
cameraOrbit.eulerAngles.x = Float(-Double.pi) * heightRatio | |
if (sender.state == .ended) { | |
lastWidthRatio = widthRatio.truncatingRemainder(dividingBy: 1) | |
lastHeightRatio = heightRatio.truncatingRemainder(dividingBy: 1) | |
} | |
} | |
} | |
// add a tap gesture recognizer | |
let gesture = UIPanGestureRecognizer( | |
target: sceneView, | |
action: #selector(sceneView.handlePanGesture(_:)) as Selector | |
) | |
sceneView.addGestureRecognizer(gesture) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment