diff --git a/NYT360Video.podspec b/NYT360Video.podspec index 8d8184d..803e007 100644 --- a/NYT360Video.podspec +++ b/NYT360Video.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'NYT360Video' - s.version = '0.5.0' + s.version = '0.5.1' s.summary = 'NYT360Video plays 360ยบ video streamed from an AVPlayer.' s.description = <<-DESC diff --git a/NYT360VideoExample/Info.plist b/NYT360VideoExample/Info.plist index 99332e6..2c01394 100644 --- a/NYT360VideoExample/Info.plist +++ b/NYT360VideoExample/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.5.0 + 0.5.1 CFBundleSignature ???? CFBundleVersion diff --git a/NYT360VideoTests/Info.plist b/NYT360VideoTests/Info.plist index 96201fb..4e4720d 100644 --- a/NYT360VideoTests/Info.plist +++ b/NYT360VideoTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 0.5.0 + 0.5.1 CFBundleSignature ???? CFBundleVersion diff --git a/NYT360VideoTests/NYT360EulerAngleCalculationsTests.m b/NYT360VideoTests/NYT360EulerAngleCalculationsTests.m index af72799..09a78f0 100644 --- a/NYT360VideoTests/NYT360EulerAngleCalculationsTests.m +++ b/NYT360VideoTests/NYT360EulerAngleCalculationsTests.m @@ -121,5 +121,15 @@ - (void)testPanGestureChangeFunctionShouldZeroOutDisallowedXAxis { XCTAssertNotEqual(result.position.y, 0); } +- (void)testItCalculatesTheOptimalYFovForAVarietyOfInputs { + XCTAssertEqualWithAccuracy(NYT360OptimalYFovForViewSize(CGSizeMake(568, 320)), 60.0, 2.0); + XCTAssertEqualWithAccuracy(NYT360OptimalYFovForViewSize(CGSizeMake(1024, 768)), 74.6, 2.0); + XCTAssertEqualWithAccuracy(NYT360OptimalYFovForViewSize(CGSizeMake(320, 568)), 100.0, 2.0); + XCTAssertEqualWithAccuracy(NYT360OptimalYFovForViewSize(CGSizeMake(16000, 1)), 40.0, 2.0); + XCTAssertEqualWithAccuracy(NYT360OptimalYFovForViewSize(CGSizeMake(1, 16000)), 120.0, 2.0); + XCTAssertEqualWithAccuracy(NYT360OptimalYFovForViewSize(CGSizeMake(0, 0)), 60.0, 2.0); + XCTAssertEqualWithAccuracy(NYT360OptimalYFovForViewSize(CGSizeMake(1, 0)), 60.0, 2.0); + XCTAssertEqualWithAccuracy(NYT360OptimalYFovForViewSize(CGSizeMake(0, 1)), 120.0, 2.0); +} @end diff --git a/Sources/Info.plist b/Sources/Info.plist index 288c341..504fc36 100644 --- a/Sources/Info.plist +++ b/Sources/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.5.0 + 0.5.1 CFBundleSignature ???? CFBundleVersion diff --git a/Sources/NYT360CameraController.h b/Sources/NYT360CameraController.h index bed3847..f8e16c5 100644 --- a/Sources/NYT360CameraController.h +++ b/Sources/NYT360CameraController.h @@ -60,6 +60,11 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Panning Options +/** + * Updates the yFov of the camera to provide the optimal viewing angle for a given view size. Portrait videos will use a wider angle than landscape videos. + */ +- (void)updateCameraFOV:(CGSize)viewSize; + /** * An otherwise vanilla subclass of UIPanGestureRecognizer used by NYT360Video to enable manual camera panning. This class is exposed so that host applications can more easily configure interaction with other gesture recognizers without having to have references to specific instances of an NYT360Video pan recognizer. */ diff --git a/Sources/NYT360CameraController.m b/Sources/NYT360CameraController.m index 8d0bbfb..0ddd39c 100644 --- a/Sources/NYT360CameraController.m +++ b/Sources/NYT360CameraController.m @@ -21,7 +21,7 @@ @interface NYT360CameraController () @property (nonatomic) SCNView *view; @property (nonatomic) id motionManager; @property (nonatomic, strong, nullable) NYT360MotionManagementToken motionUpdateToken; -@property (nonatomic) SCNNode *camera; +@property (nonatomic) SCNNode *pointOfView; @property (nonatomic, assign) CGPoint rotateStart; @property (nonatomic, assign) CGPoint rotateCurrent; @@ -41,7 +41,7 @@ - (instancetype)initWithView:(SCNView *)view motionManager:(id 0) { + CGFloat ratio = viewSize.width / viewSize.height; + CGFloat slope = NYT360EulerAngleCalculationYFovFunctionSlope; + yFov = (slope * ratio) + NYT360EulerAngleCalculationYFovFunctionConstant; + yFov = MIN(MAX(yFov, NYT360EulerAngleCalculationYFovMin), NYT360EulerAngleCalculationYFovMax); + } else { + yFov = NYT360EulerAngleCalculationYFovDefault; + } + return yFov; +} diff --git a/Sources/NYT360ViewController.m b/Sources/NYT360ViewController.m index 7d88be5..34c6840 100644 --- a/Sources/NYT360ViewController.m +++ b/Sources/NYT360ViewController.m @@ -10,8 +10,6 @@ #import "NYT360CameraController.h" #import "NYT360PlayerScene.h" -static const CGFloat NYT360ViewControllerWideAngleAspectRatioThreshold = 16.0 / 9.0; - CGRect NYT360ViewControllerSceneFrameForContainingBounds(CGRect containingBounds, CGSize underlyingSceneSize) { if (CGSizeEqualToSize(underlyingSceneSize, CGSizeZero)) { @@ -113,7 +111,7 @@ - (void)viewDidLoad { self.sceneView.playing = true; - [self adjustCameraFOV:self.view.bounds.size]; + [self.cameraController updateCameraFOV:self.view.bounds.size]; } - (void)viewDidLayoutSubviews { @@ -149,7 +147,7 @@ - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id _Nonnull context) { [SCNTransaction setAnimationDuration:coordinator.transitionDuration]; - [self adjustCameraFOV:size]; + [self.cameraController updateCameraFOV:size]; } completion:^(id _Nonnull context) { if (!context.isCancelled) { // If you don't reset the duration to 0, all future camera upates @@ -169,23 +167,4 @@ - (void)renderer:(id )renderer updateAtTime:(NSTimeInterval)ti [self.delegate cameraAngleWasUpdated:self]; } -#pragma mark - Private - -- (void)adjustCameraFOV:(CGSize)viewSize { - - CGFloat actualRatio = viewSize.width / viewSize.height; - CGFloat threshold = NYT360ViewControllerWideAngleAspectRatioThreshold; - BOOL isPortrait = (actualRatio < threshold); - - // TODO: [jaredsinclair] Write a function that computes the optimal `yFov` - // for a given input size, rather than hard-coded break points. - - if (isPortrait) { - self.playerScene.camera.yFov = 100; - } - else { - self.playerScene.camera.yFov = 60; - } -} - @end diff --git a/ios-360-videos.xcodeproj/project.pbxproj b/ios-360-videos.xcodeproj/project.pbxproj index 1a787b9..b858f10 100644 --- a/ios-360-videos.xcodeproj/project.pbxproj +++ b/ios-360-videos.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ 470DB5DE1D49A058001DD20C /* NYT360EulerAngleCalculations.m in Sources */ = {isa = PBXBuildFile; fileRef = 47DCD2A21D493E1400FBCD4B /* NYT360EulerAngleCalculations.m */; }; 470DB5DF1D49A058001DD20C /* NYT360PlayerScene.m in Sources */ = {isa = PBXBuildFile; fileRef = 934A49851D46B446001AD295 /* NYT360PlayerScene.m */; }; 470DB5E01D49A058001DD20C /* NYT360ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 934A49871D46B446001AD295 /* NYT360ViewController.m */; }; + 471705571D639FB1003D542B /* NYT360CameraPanGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 47ACFE331D54DFC70054F8D0 /* NYT360CameraPanGestureRecognizer.m */; }; 472324FF1D5240DF00784F8F /* NYT360MotionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 472324FD1D5240DF00784F8F /* NYT360MotionManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 472325001D5240DF00784F8F /* NYT360MotionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 472324FE1D5240DF00784F8F /* NYT360MotionManager.m */; }; 472325011D524AB600784F8F /* NYT360MotionManagement.h in Headers */ = {isa = PBXBuildFile; fileRef = 472324FC1D523F6000784F8F /* NYT360MotionManagement.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -384,6 +385,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 471705571D639FB1003D542B /* NYT360CameraPanGestureRecognizer.m in Sources */, 470DB5DD1D49A058001DD20C /* NYT360CameraController.m in Sources */, 470DB5DE1D49A058001DD20C /* NYT360EulerAngleCalculations.m in Sources */, 470DB5DF1D49A058001DD20C /* NYT360PlayerScene.m in Sources */,