Skip to content

Commit

Permalink
Merge pull request #27 from nytm/develop
Browse files Browse the repository at this point in the history
v 0.5.1
  • Loading branch information
jaredsinclair committed Aug 17, 2016
2 parents 893a636 + 6b26a60 commit c22f1f2
Show file tree
Hide file tree
Showing 11 changed files with 56 additions and 33 deletions.
2 changes: 1 addition & 1 deletion NYT360Video.podspec
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion NYT360VideoExample/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.5.0</string>
<string>0.5.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
2 changes: 1 addition & 1 deletion NYT360VideoTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>0.5.0</string>
<string>0.5.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
10 changes: 10 additions & 0 deletions NYT360VideoTests/NYT360EulerAngleCalculationsTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion Sources/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.5.0</string>
<string>0.5.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
5 changes: 5 additions & 0 deletions Sources/NYT360CameraController.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
14 changes: 9 additions & 5 deletions Sources/NYT360CameraController.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ @interface NYT360CameraController ()
@property (nonatomic) SCNView *view;
@property (nonatomic) id<NYT360MotionManagement> 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;
Expand All @@ -41,7 +41,7 @@ - (instancetype)initWithView:(SCNView *)view motionManager:(id<NYT360MotionManag
NSAssert(view.pointOfView != nil, @"NYT360CameraController must be initialized with a view with a non-nil pointOfView node.");
NSAssert(view.pointOfView.camera != nil, @"NYT360CameraController must be initialized with a view with a non-nil camera node for view.pointOfView.");

_camera = view.pointOfView;
_pointOfView = view.pointOfView;
_view = view;
_currentPosition = CGPointMake(0, 0);
_allowedPanningAxes = NYT360PanningAxisHorizontal | NYT360PanningAxisVertical;
Expand Down Expand Up @@ -95,7 +95,11 @@ - (void)updateCameraAngle {
NYT360EulerAngleCalculationResult result;
result = NYT360DeviceMotionCalculation(self.currentPosition, rotationRate, orientation, self.allowedPanningAxes, NYT360EulerAngleCalculationNoiseThresholdDefault);
self.currentPosition = result.position;
self.camera.eulerAngles = result.eulerAngles;
self.pointOfView.eulerAngles = result.eulerAngles;
}

- (void)updateCameraFOV:(CGSize)viewSize {
self.pointOfView.camera.yFov = NYT360OptimalYFovForViewSize(viewSize);
}

#pragma mark - Panning Options
Expand All @@ -106,7 +110,7 @@ - (void)setAllowedPanningAxes:(NYT360PanningAxis)allowedPanningAxes {
_allowedPanningAxes = allowedPanningAxes;
NYT360EulerAngleCalculationResult result = NYT360UpdatedPositionAndAnglesForAllowedAxes(self.currentPosition, allowedPanningAxes);
self.currentPosition = result.position;
self.camera.eulerAngles = result.eulerAngles;
self.pointOfView.eulerAngles = result.eulerAngles;

}
}
Expand All @@ -125,7 +129,7 @@ - (void)handlePan:(UIPanGestureRecognizer *)recognizer {
self.rotateStart = self.rotateCurrent;
NYT360EulerAngleCalculationResult result = NYT360PanGestureChangeCalculation(self.currentPosition, self.rotateDelta, self.view.bounds.size, self.allowedPanningAxes);
self.currentPosition = result.position;
self.camera.eulerAngles = result.eulerAngles;
self.pointOfView.eulerAngles = result.eulerAngles;
break;
default:
break;
Expand Down
2 changes: 2 additions & 0 deletions Sources/NYT360EulerAngleCalculations.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ NYT360EulerAngleCalculationResult NYT360UpdatedPositionAndAnglesForAllowedAxes(C
NYT360EulerAngleCalculationResult NYT360DeviceMotionCalculation(CGPoint position, CMRotationRate rotationRate, UIInterfaceOrientation orientation, NYT360PanningAxis allowedPanningAxes, CGFloat noiseThreshold);

NYT360EulerAngleCalculationResult NYT360PanGestureChangeCalculation(CGPoint position, CGPoint rotateDelta, CGSize viewSize, NYT360PanningAxis allowedPanningAxes);

CGFloat NYT360OptimalYFovForViewSize(CGSize viewSize);
23 changes: 22 additions & 1 deletion Sources/NYT360EulerAngleCalculations.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#pragma mark - Constants

CGFloat const NYT360EulerAngleCalculationNoiseThresholdDefault = 0.12;
static CGFloat NYT360EulerAngleCalculationRotationRateDampingFactor = 0.02;

#pragma mark - Inline Functions

Expand Down Expand Up @@ -48,6 +47,8 @@ NYT360EulerAngleCalculationResult NYT360UpdatedPositionAndAnglesForAllowedAxes(C

NYT360EulerAngleCalculationResult NYT360DeviceMotionCalculation(CGPoint position, CMRotationRate rotationRate, UIInterfaceOrientation orientation, NYT360PanningAxis allowedPanningAxes, CGFloat noiseThreshold) {

static CGFloat NYT360EulerAngleCalculationRotationRateDampingFactor = 0.02;

// On some devices, the rotation rates exhibit a low-level drift on one or
// more rotation axes. The symptom expressions are not identical, but they
// appear to be related to low component quality (iPhone 5c versus higher
Expand Down Expand Up @@ -115,3 +116,23 @@ NYT360EulerAngleCalculationResult NYT360PanGestureChangeCalculation(CGPoint posi

return NYT360EulerAngleCalculationResultMake(position, eulerAngles);
}

CGFloat NYT360OptimalYFovForViewSize(CGSize viewSize) {

static CGFloat NYT360EulerAngleCalculationYFovDefault = 60.0;
static CGFloat NYT360EulerAngleCalculationYFovMin = 40.0;
static CGFloat NYT360EulerAngleCalculationYFovMax = 120.0;
static CGFloat NYT360EulerAngleCalculationYFovFunctionSlope = -33.01365882011044;
static CGFloat NYT360EulerAngleCalculationYFovFunctionConstant = 118.599244406;

CGFloat yFov;
if (viewSize.height > 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;
}
25 changes: 2 additions & 23 deletions Sources/NYT360ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -149,7 +147,7 @@ - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIV

[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
[SCNTransaction setAnimationDuration:coordinator.transitionDuration];
[self adjustCameraFOV:size];
[self.cameraController updateCameraFOV:size];
} completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
if (!context.isCancelled) {
// If you don't reset the duration to 0, all future camera upates
Expand All @@ -169,23 +167,4 @@ - (void)renderer:(id <SCNSceneRenderer>)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
2 changes: 2 additions & 0 deletions ios-360-videos.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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, ); }; };
Expand Down Expand Up @@ -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 */,
Expand Down

0 comments on commit c22f1f2

Please sign in to comment.