Reputation: 23
The quaternion you get from CMAttitude seems flawed. In Unity I can get the iPhone's rotation, apply it to a 3d object, and the object will rotate as you rotate the iPhone. In Xcode it seems to be different.
To set up a quick test project, follow these steps:
In Xcode, create a new project from the iOS > Game template (this gives us a 3d object to test on).
In GameViewController.h
add #import <CoreMotion/CoreMotion.h>
and @property (strong, nonatomic) CMMotionManager *motionManager;
In GameViewController.m
remove the animation at line:46 [ship runAction: etc..
and don't allow camera control at line:55 (not necessary)
In GameViewController.m
add to bottom of ViewDidLoad
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.deviceMotionUpdateInterval = .1;
[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue]
withHandler:^(CMDeviceMotion *motion, NSError *error) {
CMQuaternion q = motion.attitude.quaternion;
ship.rotation = SCNVector4Make(q.x, q.y, q.z, q.w);
if(error){ NSLog(@"%@", error); }
} ];
To avoid annoyances, in Project > Targets > Project Name > Deployment Info > Device Orientation, allow only Portrait (or just lock your iPhone's rotation)
When I build this to my iPhone the 3d object (an airplane) doesn't follow the rotation of the phone. Pitching kind of works.
Is this intended? How am I using this wrong?
Upvotes: 2
Views: 493
Reputation: 3554
In 3D space there are different representations of rotations.
You are using the rotation
property of SCNNode
:
The four-component rotation vector specifies the direction of the rotation axis in the first three components and the angle of rotation (in radians) in the fourth.
But you are assigning the device rotation as quaternion.
Either assign the quaternion to the orientation
property of SCNNode
or use the yaw, pitch and roll angles of CMAttitude
and assign these to the eulerAngles
property of SCNNode
:
The node’s orientation, expressed as pitch, yaw, and roll angles, each in radians.
Upvotes: 2