├── .gitignore ├── ARKit ├── ARCoordinate.h ├── ARCoordinate.m ├── ARGeoCoordinate.h ├── ARGeoCoordinate.m ├── ARKit.h ├── ARKit.m ├── ARLocationDelegate.h ├── ARViewController.h ├── ARViewController.m ├── ARViewProtocol.h ├── AugmentedRealityController.h ├── AugmentedRealityController.m ├── GEOLocations.h ├── GEOLocations.m ├── Images │ ├── bgCallout.png │ ├── bgCallout@2x.png │ ├── bgCalloutDisclosure.png │ └── bgCalloutDisclosure@2x.png ├── MarkerView.h ├── MarkerView.m ├── Radar.h ├── Radar.m ├── RadarViewPortView.h └── RadarViewPortView.m ├── LICENSE.txt ├── README.markdown └── iPhone-AR-Demo ├── iPhone-AR-Demo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── ed.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── ed.xcuserdatad │ └── xcdebugger │ └── Breakpoints.xcbkptlist └── iPhone-AR-Demo ├── AppDelegate.h ├── AppDelegate.m ├── Default-568h@2x.png ├── Default.png ├── Default@2x.png ├── ViewController.h ├── ViewController.m ├── en.lproj ├── InfoPlist.strings └── MainStoryboard.storyboard ├── iPhone-AR-Demo-Info.plist ├── iPhone-AR-Demo-Prefix.pch └── main.m /.gitignore: -------------------------------------------------------------------------------- 1 | Assets/ 2 | build/ 3 | Payload/ 4 | .DS_Store 5 | *~.nib 6 | *.mode1v3 7 | *.mode2v3 8 | *.pbxuser 9 | *.perspective 10 | *.perspectivev3 11 | *.[oa] 12 | *.ipa 13 | 14 | .svn/ 15 | *.pyc 16 | *.pyo 17 | .DS_Store 18 | *.db 19 | *.swp 20 | *.lock 21 | *~ 22 | *.tmp 23 | *.bak 24 | access.log 25 | error.log 26 | *.pid 27 | .pid 28 | .fseventsd 29 | .Trashes 30 | 31 | # Xcode User-specific data 32 | !default.pbxuser 33 | !default.mode1v3 34 | !default.mode2v3 35 | !default.perspectivev3 36 | xcuserdata 37 | !xcshareddata 38 | *.moved-aside 39 | -------------------------------------------------------------------------------- /ARKit/ARCoordinate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARCoordinate.h 3 | // AR Kit 4 | // 5 | // Created by Zac White on 8/1/09. 6 | // Modified by Ed Rackham (a1phanumeric) 2013 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #define degreesToRadians(x) (M_PI * x / 180.0) 13 | #define radiansToDegrees(x) (x * (180.0/M_PI)) 14 | 15 | @interface ARCoordinate : NSObject 16 | 17 | - (NSUInteger)hash; 18 | - (BOOL)isEqual:(id)other; 19 | - (BOOL)isEqualToCoordinate:(ARCoordinate *)otherCoordinate; 20 | 21 | + (ARCoordinate *)coordinateWithRadialDistance:(double)newRadialDistance inclination:(double)newInclination azimuth:(double)newAzimuth; 22 | 23 | @property (nonatomic, retain) NSString *title; 24 | @property (nonatomic, copy) NSString *subtitle; 25 | @property (nonatomic) double radialDistance; 26 | @property (nonatomic) double inclination; 27 | @property (nonatomic) double azimuth; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /ARKit/ARCoordinate.m: -------------------------------------------------------------------------------- 1 | // 2 | // ARCoordinate.m 3 | // AR Kit 4 | // 5 | // Modified by Niels Hansen on 10/02/11 6 | // Modified by Ed Rackham (a1phanumeric) 2013 7 | // 8 | 9 | #import "ARCoordinate.h" 10 | 11 | @implementation ARCoordinate 12 | 13 | @synthesize radialDistance; 14 | @synthesize inclination; 15 | @synthesize azimuth; 16 | @synthesize title; 17 | @synthesize subtitle; 18 | 19 | + (ARCoordinate *)coordinateWithRadialDistance:(double)newRadialDistance inclination:(double)newInclination azimuth:(double)newAzimuth { 20 | 21 | ARCoordinate *newCoordinate = [[ARCoordinate alloc] init]; 22 | [newCoordinate setRadialDistance: newRadialDistance]; 23 | [newCoordinate setInclination: newInclination]; 24 | [newCoordinate setAzimuth: newAzimuth]; 25 | [newCoordinate setTitle: @""]; 26 | 27 | return newCoordinate; 28 | } 29 | 30 | - (NSUInteger)hash { 31 | return ([[self title] hash] ^ [[self subtitle] hash]) + (int)([self radialDistance] + [self inclination] + [self azimuth]); 32 | } 33 | 34 | - (BOOL)isEqual:(id)other { 35 | 36 | if (other == self) 37 | return YES; 38 | 39 | if (!other || ![other isKindOfClass:[self class]]) 40 | return NO; 41 | 42 | return [self isEqualToCoordinate:other]; 43 | } 44 | 45 | - (BOOL)isEqualToCoordinate:(ARCoordinate *)otherCoordinate { 46 | 47 | if (self == otherCoordinate) 48 | return YES; 49 | 50 | BOOL equal = [self radialDistance] == [otherCoordinate radialDistance]; 51 | equal = equal && [self inclination] == [otherCoordinate inclination]; 52 | equal = equal && [self azimuth] == [otherCoordinate azimuth]; 53 | 54 | if (([self title] && [otherCoordinate title]) || ([self title] && ![otherCoordinate title]) || (![self title] && [otherCoordinate title])) 55 | equal = equal && [[self title] isEqualToString:[otherCoordinate title]]; 56 | 57 | return equal; 58 | } 59 | 60 | - (NSString *)description { 61 | return [NSString stringWithFormat:@"%@ r: %.3fm φ: %.3f° θ: %.3f°", [self title], [self radialDistance], radiansToDegrees([self azimuth]), radiansToDegrees([self inclination])]; 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /ARKit/ARGeoCoordinate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARGeoCoordinate.h 3 | // AR Kit 4 | // 5 | // Created by Haseman on 8/1/09. 6 | // Modified by Ed Rackham (a1phanumeric) 2013 7 | // 8 | 9 | #import 10 | #import 11 | #import "ARCoordinate.h" 12 | 13 | @interface ARGeoCoordinate : ARCoordinate 14 | 15 | @property (nonatomic, retain) CLLocation *geoLocation; 16 | @property (nonatomic, retain) UIView *displayView; 17 | @property (nonatomic) double distanceFromOrigin; 18 | 19 | 20 | - (float)angleFromCoordinate:(CLLocationCoordinate2D)first toCoordinate:(CLLocationCoordinate2D)second; 21 | 22 | + (ARGeoCoordinate *)coordinateWithLocation:(CLLocation *)location locationTitle:(NSString *)titleOfLocation; 23 | + (ARGeoCoordinate *)coordinateWithLocation:(CLLocation *)location fromOrigin:(CLLocation *)origin; 24 | 25 | - (void)calibrateUsingOrigin:(CLLocation *)origin; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /ARKit/ARGeoCoordinate.m: -------------------------------------------------------------------------------- 1 | // 2 | // ARGeoCoordinate.m 3 | // AR Kit 4 | // 5 | // Modified by Niels Hansen on 11/23/11 6 | // Modified by Ed Rackham (a1phanumeric) 2013 7 | // 8 | 9 | #import "ARGeoCoordinate.h" 10 | 11 | @implementation ARGeoCoordinate 12 | @synthesize distanceFromOrigin; 13 | @synthesize geoLocation; 14 | @synthesize displayView; 15 | 16 | - (float)angleFromCoordinate:(CLLocationCoordinate2D)first toCoordinate:(CLLocationCoordinate2D)second{ 17 | 18 | float longitudinalDifference = second.longitude - first.longitude; 19 | float latitudinalDifference = second.latitude - first.latitude; 20 | float possibleAzimuth = (M_PI * .5f) - atan(latitudinalDifference / longitudinalDifference); 21 | 22 | if (longitudinalDifference > 0) 23 | return possibleAzimuth; 24 | else if (longitudinalDifference < 0) 25 | return possibleAzimuth + M_PI; 26 | else if (latitudinalDifference < 0) 27 | return M_PI; 28 | 29 | return 0.0f; 30 | } 31 | 32 | - (void)calibrateUsingOrigin:(CLLocation *)origin { 33 | 34 | if (![self geoLocation]) 35 | return; 36 | 37 | [self setDistanceFromOrigin:[origin distanceFromLocation:[self geoLocation]]]; 38 | [self setRadialDistance: sqrt(pow([origin altitude] - [[self geoLocation] altitude], 2) + pow([self distanceFromOrigin], 2))]; 39 | 40 | float angle = sin(ABS([origin altitude] - [[self geoLocation] altitude]) / [self radialDistance]); 41 | 42 | if ([origin altitude] > [[self geoLocation] altitude]) 43 | angle = -angle; 44 | 45 | [self setInclination: angle]; 46 | [self setAzimuth: [self angleFromCoordinate:[origin coordinate] toCoordinate:[[self geoLocation] coordinate]]]; 47 | 48 | //NSLog(@"distance from %@ is %f, angle is %f, azimuth is %f",[self title], [self distanceFromOrigin],angle,[self azimuth]); 49 | } 50 | 51 | + (ARGeoCoordinate *)coordinateWithLocation:(CLLocation *)location locationTitle:(NSString *)titleOfLocation { 52 | 53 | ARGeoCoordinate *newCoordinate = [[ARGeoCoordinate alloc] init]; 54 | [newCoordinate setGeoLocation: location]; 55 | [newCoordinate setTitle: titleOfLocation]; 56 | 57 | return newCoordinate; 58 | } 59 | 60 | + (ARGeoCoordinate *)coordinateWithLocation:(CLLocation *)location fromOrigin:(CLLocation *)origin { 61 | 62 | ARGeoCoordinate *newCoordinate = [ARGeoCoordinate coordinateWithLocation:location locationTitle:@""]; 63 | [newCoordinate calibrateUsingOrigin:origin]; 64 | return newCoordinate; 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /ARKit/ARKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARKit.h 3 | // AR Kit 4 | // 5 | // Modified by Niels Hansen on 11/20/11. 6 | // Modified by Ed Rackham (a1phanumeric) 2013 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import "ARViewController.h" 13 | #import "ARLocationDelegate.h" 14 | 15 | @interface ARKit : NSObject 16 | 17 | + (BOOL)deviceSupportsAR; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /ARKit/ARKit.m: -------------------------------------------------------------------------------- 1 | // 2 | // ARKit.m 3 | // AR Kit 4 | // 5 | // Modifed by Niels Hansen 11/20/11. 6 | // Modified by Ed Rackham (a1phanumeric) 2013 7 | // 8 | 9 | #import "ARKit.h" 10 | 11 | 12 | @implementation ARKit 13 | 14 | + (BOOL)deviceSupportsAR{ 15 | 16 | // Go thru and see if the device supports Video Capture. 17 | NSArray *devices = [AVCaptureDevice devices]; 18 | 19 | BOOL suportsVideo = NO; 20 | 21 | if (devices != nil && [devices count] > 0) { 22 | for (AVCaptureDevice *device in devices) { 23 | if ([device hasMediaType:AVMediaTypeVideo]) { 24 | suportsVideo = YES; 25 | break; 26 | } 27 | } 28 | } 29 | 30 | if (!suportsVideo) 31 | return NO; 32 | 33 | //TODO: Check to see if Device supports the Gyroscope (iPhone4 and higher) 34 | 35 | 36 | if(![CLLocationManager headingAvailable]){ 37 | return NO; 38 | } 39 | 40 | return YES; 41 | } 42 | @end 43 | -------------------------------------------------------------------------------- /ARKit/ARLocationDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARLocationDelegate.h 3 | // AR Kit 4 | // 5 | // Created by Jared Crawford on 2/13/10. 6 | // Modified by Ed Rackham (a1phanumeric) 2013 7 | // 8 | 9 | #import 10 | #import "ARGeoCoordinate.h" 11 | 12 | 13 | @protocol ARLocationDelegate 14 | 15 | //returns an array of ARGeoCoordinates 16 | - (NSMutableArray *)geoLocations; 17 | - (void)locationClicked:(ARGeoCoordinate *)coordinate; 18 | 19 | @end 20 | 21 | -------------------------------------------------------------------------------- /ARKit/ARViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARViewController.h 3 | // ARKitDemo 4 | // 5 | // Modified by Niels W Hansen on 12/31/11. 6 | // Modified by Ed Rackham (a1phanumeric) 2013 7 | // 8 | 9 | #import 10 | #import "ARLocationDelegate.h" 11 | #import "ARViewProtocol.h" 12 | 13 | @class AugmentedRealityController; 14 | 15 | @interface ARViewController : UIViewController 16 | 17 | @property (nonatomic, assign) id delegate; 18 | @property (assign, nonatomic) BOOL showsCloseButton; 19 | 20 | @property (assign, nonatomic, setter = setDebugMode:) BOOL debugMode; 21 | @property (assign, nonatomic, setter = setShowsRadar:) BOOL showsRadar; 22 | @property (assign, nonatomic, setter = setScaleViewsBasedOnDistance:) BOOL scaleViewsBasedOnDistance; 23 | @property (assign, nonatomic, setter = setMinimumScaleFactor:) float minimumScaleFactor; 24 | @property (assign, nonatomic, setter = setRotateViewsBasedOnPerspective:) BOOL rotateViewsBasedOnPerspective; 25 | @property (strong, nonatomic, setter = setRadarPointColour:) UIColor *radarPointColour; 26 | @property (strong, nonatomic, setter = setRadarBackgroundColour:) UIColor *radarBackgroundColour; 27 | @property (strong, nonatomic, setter = setRadarViewportColour:) UIColor *radarViewportColour; 28 | @property (assign, nonatomic, setter = setRadarRange:) float radarRange; 29 | @property (assign, nonatomic, setter = setOnlyShowItemsWithinRadarRange:) BOOL onlyShowItemsWithinRadarRange; 30 | 31 | - (id)initWithDelegate:(id)aDelegate; 32 | 33 | @end 34 | 35 | -------------------------------------------------------------------------------- /ARKit/ARViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ARViewController.m 3 | // ARKitDemo 4 | // 5 | // Modified by Niels W Hansen on 12/31/11. 6 | // Modified by Ed Rackham (a1phanumeric) 2013 7 | // 8 | 9 | #import "ARViewController.h" 10 | #import "AugmentedRealityController.h" 11 | #import "GEOLocations.h" 12 | #import "MarkerView.h" 13 | 14 | @implementation ARViewController{ 15 | AugmentedRealityController *_agController; 16 | } 17 | 18 | @synthesize delegate; 19 | 20 | - (id)initWithDelegate:(id)aDelegate{ 21 | 22 | [self setDelegate:aDelegate]; 23 | 24 | if (!(self = [super init])){ 25 | return nil; 26 | } 27 | 28 | [self setWantsFullScreenLayout:NO]; 29 | 30 | // Defaults 31 | _debugMode = NO; 32 | _scaleViewsBasedOnDistance = YES; 33 | _minimumScaleFactor = 0.5; 34 | _rotateViewsBasedOnPerspective = YES; 35 | _showsRadar = YES; 36 | _showsCloseButton = YES; 37 | _radarRange = 20.0; 38 | _onlyShowItemsWithinRadarRange = NO; 39 | 40 | // Create ARC 41 | _agController = [[AugmentedRealityController alloc] initWithViewController:self withDelgate:self]; 42 | 43 | [_agController setShowsRadar:_showsRadar]; 44 | [_agController setRadarRange:_radarRange]; 45 | [_agController setScaleViewsBasedOnDistance:_scaleViewsBasedOnDistance]; 46 | [_agController setMinimumScaleFactor:_minimumScaleFactor]; 47 | [_agController setRotateViewsBasedOnPerspective:_rotateViewsBasedOnPerspective]; 48 | [_agController setOnlyShowItemsWithinRadarRange:_onlyShowItemsWithinRadarRange]; 49 | 50 | GEOLocations *locations = [[GEOLocations alloc] initWithDelegate:delegate]; 51 | 52 | if([[locations returnLocations] count] > 0){ 53 | for (ARGeoCoordinate *coordinate in [locations returnLocations]){ 54 | MarkerView *cv = [[MarkerView alloc] initForCoordinate:coordinate withDelgate:self allowsCallout:YES]; 55 | [coordinate setDisplayView:cv]; 56 | [_agController addCoordinate:coordinate]; 57 | } 58 | } 59 | 60 | [self.view setAutoresizesSubviews:YES]; 61 | 62 | 63 | return self; 64 | } 65 | 66 | - (void)closeButtonClicked:(id)sender { 67 | _agController = nil; 68 | [self dismissViewControllerAnimated:YES completion:nil]; 69 | } 70 | 71 | - (void)viewDidAppear:(BOOL)animated { 72 | [super viewDidAppear:animated]; 73 | } 74 | 75 | - (void)viewWillAppear:(BOOL)animated { 76 | [super viewWillAppear:animated]; 77 | 78 | if(_showsCloseButton == YES) { 79 | UIButton *closeBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 60, 30)]; 80 | 81 | [closeBtn setTitle:@"Close" forState:UIControlStateNormal]; 82 | [closeBtn.titleLabel setFont:[UIFont boldSystemFontOfSize:13.0]]; 83 | [closeBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 84 | [closeBtn.titleLabel setShadowColor:[UIColor colorWithWhite:0.1 alpha:1.0]]; 85 | [closeBtn.titleLabel setShadowOffset:CGSizeMake(0, -1)]; 86 | [closeBtn setBackgroundColor:[UIColor colorWithWhite:0.3 alpha:1.0]]; 87 | [closeBtn addTarget:self action:@selector(closeButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; 88 | [[self view] addSubview:closeBtn]; 89 | } 90 | } 91 | 92 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 93 | return YES; 94 | } 95 | 96 | - (BOOL)shouldAutorotate{ 97 | return YES; 98 | } 99 | 100 | - (void)didTapMarker:(ARGeoCoordinate *)coordinate { 101 | NSLog(@"delegate worked click on %@", [coordinate title]); 102 | [delegate locationClicked:coordinate]; 103 | 104 | } 105 | 106 | - (void)didUpdateHeading:(CLHeading *)newHeading { 107 | //NSLog(@"Heading Updated"); 108 | } 109 | - (void)didUpdateLocation:(CLLocation *)newLocation { 110 | //NSLog(@"Location Updated"); 111 | } 112 | - (void)didUpdateOrientation:(UIDeviceOrientation)orientation { 113 | /*NSLog(@"Orientation Updated"); 114 | 115 | if(orientation == UIDeviceOrientationPortrait) 116 | NSLog(@"Portrait"); 117 | */ 118 | } 119 | 120 | #pragma mark - Custom Setters 121 | - (void)setDebugMode:(BOOL)debugMode{ 122 | _debugMode = debugMode; 123 | [_agController setDebugMode:_debugMode]; 124 | } 125 | 126 | - (void)setShowsRadar:(BOOL)showsRadar{ 127 | _showsRadar = showsRadar; 128 | [_agController setShowsRadar:_showsRadar]; 129 | } 130 | 131 | - (void)setScaleViewsBasedOnDistance:(BOOL)scaleViewsBasedOnDistance{ 132 | _scaleViewsBasedOnDistance = scaleViewsBasedOnDistance; 133 | [_agController setScaleViewsBasedOnDistance:_scaleViewsBasedOnDistance]; 134 | } 135 | 136 | - (void)setMinimumScaleFactor:(float)minimumScaleFactor{ 137 | _minimumScaleFactor = minimumScaleFactor; 138 | [_agController setMinimumScaleFactor:_minimumScaleFactor]; 139 | } 140 | 141 | - (void)setRotateViewsBasedOnPerspective:(BOOL)rotateViewsBasedOnPerspective{ 142 | _rotateViewsBasedOnPerspective = rotateViewsBasedOnPerspective; 143 | [_agController setRotateViewsBasedOnPerspective:_rotateViewsBasedOnPerspective]; 144 | } 145 | 146 | - (void)setRadarPointColour:(UIColor *)radarPointColour{ 147 | _radarPointColour = radarPointColour; 148 | [_agController.radarView setPointColour:_radarPointColour]; 149 | } 150 | 151 | - (void)setRadarBackgroundColour:(UIColor *)radarBackgroundColour{ 152 | _radarBackgroundColour = radarBackgroundColour; 153 | [_agController.radarView setRadarBackgroundColour:_radarBackgroundColour]; 154 | } 155 | 156 | - (void)setRadarViewportColour:(UIColor *)radarViewportColour{ 157 | _radarViewportColour = radarViewportColour; 158 | [_agController.radarViewPort setViewportColour:_radarViewportColour]; 159 | } 160 | 161 | - (void)setRadarRange:(float)radarRange{ 162 | _radarRange = radarRange; 163 | [_agController setRadarRange:_radarRange]; 164 | } 165 | 166 | - (void)setOnlyShowItemsWithinRadarRange:(BOOL)onlyShowItemsWithinRadarRange{ 167 | _onlyShowItemsWithinRadarRange = onlyShowItemsWithinRadarRange; 168 | [_agController setOnlyShowItemsWithinRadarRange:_onlyShowItemsWithinRadarRange]; 169 | } 170 | 171 | 172 | #pragma mark - View Cleanup 173 | - (void)didReceiveMemoryWarning { 174 | // Releases the view if it doesn't have a superview. 175 | [super didReceiveMemoryWarning]; 176 | } 177 | 178 | - (void)viewDidUnload { 179 | _agController = nil; 180 | } 181 | 182 | @end 183 | -------------------------------------------------------------------------------- /ARKit/ARViewProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARViewProtocol.h 3 | // AR Kit 4 | // 5 | // Modified by Niels Hansen on 12/31/11. 6 | // Modified by Ed Rackham (a1phanumeric) 2013 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @class ARGeoCoordinate; 13 | 14 | @protocol ARMarkerDelegate 15 | - (void)didTapMarker:(ARGeoCoordinate *)coordinate; 16 | @end 17 | 18 | @protocol ARDelegate 19 | - (void)didUpdateHeading:(CLHeading *)newHeading; 20 | - (void)didUpdateLocation:(CLLocation *)newLocation; 21 | - (void)didUpdateOrientation:(UIDeviceOrientation)orientation; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /ARKit/AugmentedRealityController.h: -------------------------------------------------------------------------------- 1 | // 2 | // AugmentedRealityController.h 3 | // AR Kit 4 | // 5 | // Modified by Niels W Hansen on 12/31/11. 6 | // Modified by Ed Rackham (a1phanumeric) 2013 7 | // 8 | 9 | #import 10 | #import 11 | #import "ARViewController.h" 12 | #import 13 | #import 14 | #import "Radar.h" 15 | #import "RadarViewPortView.h" 16 | 17 | @class ARCoordinate; 18 | 19 | @interface AugmentedRealityController : NSObject { 20 | 21 | @private 22 | double latestHeading; 23 | double degreeRange; 24 | 25 | BOOL debugMode; 26 | 27 | float viewAngle; 28 | float prevHeading; 29 | int cameraOrientation; 30 | 31 | NSMutableArray *coordinates; 32 | 33 | AVCaptureSession *captureSession; 34 | AVCaptureVideoPreviewLayer *previewLayer; 35 | 36 | UIAccelerometer *accelerometerManager; 37 | CLLocation *centerLocation; 38 | UIView *displayView; 39 | UILabel *radarNorthLabel; 40 | } 41 | 42 | @property BOOL scaleViewsBasedOnDistance; 43 | @property BOOL rotateViewsBasedOnPerspective; 44 | @property BOOL debugMode; 45 | 46 | @property double maximumScaleDistance; 47 | @property double minimumScaleFactor; 48 | @property double maximumRotationAngle; 49 | 50 | @property (nonatomic, assign, setter = setShowsRadar:) BOOL showsRadar; 51 | 52 | @property (nonatomic, retain) UIAccelerometer *accelerometerManager; 53 | @property (nonatomic, retain) CLLocationManager *locationManager; 54 | @property (nonatomic, retain) ARCoordinate *centerCoordinate; 55 | @property (nonatomic, retain) CLLocation *centerLocation; 56 | @property (nonatomic, retain) UIView *displayView; 57 | @property (nonatomic, retain) UIView *cameraView; 58 | @property (nonatomic, retain) UIViewController *rootViewController; 59 | @property (nonatomic, retain) AVCaptureSession *captureSession; 60 | @property (nonatomic, retain) AVCaptureVideoPreviewLayer *previewLayer; 61 | 62 | @property (assign, nonatomic) BOOL onlyShowItemsWithinRadarRange; 63 | @property (strong, nonatomic) Radar *radarView; 64 | @property (strong, nonatomic) RadarViewPortView *radarViewPort; 65 | @property (assign, nonatomic) float radarRange; 66 | 67 | @property (nonatomic, assign) id delegate; 68 | 69 | @property (nonatomic,retain) NSMutableArray *coordinates; 70 | 71 | - (id)initWithViewController:(UIViewController *)theView withDelgate:(id) aDelegate; 72 | 73 | - (void) updateLocations; 74 | - (void) stopListening; 75 | 76 | // Adding coordinates to the underlying data model. 77 | - (void)addCoordinate:(ARGeoCoordinate *)coordinate; 78 | 79 | // Removing coordinates 80 | - (void)removeCoordinate:(ARGeoCoordinate *)coordinate; 81 | - (void)removeCoordinates:(NSArray *)coordinateArray; 82 | 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /ARKit/AugmentedRealityController.m: -------------------------------------------------------------------------------- 1 | // 2 | // AugmentedRealityController.m 3 | // AR Kit 4 | // 5 | // Modified by Niels W Hansen on 5/25/12. 6 | // Modified by Ed Rackham (a1phanumeric) 2013 7 | // 8 | 9 | #import "AugmentedRealityController.h" 10 | #import "ARCoordinate.h" 11 | #import "ARGeoCoordinate.h" 12 | #import 13 | #import 14 | #import 15 | 16 | #define kFilteringFactor 0.05 17 | #define degreesToRadian(x) (M_PI * (x) / 180.0) 18 | #define radianToDegrees(x) ((x) * 180.0/M_PI) 19 | #define M_2PI 2.0 * M_PI 20 | #define BOX_WIDTH 150 21 | #define BOX_HEIGHT 100 22 | #define BOX_GAP 10 23 | #define ADJUST_BY 30 24 | #define DISTANCE_FILTER 2.0 25 | #define HEADING_FILTER 1.0 26 | #define INTERVAL_UPDATE 0.75 27 | #define SCALE_FACTOR 1.0 28 | #define HEADING_NOT_SET -1.0 29 | #define DEGREE_TO_UPDATE 1 30 | 31 | 32 | @interface AugmentedRealityController (Private) 33 | - (void) updateCenterCoordinate; 34 | - (void) startListening; 35 | - (void) currentDeviceOrientation; 36 | 37 | - (double) findDeltaOfRadianCenter:(double*)centerAzimuth coordinateAzimuth:(double)pointAzimuth betweenNorth:(BOOL*) isBetweenNorth; 38 | - (CGPoint) pointForCoordinate:(ARCoordinate *)coordinate; 39 | - (BOOL) shouldDisplayCoordinate:(ARCoordinate *)coordinate; 40 | 41 | @end 42 | 43 | @implementation AugmentedRealityController 44 | 45 | @synthesize locationManager; 46 | @synthesize accelerometerManager; 47 | @synthesize displayView; 48 | @synthesize cameraView; 49 | @synthesize rootViewController; 50 | @synthesize centerCoordinate; 51 | @synthesize scaleViewsBasedOnDistance; 52 | @synthesize rotateViewsBasedOnPerspective; 53 | @synthesize maximumScaleDistance; 54 | @synthesize minimumScaleFactor; 55 | @synthesize maximumRotationAngle; 56 | @synthesize centerLocation; 57 | @synthesize coordinates; 58 | @synthesize debugMode; 59 | @synthesize captureSession; 60 | @synthesize previewLayer; 61 | @synthesize delegate; 62 | 63 | 64 | - (id)initWithViewController:(UIViewController *)vc withDelgate:(id) aDelegate { 65 | 66 | if (!(self = [super init])) 67 | return nil; 68 | 69 | [self setDelegate:aDelegate]; 70 | 71 | latestHeading = HEADING_NOT_SET; 72 | prevHeading = HEADING_NOT_SET; 73 | 74 | [self setRootViewController: vc]; 75 | [self setMaximumScaleDistance: 0.0]; 76 | [self setMinimumScaleFactor: SCALE_FACTOR]; 77 | [self setScaleViewsBasedOnDistance: NO]; 78 | [self setRotateViewsBasedOnPerspective: NO]; 79 | [self setOnlyShowItemsWithinRadarRange:NO]; 80 | [self setMaximumRotationAngle: M_PI / 6.0]; 81 | [self setCoordinates:[NSMutableArray array]]; 82 | [self currentDeviceOrientation]; 83 | 84 | CGRect screenRect = [[UIScreen mainScreen] bounds]; 85 | 86 | if (cameraOrientation == UIDeviceOrientationLandscapeLeft || cameraOrientation == UIDeviceOrientationLandscapeRight) { 87 | screenRect.size.width = [[UIScreen mainScreen] bounds].size.height; 88 | screenRect.size.height = [[UIScreen mainScreen] bounds].size.width; 89 | } 90 | 91 | UIView *camView = [[UIView alloc] initWithFrame:screenRect]; 92 | UIView *displayV= [[UIView alloc] initWithFrame:screenRect]; 93 | 94 | [displayV setAutoresizesSubviews:YES]; 95 | [camView setAutoresizesSubviews:YES]; 96 | 97 | camView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 98 | displayV.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 99 | 100 | degreeRange = [camView bounds].size.width / ADJUST_BY; 101 | 102 | 103 | [vc setView:displayV]; 104 | [[vc view] insertSubview:camView atIndex:0]; 105 | 106 | 107 | #if !TARGET_IPHONE_SIMULATOR 108 | 109 | AVCaptureSession *avCaptureSession = [[AVCaptureSession alloc] init]; 110 | AVCaptureDevice *videoCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 111 | 112 | NSError *error = nil; 113 | 114 | AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoCaptureDevice error:&error]; 115 | 116 | if (videoInput) { 117 | [avCaptureSession addInput:videoInput]; 118 | } 119 | else { 120 | // Handle the failure. 121 | } 122 | 123 | AVCaptureVideoPreviewLayer *newCaptureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:avCaptureSession]; 124 | 125 | [[camView layer] setMasksToBounds:NO]; 126 | 127 | [newCaptureVideoPreviewLayer setFrame:[camView bounds]]; 128 | 129 | if ([newCaptureVideoPreviewLayer.connection isVideoOrientationSupported]) { 130 | [newCaptureVideoPreviewLayer.connection setVideoOrientation:cameraOrientation]; 131 | } 132 | 133 | [newCaptureVideoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; 134 | 135 | [[camView layer] insertSublayer:newCaptureVideoPreviewLayer below:[[[camView layer] sublayers] objectAtIndex:0]]; 136 | 137 | [self setPreviewLayer:newCaptureVideoPreviewLayer]; 138 | 139 | [avCaptureSession setSessionPreset:AVCaptureSessionPresetHigh]; 140 | [avCaptureSession startRunning]; 141 | 142 | [self setCaptureSession:avCaptureSession]; 143 | #endif 144 | 145 | CLLocation *newCenter = [[CLLocation alloc] initWithLatitude:37.41711 longitude:-122.02528]; //TODO: We should get the latest heading here. 146 | 147 | [self setCenterLocation: newCenter]; 148 | 149 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) 150 | name: UIDeviceOrientationDidChangeNotification object:nil]; 151 | [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 152 | 153 | 154 | [self startListening]; 155 | [self setCameraView:camView]; 156 | [self setDisplayView:displayV]; 157 | 158 | 159 | return self; 160 | } 161 | 162 | - (BOOL)shouldAutorotate{ 163 | return YES; 164 | } 165 | 166 | - (void)setShowsRadar:(BOOL)showsRadar{ 167 | _showsRadar = showsRadar; 168 | 169 | [_radarView removeFromSuperview]; 170 | [_radarViewPort removeFromSuperview]; 171 | [radarNorthLabel removeFromSuperview]; 172 | 173 | _radarView = nil; 174 | _radarViewPort = nil; 175 | radarNorthLabel = nil; 176 | 177 | if(_showsRadar){ 178 | 179 | CGRect displayFrame = [[[self rootViewController] view] frame]; 180 | 181 | _radarView = [[Radar alloc] initWithFrame:CGRectMake(displayFrame.size.width - 63, 2, 61, 61)]; 182 | _radarViewPort = [[RadarViewPortView alloc] initWithFrame:CGRectMake(displayFrame.size.width - 63, 2, 61, 61)]; 183 | 184 | radarNorthLabel = [[UILabel alloc] initWithFrame:CGRectMake(displayFrame.size.width - 37, 2, 10, 10)]; 185 | radarNorthLabel.backgroundColor = [UIColor clearColor]; 186 | radarNorthLabel.textColor = [UIColor whiteColor]; 187 | radarNorthLabel.font = [UIFont boldSystemFontOfSize:8.0]; 188 | radarNorthLabel.textAlignment = NSTextAlignmentCenter; 189 | radarNorthLabel.text = @"N"; 190 | radarNorthLabel.alpha = 0.8; 191 | 192 | 193 | _radarView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin; 194 | _radarViewPort.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin; 195 | radarNorthLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin; 196 | 197 | [self.displayView addSubview:_radarView]; 198 | [self.displayView addSubview:_radarViewPort]; 199 | [self.displayView addSubview:radarNorthLabel]; 200 | } 201 | } 202 | 203 | -(void)unloadAV { 204 | [captureSession stopRunning]; 205 | AVCaptureInput* input = [captureSession.inputs objectAtIndex:0]; 206 | [captureSession removeInput:input]; 207 | [[self previewLayer] removeFromSuperlayer]; 208 | [self setCaptureSession:nil]; 209 | [self setPreviewLayer:nil]; 210 | } 211 | 212 | - (void)dealloc { 213 | [self stopListening]; 214 | [self unloadAV]; 215 | [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; 216 | locationManager.delegate = nil; 217 | [UIAccelerometer sharedAccelerometer].delegate = nil; 218 | } 219 | 220 | #pragma mark - 221 | #pragma mark Location Manager methods 222 | - (void)startListening { 223 | 224 | // start our heading readings and our accelerometer readings. 225 | if (![self locationManager]) { 226 | CLLocationManager *newLocationManager = [[CLLocationManager alloc] init]; 227 | 228 | [newLocationManager setHeadingFilter: HEADING_FILTER]; 229 | [newLocationManager setDistanceFilter:DISTANCE_FILTER]; 230 | [newLocationManager setDesiredAccuracy: kCLLocationAccuracyNearestTenMeters]; 231 | [newLocationManager startUpdatingHeading]; 232 | [newLocationManager startUpdatingLocation]; 233 | [newLocationManager setDelegate: self]; 234 | 235 | [self setLocationManager: newLocationManager]; 236 | } 237 | 238 | if (![self accelerometerManager]) { 239 | [self setAccelerometerManager: [UIAccelerometer sharedAccelerometer]]; 240 | [[self accelerometerManager] setUpdateInterval: INTERVAL_UPDATE]; 241 | [[self accelerometerManager] setDelegate: self]; 242 | } 243 | 244 | if (![self centerCoordinate]) 245 | [self setCenterCoordinate:[ARCoordinate coordinateWithRadialDistance:1.0 inclination:0 azimuth:0]]; 246 | } 247 | 248 | - (void)stopListening { 249 | [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; 250 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 251 | 252 | if ([self locationManager]) { 253 | [[self locationManager] setDelegate: nil]; 254 | } 255 | 256 | if ([self accelerometerManager]) { 257 | [[self accelerometerManager] setDelegate: nil]; 258 | } 259 | } 260 | 261 | - (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading { 262 | 263 | latestHeading = degreesToRadian(newHeading.magneticHeading); 264 | 265 | //Let's only update the Center Coordinate when we have adjusted by more than X degrees 266 | if (fabs(latestHeading-prevHeading) >= degreesToRadian(DEGREE_TO_UPDATE) || prevHeading == HEADING_NOT_SET) { 267 | prevHeading = latestHeading; 268 | [self updateCenterCoordinate]; 269 | [[self delegate] didUpdateHeading:newHeading]; 270 | } 271 | 272 | 273 | if(_showsRadar){ 274 | int gradToRotate = newHeading.magneticHeading - 90 - 22.5; 275 | if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) { 276 | gradToRotate += 90; 277 | } 278 | if([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight){ 279 | gradToRotate -= 90; 280 | } 281 | if (gradToRotate < 0) { 282 | gradToRotate = 360 + gradToRotate; 283 | } 284 | 285 | _radarViewPort.referenceAngle = gradToRotate; 286 | [_radarViewPort setNeedsDisplay]; 287 | } 288 | } 289 | 290 | - (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager { 291 | return YES; 292 | } 293 | 294 | - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { 295 | [self setCenterLocation:newLocation]; 296 | [[self delegate] didUpdateLocation:newLocation]; 297 | 298 | } 299 | 300 | - (void)updateCenterCoordinate { 301 | 302 | double adjustment = 0; 303 | 304 | switch (cameraOrientation) { 305 | case UIDeviceOrientationLandscapeLeft: 306 | adjustment = degreesToRadian(270); 307 | break; 308 | case UIDeviceOrientationLandscapeRight: 309 | adjustment = degreesToRadian(90); 310 | break; 311 | case UIDeviceOrientationPortraitUpsideDown: 312 | adjustment = degreesToRadian(180); 313 | break; 314 | default: 315 | adjustment = 0; 316 | break; 317 | } 318 | 319 | [[self centerCoordinate] setAzimuth: latestHeading - adjustment]; 320 | [self updateLocations]; 321 | } 322 | 323 | - (void)setCenterLocation:(CLLocation *)newLocation { 324 | centerLocation = newLocation; 325 | 326 | for (ARGeoCoordinate *geoLocation in [self coordinates]) { 327 | 328 | if ([geoLocation isKindOfClass:[ARGeoCoordinate class]]) { 329 | [geoLocation calibrateUsingOrigin:centerLocation]; 330 | 331 | if(_onlyShowItemsWithinRadarRange){ 332 | if(([geoLocation radialDistance] / 1000) > _radarRange){ 333 | continue; 334 | } 335 | } 336 | 337 | if ([geoLocation radialDistance] > [self maximumScaleDistance]) 338 | [self setMaximumScaleDistance:[geoLocation radialDistance]]; 339 | } 340 | } 341 | } 342 | 343 | - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { 344 | 345 | switch (cameraOrientation) { 346 | case UIDeviceOrientationLandscapeLeft: 347 | viewAngle = atan2(acceleration.x, acceleration.z); 348 | break; 349 | case UIDeviceOrientationLandscapeRight: 350 | viewAngle = atan2(-acceleration.x, acceleration.z); 351 | break; 352 | case UIDeviceOrientationPortrait: 353 | viewAngle = atan2(acceleration.y, acceleration.z); 354 | break; 355 | case UIDeviceOrientationPortraitUpsideDown: 356 | viewAngle = atan2(-acceleration.y, acceleration.z); 357 | break; 358 | default: 359 | break; 360 | } 361 | } 362 | 363 | #pragma mark - 364 | #pragma mark Coordinate methods 365 | 366 | - (void)addCoordinate:(ARGeoCoordinate *)coordinate { 367 | 368 | [[self coordinates] addObject:coordinate]; 369 | 370 | if ([coordinate radialDistance] > [self maximumScaleDistance]) 371 | [self setMaximumScaleDistance: [coordinate radialDistance]]; 372 | } 373 | 374 | - (void)removeCoordinate:(ARGeoCoordinate *)coordinate { 375 | [[self coordinates] removeObject:coordinate]; 376 | } 377 | 378 | - (void)removeCoordinates:(NSArray *)coordinateArray { 379 | 380 | for (ARGeoCoordinate *coordinateToRemove in coordinateArray) { 381 | NSUInteger indexToRemove = [[self coordinates] indexOfObject:coordinateToRemove]; 382 | 383 | //TODO: Error checking in here. 384 | [[self coordinates] removeObjectAtIndex:indexToRemove]; 385 | } 386 | } 387 | 388 | #pragma mark - 389 | #pragma mark Location methods 390 | 391 | -(double) findDeltaOfRadianCenter:(double*)centerAzimuth coordinateAzimuth:(double)pointAzimuth betweenNorth:(BOOL*) isBetweenNorth { 392 | 393 | if (*centerAzimuth < 0.0) 394 | *centerAzimuth = M_2PI + *centerAzimuth; 395 | 396 | if (*centerAzimuth > M_2PI) 397 | *centerAzimuth = *centerAzimuth - M_2PI; 398 | 399 | double deltaAzimuth = ABS(pointAzimuth - *centerAzimuth); 400 | *isBetweenNorth = NO; 401 | 402 | // If values are on either side of the Azimuth of North we need to adjust it. Only check the degree range 403 | if (*centerAzimuth < degreesToRadian(degreeRange) && pointAzimuth > degreesToRadian(360-degreeRange)) { 404 | deltaAzimuth = (*centerAzimuth + (M_2PI - pointAzimuth)); 405 | *isBetweenNorth = YES; 406 | } 407 | else if (pointAzimuth < degreesToRadian(degreeRange) && *centerAzimuth > degreesToRadian(360-degreeRange)) { 408 | deltaAzimuth = (pointAzimuth + (M_2PI - *centerAzimuth)); 409 | *isBetweenNorth = YES; 410 | } 411 | 412 | return deltaAzimuth; 413 | } 414 | 415 | - (BOOL)shouldDisplayCoordinate:(ARCoordinate *)coordinate { 416 | 417 | double currentAzimuth = [[self centerCoordinate] azimuth]; 418 | double pointAzimuth = [coordinate azimuth]; 419 | BOOL isBetweenNorth = NO; 420 | double deltaAzimuth = [self findDeltaOfRadianCenter: ¤tAzimuth coordinateAzimuth:pointAzimuth betweenNorth:&isBetweenNorth]; 421 | BOOL result = NO; 422 | 423 | // NSLog(@"Current %f, Item %f, delta %f, range %f",currentAzimuth,pointAzimuth,deltaAzimith,degreesToRadian([self degreeRange])); 424 | 425 | if (deltaAzimuth <= degreesToRadian(degreeRange)){ 426 | result = YES; 427 | } 428 | 429 | // Limit results to only those within radar range (if set) 430 | if(_onlyShowItemsWithinRadarRange){ 431 | if(([coordinate radialDistance] / 1000) > _radarRange){ 432 | result = NO; 433 | } 434 | } 435 | 436 | return result; 437 | } 438 | 439 | - (CGPoint)pointForCoordinate:(ARCoordinate *)coordinate { 440 | 441 | CGPoint point; 442 | CGRect realityBounds = [[self displayView] bounds]; 443 | double currentAzimuth = [[self centerCoordinate] azimuth]; 444 | double pointAzimuth = [coordinate azimuth]; 445 | BOOL isBetweenNorth = NO; 446 | double deltaAzimith = [self findDeltaOfRadianCenter: ¤tAzimuth coordinateAzimuth:pointAzimuth betweenNorth:&isBetweenNorth]; 447 | 448 | if ((pointAzimuth > currentAzimuth && !isBetweenNorth) || 449 | (currentAzimuth > degreesToRadian(360- degreeRange) && pointAzimuth < degreesToRadian(degreeRange))) { 450 | point.x = (realityBounds.size.width / 2) + ((deltaAzimith / degreesToRadian(1)) * ADJUST_BY); // Right side of Azimuth 451 | } 452 | else 453 | point.x = (realityBounds.size.width / 2) - ((deltaAzimith / degreesToRadian(1)) * ADJUST_BY); // Left side of Azimuth 454 | 455 | point.y = (realityBounds.size.height / 2) + (radianToDegrees(M_PI_2 + viewAngle) * 2.0); 456 | 457 | return point; 458 | } 459 | 460 | - (void)updateLocations { 461 | 462 | NSMutableArray *radarPointValues = [[NSMutableArray alloc] initWithCapacity:[self.coordinates count]]; 463 | 464 | for (ARGeoCoordinate *item in [self coordinates]) { 465 | 466 | UIView *markerView = [item displayView]; 467 | 468 | if ([self shouldDisplayCoordinate:item]) { 469 | 470 | CGPoint loc = [self pointForCoordinate:item]; 471 | CGFloat scaleFactor = SCALE_FACTOR; 472 | 473 | if ([self scaleViewsBasedOnDistance]) { 474 | scaleFactor = scaleFactor - [self minimumScaleFactor]*([item radialDistance] / [self maximumScaleDistance]); 475 | } 476 | 477 | float width = [markerView bounds].size.width * scaleFactor; 478 | float height = [markerView bounds].size.height * scaleFactor; 479 | 480 | [markerView setFrame:CGRectMake(loc.x - width / 2.0, loc.y, width, height)]; 481 | [markerView setNeedsDisplay]; 482 | 483 | CATransform3D transform = CATransform3DIdentity; 484 | 485 | // Set the scale if it needs it. Scale the perspective transform if we have one. 486 | if ([self scaleViewsBasedOnDistance]) 487 | transform = CATransform3DScale(transform, scaleFactor, scaleFactor, scaleFactor); 488 | 489 | if ([self rotateViewsBasedOnPerspective]) { 490 | transform.m34 = 1.0 / 300.0; 491 | /* 492 | double itemAzimuth = [item azimuth]; 493 | double centerAzimuth = [[self centerCoordinate] azimuth]; 494 | 495 | if (itemAzimuth - centerAzimuth > M_PI) 496 | centerAzimuth += M_2PI; 497 | 498 | if (itemAzimuth - centerAzimuth < -M_PI) 499 | itemAzimuth += M_2PI; 500 | */ 501 | // double angleDifference = itemAzimuth - centerAzimuth; 502 | // transform = CATransform3DRotate(transform, [self maximumRotationAngle] * angleDifference / 0.3696f , 0, 1, 0); 503 | } 504 | [[markerView layer] setTransform:transform]; 505 | 506 | //if marker is not already set then insert it 507 | if (!([markerView superview])) { 508 | [[self displayView] insertSubview:markerView atIndex:1]; 509 | } 510 | }else { 511 | if([markerView superview]){ 512 | [markerView removeFromSuperview]; 513 | } 514 | } 515 | 516 | [radarPointValues addObject:item]; 517 | 518 | } 519 | 520 | if(_showsRadar){ 521 | _radarView.pois = radarPointValues; 522 | _radarView.radius = _radarRange; 523 | [_radarView setNeedsDisplay]; 524 | } 525 | } 526 | 527 | - (NSComparisonResult)LocationSortClosestFirst:(ARCoordinate *)s1 secondCoord:(ARCoordinate*)s2{ 528 | 529 | if ([s1 radialDistance] < [s2 radialDistance]) 530 | return NSOrderedAscending; 531 | else if ([s1 radialDistance] > [s2 radialDistance]) 532 | return NSOrderedDescending; 533 | else 534 | return NSOrderedSame; 535 | } 536 | 537 | #pragma mark - 538 | #pragma mark Device Orientation 539 | 540 | - (void)currentDeviceOrientation { 541 | UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; 542 | 543 | if (orientation != UIDeviceOrientationUnknown && orientation != UIDeviceOrientationFaceUp && orientation != UIDeviceOrientationFaceDown) { 544 | switch (orientation) { 545 | case UIDeviceOrientationLandscapeLeft: 546 | cameraOrientation = AVCaptureVideoOrientationLandscapeRight; 547 | break; 548 | case UIDeviceOrientationLandscapeRight: 549 | cameraOrientation = AVCaptureVideoOrientationLandscapeLeft; 550 | break; 551 | case UIDeviceOrientationPortraitUpsideDown: 552 | cameraOrientation = AVCaptureVideoOrientationPortraitUpsideDown; 553 | break; 554 | case UIDeviceOrientationPortrait: 555 | cameraOrientation = AVCaptureVideoOrientationPortrait; 556 | break; 557 | default: 558 | break; 559 | } 560 | } 561 | } 562 | 563 | - (void)deviceOrientationDidChange:(NSNotification *)notification { 564 | 565 | prevHeading = HEADING_NOT_SET; 566 | 567 | [self currentDeviceOrientation]; 568 | 569 | [[self previewLayer].connection setVideoOrientation:cameraOrientation]; 570 | 571 | UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; 572 | 573 | CGRect newFrame = [[UIScreen mainScreen] bounds]; 574 | 575 | switch (orientation) { 576 | case UIDeviceOrientationLandscapeLeft: 577 | case UIDeviceOrientationLandscapeRight: 578 | newFrame.size.width = [[UIScreen mainScreen] applicationFrame].size.height; 579 | newFrame.size.height = [[UIScreen mainScreen] applicationFrame].size.width; 580 | break; 581 | case UIDeviceOrientationPortraitUpsideDown: 582 | break; 583 | default: 584 | break; 585 | } 586 | 587 | [previewLayer setFrame:[self.cameraView bounds]]; 588 | 589 | if ([previewLayer.connection isVideoOrientationSupported]) { 590 | [previewLayer.connection setVideoOrientation:cameraOrientation]; 591 | } 592 | 593 | [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; 594 | 595 | //Last but not least we need to move the radar if we are displaying one 596 | if(_radarViewPort && _radarView) 597 | { 598 | [radarNorthLabel setFrame:CGRectMake(newFrame.size.width - 37, 2, 10, 10)]; 599 | [_radarView setFrame:CGRectMake(newFrame.size.width - 63, 2, 61, 61)]; 600 | [_radarViewPort setFrame:CGRectMake(newFrame.size.width - 63, 2, 61, 61)]; 601 | } 602 | } 603 | @end 604 | -------------------------------------------------------------------------------- /ARKit/GEOLocations.h: -------------------------------------------------------------------------------- 1 | // 2 | // GEOLocations.h 3 | // AR Kit 4 | // 5 | // Created by Niels W Hansen on 12/19/09. 6 | // Modified by Ed Rackham (a1phanumeric) 2013 7 | // 8 | 9 | #import 10 | #import "ARLocationDelegate.h" 11 | 12 | @class ARCoordinate; 13 | 14 | @interface GEOLocations : NSObject 15 | 16 | @property(nonatomic,assign) id delegate; 17 | 18 | - (id)initWithDelegate:(id) aDelegate; 19 | -(NSMutableArray*) returnLocations; 20 | 21 | 22 | 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /ARKit/GEOLocations.m: -------------------------------------------------------------------------------- 1 | // 2 | // GEOLocations.m 3 | // AR Kit 4 | // 5 | // Modified by Niels W Hansen on 12/19/09. 6 | // Modified by Ed Rackham (a1phanumeric) 2013 7 | // 8 | 9 | #import "GEOLocations.h" 10 | #import "ARGeoCoordinate.h" 11 | #import 12 | #import 13 | 14 | @implementation GEOLocations 15 | 16 | 17 | @synthesize delegate; 18 | 19 | - (id)initWithDelegate:(id) aDelegate{ 20 | [self setDelegate:aDelegate]; 21 | return self; 22 | } 23 | 24 | - (NSMutableArray *)returnLocations{ 25 | return [delegate geoLocations]; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /ARKit/Images/bgCallout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a1phanumeric/iPhone-AR-Toolkit/1b44aca9b9090ed641dd5c3ee35770f2bf2fcdb1/ARKit/Images/bgCallout.png -------------------------------------------------------------------------------- /ARKit/Images/bgCallout@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a1phanumeric/iPhone-AR-Toolkit/1b44aca9b9090ed641dd5c3ee35770f2bf2fcdb1/ARKit/Images/bgCallout@2x.png -------------------------------------------------------------------------------- /ARKit/Images/bgCalloutDisclosure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a1phanumeric/iPhone-AR-Toolkit/1b44aca9b9090ed641dd5c3ee35770f2bf2fcdb1/ARKit/Images/bgCalloutDisclosure.png -------------------------------------------------------------------------------- /ARKit/Images/bgCalloutDisclosure@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a1phanumeric/iPhone-AR-Toolkit/1b44aca9b9090ed641dd5c3ee35770f2bf2fcdb1/ARKit/Images/bgCalloutDisclosure@2x.png -------------------------------------------------------------------------------- /ARKit/MarkerView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CoordinateView.h 3 | // AR Kit 4 | // 5 | // Created by Niels W Hansen on 12/31/11. 6 | // Modified by Ed Rackham (a1phanumeric) 2013 7 | // 8 | 9 | #import 10 | #import "ARViewProtocol.h" 11 | 12 | @class ARGeoCoordinate; 13 | 14 | @interface MarkerView : UIView 15 | 16 | @property (nonatomic) BOOL usesMetric; 17 | 18 | - (id)initForCoordinate:(ARGeoCoordinate *)coordinate withDelgate:(id) aDelegate; 19 | - (id)initForCoordinate:(ARGeoCoordinate *)coordinate withDelgate:(id)aDelegate allowsCallout:(BOOL)allowsCallout; 20 | @end 21 | -------------------------------------------------------------------------------- /ARKit/MarkerView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CoordinateView.m 3 | // ARKitDemo 4 | // 5 | // Modified by Niels W Hansen on 12/31/11. 6 | // Modified by Ed Rackham (a1phanumeric) 2013 7 | // 8 | 9 | #import "ARViewProtocol.h" 10 | #import "ARGeoCoordinate.h" 11 | #import "MarkerView.h" 12 | 13 | #define LABEL_HEIGHT 20 14 | #define LABEL_MARGIN 5 15 | #define DISCLOSURE_MARGIN 10 16 | 17 | @implementation MarkerView{ 18 | BOOL _allowsCallout; 19 | UIImage *_bgImage; 20 | UILabel *_lblDistance; 21 | id _delegate; 22 | ARGeoCoordinate *_coordinateInfo; 23 | } 24 | 25 | - (id)initForCoordinate:(ARGeoCoordinate *)coordinate withDelgate:(id)aDelegate{ 26 | return [self initForCoordinate:coordinate withDelgate:aDelegate allowsCallout:YES]; 27 | } 28 | 29 | - (id)initForCoordinate:(ARGeoCoordinate *)coordinate withDelgate:(id)aDelegate allowsCallout:(BOOL)allowsCallout{ 30 | 31 | _coordinateInfo = coordinate; 32 | _delegate = aDelegate; 33 | _allowsCallout = allowsCallout; 34 | _bgImage = [UIImage imageNamed:@"bgCallout.png"]; 35 | 36 | UIImage *disclosureImage = [UIImage imageNamed:@"bgCalloutDisclosure.png"]; 37 | CGSize calloutSize = _bgImage.size; 38 | CGRect theFrame = CGRectMake(0, 0, calloutSize.width, calloutSize.height); 39 | 40 | 41 | if(self = [super initWithFrame:theFrame]){ 42 | 43 | [self setContentMode:UIViewContentModeScaleAspectFit]; 44 | [self setAutoresizesSubviews:YES]; 45 | 46 | if(_allowsCallout){ 47 | [self setUserInteractionEnabled:YES]; 48 | } 49 | 50 | UIImageView *bgImageView = [[UIImageView alloc] initWithImage:_bgImage]; 51 | [self addSubview:bgImageView]; 52 | 53 | CGSize labelSize = CGSizeMake(calloutSize.width - (LABEL_MARGIN * 2), LABEL_HEIGHT); 54 | if(_allowsCallout){ 55 | labelSize.width -= disclosureImage.size.width + (DISCLOSURE_MARGIN * 2); 56 | } 57 | 58 | UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(LABEL_MARGIN, LABEL_MARGIN, labelSize.width, labelSize.height)]; 59 | [titleLabel setBackgroundColor: [UIColor clearColor]]; 60 | [titleLabel setTextColor: [UIColor whiteColor]]; 61 | [titleLabel setTextAlignment: NSTextAlignmentCenter]; 62 | [titleLabel setFont: [UIFont fontWithName:@"Helvetica-Bold" size:17.0]]; 63 | [titleLabel setText: [coordinate title]]; 64 | [self addSubview:titleLabel]; 65 | 66 | NSLocale *locale = [NSLocale currentLocale]; 67 | _usesMetric = [[locale objectForKey:NSLocaleUsesMetricSystem] boolValue]; 68 | 69 | 70 | _lblDistance = [[UILabel alloc] initWithFrame:CGRectMake(0, LABEL_HEIGHT + LABEL_MARGIN, labelSize.width, labelSize.height)]; 71 | [_lblDistance setBackgroundColor: [UIColor clearColor]]; 72 | [_lblDistance setTextColor: [UIColor whiteColor]]; 73 | [_lblDistance setTextAlignment: NSTextAlignmentCenter]; 74 | [_lblDistance setFont: [UIFont fontWithName:@"Helvetica" size:13.0]]; 75 | if(_usesMetric == YES){ 76 | [_lblDistance setText:[NSString stringWithFormat:@"%.2f km", [_coordinateInfo distanceFromOrigin]/1000.0f]]; 77 | } else { 78 | [_lblDistance setText:[NSString stringWithFormat:@"%.2f mi", ([_coordinateInfo distanceFromOrigin]/1000.0f) * 0.621371]]; 79 | } 80 | [self addSubview:_lblDistance]; 81 | 82 | 83 | if(_allowsCallout){ 84 | UIImageView *disclosureImageView = [[UIImageView alloc] initWithFrame:CGRectMake(calloutSize.width - disclosureImage.size.width - DISCLOSURE_MARGIN, DISCLOSURE_MARGIN, disclosureImage.size.width, disclosureImage.size.height)]; 85 | [disclosureImageView setImage:[UIImage imageNamed:@"bgCalloutDisclosure.png"]]; 86 | [self addSubview:disclosureImageView]; 87 | } 88 | 89 | 90 | [self setBackgroundColor:[UIColor clearColor]]; 91 | } 92 | 93 | return self; 94 | 95 | } 96 | 97 | - (void)drawRect:(CGRect)rect{ 98 | [super drawRect:rect]; 99 | if(_usesMetric == YES){ 100 | [_lblDistance setText:[NSString stringWithFormat:@"%.2f km", [_coordinateInfo distanceFromOrigin]/1000.0f]]; 101 | } else { 102 | [_lblDistance setText:[NSString stringWithFormat:@"%.2f mi", ([_coordinateInfo distanceFromOrigin]/1000.0f) * 0.621371]]; 103 | } 104 | } 105 | 106 | 107 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 108 | [_delegate didTapMarker:_coordinateInfo]; 109 | } 110 | 111 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ 112 | } 113 | 114 | - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{ 115 | CGRect theFrame = CGRectMake(0, 0, _bgImage.size.width, _bgImage.size.height); 116 | if(CGRectContainsPoint(theFrame, point)) 117 | return YES; // touched the view; 118 | 119 | return NO; 120 | } 121 | 122 | @end 123 | -------------------------------------------------------------------------------- /ARKit/Radar.h: -------------------------------------------------------------------------------- 1 | // 2 | // Radar.h 3 | // ARKitDemo 4 | // 5 | // Created by Ed Rackham (a1phanumeric) 2013 6 | // Based on mixare's implementation. 7 | // 8 | 9 | #import 10 | #import "ARGeoCoordinate.h" 11 | 12 | #define RADIUS 30.0 13 | 14 | @interface Radar : UIView 15 | 16 | @property (nonatomic, strong) NSArray *pois; 17 | @property (nonatomic, assign) float radius; 18 | 19 | @property (strong, nonatomic) UIColor *radarBackgroundColour; 20 | @property (strong, nonatomic) UIColor *pointColour; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /ARKit/Radar.m: -------------------------------------------------------------------------------- 1 | // 2 | // Radar.m 3 | // ARKitDemo 4 | // 5 | // Created by Ed Rackham (a1phanumeric) 2013 6 | // Based on mixare's implementation. 7 | // 8 | 9 | #import "Radar.h" 10 | 11 | @implementation Radar{ 12 | float _range; 13 | } 14 | 15 | @synthesize pois = _pois; 16 | @synthesize radius = _radius; 17 | 18 | - (id)initWithFrame:(CGRect)frame{ 19 | if ((self = [super initWithFrame:frame])) { 20 | self.backgroundColor = [UIColor clearColor]; 21 | _radarBackgroundColour = [UIColor colorWithRed:14.0/255.0 green:140.0/255.0 blue:14.0/255.0 alpha:0.2]; 22 | _pointColour = [UIColor whiteColor]; 23 | } 24 | return self; 25 | } 26 | 27 | 28 | - (void)drawRect:(CGRect)rect{ 29 | CGContextRef contextRef = UIGraphicsGetCurrentContext(); 30 | CGContextSetFillColorWithColor(contextRef, _radarBackgroundColour.CGColor); 31 | 32 | // Draw a radar and the view port 33 | CGContextFillEllipseInRect(contextRef, CGRectMake(0.5, 0.5, RADIUS*2, RADIUS*2)); 34 | CGContextSetRGBStrokeColor(contextRef, 0, 255, 0, 0.5); 35 | 36 | _range = _radius *1000; 37 | float scale = _range / RADIUS; 38 | if (_pois != nil) { 39 | for (ARGeoCoordinate *poi in _pois) { 40 | float x, y; 41 | //case1: azimiut is in the 1 quadrant of the radar 42 | if (poi.azimuth >= 0 && poi.azimuth < M_PI / 2) { 43 | x = RADIUS + cosf((M_PI / 2) - poi.azimuth) * (poi.radialDistance / scale); 44 | y = RADIUS - sinf((M_PI / 2) - poi.azimuth) * (poi.radialDistance / scale); 45 | } else if (poi.azimuth > M_PI / 2 && poi.azimuth < M_PI) { 46 | //case2: azimiut is in the 2 quadrant of the radar 47 | x = RADIUS + cosf(poi.azimuth - (M_PI / 2)) * (poi.radialDistance / scale); 48 | y = RADIUS + sinf(poi.azimuth - (M_PI / 2)) * (poi.radialDistance / scale); 49 | } else if (poi.azimuth > M_PI && poi.azimuth < (3 * M_PI / 2)) { 50 | //case3: azimiut is in the 3 quadrant of the radar 51 | x = RADIUS - cosf((3 * M_PI / 2) - poi.azimuth) * (poi.radialDistance / scale); 52 | y = RADIUS + sinf((3 * M_PI / 2) - poi.azimuth) * (poi.radialDistance / scale); 53 | } else if(poi.azimuth > (3 * M_PI / 2) && poi.azimuth < (2 * M_PI)) { 54 | //case4: azimiut is in the 4 quadrant of the radar 55 | x = RADIUS - cosf(poi.azimuth - (3 * M_PI / 2)) * (poi.radialDistance / scale); 56 | y = RADIUS - sinf(poi.azimuth - (3 * M_PI / 2)) * (poi.radialDistance / scale); 57 | } else if (poi.azimuth == 0) { 58 | x = RADIUS; 59 | y = RADIUS - poi.radialDistance / scale; 60 | } else if(poi.azimuth == M_PI/2) { 61 | x = RADIUS + poi.radialDistance / scale; 62 | y = RADIUS; 63 | } else if(poi.azimuth == (3 * M_PI / 2)) { 64 | x = RADIUS; 65 | y = RADIUS + poi.radialDistance / scale; 66 | } else if (poi.azimuth == (3 * M_PI / 2)) { 67 | x = RADIUS - poi.radialDistance / scale; 68 | y = RADIUS; 69 | } else { 70 | //If none of the above match we use the scenario where azimuth is 0 71 | x = RADIUS; 72 | y = RADIUS - poi.radialDistance / scale; 73 | } 74 | //drawing the radar point 75 | CGContextSetFillColorWithColor(contextRef, _pointColour.CGColor); 76 | if (x <= RADIUS * 2 && x >= 0 && y >= 0 && y <= RADIUS * 2) { 77 | CGContextFillEllipseInRect(contextRef, CGRectMake(x, y, 2, 2)); 78 | } 79 | } 80 | } 81 | } 82 | @end 83 | -------------------------------------------------------------------------------- /ARKit/RadarViewPortView.h: -------------------------------------------------------------------------------- 1 | // 2 | // RadarViewPortView.h 3 | // ARKitDemo 4 | // 5 | // Created by Ed Rackham (a1phanumeric) 2013 6 | // Based on mixare's implementation. 7 | // 8 | 9 | #import 10 | #import "Radar.h" 11 | 12 | @interface RadarViewPortView : UIView 13 | 14 | @property (assign, nonatomic) float referenceAngle; 15 | @property (strong, nonatomic) UIColor *viewportColour; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /ARKit/RadarViewPortView.m: -------------------------------------------------------------------------------- 1 | // 2 | // RadarViewPortView.m 3 | // ARKitDemo 4 | // 5 | // Created by Ed Rackham (a1phanumeric) 2013 6 | // Based on mixare's implementation. 7 | // 8 | 9 | #import "RadarViewPortView.h" 10 | #define radians(x) (M_PI * (x) / 180.0) 11 | 12 | @implementation RadarViewPortView{ 13 | float _newAngle; 14 | } 15 | 16 | - (id)initWithFrame:(CGRect)frame { 17 | if ((self = [super initWithFrame:frame])) { 18 | _newAngle = 45.0; 19 | _referenceAngle = 247.5; 20 | self.backgroundColor = [UIColor clearColor]; 21 | _viewportColour = [UIColor colorWithRed:14.0/255.0 green:140.0/255.0 blue:14.0/255.0 alpha:0.5]; 22 | } 23 | 24 | return self; 25 | } 26 | 27 | - (void)drawRect:(CGRect)rect{ 28 | CGContextRef contextRef = UIGraphicsGetCurrentContext(); 29 | CGContextSetFillColorWithColor(contextRef, _viewportColour.CGColor); 30 | CGContextMoveToPoint(contextRef, RADIUS, RADIUS); 31 | CGContextAddArc(contextRef, RADIUS, RADIUS, RADIUS, radians(_referenceAngle), radians(_referenceAngle+_newAngle),0); 32 | CGContextClosePath(contextRef); 33 | CGContextFillPath(contextRef); 34 | } 35 | 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Based on existing work by Ed Rackham (edrackham.com) 2 | 3 | 4 | Copyright (C) 2013 edrackham.com 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | 12 | =============================================================================== 13 | 14 | Based on existing work by Niels Hansen (Agilite Software): 15 | 16 | 17 | Copyright (c) 2012 Agilite Software LLC 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | =============================================================================== 38 | 39 | Based on existing work by Zac White: 40 | 41 | 42 | "It isn't GPL. I haven't made the license clear, but it is a non-viral 43 | license with attribution." 44 | http://twitter.com/iphonearkit/status/5463780383 45 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # iPhone Augmented Reality Toolkit # 2 | 3 | ## Overview ## 4 | 5 | This version of the iPhone ARKit is a forked version of the ARKit started on GitHub by Zac White, then forked by jjamminjim. I have made several improvements, which include a new customisable radar control, easier integration, better orientation / screen size detection. 6 | 7 | ## Screenshots ## 8 | ![Vertical](http://i.imgur.com/k5HJS.jpg) ![Horizontal 1](http://i.imgur.com/k9JMZ.jpg) 9 | 10 | ## Goals of the project ## 11 | * ~~Not depended on a specific View Controller or the main App Delegate. (Completed) [jjamminjim]~~ 12 | * ~~Ability to use both the Landscape and Portrait modes. (Completed) [jjamminjim]~~ 13 | * ~~Use CoreLocation coordinates and update location as the user moves around. (Completed) [jjamminjim]~~ 14 | * ~~Ability to add different type of views to augment. (Completed) [jjamminjim]~~ 15 | * ~~Ability to touch any of the augment views to handle other tasks. (Completed) [jjamminjim]~~ 16 | * ~~Convert to ARC / remove deallocs (Completed)~~ 17 | * ~~Improve the markers (aesthetically) (Completed)~~ 18 | * ~~Add a Radar Control (Completed)~~ 19 | 20 | ## In the pipeline ## 21 | * iOS 5 Support 22 | * Better callout placement 23 | * API for useful data to be built in (such as country lists) 24 | 25 | iPhone ARKit's APIs are modeled after MapKit's. For an overview of MapKit, please read [the documentation](http://developer.apple.com/iphone/library/documentation/MapKit/Reference/MapKit_Framework_Reference/index.html) for more information. 26 | 27 | ## How to Use ## 28 | Firstly, copy the contents of the ARKit directory into your project. Then make sure you have the following frameworks linked: 29 | 30 | - `QuartzCore` 31 | - `MapKit` 32 | - `CoreLocation` 33 | - `AVFoundation` 34 | 35 | #### Include ARKit.h #### 36 | Open the .h file of the view controller you are going to use to display the augmented reality view. In here, add `#import "ARKit.h"` 37 | 38 | #### Implement delegate methods #### 39 | Now open the .m file for the same UIViewController and implement the following two methods: 40 | 41 | `- (NSMutableArray *)geoLocations` This must return an array of `ARGeoCoordinate`'s. For example: 42 | ``` 43 | - (NSMutableArray *)geoLocations 44 | NSMutableArray *locationArray = [[NSMutableArray alloc] init]; 45 | ARGeoCoordinate *tempCoordinate; 46 | CLLocation *tempLocation; 47 | 48 | tempLocation = [[CLLocation alloc] initWithLatitude:39.550051 longitude:-105.782067]; 49 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Denver"]; 50 | [locationArray addObject:tempCoordinate]; 51 | 52 | tempLocation = [[CLLocation alloc] initWithLatitude:45.523875 longitude:-122.670399]; 53 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Portland"]; 54 | [locationArray addObject:tempCoordinate]; 55 | 56 | return locationArray; 57 | } 58 | ``` 59 | 60 | `- (void)locationClicked:(ARGeoCoordinate *)coordinate` This is to handle the taps on the locations. You can do whatever you wish within this method. 61 | 62 | 63 | #### Display the augmented reality view #### 64 | To display the augmented reality view (typically from a button) use: 65 | 66 | ``` 67 | if([ARKit deviceSupportsAR]){ 68 | _arViewController = [[ARViewController alloc] initWithDelegate:self]; 69 | [_arViewController setModalTransitionStyle: UIModalTransitionStyleFlipHorizontal]; 70 | [self presentViewController:_arViewController animated:YES completion:nil]; 71 | } 72 | ``` 73 | 74 | ## ARKit Options ## 75 | There are a few options I've added in for turning things on/off, colourising the radar, setting the range etc... They are as follows: 76 | 77 | - `setDebugMode:` *bool* - toggles debug mode on or off. Not really that useful. Default: NO. 78 | - `setShowsRadar:` *bool* - toggles the radar on or off. Default: YES. 79 | - `setScaleViewsBasedOnDistance:` *bool* - toggles whether to scale the popups based on their distance from you. Default: YES. 80 | - `setMinimumScaleFactor:` *float* - sets the minimum scale factor for the popups. Default: 0.5. 81 | - `setRotateViewsBasedOnPerspective:` *bool* - slightly rotates the popups based on the perspective. Default: YES. 82 | - `setRadarPointColour:` *UIColor* - sets the colour of the points on the radar. Default: White. 83 | - `setRadarBackgroundColour:` *UIColor* - sets the background colour of the radar. Default: Transparent green. 84 | - `setRadarViewportColour:` *UIColor* - sets the viewport colour of the radar. Default: Less transparent green. 85 | - `setRadarRange:` *float* - sets the range of the radar (in km). Default 20.0. 86 | - `setOnlyShowItemsWithinRadarRange:` *bool* - toggles whether to show all popups, or hide the ones beyond the range of the radar. Default: NO. 87 | 88 | ### Example ### 89 | This example will change the default look of the radar, limit the range to 4000km and hide any coordinates that would appear outside of this range. 90 | 91 | ``` 92 | if([ARKit deviceSupportsAR]){ 93 | _arViewController = [[ARViewController alloc] initWithDelegate:self]; 94 | [_arViewController setRadarBackgroundColour:[UIColor blackColor]]; 95 | [_arViewController setRadarViewportColour:[UIColor colorWithWhite: 0.0 alpha:0.5]]; 96 | [_arViewController setRadarPointColour:[UIColor whiteColor]]; 97 | [_arViewController setRadarRange:4000.0]; 98 | [_arViewController setOnlyShowItemsWithinRadarRange:YES]; 99 | [_arViewController setModalTransitionStyle: UIModalTransitionStyleFlipHorizontal]; 100 | [self presentViewController:_arViewController animated:YES completion:nil]; 101 | } 102 | ``` 103 | 104 | 105 | ## Current Status ## 106 | The ARKit is targeting the iOS6 SDK. 107 | 108 | ## Acknowledgements ## 109 | I would like to thank Zac White for starting the initial project and giving me the ability to fork his code and make the changes I see to make an awesome ARKit. 110 | I would also like to thank Jim Boyd for allowing me to fork his code (and all the people who have helped him get the ARKit repo to where it was when I forked it). 111 | 112 | ## MIT License ## 113 | Copyright (c) 2013 Ed Rackham (edrackham.com) 114 | 115 | Permission is hereby granted, free of charge, to any person obtaining a copy 116 | of this software and associated documentation files (the "Software"), to deal 117 | in the Software without restriction, including without limitation the rights 118 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 119 | copies of the Software, and to permit persons to whom the Software is 120 | furnished to do so, subject to the following conditions: 121 | 122 | The above copyright notice and this permission notice shall be included in 123 | all copies or substantial portions of the Software. 124 | 125 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 126 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 127 | FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE 128 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 129 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 130 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 131 | THE SOFTWARE. 132 | -------------------------------------------------------------------------------- /iPhone-AR-Demo/iPhone-AR-Demo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 64E4D2ED1696DBE500515B74 /* Radar.m in Sources */ = {isa = PBXBuildFile; fileRef = 64E4D2EA1696DBE500515B74 /* Radar.m */; }; 11 | 64E4D2EE1696DBE500515B74 /* RadarViewPortView.m in Sources */ = {isa = PBXBuildFile; fileRef = 64E4D2EC1696DBE500515B74 /* RadarViewPortView.m */; }; 12 | 64F542C01695C116009F9468 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 64F542BF1695C116009F9468 /* UIKit.framework */; }; 13 | 64F542C21695C116009F9468 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 64F542C11695C116009F9468 /* Foundation.framework */; }; 14 | 64F542C41695C116009F9468 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 64F542C31695C116009F9468 /* CoreGraphics.framework */; }; 15 | 64F542CA1695C116009F9468 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 64F542C81695C116009F9468 /* InfoPlist.strings */; }; 16 | 64F542CC1695C116009F9468 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 64F542CB1695C116009F9468 /* main.m */; }; 17 | 64F542D01695C116009F9468 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 64F542CF1695C116009F9468 /* AppDelegate.m */; }; 18 | 64F542D21695C116009F9468 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 64F542D11695C116009F9468 /* Default.png */; }; 19 | 64F542D41695C116009F9468 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 64F542D31695C116009F9468 /* Default@2x.png */; }; 20 | 64F542D61695C116009F9468 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 64F542D51695C116009F9468 /* Default-568h@2x.png */; }; 21 | 64F542D91695C116009F9468 /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 64F542D71695C116009F9468 /* MainStoryboard.storyboard */; }; 22 | 64F542DC1695C116009F9468 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 64F542DB1695C116009F9468 /* ViewController.m */; }; 23 | 64F542F51695C184009F9468 /* ARCoordinate.m in Sources */ = {isa = PBXBuildFile; fileRef = 64F542E41695C184009F9468 /* ARCoordinate.m */; }; 24 | 64F542F61695C184009F9468 /* ARGeoCoordinate.m in Sources */ = {isa = PBXBuildFile; fileRef = 64F542E61695C184009F9468 /* ARGeoCoordinate.m */; }; 25 | 64F542F71695C184009F9468 /* ARKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 64F542E81695C184009F9468 /* ARKit.m */; }; 26 | 64F542F81695C184009F9468 /* ARViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 64F542EB1695C184009F9468 /* ARViewController.m */; }; 27 | 64F542F91695C184009F9468 /* AugmentedRealityController.m in Sources */ = {isa = PBXBuildFile; fileRef = 64F542EE1695C184009F9468 /* AugmentedRealityController.m */; }; 28 | 64F542FA1695C184009F9468 /* GEOLocations.m in Sources */ = {isa = PBXBuildFile; fileRef = 64F542F01695C184009F9468 /* GEOLocations.m */; }; 29 | 64F542FC1695C184009F9468 /* MarkerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 64F542F41695C184009F9468 /* MarkerView.m */; }; 30 | 64F542FE1695C1A1009F9468 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 64F542FD1695C1A1009F9468 /* AVFoundation.framework */; }; 31 | 64F543001695C1A9009F9468 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 64F542FF1695C1A9009F9468 /* CoreLocation.framework */; }; 32 | 64F543021695C1D7009F9468 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 64F543011695C1D7009F9468 /* MapKit.framework */; }; 33 | 64F543041695C510009F9468 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 64F543031695C510009F9468 /* QuartzCore.framework */; }; 34 | 64F543121695DF09009F9468 /* bgCalloutDisclosure.png in Resources */ = {isa = PBXBuildFile; fileRef = 64F5430A1695DF09009F9468 /* bgCalloutDisclosure.png */; }; 35 | 64F543131695DF09009F9468 /* bgCalloutDisclosure@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 64F5430B1695DF09009F9468 /* bgCalloutDisclosure@2x.png */; }; 36 | 64F5431A1695E1ED009F9468 /* bgCallout.png in Resources */ = {isa = PBXBuildFile; fileRef = 64F543181695E1ED009F9468 /* bgCallout.png */; }; 37 | 64F5431B1695E1ED009F9468 /* bgCallout@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 64F543191695E1ED009F9468 /* bgCallout@2x.png */; }; 38 | /* End PBXBuildFile section */ 39 | 40 | /* Begin PBXFileReference section */ 41 | 64E4D2E91696DBE400515B74 /* Radar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Radar.h; path = ../../ARKit/Radar.h; sourceTree = ""; }; 42 | 64E4D2EA1696DBE500515B74 /* Radar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Radar.m; path = ../../ARKit/Radar.m; sourceTree = ""; }; 43 | 64E4D2EB1696DBE500515B74 /* RadarViewPortView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RadarViewPortView.h; path = ../../ARKit/RadarViewPortView.h; sourceTree = ""; }; 44 | 64E4D2EC1696DBE500515B74 /* RadarViewPortView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RadarViewPortView.m; path = ../../ARKit/RadarViewPortView.m; sourceTree = ""; }; 45 | 64F542BB1695C116009F9468 /* iPhone-AR-Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "iPhone-AR-Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 64F542BF1695C116009F9468 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 47 | 64F542C11695C116009F9468 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 48 | 64F542C31695C116009F9468 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 49 | 64F542C71695C116009F9468 /* iPhone-AR-Demo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "iPhone-AR-Demo-Info.plist"; sourceTree = ""; }; 50 | 64F542C91695C116009F9468 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 51 | 64F542CB1695C116009F9468 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 52 | 64F542CD1695C116009F9468 /* iPhone-AR-Demo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "iPhone-AR-Demo-Prefix.pch"; sourceTree = ""; }; 53 | 64F542CE1695C116009F9468 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 54 | 64F542CF1695C116009F9468 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 55 | 64F542D11695C116009F9468 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 56 | 64F542D31695C116009F9468 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 57 | 64F542D51695C116009F9468 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 58 | 64F542D81695C116009F9468 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard.storyboard; sourceTree = ""; }; 59 | 64F542DA1695C116009F9468 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 60 | 64F542DB1695C116009F9468 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 61 | 64F542E31695C184009F9468 /* ARCoordinate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARCoordinate.h; path = ../../ARKit/ARCoordinate.h; sourceTree = ""; }; 62 | 64F542E41695C184009F9468 /* ARCoordinate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ARCoordinate.m; path = ../../ARKit/ARCoordinate.m; sourceTree = ""; }; 63 | 64F542E51695C184009F9468 /* ARGeoCoordinate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARGeoCoordinate.h; path = ../../ARKit/ARGeoCoordinate.h; sourceTree = ""; }; 64 | 64F542E61695C184009F9468 /* ARGeoCoordinate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ARGeoCoordinate.m; path = ../../ARKit/ARGeoCoordinate.m; sourceTree = ""; }; 65 | 64F542E71695C184009F9468 /* ARKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARKit.h; path = ../../ARKit/ARKit.h; sourceTree = ""; }; 66 | 64F542E81695C184009F9468 /* ARKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ARKit.m; path = ../../ARKit/ARKit.m; sourceTree = ""; }; 67 | 64F542E91695C184009F9468 /* ARLocationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARLocationDelegate.h; path = ../../ARKit/ARLocationDelegate.h; sourceTree = ""; }; 68 | 64F542EA1695C184009F9468 /* ARViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARViewController.h; path = ../../ARKit/ARViewController.h; sourceTree = ""; }; 69 | 64F542EB1695C184009F9468 /* ARViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ARViewController.m; path = ../../ARKit/ARViewController.m; sourceTree = ""; }; 70 | 64F542EC1695C184009F9468 /* ARViewProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARViewProtocol.h; path = ../../ARKit/ARViewProtocol.h; sourceTree = ""; }; 71 | 64F542ED1695C184009F9468 /* AugmentedRealityController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AugmentedRealityController.h; path = ../../ARKit/AugmentedRealityController.h; sourceTree = ""; }; 72 | 64F542EE1695C184009F9468 /* AugmentedRealityController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AugmentedRealityController.m; path = ../../ARKit/AugmentedRealityController.m; sourceTree = ""; }; 73 | 64F542EF1695C184009F9468 /* GEOLocations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GEOLocations.h; path = ../../ARKit/GEOLocations.h; sourceTree = ""; }; 74 | 64F542F01695C184009F9468 /* GEOLocations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GEOLocations.m; path = ../../ARKit/GEOLocations.m; sourceTree = ""; }; 75 | 64F542F31695C184009F9468 /* MarkerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MarkerView.h; path = ../../ARKit/MarkerView.h; sourceTree = ""; }; 76 | 64F542F41695C184009F9468 /* MarkerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MarkerView.m; path = ../../ARKit/MarkerView.m; sourceTree = ""; }; 77 | 64F542FD1695C1A1009F9468 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; 78 | 64F542FF1695C1A9009F9468 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; 79 | 64F543011695C1D7009F9468 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; 80 | 64F543031695C510009F9468 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 81 | 64F5430A1695DF09009F9468 /* bgCalloutDisclosure.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = bgCalloutDisclosure.png; sourceTree = ""; }; 82 | 64F5430B1695DF09009F9468 /* bgCalloutDisclosure@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "bgCalloutDisclosure@2x.png"; sourceTree = ""; }; 83 | 64F543181695E1ED009F9468 /* bgCallout.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = bgCallout.png; sourceTree = ""; }; 84 | 64F543191695E1ED009F9468 /* bgCallout@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "bgCallout@2x.png"; sourceTree = ""; }; 85 | /* End PBXFileReference section */ 86 | 87 | /* Begin PBXFrameworksBuildPhase section */ 88 | 64F542B81695C116009F9468 /* Frameworks */ = { 89 | isa = PBXFrameworksBuildPhase; 90 | buildActionMask = 2147483647; 91 | files = ( 92 | 64F543041695C510009F9468 /* QuartzCore.framework in Frameworks */, 93 | 64F543021695C1D7009F9468 /* MapKit.framework in Frameworks */, 94 | 64F543001695C1A9009F9468 /* CoreLocation.framework in Frameworks */, 95 | 64F542FE1695C1A1009F9468 /* AVFoundation.framework in Frameworks */, 96 | 64F542C01695C116009F9468 /* UIKit.framework in Frameworks */, 97 | 64F542C21695C116009F9468 /* Foundation.framework in Frameworks */, 98 | 64F542C41695C116009F9468 /* CoreGraphics.framework in Frameworks */, 99 | ); 100 | runOnlyForDeploymentPostprocessing = 0; 101 | }; 102 | /* End PBXFrameworksBuildPhase section */ 103 | 104 | /* Begin PBXGroup section */ 105 | 64F542B01695C116009F9468 = { 106 | isa = PBXGroup; 107 | children = ( 108 | 64F542C51695C116009F9468 /* iPhone-AR-Demo */, 109 | 64F542BE1695C116009F9468 /* Frameworks */, 110 | 64F542BC1695C116009F9468 /* Products */, 111 | ); 112 | sourceTree = ""; 113 | }; 114 | 64F542BC1695C116009F9468 /* Products */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 64F542BB1695C116009F9468 /* iPhone-AR-Demo.app */, 118 | ); 119 | name = Products; 120 | sourceTree = ""; 121 | }; 122 | 64F542BE1695C116009F9468 /* Frameworks */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 64F543031695C510009F9468 /* QuartzCore.framework */, 126 | 64F543011695C1D7009F9468 /* MapKit.framework */, 127 | 64F542FF1695C1A9009F9468 /* CoreLocation.framework */, 128 | 64F542FD1695C1A1009F9468 /* AVFoundation.framework */, 129 | 64F542BF1695C116009F9468 /* UIKit.framework */, 130 | 64F542C11695C116009F9468 /* Foundation.framework */, 131 | 64F542C31695C116009F9468 /* CoreGraphics.framework */, 132 | ); 133 | name = Frameworks; 134 | sourceTree = ""; 135 | }; 136 | 64F542C51695C116009F9468 /* iPhone-AR-Demo */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | 64F542CE1695C116009F9468 /* AppDelegate.h */, 140 | 64F542CF1695C116009F9468 /* AppDelegate.m */, 141 | 64F542D71695C116009F9468 /* MainStoryboard.storyboard */, 142 | 64F542DA1695C116009F9468 /* ViewController.h */, 143 | 64F542DB1695C116009F9468 /* ViewController.m */, 144 | 64F542C61695C116009F9468 /* Supporting Files */, 145 | ); 146 | path = "iPhone-AR-Demo"; 147 | sourceTree = ""; 148 | }; 149 | 64F542C61695C116009F9468 /* Supporting Files */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | 64F542E21695C13D009F9468 /* ARKit */, 153 | 64F542C71695C116009F9468 /* iPhone-AR-Demo-Info.plist */, 154 | 64F542C81695C116009F9468 /* InfoPlist.strings */, 155 | 64F542CB1695C116009F9468 /* main.m */, 156 | 64F542CD1695C116009F9468 /* iPhone-AR-Demo-Prefix.pch */, 157 | 64F542D11695C116009F9468 /* Default.png */, 158 | 64F542D31695C116009F9468 /* Default@2x.png */, 159 | 64F542D51695C116009F9468 /* Default-568h@2x.png */, 160 | ); 161 | name = "Supporting Files"; 162 | sourceTree = ""; 163 | }; 164 | 64F542E21695C13D009F9468 /* ARKit */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | 64F543071695DF08009F9468 /* Images */, 168 | 64F542E31695C184009F9468 /* ARCoordinate.h */, 169 | 64F542E41695C184009F9468 /* ARCoordinate.m */, 170 | 64F542E51695C184009F9468 /* ARGeoCoordinate.h */, 171 | 64F542E61695C184009F9468 /* ARGeoCoordinate.m */, 172 | 64F542E71695C184009F9468 /* ARKit.h */, 173 | 64F542E81695C184009F9468 /* ARKit.m */, 174 | 64F542E91695C184009F9468 /* ARLocationDelegate.h */, 175 | 64F542EA1695C184009F9468 /* ARViewController.h */, 176 | 64F542EB1695C184009F9468 /* ARViewController.m */, 177 | 64F542EC1695C184009F9468 /* ARViewProtocol.h */, 178 | 64F542ED1695C184009F9468 /* AugmentedRealityController.h */, 179 | 64F542EE1695C184009F9468 /* AugmentedRealityController.m */, 180 | 64F542EF1695C184009F9468 /* GEOLocations.h */, 181 | 64F542F01695C184009F9468 /* GEOLocations.m */, 182 | 64F542F31695C184009F9468 /* MarkerView.h */, 183 | 64F542F41695C184009F9468 /* MarkerView.m */, 184 | 64E4D2E91696DBE400515B74 /* Radar.h */, 185 | 64E4D2EA1696DBE500515B74 /* Radar.m */, 186 | 64E4D2EB1696DBE500515B74 /* RadarViewPortView.h */, 187 | 64E4D2EC1696DBE500515B74 /* RadarViewPortView.m */, 188 | ); 189 | name = ARKit; 190 | sourceTree = ""; 191 | }; 192 | 64F543071695DF08009F9468 /* Images */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | 64F5430A1695DF09009F9468 /* bgCalloutDisclosure.png */, 196 | 64F5430B1695DF09009F9468 /* bgCalloutDisclosure@2x.png */, 197 | 64F543181695E1ED009F9468 /* bgCallout.png */, 198 | 64F543191695E1ED009F9468 /* bgCallout@2x.png */, 199 | ); 200 | name = Images; 201 | path = ../../ARKit/Images; 202 | sourceTree = ""; 203 | }; 204 | /* End PBXGroup section */ 205 | 206 | /* Begin PBXNativeTarget section */ 207 | 64F542BA1695C116009F9468 /* iPhone-AR-Demo */ = { 208 | isa = PBXNativeTarget; 209 | buildConfigurationList = 64F542DF1695C116009F9468 /* Build configuration list for PBXNativeTarget "iPhone-AR-Demo" */; 210 | buildPhases = ( 211 | 64F542B71695C116009F9468 /* Sources */, 212 | 64F542B81695C116009F9468 /* Frameworks */, 213 | 64F542B91695C116009F9468 /* Resources */, 214 | ); 215 | buildRules = ( 216 | ); 217 | dependencies = ( 218 | ); 219 | name = "iPhone-AR-Demo"; 220 | productName = "iPhone-AR-Demo"; 221 | productReference = 64F542BB1695C116009F9468 /* iPhone-AR-Demo.app */; 222 | productType = "com.apple.product-type.application"; 223 | }; 224 | /* End PBXNativeTarget section */ 225 | 226 | /* Begin PBXProject section */ 227 | 64F542B21695C116009F9468 /* Project object */ = { 228 | isa = PBXProject; 229 | attributes = { 230 | LastUpgradeCheck = 0450; 231 | ORGANIZATIONNAME = edrackham.com; 232 | }; 233 | buildConfigurationList = 64F542B51695C116009F9468 /* Build configuration list for PBXProject "iPhone-AR-Demo" */; 234 | compatibilityVersion = "Xcode 3.2"; 235 | developmentRegion = English; 236 | hasScannedForEncodings = 0; 237 | knownRegions = ( 238 | en, 239 | ); 240 | mainGroup = 64F542B01695C116009F9468; 241 | productRefGroup = 64F542BC1695C116009F9468 /* Products */; 242 | projectDirPath = ""; 243 | projectRoot = ""; 244 | targets = ( 245 | 64F542BA1695C116009F9468 /* iPhone-AR-Demo */, 246 | ); 247 | }; 248 | /* End PBXProject section */ 249 | 250 | /* Begin PBXResourcesBuildPhase section */ 251 | 64F542B91695C116009F9468 /* Resources */ = { 252 | isa = PBXResourcesBuildPhase; 253 | buildActionMask = 2147483647; 254 | files = ( 255 | 64F542CA1695C116009F9468 /* InfoPlist.strings in Resources */, 256 | 64F542D21695C116009F9468 /* Default.png in Resources */, 257 | 64F542D41695C116009F9468 /* Default@2x.png in Resources */, 258 | 64F542D61695C116009F9468 /* Default-568h@2x.png in Resources */, 259 | 64F542D91695C116009F9468 /* MainStoryboard.storyboard in Resources */, 260 | 64F543121695DF09009F9468 /* bgCalloutDisclosure.png in Resources */, 261 | 64F543131695DF09009F9468 /* bgCalloutDisclosure@2x.png in Resources */, 262 | 64F5431A1695E1ED009F9468 /* bgCallout.png in Resources */, 263 | 64F5431B1695E1ED009F9468 /* bgCallout@2x.png in Resources */, 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | }; 267 | /* End PBXResourcesBuildPhase section */ 268 | 269 | /* Begin PBXSourcesBuildPhase section */ 270 | 64F542B71695C116009F9468 /* Sources */ = { 271 | isa = PBXSourcesBuildPhase; 272 | buildActionMask = 2147483647; 273 | files = ( 274 | 64F542CC1695C116009F9468 /* main.m in Sources */, 275 | 64F542D01695C116009F9468 /* AppDelegate.m in Sources */, 276 | 64F542DC1695C116009F9468 /* ViewController.m in Sources */, 277 | 64F542F51695C184009F9468 /* ARCoordinate.m in Sources */, 278 | 64F542F61695C184009F9468 /* ARGeoCoordinate.m in Sources */, 279 | 64F542F71695C184009F9468 /* ARKit.m in Sources */, 280 | 64F542F81695C184009F9468 /* ARViewController.m in Sources */, 281 | 64F542F91695C184009F9468 /* AugmentedRealityController.m in Sources */, 282 | 64F542FA1695C184009F9468 /* GEOLocations.m in Sources */, 283 | 64F542FC1695C184009F9468 /* MarkerView.m in Sources */, 284 | 64E4D2ED1696DBE500515B74 /* Radar.m in Sources */, 285 | 64E4D2EE1696DBE500515B74 /* RadarViewPortView.m in Sources */, 286 | ); 287 | runOnlyForDeploymentPostprocessing = 0; 288 | }; 289 | /* End PBXSourcesBuildPhase section */ 290 | 291 | /* Begin PBXVariantGroup section */ 292 | 64F542C81695C116009F9468 /* InfoPlist.strings */ = { 293 | isa = PBXVariantGroup; 294 | children = ( 295 | 64F542C91695C116009F9468 /* en */, 296 | ); 297 | name = InfoPlist.strings; 298 | sourceTree = ""; 299 | }; 300 | 64F542D71695C116009F9468 /* MainStoryboard.storyboard */ = { 301 | isa = PBXVariantGroup; 302 | children = ( 303 | 64F542D81695C116009F9468 /* en */, 304 | ); 305 | name = MainStoryboard.storyboard; 306 | sourceTree = ""; 307 | }; 308 | /* End PBXVariantGroup section */ 309 | 310 | /* Begin XCBuildConfiguration section */ 311 | 64F542DD1695C116009F9468 /* Debug */ = { 312 | isa = XCBuildConfiguration; 313 | buildSettings = { 314 | ALWAYS_SEARCH_USER_PATHS = NO; 315 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 316 | CLANG_CXX_LIBRARY = "libc++"; 317 | CLANG_ENABLE_OBJC_ARC = YES; 318 | CLANG_WARN_EMPTY_BODY = YES; 319 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 320 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 321 | COPY_PHASE_STRIP = NO; 322 | GCC_C_LANGUAGE_STANDARD = gnu99; 323 | GCC_DYNAMIC_NO_PIC = NO; 324 | GCC_OPTIMIZATION_LEVEL = 0; 325 | GCC_PREPROCESSOR_DEFINITIONS = ( 326 | "DEBUG=1", 327 | "$(inherited)", 328 | ); 329 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 330 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 331 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 332 | GCC_WARN_UNUSED_VARIABLE = YES; 333 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 334 | SDKROOT = iphoneos; 335 | }; 336 | name = Debug; 337 | }; 338 | 64F542DE1695C116009F9468 /* Release */ = { 339 | isa = XCBuildConfiguration; 340 | buildSettings = { 341 | ALWAYS_SEARCH_USER_PATHS = NO; 342 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 343 | CLANG_CXX_LIBRARY = "libc++"; 344 | CLANG_ENABLE_OBJC_ARC = YES; 345 | CLANG_WARN_EMPTY_BODY = YES; 346 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 347 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 348 | COPY_PHASE_STRIP = YES; 349 | GCC_C_LANGUAGE_STANDARD = gnu99; 350 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 351 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 352 | GCC_WARN_UNUSED_VARIABLE = YES; 353 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 354 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 355 | SDKROOT = iphoneos; 356 | VALIDATE_PRODUCT = YES; 357 | }; 358 | name = Release; 359 | }; 360 | 64F542E01695C116009F9468 /* Debug */ = { 361 | isa = XCBuildConfiguration; 362 | buildSettings = { 363 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 364 | GCC_PREFIX_HEADER = "iPhone-AR-Demo/iPhone-AR-Demo-Prefix.pch"; 365 | INFOPLIST_FILE = "iPhone-AR-Demo/iPhone-AR-Demo-Info.plist"; 366 | PRODUCT_NAME = "$(TARGET_NAME)"; 367 | WRAPPER_EXTENSION = app; 368 | }; 369 | name = Debug; 370 | }; 371 | 64F542E11695C116009F9468 /* Release */ = { 372 | isa = XCBuildConfiguration; 373 | buildSettings = { 374 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 375 | GCC_PREFIX_HEADER = "iPhone-AR-Demo/iPhone-AR-Demo-Prefix.pch"; 376 | INFOPLIST_FILE = "iPhone-AR-Demo/iPhone-AR-Demo-Info.plist"; 377 | PRODUCT_NAME = "$(TARGET_NAME)"; 378 | WRAPPER_EXTENSION = app; 379 | }; 380 | name = Release; 381 | }; 382 | /* End XCBuildConfiguration section */ 383 | 384 | /* Begin XCConfigurationList section */ 385 | 64F542B51695C116009F9468 /* Build configuration list for PBXProject "iPhone-AR-Demo" */ = { 386 | isa = XCConfigurationList; 387 | buildConfigurations = ( 388 | 64F542DD1695C116009F9468 /* Debug */, 389 | 64F542DE1695C116009F9468 /* Release */, 390 | ); 391 | defaultConfigurationIsVisible = 0; 392 | defaultConfigurationName = Release; 393 | }; 394 | 64F542DF1695C116009F9468 /* Build configuration list for PBXNativeTarget "iPhone-AR-Demo" */ = { 395 | isa = XCConfigurationList; 396 | buildConfigurations = ( 397 | 64F542E01695C116009F9468 /* Debug */, 398 | 64F542E11695C116009F9468 /* Release */, 399 | ); 400 | defaultConfigurationIsVisible = 0; 401 | defaultConfigurationName = Release; 402 | }; 403 | /* End XCConfigurationList section */ 404 | }; 405 | rootObject = 64F542B21695C116009F9468 /* Project object */; 406 | } 407 | -------------------------------------------------------------------------------- /iPhone-AR-Demo/iPhone-AR-Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iPhone-AR-Demo/iPhone-AR-Demo.xcodeproj/project.xcworkspace/xcuserdata/ed.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a1phanumeric/iPhone-AR-Toolkit/1b44aca9b9090ed641dd5c3ee35770f2bf2fcdb1/iPhone-AR-Demo/iPhone-AR-Demo.xcodeproj/project.xcworkspace/xcuserdata/ed.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iPhone-AR-Demo/iPhone-AR-Demo.xcodeproj/xcuserdata/ed.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /iPhone-AR-Demo/iPhone-AR-Demo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // iPhone-AR-Demo 4 | // 5 | // Created by Ed Rackham on 03/01/2013. 6 | // Copyright (c) 2013 edrackham.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /iPhone-AR-Demo/iPhone-AR-Demo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // iPhone-AR-Demo 4 | // 5 | // Created by Ed Rackham on 03/01/2013. 6 | // Copyright (c) 2013 edrackham.com. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @implementation AppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 22 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application 32 | { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application 37 | { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application 42 | { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /iPhone-AR-Demo/iPhone-AR-Demo/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a1phanumeric/iPhone-AR-Toolkit/1b44aca9b9090ed641dd5c3ee35770f2bf2fcdb1/iPhone-AR-Demo/iPhone-AR-Demo/Default-568h@2x.png -------------------------------------------------------------------------------- /iPhone-AR-Demo/iPhone-AR-Demo/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a1phanumeric/iPhone-AR-Toolkit/1b44aca9b9090ed641dd5c3ee35770f2bf2fcdb1/iPhone-AR-Demo/iPhone-AR-Demo/Default.png -------------------------------------------------------------------------------- /iPhone-AR-Demo/iPhone-AR-Demo/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a1phanumeric/iPhone-AR-Toolkit/1b44aca9b9090ed641dd5c3ee35770f2bf2fcdb1/iPhone-AR-Demo/iPhone-AR-Demo/Default@2x.png -------------------------------------------------------------------------------- /iPhone-AR-Demo/iPhone-AR-Demo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // iPhone-AR-Demo 4 | // 5 | // Created by Ed Rackham on 03/01/2013. 6 | // Copyright (c) 2013 edrackham.com. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ARKit.h" 11 | 12 | @interface ViewController : UIViewController 13 | 14 | - (IBAction)startAR:(id)sender; 15 | - (IBAction)startARWithoutCloseButton:(id)sender; 16 | - (IBAction)startARNothing:(id)sender; 17 | - (IBAction)startARNavBar:(id)sender; 18 | - (IBAction)startAREverything:(id)sender; 19 | @end 20 | -------------------------------------------------------------------------------- /iPhone-AR-Demo/iPhone-AR-Demo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // iPhone-AR-Demo 4 | // 5 | // Created by Ed Rackham on 03/01/2013. 6 | // Copyright (c) 2013 edrackham.com. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController (){ 12 | ARViewController *_arViewController; 13 | NSArray *_mapPoints; 14 | } 15 | 16 | @end 17 | 18 | @implementation ViewController 19 | 20 | - (void)viewDidLoad{ 21 | [super viewDidLoad]; 22 | } 23 | 24 | - (void)viewDidAppear:(BOOL)animated{ 25 | _arViewController = nil; 26 | } 27 | 28 | - (void)didReceiveMemoryWarning{ 29 | [super didReceiveMemoryWarning]; 30 | // Dispose of any resources that can be recreated. 31 | } 32 | 33 | - (IBAction)startAR:(id)sender { 34 | //if([ARKit deviceSupportsAR]){ 35 | _arViewController = [[ARViewController alloc] initWithDelegate:self]; 36 | //[_arViewController setShowsRadar:YES]; 37 | //[_arViewController setRadarBackgroundColour:[UIColor blackColor]]; 38 | //[_arViewController setRadarViewportColour:[UIColor darkGrayColor]]; 39 | //[_arViewController setRadarPointColour:[UIColor whiteColor]]; 40 | [_arViewController setRadarRange:4000.0]; 41 | [_arViewController setOnlyShowItemsWithinRadarRange:YES]; 42 | [_arViewController setModalTransitionStyle: UIModalTransitionStyleFlipHorizontal]; 43 | [self presentViewController:_arViewController animated:YES completion:nil]; 44 | //} 45 | } 46 | 47 | - (IBAction)startARWithoutCloseButton:(id)sender { 48 | //if([ARKit deviceSupportsAR]){ 49 | _arViewController = [[ARViewController alloc] initWithDelegate:self]; 50 | _arViewController.showsCloseButton = false; 51 | [_arViewController setRadarRange:4000.0]; 52 | [_arViewController setOnlyShowItemsWithinRadarRange:YES]; 53 | [_arViewController setModalTransitionStyle: UIModalTransitionStyleFlipHorizontal]; 54 | [self presentViewController:_arViewController animated:YES completion:nil]; 55 | //} 56 | } 57 | 58 | - (IBAction)startARNothing:(id)sender { 59 | //if([ARKit deviceSupportsAR]){ 60 | _arViewController = [[ARViewController alloc] initWithDelegate:self]; 61 | [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; 62 | [_arViewController setRadarRange:4000.0]; 63 | [_arViewController setOnlyShowItemsWithinRadarRange:YES]; 64 | [_arViewController setModalTransitionStyle: UIModalTransitionStyleFlipHorizontal]; 65 | [self presentViewController:_arViewController animated:YES completion:nil]; 66 | //} 67 | } 68 | 69 | - (IBAction)startARNavBar:(id)sender { 70 | //if([ARKit deviceSupportsAR]){ 71 | _arViewController = [[ARViewController alloc] initWithDelegate:self]; 72 | _arViewController.showsCloseButton = false; 73 | [_arViewController setHidesBottomBarWhenPushed:YES]; 74 | [_arViewController setRadarRange:4000.0]; 75 | [_arViewController setOnlyShowItemsWithinRadarRange:YES]; 76 | [self.navigationController pushViewController:_arViewController animated:YES]; 77 | //} 78 | } 79 | 80 | - (IBAction)startAREverything:(id)sender { 81 | //if([ARKit deviceSupportsAR]){ 82 | _arViewController = [[ARViewController alloc] initWithDelegate:self]; 83 | _arViewController.showsCloseButton = false; 84 | [_arViewController setRadarRange:4000.0]; 85 | [_arViewController setOnlyShowItemsWithinRadarRange:YES]; 86 | [self.navigationController pushViewController:_arViewController animated:YES]; 87 | //} 88 | } 89 | 90 | - (NSMutableArray *)geoLocations{ 91 | 92 | NSMutableArray *locationArray = [[NSMutableArray alloc] init]; 93 | ARGeoCoordinate *tempCoordinate; 94 | CLLocation *tempLocation; 95 | 96 | 97 | tempLocation = [[CLLocation alloc] initWithLatitude:39.550051 longitude:-105.782067]; 98 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Denver"]; 99 | [locationArray addObject:tempCoordinate]; 100 | 101 | 102 | tempLocation = [[CLLocation alloc] initWithLatitude:45.523875 longitude:-122.670399]; 103 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Portland"]; 104 | [locationArray addObject:tempCoordinate]; 105 | 106 | 107 | tempLocation = [[CLLocation alloc] initWithLatitude:41.879535 longitude:-87.624333]; 108 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Chicago"]; 109 | [locationArray addObject:tempCoordinate]; 110 | 111 | 112 | tempLocation = [[CLLocation alloc] initWithLatitude:30.268735 longitude:-97.745209]; 113 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Austin"]; 114 | [locationArray addObject:tempCoordinate]; 115 | 116 | 117 | tempLocation = [[CLLocation alloc] initWithLatitude:51.500152 longitude:-0.126236]; 118 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"London"]; 119 | [locationArray addObject:tempCoordinate]; 120 | 121 | 122 | tempLocation = [[CLLocation alloc] initWithLatitude:48.856667 longitude:2.350987]; 123 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Paris"]; 124 | [locationArray addObject:tempCoordinate]; 125 | 126 | 127 | tempLocation = [[CLLocation alloc] initWithLatitude:55.676294 longitude:12.568116]; 128 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Copenhagen"]; 129 | [locationArray addObject:tempCoordinate]; 130 | 131 | 132 | tempLocation = [[CLLocation alloc] initWithLatitude:52.373801 longitude:4.890935]; 133 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Amsterdam"]; 134 | [locationArray addObject:tempCoordinate]; 135 | 136 | 137 | tempLocation = [[CLLocation alloc] initWithLatitude:19.611544 longitude:-155.665283]; 138 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Hawaii"]; 139 | tempCoordinate.inclination = M_PI/30; 140 | [locationArray addObject:tempCoordinate]; 141 | 142 | 143 | tempLocation = [[CLLocation alloc] initWithLatitude:40.756054 longitude:-73.986951]; 144 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"New York City"]; 145 | [locationArray addObject:tempCoordinate]; 146 | 147 | 148 | tempLocation = [[CLLocation alloc] initWithLatitude:42.35892 longitude:-71.05781]; 149 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Boston"]; 150 | [locationArray addObject:tempCoordinate]; 151 | 152 | 153 | tempLocation = [[CLLocation alloc] initWithLatitude:49.817492 longitude:15.472962]; 154 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Czech Republic"]; 155 | [locationArray addObject:tempCoordinate]; 156 | 157 | 158 | tempLocation = [[CLLocation alloc] initWithLatitude:53.41291 longitude:-8.24389]; 159 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Ireland"]; 160 | [locationArray addObject:tempCoordinate]; 161 | 162 | 163 | tempLocation = [[CLLocation alloc] initWithLatitude:38.892091 longitude:-77.024055]; 164 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Washington, DC"]; 165 | [locationArray addObject:tempCoordinate]; 166 | 167 | 168 | tempLocation = [[CLLocation alloc] initWithLatitude:45.545447 longitude:-73.639076]; 169 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Montreal"]; 170 | [locationArray addObject:tempCoordinate]; 171 | 172 | 173 | tempLocation = [[CLLocation alloc] initWithLatitude:32.78 longitude:-117.15]; 174 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"San Diego"]; 175 | [locationArray addObject:tempCoordinate]; 176 | 177 | 178 | tempLocation = [[CLLocation alloc] initWithLatitude:-40.900557 longitude:174.885971]; 179 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Munich"]; 180 | [locationArray addObject:tempCoordinate]; 181 | 182 | 183 | tempLocation = [[CLLocation alloc] initWithLatitude:33.5033333 longitude:-117.126611]; 184 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Temecula"]; 185 | [locationArray addObject:tempCoordinate]; 186 | 187 | 188 | tempLocation = [[CLLocation alloc] initWithLatitude:19.26 longitude:-99.8]; 189 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Mexico City"]; 190 | [locationArray addObject:tempCoordinate]; 191 | 192 | 193 | tempLocation = [[CLLocation alloc] initWithLatitude:53.566667 longitude:-113.516667]; 194 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Edmonton"]; 195 | tempCoordinate.inclination = 0.5; 196 | [locationArray addObject:tempCoordinate]; 197 | 198 | 199 | tempLocation = [[CLLocation alloc] initWithLatitude:47.620973 longitude:-122.347276]; 200 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Seattle"]; 201 | [locationArray addObject:tempCoordinate]; 202 | 203 | tempLocation = [[CLLocation alloc] initWithLatitude:50.461921 longitude:-3.525315]; 204 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Torquay"]; 205 | [locationArray addObject:tempCoordinate]; 206 | 207 | tempLocation = [[CLLocation alloc] initWithLatitude:50.43548 longitude:-3.561437]; 208 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Paignton"]; 209 | [locationArray addObject:tempCoordinate]; 210 | 211 | tempLocation = [[CLLocation alloc] initWithLatitude:50.394304 longitude:-3.513823]; 212 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Brixham"]; 213 | [locationArray addObject:tempCoordinate]; 214 | 215 | tempLocation = [[CLLocation alloc] initWithLatitude:50.4327 longitude:-3.686686]; 216 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Totnes"]; 217 | [locationArray addObject:tempCoordinate]; 218 | 219 | tempLocation = [[CLLocation alloc] initWithLatitude:50.458061 longitude:-3.597078]; 220 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Marldon"]; 221 | [locationArray addObject:tempCoordinate]; 222 | 223 | tempLocation = [[CLLocation alloc] initWithLatitude:50.528717 longitude:-3.606691]; 224 | tempCoordinate = [ARGeoCoordinate coordinateWithLocation:tempLocation locationTitle:@"Newton Abbot"]; 225 | [locationArray addObject:tempCoordinate]; 226 | 227 | 228 | return locationArray; 229 | } 230 | 231 | 232 | - (void)locationClicked:(ARGeoCoordinate *)coordinate{ 233 | NSLog(@"%@", coordinate); 234 | } 235 | @end 236 | -------------------------------------------------------------------------------- /iPhone-AR-Demo/iPhone-AR-Demo/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /iPhone-AR-Demo/iPhone-AR-Demo/en.lproj/MainStoryboard.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 49 | 66 | 83 | 100 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /iPhone-AR-Demo/iPhone-AR-Demo/iPhone-AR-Demo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.edrackham.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | MainStoryboard 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /iPhone-AR-Demo/iPhone-AR-Demo/iPhone-AR-Demo-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'iPhone-AR-Demo' target in the 'iPhone-AR-Demo' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_5_0 8 | #warning "This project uses features only available in iOS SDK 5.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /iPhone-AR-Demo/iPhone-AR-Demo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // iPhone-AR-Demo 4 | // 5 | // Created by Ed Rackham on 03/01/2013. 6 | // Copyright (c) 2013 edrackham.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | --------------------------------------------------------------------------------