Изолировать и удалить горизонтальное вращение из вращения Coremotion к вращению Matrix
-
27-10-2019 - |
Вопрос
Я делаю что -то вроде приложения дополненной реальности, в котором у меня есть сцена OpenGL, которую я хочу оставаться в соответствии с гравитацией, независимо от того, как движется устройство iOS. Я думал, что у меня все было хорошо с cmdevicemotion.attitude.pitch, пока я не обнаружил, что склонение к iPhone бокового бокового происхождения связывается с этим номером. Поэтому я взял какой -то код из примера парка*, и теперь я пытаюсь выделить вращение вокруг вертикального доступа. Сцена, которую я рисую, не заботится о том, с каким направлением пользователя сталкивается, цифры всегда будут нарисоваться на установленном расстоянии от зрителя. Я думаю, что, когда я выясняю компонент вращения вертикальной оси, я могу изменить его и размножить его из матрицы вращения, так что оставьте фигуры OpenGL по -прежнему, когда пользователь меняет заголовок.
Вот мой код:
CMDeviceMotion *d = motionManager.deviceMotion;
if (d != nil) {
CMRotationMatrix r = d.attitude.rotationMatrix;
transformFromCMRotationMatrix(cameraTransform, &r);
mat4f_t projectionCameraTransform;
multiplyMatrixAndMatrix(projectionCameraTransform, projectionTransform, cameraTransform);
GLKMatrix4 rotMatrix = GLKMatrix4Make(projectionCameraTransform[0],
projectionCameraTransform[1],
projectionCameraTransform[2],
projectionCameraTransform[3],
projectionCameraTransform[4],
projectionCameraTransform[5],
projectionCameraTransform[6],
projectionCameraTransform[7],
projectionCameraTransform[8],
projectionCameraTransform[9],
projectionCameraTransform[10],
projectionCameraTransform[11],
projectionCameraTransform[12],
projectionCameraTransform[13],
projectionCameraTransform[14],
projectionCameraTransform[15]);
}
Затем я использую Rotmatrix как обычно в OpenGL.
Мысли, предложения? Заранее спасибо.
*Примерный код парка устанавливает несколько очков в реальном пространстве, разрабатывает местоположение пользователя и относительное направление этих точек и привлекает их на экране, поэтому, похоже, плавает на горизонте, указывающем на их местоположение.
Решение 3
Я взял некоторые намеки из этого ответа и придумал решение:
if (d != nil) {
GLKMatrix4 rotMatrix = GLKMatrix4MakeRotation(0, 0, 1, 0);
float pitch = d.attitude.pitch;
if (d.gravity.z > 0)
pitch = -pitch;
rotMatrix = GLKMatrix4Rotate(rotMatrix, pitch, -1, 0, 0);
rotMatrix = GLKMatrix4Rotate(rotMatrix, d.attitude.roll, 0, -1, 0);
rotMatrix = GLKMatrix4Rotate(rotMatrix, d.attitude.yaw, 0, 0, -1);
rotMatrix = GLKMatrix4Multiply(rotMatrix, GLKMatrix4MakeRotation(M_PI/2, 1, 0, 0));
}
Однако этот склонен, когда телефон находится почти вертикальным. Так что я все еще смотрю.
Другие советы
Я просто поворачиваю ориентацию вокруг оси Z в зависимости от ориентации экрана устройства. Это не самое красивое, но, похоже, он делает именно то, что мне нужно, не обращаясь к Эйлеру и обратно (и, таким образом, избегая проблем с заблокированным гимфоном)
GLKMatrix4 deviceMotionAttitudeMatrix;
if (_cmMotionmanager.deviceMotionActive) {
CMDeviceMotion *deviceMotion = _cmMotionmanager.deviceMotion;
// Correct for the rotation matrix not including the screen orientation:
// TODO: Let the device notify me when the orientation changes instead of querying on each update.
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
float deviceOrientationRadians = 0.0f;
if (orientation == UIDeviceOrientationLandscapeLeft) {
deviceOrientationRadians = M_PI_2;
}
if (orientation == UIDeviceOrientationLandscapeRight) {
deviceOrientationRadians = -M_PI_2;
}
if (orientation == UIDeviceOrientationPortraitUpsideDown) {
deviceOrientationRadians = M_PI;
}
GLKMatrix4 baseRotation = GLKMatrix4MakeRotation(deviceOrientationRadians, 0.0f, 0.0f, 1.0f);
CMRotationMatrix a = deviceMotion.attitude.rotationMatrix;
deviceMotionAttitudeMatrix
= GLKMatrix4Make(a.m11, a.m21, a.m31, 0.0f,
a.m12, a.m22, a.m32, 0.0f,
a.m13, a.m23, a.m33, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
deviceMotionAttitudeMatrix = GLKMatrix4Multiply(baseRotation, deviceMotionAttitudeMatrix);
}
else
{
// Look straight forward (we're probably in the simulator, or a device without a gyro)
deviceMotionAttitudeMatrix = GLKMatrix4MakeRotation(-M_PI_2, 1.0f, 0.0f, 0.0f);
}
Вот какой -то код, чтобы уточнить, как использовать attlect.RotationMatrix
// initial model view matrix
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -5.f);
// convert CMRotationMatrix to GLKMatrix4
CMRotationMatrix r = motion.attitude.rotationMatrix;
GLKMatrix4 = GLKMatrix4Make(r.m11, r.m21, r.m31, 0.0f,
r.m12, r.m22, r.m32, 0.0f,
r.m13, r.m23, r.m33, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
// apply motion rotation matrix
modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, _motionRotationMatrix);
// apply matrix to effect
self.effect.transform.modelviewMatrix = modelViewMatrix;