Ios 如何在AR工具包中旋转或缩放三维模型scn文件
这个类也呈现我的SCN文件Ios 如何在AR工具包中旋转或缩放三维模型scn文件,ios,swift,xcode,scenekit,arkit,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.sc
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 { }
}
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)
}
/// 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
}
}
其中当前节点指的是SCNNode
如果要移动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 { }
}
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)
}
/// 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
}
}
然后你可以这样做:
/// 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 { }
}
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)
}
/// 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;