1

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.

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
Ryan Aluvihare
  • 225
  • 1
  • 2
  • 9

1 Answers1

1

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()
    }
}
Andy Jazz
  • 49,178
  • 17
  • 136
  • 220