как указать и разместить текст arkit - PullRequest
0 голосов
/ 29 мая 2018

Код ниже просто размещает текст в произвольном порядке в представлении.Я хотел бы, чтобы пользователь мог указывать, а затем располагать текст так, как он выберет.enter image description here

1 Ответ

0 голосов
/ 30 мая 2018

Учитывая, что не совсем ясно, что вы хотите сделать, я предоставлю ответ, основанный на моей интерпретации вашего вопроса, который, как я полагаю, спрашивает, как пользователь может разместить 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
            }
        }

    }
}

Надеюсь, это поможет ...

...