экспериментируя с набором сцен, я использую self.motionManager.deviceMotion.attitude.quaternion
для поворота узла сцены (камеры) в 3D-сцене. Допустим, пользователь запускает приложение, а устройство каким-то образом наклонено, поэтому эта начальная ориентация должна считаться точкой покоя, и в этом положении не должно происходить вращения. когда пользователь наклоняет устройство (влево ‹--› вправо и / или вверх ‹--› вниз), оно должно постепенно поворачиваться, пока пользователь не вернет устройство в исходную / исходную ориентацию, при которой вращения не произойдет. Согласно этому ответу я знаю, как фильтровать шум и случайное покачивание
эти следующие моменты важны:
- иметь ориентацию в состоянии покоя, при которой вращения не происходит
- когда устройство наклонено, затем поворачивайте постепенно
- при достижении вышеуказанных пунктов пользователю не нужно переворачивать устройство, чтобы получить полное вращение :-)
Я понятия не имею, как этого добиться. любая помощь приветствуется.
изменить: добавление кода, пытающегося реализовать ответ Рикстера
Мне нужно получить значения крена, рыскания, тангажа в startDeviceMotionUpdatesToQueue:withHandler:
, иначе все равно нулю
-(void) awakeFromNib
{
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.deviceMotionUpdateInterval = 1.0/60.0;
[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {
if (error == nil)
{
if (firstValue == NO)
{
firstValue = YES;
yaw = self.motionManager.deviceMotion.attitude.yaw;
roll = self.motionManager.deviceMotion.attitude.roll;
pitch = self.motionManager.deviceMotion.attitude.pitch;
}
}
}];
}
Я пытаюсь сначала повернуть по оси x на 5 градусов для простоты:
- (void)renderer:(id<SCNSceneRenderer>)aRenderer didSimulatePhysicsAtTime:(NSTimeInterval)time
{
currentYaw = self.motionManager.deviceMotion.attitude.yaw;
currentRoll = self.motionManager.deviceMotion.attitude.roll;
currentPitch = self.motionManager.deviceMotion.attitude.pitch;
SCNVector4 q =_cameraNode.presentationNode.rotation;
float phi = atan((2*(q.x*q.y + q.z*q.w))/(1-2*(pow(q.y,2)*pow(q.z,2))));
if (currentRoll > 0)
{
[_cameraNode runAction:[SCNAction rotateToAxisAngle:SCNVector4Make(1, 0, 0, ( phi + DEGREES_TO_RADIANS(5))) duration:1]];
}
else if(currentRoll < 0 )
{
[_cameraNode runAction:[SCNAction rotateToAxisAngle:SCNVector4Make(1, 0, 0, (phi - DEGREES_TO_RADIANS(5))) duration:1]];
}
}
вывод отладки для переменных:
отладка: q = (x = 0,999998092, y = 0, z = 0, w = -0,0872662216)
phi = 0
currentRoll = -1,1897298305515105
на самом деле он вообще не вращается. значение phi выглядит не очень хорошо. Что я делаю неправильно?
примечание: как сделать вращение сразу для всех осей? умножить кватернион oldRotation на x, затем на y, затем на z? это правильный порядок?