如何在 AR 套件中旋转或缩放 3D 模型 scn 文件

How to rotate or scale 3D model scn file in AR kit

这个 class 也呈现我的 SCN 文件。

import UIKit
import ARKit

class SimpleViewController: UIViewController {

    @IBOutlet var sceneView: ARSCNView!

    override func viewDidLoad() {
        super.viewDidLoad()        
        sceneView.scene = SCNScene(named: "duck.scn", inDirectory: "models.scnassets/furniture")!
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        sceneView.session.run(ARWorldTrackingConfiguration())
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        sceneView.session.pause()
    }
}

但我知道如何旋转或缩放我的对象 (duck.scn) 文件。我希望用户可以与我的对象进行交互。

如果你想缩放 SCNNode 你可以这样做:

/// Scales An SCNNode
///
/// - Parameter gesture: UIPinchGestureRecognizer
@objc func scaleObject(gesture: UIPinchGestureRecognizer) {

    guard let nodeToScale = currentNode else { return }
    if gesture.state == .changed {

        let pinchScaleX: CGFloat = gesture.scale * CGFloat((nodeToScale.scale.x))
        let pinchScaleY: CGFloat = gesture.scale * CGFloat((nodeToScale.scale.y))
        let pinchScaleZ: CGFloat = gesture.scale * CGFloat((nodeToScale.scale.z))
        nodeToScale.scale = SCNVector3Make(Float(pinchScaleX), Float(pinchScaleY), Float(pinchScaleZ))
        gesture.scale = 1

    }
    if gesture.state == .ended { }

}

当前节点指的是SCNNode.

如果你想移动一个 SCNNode 你可以这样做:

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

    //1. Get The Current Touch Point
    guard let currentTouchPoint = touches.first?.location(in: self.augmentedRealityView),
        //2. Get The Next Feature Point Etc
        let hitTest = 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)

}

如果您想旋转 SCNNode,您首先应该创建一个变量来存储原始角度,例如:

//Store The Rotation Of The CurrentNode
var currentAngleY: Float = 0.0

那么你可以这样做:

/// Rotates An SCNNode Around It's YAxis
///
/// - Parameter gesture: UIRotationGestureRecognizer
@objc func rotateNode(_ gesture: UIRotationGestureRecognizer){

    //1. Get The Current Rotation From The Gesture
    let rotation = Float(gesture.rotation)

    //2. If The Gesture State Has Changed Set The Nodes EulerAngles.y
    if gesture.state == .changed{

        currentNode.eulerAngles.y = currentAngleY + rotation
    }

    //3. If The Gesture Has Ended Store The Last Angle Of The Cube
    if(gesture.state == .ended) {
        currentAngleY = currentNode.eulerAngles.y

    }
}

如果你想直接与你的 SCNScene 交互(虽然我相信不是在 ARKit 中)你可以使用以下方法:

var allowsCameraControl: Bool { get set }

由此:

If you set this property to true, SceneKit creates a camera node and handles mouse or touch events to allow the user to pan, zoom, and rotate their view of the scene. (Enabling user camera control does not modify camera objects already existing in the scene graph or the nodes containing them.)

例如:

 sceneView.scene = SCNScene(named: "duck.scn", inDirectory: "models.scnassets/furniture")!
 sceneView.allowsCameraControl = true;