如何从url加载ModelEntity

问题描述 投票:0回答:1

我有一个带 AR 的屏幕。目前,正在加载项目中本地存储的模型。我如何让它们从网址加载?

import SwiftUI
import RealityKit
import ARKit
import FocusEntity

struct ARScreen : View {
    
    @StateObject var ArScreenVM = ArScreenViewModel()
    
    @State private var isPlacementEnabled = false
    @State private var selectedModel = "sitdown.usdz"//: String?
    @State private var modelComfiredForPlacement: String?
    
    init() {
        let navBarAppearance = UINavigationController()
        navBarAppearance.navigationBar.largeTitleTextAttributes=[NSAttributedString.Key.foregroundColor:
        UIColor.white]
        UINavigationBar.appearance().tintColor = .black
    }
    
    
    var body: some View {
        NavigationView {
            ZStack(alignment: .bottom) {
                ARViewContainer(modelConfirmedForPlacement: self.$modelComfiredForPlacement)
                
                PlacementButtonView(isPlacementEnabled: self.$isPlacementEnabled, selectedModel: self.selectedModel, modelComfirmedForPlacement: self.$modelComfiredForPlacement)
            }.background(Color("Yellow").ignoresSafeArea())
        }.navigationBarTitle("", displayMode: .inline)
        
        
        
    }
    
    struct ARViewContainer: UIViewRepresentable {
        
        @Binding var modelConfirmedForPlacement: String?
        
        func makeUIView(context: Context) -> ARView {
            
            let arView = CustomARView(frame: .zero)//ARView(frame: .zero)
            
            
            
            return arView
            
        }
        
        func updateUIView(_ uiView: ARView, context: Context) {
                if let modelName = self.modelConfirmedForPlacement {
                    print("Debug: adding model to scene")

                    if let modelURL = URL(string: "https://developer.apple.com/augmented-reality/quick-look/models/vintagerobot2k/robot_walk_idle.usdz") {
                        switch loadModelFromURL(url: modelURL) {
                        case .success(let modelEntity):
                            let anchorEntity = AnchorEntity(plane: .any)
                            anchorEntity.addChild(modelEntity)

                            uiView.scene.addAnchor(anchorEntity)

                            modelEntity.playAnimation(modelEntity.availableAnimations[0].repeat(),
                                                          transitionDuration: 0.5,
                                                          startsPaused: false)

                            DispatchQueue.main.async {
                                self.modelConfirmedForPlacement = nil
                            }
                        case .failure(let error):
                            print("Error loading model: \(error.localizedDescription)")
                        }
                    } else {
                        print("Invalid model URL")
                    }
                }
            }

        
        func loadModelFromURL(url: URL) -> Result<ModelEntity, Error> {
                do {
                    let modelEntity = try ModelEntity.load(contentsOf: url)
                    return .success(modelEntity as! ModelEntity)
                } catch {
                    return .failure(error)
                }
            }

    }
    
    class CustomARView: ARView, FEDelegate {
        let focusSquare = FESquare()
        
        required init(frame frameRect: CGRect) {
            super.init(frame: frameRect)
            
            focusSquare.viewDelegate = self
            focusSquare.delegate = self
            focusSquare.setAutoUpdate(to: true)
        
            self.setupARView()
        }
        func setupARView() {
            let config = ARWorldTrackingConfiguration()
            config.planeDetection = [.horizontal, .vertical]
            config.environmentTexturing = .automatic
            if ARWorldTrackingConfiguration.supportsSceneReconstruction(.mesh) {
                config.sceneReconstruction = .mesh
            }
            self.session.run(config)
        }
        @MainActor required dynamic init?(coder decoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
}

struct PlacementButtonView: View {
    
    @Binding var isPlacementEnabled: Bool
    var selectedModel: String?
    @Binding var modelComfirmedForPlacement: String?
    
    var body: some View {
        Button(action: {
            print("Debug: Confirm model")
            self.modelComfirmedForPlacement = self.selectedModel
        }) {
            Image(systemName: "checkmark")
                .frame(width: 60, height: 60)
                .font(.title)
                .background(Color.white.opacity(0.75))
                .cornerRadius(30)
                .padding(20)
        }
    }
}

#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ARScreen()
    }
}
#endif

我尝试了很多方法来解决这个问题,这是我最近关于这个主题的问题:ModelEntity.load from url,但是所有使用这个库加载模型的尝试都失败了

ios swift swiftui augmented-reality usdz
1个回答
0
投票

目前很多人在使用 Vision OS 时也遇到这个问题。

ModelEntity
没有从 URL 加载的内置功能。对于 Vision OS,有
Model3D
。那么,最好的方法是将模型托管在远程服务器上。

我个人推荐Halocline,它是免费且易于使用的,但请注意我是附属的。

您可以轻松上传模型并直接使用您的链接。

只需下载在学习页面上找到的脚本,您就可以将其与 Halocline 或其他提供商一起使用。

那么就简单了,如下代码:

let halocline = HaloclineHelper()
let url = URL(string: "your-halocline-url")!
let modelEntity = try await halocline.loadEntity(from: url)
© www.soinside.com 2019 - 2024. All rights reserved.