-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Groundwork for Feature MO-7031 #3
Changes from 12 commits
1c10897
df06bcc
c95b021
ee6318f
61f94f7
04c07dc
6d17d2f
b59f3c2
2f06167
66cf352
08942c2
00b2e17
1fcf076
36640d6
3a822a4
c51e6f1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// | ||
// NYT360DataTypes.h | ||
// ios-360-videos | ||
// | ||
// Created by Jared Sinclair on 7/27/16. | ||
// Copyright © 2016 The New York Times Company. All rights reserved. | ||
// | ||
|
||
@import Foundation; | ||
@import UIKit; | ||
@import SceneKit; | ||
@import CoreMotion; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not all these |
||
|
||
typedef NS_OPTIONS(NSInteger, NYT360PanningAxis) { | ||
NYT360PanningAxisHorizontal = 1 << 0, | ||
NYT360PanningAxisVertical = 1 << 1 | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// | ||
// NYT360EulerAngleCalculations.h | ||
// ios-360-videos | ||
// | ||
// Created by Jared Sinclair on 7/27/16. | ||
// Copyright © 2016 The New York Times Company. All rights reserved. | ||
// | ||
|
||
@import Foundation; | ||
@import UIKit; | ||
@import SceneKit; | ||
@import CoreMotion; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not all these |
||
|
||
#import "NYT360DataTypes.h" | ||
|
||
#pragma mark - Data Types | ||
|
||
struct NYT360EulerAngleCalculationResult { | ||
CGPoint position; | ||
SCNVector3 eulerAngles; | ||
}; | ||
typedef struct NYT360EulerAngleCalculationResult NYT360EulerAngleCalculationResult; | ||
|
||
#pragma mark - Calculations | ||
|
||
NYT360EulerAngleCalculationResult NYT360UpdatedPositionAndAnglesForAllowedAxes(CGPoint position, NYT360PanningAxis allowedPanningAxes); | ||
|
||
NYT360EulerAngleCalculationResult NYT360DeviceMotionCalculation(CGPoint position, CMRotationRate rotationRate, UIInterfaceOrientation orientation, NYT360PanningAxis allowedPanningAxes); | ||
|
||
NYT360EulerAngleCalculationResult NYT360PanGestureChangeCalculation(CGPoint position, CGPoint rotateDelta, CGSize viewSize, NYT360PanningAxis allowedPanningAxes); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// | ||
// NYT360EulerAngleCalculations.m | ||
// ios-360-videos | ||
// | ||
// Created by Jared Sinclair on 7/27/16. | ||
// Copyright © 2016 The New York Times Company. All rights reserved. | ||
// | ||
|
||
#import "NYT360EulerAngleCalculations.h" | ||
|
||
#pragma mark - Constants | ||
|
||
static CGFloat NYT360EulerAngleCalculationRotationRateDampingFactor = 0.02; | ||
|
||
#pragma mark - Inline Functions | ||
|
||
static inline CGFloat NYT360Clamp(CGFloat x, CGFloat low, CGFloat high) { | ||
return (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))); | ||
} | ||
|
||
static inline NYT360EulerAngleCalculationResult NYT360EulerAngleCalculationResultMake(CGPoint position, SCNVector3 eulerAngles) { | ||
NYT360EulerAngleCalculationResult result; | ||
result.position = position; | ||
result.eulerAngles = eulerAngles; | ||
return result; | ||
} | ||
|
||
static inline CGPoint NYT360AdjustPositionForAllowedAxes(CGPoint position, NYT360PanningAxis allowedPanningAxes) { | ||
BOOL suppressXaxis = (allowedPanningAxes & NYT360PanningAxisHorizontal) == 0; | ||
BOOL suppressYaxis = (allowedPanningAxes & NYT360PanningAxisVertical) == 0; | ||
if (suppressXaxis) { | ||
position.x = 0; | ||
} | ||
if (suppressYaxis) { | ||
position.y = 0; | ||
} | ||
return position; | ||
} | ||
|
||
#pragma mark - Calculations | ||
|
||
NYT360EulerAngleCalculationResult NYT360UpdatedPositionAndAnglesForAllowedAxes(CGPoint position, NYT360PanningAxis allowedPanningAxes) { | ||
position = NYT360AdjustPositionForAllowedAxes(position, allowedPanningAxes); | ||
SCNVector3 eulerAngles = SCNVector3Make(position.y, position.x, 0); | ||
return NYT360EulerAngleCalculationResultMake(position, eulerAngles); | ||
} | ||
|
||
NYT360EulerAngleCalculationResult NYT360DeviceMotionCalculation(CGPoint position, CMRotationRate rotationRate, UIInterfaceOrientation orientation, NYT360PanningAxis allowedPanningAxes) { | ||
|
||
CGFloat damping = NYT360EulerAngleCalculationRotationRateDampingFactor; | ||
|
||
// TODO: [thiago] I think this can be simplified later | ||
if (UIInterfaceOrientationIsLandscape(orientation)) { | ||
if (orientation == UIInterfaceOrientationLandscapeLeft) { | ||
position = CGPointMake(position.x + rotationRate.x * damping * -1, | ||
position.y + rotationRate.y * damping); | ||
} | ||
else { | ||
position = CGPointMake(position.x + rotationRate.x * damping, | ||
position.y + rotationRate.y * damping * -1); | ||
} | ||
} | ||
else { | ||
position = CGPointMake(position.x + rotationRate.y * damping, | ||
position.y - rotationRate.x * damping * -1); | ||
} | ||
position = CGPointMake(position.x, | ||
NYT360Clamp(position.y, -M_PI / 2, M_PI / 2)); | ||
|
||
// Zero-out these values here rather than above, since that would over- | ||
// complicate the if/else logic or require unreadable numbers of ternary | ||
// operators. | ||
position = NYT360AdjustPositionForAllowedAxes(position, allowedPanningAxes); | ||
|
||
SCNVector3 eulerAngles = SCNVector3Make(position.y, position.x, 0); | ||
|
||
return NYT360EulerAngleCalculationResultMake(position, eulerAngles); | ||
} | ||
|
||
NYT360EulerAngleCalculationResult NYT360PanGestureChangeCalculation(CGPoint position, CGPoint rotateDelta, CGSize viewSize, NYT360PanningAxis allowedPanningAxes) { | ||
|
||
// TODO: [jaredsinclair] Consider adding constants for the multipliers | ||
// TODO: [jaredsinclair] Find out why the y multiplier is 0.4 and not 0.5 | ||
position = CGPointMake(position.x + 2 * M_PI * rotateDelta.x / viewSize.width * 0.5, | ||
position.y + 2 * M_PI * rotateDelta.y / viewSize.height * 0.4); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm curious why the y component uses a 0.4 multiplier instead of 0.5. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when we were testing the movements this speed was discomforting on the y axis |
||
position.y = NYT360Clamp(position.y, -M_PI / 2, M_PI / 2); | ||
|
||
position = NYT360AdjustPositionForAllowedAxes(position, allowedPanningAxes); | ||
|
||
SCNVector3 eulerAngles = SCNVector3Make(position.y, position.x, 0); | ||
|
||
return NYT360EulerAngleCalculationResultMake(position, eulerAngles); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,3 +17,5 @@ FOUNDATION_EXPORT const unsigned char Three60_PlayerVersionString[]; | |
// In this header, you should import all the public headers of your framework using statements like #import <Three60_Player_iOS/PublicHeader.h> | ||
|
||
#import <Three60_Player/NYT360ViewController.h> | ||
#import <Three60_Player/NYT360DataTypes.h> | ||
#import <Three60_Player/NYT360EulerAngleCalculations.h> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// | ||
// NYT360EulerAngleCalculationsTests.m | ||
// ios-360-videos | ||
// | ||
// Created by Jared Sinclair on 7/27/16. | ||
// Copyright © 2016 The New York Times Company. All rights reserved. | ||
// | ||
|
||
@import XCTest; | ||
@import CoreMotion; | ||
@import Three60_Player; | ||
|
||
@interface NYT360EulerAngleCalculationsTests : XCTestCase | ||
|
||
@end | ||
|
||
@implementation NYT360EulerAngleCalculationsTests | ||
|
||
- (void)testUpdateFunctionShouldZeroOutDisallowedYAxis { | ||
CGPoint position = CGPointMake(100, 100); | ||
NYT360EulerAngleCalculationResult result = NYT360UpdatedPositionAndAnglesForAllowedAxes(position, NYT360PanningAxisHorizontal); | ||
XCTAssertEqual(result.position.x, 100); | ||
XCTAssertEqual(result.position.y, 0); | ||
} | ||
|
||
- (void)testUpdateFunctionShouldZeroOutDisallowedXAxis { | ||
CGPoint position = CGPointMake(100, 100); | ||
NYT360EulerAngleCalculationResult result = NYT360UpdatedPositionAndAnglesForAllowedAxes(position, NYT360PanningAxisVertical); | ||
XCTAssertEqual(result.position.x, 0); | ||
XCTAssertEqual(result.position.y, 100); | ||
} | ||
|
||
- (void)testDeviceMotionFunctionShouldZeroOutDisallowedYAxis { | ||
CGPoint position = CGPointMake(100, 100); | ||
CMRotationRate rate; | ||
rate.x = 1000; | ||
rate.y = -1000; | ||
rate.z = 10; | ||
UIInterfaceOrientation orientation = UIInterfaceOrientationLandscapeLeft; | ||
NYT360EulerAngleCalculationResult result = NYT360DeviceMotionCalculation(position, rate, orientation, NYT360PanningAxisHorizontal); | ||
XCTAssertNotEqual(result.position.x, 0); | ||
XCTAssertEqual(result.position.y, 0); | ||
} | ||
|
||
- (void)testDeviceMotionFunctionShouldZeroOutDisallowedXAxis { | ||
CGPoint position = CGPointMake(100, 100); | ||
CMRotationRate rate; | ||
rate.x = 1000; | ||
rate.y = -1000; | ||
rate.z = 10; | ||
UIInterfaceOrientation orientation = UIInterfaceOrientationLandscapeLeft; | ||
NYT360EulerAngleCalculationResult result = NYT360DeviceMotionCalculation(position, rate, orientation, NYT360PanningAxisVertical); | ||
XCTAssertEqual(result.position.x, 0); | ||
XCTAssertNotEqual(result.position.y, 0); | ||
} | ||
|
||
- (void)testPanGestureChangeFunctionShouldZeroOutDisallowedYAxis { | ||
CGPoint position = CGPointMake(100, 100); | ||
CGPoint delta = CGPointMake(1000, -1000); | ||
CGSize viewSize = CGSizeMake(536, 320); | ||
NYT360EulerAngleCalculationResult result = NYT360PanGestureChangeCalculation(position, delta, viewSize, NYT360PanningAxisHorizontal); | ||
XCTAssertNotEqual(result.position.x, 0); | ||
XCTAssertEqual(result.position.y, 0); | ||
} | ||
|
||
- (void)testPanGestureChangeFunctionShouldZeroOutDisallowedXAxis { | ||
CGPoint position = CGPointMake(100, 100); | ||
CGPoint delta = CGPointMake(1000, -1000); | ||
CGSize viewSize = CGSizeMake(536, 320); | ||
NYT360EulerAngleCalculationResult result = NYT360PanGestureChangeCalculation(position, delta, viewSize, NYT360PanningAxisVertical); | ||
XCTAssertEqual(result.position.x, 0); | ||
XCTAssertNotEqual(result.position.y, 0); | ||
} | ||
|
||
|
||
@end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it worth only running the remainder of this method if
allowedPanningAxes != _allowedPanningAxes
?