Skip to content

Commit

Permalink
Merge pull request #23 from maxxfrazer/drag-gesture-component/issue19
Browse files Browse the repository at this point in the history
Drag gesture component/issue19
  • Loading branch information
maxxfrazer authored Nov 22, 2023
2 parents e8d6ec8 + c9ee20d commit e7fab33
Show file tree
Hide file tree
Showing 44 changed files with 1,398 additions and 960 deletions.
10 changes: 6 additions & 4 deletions .github/workflows/build-docc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ jobs:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: macos-12
runs-on: macos-13
steps:
- name: Checkout 🛎️
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Switch Xcode 🔄
run: sudo xcode-select --switch /Applications/Xcode_15.0.app
- name: Build DocC
run: |
xcodebuild docbuild -scheme RealityUI -derivedDataPath /tmp/docbuild -destination 'generic/platform=iOS';
Expand All @@ -36,10 +38,10 @@ jobs:
--output-path docs;
echo "<script>window.location.href += \"/documentation/realityui\"</script>" > docs/index.html
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
uses: actions/upload-pages-artifact@v2
with:
# Upload docs directory
path: 'docs'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1
uses: actions/deploy-pages@v2
21 changes: 13 additions & 8 deletions .github/workflows/swift-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,21 @@ on:

jobs:
build:
runs-on: macOS-12
runs-on: macOS-13
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Switch Xcode 🔄
run: sudo xcode-select --switch /Applications/Xcode_15.0.app
- name: Swift Lint
run: swiftlint --strict
- name: Test iOS
run: |
xcodebuild build -scheme RealityUI -destination "platform=iOS Simulator,name=iPhone 14" | xcpretty
run: xcodebuild test -scheme RealityUI -destination "platform=iOS Simulator,name=iPhone 15" -enableCodeCoverage YES
- name: Fetch Coverage
uses: sersoft-gmbh/swift-coverage-action@v4
id: coverage-files
- name: Publish Coverage to Codecov
uses: codecov/codecov-action@v3
with:
files: ${{ join(fromJSON(steps.coverage-files.outputs.files), ',') }}
- name: Test macOS
run: |
xcodebuild build -scheme RealityUI -destination "platform=macOS" | xcpretty
env:
SCHEME: RealityUI
run: xcodebuild test -scheme RealityUI -destination "platform=macOS" -enableCodeCoverage YES
3 changes: 3 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
line_length:
ignores_comments: true
identifier_name:
excluded:
- t
excluded:
- RealityUI+Example
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.6
// swift-tools-version:5.8
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ All components used in RealityUI must be registered before they are used, simply

Enabling RealityUI gestures can be doen by calling `RealityUI.enableGestures(.all, on: ARView)`, with `ARView` being your instance of an [ARView](https://developer.apple.com/documentation/realitykit/arview) object.

RUISlider, RUISwitch, RUIStepper and RUIButton all use `.longTouch`, and if you are adding elements that use the component `TapActionComponent` you can use the gesture `.tap`.
RUISlider, RUISwitch, RUIStepper and RUIButton all use ``RUIDragComponent``, which requires `.ruiDrag`. If you are adding elements that use the component `RUITapComponent` you can use the gesture `.tap`.
I would just recommend using `.all` when enabling gestures, as these will inevitably move around as RealityUI develops.

`RealityUI.enableGestures(.all, on: arView)`
Expand Down Expand Up @@ -120,13 +120,13 @@ Unlock the ability to rotate a RealityKit entity with just one finger.

![Turning key](https://github.com/maxxfrazer/RealityUI/raw/e3cb908fa9051512671e01dd3fe01f59c45f0936/media/RealityUI_pivot_key.gif?raw=true)

[More details](https://github.com/maxxfrazer/RealityUI/wiki/Gestures#turn)
[More details](https://maxxfrazer.github.io/RealityUI/documentation/realityui/RUIDragComponent/DragComponentType/turn(axis:))

### Tap

Create an object in your RealityKit scene with an action, and it will automatically be picked up whenever the user taps on it!

No Gif for this one, but check out [RealityUI Gestures wiki](https://github.com/maxxfrazer/RealityUI/wiki/Gestures#tap) to see how to add [TapActionComponent](https://maxxfrazer.github.io/RealityUI/documentation/realityui/TapActionComponent.html) to an entity in your application.
No Gif for this one, but check out [RUITapComponent](https://maxxfrazer.github.io/RealityUI/documentation/realityui/RUITapComponent) to see how to add this to an entity in your application.

---
## Animations
Expand Down Expand Up @@ -161,6 +161,6 @@ With RUIText you can easily create an Entity with the specified text placed with
---
## More

More information on everything provided in this Swift Package in the [GitHub Wiki](https://github.com/maxxfrazer/RealityUI/wiki), and also the [documentation](https://maxxfrazer.github.io/RealityUI/documentation/realityui/).
More information on everything provided in this Swift Package in the [documentation](https://maxxfrazer.github.io/RealityUI/documentation/realityui/).

Also see the [Example Project](https://github.com/maxxfrazer/RealityUI/tree/main/RealityUI%2BExamples) for iOS in this repository.
4 changes: 4 additions & 0 deletions RealityUI+Example/RealityUI+Example.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@
Base,
);
mainGroup = F31E9ACF29E47B060084306F;
packageReferences = (
);
productRefGroup = F31E9AD929E47B060084306F /* Products */;
projectDirPath = "";
projectRoot = "";
Expand Down Expand Up @@ -299,6 +301,7 @@
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "RealityUI-Example-Info.plist";
INFOPLIST_KEY_NSCameraUsageDescription = ar;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
Expand Down Expand Up @@ -338,6 +341,7 @@
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "RealityUI-Example-Info.plist";
INFOPLIST_KEY_NSCameraUsageDescription = ar;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
Expand Down
73 changes: 58 additions & 15 deletions RealityUI+Example/RealityUI+Example/ARViewContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,25 @@ struct ARViewContainer: UIViewRepresentable {
// Create an ARView
let arView = ARView(frame: .zero)
#if os(iOS)
arView.cameraMode = .nonAR
arView.cameraMode = .ar
#endif

// Add the anchor to the scene
#if os(iOS)
let anchor = AnchorEntity(world: [0, 0, -2])
anchor.scale *= 0.5
#else
let anchor = AnchorEntity(world: .zero)
#endif
arView.scene.addAnchor(anchor)

arView.debugOptions.insert(.showPhysics)
// Setup RealityKit camera
#if os(macOS)
let cam = PerspectiveCamera()
cam.look(at: .zero, from: [0, 0, -2.5], relativeTo: nil)
cam.look(at: .zero, from: [0, 0, -3], relativeTo: nil)
anchor.addChild(cam)
#endif

self.setModel(view: arView)
RealityUI.enableGestures(.all, on: arView)
Expand All @@ -60,7 +68,42 @@ struct ARViewContainer: UIViewRepresentable {
}
view.environment.background = .color(.gray)
let ruiModel: Entity
let smallMove: Float = .random(in: 0.1...0.4)
switch objectType {
case .mover:
ruiModel = Entity()
for idx in 0...5 {
let modEnt = ModelEntity(
mesh: .generateBox(width: 0.5, height: 0.5, depth: 0.5, splitFaces: true),
materials: [
SimpleMaterial(color: .blue, isMetallic: false),
SimpleMaterial(color: .yellow, isMetallic: false),
SimpleMaterial(color: .orange, isMetallic: false),
SimpleMaterial(color: .purple, isMetallic: false),
SimpleMaterial(color: .green, isMetallic: false),
SimpleMaterial(color: .red, isMetallic: false)
].shuffled()
)
modEnt.generateCollisionShapes(recursive: false)
modEnt.components.set(RUIDragComponent(
type: .move(.box(
BoundingBox(min: [-2, -1, -1], max: [2, 1, 1])
))
))
modEnt.position.x = 2 * sin(
Float(idx) / 3 * .pi + smallMove
)
modEnt.position.y = cos(
Float(idx) / 3 * .pi + smallMove
)
ruiModel.addChild(modEnt)
}
let container = ModelEntity(
mesh: .generateBox(width: 4.5, height: 2.5, depth: 2.5),
materials: [SimpleMaterial(color: .white.withAlphaComponent(0.2), isMetallic: false)]
)
container.scale *= -1
ruiModel.addChild(container)
case .toggle:
ruiModel = RUISwitch(switchCallback: { hasSwitch in
view.environment.background = .color(hasSwitch.isOn ? .green : .gray)
Expand All @@ -70,18 +113,18 @@ struct ARViewContainer: UIViewRepresentable {
text: "hello", font: .systemFont(ofSize: 1),
alignment: .center, extrusion: 0.1
))
textObj.components.set(TapActionComponent { ent, _ in
textObj.components.set(RUITapComponent { ent, _ in
ent.ruiSpin(
by: [[1, 0, 0], [0, 1, 0], [0, 0, 1]].randomElement()!,
period: 0.3, times: 1
)
})
textObj.updateCollision()
textObj.addCollision()
ruiModel = textObj
case .slider:
let scalingCube = ModelEntity(mesh: .generateBox(size: 3))
scalingCube.position.z = 3
ruiModel = RUISlider(start: 0.5) { slider, state in
ruiModel = RUISlider(length: 7, start: 0.5, steps: Bool.random() ? 4 : 0) { slider, state in
scalingCube.scale = .one * (slider.value + 0.2) / 1.2
}
ruiModel.addChild(scalingCube)
Expand All @@ -101,8 +144,12 @@ struct ARViewContainer: UIViewRepresentable {
}
ruiModel.look(at: [0, 1, -1], from: .zero, relativeTo: nil)
case .rotation:
ruiModel = RotationPlane(turnAxis: [0, 0, 1])
ruiModel.scale = .one * 2
ruiModel = RotationPlane()
// stand up the model, so it's facing the camera
ruiModel.orientation = simd_quatf(angle: .pi, axis: [0, 1, 0])

// set the turn/rotation component
ruiModel.components.set(RUIDragComponent(type: .turn(axis: [0, 0, 1])))
}
ruiModel.name = "ruiReplace"
worldAnchor.addChild(ruiModel)
Expand All @@ -117,27 +164,23 @@ struct ARViewContainer: UIViewRepresentable {
}

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

/// Create a new ``RotationPlane``, which conforms to HasTurnTouch
/// - Parameter turnAxis: Axis that the object will be rotated around.
required init(turnAxis: SIMD3<Float>) {
required init() {
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.scale = .one * 2

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 {
Expand Down
1 change: 1 addition & 0 deletions RealityUI+Example/RealityUI+Example/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public enum RealityObject: String, CaseIterable {
case button
case rotation
case text
case mover
}

struct ContentView: View {
Expand Down
13 changes: 3 additions & 10 deletions Sources/RealityUI/HasRUI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,24 +57,17 @@ public extension HasRUI {
(self as? HasRUIMaterials)?.materialsShouldChange()
}

@available(*, deprecated, renamed: "rui")
internal(set) var RUI: RUIComponent {
get { self.rui }
set { self.rui = newValue }
}
/// RealityUI Component for the entity.
internal(set) var rui: RUIComponent {
get {
if let ruiComp = self.components[RUIComponent.self] as? RUIComponent {
if let ruiComp = self.components.get(RUIComponent.self) {
return ruiComp
} else {
self.components[RUIComponent.self] = RUIComponent()
self.components.set(RUIComponent())
return self.components[RUIComponent.self]!
}
}
set {
self.components[RUIComponent.self] = newValue
}
set { self.components.set(newValue) }
}

}
Expand Down
Loading

0 comments on commit e7fab33

Please sign in to comment.