How do i return the radius of a sphere geometry(SCNSphere) used to set up a SCNNode. I want to use the radius in a method where i move some child nodes in relation to a parent node. The code below fails since radius appears to be unknown to the resulting node, should i not pass the node to the method?
Also my array index fails saying that Int is not a Range.
I am trying to build something from this
import UIKit
import SceneKit
class PrimitivesScene: SCNScene {
override init() {
super.init()
self.addSpheres();
}
func addSpheres() {
let sphereGeometry = SCNSphere(radius: 1.0)
sphereGeometry.firstMaterial?.diffuse.contents = UIColor.redColor()
let sphereNode = SCNNode(geometry: sphereGeometry)
self.rootNode.addChildNode(sphereNode)
let secondSphereGeometry = SCNSphere(radius: 0.5)
secondSphereGeometry.firstMaterial?.diffuse.contents = UIColor.greenColor()
let secondSphereNode = SCNNode(geometry: secondSphereGeometry)
secondSphereNode.position = SCNVector3(x: 0, y: 1.25, z: 0.0)
self.rootNode.addChildNode(secondSphereNode)
self.attachChildrenWithAngle(sphereNode, children:[secondSphereNode, sphereNode], angle:20)
}
func attachChildrenWithAngle(parent: SCNNode, children:[SCNNode], angle:Int) {
let parentRadius = parent.geometry.radius //This fails cause geometry does not know radius.
for var index = 0; index < 3; ++index{
children[index].position=SCNVector3(x:Float(index),y:parentRadius+children[index].radius/2, z:0);// fails saying int is not convertible to range.
}
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
The issue with radius
is that parent.geometry
returns a SCNGeometry
and not an SCNSphere
. If you need to get the radius
, you'll need to cast parent.geometry
to SCNSphere
first. To be safe, it's probably best to use some optional binding and chaining to do that:
if let parentRadius = (parent.geometry as? SCNSphere)?.radius {
// use parentRadius here
}
You'll also need to do that when accessing the radius
on your children
nodes. If you put all that together and clean things up a little, you get something like this:
func attachChildrenWithAngle(parent: SCNNode, children:[SCNNode], angle:Int) {
if let parentRadius = (parent.geometry as? SCNSphere)?.radius {
for var index = 0; index < 3; ++index{
let child = children[index]
if let childRadius = (child.geometry as? SCNSphere)?.radius {
let radius = parentRadius + childRadius / 2.0
child.position = SCNVector3(x:CGFloat(index), y:radius, z:0.0);
}
}
}
}
Note though that you're calling attachChildrenWithAngle
with an array of 2 children:
self.attachChildrenWithAngle(sphereNode, children:[secondSphereNode, sphereNode], angle:20)
If you do that, you're going to get a runtime crash in that for
loop when accessing the 3rd element. You'll either need to pass an array with 3 children every time you call that function, or change the logic in that for
loop.