replate-camera 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ios/ReplateCameraViewManager.swift +116 -61
- package/package.json +1 -1
|
@@ -45,7 +45,6 @@ extension UIImage {
|
|
|
45
45
|
class ReplateCameraView : UIView, ARSessionDelegate {
|
|
46
46
|
|
|
47
47
|
static var arView: ARView!
|
|
48
|
-
static var anchor: ARAnchor!
|
|
49
48
|
static var anchorEntity: AnchorEntity!
|
|
50
49
|
static var model: Entity!
|
|
51
50
|
static var spheresModels: [ModelEntity] = []
|
|
@@ -53,20 +52,27 @@ class ReplateCameraView : UIView, ARSessionDelegate {
|
|
|
53
52
|
static var lowerSpheresSet: [Bool] = [Bool](repeating: false, count: 72)
|
|
54
53
|
static var totalPhotosTaken: Int = 0
|
|
55
54
|
static var photosFromDifferentAnglesTaken = 0
|
|
55
|
+
static var INSTANCE: ReplateCameraView!
|
|
56
56
|
|
|
57
57
|
override init(frame: CGRect) {
|
|
58
58
|
super.init(frame: frame)
|
|
59
59
|
requestCameraPermissions()
|
|
60
60
|
// setupAR()
|
|
61
|
+
ReplateCameraView.INSTANCE = self
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
required init?(coder: NSCoder) {
|
|
64
65
|
super.init(coder: coder)
|
|
65
66
|
requestCameraPermissions()
|
|
67
|
+
ReplateCameraView.INSTANCE = self
|
|
66
68
|
// setupAR()
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
|
|
71
|
+
static func addRecognizer(){
|
|
72
|
+
let recognizer = UITapGestureRecognizer(target: ReplateCameraView.INSTANCE,
|
|
73
|
+
action: #selector(ReplateCameraView.INSTANCE.viewTapped(_:)))
|
|
74
|
+
ReplateCameraView.arView.addGestureRecognizer(recognizer)
|
|
75
|
+
}
|
|
70
76
|
|
|
71
77
|
func requestCameraPermissions(){
|
|
72
78
|
|
|
@@ -94,6 +100,65 @@ class ReplateCameraView : UIView, ARSessionDelegate {
|
|
|
94
100
|
print("Width: \(width), Height: \(height)")
|
|
95
101
|
self.setupAR()
|
|
96
102
|
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@objc private func viewTapped(_ recognizer: UITapGestureRecognizer) {
|
|
106
|
+
print("VIEW TAPPED")
|
|
107
|
+
// guard !ReplateCameraView.arView.canBecomeFocused else {
|
|
108
|
+
// return
|
|
109
|
+
// }
|
|
110
|
+
|
|
111
|
+
let tapLocation: CGPoint = recognizer.location(in: ReplateCameraView.arView)
|
|
112
|
+
let estimatedPlane: ARRaycastQuery.Target = .estimatedPlane
|
|
113
|
+
let alignment: ARRaycastQuery.TargetAlignment = .horizontal
|
|
114
|
+
|
|
115
|
+
let result: [ARRaycastResult] = ReplateCameraView.arView.raycast(from: tapLocation,
|
|
116
|
+
allowing: estimatedPlane,
|
|
117
|
+
alignment: alignment)
|
|
118
|
+
|
|
119
|
+
guard let rayCast: ARRaycastResult = result.first
|
|
120
|
+
else { return }
|
|
121
|
+
let anchor = AnchorEntity(raycastResult: rayCast)
|
|
122
|
+
print("ANCHOR FOUND\n", anchor.transform)
|
|
123
|
+
if (ReplateCameraView.model == nil && ReplateCameraView.anchorEntity == nil){
|
|
124
|
+
ReplateCameraView.anchorEntity = anchor
|
|
125
|
+
let anchorTransform = anchor.transform
|
|
126
|
+
// let path = Bundle.main.path(forResource: "anchor", ofType: "usdz")!
|
|
127
|
+
// let url = URL(fileURLWithPath: path)
|
|
128
|
+
// let entity: ModelEntity = try! ModelEntity.loadModel(contentsOf: url)
|
|
129
|
+
|
|
130
|
+
// if #available(iOS 15.0, *) {
|
|
131
|
+
// entity.model!.mesh.
|
|
132
|
+
// ReplateCameraView.spheresModels = Array(entity.model!.mesh.contents.models)
|
|
133
|
+
// }
|
|
134
|
+
// entity.scale *= 4.5
|
|
135
|
+
// entity.position = SIMD3(anchorTransform.columns.3.x, anchorTransform.columns.3.y, anchorTransform.columns.3.z)
|
|
136
|
+
|
|
137
|
+
func createSphere(position: SIMD3<Float>) -> ModelEntity {
|
|
138
|
+
let sphereMesh = MeshResource.generateSphere(radius: 0.0025)
|
|
139
|
+
let sphereEntity = ModelEntity(mesh: sphereMesh, materials: [SimpleMaterial(color: .white.withAlphaComponent(0.7), isMetallic: false)])
|
|
140
|
+
sphereEntity.position = position
|
|
141
|
+
return sphereEntity
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
func createSpheres(y: Float){
|
|
145
|
+
let radius = Float(0.1)
|
|
146
|
+
for i in 0..<72 {
|
|
147
|
+
let angle = Float(i) * (Float.pi / 180) * 5 // 10 degrees in radians
|
|
148
|
+
let x = radius * cos(angle)
|
|
149
|
+
let z = radius * sin(angle)
|
|
150
|
+
let spherePosition = SIMD3<Float>(x, y, z)
|
|
151
|
+
let sphereEntity = createSphere(position: spherePosition)
|
|
152
|
+
ReplateCameraView.spheresModels.append(sphereEntity)
|
|
153
|
+
ReplateCameraView.anchorEntity.addChild(sphereEntity)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
createSpheres(y: 0.0)
|
|
158
|
+
createSpheres(y: 0.3)
|
|
159
|
+
ReplateCameraView.arView.scene.anchors.append(ReplateCameraView.anchorEntity)
|
|
160
|
+
}
|
|
161
|
+
}
|
|
97
162
|
|
|
98
163
|
func setupAR() {
|
|
99
164
|
print("Setup AR")
|
|
@@ -109,6 +174,10 @@ class ReplateCameraView : UIView, ARSessionDelegate {
|
|
|
109
174
|
// else { fatalError("See no reference object") }
|
|
110
175
|
// print(obj)
|
|
111
176
|
configuration.planeDetection = ARWorldTrackingConfiguration.PlaneDetection.horizontal
|
|
177
|
+
// ReplateCameraView.arView.debugOptions = [
|
|
178
|
+
// .showAnchorOrigins,
|
|
179
|
+
// .showAnchorGeometry
|
|
180
|
+
// ]
|
|
112
181
|
if #available(iOS 16.0, *) {
|
|
113
182
|
print("recommendedVideoFormatForHighResolutionFrameCapturing")
|
|
114
183
|
configuration.videoFormat = ARWorldTrackingConfiguration.recommendedVideoFormatForHighResolutionFrameCapturing ?? ARWorldTrackingConfiguration.recommendedVideoFormatFor4KResolution ?? ARWorldTrackingConfiguration.supportedVideoFormats[0]
|
|
@@ -123,61 +192,14 @@ class ReplateCameraView : UIView, ARSessionDelegate {
|
|
|
123
192
|
}
|
|
124
193
|
// configuration.detectionObjects = obj
|
|
125
194
|
ReplateCameraView.arView.session.run(configuration)
|
|
195
|
+
|
|
196
|
+
ReplateCameraView.arView.addCoaching()
|
|
126
197
|
}
|
|
127
198
|
|
|
128
199
|
func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
|
|
129
|
-
|
|
130
|
-
if (ReplateCameraView.anchor == nil){
|
|
131
|
-
guard let _anchor = anchors.first else { return }
|
|
132
|
-
ReplateCameraView.anchor = _anchor
|
|
133
|
-
}
|
|
134
|
-
if (ReplateCameraView.model == nil && ReplateCameraView.anchorEntity == nil){
|
|
135
|
-
let anchorTransform = ReplateCameraView.anchor.transform
|
|
136
|
-
// let path = Bundle.main.path(forResource: "anchor", ofType: "usdz")!
|
|
137
|
-
// let url = URL(fileURLWithPath: path)
|
|
138
|
-
// let entity: ModelEntity = try! ModelEntity.loadModel(contentsOf: url)
|
|
139
|
-
|
|
140
|
-
// if #available(iOS 15.0, *) {
|
|
141
|
-
// entity.model!.mesh.
|
|
142
|
-
// ReplateCameraView.spheresModels = Array(entity.model!.mesh.contents.models)
|
|
143
|
-
// }
|
|
144
|
-
// entity.scale *= 4.5
|
|
145
|
-
// entity.position = SIMD3(anchorTransform.columns.3.x, anchorTransform.columns.3.y, anchorTransform.columns.3.z)
|
|
146
|
-
|
|
147
|
-
func createSphere(position: SIMD3<Float>) -> ModelEntity {
|
|
148
|
-
let sphereMesh = MeshResource.generateSphere(radius: 0.0025)
|
|
149
|
-
let sphereEntity = ModelEntity(mesh: sphereMesh, materials: [SimpleMaterial(color: .white.withAlphaComponent(0.7), isMetallic: false)])
|
|
150
|
-
sphereEntity.position = position
|
|
151
|
-
return sphereEntity
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
func createSpheres(y: Float){
|
|
155
|
-
let radius = Float(0.1)
|
|
156
|
-
for i in 0..<72 {
|
|
157
|
-
let angle = Float(i) * (Float.pi / 180) * 5 // 10 degrees in radians
|
|
158
|
-
let x = radius * cos(angle)
|
|
159
|
-
let z = radius * sin(angle)
|
|
160
|
-
let spherePosition = SIMD3<Float>(x, y, z)
|
|
161
|
-
let sphereEntity = createSphere(position: spherePosition)
|
|
162
|
-
ReplateCameraView.spheresModels.append(sphereEntity)
|
|
163
|
-
ReplateCameraView.anchorEntity.addChild(sphereEntity)
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
ReplateCameraView.anchorEntity = AnchorEntity()
|
|
168
|
-
createSpheres(y: 0.0)
|
|
169
|
-
createSpheres(y: 0.3)
|
|
170
|
-
ReplateCameraView.arView.scene.anchors.append(ReplateCameraView.anchorEntity)
|
|
171
|
-
}
|
|
200
|
+
|
|
172
201
|
}
|
|
173
202
|
|
|
174
|
-
// @objc func setCameraRect(_ node: NSNumber, rect: NSDictionary) {
|
|
175
|
-
// let x = rect["x"] as? CGFloat ?? 0
|
|
176
|
-
// let y = rect["y"] as? CGFloat ?? 0
|
|
177
|
-
// let width = rect["width"] as? CGFloat ?? 0
|
|
178
|
-
// let height = rect["height"] as? CGFloat ?? 0
|
|
179
|
-
//// arView.(CGRect(x: x, y: y, width: width, height: height))
|
|
180
|
-
// }
|
|
181
203
|
|
|
182
204
|
@objc var color: String = "" {
|
|
183
205
|
didSet {
|
|
@@ -220,11 +242,17 @@ class ReplateCameraView : UIView, ARSessionDelegate {
|
|
|
220
242
|
ReplateCameraView.arView.session.run(ARWorldTrackingConfiguration())
|
|
221
243
|
}
|
|
222
244
|
|
|
223
|
-
|
|
224
245
|
}
|
|
225
246
|
|
|
226
247
|
@objc(ReplateCameraController)
|
|
227
|
-
class ReplateCameraController:
|
|
248
|
+
class ReplateCameraController: RCTEventEmitter {
|
|
249
|
+
|
|
250
|
+
static var INSTANCE: ReplateCameraController!
|
|
251
|
+
|
|
252
|
+
override init() {
|
|
253
|
+
super.init()
|
|
254
|
+
ReplateCameraController.INSTANCE = self
|
|
255
|
+
}
|
|
228
256
|
|
|
229
257
|
@objc(getPhotosCount:rejecter:)
|
|
230
258
|
func getPhotosCount(_ resolver: RCTPromiseResolveBlock, rejecter: RCTPromiseRejectBlock) -> Void{
|
|
@@ -330,7 +358,6 @@ class ReplateCameraController: NSObject {
|
|
|
330
358
|
}
|
|
331
359
|
|
|
332
360
|
|
|
333
|
-
|
|
334
361
|
static func saveImageAsJPEG(_ image: UIImage) -> URL? {
|
|
335
362
|
// Convert UIImage to Data with JPEG representation
|
|
336
363
|
guard let imageData = image.jpegData(compressionQuality: 1.0) else {
|
|
@@ -363,12 +390,12 @@ class ReplateCameraController: NSObject {
|
|
|
363
390
|
return nil
|
|
364
391
|
}
|
|
365
392
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
393
|
+
|
|
394
|
+
@objc
|
|
395
|
+
func sendTutorialEndedEvent(){
|
|
396
|
+
self.sendEvent(withName: "arTutorialCompleted", body: true)
|
|
397
|
+
}
|
|
398
|
+
|
|
372
399
|
|
|
373
400
|
func updateSpheres(deviceTargetInFocus: Int) {
|
|
374
401
|
guard let anchorNode = ReplateCameraView.anchorEntity else { return }
|
|
@@ -436,3 +463,31 @@ extension SCNVector3 {
|
|
|
436
463
|
return a.x*b.x + a.y*b.y + a.z*b.z
|
|
437
464
|
}
|
|
438
465
|
}
|
|
466
|
+
|
|
467
|
+
extension ARView: ARCoachingOverlayViewDelegate {
|
|
468
|
+
func addCoaching() {
|
|
469
|
+
print("ADD COACHING")
|
|
470
|
+
// Create a ARCoachingOverlayView object
|
|
471
|
+
let coachingOverlay = ARCoachingOverlayView()
|
|
472
|
+
// Make sure it rescales if the device orientation changes
|
|
473
|
+
coachingOverlay.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
474
|
+
self.addSubview(coachingOverlay)
|
|
475
|
+
coachingOverlay.center = self.convert(self.center, from:self.superview)
|
|
476
|
+
// Set the Augmented Reality goal
|
|
477
|
+
coachingOverlay.goal = .horizontalPlane
|
|
478
|
+
// Set the ARSession
|
|
479
|
+
coachingOverlay.session = self.session
|
|
480
|
+
// Set the delegate for any callbacks
|
|
481
|
+
coachingOverlay.delegate = self
|
|
482
|
+
coachingOverlay.setActive(true, animated: true)
|
|
483
|
+
}
|
|
484
|
+
// Example callback for the delegate object
|
|
485
|
+
public func coachingOverlayViewDidDeactivate(
|
|
486
|
+
_ coachingOverlayView: ARCoachingOverlayView
|
|
487
|
+
) {
|
|
488
|
+
print("DEACTIVATED")
|
|
489
|
+
ReplateCameraController.INSTANCE.sendTutorialEndedEvent()
|
|
490
|
+
ReplateCameraView.addRecognizer()
|
|
491
|
+
print("CRASHED")
|
|
492
|
+
}
|
|
493
|
+
}
|