mayakraft / Panorama

Spherical panorama view, iOS
MIT License
649 stars 135 forks source link

360° spherical panorama view

Features

example

Equirectangular projections

OpenGL has strict texture size requirements

acceptable image sizes:

4096 supported on iPhone 4s / iPad2 and newer

Methods

image

-(void) setImage:(UIImage*)image
-(void) setImageWithName:(NSString*)fileName  // path or bundle. will check at both

orientation

 // auto-update (usually only one of these at a time is recommended)
-(void) setOrientToDevice:(BOOL)   // activate motion sensors
-(void) setTouchToPan:(BOOL)       // activate UIPanGesture

 // aligns z-axis (into screen)
-(void) orientToVector:(GLKVector3)
-(void) orientToAzimuth:(float) Altitude:(float)

// rotate cardinal north around the image horizon. in degrees
-(void) setCardinalOffset:(float)

field of view

-(void) setFieldOfView:(float)     // in degrees
-(void) setPinchToZoom:(BOOL)      // activate UIPinchGesture

touches

-(void) setShowTouches:(BOOL)      // overlay latitude longitude intersects
-(BOOL) touchInRect:(CGRect)       // hotspot detection in world coordinates

2D - 3D conversion

-(CGPoint) screenLocationFromVector:(GLKVector3) // 2D screen point from a 3D point
-(GLKVector3) vectorFromScreenLocation:(CGPoint) // 3D point from 2D screen point
-(CGPoint) imagePixelAtScreenLocation:(CGPoint)  // 3D point from 2D screen point
  // except this 3D point is expressed as 2D pixel unit in the panorama image

VR Split screen

-(void) setVRMode:(BOOL)

This activates a split screen that works inside of VR headsets like Google Cardboard. TBD if more VR best practices are needed, such as a barrel shader.

Installation

copy PanoramaView.h/.m into your project or use CocoaPods

  1. use a GLKViewController instead of UIViewController
  2. initialize your panoramaView and set it as self.view
  3. implement glkView:drawInRect:
@interface ViewController (){
    PanoramaView *panoramaView;
}
@end

@implementation ViewController
- (void)viewDidLoad{
    [super viewDidLoad];
    panoramaView = [[PanoramaView alloc] init];
    [panoramaView setImageWithName:@"image.jpg"];
    [self setView:panoramaView];
}
-(void) glkView:(GLKView *)view drawInRect:(CGRect)rect{
    [panoramaView draw];
}
@end

Swift

import PanoramaView

class ViewController: GLKViewController {

    let panoramaView:PanoramaView

    required init?(coder aDecoder: NSCoder) {
        panoramaView = PanoramaView()
        super.init(coder: aDecoder)
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        panoramaView.setImageWithName("image.jpg")
        self.view = panoramaView
    }
    override func glkView(_ view: GLKView, drawIn rect: CGRect) {
        panoramaView.draw()
    }
}

make sure

device

Orientation

coordinates

The program begins by facing the center column of the image, or azimuth 0°

wikipedia

About equirectangular

sample

equirectangular images mapped to the inside of a celestial sphere come out looking like the original scene, and the math is relatively simple http://en.wikipedia.org/wiki/Equirectangular_projection

License

MIT