Skip to content

Instantly share code, notes, and snippets.

@scottyob
Created December 30, 2022 01:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scottyob/0f47219022b4b8a04fccb03c7fbfca71 to your computer and use it in GitHub Desktop.
Save scottyob/0f47219022b4b8a04fccb03c7fbfca71 to your computer and use it in GitHub Desktop.
//
// 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