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

时间:2018-04-20 09:59:30

标签: ios swift xcode scenekit arkit

此类也会渲染我的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)文件。我想用户可以与我的对象进行交互。

1 个答案:

答案 0 :(得分:7)

如果您想缩放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 }

因此:

  

如果将此属性设置为true,则SceneKit会创建一个摄像机节点   处理鼠标或触摸事件以允许用户平移,缩放和   旋转他们的场景视图。 (启用用户摄像头控制不会   修改场景图或节点中已存在的摄像机对象   包含它们。)

因此,一个例子是:

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