Поверните значок UCS как SK3DNode в SpriteKit, наложение соответствует вращению в SCNView - PullRequest
0 голосов
/ 23 февраля 2020

У меня есть 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
    }
}
...