Skip to content

Commit

Permalink
Merge pull request #15 from maxxfrazer/new-example
Browse files Browse the repository at this point in the history
New Example Project
  • Loading branch information
maxxfrazer committed Apr 11, 2023
2 parents 0ab8a07 + 4fd66e0 commit 041d7a9
Show file tree
Hide file tree
Showing 29 changed files with 715 additions and 993 deletions.
2 changes: 1 addition & 1 deletion .swiftlint.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
line_length:
ignores_comments: true
excluded:
- RealityUI+Examples
- RealityUI+Example
397 changes: 397 additions & 0 deletions RealityUI+Example/RealityUI+Example.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

140 changes: 140 additions & 0 deletions RealityUI+Example/RealityUI+Example/ARViewContainer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
//
// ARViewContainer.swift
// RealityUI+Example
//
// Created by Max Cobb on 10/04/2023.
//

import Foundation
import RealityKit
import SwiftUI
import RealityUI
#if os(macOS)
typealias UIViewRepresentable = NSViewRepresentable
#endif

struct ARViewContainer: UIViewRepresentable {
func makeNSView(context: Context) -> ARView {
self.makeUIView(context: context)
}

func updateNSView(_ nsView: ARView, context: Context) {
updateUIView(nsView, context: context)
}

typealias NSViewType = ARView


@Binding var objectType: RealityObject
/// Stepper tally will be displayed at the top of the view when `RUIStepper` is visible.
@Binding var stepperTally: Int
@State fileprivate var prevObjectType: RealityObject? = nil
func makeUIView(context: Context) -> ARView {
// Create an ARView
let arView = ARView(frame: .zero)
#if os(iOS)
arView.cameraMode = .nonAR
#endif

// Add the anchor to the scene
let anchor = AnchorEntity(world: .zero)
arView.scene.addAnchor(anchor)

// Setup RealityKit camera
let cam = PerspectiveCamera()
cam.look(at: .zero, from: [0, 0, -2.5], relativeTo: nil)
anchor.addChild(cam)

self.setModel(view: arView)
RealityUI.enableGestures(.all, on: arView)
return arView
}

/// Update the model in the scene depending on ``objectType``
/// - Parameter view: The `ARView` being displayed.
func setModel(view: ARView) {
guard let worldAnchor = view.scene.anchors.first,
prevObjectType != objectType else { return }
if let oldRui = view.scene.findEntity(named: "ruiReplace") {
worldAnchor.removeChild(oldRui)
}
view.environment.background = .color(.gray)
let ruiModel: Entity
switch objectType {
case .toggle:
ruiModel = RUISwitch(switchCallback: { hasSwitch in
view.environment.background = .color(hasSwitch.isOn ? .green : .gray)
})
case .slider:
let scalingCube = ModelEntity(mesh: .generateBox(size: 3))
scalingCube.position.z = 3
ruiModel = RUISlider(start: 0.5) { slider, state in
scalingCube.scale = .one * (slider.value + 0.2) / 1.2
}
ruiModel.addChild(scalingCube)
ruiModel.scale = .init(repeating: 0.3)
scalingCube.scale = .one * ((ruiModel as! HasSlider).value + 0.2) / 1.2
case .stepper:
ruiModel = RUIStepper { _ in
stepperTally += 1
} downTrigger: { _ in
stepperTally -= 1
}
case .button:
ruiModel = RUIButton(
rui: RUIComponent(respondsToLighting: true)
) { button in
button.ruiShake(by: .init(angle: .pi / 16, axis: [0, 0, 1]), period: 0.05, times: 3)
}
ruiModel.look(at: [0, 1, -1], from: .zero, relativeTo: nil)
case .rotation:
ruiModel = RotationPlane(turnAxis: [0, 0, 1])
ruiModel.scale = .one * 2
}
ruiModel.name = "ruiReplace"
worldAnchor.addChild(ruiModel)
DispatchQueue.main.async {
prevObjectType = objectType
}
}

func updateUIView(_ uiView: ARView, context: Context) {
setModel(view: uiView)
}
}

/// Class for demonstrating the HasTurnTouch protocol.
class RotationPlane: Entity, HasModel, HasCollision, HasTurnTouch {

/// Create a new ``RotationPlane``, which conforms to HasTurnTouch
/// - Parameter turnAxis: Axis that the object will be rotated around.
required init(turnAxis: SIMD3<Float>) {
super.init()
self.turnAxis = turnAxis
var rotateMat = SimpleMaterial()
rotateMat.color = SimpleMaterial.BaseColor(
tint: .white.withAlphaComponent(0.99), texture: MaterialParameters.Texture(
try! TextureResource.load(named: "rotato")
)
)
self.model = ModelComponent(mesh: .generatePlane(width: 1, height: 1), materials: [rotateMat])
self.orientation = .init(angle: .pi, axis: [0, 1, 0])
self.collision = CollisionComponent(shapes: [.generateBox(width: 1, height: 1, depth: 0.1)])
}

@MainActor required init() {
fatalError("init() has not been implemented")
}
}

extension ARViewContainer {
func switchAction(switch: HasSwitch) {

}
}

struct ARViewContainer_Previews: PreviewProvider {
static var previews: some View {
ARViewContainer(objectType: .constant(.toggle), stepperTally: .constant(0))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"images" : [
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
49 changes: 49 additions & 0 deletions RealityUI+Example/RealityUI+Example/ContentView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// ContentView.swift
// RealityUI+Example
//
// Created by Max Cobb on 10/04/2023.
//

import SwiftUI

/// An enum object that will determine which 3D model to display
public enum RealityObject: String, CaseIterable {
case toggle
case slider
case stepper
case button
case rotation
}

struct ContentView: View {
/// 3D RealityUI object that is displayed
@State var displayObject: RealityObject = .toggle
@State var stepperTally = 0
var body: some View {
VStack {
ARViewContainer(
objectType: $displayObject, stepperTally: $stepperTally
).overlay {
if self.displayObject == .stepper {
VStack {
Text("Stepper Count: \(stepperTally)")
Spacer()
}
}
}
Picker("RealityUI Object", selection: $displayObject) {
ForEach(RealityObject.allCases, id: \.self) { val in
Text(val.rawValue).tag(val)
}
}.pickerStyle(SegmentedPickerStyle())
}
.padding()
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
10 changes: 10 additions & 0 deletions RealityUI+Example/RealityUI+Example/RealityUI_Example.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?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>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
</dict>
</plist>
17 changes: 17 additions & 0 deletions RealityUI+Example/RealityUI+Example/RealityUI_ExampleApp.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// RealityUI_ExampleApp.swift
// RealityUI+Example
//
// Created by Max Cobb on 10/04/2023.
//

import SwiftUI

@main
struct RealityUI_ExampleApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
5 changes: 5 additions & 0 deletions RealityUI+Example/RealityUI-Example-Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?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/>
</plist>
Loading

0 comments on commit 041d7a9

Please sign in to comment.