Skip to content

Commit

Permalink
Add SwiftUI visionOS example. (#115)
Browse files Browse the repository at this point in the history
  • Loading branch information
halmueller authored and nicklockwood committed Jul 23, 2024
1 parent e6fbe24 commit dabe752
Show file tree
Hide file tree
Showing 16 changed files with 422 additions and 9 deletions.
207 changes: 200 additions & 7 deletions Euclid.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"layers" : [
{
"filename" : "Front.solidimagestacklayer"
},
{
"filename" : "Middle.solidimagestacklayer"
},
{
"filename" : "Back.solidimagestacklayer"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images" : [
{
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
6 changes: 6 additions & 0 deletions ExampleVisionOS/Assets.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
22 changes: 22 additions & 0 deletions ExampleVisionOS/ContentView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// ContentView.swift
// ExampleVisionOS
//
// Created by Hal Mueller on 3/5/24.
// Copyright © 2024 Nick Lockwood. All rights reserved.
//

import RealityKit
import SwiftUI

struct ContentView: View {
@State private var enlarge = false

var body: some View {
VolumetricView()
}
}

#Preview(windowStyle: .volumetric) {
ContentView()
}
26 changes: 26 additions & 0 deletions ExampleVisionOS/EuclidMesh.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// EuclidMesh.swift
// ExampleVisionOS
//
// Created by Hal Mueller on 3/5/24.
// Copyright © 2024 Nick Lockwood. All rights reserved.
//

import CoreGraphics
import Euclid

let euclidMesh: Mesh = {
let start = CFAbsoluteTimeGetCurrent()

// create some geometry using Euclid
let cube = Mesh.cube(size: 0.8, material: Color.red)
let sphere = Mesh.sphere(slices: 120, material: CGImage.checkerboard())
let mesh = cube.subtracting(sphere).makeWatertight()

print("Time:", CFAbsoluteTimeGetCurrent() - start)
print("Polygons:", mesh.polygons.count)
print("Triangles:", mesh.triangulate().polygons.count)
print("Watertight:", mesh.isWatertight)

return mesh
}()
20 changes: 20 additions & 0 deletions ExampleVisionOS/ExampleVisionOSApp.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// ExampleVisionOSApp.swift
// ExampleVisionOS
//
// Created by Hal Mueller on 3/5/24.
// Copyright © 2024 Nick Lockwood. All rights reserved.
//

import SwiftUI

@main
struct ExampleVisionOSApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.windowStyle(.volumetric)
.defaultSize(width: 1.5, height: 1.5, depth: 1.5, in: .meters)
}
}
15 changes: 15 additions & 0 deletions ExampleVisionOS/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationPreferredDefaultSceneSessionRole</key>
<string>UIWindowSceneSessionRoleVolumetricApplication</string>
<key>UIApplicationSupportsMultipleScenes</key>
<true/>
<key>UISceneConfigurations</key>
<dict/>
</dict>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
53 changes: 53 additions & 0 deletions ExampleVisionOS/VolumetricView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//
// VolumetricView.swift
// ExampleVisionOS
//
// Created by Hal Mueller on 3/6/24.
// Copyright © 2024 Nick Lockwood. All rights reserved.
//

import RealityKit
import SwiftUI

struct VolumetricView: View {
@State private var spinX = 0.0
@State private var spinY = 0.0

var body: some View {
RealityView { content in
if let demoBoxEntity = try? ModelEntity(euclidMesh.scaled(by: 0.5)) {
// for more realism, add a shadow
demoBoxEntity.components.set(GroundingShadowComponent(castsShadow: true))

// needed for tap detection/response
demoBoxEntity.generateCollisionShapes(recursive: true)

// for gesture targeting
demoBoxEntity.components.set(InputTargetComponent())

content.add(demoBoxEntity)
}
} update: { content in
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
}
.gesture(
DragGesture(minimumDistance: 0)
.targetedToAnyEntity()
.onChanged { value in
let startLocation = value.convert(value.startLocation3D, from: .local, to: .scene)
let currentLocation = value.convert(value.location3D, from: .local, to: .scene)
let delta = currentLocation - startLocation
spinX = Double(delta.y) * 5
spinY = Double(delta.x) * 5
}
)
}
}

#Preview {
VolumetricView()
}
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ Feel free to open an issue in Github if you have questions about how to use the
If you wish to contribute improvements to the documentation or the code itself, that's great! But please read the [CONTRIBUTING.md](CONTRIBUTING.md) file before submitting a pull request.


# Example
# Example and ExampleVisionOS

See the included project for an example of how Euclid can be used in conjunction with SceneKit or RealityKit to generate and render a nontrivial 3D shape on iOS.
See the included projects for examples of how Euclid can be used in conjunction with SceneKit or RealityKit to generate and render a nontrivial 3D shape. `Example` uses storyboards, is built for iOS, and runs in "Designed for iPad" mode on macOS and visionOS.
`ExampleVisionPro` uses SwiftUI and a RealityView in a volumetric window, and runs only on visionOS.


# Documentation
Expand Down

0 comments on commit dabe752

Please sign in to comment.