用锚移动3D对象

时间:2018-12-19 10:35:16

标签: ios anchor arkit

我目前正在开发ARKit应用。它应该能够放置不同的3d对象,将它们四处移动并保存世界地图。只要我不使用锚点,就可以放置和移动不同的对象。一旦放置锚点以保存世界地图,我就无法正确移动对象。我使用苹果开发人员项目“与3d对象交互”作为想法。他们开始移动物体时移开了锚,然后又添加了一个新物体。但是由于我有不同种类的对象,因此无法正常工作。当用户点击添加按钮时,他选择他想放置的对象。这会将模型名称设置为正确的模型。当他在屏幕上点击时,它会将锚与modelName一起放置。在renderer(didAdd)中将创建正确的节点。移动功能将替换模型和锚点,但不起作用(重新加载时会破裂)。我认为问题是不允许使用零锚,但我没有找到一个好的方法。

你能帮我吗?

@objc func tapped(sender: UITapGestureRecognizer){
    let sceneView = sender.view as! ARSCNView
    let tapLocation = sender.location(in: sceneView)

    let hitTest = sceneView.hitTest(tapLocation, types: .existingPlaneUsingExtent)
    if !hitTest.isEmpty{
    print("Touched on the plane")


        let hitTestResult = hitTest.first!
        anchor = ARAnchor(name: "\(modelName)", transform: hitTestResult.worldTransform)
        print ("Anchor Name: , \(anchor!.name)" )

        self.sceneView.session.add(anchor: anchor!)

    }else{
        print("Not a plane")}
    }
@objc func moveNode(_ gesture: UIPanGestureRecognizer) {

    //1. Get The Current Touch Point
    let currentTouchPoint = gesture.location(in: sceneView)


    //2. If The Gesture State Has Begun Perform A Hit Test To Get The SCNNode At The Touch Location
    if gesture.state == .began{

        //2a. Perform An SCNHitTest To Detect If An SCNNode Has Been Touched
        guard let nodeHitTest = sceneView.hitTest(currentTouchPoint, options: nil).first else { return }

        //2b. Get The SCNNode Result
        let nodeHit = nodeHitTest.node

        //2c. Set As The Current Node
        selectedNode = nodeHit
        //if anchor is not nil remove from session



    }

    //3. If The Gesture State Has Changed Then Perform An ARSCNHitTest To Detect Any Existing Planes
    if gesture.state == .changed{

        //3b. Get The Next Feature Point Etc
        guard let hitTest = sceneView.hitTest(currentTouchPoint, types: .existingPlane).first else { return }

        //3c. Convert To World Coordinates
         let worldTransform = hitTest.worldTransform

        //3d. Set The New Position
        let newPosition = SCNVector3(worldTransform.columns.3.x, worldTransform.columns.3.y, worldTransform.columns.3.z)

        //3e. Apply To The Node
        selectedNode?.simdPosition = float3(newPosition.x, newPosition.y, newPosition.z)

    }

    //4. If The Gesture State Has Ended Remove The Reference To The Current Node
    if gesture.state == .ended{

        let selectedAnchor = sceneView.anchor(for: selectedNode!)
        if( selectedAnchor == nil){
            return

        }
        sceneView.session.remove(anchor: selectedAnchor!)
        guard let hitTest = sceneView.hitTest(currentTouchPoint, types: .existingPlane).first else { return }

        //3c. Convert To World Coordinates
        selectedNodeName = getParent(selectedNode)?.name

        let worldTransform = hitTest.worldTransform
        let newAnchor = ARAnchor(name: "\(selectedNodeName)", transform: worldTransform)
        print("NewAnchorName: , \(newAnchor.name)")
        sceneView.session.add(anchor: newAnchor)


        selectedNode = nil
        selectedNodeName = nil
        print("NewAnchorNameAfterNil: , \(newAnchor.name)")
        //adOrUpdateAnchor
    }
}

0 个答案:

没有答案
相关问题