ARSCNView 中的平滑对象旋转
Smooth object rotation in ARSCNView
在 AR 中旋转 3d 对象时,我试图使我的平移手势与 jigspace 应用程序一样流畅。这是我现在拥有的:
@objc func rotateObject(sender: UIPanGestureRecognizer) {
let sceneView = sender.view as! ARSCNView
var currentAngleY: Float = 0.0
let translation = sender.translation(in: sceneView)
var newAngleY = Float(translation.x)*Float(Double.pi)/180
sceneView.scene.rootNode.enumerateChildNodes { (node, stop) in
if sender.state == .changed {
newAngleY -= currentAngleY
node.eulerAngles.y = newAngleY
} else if sender.state == .ended {
currentAngleY = newAngleY
node.removeAllActions()
}
}
}
我在使用它时似乎有延迟,我正在尝试弄清楚如何使旋转尽可能平滑,同样,有点像 jigspace 或宜家应用程序。
我还注意到,当我尝试旋转某个角度的对象时,它会变得很尴尬。
查看您的旋转对象函数,似乎有些逻辑不太正确。
首先,我认为 var currentAngleY: Float = 0
应该在函数体之外。
其次,您应该将 currentAngleY
添加到 newAngleY
变量,例如:
/// Rotates The Models On Their YAxis
///
/// - Parameter gesture: UIPanGestureRecognizer
@objc func rotateModels(_ gesture: UIPanGestureRecognizer) {
let translation = gesture.translation(in: gesture.view!)
var newAngleY = (Float)(translation.x)*(Float)(Double.pi)/180.0
newAngleY += currentAngleY
DispatchQueue.main.async {
self.sceneView.scene.rootNode.enumerateChildNodes { (node, _) in
node.eulerAngles.y = newAngleY
}
}
if(gesture.state == .ended) { currentAngleY = newAngleY }
}
因此,在工作环境中的一个例子如下:
class ViewController: UIViewController {
@IBOutlet var augmentedRealityView: ARSCNView!
var currentAngleY: Float = 0
//-----------------------
// MARK: - View LifeCycle
//-----------------------
override func viewDidLoad() {
super.viewDidLoad()
//1. Generate Our Three Box Nodes
generateBoxNodes()
//2. Create Our Rotation Gesture
let rotateGesture = UIPanGestureRecognizer(target: self, action: #selector(rotateModels(_:)))
self.view.addGestureRecognizer(rotateGesture)
//3. Run The Session
let configuration = ARWorldTrackingConfiguration()
augmentedRealityView.session.run(configuration)
}
//------------------------
// MARK: - Node Generation
//------------------------
/// Generates Three SCNNodes With An SCNBox Geometry
func generateBoxNodes(){
//1. Create An Array Of Colours For Each Face
let colours: [UIColor] = [.red, .green, .blue, .purple, .cyan, .black]
//2. Create An SCNNode Wih An SCNBox Geometry
let boxNode = SCNNode()
let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0.01)
boxNode.geometry = boxGeometry
//3. Create A Different Material For Each Face
var materials = [SCNMaterial]()
for i in 0..<5{
let faceMaterial = SCNMaterial()
faceMaterial.diffuse.contents = colours[i]
materials.append(faceMaterial)
}
//4. Set The Geometries Materials
boxNode.geometry?.materials = materials
//5. Create Two More Nodes By Cloning The First One
let secondBox = boxNode.flattenedClone()
let thirdBox = boxNode.flattenedClone()
//6. Position Them In A Line & Add To The Scene
boxNode.position = SCNVector3(-0.2, 0, -1.5)
secondBox.position = SCNVector3(0, 0, -1.5)
thirdBox.position = SCNVector3(0.2, 0, -1.5)
self.augmentedRealityView.scene.rootNode.addChildNode(boxNode)
self.augmentedRealityView.scene.rootNode.addChildNode(secondBox)
self.augmentedRealityView.scene.rootNode.addChildNode(thirdBox)
}
//----------------------
// MARK: - Node Rotation
//----------------------
/// Rotates The Models On Their YAxis
///
/// - Parameter gesture: UIPanGestureRecognizer
@objc func rotateModels(_ gesture: UIPanGestureRecognizer) {
let translation = gesture.translation(in: gesture.view!)
var newAngleY = (Float)(translation.x)*(Float)(Double.pi)/180.0
newAngleY += currentAngleY
DispatchQueue.main.async {
self.augmentedRealityView.scene.rootNode.enumerateChildNodes { (node, _) in
node.eulerAngles.y = newAngleY
}
}
if(gesture.state == .ended) { currentAngleY = newAngleY }
}
}
希望对您有所帮助...
在 AR 中旋转 3d 对象时,我试图使我的平移手势与 jigspace 应用程序一样流畅。这是我现在拥有的:
@objc func rotateObject(sender: UIPanGestureRecognizer) {
let sceneView = sender.view as! ARSCNView
var currentAngleY: Float = 0.0
let translation = sender.translation(in: sceneView)
var newAngleY = Float(translation.x)*Float(Double.pi)/180
sceneView.scene.rootNode.enumerateChildNodes { (node, stop) in
if sender.state == .changed {
newAngleY -= currentAngleY
node.eulerAngles.y = newAngleY
} else if sender.state == .ended {
currentAngleY = newAngleY
node.removeAllActions()
}
}
}
我在使用它时似乎有延迟,我正在尝试弄清楚如何使旋转尽可能平滑,同样,有点像 jigspace 或宜家应用程序。
我还注意到,当我尝试旋转某个角度的对象时,它会变得很尴尬。
查看您的旋转对象函数,似乎有些逻辑不太正确。
首先,我认为 var currentAngleY: Float = 0
应该在函数体之外。
其次,您应该将 currentAngleY
添加到 newAngleY
变量,例如:
/// Rotates The Models On Their YAxis
///
/// - Parameter gesture: UIPanGestureRecognizer
@objc func rotateModels(_ gesture: UIPanGestureRecognizer) {
let translation = gesture.translation(in: gesture.view!)
var newAngleY = (Float)(translation.x)*(Float)(Double.pi)/180.0
newAngleY += currentAngleY
DispatchQueue.main.async {
self.sceneView.scene.rootNode.enumerateChildNodes { (node, _) in
node.eulerAngles.y = newAngleY
}
}
if(gesture.state == .ended) { currentAngleY = newAngleY }
}
因此,在工作环境中的一个例子如下:
class ViewController: UIViewController {
@IBOutlet var augmentedRealityView: ARSCNView!
var currentAngleY: Float = 0
//-----------------------
// MARK: - View LifeCycle
//-----------------------
override func viewDidLoad() {
super.viewDidLoad()
//1. Generate Our Three Box Nodes
generateBoxNodes()
//2. Create Our Rotation Gesture
let rotateGesture = UIPanGestureRecognizer(target: self, action: #selector(rotateModels(_:)))
self.view.addGestureRecognizer(rotateGesture)
//3. Run The Session
let configuration = ARWorldTrackingConfiguration()
augmentedRealityView.session.run(configuration)
}
//------------------------
// MARK: - Node Generation
//------------------------
/// Generates Three SCNNodes With An SCNBox Geometry
func generateBoxNodes(){
//1. Create An Array Of Colours For Each Face
let colours: [UIColor] = [.red, .green, .blue, .purple, .cyan, .black]
//2. Create An SCNNode Wih An SCNBox Geometry
let boxNode = SCNNode()
let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0.01)
boxNode.geometry = boxGeometry
//3. Create A Different Material For Each Face
var materials = [SCNMaterial]()
for i in 0..<5{
let faceMaterial = SCNMaterial()
faceMaterial.diffuse.contents = colours[i]
materials.append(faceMaterial)
}
//4. Set The Geometries Materials
boxNode.geometry?.materials = materials
//5. Create Two More Nodes By Cloning The First One
let secondBox = boxNode.flattenedClone()
let thirdBox = boxNode.flattenedClone()
//6. Position Them In A Line & Add To The Scene
boxNode.position = SCNVector3(-0.2, 0, -1.5)
secondBox.position = SCNVector3(0, 0, -1.5)
thirdBox.position = SCNVector3(0.2, 0, -1.5)
self.augmentedRealityView.scene.rootNode.addChildNode(boxNode)
self.augmentedRealityView.scene.rootNode.addChildNode(secondBox)
self.augmentedRealityView.scene.rootNode.addChildNode(thirdBox)
}
//----------------------
// MARK: - Node Rotation
//----------------------
/// Rotates The Models On Their YAxis
///
/// - Parameter gesture: UIPanGestureRecognizer
@objc func rotateModels(_ gesture: UIPanGestureRecognizer) {
let translation = gesture.translation(in: gesture.view!)
var newAngleY = (Float)(translation.x)*(Float)(Double.pi)/180.0
newAngleY += currentAngleY
DispatchQueue.main.async {
self.augmentedRealityView.scene.rootNode.enumerateChildNodes { (node, _) in
node.eulerAngles.y = newAngleY
}
}
if(gesture.state == .ended) { currentAngleY = newAngleY }
}
}
希望对您有所帮助...