Как изменить файл COLLADA (.dae) на файл SceneKit (.scn) программно быстро

#swift #mobile #native #scenekit #arkit

#swift #Мобильный #родной #scenekit #arkit

Вопрос:

 COLLADA(.dae) , SceneKit(.scn)
 

Я работаю, scenekit и проблема в том, что есть администратор, который загрузит .dae файл на сервер, и я получу эту ссылку в приложении, и с помощью кода я должен показать его на камеру. При запуске приложения для .scn URL-адреса файла оно работает нормально, но для URL-адреса файла .dae оно выдает ошибку COLLADA files are not supported on this platform. , поэтому я хочу преобразовать файл .dae в файл .scn во время выполнения. Если кто-нибудь знает какой-либо другой источник, который может конвертировать .dae файл в .scn файл, пожалуйста, укажите. С помощью этого источника администратор загрузит .scn файл на сервер после конвертации.

Ответ №1:

Наконец-то решено благодаря stackoverflow с использованием концепции быстрого ввода-вывода модели

Шаг 1#

 // 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 amp; Run It
    let downloadTask = downloadSession.downloadTask(with: url)
    downloadTask.resume()
}
 

Шаг2#

Теперь у меня есть URL-адрес, сохраненный в памяти моего локального устройства, теперь я щелкну в любом месте камеры и загружу этот локальный URL-адрес в сцену.

 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!)
}
 

Шаг 3#

Моя функция viewDidLoad будет выглядеть

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

Шаг 4#

Добавить протокол 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

    }
}