【问题标题】:Smooth object rotation in ARSCNViewARSCNView 中的平滑对象旋转
【发布时间】:2018-07-06 20:22:47
【问题描述】:

在 AR 中旋转 3d 对象时,我试图让我的平移手势与 jigspace 应用程序一样流畅。这是我现在拥有的:

@objc func rotateObject(sender: UIPanGestureRecognizer) {

    let sceneView = sender.view as! ARSCNView
    var currentAngleY: Float = 0.0

    let translation = sender.translation(in: sceneView)
    var newAngleY = Float(translation.x)*Float(Double.pi)/180

    sceneView.scene.rootNode.enumerateChildNodes { (node, stop) in

        if sender.state == .changed {
            newAngleY -= currentAngleY
            node.eulerAngles.y = newAngleY
        } else if sender.state == .ended {
            currentAngleY = newAngleY
            node.removeAllActions()
        }
    }
}

我在使用它时似乎有延迟,我正试图弄清楚如何使旋转尽可能平滑,再次,有点像 jigspace 或宜家应用程序。

我还注意到,当我尝试在某个角度旋转对象时,它可能会变得很尴尬。

【问题讨论】:

    标签: swift xcode scenekit arkit uipangesturerecognizer


    【解决方案1】:

    查看您的旋转对象函数,似乎有些逻辑不太正确。

    首先,我认为var currentAngleY: Float = 0 应该在你的函数体之外。

    其次,您应该将currentAngleY 添加到newAngleY 变量中,例如:

    /// Rotates The Models On Their YAxis
    ///
    /// - Parameter gesture: UIPanGestureRecognizer
    @objc func rotateModels(_ gesture: UIPanGestureRecognizer) {
    
        let translation = gesture.translation(in: gesture.view!)
        var newAngleY = (Float)(translation.x)*(Float)(Double.pi)/180.0
        newAngleY += currentAngleY
    
        DispatchQueue.main.async {
            self.sceneView.scene.rootNode.enumerateChildNodes { (node, _) in
                node.eulerAngles.y = newAngleY
    
            }
        }
    
        if(gesture.state == .ended) { currentAngleY = newAngleY }
    
    }
    

    因此,在工作环境中的示例如下:

     class ViewController: UIViewController {
    
        @IBOutlet var augmentedRealityView: ARSCNView!
    
        var currentAngleY: Float = 0
    
        //-----------------------
        // MARK: - View LifeCycle
        //-----------------------
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            //1. Generate Our Three Box Nodes
            generateBoxNodes()
    
            //2. Create Our Rotation Gesture
            let rotateGesture = UIPanGestureRecognizer(target: self, action: #selector(rotateModels(_:)))
            self.view.addGestureRecognizer(rotateGesture)
    
            //3. Run The Session
            let configuration = ARWorldTrackingConfiguration()
            augmentedRealityView.session.run(configuration)
        }
    
    
        //------------------------
        // MARK: - Node Generation
        //------------------------
    
        /// Generates Three SCNNodes With An SCNBox Geometry
        func generateBoxNodes(){
    
            //1. Create An Array Of Colours For Each Face
            let colours: [UIColor] = [.red, .green, .blue, .purple, .cyan, .black]
    
            //2. Create An SCNNode Wih An SCNBox Geometry
            let boxNode = SCNNode()
            let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0.01)
            boxNode.geometry = boxGeometry
    
            //3. Create A Different Material For Each Face
            var materials = [SCNMaterial]()
    
            for i in 0..<5{
                let faceMaterial = SCNMaterial()
                faceMaterial.diffuse.contents = colours[i]
                materials.append(faceMaterial)
            }
    
            //4. Set The Geometries Materials
            boxNode.geometry?.materials = materials
    
            //5. Create Two More Nodes By Cloning The First One
            let secondBox = boxNode.flattenedClone()
            let thirdBox = boxNode.flattenedClone()
    
            //6. Position Them In A Line & Add To The Scene
            boxNode.position = SCNVector3(-0.2, 0, -1.5)
            secondBox.position = SCNVector3(0, 0, -1.5)
            thirdBox.position = SCNVector3(0.2, 0, -1.5)
    
            self.augmentedRealityView.scene.rootNode.addChildNode(boxNode)
            self.augmentedRealityView.scene.rootNode.addChildNode(secondBox)
            self.augmentedRealityView.scene.rootNode.addChildNode(thirdBox)
        }
    
        //----------------------
        // MARK: - Node Rotation
        //----------------------
    
        /// Rotates The Models On Their YAxis
        ///
        /// - Parameter gesture: UIPanGestureRecognizer
        @objc func rotateModels(_ gesture: UIPanGestureRecognizer) {
    
            let translation = gesture.translation(in: gesture.view!)
            var newAngleY = (Float)(translation.x)*(Float)(Double.pi)/180.0
            newAngleY += currentAngleY
    
            DispatchQueue.main.async {
                self.augmentedRealityView.scene.rootNode.enumerateChildNodes { (node, _) in
                    node.eulerAngles.y = newAngleY
    
                }
            }
    
            if(gesture.state == .ended) { currentAngleY = newAngleY }
    
        }
    
    }
    

    希望对你有帮助...

    【讨论】:

    • 这正是我想要的!非常感谢!
    • 很高兴它有帮助:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 1970-01-01
    • 2015-11-12
    • 2022-01-14
    • 1970-01-01
    相关资源
    最近更新 更多