Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AR: World scale #466

Closed
wants to merge 81 commits into from
Closed
Show file tree
Hide file tree
Changes from 62 commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
18f4361
move ARSwiftUIView
rolson Oct 2, 2023
078cda3
Add world scale scene view
rolson Oct 2, 2023
97fe1e7
add parcel data
rolson Oct 2, 2023
e73ee69
geotracking availability
rolson Oct 2, 2023
ad0eb7f
cleanup
rolson Oct 2, 2023
e8d2a8f
tracking state
rolson Oct 2, 2023
c2b0039
simplify
rolson Oct 2, 2023
ac6acf0
try to get it to work
rolson Oct 2, 2023
c81d9c1
prototype
rolson Oct 3, 2023
30f8552
play with rotation
rolson Oct 3, 2023
6d7084a
fix team
rolson Oct 3, 2023
9c11b7a
Merge branch 'ryan/offBy90' into ryan/worldScale2
rolson Oct 3, 2023
951257d
cleanup
rolson Oct 3, 2023
050a53d
opacity slider
rolson Oct 3, 2023
5038d2a
cleanup
rolson Oct 3, 2023
b217809
revert changes
rolson Oct 4, 2023
a213df4
cleanup
rolson Oct 4, 2023
7476488
cleanup
rolson Oct 4, 2023
0ed4e65
cleanup
rolson Oct 4, 2023
95c03b2
cleanup
rolson Oct 4, 2023
f9e8399
cleanup
rolson Oct 4, 2023
dbc1e02
cleanup
rolson Oct 4, 2023
e2e168d
try adding box
rolson Oct 4, 2023
c508410
cleanup
rolson Oct 4, 2023
cb57032
use elevation
rolson Oct 4, 2023
634946d
update plist
rolson Oct 4, 2023
0331d13
add modifier for onGeoTrackingStatus changes
rolson Oct 5, 2023
d69dc36
add replay data
rolson Oct 6, 2023
1c65e52
get compass heading
rolson Oct 6, 2023
22d69ab
cleanup
rolson Oct 6, 2023
3683b64
cleanup
rolson Oct 6, 2023
dae6acf
clanup
rolson Oct 6, 2023
b03483d
cleanup
rolson Oct 6, 2023
eea335e
cleanup
rolson Oct 6, 2023
522acb5
Merge branch 'v.next' into ryan/worldScale3
rolson Oct 9, 2023
eeee003
prototype with location
rolson Oct 9, 2023
0892441
flashing, orientation
rolson Oct 9, 2023
053ba6d
reset tracking every so often
rolson Oct 9, 2023
8c274d9
research
rolson Oct 9, 2023
e474bce
proto
rolson Oct 9, 2023
19cd230
cleanup
rolson Oct 9, 2023
0d9fbe7
use orientation of 0
rolson Oct 10, 2023
f76b535
no need to reset tracking
rolson Oct 10, 2023
3a68848
no need to reset tracking
rolson Oct 10, 2023
36e82ec
must reset tracking or error gets bigger
rolson Oct 10, 2023
f9fdffb
add doc
rolson Oct 10, 2023
d86b5a2
worldscale -> world tracking
rolson Oct 10, 2023
09085e0
cleanup
rolson Oct 10, 2023
c5b05c5
back to world scale
rolson Oct 10, 2023
ffea381
remove geotracking scene view
rolson Oct 10, 2023
d3276dd
cleanup
rolson Oct 10, 2023
fb18225
cleanup
rolson Oct 10, 2023
50e2fda
cleanup
rolson Oct 10, 2023
ac3ae6f
cleanup
rolson Oct 10, 2023
1e98a78
revert proj changes
rolson Oct 10, 2023
52d3ab8
change when in use description
rolson Oct 10, 2023
4de5ff8
remove scheme
rolson Oct 10, 2023
851affe
add red circle graphic locally
rolson Oct 10, 2023
1c34136
add all of vertical accuracy so don't go under earth
rolson Oct 10, 2023
5316eec
remove geotracking status delegate
rolson Oct 10, 2023
83c295c
comment
rolson Oct 10, 2023
601a973
add comments
rolson Oct 10, 2023
80f8d8c
Update Examples/ExamplesApp/Info.plist
rolson Oct 10, 2023
039925b
Update Sources/ArcGISToolkit/Components/AR/WorldScaleSceneView.swift
rolson Oct 10, 2023
3dbeb52
Update Sources/ArcGISToolkit/Components/AR/WorldScaleSceneView.swift
rolson Oct 10, 2023
c00a8b1
add parameter for location datasource
rolson Oct 10, 2023
ba9147c
disable user interactive navigation
rolson Oct 10, 2023
99988c2
Merge pull request #532 from Esri/v.next
des12437 Dec 6, 2023
e02f704
Apply suggestions from code review
rolson Dec 6, 2023
d7a797b
Delete ARSwiftUIView.swift
des12437 Jan 3, 2024
1d9b5d9
Merge branch 'main' into destiny/patch-world-scale
des12437 Jan 3, 2024
d2ba8b1
Update View.swift
des12437 Jan 3, 2024
99e952f
Merge pull request #552 from Esri/destiny/patch-world-scale
des12437 Jan 4, 2024
bb3cf5d
Refactor geotracking world scale AR
des12437 Jan 3, 2024
62ae2f9
Add view modifiers
des12437 Jan 4, 2024
3d9249d
Add indentation
des12437 Jan 5, 2024
28304d1
PR feedback
des12437 Jan 5, 2024
12b4c81
Handle location and heading updates
des12437 Jan 5, 2024
fcee3bd
Add valid accuracy check
des12437 Jan 5, 2024
56114d1
Remove redundant constants
des12437 Jan 5, 2024
dc1347f
Merge pull request #554 from Esri/destiny/geotracking-refactor
des12437 Jan 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Examples/Examples.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
75C37C9227BEDBD800FC9DCE /* BookmarksExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C37C9127BEDBD800FC9DCE /* BookmarksExampleView.swift */; };
75D41B2B27C6F21400624D7C /* ScalebarExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D41B2A27C6F21400624D7C /* ScalebarExampleView.swift */; };
882899FD2AB5099300A0BDC1 /* FlyoverExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 882899FC2AB5099300A0BDC1 /* FlyoverExampleView.swift */; };
885554952ACB4D9600ECBB4A /* WorldScaleExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 885554942ACB4D9600ECBB4A /* WorldScaleExampleView.swift */; };
E42BFBE92672BF9500159107 /* SearchExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E42BFBE82672BF9500159107 /* SearchExampleView.swift */; };
E4624A25278CE815000D2A38 /* FloorFilterExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4624A24278CE815000D2A38 /* FloorFilterExampleView.swift */; };
E47ABE442652FE0900FD2FE3 /* ExamplesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = E47ABE432652FE0900FD2FE3 /* ExamplesApp.swift */; };
Expand Down Expand Up @@ -55,6 +56,7 @@
75C37C9127BEDBD800FC9DCE /* BookmarksExampleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksExampleView.swift; sourceTree = "<group>"; };
75D41B2A27C6F21400624D7C /* ScalebarExampleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScalebarExampleView.swift; sourceTree = "<group>"; };
882899FC2AB5099300A0BDC1 /* FlyoverExampleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlyoverExampleView.swift; sourceTree = "<group>"; };
885554942ACB4D9600ECBB4A /* WorldScaleExampleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WorldScaleExampleView.swift; sourceTree = "<group>"; };
E42BFBE82672BF9500159107 /* SearchExampleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchExampleView.swift; sourceTree = "<group>"; };
E4624A24278CE815000D2A38 /* FloorFilterExampleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloorFilterExampleView.swift; sourceTree = "<group>"; };
E47ABE402652FE0900FD2FE3 /* Toolkit Examples.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Toolkit Examples.app"; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -110,6 +112,7 @@
75230DAD28614369009AF501 /* UtilityNetworkTraceExampleView.swift */,
882899FC2AB5099300A0BDC1 /* FlyoverExampleView.swift */,
1CC376D32ABA0B3700A83300 /* TableTopExampleView.swift */,
885554942ACB4D9600ECBB4A /* WorldScaleExampleView.swift */,
);
name = Examples;
sourceTree = "<group>";
Expand Down Expand Up @@ -287,6 +290,7 @@
4D19FCB52881C8F3002601E8 /* PopupExampleView.swift in Sources */,
882899FD2AB5099300A0BDC1 /* FlyoverExampleView.swift in Sources */,
E48A73462658227100F5C118 /* ExampleView.swift in Sources */,
885554952ACB4D9600ECBB4A /* WorldScaleExampleView.swift in Sources */,
E42BFBE92672BF9500159107 /* SearchExampleView.swift in Sources */,
E4C389D526B8A12C002BC255 /* BasemapGalleryExampleView.swift in Sources */,
75D41B2B27C6F21400624D7C /* ScalebarExampleView.swift in Sources */,
Expand Down
92 changes: 92 additions & 0 deletions Examples/Examples/WorldScaleExampleView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright 2023 Esri.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
rolson marked this conversation as resolved.
Show resolved Hide resolved

import SwiftUI
import ArcGIS
import ArcGISToolkit
import CoreLocation

/// An example that utilizes the `WorldScaleSceneView` to show an augmented reality view
/// of your current location. Because this is an example that can be run from anywhere,
/// it places a red circle around your initial location which can be explored.
struct WorldScaleExampleView: View {
@State private var scene: ArcGIS.Scene = {
// Creates an elevation source from Terrain3D REST service.
let elevationServiceURL = URL(string: "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer")!
let elevationSource = ArcGISTiledElevationSource(url: elevationServiceURL)
let surface = Surface()
surface.addElevationSource(elevationSource)
let scene = Scene()
scene.baseSurface = surface
scene.baseSurface.backgroundGrid.isVisible = false
scene.baseSurface.navigationConstraint = .unconstrained
scene.basemap = Basemap(style: .arcGISImagery)
return scene
}()

/// Basemap opacity.
@State private var opacity: Float = 1
/// Graphics overlay to show a graphic around your initial location.
@State private var graphicsOverlay = GraphicsOverlay()
/// The location datasource that is used to access the device location.
@State private var locationDatasSource = SystemLocationDataSource()

var body: some View {
VStack {
WorldScaleSceneView { proxy in
SceneView(scene: scene, graphicsOverlays: [graphicsOverlay])
.onSingleTapGesture { screen, _ in
print("Identifying...")
Task.detached {
let results = try await proxy.identifyLayers(screenPoint: screen, tolerance: 20)
print("\(results.count) identify result(s).")
}
}
}
// A slider to adjust the basemap opacity.
Slider(value: $opacity, in: 0...1.0)
.padding(.horizontal)
}
.onChange(of: opacity) { opacity in
guard let basemap = scene.basemap else { return }
for layer in basemap.baseLayers {
layer.opacity = opacity
}
}
.task {
// Request when-in-use location authorization.
// This is necessary for 2 reasons:
// 1. Because we use location datasource to get the initial location in this example
// in order to display a ring around the initial location.
// 2. Because the `WorldScaleSceneView` utilizes a location datasource and that
// datasource will not start until authorized.
let locationManager = CLLocationManager()
if locationManager.authorizationStatus == .notDetermined {
locationManager.requestWhenInUseAuthorization()
}

do {
try await locationDatasSource.start()
} catch {
print("Failed to start location datasource: \(error.localizedDescription)")
}

// Retrieve initial location
guard let initialLocation = await locationDatasSource.locations.first(where: { _ in true }) else { return }

// Put a circle graphic around the initial location
let circle = GeometryEngine.geodeticBuffer(around: initialLocation.position, distance: 20, distanceUnit: .meters, maxDeviation: 1, curveType: .geodesic)
graphicsOverlay.addGraphic(Graphic(geometry: circle, symbol: SimpleLineSymbol(color: .red, width: 3)))
}
}
}
3 changes: 2 additions & 1 deletion Examples/ExamplesApp/Examples.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ extension ExampleList {
name: "Augmented Reality",
examples: [
AnyExample("Flyover", content: FlyoverExampleView()),
AnyExample("Tabletop", content: TableTopExampleView())
AnyExample("Tabletop", content: TableTopExampleView()),
AnyExample("World Scale", content: WorldScaleExampleView())
]
)

Expand Down
6 changes: 4 additions & 2 deletions Examples/ExamplesApp/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,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>NSCameraUsageDescription</key>
<string>This app uses augmented reality to overlay imagery over your real-world environment. Camera access is required for this functionality.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Tracking location in an augmented reality experience.</string>
rolson marked this conversation as resolved.
Show resolved Hide resolved
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
Expand Down Expand Up @@ -59,6 +59,8 @@
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>This app uses augmented reality to overlay imagery over your real-world environment. Camera access is required for this functionality.</string>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
Expand Down
43 changes: 1 addition & 42 deletions Sources/ArcGISToolkit/Components/AR/TableTopSceneView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public struct TableTopSceneView: View {
ZStack {
ARSwiftUIView(proxy: arViewProxy)
.onDidUpdateFrame { _, frame in
guard let sceneViewProxy, let interfaceOrientation else { return }
guard let sceneViewProxy, let interfaceOrientation, let initialTransformation else { return }
sceneViewProxy.updateCamera(
frame: frame,
cameraController: cameraController,
Expand Down Expand Up @@ -236,27 +236,6 @@ public struct TableTopSceneView: View {
}
}

private extension View {
/// Sets a closure to perform when a single tap occurs on the view.
/// - Parameters:
/// - action: The closure to perform upon single tap.
/// - screenPoint: The location of the tap in the view's coordinate space.
func onSingleTapGesture(perform action: @escaping (_ screenPoint: CGPoint) -> Void) -> some View {
if #available(iOS 16.0, *) {
return self.onTapGesture { screenPoint in
action(screenPoint)
}
} else {
return self.gesture(
DragGesture()
.onEnded { dragAttributes in
action(dragAttributes.location)
}
)
}
}
}

private extension ARSwiftUIViewProxy {
/// Performs a hit test operation to get the transformation matrix representing the corresponding real-world point for `screenPoint`.
/// - Parameter screenPoint: The screen point to determine the real world transformation matrix from.
Expand Down Expand Up @@ -312,26 +291,6 @@ private extension SceneViewProxy {

return initialTransformation
}

/// Sets the field of view for the scene view's camera for a given augmented reality frame.
/// - Parameters:
/// - frame: The current AR frame.
/// - orientation: The interface orientation.
func setFieldOfView(for frame: ARFrame, orientation: InterfaceOrientation) {
let camera = frame.camera
let intrinsics = camera.intrinsics
let imageResolution = camera.imageResolution

setFieldOfViewFromLensIntrinsics(
xFocalLength: intrinsics[0][0],
yFocalLength: intrinsics[1][1],
xPrincipal: intrinsics[2][0],
yPrincipal: intrinsics[2][1],
xImageSize: Float(imageResolution.width),
yImageSize: Float(imageResolution.height),
interfaceOrientation: orientation
)
}
}

private extension String {
Expand Down
Loading