OpenGL, device-oriented, touch-interactive
acceptable image sizes: (4096×2048), 2048×1024, 1024×512, 512×256, 256×128 ...
- (4096 supported on iPhone 4s and iPad2 onward)
#methods
-(void) setImage:(UIImage*)image;
-(void) setImageWithName:(NSString*)fileName; // path or bundle. will check at both
// 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)
-(void) setFieldOfView:(float) // in degrees
-(void) setPinchToZoom:(BOOL) // activate UIPinchGesture
-(void) setShowTouches:(BOOL) // overlay latitude longitude intersects
-(BOOL) touchInRect:(CGRect) // hotspot detection in world coordinates
-(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
-(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.
- Illusion of varying depth is not available. The two screens are rendered using the same image with no difference between camera IPD.
make your ViewController
a subclass of GLKViewController
panoramaView = [[PanoramaView alloc] init];
// load image and any other customization
[self setView:panoramaView];
also in your GLKViewController
:
-(void) glkView:(GLKView *)view drawInRect:(CGRect)rect{
[panoramaView draw];
}
- no device landscape/portrait auto-rotation
- works properly under any of the 4 device orientations
class MainView: GLKViewController {
var panoramaView = PanoramaView()
override func viewDidLoad() {
panoramaView.setImageWithName("imagename.jpg")
panoramaView.touchToPan = true // Use touch input to pan
panoramaView.orientToDevice = false // Use motion sensors to pan
panoramaView.pinchToZoom = true // Use pinch gesture to zoom
panoramaView.showTouches = true // Show touches
self.view = panoramaView
}
override func glkView(view: GLKView, drawInRect rect: CGRect) {
panoramaView.draw()
}
}
- azimuth and altitude
- look direction, the Z vector pointing through the center of the screen
The program begins by facing the center column of the image, or azimuth 0°
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
MIT