From 8042a2f4b91e75ec46a4f385e9b1184ef9a3527c Mon Sep 17 00:00:00 2001 From: Chris Dzombak Date: Fri, 26 Aug 2016 11:56:05 -0400 Subject: [PATCH 1/7] fix: handle the case where weakSelf is deallocated before executing callback block --- Sources/NYT360ViewController.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sources/NYT360ViewController.m b/Sources/NYT360ViewController.m index 0b90cde..ab02bb9 100644 --- a/Sources/NYT360ViewController.m +++ b/Sources/NYT360ViewController.m @@ -67,6 +67,10 @@ - (instancetype)initWithAVPlayer:(AVPlayer *)player motionManager:(id Date: Tue, 30 Aug 2016 10:57:52 -0500 Subject: [PATCH 2/7] Fix a bug with background audio on iOS 9. --- Sources/NYT360PlayerScene.m | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Sources/NYT360PlayerScene.m b/Sources/NYT360PlayerScene.m index 4429529..599be58 100644 --- a/Sources/NYT360PlayerScene.m +++ b/Sources/NYT360PlayerScene.m @@ -190,7 +190,20 @@ - (void)pause { else { // Prior to iOS 10, SceneKit prefers to use `setPaused:` alone to toggle // playback on a video node. Mimic this usage here to ensure consistency - // and avoid putting the player into an out-of-sync state. + // and avoid putting the player into an out-of-sync state. There is one + // caveat, however: when the host application is pausing playback as the + // app is entering the background (and if background audio is enabled in + // the host application), then if you do not also call `pause` directly + // on the AVPlayer, then the player's audio will continue playing in the + // background. Even though this bug workaround means that our `pause` + // implementation is identical between iOS 8/9 and iOS 10, it's worth + // keeping the above check for the OS version since the edge cases + // before and after iOS 10 are different enough that it's worth keeping + // the implementations separated, if only for clarity that can be added + // via OS specific documentation (and also the fact that iOS 10's + // behavior may change between the current beta and a future production + // release). + [self.player pause]; self.videoNode.paused = YES; } From 8b79878abae0792bb6113a5966712b7ac05bd36e Mon Sep 17 00:00:00 2001 From: Julieta Date: Wed, 31 Aug 2016 12:18:05 -0300 Subject: [PATCH 3/7] Compass is Moving in Opposite Direction of Phone https://jira.nyt.net/browse/MO-7115 --- Sources/NYT360EulerAngleCalculations.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/NYT360EulerAngleCalculations.m b/Sources/NYT360EulerAngleCalculations.m index 7037b94..1d12cc2 100644 --- a/Sources/NYT360EulerAngleCalculations.m +++ b/Sources/NYT360EulerAngleCalculations.m @@ -156,5 +156,5 @@ CGFloat NYT360OptimalYFovForViewSize(CGSize viewSize) { } float NYT360CompassAngleForEulerAngles(SCNVector3 eulerAngles, float referenceAngle) { - return NYT360UnitRotationForCameraRotation(eulerAngles.y + referenceAngle); + return NYT360UnitRotationForCameraRotation((-1 * eulerAngles.y) + referenceAngle); } From 4dbe43d1b008749b8497c069b5b3cd290a035601 Mon Sep 17 00:00:00 2001 From: Julieta Date: Wed, 31 Aug 2016 15:30:23 -0300 Subject: [PATCH 4/7] Update the test --- .../NYT360EulerAngleCalculationsTests.m | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/NYT360VideoTests/NYT360EulerAngleCalculationsTests.m b/NYT360VideoTests/NYT360EulerAngleCalculationsTests.m index ff439ae..60df3ce 100644 --- a/NYT360VideoTests/NYT360EulerAngleCalculationsTests.m +++ b/NYT360VideoTests/NYT360EulerAngleCalculationsTests.m @@ -154,35 +154,35 @@ - (void)testItCalculatesTheCorrectCompassAngleForAVarietyOfInputs { compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); XCTAssertEqualWithAccuracy(compassAngle, 0, 0.001); - eulerAngles.y = pi * 0.5; + eulerAngles.y = pi * -0.5; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); XCTAssertEqualWithAccuracy(compassAngle, pi * 1.5, 0.001); - eulerAngles.y = pi * -0.5; + eulerAngles.y = pi * 0.5; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); XCTAssertEqualWithAccuracy(compassAngle, pi * 0.5, 0.001); - eulerAngles.y = pi * 1.5; + eulerAngles.y = pi * -1.5; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); XCTAssertEqualWithAccuracy(compassAngle, pi * 0.5, 0.001); - eulerAngles.y = pi * -1.5; + eulerAngles.y = pi * 1.5; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); XCTAssertEqualWithAccuracy(compassAngle, pi * -0.5, 0.001); - eulerAngles.y = pi * 2.0; + eulerAngles.y = pi * -2.0; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); XCTAssertEqualWithAccuracy(compassAngle, pi, 0.001); - eulerAngles.y = pi * -2.0; + eulerAngles.y = pi * 2.0; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); XCTAssertEqualWithAccuracy(compassAngle, -pi, 0.001); - eulerAngles.y = pi * 2.5; + eulerAngles.y = pi * -2.5; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); XCTAssertEqualWithAccuracy(compassAngle, pi * 1.5, 0.001); - eulerAngles.y = pi * -2.5; + eulerAngles.y = pi * 2.5; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); XCTAssertEqualWithAccuracy(compassAngle, pi * -1.5, 0.001); @@ -194,11 +194,11 @@ - (void)testItCalculatesTheCorrectCompassAngleForAVarietyOfInputs { compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); XCTAssertEqualWithAccuracy(compassAngle, 0, 0.001); - eulerAngles.y = pi * 4.0; + eulerAngles.y = pi * -4.0; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); XCTAssertEqualWithAccuracy(compassAngle, pi, 0.001); - eulerAngles.y = pi * -4.0; + eulerAngles.y = pi * 4.0; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); XCTAssertEqualWithAccuracy(compassAngle, -pi, 0.001); } From 571345a8a6d888c88d3751a243c2075ea566c47e Mon Sep 17 00:00:00 2001 From: Jared Sinclair Date: Wed, 31 Aug 2016 14:15:52 -0500 Subject: [PATCH 5/7] Update camera angle calculations and unit tests, adding documentation. --- .../NYT360EulerAngleCalculationsTests.m | 70 ++++++++++++------- Sources/NYT360EulerAngleCalculations.h | 15 ++++ Sources/NYT360EulerAngleCalculations.m | 4 +- Sources/NYT360ViewController.h | 6 +- 4 files changed, 66 insertions(+), 29 deletions(-) diff --git a/NYT360VideoTests/NYT360EulerAngleCalculationsTests.m b/NYT360VideoTests/NYT360EulerAngleCalculationsTests.m index 60df3ce..6c186ba 100644 --- a/NYT360VideoTests/NYT360EulerAngleCalculationsTests.m +++ b/NYT360VideoTests/NYT360EulerAngleCalculationsTests.m @@ -135,8 +135,28 @@ - (void)testItCalculatesTheOptimalYFovForAVarietyOfInputs { - (void)testItCalculatesTheCorrectCompassAngleForAVarietyOfInputs { + // Unless the host application needs a non-zero reference angle (zero is the + // default), we want an input camera rotation of 0 to yield a compass angle + // of 0 where 0 is pointing "due north". + // + // The y component of the SCNVector3 is positive in the counter-clockwise + // direction, whereas as UIKit rotation transforms are positive in the + // clockwise direction. Thus we want to map camera rotation values to + // compass angle values by mapping them to the equivalent rotation transform + // in the opposite direction. + // + // For example, a positive quarter turn of the camera is equivalent to a + // negative quarter turn of a rotation transform, or: + // + // 0.25 cam rotations -> -0.25 rotation transform rotations + // + // or in their raw radian values: + // + // 1.571 camera radians -> -1.571 rotation transform radians + SCNVector3 eulerAngles; float pi = M_PI; + float oneRotation = pi * 2.0; float compassAngle; float referenceAngle; @@ -144,63 +164,63 @@ - (void)testItCalculatesTheCorrectCompassAngleForAVarietyOfInputs { eulerAngles.y = 0; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); - XCTAssertEqualWithAccuracy(compassAngle, pi, 0.001); + XCTAssertEqualWithAccuracy(compassAngle, 0, 0.001); - eulerAngles.y = pi; + eulerAngles.y = oneRotation; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); XCTAssertEqualWithAccuracy(compassAngle, 0, 0.001); - eulerAngles.y = -pi; + eulerAngles.y = -oneRotation; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); XCTAssertEqualWithAccuracy(compassAngle, 0, 0.001); - eulerAngles.y = pi * -0.5; + eulerAngles.y = oneRotation * -0.5; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); - XCTAssertEqualWithAccuracy(compassAngle, pi * 1.5, 0.001); + XCTAssertEqualWithAccuracy(compassAngle, oneRotation * 0.5, 0.001); - eulerAngles.y = pi * 0.5; + eulerAngles.y = oneRotation * 0.5; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); - XCTAssertEqualWithAccuracy(compassAngle, pi * 0.5, 0.001); + XCTAssertEqualWithAccuracy(compassAngle, oneRotation * -0.5, 0.001); - eulerAngles.y = pi * -1.5; + eulerAngles.y = oneRotation * -1.5; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); - XCTAssertEqualWithAccuracy(compassAngle, pi * 0.5, 0.001); + XCTAssertEqualWithAccuracy(compassAngle, oneRotation * 0.5, 0.001); - eulerAngles.y = pi * 1.5; + eulerAngles.y = oneRotation * 1.5; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); - XCTAssertEqualWithAccuracy(compassAngle, pi * -0.5, 0.001); + XCTAssertEqualWithAccuracy(compassAngle, oneRotation * -0.5, 0.001); - eulerAngles.y = pi * -2.0; + eulerAngles.y = oneRotation * -2.0; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); - XCTAssertEqualWithAccuracy(compassAngle, pi, 0.001); + XCTAssertEqualWithAccuracy(compassAngle, 0, 0.001); - eulerAngles.y = pi * 2.0; + eulerAngles.y = oneRotation * 2.0; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); - XCTAssertEqualWithAccuracy(compassAngle, -pi, 0.001); + XCTAssertEqualWithAccuracy(compassAngle, 0, 0.001); - eulerAngles.y = pi * -2.5; + eulerAngles.y = oneRotation * -2.5; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); - XCTAssertEqualWithAccuracy(compassAngle, pi * 1.5, 0.001); + XCTAssertEqualWithAccuracy(compassAngle, oneRotation * 0.5, 0.001); - eulerAngles.y = pi * 2.5; + eulerAngles.y = oneRotation * 2.5; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); - XCTAssertEqualWithAccuracy(compassAngle, pi * -1.5, 0.001); + XCTAssertEqualWithAccuracy(compassAngle, oneRotation * -0.5, 0.001); - eulerAngles.y = pi * 3.0; + eulerAngles.y = oneRotation * 3.0; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); XCTAssertEqualWithAccuracy(compassAngle, 0, 0.001); - eulerAngles.y = pi * -3.0; + eulerAngles.y = oneRotation * -3.0; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); XCTAssertEqualWithAccuracy(compassAngle, 0, 0.001); - eulerAngles.y = pi * -4.0; + eulerAngles.y = oneRotation * -3.5; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); - XCTAssertEqualWithAccuracy(compassAngle, pi, 0.001); + XCTAssertEqualWithAccuracy(compassAngle, oneRotation * 0.5, 0.001); - eulerAngles.y = pi * 4.0; + eulerAngles.y = oneRotation * 3.5; compassAngle = NYT360CompassAngleForEulerAngles(eulerAngles, referenceAngle); - XCTAssertEqualWithAccuracy(compassAngle, -pi, 0.001); + XCTAssertEqualWithAccuracy(compassAngle, oneRotation * -0.5, 0.001); } @end diff --git a/Sources/NYT360EulerAngleCalculations.h b/Sources/NYT360EulerAngleCalculations.h index c8912d7..f95059d 100644 --- a/Sources/NYT360EulerAngleCalculations.h +++ b/Sources/NYT360EulerAngleCalculations.h @@ -33,4 +33,19 @@ NYT360EulerAngleCalculationResult NYT360PanGestureChangeCalculation(CGPoint posi CGFloat NYT360OptimalYFovForViewSize(CGSize viewSize); +/** + * Unless the host application needs a non-zero reference angle (zero is the default), we want an input camera rotation of 0 to yield a compass angle of 0 where 0 is pointing "due north". + * + * The y component of the SCNVector3 is positive in the counter-clockwise direction, whereas as UIKit rotation transforms are positive in the clockwise direction. Thus we want to map camera rotation values to compass angle values by mapping them to the equivalent rotation transform in the opposite direction. + * + * For example, a positive quarter turn of the camera is equivalent to a negative quarter turn of a rotation transform, or: + * + * 0.25 cam rotations -> -0.25 rotation transform rotations + * + * or in their raw radian values: + * + * 1.571 camera radians -> -1.571 rotation transform radians + * + * Input values in excess of one rotation will be mapped to an equivalent value within the range of plus or minus one radian, such that output values will exceed one rotation. Input values equal (or very very close to equal) to a multiple of one radian (positive or negative) will be mapped to 0. + */ float NYT360CompassAngleForEulerAngles(SCNVector3 eulerAngles, float referenceAngle); diff --git a/Sources/NYT360EulerAngleCalculations.m b/Sources/NYT360EulerAngleCalculations.m index 1d12cc2..24634c4 100644 --- a/Sources/NYT360EulerAngleCalculations.m +++ b/Sources/NYT360EulerAngleCalculations.m @@ -11,7 +11,7 @@ #pragma mark - Constants CGFloat const NYT360EulerAngleCalculationNoiseThresholdDefault = 0.12; -float const NYT360EulerAngleCalculationDefaultReferenceCompassAngle = M_PI; +float const NYT360EulerAngleCalculationDefaultReferenceCompassAngle = 0; #pragma mark - Inline Functions @@ -156,5 +156,5 @@ CGFloat NYT360OptimalYFovForViewSize(CGSize viewSize) { } float NYT360CompassAngleForEulerAngles(SCNVector3 eulerAngles, float referenceAngle) { - return NYT360UnitRotationForCameraRotation((-1 * eulerAngles.y) + referenceAngle); + return NYT360UnitRotationForCameraRotation((-1.0 * eulerAngles.y) + referenceAngle); } diff --git a/Sources/NYT360ViewController.h b/Sources/NYT360ViewController.h index 46d1fd6..2b4b76f 100644 --- a/Sources/NYT360ViewController.h +++ b/Sources/NYT360ViewController.h @@ -27,7 +27,7 @@ NS_ASSUME_NONNULL_BEGIN * Called when the compass angle is updated. * * @param viewController The view controller that updated the angle. - * @param compassAngle The current compass angle. + * @param compassAngle The current compass angle. The value will be within the range of plus or minus one radian, non-inclusive, where a positive value is equivalent to a clockwise rotation. * * @note This method is called synchronously from SCNSceneRendererDelegate; its implementation should return quickly to avoid performance implications. */ @@ -62,7 +62,9 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Camera Movement /** - Returns the current compass angle. + * Returns the current compass angle. + * + * The value will be within the range of plus or minus one radian, non-inclusive, where a positive value is equivalent to a clockwise rotation. */ @property (nonatomic, readonly) float compassAngle; From a132ae1773078bc3d8fa5990c1a3b313c0a57e4a Mon Sep 17 00:00:00 2001 From: Jared Sinclair Date: Wed, 31 Aug 2016 14:22:38 -0500 Subject: [PATCH 6/7] Fix a typo. --- NYT360VideoTests/NYT360EulerAngleCalculationsTests.m | 2 +- Sources/NYT360EulerAngleCalculations.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NYT360VideoTests/NYT360EulerAngleCalculationsTests.m b/NYT360VideoTests/NYT360EulerAngleCalculationsTests.m index 6c186ba..4df5f5a 100644 --- a/NYT360VideoTests/NYT360EulerAngleCalculationsTests.m +++ b/NYT360VideoTests/NYT360EulerAngleCalculationsTests.m @@ -140,7 +140,7 @@ - (void)testItCalculatesTheCorrectCompassAngleForAVarietyOfInputs { // of 0 where 0 is pointing "due north". // // The y component of the SCNVector3 is positive in the counter-clockwise - // direction, whereas as UIKit rotation transforms are positive in the + // direction, whereas UIKit rotation transforms are positive in the // clockwise direction. Thus we want to map camera rotation values to // compass angle values by mapping them to the equivalent rotation transform // in the opposite direction. diff --git a/Sources/NYT360EulerAngleCalculations.h b/Sources/NYT360EulerAngleCalculations.h index f95059d..d55d1aa 100644 --- a/Sources/NYT360EulerAngleCalculations.h +++ b/Sources/NYT360EulerAngleCalculations.h @@ -36,7 +36,7 @@ CGFloat NYT360OptimalYFovForViewSize(CGSize viewSize); /** * Unless the host application needs a non-zero reference angle (zero is the default), we want an input camera rotation of 0 to yield a compass angle of 0 where 0 is pointing "due north". * - * The y component of the SCNVector3 is positive in the counter-clockwise direction, whereas as UIKit rotation transforms are positive in the clockwise direction. Thus we want to map camera rotation values to compass angle values by mapping them to the equivalent rotation transform in the opposite direction. + * The y component of the SCNVector3 is positive in the counter-clockwise direction, whereas UIKit rotation transforms are positive in the clockwise direction. Thus we want to map camera rotation values to compass angle values by mapping them to the equivalent rotation transform in the opposite direction. * * For example, a positive quarter turn of the camera is equivalent to a negative quarter turn of a rotation transform, or: * From 333d3a804239e20a4a905a75612ecfa1f6aacd80 Mon Sep 17 00:00:00 2001 From: Jared Sinclair Date: Wed, 31 Aug 2016 14:50:56 -0500 Subject: [PATCH 7/7] Bump to version 0.6.1. --- NYT360Video.podspec | 2 +- NYT360VideoExample/Info.plist | 2 +- NYT360VideoTests/Info.plist | 2 +- Sources/Info.plist | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NYT360Video.podspec b/NYT360Video.podspec index 6af3534..2eb35f1 100644 --- a/NYT360Video.podspec +++ b/NYT360Video.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'NYT360Video' - s.version = '0.6.0' + s.version = '0.6.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 7f3057e..616a369 100644 --- a/NYT360VideoExample/Info.plist +++ b/NYT360VideoExample/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.6.0 + 0.6.1 CFBundleSignature ???? CFBundleVersion diff --git a/NYT360VideoTests/Info.plist b/NYT360VideoTests/Info.plist index 3b73345..32bebf8 100644 --- a/NYT360VideoTests/Info.plist +++ b/NYT360VideoTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 0.6.0 + 0.6.1 CFBundleSignature ???? CFBundleVersion diff --git a/Sources/Info.plist b/Sources/Info.plist index 63c3e67..5b6037d 100644 --- a/Sources/Info.plist +++ b/Sources/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.6.0 + 0.6.1 CFBundleSignature ???? CFBundleVersion