下面的代码只是在视图中随机定位文本。我希望用户能够指向,然后在他们选择的方式定位文本。
发布于 2018-05-30 06:52:33
考虑到你想要做什么并不完全清楚,我将根据我对你的问题的解释提供一个答案,我相信你的问题是问用户如何将带有SCNTextGeometry
的SCNNode
放置在用户指定的位置(点击位置),然后定位或与其交互。
下面的代码是一个非常粗糙的示例,它允许用户在tapLocation中放置一个带有SCNTextGeometry
的SCNNode
。
然后,用户可以使用UIPinchGestureRecognizer
缩放它或使用UIRotationGestureRecognizer
旋转它。
您需要在tapGestureRecognizer
中设置currentNode,但它应该为您指明正确的方向。
所有的代码都有完整的注释,所以应该很有意义:
class ViewController: UIViewController {
//1. Create A Reference To Our ARSCNView In Our Storyboard Which Displays The Camera Feed
@IBOutlet weak var augmentedRealityView: ARSCNView!
//2. Create Our ARWorld Tracking Configuration
let configuration = ARWorldTrackingConfiguration()
//3. Create Our Session
let augmentedRealitySession = ARSession()
//4. Create A Variable To Store The Current Nodes Rotation Around It's Y-Axis
var currentAngleY: Float = 0.0
var isRotating = false
var currentNode: SCNNode?
//--------------------
//MARK: View LifeCycle
//--------------------
override func viewDidLoad() {
super.viewDidLoad()
//1. Run The ARSession
augmentedRealityView.session = augmentedRealitySession
augmentedRealitySession.run(configuration, options: [.resetTracking, .removeExistingAnchors])
//2. Add A UIPinchGestureRecognizer So We Can Scale Our TextNode
let scaleGesture = UIPinchGestureRecognizer(target: self, action: #selector(scaleCurrentNode(_:)))
self.view.addGestureRecognizer(scaleGesture)
//3. Add A Tap Gesture Recogizer So We Can Place Our TextNode
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(placeOrAssignNode(_:)))
self.view.addGestureRecognizer(tapGesture)
//4. Add A Rotation Gesture Recogizer So We Can Rotate Our TextNode
let rotateGesture = UIRotationGestureRecognizer(target: self, action: #selector(rotateNode(_:)))
self.view.addGestureRecognizer(rotateGesture)
}
override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() }
//-----------------------
//MARK: Touch Interaction
//-----------------------
/// Performs An ARHitTest Or SCNHitTest So We Can Place Or Assign Our TextNode
///
/// - Parameter gesture: UITapGestureRecognizer
@objc func placeOrAssignNode(_ gesture: UITapGestureRecognizer){
//1. Get The Current Location Of The Tap
let currentTouchLocation = gesture.location(in: self.augmentedRealityView)
//2. If We Hit An SCNNode Set It As The Current Node So We Can Interact With It
if let nodeHitTest = self.augmentedRealityView.hitTest(currentTouchLocation, options: nil).first?.node{
currentNode = nodeHitTest
return
}
//3. Do An ARHitTest For Features Points So We Can Place An SCNNode
if let hitTest = self.augmentedRealityView.hitTest(currentTouchLocation, types: .featurePoint).first {
//4. Get The World Transform
let hitTestPosition = hitTest.worldTransform.columns.3
//5. Add The TestNode At The Desired Position
createTextFromPosition(SCNVector3(hitTestPosition.x, hitTestPosition.y, hitTestPosition.z))
return
}
}
//-------------------
//MARK: Node Creation
//-------------------
/// Creates An SCNNode With An SCNTextGeometry
///
/// - Parameter position: SCNVector3
func createTextFromPosition(_ position: SCNVector3){
let textNode = SCNNode()
//1. Create The Text Geometry With String & Depth Parameters
let textGeometry = SCNText(string: "StackOverFlow" , extrusionDepth: 1)
//2. Set The Font With Our Set Font & Size
textGeometry.font = UIFont(name: "Helvatica", size: 1)
//3. Set The Flatness To Zero (This Makes The Text Look Smoother)
textGeometry.flatness = 0
//4. Set The Colour Of The Text
textGeometry.firstMaterial?.diffuse.contents = UIColor.white
//5. Set The Text's Material
textNode.geometry = textGeometry
//6. Set The Pivot At The Center
let min = textNode.boundingBox.min
let max = textNode.boundingBox.max
textNode.pivot = SCNMatrix4MakeTranslation(
min.x + (max.x - min.x)/2,
min.y + (max.y - min.y)/2,
min.z + (max.z - min.z)/2
)
//7. Scale The Text So We Can Actually See It!
textNode.scale = SCNVector3(0.005, 0.005 , 0.005)
//8. Add It To The Hierachy & Position It
self.augmentedRealityView.scene.rootNode.addChildNode(textNode)
textNode.position = position
//9. Set It As The Current Node
currentNode = textNode
}
//-------------
//MARK: Scaling
//-------------
/// Scales The Currently Selected Node
///
/// - Parameter gesture: UIPinchGestureRecognizer
@objc func scaleCurrentNode(_ gesture: UIPinchGestureRecognizer) {
if !isRotating, let selectedNode = currentNode{
if gesture.state == .changed {
let pinchScaleX: CGFloat = gesture.scale * CGFloat((selectedNode.scale.x))
let pinchScaleY: CGFloat = gesture.scale * CGFloat((selectedNode.scale.y))
let pinchScaleZ: CGFloat = gesture.scale * CGFloat((selectedNode.scale.z))
selectedNode.scale = SCNVector3Make(Float(pinchScaleX), Float(pinchScaleY), Float(pinchScaleZ))
gesture.scale = 1
}
if gesture.state == .ended {}
}
}
//----------------
//MARK: Rotation
//----------------
/// Rotates The Currently Selected Node Around It's YAxis
///
/// - Parameter gesture: UIRotationGestureRecognizer
@objc func rotateNode(_ gesture: UIRotationGestureRecognizer){
if let selectedNode = currentNode{
//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{
isRotating = true
selectedNode.eulerAngles.y = currentAngleY + rotation
}
//3. If The Gesture Has Ended Store The Last Angle Of The CurrentNode
if(gesture.state == .ended) {
currentAngleY = selectedNode.eulerAngles.y
isRotating = false
}
}
}
}
希望这能帮上忙。
https://stackoverflow.com/questions/50591866
复制相似问题