Учитывая, что не совсем ясно, что вы хотите сделать, я предоставлю ответ, основанный на моей интерпретации вашего вопроса, который, как я полагаю, спрашивает, как пользователь может разместить SCNNode
с SCNTextGeometry
вуказанная пользователем позиция, например (постукивающее местоположение), а затем позиционировать или взаимодействовать с ней.
Приведенный ниже код является очень грубым примером, который позволяет пользователю разместить SCNNode
с SCNTextGeometry
вa tapLocation.
Затем пользователь может масштабировать его, используя UIPinchGestureRecognizer
, или поворачивать его, используя UIRotationGestureRecognizer
.
. Вам нужно будет поработать над настройкой currentNode в tapGestureRecognizer
,но он должен указывать вам правильное направление.
Весь код полностью прокомментирован, поэтому должен иметь смысл:
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
}
}
}
}
Надеюсь, это поможет ...