gpt4 book ai didi

ios - 如何通过在屏幕上拖动手指来更改相机位置 - Swift

转载 作者:行者123 更新时间:2023-11-28 23:23:31 25 4
gpt4 key购买 nike

我正在尝试学习 ARKIT 并制作一个小型演示应用程序以在 3D 中绘图。以下是我写的代码,目前没有任何问题:

import UIKit
import ARKit

class ViewController: UIViewController, ARSCNViewDelegate {

@IBOutlet weak var sceneView: ARSCNView!

@IBOutlet weak var DRAW: UIButton!
@IBOutlet weak var DEL: UIButton!

let config = ARWorldTrackingConfiguration()

override func viewDidLoad() {
super.viewDidLoad()

self.sceneView.session.run(config)
self.sceneView.delegate = self
}

func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {

guard let pointOfView = sceneView.pointOfView else {return}
let transform = pointOfView.transform
let cameraOrientation = SCNVector3(-transform.m31,-transform.m32,-transform.m33)
let cameraLocation = SCNVector3(transform.m41,transform.m42,transform.m43)
let cameraCurrentPosition = cameraOrientation + cameraLocation

DispatchQueue.main.async {

if (self.DRAW.isTouchInside){
let sphereNode = SCNNode(geometry: SCNSphere(radius: 0.02))
sphereNode.position = cameraCurrentPosition
self.sceneView.scene.rootNode.addChildNode(sphereNode)
sphereNode.geometry?.firstMaterial?.diffuse.contents = UIColor.red
print("RED Button is Pressed")
}else if (self.DEL.isTouchInside){
self.sceneView.scene.rootNode.enumerateChildNodes{
(node, stop) in
node.removeFromParentNode()
}
}else{
let pointer = SCNNode(geometry: SCNSphere(radius: 0.01))
pointer.name = "pointer"
pointer.position = cameraCurrentPosition
self.sceneView.scene.rootNode.enumerateChildNodes({(node,_) in
if node.name == "pointer"{
node.removeFromParentNode()
}
})
self.sceneView.scene.rootNode.addChildNode(pointer)
pointer.geometry?.firstMaterial?.diffuse.contents = UIColor.purple
}
}
}
}

func +(left:SCNVector3,right:SCNVector3) -> SCNVector3 {
return SCNVector3Make(left.x + right.x, left.y + right.y, left.z + right.z)
}

如您所见,我设置了场景并进行了配置,我创建了一个按下时进行绘制的按钮、一个位于场景中心的指针(或取景器)和一个用于删除插入的节点的按钮。

现在我希望能够将 cameraCurrentPosition 移动到与中心不同的点:如果可能的话,我想通过触摸屏幕来移动它,以获取手指的位置。如果可能的话,有人可以帮我处理代码吗?

最佳答案

一般来说,您不能以编程方式在 ARSCN 内移动相机,相机变换是设备相对于虚拟场景的物理位置。

话虽如此,您可以将用户触摸到屏幕的一种方法是在 View Controller 中使用 touchesMoved 方法。

var touchRoots: [SCNNode] = [] // list of root nodes for each set of touches drawn

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// get the initial touch event
if let touch = touches.first {
guard let pointOfView = self.sceneView.pointOfView else { return }
let transform = pointOfView.transform // transformation matrix
let orientation = SCNVector3(-transform.m31, -transform.m32, -transform.m33) // camera rotation
let location = SCNVector3(transform.m41, transform.m42, transform.m43) // location of camera frustum
let currentPostionOfCamera = orientation + location // center of frustum in world space
DispatchQueue.main.async {
let touchRootNode : SCNNode = SCNNode() // create an empty node to serve as our root for the incoming points
touchRootNode.position = currentPostionOfCamera // place the root node ad the center of the camera's frustum
touchRootNode.scale = SCNVector3(1.25, 1.25, 1.25)// touches projected in Z will appear smaller than expected - increase scale of root node to compensate
guard let sceneView = self.sceneView else { return }
sceneView.scene.rootNode.addChildNode(touchRootNode) // add the root node to the scene
let constraint = SCNLookAtConstraint(target: self.sceneView.pointOfView) // force root node to always face the camera
constraint.isGimbalLockEnabled = true // enable gimbal locking to avoid issues with rotations from LookAtConstraint
touchRootNode.constraints = [constraint] // apply LookAtConstraint

self.touchRoots.append(touchRootNode)
}
}
}

override func func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let translation = touch.location(in: self.view)
let translationFromCenter = CGPoint(x: translation.x - (0.5 * self.view.frame.width), y: translation.y - (0.5 * self.view.frame.height))

// add nodes using the main thread
DispatchQueue.main.async {
guard let touchRootNode = self.touchRoots.last else { return }
let sphereNode : SCNNode = SCNNode(geometry: SCNSphere(radius: 0.015))
sphereNode.position = SCNVector3(-1*Float(translationFromCenter.x/1000), -1*Float(translationFromCenter.y/1000), 0)
sphereNode.geometry?.firstMaterial?.diffuse.contents = UIColor.white
touchRootNode.addChildNode(sphereNode) // add point to the active root
}
}
}

注意:解决方案仅处理单点触摸,但扩展示例以添加多点触摸支持足够简单。/p>

关于ios - 如何通过在屏幕上拖动手指来更改相机位置 - Swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59248637/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com