用于模型旋转的自定义平移手势处理程序

问题描述 投票:0回答:1

我想允许用户使用平移手势旋转模型。旋转应跟随手指的移动。可能的运动可能类似于 https://www.youtube.com/watch?v=50EjlzVsQM8,但也沿 z 轴旋转。

我实现了一个平移手势处理程序:

@objc private func handlePan(recognizer: UIPanGestureRecognizer) {
    let currentTouchPoint = recognizer.location(in: self.arView)
    guard let ray = self.arView.ray(through: currentTouchPoint) else {
        return
    }
    anchorEntity.transform.rotation = .init(angle: .pi, axis: ray.direction)
}

但是现在,这段代码有几个问题:

  1. 由于角度设置为 PI,手势会完全翻转模型,我可以从那里旋转它,这不是我想要的。但如果我将其设置为 .zero,我就根本无法旋转它。
  2. 旋转需要很大的力气,从某种意义上说,我需要做很长的手指运动,并且不可能进行完整的旋转/将其移回起点。

我相信我需要以某种方式调整角度/方向,但不知道从哪里开始,我不太熟悉 3D 变换。任何帮助将不胜感激。

swift arkit realitykit
1个回答
0
投票

由于 2D 平移手势只有 x/y 坐标,因此通过平移,您可以控制模型围绕确定的一对轴(例如 x/y 或 y/z)的旋转。这是代码:

import RealityKit
import ARKit

class ViewController : UIViewController {
    @IBOutlet var arView: ARView!
    let boxPrim = ModelEntity(mesh: .generateBox(size: 0.75))
    var previousPoint = CGPoint()
    let anchor = AnchorEntity()
    var deg: Float = .zero
    
    @objc func panning(recognizer: UIPanGestureRecognizer) {
        deg += 5.0
        var currentPoint = recognizer.location(in: arView)
        let rad = deg * .pi / 180
        
        if currentPoint.x > previousPoint.x {
            boxPrim.transform = Transform(yaw: rad * 1.5)  // Y
            currentPoint.y = 0
        }
        if currentPoint.x < previousPoint.x {
            boxPrim.transform = Transform(yaw: -rad * 1.5) // Y
            currentPoint.y = 0
        }
        if currentPoint.y > previousPoint.y {
            boxPrim.transform = Transform(pitch: rad)      // X
        }
        if currentPoint.y < previousPoint.y {
            boxPrim.transform = Transform(pitch: -rad)     // X
        }
        previousPoint = currentPoint
    }
    func gestureRecognizer() {
        let recognizer = UIPanGestureRecognizer(target: self,
                                                action: #selector(panning))
        arView.addGestureRecognizer(recognizer)
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        anchor.addChild(boxPrim)
        arView.scene.addAnchor(anchor)
        self.gestureRecognizer()
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.