我是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方法之前,对象无法旋转。 如何解决这个问题?谢谢。
答案 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))
}
}
而不是GestureRecognizers
和touches
的组合来解决这个问题。
让我们来看看我们如何解决这个问题。
你已经具有拖动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)
}
}
等,但希望它应该指向正确的方向......