如何设置visionOS中Volumetric窗口默认尺寸以适配下载的USDZ模型
解决visionOS中USDZ模型在Volumetric窗口的适配问题
核心思路
AR Quick Look会自动处理模型的单位转换、缩放和居中,而手动用RealityKit加载时需要手动计算模型边界,调整缩放、位置,并匹配窗口尺寸。
具体实现步骤
1. 加载USDZ模型并处理单位转换
加载模型后,先统一单位(RealityKit默认以米为单位,多数USDZ模型用厘米制作,需转换):
func loadAndPrepareModel(from url: URL) async throws -> ModelEntity { let entity = try await Entity.load(contentsOf: url) guard let modelEntity = entity as? ModelEntity else { throw NSError(domain: "ModelError", code: 0, userInfo: [NSLocalizedDescriptionKey: "无效的模型类型"]) } // 厘米转米,若模型本身是米单位可注释此行 modelEntity.scale = SIMD3<Float>(0.01, 0.01, 0.01) return modelEntity }
2. 计算适配窗口的缩放比例
根据模型尺寸和目标窗口空间,计算缩放因子确保模型完整放入窗口:
let modelEntity = try await loadAndPrepareModel(from: downloadedURL) let modelBounds = modelEntity.bounds let modelSize = modelBounds.extents // 定义Volumetric窗口的目标尺寸(可根据需求调整) let targetWindowSize = SIMD3<Float>(1.2, 0.8, 0.6) // 取各维度缩放比例的最小值,保证模型完全适配窗口 let scaleX = targetWindowSize.x / modelSize.x let scaleY = targetWindowSize.y / modelSize.y let scaleZ = targetWindowSize.z / modelSize.z let scaleFactor = min(scaleX, scaleY, scaleZ) // 应用缩放 modelEntity.scale *= SIMD3<Float>(scaleFactor, scaleFactor, scaleFactor)
3. 调整模型位置使其居中
将模型中心与窗口中心对齐:
let scaledBounds = modelEntity.bounds // 窗口中心在(0,0,0),模型位置设为负的边界中心即可居中 modelEntity.position = -scaledBounds.center
4. 设置Volumetric窗口尺寸
打开窗口时传递目标尺寸,在WindowGroup中配置窗口参数:
// 打开窗口时传入目标尺寸 openWindow(id: "VolumetricModel", value: targetWindowSize) // 对应的Volumetric窗口定义 WindowGroup(id: "VolumetricModel") { (size: SIMD3<Float>) in RealityView { content in let modelEntity = try await loadAndPrepareModel(from: downloadedURL) // 重新计算缩放与居中(确保窗口尺寸匹配) let modelBounds = modelEntity.bounds let modelSize = modelBounds.extents let scaleX = size.x / modelSize.x let scaleY = size.y / modelSize.y let scaleZ = size.z / modelSize.z let scaleFactor = min(scaleX, scaleY, scaleZ) modelEntity.scale *= SIMD3<Float>(scaleFactor, scaleFactor, scaleFactor) let scaledBounds = modelEntity.bounds modelEntity.position = -scaledBounds.center content.add(modelEntity) } .windowStyle(.volumetric) .defaultSize(CGSize( width: CGFloat(size.x), height: CGFloat(size.y), depth: CGFloat(size.z) )) }
额外注意事项
- 单位校验:若模型显示异常,先确认原始单位,避免因单位不匹配导致尺寸错误。
- 边界更新:缩放或旋转模型后,需重新获取
bounds,避免使用旧的边界数据。 - 窗口限制:visionOS的Volumetric窗口最大尺寸约为2x2x2米,不要设置超出此范围的尺寸。
内容的提问来源于stack exchange,提问作者Sadao Tokuyama
相关产品推荐
相关产品推荐

