У меня есть SCNView с allowCameraControl = true.
Я установил SKScene в качестве наложения на SCNView.
Я создал UCS (пользовательскую систему координат) Значок в виде SK3Node.
Я бы хотел, чтобы значок UCS вращался в ответ на повороты в SCNView. В основном отображают ориентацию системы координат SCNView.
Меня также беспокоит то, что значок ПСК вращается вокруг своего центра и остается того же размера, что и при вращении.
Как подключиться вращение SK3Node к вращению в основной сцене? Как сохранить вращение UCSIcon вокруг пересечения 3 стрелок? Есть ли лучший способ сделать это?
override func viewDidLoad() {
super.viewDidLoad()
let scene = SCNScene()
scnView.scene = scene
scnView.allowsCameraControl = true
scnView.backgroundColor = .windowBackgroundColor
let overlay = SKScene(size: scnView.bounds.size)
overlay.scaleMode = .resizeFill
overlay.isUserInteractionEnabled = false
let ucsIcon = UCSIcon()
let node = ucsIcon.getIconNode()
node.position = .init(x: view.bounds.width * 0.5, y: view.bounds.height * 0.5)
overlay.addChild(node)
scnView.overlaySKScene = overlay
}
struct UCSIcon {
var xAxisColor: NSColor = .red
var yAxisColor: NSColor = .green
var zAxisColor: NSColor = .blue
enum Axis: Int {
case X, Y, Z
var title: String {
switch self {
case .X: return "X"
case .Y: return "Y"
case .Z: return "Z"
}
}
}
private func getArrow( color: NSColor, axis: Axis) -> SCNNode {
let cylinderNode = SCNNode(geometry: SCNCylinder(radius: 1, height: 10))
cylinderNode.geometry?.firstMaterial?.diffuse.contents = color
cylinderNode.position = .init(0, 5, 0)
let coneNode = SCNNode(geometry: SCNCone(topRadius: 0, bottomRadius: 2, height: 4))
coneNode.geometry?.firstMaterial?.diffuse.contents = color
coneNode.position = .init(0, 12, 0)
let unitsText = SCNText(string: axis.title, extrusionDepth: 0)
unitsText.font = .systemFont(ofSize: CGFloat(6))
let textNode = SCNNode(geometry: unitsText)
textNode.position = SCNVector3(0, 16, 0)
let node = SCNNode()
node.addChildNode(cylinderNode)
node.addChildNode(coneNode)
node.addChildNode(textNode)
switch axis {
case .X:
node.rotation = .init(0, 0, 1, -Float.pi/2)
case .Y:
break
case .Z:
node.rotation = .init(1, 0, 0, Float.pi/2)
}
return node
}
func getIconSceneNode() -> SCNNode {
let node = SCNNode()
node.addChildNode(SCNNode(geometry: SCNSphere(radius: 2)))
node.addChildNode(getArrow(color: xAxisColor, axis: .X))
node.addChildNode(getArrow(color: yAxisColor, axis: .Y))
node.addChildNode(getArrow(color: zAxisColor, axis: .Z))
return node
}
func getIconNode() -> SK3DNode {
let scnScene = SCNScene()
scnScene.rootNode.addChildNode( getIconSceneNode() )
let node = SK3DNode(viewportSize: CGSize(width: 80, height: 80))
node.scnScene = scnScene
return node
}
}