Не удалось загрузить SKSpriteNode с текстурой UIImage в ARKit SCNNode - PullRequest
0 голосов
/ 20 мая 2019

Не удалось загрузить SKSpriteNode с текстурой UIImage в ARKit SCNNode

Я пытаюсь отобразить изображение штрих-кода на SCNNode, находящемся в сеансе AR WorldTracking, к сожалению, я просто не могу заставить его работать и надеюсь, что кто-то может помочь мне решить эту проблему. Ниже приведен список шагов, которые я предпринял:

  1. создание сцены SpriteKit через редактор SKScene
  2. создайте SpriteNode внутри этой сцены SpriteKit (в редакторе SKScene), этот узел будет содержать объект UIImage, созданный методом генератора штрих-кода
  3. переключиться на ViewController.swift, загрузить этот SKScene и извлечь SpriteNode, созданный в шаге-2
  4. обновить текстуру SpriteNode с помощью объекта UIImage, возвращаемого методом генератора штрих-кода (который возвращает UIImage)
  5. создайте SCNode и задайте для Geometry.firstMaterial? .Diffuse.contents этого узла сцену SpriteKit, созданную в шаге-1
  6. добавить этот SCNNode в sceneView.scene.rootNode

В целях отладки я также создал UIImageView на главном экране и загрузил изображение штрих-кода, чтобы я мог сказать, было ли создано изображение штрих-кода

Результат: штрих-код отображается в UIImageView правильно, но не в SCNNode. Исходные коды ViewController.swift перечислены ниже. Может ли кто-нибудь просмотреть мои коды и сообщить, почему я не могу правильно отобразить штрих-код в сеансе AR и как я могу исправить эту программу? Большое спасибо.

import UIKit
import SceneKit
import ARKit

class ViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!

    @IBOutlet weak var barcodeView: UIImageView!


    override func viewDidLoad() {
        super.viewDidLoad()

        // Set the view's delegate
        sceneView.delegate = self

        // Show statistics such as fps and timing information
        sceneView.showsStatistics = true

        // Create a new scene
        let scene = SCNScene()

        // Set the scene to the view
        sceneView.scene = scene

        loadBarcode()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Create a session configuration
        let configuration = ARWorldTrackingConfiguration()

        // Run the view's session
        sceneView.session.run(configuration)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        // Pause the view's session
        sceneView.session.pause()
    }

    // MARK: - ARSCNViewDelegate

/*
    // Override to create and configure nodes for anchors added to the view's session.
    func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
        let node = SCNNode()

        return node
    }
*/

    func session(_ session: ARSession, didFailWithError error: Error) {
        // Present an error message to the user

    }

    func sessionWasInterrupted(_ session: ARSession) {
        // Inform the user that the session has been interrupted, for example, by presenting an overlay

    }

    func sessionInterruptionEnded(_ session: ARSession) {
        // Reset tracking and/or remove existing anchors if consistent tracking is required

    }

    func loadBarcode() {
        guard let barcodeScene = SKScene(fileNamed: "art.scnassets/barcodeSKScene.sks") else {
            fatalError("failed to load barcodeSKScene.sks from project")
        }
        guard let barcodeNode = barcodeScene.childNode(withName: "barcodeSKNode") as! SKSpriteNode? else {
            fatalError("failed to get barcode node from SKScene")
        }
        guard let barcodeImage = getBarcodeImage() else {
            fatalError("failed to get barcode")
        }
        barcodeNode.texture = SKTexture(image:barcodeImage )
        let planeGeometry = SCNPlane(width: 0.5, height: 0.3)
        planeGeometry.firstMaterial?.diffuse.contents = barcodeScene
        let planeNode = SCNNode(geometry: planeGeometry)
        planeNode.position = SCNVector3(x: 0, y: 0, z: -2.0)
        sceneView.scene.rootNode.addChildNode(planeNode)
        barcodeView.image = barcodeImage
    }

    func getBarcodeImage() -> UIImage? {
        return generateBarcode(from: "A0123456789")
    }

    func generateBarcode(from string: String) -> UIImage? {
        let data = string.data(using: String.Encoding.ascii)

        if let filter = CIFilter(name: "CICode128BarcodeGenerator") {
            filter.setValue(data, forKey: "inputMessage")
            let transform = CGAffineTransform(scaleX: 3, y: 3)

            if let output = filter.outputImage?.transformed(by: transform) {
                return UIImage(ciImage: output)
            }
        }

        return nil
    }
}

Я хочу отобразить SpriteNode (с изображением в качестве текстуры) в сцене SpriteKit на SCNNode (в ARKit)

...