首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何指向和定位arkit文本

如何指向和定位arkit文本
EN

Stack Overflow用户
提问于 2018-05-30 03:46:32
回答 1查看 548关注 0票数 0

下面的代码只是在视图中随机定位文本。我希望用户能够指向,然后在他们选择的方式定位文本。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-30 06:52:33

考虑到你想要做什么并不完全清楚,我将根据我对你的问题的解释提供一个答案,我相信你的问题是问用户如何将带有SCNTextGeometrySCNNode放置在用户指定的位置(点击位置),然后定位或与其交互。

下面的代码是一个非常粗糙的示例,它允许用户在tapLocation中放置一个带有SCNTextGeometrySCNNode

然后,用户可以使用UIPinchGestureRecognizer缩放它或使用UIRotationGestureRecognizer旋转它。

您需要在tapGestureRecognizer中设置currentNode,但它应该为您指明正确的方向。

所有的代码都有完整的注释,所以应该很有意义:

代码语言:javascript
复制
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
            }
        }

    }
}

希望这能帮上忙。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50591866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档