Ali Aqdas
Ali Aqdas

Reputation: 445

How to change COLLADA(.dae) file to SceneKit(.scn) file programmatically Swift

COLLADA(.dae) , SceneKit(.scn)

I am working with scenekit and problem is there is an admin who will upload .dae file to server and i'll get that link in app and by using code i have to show it on camera. In running app for .scn file url it is working fine but for .dae file url it is generating an error COLLADA files are not supported on this platform. so i want to convert .dae file to .scn file at run time. If anyone know any other source which can convert .dae file to .scn file kindly mention. By this source admin will upload .scn file to server after converting.

Upvotes: 0

Views: 433

Answers (1)

Ali Aqdas
Ali Aqdas

Reputation: 445

Finally solved thanks stackoverflow by using Model I/O swift concept

Step1#

// first need to download file to local directory
func downloadSceneTask(){
    
    //1. Get The URL Of The SCN File
    guard let url = URL(string: "Your_url") else { return }
    
    //2. Create The Download Session
    let downloadSession = URLSession(configuration: URLSession.shared.configuration, delegate: self, delegateQueue: nil)
    
    //3. Create The Download Task & Run It
    let downloadTask = downloadSession.downloadTask(with: url)
    downloadTask.resume()
}

Step2#

Now i have url saved in my local device memory now i'll click anywhere in camera and load that local url in scene.

func addTapGestureToSceneView() {
    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(didReceiveTapGesture(_:)))
    sceneView.addGestureRecognizer(tapGestureRecognizer)
}

@objc func didReceiveTapGesture(_ sender: UITapGestureRecognizer) {
    let location = sender.location(in: sceneView)
    guard let hitTestResult = sceneView.hitTest(location, types: [.featurePoint, .estimatedHorizontalPlane]).first
        else { return }
    let results = self.sceneView.hitTest(location, types: .featurePoint)

    // 2
    guard let result = results.first else {
        return
    }
    // 3
    let translation = result.worldTransform.translation
    self.translation = translation
    anchor = ARAnchor(transform: hitTestResult.worldTransform)
    sceneView.session.add(anchor: anchor!)
}

Step3#

My ViewDidLoad function be like

override func viewDidLoad() {
    super.viewDidLoad()
    sceneView.delegate = self
    addTapGestureToSceneView()
    downloadSceneTask()
}

Step4#

Add Protocol ARSCNViewDelegate

// Getting file from local directory and load
extension ViewController: ARSCNViewDelegate {

   func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
       guard !(anchor is ARPlaneAnchor) else { return }
       if let droneNode = loadModel() {
           DispatchQueue.main.async {
               node.addChildNode(droneNode)
           }
       }
   }

   func getDocumentsDirectory() -> URL {
       let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
       let documentsDirectory = paths[0]
       return documentsDirectory

   }

   // Loads The SCNFile From The Documents Directory
   func loadModel() -> SCNNode? {
       //1. Get The Path Of The Downloaded File
       let downloadedScenePath = getDocumentsDirectory().appendingPathComponent("table.obj")
       let asset = MDLAsset(url: downloadedScenePath)
       let object = asset.object(at: 0)
       let node = SCNNode(mdlObject: object)
       //7. Add It To The Scene
       return node

    }
}

Upvotes: 1

Related Questions