Skip to content

Instantly share code, notes, and snippets.

@heckj
Created April 20, 2019 22:29
Show Gist options
  • Save heckj/5b588ad3468f3e91f70fed7734c39cf5 to your computer and use it in GitHub Desktop.
Save heckj/5b588ad3468f3e91f70fed7734c39cf5 to your computer and use it in GitHub Desktop.
A Reusable SCNNode SubClass With An SCNCone Geometry
//
// Cone.swift
//
//
// Created by Josh Robbins on 24/02/2018.
// Copyright © 2018 BlackMirror. All rights reserved.
//
import Foundation
import SceneKit
class Cone: SCNNode{
private var faceArray = [SCNMaterial]()
/// Creates An SCNCone With Either A Single Colour Or Image For It's Material
/// (Either A Colour Or UIImage Must Be Input)
/// - Parameters:
/// - extends: Bool (If extends == false The Cone Will Taper To The Top Else It Will Extend To The Top)
/// - topRadius: Optional CGFloat (Defaults To 0cm)
/// - bottomRadius: Optional CGFloat (Defaults To 30cm)
/// - height: Optional CGFloat (Defaults To 60cm)
/// - content: Any (UIColor Or UIImage)
init(extends: Bool, topRadius: CGFloat = 0, bottomRadius: CGFloat = 0.3, height: CGFloat = 0.6, content: Any) {
super.init()
//1. Declare A Variable So We Can Extend Or Taper The Cone
var adjustedTopRadius = topRadius
var adjustedBottomRadius = bottomRadius
//2. If The Cone Needs To Extend To The Top Invert The Initial Values
if extends{
adjustedTopRadius = bottomRadius
adjustedBottomRadius = topRadius
}
//3. Create The Cone Geometry With Our TopRadius, BottomRadius & Height Paramaters
self.geometry = SCNCone(topRadius: adjustedTopRadius, bottomRadius: adjustedBottomRadius, height: height)
let material = SCNMaterial()
//4. Set The Material Contents
if let colour = content as? UIColor{
//The Material Will Be A UIColor
material.diffuse.contents = colour
}else if let image = content as? UIImage{
//The Material Will Be A UIImage
material.diffuse.contents = image
}else{
//Set Our Material Colour To Cyan
material.diffuse.contents = UIColor.cyan
}
//4. Set The Material Of The Cone
self.geometry?.firstMaterial = material
}
/// Creates An SCNCone With Either A Colour Or UIImage For It's Base & Body
/// (Either An Array [UIColour] Or [UIImage] Must Be Input)
/// - Parameters:
/// - extends: Bool (If extends == false The Cone Will Taper To The Top Else It Will Extend To The Top)
/// - topRadius: Optional CGFloat (Defaults To 0cm)
/// - bottomRadius: Optional CGFloat (Defaults To 30cm)
/// - contents: [Any] - [Base, Body]
init(extends: Bool, topRadius: CGFloat = 0, bottomRadius: CGFloat = 0.3, height: CGFloat = 0.6, contents: [Any]) {
super.init()
//1. Declare A Variable So We Can Extend Or Taper The Cone
var adjustedTopRadius = topRadius
var adjustedBottomRadius = bottomRadius
//2. If The Cone Needs To Extend To The Top Invert The Initial Values
if extends{
adjustedTopRadius = bottomRadius
adjustedBottomRadius = topRadius
}
//3. Create The Cone Geometry With Our TopRadius, BottomRadius & Height Paramaters
self.geometry = SCNCone(topRadius: adjustedTopRadius, bottomRadius: adjustedBottomRadius, height: height)
//4. Create A Temporary Array To Store Either Our UIColors Or UIImages
var sideArray = [Any]()
//5. Assign The Colours Or UIImages
if let colours = contents as? [UIColor], colours.count == 2{
//The Materials Will Be A UIColor
sideArray = colours
}else if let images = contents as? [UIImage], images.count == 2{
//The Materials Will Be A UIImage
sideArray = images
}else{
//Set Our Material Colours To Cyan, Red
sideArray = [UIColor.cyan, UIColor.red]
}
//6. Loop Through The Number Of Faces & Create A New Material For Each
for index in 0 ..< 2{
let face = SCNMaterial()
face.diffuse.contents = sideArray[index]
//Add The Material To Our Face Array
faceArray.append(face)
}
//7. Set The Cones Materials From Our Face Array
self.geometry?.materials = faceArray
}
required init?(coder aDecoder: NSCoder) { fatalError("Cone Node Coder Not Implemented") }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment