17 #import <CoreMotion/CoreMotion.h>
29 #include <mach/mach_time.h>
30 #import <sys/utsname.h>
31 #import <mach-o/arch.h>
62 static mach_timebase_info_data_t info;
63 mach_timebase_info(&info);
64 uint64_t now = mach_absolute_time();
67 double sec = (double)now / 1000000000.0;
86 @property (strong, nonatomic) EAGLContext* context;
87 @property (strong, nonatomic) CMMotionManager* motionManager;
88 @property (strong, nonatomic) NSTimer* motionTimer;
89 @property (strong, nonatomic) CLLocationManager* locationManager;
105 self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
108 NSLog(
@"Failed to create ES3 context");
109 self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
110 if (!
self.
context) NSLog(
@"Failed to create ES2 context");
113 myView = (GLKView*)
self.view;
114 myView.context =
self.context;
115 myView.drawableDepthFormat = GLKViewDrawableDepthFormat24;
117 if ([UIDevice currentDevice].multitaskingSupported)
118 myView.drawableMultisample = GLKViewDrawableMultisample4X;
120 self.preferredFramesPerSecond = 60;
121 self.view.multipleTouchEnabled =
true;
125 [EAGLContext setCurrentContext:self.context];
130 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
132 else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
143 struct utsname systemInfo;
145 NSString* model = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
146 NSString* osver = [[UIDevice currentDevice] systemVersion];
147 const NXArchInfo* archInfo = NXGetLocalArchInfo();
148 NSString* arch = [NSString stringWithUTF8String:archInfo->description];
186 [
self setupMotionManager:1.0 / 20.0];
187 [
self setupLocationManager];
197 - (
void)didReceiveMemoryWarning
199 printf(
"didReceiveMemoryWarning\n");
201 [
super didReceiveMemoryWarning];
205 if ([EAGLContext currentContext] ==
self.context)
207 [EAGLContext setCurrentContext:nil];
218 - (
void)glkView:(GLKView*)view drawInRect:(CGRect)rect
225 [
self setVideoType:CVCapture::instance()->videoType()
226 videoSizeIndex:CVCapture::instance()->activeCamera->camSizeIndex()];
229 [
self startLocationManager];
231 [
self stopLocationManager];
249 m_lastVideoImageIsConsumed =
true;
259 - (
void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
261 NSArray* myTouches = [touches allObjects];
262 UITouch* touch1 = [myTouches objectAtIndex:0];
263 m_touchDownPos1 = [touch1 locationInView:touch1.view];
269 if (m_touchDowns > 0)
271 if (m_touchDowns == 1)
273 if (m_touchDowns == 2)
279 if (m_lastTouchTimeSec < (m_lastFrameTimeSec - 2.0f))
283 m_touchDowns += [touches count];
286 if (m_touchDowns == 1 && [touches count] == 1)
288 if (touchDownNowSec - m_lastTouchDownSec < 0.3f)
293 else if (m_touchDowns == 2)
295 if ([touches count] == 2)
297 UITouch*
touch2 = [myTouches objectAtIndex:1];
298 CGPoint pos2 = [touch2 locationInView:touch2.view];
303 else if ([touches count] == 1)
307 m_lastTouchTimeSec = m_lastTouchDownSec = touchDownNowSec;
311 - (
void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
313 NSArray* myTouches = [touches allObjects];
314 UITouch* touch1 = [myTouches objectAtIndex:0];
315 CGPoint pos1 = [touch1 locationInView:touch1.view];
319 if (m_touchDowns == 1 && [touches count] == 1)
323 else if (m_touchDowns == 2 && [touches count] == 2)
325 UITouch*
touch2 = [myTouches objectAtIndex:1];
326 CGPoint pos2 = [touch2 locationInView:touch2.view];
332 m_lastTouchTimeSec = m_lastFrameTimeSec;
336 - (
void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
338 NSArray* myTouches = [touches allObjects];
339 UITouch* touch1 = [myTouches objectAtIndex:0];
340 CGPoint pos1 = [touch1 locationInView:touch1.view];
344 int dX =
std::abs(m_touchDownPos1.x - pos1.x);
345 int dY =
std::abs(m_touchDownPos1.y - pos1.y);
346 float dSec = touchUpNowSec - m_lastTouchDownSec;
348 if (m_touchDowns == 1 || [touches count] == 1)
351 if (dSec > 0.8f && dX < 3 && dY < 3)
359 else if (m_touchDowns == 2 && [touches count] == 2)
361 UITouch*
touch2 = [myTouches objectAtIndex:1];
362 CGPoint pos2 = [touch2 locationInView:touch2.view];
372 m_lastTouchTimeSec = m_lastFrameTimeSec;
376 - (
void)touchesCancle:(NSSet*)touches withEvent:(UIEvent*)event
378 NSArray* myTouches = [touches allObjects];
379 UITouch* touch1 = [myTouches objectAtIndex:0];
380 CGPoint pos1 = [touch1 locationInView:touch1.view];
382 if (m_touchDowns == 1 || [touches count] == 1)
386 else if (m_touchDowns == 2 && [touches count] >= 2)
388 UITouch*
touch2 = [myTouches objectAtIndex:1];
389 CGPoint pos2 = [touch2 locationInView:touch2.view];
392 m_touchDowns -= (int)[touches count];
393 if (m_touchDowns < 0) m_touchDowns = 0;
397 m_lastTouchTimeSec = m_lastFrameTimeSec;
401 - (
void)captureOutput:(AVCaptureOutput*)captureOutput
402 didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
403 fromConnection:(AVCaptureConnection*)connection
406 if (!m_lastVideoImageIsConsumed)
return;
409 CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
411 CVPixelBufferLockBaseAddress(pixelBuffer, 0);
413 int imgWidth = (int)CVPixelBufferGetWidth(pixelBuffer);
414 int imgHeight = (int)CVPixelBufferGetHeight(pixelBuffer);
415 unsigned char* data = (
unsigned char*)CVPixelBufferGetBaseAddress(pixelBuffer);
419 NSLog(
@"No pixel buffer data");
425 float videoImgWdivH = (float)imgWidth / (
float)imgHeight;
441 CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
443 m_lastVideoImageIsConsumed =
false;
446 - (
void)onAccelerationData:(CMAcceleration)acceleration
452 - (
void)onGyroData:(CMRotationRate)rotation
458 - (
void)onMotionData:(CMAttitude*)attitude
462 if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft)
464 NSLog(
@"UIDeviceOrientationLandscapeLeft");
466 else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight)
468 float pitch = attitude.roll -
Utils::HALFPI;
469 float yaw = attitude.yaw -
Utils::HALFPI;
470 float roll = attitude.pitch;
471 SL_LOG(
"Pitch: %3.0f, Yaw: %3.0f, Roll: %3.0f\n",
476 else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait)
478 NSLog(
@"UIDeviceOrientationPortrait");
480 else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)
482 NSLog(
@"UIDeviceOrientationPortraitUpsideDown");
488 - (
void)setupVideo:(
bool)useFaceCamera videoSizeIndex:(
int)sizeIndex
492 case 0: m_avSessionPreset = AVCaptureSessionPreset1920x1080;
break;
493 case 1: m_avSessionPreset = AVCaptureSessionPreset1280x720;
break;
494 default: m_avSessionPreset = AVCaptureSessionPreset640x480;
498 m_avSession = [[AVCaptureSession alloc] init];
499 [m_avSession beginConfiguration];
502 [m_avSession setSessionPreset:m_avSessionPreset];
506 AVCaptureDevice* videoDevice = nil;
508 videoDevice = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera
509 mediaType:AVMediaTypeVideo
510 position:AVCaptureDevicePositionFront];
512 videoDevice = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera
513 mediaType:AVMediaTypeVideo
514 position:AVCaptureDevicePositionBack];
515 if (videoDevice == nil)
528 AVCaptureDeviceInput* input = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
532 [m_avSession addInput:input];
535 AVCaptureVideoDataOutput* dataOutput = [[AVCaptureVideoDataOutput alloc] init];
536 [dataOutput setAlwaysDiscardsLateVideoFrames:YES];
543 [dataOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
544 forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
547 [dataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
549 [m_avSession addOutput:dataOutput];
550 [m_avSession commitConfiguration];
552 m_lastVideoImageIsConsumed =
true;
559 - (
void)setVideoType:(
int)videoType
560 videoSizeIndex:(
int)sizeIndex
564 if (m_avSession != nil && ![m_avSession isRunning])
566 printf(
"Stopping AV Session\n");
567 [m_avSession stopRunning];
572 if (m_avSession != nil && ![m_avSession isRunning])
574 printf(
"Stopping AV Session\n");
575 [m_avSession stopRunning];
602 if (m_avSession == nil)
604 printf(
"Creating AV Session for Front Camera\n");
605 [
self setupVideo:false videoSizeIndex:sizeIndex];
606 printf(
"Starting AV Session\n");
607 [m_avSession startRunning];
609 else if (m_lastVideoType == videoType)
611 if (m_lastVideoSizeIndex != sizeIndex)
613 printf(
"Stopping AV Session for resolution change\n");
614 [m_avSession stopRunning];
617 else if (![m_avSession isRunning])
619 printf(
"Starting AV Session\n");
620 [m_avSession startRunning];
625 if ([m_avSession isRunning])
627 printf(
"Deleting AV Session\n");
628 [m_avSession stopRunning];
631 printf(
"Creating AV Session for Front Camera\n");
632 [
self setupVideo:false videoSizeIndex:sizeIndex];
633 printf(
"Starting AV Session\n");
634 [m_avSession startRunning];
639 if (m_avSession == nil)
641 printf(
"Creating AV Session for Back Camera\n");
642 [
self setupVideo:true videoSizeIndex:sizeIndex];
643 printf(
"Starting AV Session\n");
644 [m_avSession startRunning];
646 else if (m_lastVideoType == videoType)
648 if (m_lastVideoSizeIndex != sizeIndex)
650 printf(
"Stopping AV Session for resolution change\n");
651 [m_avSession stopRunning];
654 else if (![m_avSession isRunning])
656 printf(
"Starting AV Session\n");
657 [m_avSession startRunning];
662 if ([m_avSession isRunning])
664 printf(
"Deleting AV Session\n");
665 [m_avSession stopRunning];
668 printf(
"Creating AV Session for Back Camera\n");
669 [
self setupVideo:true videoSizeIndex:sizeIndex];
670 printf(
"Starting AV Session\n");
671 [m_avSession startRunning];
675 m_lastVideoType = videoType;
676 m_lastVideoSizeIndex = sizeIndex;
680 - (
void)setupMotionManager:(
double)intervalTimeSEC
683 self.motionManager = [[CMMotionManager alloc] init];
685 if ([
self.motionManager isDeviceMotionAvailable] == YES)
687 self.motionManager.deviceMotionUpdateInterval = intervalTimeSEC;
690 [
self.motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXMagneticNorthZVertical
691 toQueue:[NSOperationQueue currentQueue]
692 withHandler:^(CMDeviceMotion* motion, NSError* error) {
693 [
self performSelectorOnMainThread:@selector(onDeviceMotionUpdate:)
699 [
self.motionManager stopDeviceMotionUpdates];
702 - (
void)onDeviceMotionUpdate:(CMDeviceMotion*)motion
706 CMDeviceMotion* motionData =
self.motionManager.deviceMotion;
707 CMAttitude* attitude = motionData.attitude;
712 CMQuaternion q = attitude.quaternion;
715 GLKQuaternion qNWU = GLKQuaternionMake(q.x, q.y, q.z, q.w);
716 GLKQuaternion qRot90Z = GLKQuaternionMakeWithAngleAndAxis(GLKMathDegreesToRadians(90), 0, 0, 1);
717 GLKQuaternion qENU = GLKQuaternionMultiply(qRot90Z, qNWU);
729 - (
void)setupLocationManager
731 if ([CLLocationManager locationServicesEnabled])
734 self.locationManager = [[CLLocationManager alloc] init];
735 self.locationManager.delegate =
self;
736 self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
743 if ([
self.locationManager respondsToSelector:
@selector(requestWhenInUseAuthorization)])
745 [
self.locationManager requestWhenInUseAuthorization];
753 NSLog(
@"Location services are not enabled");
756 m_locationIsRunning =
false;
760 - (
void)startLocationManager
762 if (!m_locationIsRunning)
764 [
self.locationManager startUpdatingLocation];
765 m_locationIsRunning =
true;
766 printf(
"Starting Location Manager\n");
771 - (
void)stopLocationManager
773 if (m_locationIsRunning)
775 [
self.locationManager stopUpdatingLocation];
776 m_locationIsRunning =
false;
777 printf(
"Stopping Location Manager\n");
781 - (
void)locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation*)oldLocation
783 printf(
"horizontalAccuracy: %f\n", newLocation.horizontalAccuracy);
786 if (newLocation.horizontalAccuracy > 0.0)
789 newLocation.coordinate.longitude,
790 newLocation.altitude,
791 newLocation.horizontalAccuracy);
795 - (
void)locationManager:(CLLocationManager*)manager didFailWithError:(NSError*)error
801 if ([error code] != kCLErrorLocationUnknown)
803 printf(
"**** locationManager didFailWithError ****\n");
804 [
self stopLocationManager];
811 NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
814 NSString* documentsDirectory = [paths objectAtIndex:0];
815 string documentsDir = [documentsDirectory UTF8String];
816 documentsDir +=
"/SLProject";
817 NSString* documentsPath = [NSString stringWithUTF8String:documentsDir.c_str()];
821 if (![[NSFileManager defaultManager] fileExistsAtPath:documentsPath])
822 [[NSFileManager defaultManager] createDirectoryAtPath:documentsPath
823 withIntermediateDirectories:NO
827 return documentsDir +
"/";
The App namespace declares the App::Config struct and the App::run function.
The AppCommon class holds the top-level instances of the app-demo.
static SLVec2i touch2
Last finger touch 2 position in pixels.
static SLint dpi
Dot per inch resolution of screen.
@ VT_SCND
Selfie camera on mobile devices.
@ VT_FILE
Loads a video from file with OpenCV.
@ VT_NONE
No camera needed.
@ VT_MAIN
Main camera on all on all all devices.
vector< SLstring > SLVstring
typedef void(SL_STDCALL *cbOnImGuiBuild)(SLScene *s
Callback function typedef for ImGui build function.
void slRotationQUAT(float quatX, float quatY, float quatZ, float quatW)
void slTouch2Move(int sceneViewIndex, int xpos1, int ypos1, int xpos2, int ypos2)
void slMouseDown(int sceneViewIndex, SLMouseButton button, int xpos, int ypos, SLKey modifier)
void slTouch2Down(int sceneViewIndex, int xpos1, int ypos1, int xpos2, int ypos2)
void slMouseMove(int sceneViewIndex, int x, int y)
void slSwitchScene(SLSceneView *sv, SLSceneID sceneID)
void slLocationLatLonAlt(double latitudeDEG, double longitudeDEG, double altitudeM, float accuracyM)
void slMouseUp(int sceneViewIndex, SLMouseButton button, int xpos, int ypos, SLKey modifier)
void slTouch2Up(int sceneViewIndex, int xpos1, int ypos1, int xpos2, int ypos2)
void slDoubleClick(int sceneViewIndex, SLMouseButton button, int xpos, int ypos, SLKey modifier)
void slLoadCoreAssetsSync()
void slResize(int sceneViewIndex, int width, int height)
bool slUpdateParallelJob()
void slCreateApp(SLVstring &cmdLineArgs, const SLstring &dataPath, const SLstring &shaderPath, const SLstring &modelPath, const SLstring &texturePath, const SLstring &fontPath, const SLstring &videoPath, const SLstring &configPath, const SLstring &applicationName)
SLint slCreateSceneView(SLAssetManager *am, SLScene *scene, int screenWidth, int screenHeight, int dotsPerInch, SLSceneID initScene, void *onWndUpdateCallback, void *onSelectNodeMeshCallback, void *onNewSceneViewCallback, void *onImGuiBuild, void *onImGuiLoadConfig, void *onImGuiSaveConfig)
Declaration of the main Scene Library C-Interface.
static SLstring configPath
Default path for calibration files.
static SLstring calibIniPath
That's where data/calibrations folder is located.
static optional< SLSceneID > sceneToLoad
Scene id to load at start up.
static SLAssetManager * assetManager
asset manager is the owner of all assets
static SLstring exePath
executable root path
static SLVSceneView sceneViews
Vector of sceneview pointers.
static SLAssetLoader * assetLoader
Asset-loader for async asset loading.
static SLstring externalPath
Default path for external file storage.
static SLScene * scene
Pointer to the one and only SLScene instance.
Encapsulation of the OpenCV Capture Device and holder of the last frame.
void loadCalibrations(const string &computerInfo, const string &configPath)
CVSize captureSize
size of captured frame
void setCameraSize(int sizeIndex, int sizeIndexMax, int width, int height)
static CVCapture * instance()
Public static instance getter for singleton pattern.
void loadIntoLastFrame(float vieportWdivH, int camWidth, int camHeight, CVPixelFormatGL srcPixelFormat, const uchar *data, bool isContinuous)
bool grabAndAdjustForSL(float viewportWdivH)
void checkIfAsyncLoadingIsDone()
SceneView class represents a dynamic real time 3D view onto the scene.
void viewportSameAsVideo(bool sameAsVideo)
void setViewportFromRatio(const SLVec2i &vpRatio, SLViewportAlign vpAlignment, SLbool vpSameAsVideo)
Sets the viewport ratio and the viewport rectangle.
SLViewportAlign viewportAlign() const
SLfloat viewportWdivH() const
static std::string getCurrentWorkingDir()
Returns the working directory.
static std::string getAppsWritableDir()
Returns the writable configuration directory.
AVCaptureSession * m_avSession
SLfloat m_lastFrameTimeSec
SLfloat m_lastTouchDownSec
NSString * m_avSessionPreset
bool m_lastVideoImageIsConsumed
SLfloat m_lastTouchTimeSec
std::string getAppsDocumentsDir()
Config config
The configuration set in App::run.
Utils provides utilities for string & file handling, logging and math functions.
static const float RAD2DEG
OnGuiLoadConfigCallback onGuiLoadConfig
OnNewSceneViewCallback onNewSceneView
OnUpdateCallback onUpdate
OnGuiSaveConfigCallback onGuiSaveConfig
OnGuiBuildCallback onGuiBuild