I have 2 SCNSphere and I want to "link" them with a SCNCylinder (something like this O<->O) but I cannot achieve it I tried using SCNNode pivot property applying rotations, the lookAt(_:) but none of them allow me to achieve what I want.
As a constraint, I want the cylinder to be child of the first sphere for architecture reasons.
Let's say we have a trivial case, first and second sphere have a radius of 0.1 and no rotation is applied to them, only the position is relevant :
static func createSphere(position: SCNVector3, color: UIColor = .red) -> SCNNode {
let shape = SCNSphere(radius: 0.1)
shape.firstMaterial?.diffuse.contents = color
let node = SCNNode(geometry: shape)
node.position = position
return node
}
And to create the "link node" :
static func createCylinder(position: SCNVector3, color: UIColor = .green) -> SCNNode {
let shape = SCNCylinder(radius: 0.2, height: 1.0)
shape.firstMaterial?.diffuse.contents = color
let node = SCNNode(geometry: shape)
node.position = position
return node
}
All being used like this :
/// Create a sphere and the related link if there is a next sphere
static func createPOI(position: SCNVector3, nextPosition: SCNVector3? = nil) -> SCNNode {
var node: SCNNode = createSphere(position: position, color: .black)
if let nextPosition = nextPosition {
let lineNode = createLine(position: SCNVector3.zero, targetPosition: nextPosition)
node.addChildNode(lineNode)
}
return node
}
static func createLine(position: SCNVector3, targetPosition: SCNVector3) -> SCNNode {
let node = createCylinder(position: position)
//step 1: handle rotation
node.position = position
//node.look(at: targetPosition)
node.eulerAngles.x = Float.pi/2
node.eulerAngles.y = atan2f(targetPosition.y, targetPosition.magnitude)
//step 2: handle scaling and positioning
node.pivot = SCNMatrix4MakeTranslation(-0.5, 0, 0)
let width = CGFloat((targetPosition - position).magnitude)
(node.geometry as? SCNCylinder)?.height = width
//TODO: Cylinder should link source and target nodes
//Tried a lot of things above but didn't manage to do it
return node
}