Created
December 30, 2022 01:22
-
-
Save scottyob/0f47219022b4b8a04fccb03c7fbfca71 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ContentView.swift | |
// playing2 | |
// | |
// Created by Scott O'Brien on 12/29/22. | |
// | |
import SwiftUI | |
import RealityKit | |
import ARKit | |
extension Array { | |
func filteredByType<T> (_: T.Type) -> [T] { | |
return compactMap({ (element) in | |
return element as? T | |
}) | |
} | |
} | |
let refImg = ReferenceImageDelegate() | |
var refBox: Experience.Box! | |
struct ContentView : View { | |
var body: some View { | |
ARViewContainer().edgesIgnoringSafeArea(.all) | |
} | |
} | |
struct ARViewContainer: UIViewRepresentable { | |
func makeUIView(context: Context) -> ARView { | |
let arView = ARView(frame: .zero) | |
// Load the "Box" scene from the "Experience" Reality File | |
let boxAnchor = try! Experience.loadBox() | |
refBox = boxAnchor | |
// Add the box anchor to the scene | |
arView.scene.anchors.append(boxAnchor) | |
// Add the reference marker, assign the delegate | |
refImg.set(arView: arView) | |
arView.session.delegate = refImg | |
return arView | |
} | |
func updateUIView(_ uiView: ARView, context: Context) {} | |
} | |
#if DEBUG | |
struct ContentView_Previews : PreviewProvider { | |
static var previews: some View { | |
ContentView() | |
} | |
} | |
#endif | |
// MARK: ReferenceMarker | |
final class ReferenceImageDelegate: NSObject, ARSessionDelegate { | |
var arView: ARView! | |
let markerA = AnchorEntity(world: [0, 0.5, 0]) | |
let markerB = AnchorEntity(world: [0, 0.5 ,0]) | |
var floorY: Float? | |
// For showing the distance | |
let distanceMarker = AnchorEntity(world: [0,0,0]) | |
var distanceMesh: ModelEntity! | |
func set(arView: ARView) { | |
self.arView = arView | |
// Add in the markers | |
let marker = ModelEntity(mesh: MeshResource.generateBox(width: 0.01, height: 1, depth: 0.01)) | |
let marker2 = ModelEntity(mesh: MeshResource.generateBox(width: 0.01, height: 1, depth: 0.01)) | |
markerA.addChild(marker) | |
markerB.addChild(marker2) | |
let positionDiff = markerB.position(relativeTo: markerA) | |
let text = MeshResource.generateText( | |
"\(abs(positionDiff.sum()))", | |
extrusionDepth: 0.08, | |
font: .systemFont(ofSize: 0.05, weight: .bold) | |
) | |
distanceMesh = ModelEntity(mesh: text) | |
distanceMarker.addChild(distanceMesh) | |
arView.scene.addAnchor(markerA) | |
arView.scene.addAnchor(markerB) | |
arView.scene.addAnchor(distanceMarker) | |
// Add images to search for | |
var imageAnchor = AnchorEntity(.image(group: "AR Resources", name: "a")) | |
arView.scene.anchors.append(imageAnchor) | |
imageAnchor = AnchorEntity(.image(group: "AR Resources", name: "b")) | |
arView.scene.anchors.append(imageAnchor) | |
} | |
/* | |
Used for when we find when a marker has a new position | |
*/ | |
func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) { | |
// Update the floor location if we can see a floor | |
let planes = anchors.filteredByType(ARPlaneAnchor.self) | |
let floor = planes.filter{$0.classification == ARPlaneAnchor.Classification.floor}.first | |
if(floor != nil) { | |
floorY = floor?.transform.columns.3.y | |
} | |
// Put the measurement text to one of the markers | |
let positionDiff = markerB.position(relativeTo: markerA) | |
let text = MeshResource.generateText( | |
"\(abs(positionDiff.sum()))", | |
extrusionDepth: 0.008, | |
font: .systemFont(ofSize: 0.05, weight: .bold) | |
) | |
distanceMesh = ModelEntity(mesh: text) | |
distanceMarker.children.removeAll() | |
distanceMarker.addChild(distanceMesh) | |
distanceMarker.transform = markerB.transform | |
let imageMaps = anchors.filteredByType(ARImageAnchor.self) | |
for image in imageMaps { | |
var marker = markerB | |
if image.name == "a" { | |
// print(image.transform.columns.0) | |
// print(image.transform.columns.1) | |
// print(image.transform.columns.2) | |
// print(image.transform.columns.3) | |
// print("") | |
marker = markerA | |
} | |
// Magazines are 21.5cm wide, translate measuring to the edge | |
let translation = simd_float4x4( | |
SIMD4(1, 0, 0, 0), | |
SIMD4(0, 1, 0, 0), | |
SIMD4(0, 0, 1, 0), | |
// float4(x, y, z, 1) | |
SIMD4(0.1075, 0, 0, 1) | |
) | |
marker.transform = Transform(matrix: image.transform * translation) | |
// Place the marker on the floor | |
if(floorY != nil) { | |
marker.position.y = floorY! | |
} | |
// Orient the marker straight up | |
marker.orientation = simd_quatf(vector: [0,0,0,0]) | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment