我可以在Swift上从Web服务器获取3D模型吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我可以在Swift上从Web服务器获取3D模型吗?相关的知识,希望对你有一定的参考价值。

我正在和Arkit一起申请。有很多3D模型,我的应用程序的大小很大。我可以从其他服务器(外部站点)获取这些模型吗?我是swift的新手,我似乎无法从Web服务器上加载3d模型。

是否足以改变那里的模型路径?谢谢

func loadModel() {
    guard let virtualObjectScene = SCNScene(named: "(modelName).(fileExtension)", inDirectory: "Models.scnassets/(modelName)") else {
        return
    }

    let wrapperNode = SCNNode()

    for child in virtualObjectScene.rootNode.childNodes {

        let defaults = UserDefaults.standard
        wrapperNode.addChildNode(child)
    }
    self.addChildNode(wrapperNode)
}

所有代码:

import UIKit
import SceneKit
import ARKit

class VirtualObject: SCNNode {

    var modelName: String = ""
    var fileExtension: String = ""
    var thumbImage: UIImage!
    var title: String = ""

    var viewController: ViewController?

    override init() {
        super.init()
        self.name = "Virtual object root node"
    }

    init(modelName: String, fileExtension: String, thumbImageFilename: String, title: String) {
        super.init()
        self.name = "Virtual object root node"
        self.modelName = modelName
        self.fileExtension = fileExtension
        self.thumbImage = UIImage(named: thumbImageFilename)
        self.title = title
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func loadModel() {
        guard let virtualObjectScene = SCNScene(named: "(modelName).(fileExtension)", inDirectory: "Models.scnassets/(modelName)") else {
            return
        }

        let wrapperNode = SCNNode()

        for child in virtualObjectScene.rootNode.childNodes {

            let defaults = UserDefaults.standard
            wrapperNode.addChildNode(child)
        }
        self.addChildNode(wrapperNode)
    }

    func unloadModel() {
        self.removeFromParentNode()
        for child in self.childNodes {
                child.removeFromParentNode()
        }
    }

    func translateBasedOnScreenPos(_ pos: CGPoint, instantly: Bool, infinitePlane: Bool) {

        guard let controller = viewController else {
            return
        }

        let result = controller.worldPositionFromScreenPosition(pos, objectPos: self.position, infinitePlane: infinitePlane)

        controller.moveVirtualObjectToPosition(result.position, instantly, !result.hitAPlane)
    }
}

extension VirtualObject {

    static func isNodePartOfVirtualObject(_ node: SCNNode) -> Bool {
        if node.name == "Virtual object root node" {
            return true
        }

        if node.parent != nil {
            return isNodePartOfVirtualObject(node.parent!)
        }

        return false
    }

    static let availableObjects: [VirtualObject] = [
        Anatomy()
    ]
}
答案

你可以用这样的ip地址从网络服务器加载一个scn文件(我在下面使用假ip)

let myURL = NSURL(string: “http://110.151.153.202:80/scnfiles/myfile.scn”)

let scene = try! SCNScene(url: myURL! as URL, options:nil)

编辑:

这是一个简单的Swift PlayGrounds,它从我的github仓库中提取测试多维数据集scn文件。您只需点按任意位置即可加载立方体。

import ARKit
import SceneKit
import PlaygroundSupport

class ViewController: NSObject {

      var sceneView: ARSCNView
      init(sceneView: ARSCNView) {
      self.sceneView = sceneView

      super.init()

      self.setupWorldTracking()
      self.sceneView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(ViewController.handleTap(_:))))

}

private func setupWorldTracking() {
    if ARWorldTrackingConfiguration.isSupported {
        let configuration = ARWorldTrackingConfiguration()
        configuration.planeDetection = .horizontal
        configuration.isLightEstimationEnabled = true
        self.sceneView.session.run(configuration, options: [])
    }
}

@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
    }

    // pulls cube.scn from github repo

    let myURL = NSURL(string: "https://raw.githubusercontent.com/wave-electron/scnFile/master/cube.scn")
    let scene = try! SCNScene(url: myURL! as URL, options: nil)
    let node = scene.rootNode.childNode(withName: "SketchUp", recursively: true)
    node?.scale = SCNVector3(0.01,0.01,0.01)

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

 }
}

let sceneView = ARSCNView()

let viewController = ViewController(sceneView: sceneView)
sceneView.autoenablesDefaultLighting = true
PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = viewController.sceneView 

以上是关于我可以在Swift上从Web服务器获取3D模型吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 swift 4 上从 didFinishLaunchingWithOptions 获取通知中心数据

3D可以打开.dae文件吗?

如何3d模型在web网页显示展示?用啥技术

为啥我在 iOS 上从 Swift 调用服务时收到 SSL 错误?

如何在 swift4 上从服务器播放 mp3 声音?

在 Swift 上从 URL 加载/下载图像