Last active
September 19, 2021 03:56
-
-
Save kemalenver/79523e5606f62c5958fcf5e9bedc48a5 to your computer and use it in GitHub Desktop.
An SCNNode that draws a circle of given detail
This file contains 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
import Foundation | |
import SceneKit | |
class CircleNode: SCNNode { | |
init(detail: Int = 500) { | |
super.init() | |
let elements = self.generateElements(detail: detail) | |
let circleSources = self.generateCircleGeometrySources(detail: detail) | |
let materials = self.generateMaterials() | |
let circleGeometry = SCNGeometry(sources: circleSources, elements: elements) | |
self.geometry = circleGeometry | |
self.geometry?.materials = materials | |
} | |
required init?(coder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
private func generateMaterials() -> [SCNMaterial] { | |
let material = SCNMaterial() | |
material.isDoubleSided = true | |
material.lightingModel = .constant | |
material.blendMode = .add | |
material.diffuse.contents = UIImage(named: "art.scnassets/orbit_gradient.png") | |
return [material] | |
} | |
private func generateElements(detail: Int) -> [SCNGeometryElement] { | |
var indices: [Int32] = [] | |
for i in 0..<detail-1 { | |
indices.append(Int32(i)) | |
indices.append(Int32(i+1)) | |
} | |
return [SCNGeometryElement(indices: indices, primitiveType: .line)] | |
} | |
private func generateCircleGeometrySources(detail: Int) -> [SCNGeometrySource] { | |
var verticesVectors = [SCNVector3]() | |
var textureCoordsPoints = [CGPoint]() | |
for i in 0..<detail { | |
let per = Float(i) / Float(detail-1) | |
let angle = per * (Float.pi * 2) | |
let vertice = SCNVector3(cos(angle), sin(angle), 0) | |
let texture = CGPoint(x: Double(per), y: 0.5) | |
verticesVectors.append(vertice) | |
textureCoordsPoints.append(texture) | |
} | |
let vertices = SCNGeometrySource(vertices: verticesVectors) | |
let textureCoords = SCNGeometrySource(textureCoordinates: textureCoordsPoints) | |
return [vertices, textureCoords] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@screenworker - this is deliberately generating a circle using
primitiveType: .line
So it will always be a circle wireframe (which is what I needed). If you want something 'thicker' in a 3D scene then you need to use a geometry that makes sense, a cylinder, or a disk? In the code above where it generates the circle, you could generate points to make a disk instead, and change the primitive type to .triangle.