导入 USDZ 并在运行时单独处理每个表面的材质

huangapple go评论46阅读模式
英文:

Import USDZ and manipulate materials for each surface separately at runtime

问题

基本上,我的需求是导入一个 usdz,例如一辆汽车。然后为每个车身部分应用不同的材质。例如,将材质 A 应用于车身,将材质 B 应用于侧镜,将材质 C 应用于轮毂等。

我可以遍历 ModelEntity 的 ModelComponent 中的材质,并按如下方式分配材质。

func updateUIView(_ uiView: ARView, context: Context) {

    let entity = try! Entity.loadModel(named: "CarScene")
    
    var material = PhysicallyBasedMaterial()
    material.baseColor = PhysicallyBasedMaterial.BaseColor(tint:.red)
    material.roughness = PhysicallyBasedMaterial.Roughness(floatLiteral: 0.0)
    material.metallic = PhysicallyBasedMaterial.Metallic(floatLiteral: 1.0)
  
    for i in 0...(entity.model?.materials.count ?? 1) - 1 {
        entity.model?.materials[i] = material
    }
    
    let anchor = AnchorEntity(plane: .horizontal)
    anchor.addChild(entity)

    uiView.scene.addAnchor(carAnchor)
}

但是,我不知道哪个材质对应哪个部分。如果我有多个 usdz 文件,我希望能够准确地为每个车身部分分配材质。这是否可行?

我是否需要在导入到我的 Xcode 项目之前分解 usdz 模型并分配标识符?任何帮助将不胜感激。

英文:

Basically, my requirement is to import a usdz, for an example, a car. Then apply different materials for each body part. Eg: material A to body, material B to side mirrors, material C to wheels etc.

I could iterate through the materials in the ModelEntity's ModelComponent and assign material as below.

func updateUIView(_ uiView: ARView, context: Context) {

    let entity = try! Entity.loadModel(named: "CarScene")
    
    var material = PhysicallyBasedMaterial()
    material.baseColor = PhysicallyBasedMaterial.BaseColor(tint:.red)
    material.roughness = PhysicallyBasedMaterial.Roughness(floatLiteral: 0.0)
    material.metallic = PhysicallyBasedMaterial.Metallic(floatLiteral: 1.0)
  
    for i in 0...(entity.model?.materials.count ?? 1) - 1 {
        entity.model?.materials[i] = material
    }
    
    let anchor = AnchorEntity(plane: .horizontal)
    anchor.addChild(entity)

    uiView.scene.addAnchor(carAnchor)
}

But, I don't know which material is which. If I have multiple usdz files, I want to be able to accurately assign materials for each body part. Is that doable?

Do I need to break the usdz model and assign identifiers before importing to my Xcode project? Any help would be really appreciated.

答案1

得分: 1

以下是代码的翻译部分:

使用以下示例代码,它展示了如何在运行时修改材料:

import SwiftUI
import RealityKit

struct ARViewContainer: UIViewRepresentable {
    
    let arView = ARView(frame: .zero)
    let fiat = try! Entity.load(named: "Fiat_Uno")
    
    func makeUIView(context: Context) -> ARView {
        print(fiat)
        fiat.scale /= 5
        fiat.orientation = .init(angle: .pi/1.5, axis: [0,1,0])
        let anchor = AnchorEntity()
        anchor.addChild(fiat)
        arView.scene.anchors.append(anchor)
        return arView
    }
    func updateUIView(_ view: ARView, context: Context) {

        DispatchQueue.main.asyncAfter(deadline: .now() + 0.75) {
            let wheels = fiat.findEntity(named: "Rodas_Material_001_0")?
                                              .children[0] as? ModelEntity
            wheels?.model?.materials[0] = UnlitMaterial(color: .green)
            
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.75) {
                let body = fiat.findEntity(named: "Fiat_UNO_Material_001_0")?
                                            .children[0] as? ModelEntity
                body?.model?.materials[0] = UnlitMaterial(color: .blue)
                
            }
        }
    }
}

struct ContentView : View {
    var body: some View {
        ARViewContainer().ignoresSafeArea()
    }
}

希望这些翻译对你有所帮助。如果你有任何其他问题,请随时提出。

英文:

Use the following sample code which shows you how to modify materials at runtime:

import SwiftUI
import RealityKit

struct ARViewContainer: UIViewRepresentable {
    
    let arView = ARView(frame: .zero)
    let fiat = try! Entity.load(named: "Fiat_Uno")
    
    func makeUIView(context: Context) -> ARView {
        print(fiat)
        fiat.scale /= 5
        fiat.orientation = .init(angle: .pi/1.5, axis: [0,1,0])
        let anchor = AnchorEntity()
        anchor.addChild(fiat)
        arView.scene.anchors.append(anchor)
        return arView
    }
    func updateUIView(_ view: ARView, context: Context) {

        DispatchQueue.main.asyncAfter(deadline: .now() + 0.75) {
            let wheels = fiat.findEntity(named: "Rodas_Material_001_0")?
                                              .children[0] as? ModelEntity
            wheels?.model?.materials[0] = UnlitMaterial(color: .green)
            
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.75) {
                let body = fiat.findEntity(named: "Fiat_UNO_Material_001_0")?
                                                .children[0] as? ModelEntity
                body?.model?.materials[0] = UnlitMaterial(color: .blue)
                
            }
        }
    }
}

struct ContentView : View {
    var body: some View {
        ARViewContainer().ignoresSafeArea()
    }
}

huangapple
  • 本文由 发表于 2023年2月19日 20:27:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75500138.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定