【问题标题】:Can I get 3d models from web servers on Swift?我可以从 Swift 上的网络服务器获取 3d 模型吗?
【发布时间】:2017-12-30 16:50:30
【问题描述】:

我正在使用 Arkit 开发一个应用程序。我的应用程序中有很多 3D 模型,而且尺寸很大。我可以从另一台服务器(外部站点)中获取这些模型吗?我是 swift 新手,我似乎找不到从网络服务器加载 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()
    ]
}

【问题讨论】:

    标签: swift model 3d arkit


    【解决方案1】:

    你可以使用这样的 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 
    

    【讨论】:

    • 看看 zip 基础 -> github.com/weichsel/ZIPFoundation 您需要将您的 3D 模型(scn 或 dae 文件)与材料捆绑到一个 zip 文件中。将该 zip 文件设为您的目标文件 URL 链接。然后您必须处理 URL 请求、文件管理等。您将需要尝试 fileManager.unzipItem(at:destinationFileUrl!to:documentsUrl!) 之类的东西。这应该是足够的提示了。
    • 如何用不同的模型创建这种raw.githubusercontent.com/wave-electron/scnFile/master/cube.scn链接
    猜你喜欢
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 2020-08-05
    相关资源
    最近更新 更多