无法将具有UIImage纹理的SKSpriteNode加载到ARKit SCNNode中

时间:2019-05-20 11:51:23

标签: image textures arkit skspritenode scnnode

无法将具有UIImage纹理的SKSpriteNode加载到ARKit SCNNode中

不幸的是,我试图在AR WorldTracking会话中的SCNNode上显示条形码图像,但我无法使其正常工作,希望有人可以帮助我解决此问题。以下是我采取的步骤:

  1. 通过SKScene编辑器创建SpriteKit场景
  2. 在此SpriteKit场景内创建一个SpriteNode(在SKScene编辑器中),该节点将保存由条形码生成器方法创建的UIImage对象
  3. 切换到ViewController.swift,加载此SKScene并检索在第2步中创建的SpriteNode
  4. 通过条形码生成器方法返回的UIImage对象(返回UIImage)更新SpriteNode的纹理
  5. 创建一个SCNode并将该节点的Geometry.firstMaterial?.diffuse.contents设置为在步骤1中创建的SpriteKit场景
  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
    }
}

我想在SCNNode(在ARKit中)的SpriteKit场景中显示SpriteNode(以图像作为纹理)

0 个答案:

没有答案