SLProject  4.3.020
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SENSiOSARKitDelegate.mm
Go to the documentation of this file.
2 #include <Utils.h>
3 
4 @interface SENSiOSARCoreDelegate () {
5 
6 @private
7 
8  ARSession* _arSession;
9  ARConfiguration* _arConfig;
10 }
11 
12 @end
13 
14 @implementation SENSiOSARCoreDelegate
15 
16 - (id)init
17 {
18  //Initialize the parent class(es) up the hierarchy and create self:
19  self = [super init];
20 
21  //Initialize members (not necessary with ARC)
22  _arSession = nil;
23  _arConfig = nil;
24  //if (self)
25  //{
26  // [self initARKit];
27  //}
28 
29  return self;
30 }
31 
32 - (void)initARKit
33 {
34  if (ARWorldTrackingConfiguration.isSupported)
35  {
36  // Create an ARSession
37  if (_arSession == nil)
38  {
39  _arSession = [ARSession new];
40  _arSession.delegate = self;
41  }
42 
43  if (_arConfig == nil)
44  _arConfig = [ARWorldTrackingConfiguration new];
45 
46  //for (int i = 0; i < ARWorldTrackingConfiguration.supportedVideoFormats.count; ++i)
47  //{
48  // CGSize s = ARWorldTrackingConfiguration.supportedVideoFormats[i].imageResolution;
49  // NSLog(NSStringFromCGSize(s));
50  //}
51  _arConfig.videoFormat = ARWorldTrackingConfiguration.supportedVideoFormats.lastObject;
52  //ARWorldAlignmentGravity is default
53  _arConfig.worldAlignment = ARWorldAlignmentGravity;
54  }
55 }
56 
57 - (BOOL)isAvailable
58 {
59  return ARWorldTrackingConfiguration.isSupported;
60 }
61 
62 - (BOOL)run
63 {
64  if (ARWorldTrackingConfiguration.isSupported && _arSession)
65  {
66  [_arSession runWithConfiguration:_arConfig];
67  return YES;
68  }
69  else
70  return NO;
71 }
72 
73 - (void)pause
74 {
75  if (_arSession)
76  {
77  [_arSession pause];
78  }
79 }
80 
81 - (BOOL)reset
82 {
83  if (ARWorldTrackingConfiguration.isSupported && _arSession)
84  {
85  [_arSession runWithConfiguration:_arConfig options:ARSessionRunOptionResetTracking | ARSessionRunOptionRemoveExistingAnchors];
86  return YES;
87  }
88  else
89  return NO;
90 }
91 
92 - (void)latestFrame:(cv::Mat*)pose
93  withImg:(cv::Mat*)imgBGR
94  AndIntrinsic:(cv::Mat*)intrinsic
95  AndImgWidth:(int*)w
96  AndImgHeight:(int*)h
97  IsTracking:(BOOL*)isTracking
98  WithPointClout:(cv::Mat*)pc
99 {
100  //Reference the current ARFrame (I think the referenced "currentFrame" may change during this function call)
101  ARFrame* frame = _arSession.currentFrame;
102  if (!frame)
103  {
104  Utils::log("SENSiOSARCoreDelegate", "frame is invalid");
105  *isTracking = NO;
106  return;
107  }
108  ARCamera* camera = frame.camera;
109 
110  //copy camera pose
111  *pose = cv::Mat_<float>(4, 4);
112  for (int i = 0; i < 4; ++i)
113  {
114  simd_float4 col = camera.transform.columns[i];
115  pose->at<float>(0, i) = (float)col[0];
116  pose->at<float>(1, i) = (float)col[1];
117  pose->at<float>(2, i) = (float)col[2];
118  pose->at<float>(3, i) = (float)col[3];
119  }
120 
121  //copy intrinsic
122  *intrinsic = cv::Mat_<double>(3, 3);
123  for (int i = 0; i < 3; ++i)
124  {
125  simd_float3 col = camera.intrinsics.columns[i];
126  intrinsic->at<double>(0, i) = (double)col[0];
127  intrinsic->at<double>(1, i) = (double)col[1];
128  intrinsic->at<double>(2, i) = (double)col[2];
129  }
130 
131  if (frame.camera.trackingState == ARTrackingStateNormal)
132  *isTracking = YES;
133  else
134  *isTracking = NO;
135 
136  //copy the image as in camera
137  CVImageBufferRef pixelBuffer = frame.capturedImage;
138 
139  CVReturn ret = CVPixelBufferLockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
140 
141  //This is NV12, so the order is U/V (NV12: YYYYUV NV21: YYYYVU)
142  if (ret == kCVReturnSuccess)
143  {
144  OSType pixelFormat = CVPixelBufferGetPixelFormatType(pixelBuffer);
145  if (pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange)
146  {
147  size_t imgWidth = CVPixelBufferGetWidth(pixelBuffer);
148  size_t imgHeight = CVPixelBufferGetHeight(pixelBuffer);
149  *w = (int)imgWidth;
150  *h = (int)imgHeight;
151 
152  uint8_t* yPlane = (uint8_t*)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);
153 
154  cv::Mat yuvImg((int)imgHeight + ((int)imgHeight / 2), (int)imgWidth, CV_8UC1, yPlane);
155  cv::cvtColor(yuvImg, *imgBGR, cv::COLOR_YUV2BGR_NV12, 3);
156  }
157  }
158  if (ret != kCVReturnSuccess)
159  {
160  Utils::log("SENSiOSARCoreDelegate", "pixelbuffer not locked");
161  }
162  CVPixelBufferUnlockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
163 
164  //extract 3D points
165  if (pc)
166  {
167  ARPointCloud* rawFPts = [frame rawFeaturePoints];
168  if (pc != nil)
169  {
170  //(simd_float3 is an array of four floats)
171  *pc = cv::Mat((int)rawFPts.count, 4, CV_32F);
172  memcpy(pc->data, rawFPts.points, rawFPts.count * sizeof(simd_float3));
173  }
174  }
175 }
176 
177 #pragma mark - ARSessionDelegate
178 
179 - (void)session:(ARSession*)session didFailWithError:(NSError*)error
180 {
181  // Present an error message to the user
182 }
183 
184 - (void)session:(ARSession*)session cameraDidChangeTrackingState:(ARCamera*)camera
185 {
186  switch (camera.trackingState)
187  {
188  case ARTrackingStateNormal:
189  NSLog(@"Tracking is Normal.\n");
190  break;
191  case ARTrackingStateLimited:
192  NSLog(@"Tracking is limited: ");
193  switch (camera.trackingStateReason)
194  {
195  case ARTrackingStateReasonNone:
196  NSLog(@"Tracking is not limited.\n");
197  break;
198  case ARTrackingStateReasonInitializing:
199  NSLog(@"Tracking is limited due to initialization in progress.\n");
200  break;
201  case ARTrackingStateReasonExcessiveMotion:
202  NSLog(@"Tracking is limited due to a excessive motion of the camera.\n");
203  break;
204  case ARTrackingStateReasonInsufficientFeatures:
205  NSLog(@"Tracking is limited due to a lack of features visible to the camera.\n");
206  break;
207  case ARTrackingStateReasonRelocalizing:
208  NSLog(@"Tracking is limited due to a relocalization in progress.\n");
209  break;
210  default:
211  break;
212  }
213  break;
214  case ARTrackingStateNotAvailable:
215  NSLog(@"Tracking is not available.\n");
216  break;
217  default:
218  break;
219  }
220 }
221 
222 - (void)sessionWasInterrupted:(ARSession*)session
223 {
224  NSLog(@"sessionInterruptionEnded.\n");
225  // Inform the user that the session has been interrupted, for example, by presenting an overlay
226 }
227 
228 - (void)sessionInterruptionEnded:(ARSession*)session
229 {
230  NSLog(@"sessionInterruptionEnded.\n");
231  // Reset tracking and/or remove existing anchors if consistent tracking is required
232 }
233 
234 //ATTENTION: DO NO OVERRIDE THIS AND RETURN YES. It leads to problems, maybe never relocalizes..
235 //if this is overridden and returns true, it tries to relocalize rather than new initialise
236 /*
237 - (BOOL)sessionShouldAttemptRelocalization:(ARSession *)session
238 {
239  NSLog(@"sessionShouldAttemptRelocalization.\n");
240  return YES;
241 }
242 */
243 @end
typedef void(SL_STDCALL *cbOnImGuiBuild)(SLScene *s
Callback function typedef for ImGui build function.
ARConfiguration * _arConfig
int run(Config config)
App::run implementation from App.h for the Emscripten platform.
Definition: AppAndroid.cpp:78
void log(const char *tag, const char *format,...)
logs a formatted string platform independently
Definition: Utils.cpp:1100