Как загрузить модель и текстуры с удаленного сервера, используя ARKit? - PullRequest
0 голосов
/ 08 мая 2019

Я работаю над приложением ARKit, использующим Swift в XCode, пытаюсь загрузить модели с удаленного сервера, но у меня проблема с получением модели и текстур / материалов для загрузки вместе и корректным отображением текстур / материалов.

Я просмотрел несколько ссылок и учебных пособий и загрузил модель, но материалы не отображаются. Я создал модели в редакторе сцены или загрузил их и преобразовал в файлы .scn, нашел их в Finder и затем загрузил на веб-сервер. Только файл .scn и материал (изображения).

//Tap Gesture 
@objc func handleTap(_ gesture: UITapGestureRecognizer) {

    //hittest
    let results = self.sceneView.hitTest(gesture.location(in: gesture.view), types: ARHitTestResult.ResultType.featurePoint)

    //return first tap
    guard let result: ARHitTestResult = results.first else {
        return
    }

    //Set URL of location of model
    let myURL = NSURL(string: "https://www.website.com/scnfiles/iPhoneX.scn")

    //Try getting this url or return 
    guard let scene = try? SCNScene(url: myURL! as URL, options: nil) else {return}

    //Set the node to be the model
    let node = scene.rootNode.childNode(withName: "SketchUp", recursively: true)

    //Set scale
    node?.scale = SCNVector3(0.025,0.025,0.025)

    //The material image is located in the same directory
    node?.geometry?.firstMaterial?.diffuse.contents = UIImage(named: "https://website/scnfiles/iPhoneX_Screen.jpg")

    //set the position of the model
    let position = SCNVector3Make(result.worldTransform.columns.3.x, result.worldTransform.columns.3.y, result.worldTransform.columns.3.z)
        node?.position = position

    //Add to scene
    self.sceneView.scene.rootNode.addChildNode(node!)
}

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

Я получаю следующую ошибку, которая выглядит так, будто она пытается загрузить его локально?

ARKitModels[10386:3406637] [SceneKit] Error: Failed to load : <C3DImage 0x281e45180 src:file:///var/containers/Bundle/Application/233AE78F-748F-420B-96AD-30F591ADF80C/ARKitModels.app/material/iPhoneX_Screen.jpg [0.000000x0.000000]>

Любая помощь приветствуется, и если есть лучший способ сделать это, пожалуйста, дайте мне знать. Спасибо!

Ответы [ 2 ]

0 голосов
/ 08 мая 2019

Итак, так как я хочу загрузить все с удаленного сервера, ничего локального здесь нет, это то, что я придумала благодаря некоторой помощи @ ATV.

Решение: зацикливание дочерних узлов и установка текстуры нато же имя, что и имя узла.Вы можете установить имя узла в редакторе сцены, а затем иметь те же именованные файлы изображений в соответствующей папке.Это позволяет для динамической загрузки.Это работает, только если у вас есть контроль над моделями / сервером или есть четкие инструкции.

@objc func handleTap(_ gesture: UITapGestureRecognizer) {
        let results = self.sceneView.hitTest(gesture.location(in: gesture.view), types: ARHitTestResult.ResultType.featurePoint)
        guard let result: ARHitTestResult = results.first else {
            return
        }
        let myURL = NSURL(string: "https://www.website.com/scnfiles/model/model.scn")

        guard let scene = try? SCNScene(url: myURL! as URL, options: nil) else {return}

        let node = scene.rootNode.childNode(withName: "SketchUp", recursively: true)

        //Solution//
        let children = (node?.childNodes)!
        for child in children {
            child.geometry?.materials.forEach{$0.diffuse.contents = "https://www.website.com/scnfiles/model/materials/" + child.name! + ".jpg"
        }

        node?.scale = SCNVector3(0.025,0.025,0.025)

        let position = SCNVector3Make(result.worldTransform.columns.3.x, result.worldTransform.columns.3.y, result.worldTransform.columns.3.z)
        node?.position = position
        self.sceneView.scene.rootNode.addChildNode(node!)

    }
0 голосов
/ 08 мая 2019

Попробуйте установить предварительно загруженный UIImage в качестве содержимого для всех материалов из вашей геометрии.Что-то вроде:

geometry.materials.forEach{$0.diffuse.contents = textureImage}
...