diff --git a/ExampleVisionOS/EuclidMesh.swift b/ExampleVisionOS/EuclidMesh.swift index 7ee0a3c7..d7649fcc 100644 --- a/ExampleVisionOS/EuclidMesh.swift +++ b/ExampleVisionOS/EuclidMesh.swift @@ -22,7 +22,8 @@ let euclidMesh: Mesh = { print("Triangles:", mesh.triangulate().polygons.count) print("Watertight:", mesh.isWatertight) - sleep(5) // simulate long-running task + // Sleep here to simulate a long-running mesh construction. + sleep(5) return mesh }() diff --git a/ExampleVisionOS/MeshViewModel.swift b/ExampleVisionOS/MeshViewModel.swift index a2951016..29f71528 100644 --- a/ExampleVisionOS/MeshViewModel.swift +++ b/ExampleVisionOS/MeshViewModel.swift @@ -10,28 +10,33 @@ import CoreGraphics import Euclid import RealityKit +/// Holds an Entity built from a Euclid Mesh, plus state for the VolumetricView. @Observable class MeshViewModel: ObservableObject { + /// The Euclid mesh's Entity lands here. public var entity: Entity? = nil - public var status = false + /// Euclid has finished preparing the content. + public var contentReady = false + /// The RealityView instance has added the content. + public var contentAdded = false - func prepareContent() { + func prepareContent() { Task.init { do { - let demoBoxEntity = try await ModelEntity(euclidMesh.scaled(by: 0.5))// { - + let demoBoxEntity = try await ModelEntity(euclidMesh.scaled(by: 0.5)) + // for more realism, add a shadow await demoBoxEntity.components.set(GroundingShadowComponent(castsShadow: true)) - + // needed for tap detection/response await demoBoxEntity.generateCollisionShapes(recursive: true) - + // for gesture targeting await demoBoxEntity.components.set(InputTargetComponent()) - + print(#function, "complete") entity = demoBoxEntity - status = true + contentReady = true } catch { print("nope") } diff --git a/ExampleVisionOS/VolumetricView.swift b/ExampleVisionOS/VolumetricView.swift index 94ab3d17..6e6eff3a 100644 --- a/ExampleVisionOS/VolumetricView.swift +++ b/ExampleVisionOS/VolumetricView.swift @@ -14,23 +14,27 @@ struct VolumetricView: View { @State private var spinY = 0.0 private var viewModel = MeshViewModel() - @State private var contentAdded = false - + var body: some View { let _ = Self._printChanges() RealityView { content in + // In this demo we'll skip adding content at init time. But if you have other content + // that you want visible while the EuclidMesh is being built, add it in this closure. + // A simulated expensive, long-running Mesh generation happens on its own Task. + debugPrint(content) } update: { content in - if !contentAdded, - let box = viewModel.entity { + if viewModel.contentReady, + !viewModel.contentAdded, + let box = viewModel.entity + { content.add(box) - contentAdded = true + viewModel.contentAdded = true } - print(content.entities) guard let entity = content.entities.first else { return } - + let pitch = Transform(pitch: Float(spinX * -1)).matrix let yaw = Transform(yaw: Float(spinY)).matrix entity.transform.matrix = pitch * yaw @@ -49,9 +53,9 @@ struct VolumetricView: View { .task { viewModel.prepareContent() print("content preparation launched...") - } } } +} #Preview { VolumetricView()