iOS/macCatalyst中如何获取USD/USDZ模型的metersPerUnit值?
获取USD/USDZ模型的metersPerUnit值解决方案
你遇到的SCNSceneSource.getProperty(forKey: SCNSceneSourceAssetUnitKey)始终返回nil的问题,是因为该API对USD/USDZ等格式的元数据提取支持不完善。正确的做法是使用ModelIO框架的MDLAsset来读取单位信息,它对USD规范的支持更完整。
核心解决方案代码
直接通过MDLAsset获取模型的metersPerUnit值:
import ModelIO func retrieveMetersPerUnit(from modelURL: URL) -> Float { let asset = MDLAsset(url: modelURL) // 若模型未指定metersPerUnit,默认返回0.01(符合Pixar USD规范) return asset.metersPerUnit }
结合SceneKit加载的完整实现
将获取到的单位值传入SceneKit的加载选项,实现正确的单位转换:
do { var loadOptions: [SCNSceneSource.LoadingOption : Any] = [ .animationImportPolicy: SCNSceneSource.AnimationImportPolicy.doNotPlay ] // 用ModelIO读取单位信息 let mdlAsset = MDLAsset(url: url) let metersPerUnit = mdlAsset.metersPerUnit loadOptions[.convertUnitsToMeters] = NSNumber(value: metersPerUnit) if let sceneSource = SCNSceneSource(url: url) { let scene = try sceneSource.scene(options: loadOptions) // 后续处理加载完成的SceneKit场景 } } catch { throw NSError(domain: "OurApp", code: 0, userInfo: [NSLocalizedDescriptionKey: "Model \(url.lastPathComponent) cannot be loaded"]) }
关键说明
MDLAsset.metersPerUnit会直接返回模型中定义的单位转换值,比如通过RealityConverter或usdconvert设置的自定义值;如果模型未指定,会自动返回USD规范的默认值0.01(即1单位=1厘米)。- 相比
SCNSceneSource,ModelIO作为Apple处理3D资产的底层框架,对USD、USDZ等格式的元数据解析更准确,能覆盖你遇到的各种自定义单位场景。
内容的提问来源于stack exchange,提问作者LenK
相关产品推荐
相关产品推荐

