Isolate and remove horizontal rotation from rotation of orientation CoreMotionMatrix

I am doing something like an augmented reality application in which I have an OpenGL scene that I want to maintain in accordance with gravity no matter how the iOS device moves. I thought that everything worked out with CMDeviceMotion.attitude.pitch, until I found that leaning against the iPhone, he bypasses this number. So I took the code from the pARk * example, and now I'm trying to isolate the rotation around vertical access. The scene I am painting doesn’t care what title the user stands with, the numbers will always be drawn at a given distance from the viewer. I think that when I figure out the rotation component of the vertical axis, I can flip it and multiply it by the rotation matrix, so keep the OpenGL shapes fixed when the user changes the title.

Here is my code:

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]); } 

Then I use rotMatrix, as usual, in OpenGL.

Thoughts, suggestions? Thanks in advance.

* The pARk sample code sets up several points in real space, gives the user's location and the relative direction of these points and draws them on the screen, so they appear on the horizon, indicating their location.

0
source share
3 answers

I took some hints from this answer and came up with a solution:

fooobar.com/questions/578214 / ...

 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)); } 

However, this can happen when the phone is near vertical. Therefore, I am still watching.

0
source

I just rotate the orientation around the Z axis depending on the orientation of the device screen. This is not the most beautiful, but it seems to do exactly what I need without going to the Euler and back (and thus avoiding problems with the lock in the gym)

 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); } 
+3
source

Here is some code explaining how to use .rotationMatrix relation

 // 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; 
+2
source

Source: https://habr.com/ru/post/1383713/


All Articles