ios - ARKit - 如何创建旋转对象手势功能?

时间:2018-03-25 08:06:53

标签: ios swift arkit

我是ARKit的新手。我想创建一个旋转对象的函数。这是关于拖动和旋转对象的代码:

// Rotate object
@objc func rotateRecognized(sender: UIPanGestureRecognizer) {
    let sceneView = sender.view as! ARSCNView
    let swipeLocation = sender.location(in: sceneView)
    let hitTest = sceneView.hitTest(swipeLocation)
    if !hitTest.isEmpty {
        sender.minimumNumberOfTouches = 2
        let results = hitTest.first!
        let node = results.node
        let xPan = sender.velocity(in: sceneView).x/10000
        node.runAction(SCNAction.rotateBy(x: 0, y: xPan, z: 0, duration: 0.1))
    }
}

// Drag object
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    //1. Get The Current Touch Point
    guard let currentTouchPoint = touches.first?.location(in: self.sceneView),
        //2. Get The Next Feature Point Etc
        let hitTest = sceneView.hitTest(currentTouchPoint, types: .existingPlane).first else { return }

    //3. Convert To World Coordinates
    let worldTransform = hitTest.worldTransform

    //4. Set The New Position
    let newPosition = SCNVector3(worldTransform.columns.3.x, worldTransform.columns.3.y, worldTransform.columns.3.z)

    //5. Apply To The Node
    self.sceneView.scene.rootNode.enumerateChildNodes{ (node, _) in
       node.simdPosition = float3(newPosition.x, newPosition.y, newPosition.z)
    }

}

当我拖动一个对象时,它工作正常。但是当我用两根手指滑动旋转对象时,在删除touchesMoves方法之前,对象无法旋转。 如何解决这个问题?谢谢。

1 个答案:

答案 0 :(得分:10)

我认为最好使用fun getData() { val disposable = dataSource.getLivePayments() .subscribeOn(schedulerProvider.io()) .observeOn(schedulerProvider.ui()) .subscribe(({ livePayments: List<Payment> -> this.livePayments.clear() this.livePayments.addAll(livePayments) dataSource.getLiveRemittances() .subscribeOn(schedulerProvider.io()) .observeOn(schedulerProvider.ui()) .subscribe(({ liveRemittances: List<Remittance> -> this.liveRemittances.clear() this.liveRemittances.addAll(liveRemittances) // similarly called dataSource.getLiveTimeSheets() // and dataSource.getArchiveTimeSheets() // synchronous // then call calculateAmount() }), ({ t -> this.parseError(t) })) }), ({ t -> this.parseError(t) })) compositeDisposable.add(disposable) } fun calculateAmount() { val balance = if(liveRemittances.isNotEmpty()) { (sum(payment.amount) - sum(timesheet.amount)) * sum(liveRemittance.amount) } else { (sum(payment.amount) - sum(timesheet.amount)) } } 而不是GestureRecognizerstouches的组合来解决这个问题。

让我们来看看我们如何解决这个问题。

你已经具有拖动SCNNode的功能,可以很容易地将其转换为gestures,并且你想要一个函数围绕它的YAx旋转SCNNode,我们可以很容易地使用{{1} }。

在我的例子中,我有一个名为currentNode的SCNNode,虽然你的当然会有所不同。

首先,我们将创建两个变量:

UIPanGesture

然后我们将在UIRotationGestureRecognizer中创建两个//Store The Rotation Of The CurrentNode var currentAngleY: Float = 0.0 //Not Really Necessary But Can Use If You Like var isRotating = false

gestureRecognizers

完成此操作后,我们需要创建我们的函数。

第一个将处理拖动currentNode,例如:

viewDidLoad

第二个围绕它转动它的YAxis:

 let panGesture = UIPanGestureRecognizer(target: self, action: #selector(moveNode(_:)))
 self.view.addGestureRecognizer(panGesture)

 let rotateGesture = UIRotationGestureRecognizer(target: self, action: #selector(rotateNode(_:)))
 self.view.addGestureRecognizer(rotateGesture)

这是一个非常粗略的例子,您需要查看不同的/// Rotates An Object On It's YAxis /// /// - Parameter gesture: UIPanGestureRecognizer @objc func moveNode(_ gesture: UIPanGestureRecognizer) { if !isRotating{ //1. Get The Current Touch Point let currentTouchPoint = gesture.location(in: self.augmentedRealityView) //2. Get The Next Feature Point Etc guard let hitTest = self.augmentedRealityView.hitTest(currentTouchPoint, types: .existingPlane).first else { return } //3. Convert To World Coordinates let worldTransform = hitTest.worldTransform //4. Set The New Position let newPosition = SCNVector3(worldTransform.columns.3.x, worldTransform.columns.3.y, worldTransform.columns.3.z) //5. Apply To The Node currentNode.simdPosition = float3(newPosition.x, newPosition.y, newPosition.z) } } 等,但希望它应该指向正确的方向......