SceneKit子节点旋转

时间:2018-07-09 23:38:39

标签: ios swift scenekit arkit

在添加球后旋转并单击飞船以添加另一个球时,命中测试坐标是否正确返回并使球完全脱离触摸?

class Ship:SCNNode{
    var currentAlignment: ARPlaneAnchor.Alignment = .horizontal
    var rotationWhenAlignedHorizontally: Float = 0
    var objectRotation: Float {
        get {
            return childNodes.first!.eulerAngles.y
        }
        set (newValue) {
            var normalized = newValue.truncatingRemainder(dividingBy: 2 * .pi)
            normalized = (normalized + 2 * .pi).truncatingRemainder(dividingBy: 2 * .pi)
            if normalized > .pi {
                normalized -= 2 * .pi
            }
            childNodes.first!.eulerAngles.y = normalized
            if currentAlignment == .horizontal {
                rotationWhenAlignedHorizontally = normalized
            }
        }
    }

    override init() {
        super.init()
        guard let virtualObject = SCNScene(named: "art.scnassets/ship.scn") else {return}
        let wrapperNode = SCNNode()
        for child in virtualObject.rootNode.childNodes {
            child.geometry?.firstMaterial?.lightingModel = .phong
            wrapperNode.addChildNode(child)
        }
        self.addChildNode(wrapperNode)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

class Ball:SCNNode{
    override init() {
        super.init()
        let sphere = SCNSphere(radius: 0.025)
        self.geometry = sphere
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class ViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!
    var nodeOne:Ship = Ship()

    override func viewDidLoad() {
        super.viewDidLoad()
        sceneView.delegate = self
        sceneView.showsStatistics = true
        sceneView.autoenablesDefaultLighting = true

        nodeOne.position = SCNVector3(x:0,y:0,z:0)
        self.sceneView.scene.rootNode.addChildNode(nodeOne)

        let tap = UITapGestureRecognizer(target: self, action: #selector(tap(gesture: )))
        self.sceneView.addGestureRecognizer(tap)

        let rotate = UIRotationGestureRecognizer(target: self, action: #selector(rotate(gesture:)))
        self.sceneView.addGestureRecognizer(rotate)
    }

    @objc func tap(gesture:UITapGestureRecognizer){
        let tapLocation = gesture.location(in: self.sceneView)
        let hitTestNode = sceneView.hitTest(tapLocation, options: nil)
        let nodeTwo = Ball()
        nodeTwo.position = (hitTestNode.first?.worldCoordinates)!

        nodeOne.childNodes.first.addChildNode(nodeTwo)
    }

    @objc func rotate(gesture:UIRotationGestureRecognizer){
        guard gesture.state == .changed else { return }
        nodeOne.objectRotation -= Float(gesture.rotation)
        gesture.rotation = 0
    }
}

以下是一个视频,其中有一个问题:https://drh2acu5z204m.cloudfront.net/items/291B1C1U0S3f192t3B32/ScreenRecording_07-10-2018%2011-19-47.mp4?X-CloudApp-Visitor-Id=3097286

1 个答案:

答案 0 :(得分:0)

我能够解决它。它与将本地抽头坐标转换为世界有关

nodeTwo.position = (hitTestNode.first?.node.convertPosition((hitTestNode.first?.localCoordinates)!, to: nodeOne))!